added CElementShapeOBJ
MODIFY
ext/MitsubaLoader/CElementFactory.cpp
ext/MitsubaLoader/CElementFactory.cpp
#include "ParserUtil.h"
#include "IElement.h"
#include "CElementShapeCube.h"
+#include "CElementShapeOBJ.h"
#include "CSimpleElement.h"
namespace irr { namespace ext { namespace MitsubaLoader {
@@ -40,6 +41,10 @@ IElement* CElementFactory::createElement(const char* _el, const char** _atts)
{
return parseSimpleElement(_el, _atts, IElement::Type::POINT);
}
+ if (!std::strcmp(_el, "string"))
+ {
+ return parseSimpleElement(_el, _atts, IElement::Type::STRING);
+ }
else
{
ParserLog::mitsubaLoaderError("invalid .xml file structure: element " + std::string(_el) + "is unknown. \n");
@@ -64,6 +69,10 @@ IElement* CElementFactory::parseShape(const char* _el, const char** _atts)
{
return new CElementShapeCube();
}
+ if (!std::strcmp(_atts[i + 1], "obj"))
+ {
+ return new CElementShapeOBJ();
+ }
else
{
ParserLog::mitsubaLoaderError(std::string(_atts[i + 1]) + "is not a type of shape element. \n");
@@ -82,6 +91,10 @@ IElement* CElementFactory::parseSimpleElement(const char* _el, const char** _att
{
case IElement::Type::FLOAT:
return new CElementFloat();
+
+ case IElement::Type::STRING:
+ return new CElementString();
+
case IElement::Type::INTEGER:
{
//not implemented
@@ -90,13 +103,15 @@ IElement* CElementFactory::parseSimpleElement(const char* _el, const char** _att
}
case IElement::Type::BOOLEAN:
return new CElementBoolean();
+
case IElement::Type::POINT:
return new CElementPoint();
+
default:
_IRR_DEBUG_BREAK_IF(true);
return nullptr;
+
}
- return new CElementFloat();
}
}

ADD
ext/MitsubaLoader/CElementShapeOBJ.cpp
+#include "CElementShapeOBJ.h"
+
+#include "ParserUtil.h"
+#include "CSimpleElement.h"
+
+namespace irr { namespace ext { namespace MitsubaLoader {
+
+
+CElementShapeOBJ::~CElementShapeOBJ()
+{
+ if (mesh)
+ mesh->drop();
+}
+
+bool CElementShapeOBJ::processAttributes(const char** _atts)
+{
+ //only type is an acceptable argument
+ for (int i = 0; _atts[i]; i += 2)
+ {
+ if (std::strcmp(_atts[i], "type"))
+ {
+ ParserLog::wrongAttribute(_atts[i], getLogName());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CElementShapeOBJ::onEndTag(asset::IAssetManager& _assetManager, IElement* _parent)
+{
+ if (!fileName.size())
+ {
+ _IRR_DEBUG_BREAK_IF(true);
+ //print error (name of the .obj file is not set)
+ return false;
+ }
+
+ //getAssetInHierarchy?
+ mesh = static_cast<asset::ICPUMesh*>(_assetManager.getAsset(fileName, asset::IAssetLoader::SAssetLoadParams()));
+
+ if (!mesh)
+ return false;
+
+ //transform mesh by this->transformMatrix
+
+ return _parent->processChildData(this);
+}
+
+bool CElementShapeOBJ::processChildData(IElement* _child)
+{
+ switch (_child->getType())
+ {
+ case IElement::Type::TRANSFORM:
+ return true;
+
+ case IElement::Type::STRING:
+ {
+ CElementString* stringElement = static_cast<CElementString*>(_child);
+
+ if (stringElement->getNameAttribute() == "filename")
+ {
+ fileName = stringElement->getValueAttribute();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ default:
+ ParserLog::wrongChildElement(getLogName(), _child->getLogName());
+ return false;
+ }
+}
+
+}
+}
+}
\ No newline at end of file

ADD
ext/MitsubaLoader/CElementSphere.cpp
ext/MitsubaLoader/CElementSphere.cpp
ADD
ext/MitsubaLoader/CElementSphere.h
ext/MitsubaLoader/CElementSphere.h
MODIFY
ext/MitsubaLoader/CMitsubaLoader.cpp
ext/MitsubaLoader/CMitsubaLoader.cpp
@@ -16,9 +16,6 @@ namespace irr { namespace ext { namespace MitsubaLoader {
//TODO:
/*
- - !!!!!!!! REDUCE NUMBER OF ENUMS IN IElement::Type
- - consider if getName function is really needed (getLogName maybe?)
-
- proper handling of incorrect .xml file structure (in some situations parsing should be stoped and nullptr should be returned
from CMitsubaLoader::loadAsset, and in other situations only warning should be shown.)
- handle 'version' attribute
@@ -26,6 +23,9 @@ namespace irr { namespace ext { namespace MitsubaLoader {
- make sure default values for <float .. /> <boolean .. /> etc. are correct
- test atof function (CSimpleElement.h)
+ - how should loader treat upper/lower case letters in xml?
+
+ - clean up memory dynamically allocated by ParserData::scene
*/

MODIFY
ext/MitsubaLoader/CMitsubaScene.cpp
ext/MitsubaLoader/CMitsubaScene.cpp
#include "irrlicht.h"
#include "ParserUtil.h"
+#include "CElementSHapeOBJ.h"
+#include "CSimpleElement.h"
+
namespace irr { namespace ext { namespace MitsubaLoader {
@@ -35,19 +38,38 @@ bool CMitsubaScene::processChildData(IElement* _child)
switch (_child->getType())
{
case IElement::Type::SHAPE_OBJ:
- //add contents of the mesh held by child here
- //for example:
- /*
- CElementShapeObj childObjElement = static_cast<CElementShapeObj*>(_child);
- _child->getMesh()->getMeshBufferCount();
- */
+ {
+ CElementShapeOBJ* shape = static_cast<CElementShapeOBJ*>(_child);
+ const asset::ICPUMesh* shapeMesh = shape->getMesh();
+
+
+ if (!shapeMesh)
+ {
+ _IRR_DEBUG_BREAK_IF(true);
return false;
+ }
+
+
+ //is it possible that shapeMesh->getMeshBufferCount() > 1 ?
+ for (int i = 0; i < shapeMesh->getMeshBufferCount(); i++)
+ mesh->addMeshBuffer(shapeMesh->getMeshBuffer(i));
+
+
+ return true;
+ }
case IElement::Type::SHAPE_CUBE:
os::Printer::print("Alright! Cube has been added to the scene! \n");
return true;
+ case IElement::Type::FLOAT:
+
+ std::cout << static_cast<CElementFloat*>(_child)->getValueAttribute() << std::endl;
+
+ return true;
+
+
default:
ParserLog::wrongChildElement(getLogName(), _child->getLogName());

ADD
ext/MitsubaLoader/CSimpleElement.cpp
ext/MitsubaLoader/CSimpleElement.cpp
MODIFY
ext/MitsubaLoader/CSimpleElement.h
ext/MitsubaLoader/CSimpleElement.h
@@ -15,98 +15,76 @@ class CSimpleElement : public IElement
static_assert(
std::is_same<T, float>::value ||
std::is_same<T, bool>::value ||
- std::is_same<T, core::vector3df_SIMD>::value,
+ std::is_same<T, int>::value ||
+ std::is_same<T, core::vector3df_SIMD>::value ||
+ std::is_same<T, std::string>::value,
"assertion failed: cannot use this type");
public:
CSimpleElement()
- :type(IElement::Type::NONE),
- value(0.0f)
{
- IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, float>::value)
- {
- logName = "float";
- return;
- }
+ IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, float>::value) { logName = "float"; type = IElement::Type::FLOAT; }
IRR_PSEUDO_IF_CONSTEXPR_END
- IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, bool>::value)
- {
- logName = "boolean";
- return;
- }
+ IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, bool>::value) { logName = "boolean"; type = IElement::Type::BOOLEAN; }
IRR_PSEUDO_IF_CONSTEXPR_END
- IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, core::vector3df_SIMD>::value)
- {
- logName = "point";
- return;
- }
+ IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, core::vector3df_SIMD>::value) { logName = "point"; type = IElement::Type::POINT; }
IRR_PSEUDO_IF_CONSTEXPR_END
- };
- virtual bool processAttributes(const char** _atts) override;
- virtual bool onEndTag(asset::IAssetManager& _assetManager, IElement* _parent) override
- {
- //so far it is only for testing purpose
+ IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, int>::value) { logName = "integer"; type = IElement::Type::INTEGER; }
+ IRR_PSEUDO_IF_CONSTEXPR_END
- os::Printer::print("\t" + getLogName() + " name: " + nameAttr + " value: ");
- //os::Printer::print(value);
+ IRR_PSEUDO_IF_CONSTEXPR_BEGIN(std::is_same<T, std::string>::value) { logName = "string"; type = IElement::Type::STRING; }
+ IRR_PSEUDO_IF_CONSTEXPR_END
+ };
- return true;
- }
+ virtual bool processAttributes(const char** _atts) override;
+ virtual bool onEndTag(asset::IAssetManager& _assetManager, IElement* _parent) override;
virtual IElement::Type getType() const override { return type; };
virtual std::string getLogName() const override { return logName; };
inline std::string getNameAttribute() const { return nameAttr; }
- inline T getValueAttribute() const { return valueAttr; }
+ inline T getValueAttribute() const { return value; }
private:
- T value;
IElement::Type type;
std::string logName;
std::string nameAttr;
- T valueAttr;
+ T value;
};
using CElementFloat = CSimpleElement<float>;
using CElementBoolean = CSimpleElement<bool>;
using CElementPoint = CSimpleElement<irr::core::vector3df_SIMD>;
+using CElementString = CSimpleElement<std::string>;
template<typename T>
-bool CSimpleElement<T>::processAttributes(const char** _atts)
+inline bool CSimpleElement<T>::processAttributes(const char** _atts)
{
static_assert(false);
}
template<>
-bool CSimpleElement<float>::processAttributes(const char** _atts)
+inline bool CSimpleElement<float>::processAttributes(const char** _atts)
{
bool isNameSet = false;
for (int i = 0; _atts[i]; i += 2)
{
if (!std::strcmp(_atts[i], "name"))
- {
- if (!std::strcmp(_atts[i + 1], "radius") ||
- !std::strcmp(_atts[i + 1], "maxSmoothAngle"))
{
nameAttr = _atts[i + 1];
isNameSet = true;
}
- else
- {
- //print warning
- }
- }
else if (!std::strcmp(_atts[i], "value"))
{
value = static_cast<float>(atof(_atts[i + 1]));
}
else
{
- //print warning
+ //print warning (only attributes float has are name and value)
}
}
@@ -118,53 +96,89 @@ bool CSimpleElement<float>::processAttributes(const char** _atts)
}
template<>
-bool CSimpleElement<bool>::processAttributes(const char** _atts)
+inline bool CSimpleElement<bool>::processAttributes(const char** _atts)
{
bool isNameSet = false;
for (int i = 0; _atts[i]; i += 2)
{
if (!std::strcmp(_atts[i], "name"))
- {
- if (!std::strcmp(_atts[i + 1], "flipNormals") ||
- !std::strcmp(_atts[i + 1], "flipTexCoords") ||
- !std::strcmp(_atts[i + 1], "faceNormals") ||
- !std::strcmp(_atts[i + 1], "srgb"))
{
nameAttr = _atts[i + 1];
isNameSet = true;
}
- else
- {
- //print warning
- }
- }
if (!std::strcmp(_atts[i], "value"))
{
if (!std::strcmp(_atts[i + 1], "true"))
value = true;
- else if (!std::strcmp(_atts[i + 1], "true"))
+ else if (!std::strcmp(_atts[i + 1], "false"))
value = false;
else
{
- //print warning
+ //print warning (only true or false)
+ }
+ }
+ }
+
+ return isNameSet;
+}
+
+template<>
+inline bool CSimpleElement<std::string>::processAttributes(const char** _atts)
+{
+ bool isNameSet = false;
+
+ for (int i = 0; _atts[i]; i += 2)
+ {
+ if (!std::strcmp(_atts[i], "name"))
+ {
+ nameAttr = _atts[i + 1];
+ isNameSet = true;
+ }
+ else if (!std::strcmp(_atts[i], "value"))
+ {
+ value = _atts[i + 1];
+ }
+ else
+ {
+ //print warning (only attributes string has are name and value)
}
+
}
+
+ if (!isNameSet)
+ ;//print error
+
+ return isNameSet;
}
+template<>
+inline bool CSimpleElement<core::vector3df_SIMD>::processAttributes(const char** _atts)
+{
+ bool isNameSet = false;
+
return isNameSet;
}
template<>
-bool CSimpleElement<core::vector3df_SIMD>::processAttributes(const char** _atts)
+inline bool CSimpleElement<int>::processAttributes(const char** _atts)
{
bool isNameSet = false;
return isNameSet;
}
+template<typename T>
+bool CSimpleElement<T>::onEndTag(asset::IAssetManager& _assetManager, IElement* _parent)
+{
+ if (_parent)
+ return _parent->processChildData(this);
+
+ return true;
+}
+
}
}
}

MODIFY
ext/MitsubaLoader/IElement.h
ext/MitsubaLoader/IElement.h
@@ -36,7 +36,8 @@ public:
//other
TRANSFORM,
- TEXTURE
+ TEXTURE,
+ STRING
};
public:
@@ -61,6 +62,7 @@ public:
}
return true;
}
+ //
virtual bool onEndTag(asset::IAssetManager& _assetManager, IElement* _parent) = 0;
virtual IElement::Type getType() const = 0;
virtual std::string getLogName() const = 0;

MODIFY
ext/MitsubaLoader/ParserUtil.cpp
ext/MitsubaLoader/ParserUtil.cpp
@@ -109,38 +109,6 @@ void elementHandlerEnd(void* _data, const char* _el)
return;
}
}
-
-
-
-
- //if (!std::strcmp(_el, "scene"))
- //{
- // if (!data->isSceneActive) //this scenario is not possible to happen i think (parser would return with XML_STATUS_ERROR anyway)
- // {
- // assert(false);
- // std::cout << "invalid .xml file structure: wat? \n";
- // //stop parsing and return nullptr from CMitsubaLoader::loadAsset
- // }
- // else
- // {
- // data->scene.onEndTag(data->assetManager, nullptr);
- // data->isSceneActive = false;
- // }
- //}
- //else
- //{
- // //here, array of elements should have at least one element
- // assert(!data->elements.empty());
-
- // IElement* element = *(data->elements.end() - 1);
- // data->elements.pop_back();
-
- // //
- // IElement* parent = (data->elements.empty()) ? &(data->scene) : *(data->elements.end() - 1);
-
- // element->onEndTag(data->assetManager, parent);
- // delete element;
- //}
}
}

added CElementShapeOBJ