Added CElementSensor
MODIFY
ext/MitsubaLoader/CElementFactory.cpp
ext/MitsubaLoader/CElementFactory.cpp
#include "../../ext/MitsubaLoader/ParserUtil.h"
#include "../../ext/MitsubaLoader/IElement.h"
#include "../../ext/MitsubaLoader/CElementTransform.h"
+#include "../../ext/MitsubaLoader/CElementSensor.h"
#include "../../ext/MitsubaLoader/CElementSampler.h"
#include "../../ext/MitsubaLoader/CElementFilm.h"
#include "../../ext/MitsubaLoader/CShapeCreator.h"
@@ -45,6 +46,20 @@ IElement* CElementFactory::createElement(const char* _el, const char** _atts)
return transform;
}
else
+ if (!std::strcmp(_el, "sensor"))
+ {
+ CElementSensor* sensor = new CElementSensor();
+
+ if (!sensor->processAttributes(_atts))
+ {
+ delete sensor;
+ _IRR_DEBUG_BREAK_IF(true);
+ return nullptr;
+ }
+
+ return sensor;
+ }
+ else
if (!std::strcmp(_el, "sampler"))
{
CElementSampler* sampler = new CElementSampler();

MODIFY
ext/MitsubaLoader/CElementFilm.h
ext/MitsubaLoader/CElementFilm.h
@@ -77,13 +77,54 @@ struct SFilmMetadata
{
case EFilmType::HDR_FILM:
hdrFilmData = other.hdrFilmData;
+ break;
+
+ case EFilmType::TILED_HDR_FILM:
+ tiledHdrFilmData = other.tiledHdrFilmData;
+ break;
+
+ case EFilmType::LDR_FILM:
+ ldrFilmData = other.ldrFilmData;
+ break;
+
+ case EFilmType::M_FILM:
+ mFilmData = other.mFilmData;
+ break;
+ }
+ }
+
+ SFilmMetadata& operator=(const SFilmMetadata& other)
+ {
+ type = other.type;
+ width = other.width;
+ height = other.height;
+ isCropUsed = other.isCropUsed;
+ cropOffsetX = other.cropOffsetX;
+ cropOffsetY = other.cropOffsetY;
+ cropWidth = other.cropWidth;
+ cropHeight = other.cropHeight;
+ pixelFormat = other.pixelFormat;
+
+ switch (other.type)
+ {
+ case EFilmType::HDR_FILM:
+ hdrFilmData = other.hdrFilmData;
+ break;
+
case EFilmType::TILED_HDR_FILM:
tiledHdrFilmData = other.tiledHdrFilmData;
+ break;
+
case EFilmType::LDR_FILM:
ldrFilmData = other.ldrFilmData;
+ break;
+
case EFilmType::M_FILM:
mFilmData = other.mFilmData;
+ break;
}
+
+ return *this;
}
~SFilmMetadata()
@@ -151,8 +192,8 @@ class CElementFilm : public IElement
public:
virtual bool processAttributes(const char** _atts) override;
virtual bool onEndTag(asset::IAssetManager& _assetManager) override;
- virtual IElement::Type getType() const override { return IElement::Type::SAMPLER; }
- virtual std::string getLogName() const override { return "sampler"; }
+ virtual IElement::Type getType() const override { return IElement::Type::FILM; }
+ virtual std::string getLogName() const override { return "film"; }
SFilmMetadata getMetadata() const { return data; };

ADD
ext/MitsubaLoader/CElementSensor.cpp
+#include "../../ext/MitsubaLoader/CElementSensor.h"
+#include "../../ext/MitsubaLoader/CElementTransform.h"
+#include "../../ext/MitsubaLoader/ParserUtil.h"
+#include "../../ext/MitsubaLoader/PropertyElement.h"
+
+
+#include <functional>
+
+namespace irr { namespace ext { namespace MitsubaLoader {
+
+bool CElementSensor::processAttributes(const char** _atts)
+{
+ static const core::unordered_map<std::string, ESensorType> acceptableTypes = {
+ std::make_pair("perspective", ESensorType::PERSPECTIVE),
+ std::make_pair("thinlens", ESensorType::THINLENS),
+ std::make_pair("orthographic", ESensorType::ORTHOGRAPHIC),
+ std::make_pair("telecentric", ESensorType::TELECENTRIC),
+ std::make_pair("spherical", ESensorType::SPHERICAL),
+ std::make_pair("irradiancemeter", ESensorType::IRRADIANCEMETER),
+ std::make_pair("radiancemeter", ESensorType::RADIANCEMETER),
+ std::make_pair("fluencemeter", ESensorType::FLUENCEMETER)
+ };
+
+ //only type is an acceptable argument
+ for (int i = 0; _atts[i]; i += 2)
+ {
+ if (std::strcmp(_atts[i], "type"))
+ {
+ ParserLog::invalidXMLFileStructure(std::string(_atts[i]) + " is not attribute of shape element.");
+ return false;
+ }
+ else
+ {
+ auto samplerType = acceptableTypes.find(_atts[i + 1]);
+ if (samplerType == acceptableTypes.end())
+ {
+ ParserLog::invalidXMLFileStructure("unknown type");
+ _IRR_DEBUG_BREAK_IF(false);
+ return false;
+ }
+
+ data.type = samplerType->second;
+
+ //set default values
+ switch (data.type)
+ {
+ case ESensorType::PERSPECTIVE:
+ {
+ data.perspectiveData.focalLength = "50mm";
+ data.perspectiveData.fovAxis = EFOVAxis::X;
+ data.perspectiveData.fov = 0.0f;
+ data.perspectiveData.nearClip = 0.01f;
+ data.perspectiveData.nearClip = 10000.0f;
+
+ }
+ break;
+ case ESensorType::THINLENS:
+ {
+ data.thinlensData.focalLength = "50mm";
+ data.thinlensData.fovAxis = EFOVAxis::X;
+ data.thinlensData.fov = 0.0f;
+ data.thinlensData.nearClip = 0.01f;
+ data.thinlensData.nearClip = 10000.0f;
+ data.thinlensData.apertureRadius = 0.0f;
+ data.thinlensData.focusDistance = 0.0f;
+ }
+ break;
+ case ESensorType::ORTHOGRAPHIC:
+ {
+ data.thinlensData.nearClip = 0.01f;
+ data.thinlensData.nearClip = 10000.0f;
+ }
+ break;
+ case ESensorType::TELECENTRIC:
+ {
+ data.thinlensData.nearClip = 0.01f;
+ data.thinlensData.nearClip = 10000.0f;
+ data.thinlensData.apertureRadius = 0.0f;
+ data.thinlensData.focusDistance = 0.0f;
+ }
+ break;
+ default:
+ assert(true);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CElementSensor::processChildData(IElement* _child)
+{
+ switch (_child->getType())
+ {
+ case IElement::Type::FILM:
+ {
+ data.filmData = static_cast<CElementFilm*>(_child)->getMetadata();
+ return true;
+ }
+
+ case IElement::Type::SAMPLER:
+ {
+ data.samperData = static_cast<CElementSampler*>(_child)->getMetadata();
+ return true;
+ }
+ case IElement::Type::TRANSFORM:
+ {
+ transform = static_cast<CElementTransform*>(_child)->getMatrix();
+ return true;
+ }
+ default:
+ {
+ ParserLog::invalidXMLFileStructure(_child->getLogName() + "is not a child of sensor element");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+}
+
+bool CElementSensor::onEndTag(asset::IAssetManager& _assetManager)
+{
+ switch (data.type)
+ {
+ case ESensorType::PERSPECTIVE:
+ data.perspectiveData.toWorld = transform;
+ return processPerspectiveSensorProperties();
+
+ case ESensorType::THINLENS:
+ data.thinlensData.toWorld = transform;
+ return processThinlensSensorProperties();
+
+ case ESensorType::ORTHOGRAPHIC:
+ data.orthographicData.toWorld = transform;
+ return processOrthographicSensorProperties();
+
+ case ESensorType::TELECENTRIC:
+ data.telecentricData.toWorld = transform;
+ return processTelecentricSensorProperties();
+
+ case ESensorType::SPHERICAL:
+ data.sphericalData.toWorld = transform;
+ return true;
+
+ case ESensorType::IRRADIANCEMETER:
+ return true;
+
+ case ESensorType::RADIANCEMETER:
+ data.telecentricData.toWorld = transform;
+ return true;
+
+ case ESensorType::FLUENCEMETER:
+ data.telecentricData.toWorld = transform;
+ return true;
+
+ default:
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+}
+
+bool CElementSensor::processSharedDataProperty(const SPropertyElementData& _property)
+{
+ if (_property.type == SPropertyElementData::Type::FLOAT)
+ {
+ if (_property.name == "shutterOpen")
+ {
+ data.shutterOpen = CPropertyElementManager::retriveIntValue(_property.value);
+ }
+ else if (_property.name == "shutterClose")
+ {
+ data.shutterClose = CPropertyElementManager::retriveIntValue(_property.value);
+ }
+ else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else
+ {
+ ParserLog::invalidXMLFileStructure("unkown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+
+ return true;
+}
+
+bool CElementSensor::processPerspectiveSensorProperties()
+{
+ for (const SPropertyElementData& property : properties)
+ {
+ if (property.type == SPropertyElementData::Type::STRING &&
+ property.name == "focalLength")
+ {
+ data.perspectiveData.focalLength = property.value;
+ }
+ else
+ if (property.type == SPropertyElementData::Type::STRING &&
+ property.name == "fovAxis")
+ {
+ if (property.value == "x") data.perspectiveData.fovAxis = EFOVAxis::X; else
+ if (property.value == "y") data.perspectiveData.fovAxis = EFOVAxis::Y; else
+ if (property.value == "diagonal") data.perspectiveData.fovAxis = EFOVAxis::DIAGONAL; else
+ if (property.value == "smaller") data.perspectiveData.fovAxis = EFOVAxis::SMALLER; else
+ if (property.value == "larger") data.perspectiveData.fovAxis = EFOVAxis::LARGER; else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else
+ if (property.type == SPropertyElementData::Type::FLOAT)
+ {
+ if (property.name == "fov")
+ {
+ data.perspectiveData.fov = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "nearClip")
+ {
+ data.perspectiveData.nearClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "farClip")
+ {
+ data.perspectiveData.farClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else if(!processSharedDataProperty(property))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CElementSensor::processThinlensSensorProperties()
+{
+ for (const SPropertyElementData& property : properties)
+ {
+ if (property.type == SPropertyElementData::Type::STRING &&
+ property.name == "focalLength")
+ {
+ data.perspectiveData.focalLength = property.value;
+ }
+ else
+ if (property.type == SPropertyElementData::Type::STRING &&
+ property.name == "fovAxis")
+ {
+ if (property.value == "x") data.thinlensData.fovAxis = EFOVAxis::X; else
+ if (property.value == "y") data.thinlensData.fovAxis = EFOVAxis::Y; else
+ if (property.value == "diagonal") data.thinlensData.fovAxis = EFOVAxis::DIAGONAL; else
+ if (property.value == "smaller") data.thinlensData.fovAxis = EFOVAxis::SMALLER; else
+ if (property.value == "larger") data.thinlensData.fovAxis = EFOVAxis::LARGER; else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else
+ if (property.type == SPropertyElementData::Type::FLOAT)
+ {
+ if (property.name == "fov")
+ {
+ data.thinlensData.fov = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "nearClip")
+ {
+ data.thinlensData.nearClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "farClip")
+ {
+ data.thinlensData.farClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "apertureRadius")
+ {
+ data.thinlensData.apertureRadius = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "focusDistance")
+ {
+ data.thinlensData.focusDistance = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else if(!processSharedDataProperty(property))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CElementSensor::processOrthographicSensorProperties()
+{
+ for (const SPropertyElementData& property : properties)
+ {
+ if (property.type == SPropertyElementData::Type::FLOAT)
+ {
+
+ if (property.name == "nearClip")
+ {
+ data.perspectiveData.nearClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "farClip")
+ {
+ data.perspectiveData.farClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else if(!processSharedDataProperty(property))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CElementSensor::processTelecentricSensorProperties()
+{
+ for (const SPropertyElementData& property : properties)
+ {
+ if (property.type == SPropertyElementData::Type::FLOAT)
+ {
+
+ if (property.name == "nearClip")
+ {
+ data.perspectiveData.nearClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "farClip")
+ {
+ data.perspectiveData.farClip = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "apertureRadius")
+ {
+ data.telecentricData.apertureRadius = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if (property.name == "focusDistance")
+ {
+ data.telecentricData.focusDistance = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else
+ {
+ ParserLog::invalidXMLFileStructure("unknown property");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ }
+ else if(!processSharedDataProperty(property))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+}
+}
+}
\ No newline at end of file

ADD
ext/MitsubaLoader/CElementSensor.h
+#ifndef __C_ELEMENT_SENSOR_H_INCLUDED__
+#define __C_ELEMENT_SENSOR_H_INCLUDED__
+
+#include "../../ext/MitsubaLoader/IElement.h"
+#include "../../ext/MitsubaLoader/CElementFilm.h"
+#include "../../ext/MitsubaLoader/CElementSampler.h"
+
+#include "irrlicht.h"
+
+namespace irr { namespace ext { namespace MitsubaLoader {
+
+enum class ESensorType
+{
+ NONE,
+ PERSPECTIVE,
+ THINLENS,
+ ORTHOGRAPHIC,
+ TELECENTRIC,
+ SPHERICAL,
+ IRRADIANCEMETER,
+ RADIANCEMETER,
+ FLUENCEMETER
+};
+
+enum class EFOVAxis
+{
+ X,
+ Y,
+ DIAGONAL,
+ SMALLER,
+ LARGER
+};
+
+struct SSensorMetadata
+{
+ SSensorMetadata()
+ :type(ESensorType::NONE) {};
+
+ SSensorMetadata(const SSensorMetadata& other)
+ : type(other.type), shutterOpen(other.shutterOpen), shutterClose(other.shutterClose)
+ {
+ switch (other.type)
+ {
+ case ESensorType::PERSPECTIVE:
+ perspectiveData = other.perspectiveData;
+ break;
+
+ case ESensorType::THINLENS:
+ thinlensData = other.thinlensData;
+ break;
+
+ case ESensorType::ORTHOGRAPHIC:
+ perspectiveData = other.perspectiveData;
+ break;
+
+ case ESensorType::TELECENTRIC:
+ telecentricData = other.telecentricData;
+ break;
+
+ case ESensorType::SPHERICAL:
+ sphericalData = other.sphericalData;
+ break;
+
+ case ESensorType::RADIANCEMETER:
+ radiancemeterData = other.radiancemeterData;
+ break;
+
+ case ESensorType::FLUENCEMETER:
+ fluencemeterData = other.fluencemeterData;
+ break;
+
+ default:
+ assert(false);
+ }
+ }
+
+ ~SSensorMetadata()
+ {
+
+ }
+
+ SSamplerMetadata samperData;
+ SFilmMetadata filmData;
+
+ ESensorType type;
+
+ float shutterOpen = 0.0f;
+ float shutterClose = 0.0f;
+
+ union
+ {
+ struct PerspectiveData
+ {
+ core::matrix4SIMD toWorld;
+ std::string focalLength;
+ EFOVAxis fovAxis;
+ float fov;
+ float nearClip;
+ float farClip;
+
+ } perspectiveData;
+
+ struct ThinlensData
+ {
+ core::matrix4SIMD toWorld;
+ std::string focalLength;
+ EFOVAxis fovAxis;
+ float fov;
+ float nearClip;
+ float farClip;
+ float apertureRadius;
+ float focusDistance;
+
+ } thinlensData;
+
+ struct OrthographicData
+ {
+ core::matrix4SIMD toWorld;
+ float nearClip;
+ float farClip;
+
+ } orthographicData;
+
+ struct TelecentricData
+ {
+ core::matrix4SIMD toWorld;
+ float nearClip;
+ float farClip;
+ float apertureRadius;
+ float focusDistance;
+
+ } telecentricData;
+
+ struct SphericalData
+ {
+ core::matrix4SIMD toWorld;
+
+ } sphericalData;
+
+ struct RadiancemeterData
+ {
+ core::matrix4SIMD toWorld;
+
+ } radiancemeterData;
+
+ struct FluencemeterData
+ {
+ core::matrix4SIMD toWorld;
+
+ } fluencemeterData;
+ };
+};
+
+class CElementSensor : public IElement
+{
+public:
+ virtual bool processAttributes(const char** _atts) override;
+ virtual bool processChildData(IElement* _child) override;
+ virtual bool onEndTag(asset::IAssetManager& _assetManager) override;
+ virtual IElement::Type getType() const override { return IElement::Type::SENSOR; }
+ virtual std::string getLogName() const override { return "sensor"; }
+
+ SSensorMetadata getMetadata() { return data; }
+
+private:
+ bool processSharedDataProperty(const SPropertyElementData& _property);
+ bool processPerspectiveSensorProperties();
+ bool processThinlensSensorProperties();
+ bool processOrthographicSensorProperties();
+ bool processTelecentricSensorProperties();
+
+private:
+ SSensorMetadata data;
+ core::matrix4SIMD transform;
+
+};
+
+
+
+}
+}
+}
+
+#endif
\ No newline at end of file

MODIFY
ext/MitsubaLoader/IElement.h
ext/MitsubaLoader/IElement.h
@@ -19,6 +19,8 @@ public:
NONE,
SCENE,
SAMPLER,
+ FILM,
+ SENSOR,
//shapes
SHAPE,

MODIFY
ext/MitsubaLoader/ParserUtil.h
ext/MitsubaLoader/ParserUtil.h
@@ -28,7 +28,11 @@ public:
inline bool isParsingSuspended() const { return isParsingSuspendedFlag; }
private:
- static constexpr const char* unsElements[] = { "integrator", "emitter", "ref", "bsdf", "sensor", "medium", nullptr };
+ static constexpr const char* unsElements[] =
+ {
+ "integrator", "emitter", "ref", "bsdf",
+ "rfilter", "medium", "include", nullptr
+ };
bool isParsingSuspendedFlag;
std::string notSupportedElement;

MODIFY
ext/MitsubaLoader/PropertyElement.cpp
ext/MitsubaLoader/PropertyElement.cpp
@@ -115,7 +115,11 @@ std::pair<bool, SPropertyElementData> CPropertyElementManager::createPropertyDat
result.value = findStandardValue(_atts, errorOccurred);
if (errorOccurred)
+ {
+ _IRR_DEBUG_BREAK_IF(true);
return std::make_pair(false, SPropertyElementData());
+ }
+
return std::make_pair(true, result);
}

Added CElementSensor