Added CElementEmitter
ADD
ext/MitsubaLoader/CElementEmitter.cpp
+#include "../../ext/MitsubaLoader/CElementEmitter.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 CElementEmitter::processAttributes(const char** _atts)
+{
+ static const core::unordered_map<std::string, EEmitterType> acceptableTypes = {
+ std::make_pair("point", EEmitterType::POINT),
+ std::make_pair("area", EEmitterType::AREA),
+ std::make_pair("spot", EEmitterType::SPOT),
+ std::make_pair("directional", EEmitterType::DIRECTIONAL),
+ std::make_pair("collimated", EEmitterType::COLLIMATED),
+ std::make_pair("sky", EEmitterType::SKY),
+ std::make_pair("sunsky", EEmitterType::SUNSKY),
+ std::make_pair("envmap", EEmitterType::ENVMAP),
+ std::make_pair("constant", EEmitterType::CONSTANT)
+ };
+
+ //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 EEmitterType::POINT:
+ {
+ data.pointData.position = core::vector3df_SIMD(0.0f);
+ data.pointData.intensity = video::SColorf(1.0f);
+ data.pointData.samplingWeight = 1.0f;
+
+ }
+ break;
+ case EEmitterType::AREA:
+ {
+ data.areaData.radiance = video::SColorf(1.0f);
+ data.areaData.samplingWeight = 1.0f;
+ }
+ break;
+ case EEmitterType::SPOT:
+ {
+ data.spotData.intensity = video::SColorf(1.0f);
+ data.spotData.cutoffAngle = 20.0f;
+ data.spotData.beamWidth = 20.0f * (3.0f / 4.0f);
+ data.spotData.samplingWeight = 1.0f;
+ }
+ break;
+ case EEmitterType::DIRECTIONAL:
+ {
+ data.directionalData.direction = core::vector3df_SIMD(0.0f,-1.0f, 0.0f);
+ data.directionalData.irradiance = video::SColorf(1.0f);
+ data.directionalData.samplingWeight = 1.0f;
+ }
+ break;
+ case EEmitterType::COLLIMATED:
+ {
+ data.collimatedData.power = video::SColorf(1.0f);
+ data.collimatedData.samplingWeight = 1.0f;
+ }
+ break;
+ case EEmitterType::SKY:
+ case EEmitterType::SUN:
+ case EEmitterType::SUNSKY:
+ case EEmitterType::ENVMAP:
+ {
+ ParserLog::invalidXMLFileStructure("not supported yet.");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ break;
+ case EEmitterType::CONSTANT:
+ {
+ data.constantData.radiance = video::SColorf(1.0f);
+ data.constantData.samplingWeight = 1.0f;
+ }
+ break;
+ default:
+ assert(false);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CElementEmitter::processChildData(IElement* _child)
+{
+ switch (_child->getType())
+ {
+ 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 CElementEmitter::onEndTag(asset::IAssetManager& _assetManager)
+{
+ switch (data.type)
+ {
+ case EEmitterType::POINT:
+ return processPointEmitterProperties();
+
+ case EEmitterType::AREA:
+ return processAreaEmitterProperties();
+
+ case EEmitterType::SPOT:
+ return processSpotEmitterProperties();
+
+ case EEmitterType::DIRECTIONAL:
+ return processDirectionalEmitterProperties();
+
+ case EEmitterType::COLLIMATED:
+ return processCollimatedEmitterProperties();
+
+ case EEmitterType::SKY:
+ case EEmitterType::SUN:
+ case EEmitterType::SUNSKY:
+ case EEmitterType::ENVMAP:
+ ParserLog::invalidXMLFileStructure("not supported yet.");
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+
+ case EEmitterType::CONSTANT:
+ return processConstantEmitterProperties();
+
+ default:
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+}
+
+bool CElementEmitter::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 CElementEmitter::processPointEmitterProperties()
+{
+ for (const SPropertyElementData& property : properties)
+ {
+ if (property.type == SPropertyElementData::Type::POINT &&
+ property.name == "position")
+ {
+ data.pointData.position = CPropertyElementManager::retriveVector(property.value);
+ }
+ else
+ if ((property.type == SPropertyElementData::Type::RGB ||
+ property.type == SPropertyElementData::Type::SRGB) &&
+ property.name == "intensity")
+ {
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ else
+ if (property.type == SPropertyElementData::Type::FLOAT &&
+ property.name == "samplingWeight")
+ {
+ data.pointData.samplingWeight = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if(!processSharedDataProperty(property))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CElementEmitter::processAreaEmitterProperties()
+{
+ _IRR_DEBUG_BREAK_IF(true);
+ return true;
+}
+
+bool CElementEmitter::processSpotEmitterProperties()
+{
+ _IRR_DEBUG_BREAK_IF(true);
+ return true;
+}
+
+bool CElementEmitter::processDirectionalEmitterProperties()
+{
+ _IRR_DEBUG_BREAK_IF(true);
+ return true;
+}
+
+
+bool CElementEmitter::processCollimatedEmitterProperties()
+{
+ _IRR_DEBUG_BREAK_IF(true);
+ return true;
+}
+
+bool CElementEmitter::processConstantEmitterProperties()
+{
+ for (const SPropertyElementData& property : properties)
+ {
+ if ((property.type == SPropertyElementData::Type::RGB ||
+ property.type == SPropertyElementData::Type::SRGB) &&
+ property.name == "radiance")
+ {
+ _IRR_DEBUG_BREAK_IF(true);
+ return false;
+ }
+ else
+ if (property.type == SPropertyElementData::Type::FLOAT &&
+ property.name == "samplingWeight")
+ {
+ data.constantData.samplingWeight = CPropertyElementManager::retriveFloatValue(property.value);
+ }
+ else if(!processSharedDataProperty(property))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+}
+}
+}
\ No newline at end of file

ADD
ext/MitsubaLoader/CElementEmitter.h
+#ifndef __C_ELEMENT_EMITTER_H_INCLUDED__
+#define __C_ELEMENT_EMITTER_H_INCLUDED__
+
+#include "../../ext/MitsubaLoader/IElement.h"
+#include "irrlicht.h"
+
+namespace irr { namespace ext { namespace MitsubaLoader {
+
+enum class EEmitterType
+{
+ NONE,
+ POINT,
+ AREA,
+ SPOT,
+ DIRECTIONAL,
+ COLLIMATED,
+ SKY,
+ SUN,
+ SUNSKY,
+ ENVMAP,
+ CONSTANT
+};
+
+struct SEmitterMetadata
+{
+ SEmitterMetadata()
+ :type(EEmitterType::NONE) {};
+
+ SEmitterMetadata(const SEmitterMetadata& other)
+ : type(other.type), shutterOpen(other.shutterOpen), shutterClose(other.shutterClose)
+ {
+ switch (other.type)
+ {
+ case EEmitterType::POINT:
+ pointData = other.pointData;
+ break;
+
+ case EEmitterType::AREA:
+ areaData = other.areaData;
+ break;
+
+ case EEmitterType::SPOT:
+ spotData = other.spotData;
+ break;
+
+ case EEmitterType::DIRECTIONAL:
+ directionalData = other.directionalData;
+ break;
+
+ case EEmitterType::COLLIMATED:
+ collimatedData = other.collimatedData;
+ break;
+
+ case EEmitterType::SKY:
+ skyData = other.skyData;
+ break;
+
+ case EEmitterType::SUN:
+ sunData = other.sunData;
+ break;
+
+ case EEmitterType::SUNSKY:
+ sunskyData = other.sunskyData;
+ break;
+
+ case EEmitterType::ENVMAP:
+ envmapData = other.envmapData;
+ break;
+
+ case EEmitterType::CONSTANT:
+ constantData = other.constantData;
+ break;
+
+ default:
+ assert(false);
+ }
+ }
+
+ ~SEmitterMetadata()
+ {
+
+ }
+
+ EEmitterType type;
+
+ float shutterOpen = 0.0f;
+ float shutterClose = 0.0f;
+
+ union
+ {
+ struct PointData
+ {
+ core::vector3df_SIMD position;
+ video::SColorf intensity;
+ float samplingWeight;
+
+ } pointData;
+
+ struct AreaData
+ {
+ video::SColorf radiance;
+ float samplingWeight;
+
+ } areaData;
+
+ struct SpotData
+ {
+ core::matrix4SIMD toWorld;
+ video::SColorf intensity;
+ float cutoffAngle;
+ float beamWidth;
+ //texture
+ float samplingWeight;
+
+ } spotData;
+
+ struct DirectionalData
+ {
+ core::matrix4SIMD toWorld;
+ video::SColorf irradiance;
+ core::vector3df_SIMD direction;
+ float samplingWeight;
+
+ } directionalData;
+
+ struct CollimatedData
+ {
+ core::matrix4SIMD toWorld;
+ video::SColorf power;
+ float samplingWeight;
+
+ } collimatedData;
+
+ struct SkyData
+ {
+ core::matrix4SIMD toWorld;
+ float samplingWeight;
+ float turbidity;
+ video::SColorf albedo;
+ int day;
+ int month;
+ int year;
+ float second;
+ float minute;
+ float hour;
+ float latitude;
+ float longitude;
+ float timezone;
+ core::vector3df_SIMD sunDirection;
+ float stretch;
+ int resolution;
+ float scale;
+
+ } skyData;
+
+ struct SunData
+ {
+ float samplingWeight;
+ float turbidity;
+ int day;
+ int month;
+ int year;
+ float second;
+ float minute;
+ float hour;
+ float latitude;
+ float longitude;
+ float timezone;
+ core::vector3df_SIMD sunDirection;
+ float scale;
+ float sunRadiusScale;
+
+ } sunData;
+
+ struct SunskyData
+ {
+ float turbidity;
+ video::SColorf albedo;
+ int day;
+ int month;
+ int year;
+ float second;
+ float minute;
+ float hour;
+ float latitude;
+ float longitude;
+ float timezone;
+ core::vector3df_SIMD sunDirection;
+ float stretch;
+ float sunScale;
+ float skyScale;
+ float sunRadiusScale;
+ int resolution;
+
+ } sunskyData;
+
+ struct EnvmapData
+ {
+ core::matrix4SIMD toWorld;
+ std::string filename;
+ float scale;
+ float gamma;
+ bool cache;
+ float samplingWeight;
+
+ } envmapData;
+
+ struct ConstantData
+ {
+ video::SColorf radiance;
+ float samplingWeight;
+
+ } constantData;
+ };
+};
+
+class CElementEmitter : 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::EMITTER; }
+ virtual std::string getLogName() const override { return "emitter"; }
+
+ SEmitterMetadata getMetadata() { return data; }
+
+private:
+ bool processSharedDataProperty(const SPropertyElementData& _property);
+ bool processPointEmitterProperties();
+ bool processAreaEmitterProperties();
+ bool processSpotEmitterProperties();
+ bool processDirectionalEmitterProperties();
+ bool processCollimatedEmitterProperties();
+ bool processConstantEmitterProperties();
+
+private:
+ SEmitterMetadata data;
+ core::matrix4SIMD transform;
+
+};
+
+
+
+}
+}
+}
+
+#endif
\ No newline at end of file

Added CElementEmitter