TheaSDK::Normal3D TheaRenderer::getSunDirection() { MFnDependencyNode depFn(getRenderGlobalsNode()); std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; std::shared_ptr<TheaRenderer> renderer = std::static_pointer_cast<TheaRenderer>(MayaTo::getWorldPtr()->worldRendererPtr); TheaSDK::Normal3D sunDir; MObjectArray nodeList; getConnectedInNodes(MString("sunLightConnection"), getRenderGlobalsNode(), nodeList); if( nodeList.length() > 0) { MVector lightDir(0,0,1); MFnDagNode sunDagNode(nodeList[0]); //lightDir *= this->mtth_renderGlobals->globalConversionMatrix.inverse(); lightDir *= sunDagNode.transformationMatrix(); lightDir *= renderGlobals->globalConversionMatrix; lightDir.normalize(); return TheaSDK::Normal3D(lightDir.x,lightDir.y,lightDir.z); } float sunDirX = 0.0f, sunDirY = 0.0f, sunDirZ = 1.0f; MPlug sunDirPlug = depFn.findPlug("sunDirection"); if (!sunDirPlug.isNull()) { sunDirX = sunDirPlug.child(0).asFloat(); sunDirY = sunDirPlug.child(1).asFloat(); sunDirZ = sunDirPlug.child(2).asFloat(); } return TheaSDK::Normal3D(sunDirX, sunDirY, sunDirZ); }
void ShadingNode::getConnectedInputObjects(MObjectArray& objectArray) { MStatus stat; MFnDependencyNode depFn(this->mobject); MStringArray aliasArray; depFn.getAliasList(aliasArray); MObjectArray objectList; MPlugArray connections; depFn.getConnections(connections); for (uint connId = 0; connId < connections.length(); connId++) { MPlug p = connections[connId]; if (!p.isDestination()) continue; // a connection can be a direct connection or a child connection e.g. colorR, colorG... // but in a shader description file only the main attribute is listed so we go up until we have the main plug MPlug mainPlug = p; while (mainPlug.isChild()) mainPlug = mainPlug.parent(); if (mainPlug.isElement()) mainPlug = mainPlug.array(); MStringArray stringArray; // name contains node.attributeName, so we have to get rid of the nodeName mainPlug.name().split('.', stringArray); MString plugName = stringArray[stringArray.length() - 1]; if (!this->isAttributeValid(plugName)) continue; getConnectedInNodes(p, objectList); makeUniqueArray(objectList); } objectArray = objectList; }
bool CoronaRenderer::isSunLight(std::shared_ptr<MayaObject> obj) { // a sun light has a transform connection to the coronaGlobals.sunLightConnection plug MObject coronaGlobals = objectFromName(MString("coronaGlobals")); MObjectArray nodeList; MStatus stat; getConnectedInNodes(MString("sunLightConnection"), coronaGlobals, nodeList); if( nodeList.length() > 0) { MObject sunObj = nodeList[0]; if(sunObj.hasFn(MFn::kTransform)) { MFnDagNode sunDagNode(sunObj); MObject sunDagObj = sunDagNode.child(0, &stat); if( sunDagObj == obj->mobject) return true; } } return false; }
bool isSunLight(MObject& obj) { MObjectArray nodeList; MStatus stat; MObject sun = obj; if (obj.hasFn(MFn::kDirectionalLight)) { MFnDagNode sunDagNode(obj); sun = sunDagNode.parent(0); } getConnectedInNodes(MString("physicalSunConnection"), getRenderGlobalsNode(), nodeList); if (nodeList.length() > 0) { MObject sunObj = nodeList[0]; if (sunObj.hasFn(MFn::kTransform)) { if (sunObj == sun) return true; } } return false; }
void CoronaRenderer::defineLights() { // first get the globals node and serach for a directional light connection MObject coronaGlobals = objectFromName(MString("coronaGlobals")); MObjectArray nodeList; MStatus stat; if( this->mtco_renderGlobals->useSunLightConnection ) { getConnectedInNodes(MString("sunLightConnection"), coronaGlobals, nodeList); if( nodeList.length() > 0) { MObject sunObj = nodeList[0]; if(sunObj.hasFn(MFn::kTransform)) { // we suppose what's connected here is a dir light transform MVector lightDir(0, 0, 1); // default dir light dir MFnDagNode sunDagNode(sunObj); lightDir *= sunDagNode.transformationMatrix(); lightDir *= this->mtco_renderGlobals->globalConversionMatrix; lightDir.normalize(); MObject sunDagObj = sunDagNode.child(0, &stat); if( !stat ) logger.error("no child 0"); MColor sunColor(1); float colorMultiplier = 1.0f; if(sunDagObj.hasFn(MFn::kDirectionalLight)) { MFnDependencyNode sunNode(sunDagObj); getColor("color", sunNode, sunColor); getFloat("mtco_sun_multiplier", sunNode, colorMultiplier); }else{ logger.warning(MString("Sun connection is not a directional light - using transform only.")); } sunColor *= colorMultiplier * 10000.0; Corona::Sun sun; sun.active = true; sun.dirTo = Corona::Dir(lightDir.x, lightDir.y, lightDir.z).getNormalized(); sun.color = Corona::Rgb(sunColor.r,sunColor.g,sunColor.b); sun.visibleDirect = true; sun.visibleReflect = true; sun.visibleRefract = true; sun.sizeMultiplier = 2.0f; this->context.scene->getSun() = sun; } } } for( size_t lightId = 0; lightId < this->mtco_scene->lightList.size(); lightId++) { mtco_MayaObject *obj = (mtco_MayaObject *)this->mtco_scene->lightList[lightId]; if(!obj->visible) continue; if( this->isSunLight(obj)) continue; MFnDependencyNode depFn(obj->mobject); if( obj->mobject.hasFn(MFn::kPointLight)) { MColor col; getColor("color", depFn, col); float intensity = 1.0f; getFloat("intensity", depFn, intensity); int decay = 0; getEnum(MString("decayRate"), depFn, decay); MMatrix m = obj->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; Corona::Pos LP(m[3][0],m[3][1],m[3][2]); PointLight *pl = new PointLight; pl->LP = LP; pl->distFactor = 1.0/this->mtco_renderGlobals->scaleFactor; pl->lightColor = Corona::Rgb(col.r, col.g, col.b); pl->lightIntensity = intensity; getEnum(MString("decayRate"), depFn, pl->decayType); this->context.scene->addLightShader(pl); } if( obj->mobject.hasFn(MFn::kSpotLight)) { MVector lightDir(0, 0, -1); MColor col; getColor("color", depFn, col); float intensity = 1.0f; getFloat("intensity", depFn, intensity); MMatrix m = obj->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; lightDir *= obj->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; lightDir.normalize(); Corona::Pos LP(m[3][0],m[3][1],m[3][2]); SpotLight *sl = new SpotLight; sl->LP = LP; sl->lightColor = Corona::Rgb(col.r, col.g, col.b); sl->lightIntensity = intensity; sl->LD = Corona::Dir(lightDir.x, lightDir.y, lightDir.z); sl->angle = 45.0f; sl->distFactor = 1.0/this->mtco_renderGlobals->scaleFactor; getEnum(MString("decayRate"), depFn, sl->decayType); getFloat("coneAngle", depFn, sl->angle); getFloat("penumbraAngle", depFn, sl->penumbraAngle); getFloat("dropoff", depFn, sl->dropoff); this->context.scene->addLightShader(sl); } if( obj->mobject.hasFn(MFn::kDirectionalLight)) { MVector lightDir(0, 0, -1); MColor col; getColor("color", depFn, col); float intensity = 1.0f; getFloat("intensity", depFn, intensity); MMatrix m = obj->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; lightDir *= m; lightDir.normalize(); Corona::Pos LP(m[3][0],m[3][1],m[3][2]); DirectionalLight *dl = new DirectionalLight; dl->LP = LP; dl->lightColor = Corona::Rgb(col.r, col.g, col.b); dl->lightIntensity = intensity; dl->LD = Corona::Dir(lightDir.x, lightDir.y, lightDir.z); this->context.scene->addLightShader(dl); } if( obj->mobject.hasFn(MFn::kAreaLight)) { logger.warning(MString("Area light: ") + obj->shortName + " not yet supported."); MMatrix m = obj->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; obj->geom = defineStdPlane(); Corona::AnimatedAffineTm atm; this->setAnimatedTransformationMatrix(atm, obj); obj->instance = obj->geom->addInstance(atm, NULL, NULL); //this->defineMaterial(obj->instance, obj); } } }
void getConnectedInNodes(const MString& attribute, const MObject& thisObject, MObjectArray& nodeList) { MFnDependencyNode depFn(thisObject); MPlug attrPlug = depFn.findPlug(attribute); getConnectedInNodes(attrPlug, nodeList); }
void IndigoRenderer::defineEnvironment() { std::shared_ptr<MayaScene> mayaScene = MayaTo::getWorldPtr()->worldScenePtr; std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; MFnDependencyNode gFn(getRenderGlobalsNode()); switch (getEnumInt("environmentType", gFn)) { case 0: // off { break; } case 1: // environment light map { MString texName; bool useTexture = false; Indigo::String texturePath = ""; MObject fileTexObj; if( getConnectedFileTexturePath(MString("environmentColor"), MString("indigoGlobals"), texName, fileTexObj) ) { useTexture = true; texturePath = texName.asChar(); } MFnDependencyNode fileTexNode(fileTexObj); MColor bgColor = getColorAttr("environmentColor", gFn); int mapType = getIntAttr("environmentMapType", gFn, 0); Indigo::SceneNodeBackgroundSettingsRef background_settings(new Indigo::SceneNodeBackgroundSettings()); Reference<Indigo::DiffuseMaterial> mat(new Indigo::DiffuseMaterial()); // Albedo should be zero. mat->albedo = Reference<Indigo::WavelengthDependentParam>(new Indigo::ConstantWavelengthDependentParam(Reference<Indigo::Spectrum>(new Indigo::UniformSpectrum(0)))); Indigo::Texture texture; if( useTexture ) { texture.path = texturePath; texture.exponent = 1; // Since we will usually use a HDR image, the exponent (gamma) should be set to one. MColor colorGain(1,1,1); getColor("colorGain", fileTexNode, colorGain); MColor colorOffset(0,0,0); getColor("colorOffset", fileTexNode, colorOffset); double cg = (colorGain.r + colorGain.g + colorGain.b) / 3.0; double co = (colorOffset.r + colorOffset.g + colorOffset.b) / 3.0; texture.a = 0.0; texture.b = cg; texture.c = co; texture.tex_coord_generation = Reference<Indigo::TexCoordGenerator>(new Indigo::SphericalTexCoordGenerator(Reference<Indigo::Rotation>(new Indigo::MatrixRotation()))); if( mapType == 1 ) { texture.tex_coord_generation = Reference<Indigo::TexCoordGenerator>(new Indigo::SphericalEnvTexCoordGenerator(Reference<Indigo::Rotation>(new Indigo::MatrixRotation()))); } mat->emission = Reference<Indigo::WavelengthDependentParam>(new Indigo::TextureWavelengthDependentParam(0)); mat->textures.push_back(texture); }else{ Indigo::RGBSpectrum *iBgColor = new Indigo::RGBSpectrum(Indigo::Vec3d(bgColor.r,bgColor.g,bgColor.b), 2.2); mat->emission = Reference<Indigo::WavelengthDependentParam>(new Indigo::ConstantWavelengthDependentParam(Reference<Indigo::Spectrum>(iBgColor))); } // Base emission is the emitted spectral radiance. No effect here? double multiplier = (double)getFloatAttr("environmentMapMultiplier", gFn, 1.0) * 1000.0; mat->base_emission = Reference<Indigo::WavelengthDependentParam>(new Indigo::ConstantWavelengthDependentParam(Reference<Indigo::Spectrum>(new Indigo::UniformSpectrum(multiplier)))); background_settings->background_material = mat; sceneRootRef->addChildNode(background_settings); break; } case 2: // sun/sky { // first get the globals node and serach for a directional light connection MObjectArray nodeList; getConnectedInNodes(MString("sunLightConnection"), gFn.object(), nodeList); if( nodeList.length() > 0) { MObject sunObj = nodeList[0]; if(sunObj.hasFn(MFn::kTransform)) { // we suppose what's connected here is a dir light transform MVector lightDir(0,0,1); // default dir light dir MFnDagNode sunDagNode(sunObj); lightDir *= sunDagNode.transformationMatrix() * renderGlobals->globalConversionMatrix; lightDir.normalize(); Indigo::SceneNodeBackgroundSettingsRef background_settings_node(new Indigo::SceneNodeBackgroundSettings()); Reference<Indigo::SunSkyMaterial> sun_sky_mat(new Indigo::SunSkyMaterial()); MString sky_model; int modelId; getEnum("sky_model", gFn, modelId, sky_model); sun_sky_mat->model = sky_model.asChar(); sun_sky_mat->enable_sky = true; getBool("extra_atmospheric", gFn, sun_sky_mat->extra_atmospheric); sun_sky_mat->name = "sunsky"; getUInt("sky_layer", gFn, sun_sky_mat->sky_layer); getUInt("sun_layer", gFn, sun_sky_mat->sun_layer); getDouble(MString("turbidity"), gFn, sun_sky_mat->turbidity); sun_sky_mat->sundir = Indigo::Vec3d(lightDir.x, lightDir.y, lightDir.z); // Direction to sun. background_settings_node->background_material = sun_sky_mat; sceneRootRef->addChildNode(background_settings_node); } } break; } } }