diff --git a/scripts/appleseedMaya/AETemplates/appleseedPhysicalSkyLightTemplate.py b/scripts/appleseedMaya/AETemplates/appleseedPhysicalSkyLightTemplate.py index 72565b8..e760643 100644 --- a/scripts/appleseedMaya/AETemplates/appleseedPhysicalSkyLightTemplate.py +++ b/scripts/appleseedMaya/AETemplates/appleseedPhysicalSkyLightTemplate.py @@ -32,6 +32,40 @@ # appleseedMaya imports. from appleseedMaya.logger import logger +global changesunPositioningSystem + +def changesunPositioningSystem(nodeName): + sunPositioningSystem = pm.getAttr(nodeName + ".sunPositioningSystem") + if sunPositioningSystem == 0: + pm.setAttr(nodeName + ".sunTheta", lock=False) + pm.setAttr(nodeName + ".sunPhi", lock=False) + + pm.setAttr(nodeName + ".hour", lock=True) + pm.setAttr(nodeName + ".minute", lock=True) + pm.setAttr(nodeName + ".second", lock=True) + pm.setAttr(nodeName + ".month", lock=True) + pm.setAttr(nodeName + ".day", lock=True) + pm.setAttr(nodeName + ".year", lock=True) + pm.setAttr(nodeName + ".timezone", lock=True) + pm.setAttr(nodeName + ".north", lock=True) + pm.setAttr(nodeName + ".latitude", lock=True) + pm.setAttr(nodeName + ".longitude", lock=True) + else: + pm.setAttr(nodeName + ".sunTheta", lock=True) + pm.setAttr(nodeName + ".sunPhi", lock=True) + + pm.setAttr(nodeName + ".hour", lock=False) + pm.setAttr(nodeName + ".minute", lock=False) + pm.setAttr(nodeName + ".second", lock=False) + pm.setAttr(nodeName + ".month", lock=False) + pm.setAttr(nodeName + ".day", lock=False) + pm.setAttr(nodeName + ".year", lock=False) + pm.setAttr(nodeName + ".timezone", lock=False) + pm.setAttr(nodeName + ".north", lock=False) + pm.setAttr(nodeName + ".latitude", lock=False) + pm.setAttr(nodeName + ".longitude", lock=False) + + class AEappleseedPhysicalSkyLightTemplate(pm.ui.AETemplate): @@ -50,8 +84,6 @@ def beginLayout(self, name, collapse=True): def buildBody(self, nodeName): self.beginLayout('Sky Attributes', collapse=0) - self.addControl('sunTheta') - self.addControl('sunPhi') self.addSeparator() self.addControl('turbidity') self.addControl('turbidityScale') @@ -62,6 +94,25 @@ def buildBody(self, nodeName): self.addSeparator() self.addControl('horizonShift') self.addControl('groundAlbedo') + self.addControl('sunPositioningSystem', changeCommand=changesunPositioningSystem) + + self.beginLayout('Sun Theta/Sun Phi', collapse=0) + self.addControl('sunTheta') + self.addControl('sunPhi') + self.endLayout() + + self.beginLayout('Time and Location', collapse=0) + self.addControl('hour') + self.addControl('minute') + self.addControl('second') + self.addControl('month') + self.addControl('day') + self.addControl('year') + self.addControl('timezone') + self.addControl('north') + self.addControl('latitude') + self.addControl('longitude') + self.endLayout() self.endLayout() self.beginLayout('Sun Attributes', collapse=0) diff --git a/src/appleseedmaya/exporters/envlightexporter.cpp b/src/appleseedmaya/exporters/envlightexporter.cpp index a7ca90f..706758d 100644 --- a/src/appleseedmaya/exporters/envlightexporter.cpp +++ b/src/appleseedmaya/exporters/envlightexporter.cpp @@ -45,6 +45,7 @@ // Maya headers. #include "appleseedmaya/_beginmayaheaders.h" #include +#include #include "appleseedmaya/_endmayaheaders.h" namespace asf = foundation; diff --git a/src/appleseedmaya/physicalskylightnode.cpp b/src/appleseedmaya/physicalskylightnode.cpp index 9fa4eff..4f4a73e 100644 --- a/src/appleseedmaya/physicalskylightnode.cpp +++ b/src/appleseedmaya/physicalskylightnode.cpp @@ -37,17 +37,33 @@ // Maya headers. #include "appleseedmaya/_beginmayaheaders.h" +#include #include #include #include #include "appleseedmaya/_endmayaheaders.h" +#include "renderer/utility/solarpositionalgorithm.h" + +#include + const MString PhysicalSkyLightNode::nodeName("appleseedPhysicalSkyLight"); const MTypeId PhysicalSkyLightNode::id(PhysicalSkyLightNodeTypeId); const MString PhysicalSkyLightNode::drawDbClassification("drawdb/geometry/appleseedPhysicalSkyLight"); +MObject PhysicalSkyLightNode::m_sunPositioningSystem; MObject PhysicalSkyLightNode::m_sunTheta; MObject PhysicalSkyLightNode::m_sunPhi; +MObject PhysicalSkyLightNode::m_hour; +MObject PhysicalSkyLightNode::m_minute; +MObject PhysicalSkyLightNode::m_second; +MObject PhysicalSkyLightNode::m_month; +MObject PhysicalSkyLightNode::m_day; +MObject PhysicalSkyLightNode::m_year; +MObject PhysicalSkyLightNode::m_timezone; +MObject PhysicalSkyLightNode::m_north; +MObject PhysicalSkyLightNode::m_latitude; +MObject PhysicalSkyLightNode::m_longitude; MObject PhysicalSkyLightNode::m_turbidity; MObject PhysicalSkyLightNode::m_turbidityMultiplier; MObject PhysicalSkyLightNode::m_luminanceMultiplier; @@ -68,6 +84,7 @@ void* PhysicalSkyLightNode::creator() MStatus PhysicalSkyLightNode::initialize() { + MFnEnumAttribute enumAttrFn; MFnMessageAttribute msgAttrFn; MFnNumericAttribute numAttrFn; MFnUnitAttribute unitAttrFn; @@ -90,31 +107,6 @@ MStatus PhysicalSkyLightNode::initialize() status = addAttribute(m_displaySize); APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); - m_sunTheta = unitAttrFn.create( - "sunTheta", - "sunTheta", - MFnUnitAttribute::kAngle, - M_PI * 0.25, // 45 degrees - &status); - APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); - unitAttrFn.setNiceNameOverride("Sun Theta Angle"); - unitAttrFn.setMin(0.0); - unitAttrFn.setMax(M_PI * 0.5); - status = addAttribute(m_sunTheta); - - m_sunPhi = unitAttrFn.create( - "sunPhi", - "sunPhi", - MFnUnitAttribute::kAngle, - 0.0, - &status); - APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); - unitAttrFn.setNiceNameOverride("Sun Phi Angle"); - unitAttrFn.setMin(-M_PI * 2.0); - unitAttrFn.setMax(M_PI * 2.0); - status = addAttribute(m_sunPhi); - APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); - m_turbidity = numAttrFn.create( "turbidity", "turbidity", @@ -203,6 +195,172 @@ MStatus PhysicalSkyLightNode::initialize() numAttrFn.setNiceNameOverride("Ground Albedo"); status = addAttribute(m_groundAlbedo); APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_sunPositioningSystem = enumAttrFn.create( + "sunPositioningSystem", + "sunPositioningSystem", + SunPositioningSystem::Analytical, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + enumAttrFn.addField("Sun Theta/Sun Phi", SunPositioningSystem::Analytical); + enumAttrFn.addField("Time and Location", SunPositioningSystem::TimeLocation); + status = addAttribute(m_sunPositioningSystem); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_sunTheta = unitAttrFn.create( + "sunTheta", + "sunTheta", + MFnUnitAttribute::kAngle, + M_PI * 0.25, // 45 degrees + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + unitAttrFn.setNiceNameOverride("Sun Theta Angle"); + unitAttrFn.setMin(0.0); + unitAttrFn.setMax(M_PI * 0.5); + status = addAttribute(m_sunTheta); + + m_sunPhi = unitAttrFn.create( + "sunPhi", + "sunPhi", + MFnUnitAttribute::kAngle, + 0.0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + unitAttrFn.setNiceNameOverride("Sun Phi Angle"); + unitAttrFn.setMin(-M_PI * 2.0); + unitAttrFn.setMax(M_PI * 2.0); + status = addAttribute(m_sunPhi); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_hour = numAttrFn.create( + "hour", + "hour", + MFnNumericData::kInt, + 12, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Hour"); + numAttrFn.setMin(0); + numAttrFn.setMax(23); + status = addAttribute(m_hour); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_minute = numAttrFn.create( + "minute", + "minute", + MFnNumericData::kInt, + 0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Minute"); + numAttrFn.setMin(0); + numAttrFn.setMax(59); + status = addAttribute(m_minute); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_second = numAttrFn.create( + "second", + "second", + MFnNumericData::kInt, + 0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Second"); + numAttrFn.setMin(0); + numAttrFn.setMax(59); + status = addAttribute(m_second); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_month = numAttrFn.create( + "month", + "month", + MFnNumericData::kInt, + 1, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Month"); + numAttrFn.setMin(1); + numAttrFn.setMax(12); + status = addAttribute(m_month); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_day = numAttrFn.create( + "day", + "day", + MFnNumericData::kInt, + 1, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Day"); + numAttrFn.setMin(1); + numAttrFn.setMax(31); + status = addAttribute(m_day); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_year = numAttrFn.create( + "year", + "year", + MFnNumericData::kInt, + 2020, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Year"); + numAttrFn.setMin(-2000); + numAttrFn.setMax(4000); + status = addAttribute(m_year); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_timezone = numAttrFn.create( + "timezone", + "timezone", + MFnNumericData::kInt, + 0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Timezone"); + numAttrFn.setMin(-18); + numAttrFn.setMax(18); + status = addAttribute(m_timezone); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_north = numAttrFn.create( + "north", + "north", + MFnNumericData::kFloat, + 0.0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("North"); + numAttrFn.setMin(-180.0); + numAttrFn.setMax(180.0); + status = addAttribute(m_north); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_latitude = numAttrFn.create( + "latitude", + "latitude", + MFnNumericData::kFloat, + 0.0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Latitude"); + numAttrFn.setMin(-90.0); + numAttrFn.setMax(90.0); + status = addAttribute(m_latitude); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + + m_longitude = numAttrFn.create( + "longitude", + "longitude", + MFnNumericData::kFloat, + 0.0, + &status); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to create physical sky light attribute"); + numAttrFn.setNiceNameOverride("Longitude"); + numAttrFn.setMin(-90.0); + numAttrFn.setMax(90.0); + status = addAttribute(m_longitude); + APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); m_sunEnable = numAttrFn.create( "sunEnable", @@ -241,6 +399,30 @@ MStatus PhysicalSkyLightNode::initialize() status = addAttribute(m_sunSizeMultiplier); APPLESEED_MAYA_CHECK_MSTATUS_RET_MSG(status, "appleseedMaya: Failed to add physical sky light attribute"); + attributeAffects(m_sunPositioningSystem, m_sunTheta); + attributeAffects(m_hour, m_sunTheta); + attributeAffects(m_minute, m_sunTheta); + attributeAffects(m_second, m_sunTheta); + attributeAffects(m_year, m_sunTheta); + attributeAffects(m_day, m_sunTheta); + attributeAffects(m_month, m_sunTheta); + attributeAffects(m_timezone, m_sunTheta); + attributeAffects(m_north, m_sunTheta); + attributeAffects(m_latitude, m_sunTheta); + attributeAffects(m_longitude, m_sunTheta); + + attributeAffects(m_sunPositioningSystem, m_sunPhi); + attributeAffects(m_hour, m_sunPhi); + attributeAffects(m_minute, m_sunPhi); + attributeAffects(m_second, m_sunPhi); + attributeAffects(m_year, m_sunPhi); + attributeAffects(m_day, m_sunPhi); + attributeAffects(m_month, m_sunPhi); + attributeAffects(m_timezone, m_sunPhi); + attributeAffects(m_north, m_sunPhi); + attributeAffects(m_latitude, m_sunPhi); + attributeAffects(m_longitude, m_sunPhi); + return status; } @@ -300,7 +482,41 @@ void PhysicalSkyLightNode::draw( MStatus PhysicalSkyLightNode::compute(const MPlug& plug, MDataBlock& dataBlock) { - return MS::kUnknownParameter; + static MAngle sunPhi = 0.0f; + + if (dataBlock.inputValue(m_sunPositioningSystem).asInt() == 1) + { + if (strstr(plug.info().asChar(), "sunTheta") != nullptr) + { + renderer::ParamArray param; + param.insert("hour", dataBlock.inputValue(m_hour).asInt()); + param.insert("minute", dataBlock.inputValue(m_minute).asInt()); + param.insert("second", dataBlock.inputValue(m_second).asInt()); + param.insert("month", dataBlock.inputValue(m_month).asInt()); + param.insert("day", dataBlock.inputValue(m_day).asInt()); + param.insert("year", dataBlock.inputValue(m_year).asInt()); + param.insert("timezone", dataBlock.inputValue(m_timezone).asInt()); + param.insert("north", dataBlock.inputValue(m_north).asInt()); + param.insert("latitude", dataBlock.inputValue(m_latitude).asInt()); + param.insert("longitude", dataBlock.inputValue(m_longitude).asInt()); + + foundation::auto_release_ptr sunPositioner = + renderer::SunPositionerFactory::create("Sun Positioner", param); + + sunPositioner->fetch_data(); + sunPositioner->compute_sun_position(); + + dataBlock.outputValue(plug).asDouble() = MAngle(sunPositioner->get_zenith(), MAngle::Unit::kDegrees).asRadians(); + sunPhi = MAngle(sunPositioner->get_azimuth(), MAngle::Unit::kDegrees); + } + else + if ((strstr(plug.info().asChar(), "sunPhi") != nullptr)) + dataBlock.outputValue(plug).asDouble() = sunPhi.asRadians(); + } + else + return MS::kUnknownParameter; + + return MS::kSuccess; } PhysicalSkyLightData::PhysicalSkyLightData() diff --git a/src/appleseedmaya/physicalskylightnode.h b/src/appleseedmaya/physicalskylightnode.h index cf6f989..c2cb33b 100644 --- a/src/appleseedmaya/physicalskylightnode.h +++ b/src/appleseedmaya/physicalskylightnode.h @@ -44,6 +44,8 @@ #include #include "appleseedmaya/_endmayaheaders.h" +#include "renderer/api/scene.h" + class PhysicalSkyLightNode : public MPxLocatorNode { @@ -67,8 +69,19 @@ class PhysicalSkyLightNode MStatus compute(const MPlug& plug, MDataBlock& data) override; private: + static MObject m_sunPositioningSystem; static MObject m_sunTheta; static MObject m_sunPhi; + static MObject m_hour; + static MObject m_minute; + static MObject m_second; + static MObject m_month; + static MObject m_day; + static MObject m_year; + static MObject m_timezone; + static MObject m_north; + static MObject m_latitude; + static MObject m_longitude; static MObject m_turbidity; static MObject m_turbidityMultiplier; static MObject m_luminanceMultiplier; @@ -81,6 +94,12 @@ class PhysicalSkyLightNode static MObject m_sunSizeMultiplier; static MObject m_message; static MObject m_displaySize; + + enum SunPositioningSystem + { + Analytical, + TimeLocation + }; }; class PhysicalSkyLightData