void getUVFromConnectedTexturePlacementNode(MObject fileTextureNode, float inU, float inV, float& outU, float& outV) { MObject texPlaceObj = getConnectedInNode(fileTextureNode, "uvCoord"); outU = inU; outV = outV; if( texPlaceObj == MObject::kNullObj ) return; double offsetU = 0.0; double offsetV = 0.0; MFnDependencyNode texPlaceNode(texPlaceObj); getDouble(MString("offsetU"), texPlaceNode, offsetU); getDouble(MString("offsetV"), texPlaceNode, offsetV); float repeatU = 1.0f, repeatV = 1.0f, rotateUV = 0.0f; getFloat("repeatU", texPlaceNode, repeatU); getFloat("repeatV", texPlaceNode, repeatV); getFloat("rotateUV", texPlaceNode, rotateUV); MMatrix rotationMatrix; rotationMatrix.setToIdentity(); rotationMatrix[0][0] = cos(rotateUV) * repeatU; rotationMatrix[1][0] = -sin(rotateUV) * repeatU; rotationMatrix[0][1] = sin(rotateUV) * repeatV; rotationMatrix[1][1] = cos(rotateUV) * repeatV; MVector uv(inU - 0.5, inV - 0.5, 0.0); uv = uv * rotationMatrix; uv.x += 0.5; uv.y += 0.5; uv.x *= repeatU; uv.y *= repeatV; uv.x += offsetU; uv.y += offsetV; outU = uv.x; outV = uv.y; }
void CoronaRenderer::defineMaterial(Corona::IInstance* instance, std::shared_ptr<MayaObject> mobj) { std::shared_ptr<mtco_MayaObject> obj = std::static_pointer_cast<mtco_MayaObject>(mobj); getObjectShadingGroups(obj->dagPath, obj->perFaceAssignments, obj->shadingGroups, false); if( obj->shadingGroups.length() > 0) { for (uint sgId = 0; sgId < obj->shadingGroups.length(); sgId++) { MObject shadingGroup = obj->shadingGroups[sgId]; Logging::debug(MString("---------- Check shading group: ") + getObjectName(shadingGroup) + " for existence on object named " + obj->fullName); if (assingExistingMat(shadingGroup, obj)) return; MObject surfaceShader = getConnectedInNode(shadingGroup, "surfaceShader"); // check obj set overrides MObject connectedSet = getConnectedObjSet(obj->dagPath); if (connectedSet != MObject::kNullObj) { MFnDependencyNode setFn(connectedSet); Logging::debug(MString("Found connected object set:") + setFn.name()); MPlug shaderOverride = setFn.findPlug("mtco_mtlOverride"); if (!shaderOverride.isNull()) { MObject connectedObject = getConnectedInNode(shaderOverride); if (connectedObject != MObject::kNullObj) surfaceShader = connectedObject; } } // raytype shader is a special case. Here a material set gets different materials, so I have to call defineCoronaMaterial several times MFnDependencyNode shaderMat(surfaceShader); Corona::SharedPtr<Corona::IMaterial> base = nullptr; Corona::SharedPtr<Corona::IMaterial> reflect = nullptr; Corona::SharedPtr<Corona::IMaterial> refract = nullptr; Corona::SharedPtr<Corona::IMaterial> direct = nullptr; if (shaderMat.typeName() == "CoronaRaytype") { MPlug basePlug = shaderMat.findPlug("base"); MPlug reflectPlug = shaderMat.findPlug("reflect"); MPlug refractPlug = shaderMat.findPlug("refract"); MPlug directPlug = shaderMat.findPlug("direct"); if (basePlug.isConnected()) { MObject inNode = getConnectedInNode(basePlug); base = defineCoronaMaterial(inNode, nullptr); } if (reflectPlug.isConnected()) { MObject inNode = getConnectedInNode(reflectPlug); reflect = defineCoronaMaterial(inNode, nullptr); } if (refractPlug.isConnected()) { MObject inNode = getConnectedInNode(refractPlug); refract = defineCoronaMaterial(inNode, nullptr); } if (directPlug.isConnected()) { MObject inNode = getConnectedInNode(directPlug); direct = defineCoronaMaterial(inNode, nullptr); } } else{ base = defineCoronaMaterial(surfaceShader, obj); } Corona::IMaterialSet ms = Corona::IMaterialSet(base); ms.overrides.direct = direct; ms.overrides.reflect = reflect; ms.overrides.refract = refract; setRenderStats(ms, obj); obj->instance->addMaterial(ms); } } else{ Corona::SharedPtr<Corona::IMaterial> mat = defineCoronaMaterial(MObject::kNullObj, nullptr); Corona::IMaterialSet ms = Corona::IMaterialSet(mat); setRenderStats(ms, obj); obj->instance->addMaterial(ms); } }
MString defineTexture(MFnDependencyNode& shader, MString& attributeName) { boost::shared_ptr<AppleseedRenderer> appleRenderer = boost::static_pointer_cast<AppleseedRenderer>(getWorldPtr()->mRenderer); assert(appleRenderer != 0); renderer::Scene* scene = getSceneFromProject(appleRenderer->getProjectPtr()); foundation::SearchPaths &searchPaths = appleRenderer->getProjectPtr()->search_paths(); MStatus stat; MString textureDefinition(""); MPlug plug = shader.findPlug(attributeName, &stat); if (stat != MStatus::kSuccess) return textureDefinition; if (!plug.isConnected()) return textureDefinition; MObject connectedNode = getConnectedInNode(plug); if (!connectedNode.hasFn(MFn::kFileTexture)) return textureDefinition; MFnDependencyNode fileTextureNode(connectedNode, &stat); MString textureName = fileTextureNode.name() + "_texture"; MString fileTextureName = ""; getString(MString("fileTextureName"), fileTextureNode, fileTextureName); if (!pystring::endswith(fileTextureName.asChar(), ".exr") || (fileTextureName.length() == 0)) { if (fileTextureName.length() == 0) Logging::warning(MString("FileTextureName has no content.")); else Logging::warning(MString("FileTextureName does not have an .exr extension. Other filetypes are not yet supported, sorry.")); return textureDefinition; } removeTextureEntityIfItExists(textureName); MString colorProfile = "srgb"; renderer::ParamArray params; Logging::debug(MString("Now inserting file name: ") + fileTextureName); params.insert("filename", fileTextureName.asChar()); // OpenEXR only for now. The param is called filename but it can be a path params.insert("color_space", colorProfile.asChar()); foundation::auto_release_ptr<renderer::Texture> textureElement( renderer::DiskTexture2dFactory().create( textureName.asChar(), params, searchPaths)); // the project holds a set of search paths to find textures and other assets scene->textures().insert(textureElement); bool alphaIsLuminance = false; getBool(MString("alphaIsLuminance"), fileTextureNode, alphaIsLuminance); renderer::ParamArray tInstParams; tInstParams.insert("addressing_mode", "clamp"); tInstParams.insert("filtering_mode", "bilinear"); if (alphaIsLuminance) tInstParams.insert("alpha_mode", "luminance"); MString textureInstanceName = textureName + "_texInst"; foundation::auto_release_ptr<renderer::TextureInstance> tinst = renderer::TextureInstanceFactory().create( textureInstanceName.asChar(), tInstParams, textureName.asChar()); scene->texture_instances().insert(tinst); return textureInstanceName; }
void CoronaRenderer::defineMesh(std::shared_ptr<MayaObject> mobj) { std::shared_ptr<MayaScene> mayaScene = MayaTo::getWorldPtr()->worldScenePtr; std::shared_ptr<mtco_MayaObject> obj = std::static_pointer_cast<mtco_MayaObject>(mobj); MObject meshObject = obj->mobject; MStatus stat = MStatus::kSuccess; bool hasDisplacement = false; Corona::SharedPtr<Corona::Abstract::Map> displacementMap = nullptr; float displacementMin = 0.0f; float displacementMax = 0.01f; bool displacementAdaptive = false; bool diplacementIsHdr = true; Corona::DisplacementMode displacementMode = Corona::DisplacementMode::DISPLACEMENT_NORMAL; // I do it here for displacement mapping, maybe we should to another place getObjectShadingGroups(obj->dagPath, obj->perFaceAssignments, obj->shadingGroups, true); if( obj->shadingGroups.length() > 0) { MFnDependencyNode shadingGroup(obj->shadingGroups[0]); MString sgn = shadingGroup.name(); MObject displacementObj = getConnectedInNode(obj->shadingGroups[0], "displacementShader"); MString doo = getObjectName(displacementObj); if( (displacementObj != MObject::kNullObj) && (displacementObj.hasFn(MFn::kDisplacementShader))) { MObject displacementMapObj = getConnectedInNode(displacementObj, "displacement"); MObject vectorDisplacementMapObj = getConnectedInNode(displacementObj, "vectorDisplacement"); if( (displacementMapObj != MObject::kNullObj) && (displacementMapObj.hasFn(MFn::kFileTexture))) { MFnDependencyNode displacmentMapNode(displacementObj); int dispMode = getEnumInt("displacementMode", displacmentMapNode); if (dispMode == 1) displacementMode = Corona::DisplacementMode::DISPLACEMENT_VECTOR_TANGENT; if (dispMode > 1) displacementMode = Corona::DisplacementMode::DISPLACEMENT_VECTOR_OBJECT; displacementAdaptive = getBoolAttr("mtco_displacementAdaptive", displacmentMapNode, false); getFloat("mtco_displacementMin", displacmentMapNode, displacementMin); getFloat("mtco_displacementMax", displacmentMapNode, displacementMax); MObject fileTextureObject = getConnectedInNode(displacementObj, "displacement"); MString fileTexturePath = getConnectedFileTexturePath(MString("displacement"), displacmentMapNode); int vectorEncoding = getEnumInt("vectorEncoding", displacmentMapNode); if (vectorEncoding == 0) // absolute, no negative values diplacementIsHdr = false; if( fileTexturePath != "") { if( !textureFileSupported(fileTexturePath)) { Logging::error(MString("File texture extension is not supported: ") + fileTexturePath); }else{ MObject nullObj; mtco_MapLoader loader(fileTextureObject); displacementMap = loader.loadBitmap(""); hasDisplacement = true; } } } } } MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MPointArray points; MFloatVectorArray normals; MFloatArray uArray, vArray; MIntArray triPointIds, triNormalIds, triUvIds, triMatIds; Logging::debug("defineMesh pre getMeshData"); obj->getMeshData(points, normals, uArray, vArray, triPointIds, triNormalIds, triUvIds, triMatIds); int numSteps = (int)obj->meshDataList.size(); uint numVertices = points.length(); uint numNormals = normals.length(); uint numUvs = uArray.length(); MString meshFullName = makeGoodString(meshFn.fullPathName()); Corona::TriangleData td; Corona::IGeometryGroup* geom = nullptr; geom = this->context.scene->addGeomGroup(); geom->setMapChannelCount(1); // to capture the vertex and normal positions, we capture the data during the motion steps // and save them in a an std::vector. The uv's do not change, so we only sample them once. // we always have at least one motionstep even if we have no motionblur uint npts = 0; for( int mbStep = 0; mbStep < numSteps; mbStep++) { MeshData& md = obj->meshDataList[mbStep]; if (md.points.length() != numVertices) { Logging::debug(MString("Error there is a mismatch between point data length and num vertices.")); numSteps = 1; return; } if( mbStep > 0) { uint npts1 = md.points.length(); if (npts1 != obj->meshDataList[0].points.length()) { Logging::debug(MString("Error there is a mismatch between point data length between mb steps.")); numSteps = 1; break; } } npts = md.points.length(); for( uint vtxId = 0; vtxId < md.points.length(); vtxId++) { MPoint& p = md.points[vtxId]; geom->getVertices().push(Corona::Pos(p.x,p.y,p.z)); } for (uint nId = 0; nId < md.normals.length(); nId++) { MFloatVector& n = md.normals[nId]; geom->getNormals().push(Corona::Dir(n.x, n.y, n.z)); } } for( uint tId = 0; tId < uArray.length(); tId++) { size_t mcl = geom->getMapCoordIndices().size(); geom->getMapCoordIndices().push(mcl); geom->getMapCoords().push(Corona::Pos(uArray[tId], vArray[tId], 0.0f)); } obj->geom = geom; int numTris = triPointIds.length() / 3; for (uint triId = 0; triId < numTris; triId++) { uint index = triId * 3; int perFaceShadingGroup = triMatIds[triId]; int vtxId0 = triPointIds[index]; int vtxId1 = triPointIds[index + 1]; int vtxId2 = triPointIds[index + 2]; int normalId0 = triNormalIds[index]; int normalId1 = triNormalIds[index + 1]; int normalId2 = triNormalIds[index + 2]; int uvId0 = triUvIds[index]; int uvId1 = triUvIds[index + 1]; int uvId2 = triUvIds[index + 2]; if ((vtxId0 >= npts) || (vtxId1 >= npts) || (vtxId2 >= npts)) Logging::error(MString("Index > npts!!! -- Obj: ") + obj->shortName); std::auto_ptr<Corona::TriangleData> trip; if (hasDisplacement) { std::auto_ptr<Corona::DisplacedTriangleData> dtrip = std::auto_ptr<Corona::DisplacedTriangleData>(new Corona::DisplacedTriangleData); dtrip->displacement.mode = displacementMode; dtrip->displacement.isHdr = diplacementIsHdr; dtrip->displacement.mapChannel = 0; dtrip->displacement.map = displacementMap; dtrip->displacement.waterLevel = -Corona::INFINITY; dtrip->displacement.min = displacementMin; dtrip->displacement.max = displacementMax; dtrip->displacement.adaptive = displacementAdaptive; trip = dtrip; } else{ trip = std::auto_ptr<Corona::TriangleData>(new Corona::TriangleData); } trip->v.setSegments(1 - 1); // fixme for deformation motionblur trip->n.setSegments(1 - 1); // fixme for deformation motionblur for (int stepId = 0; stepId < 1; stepId++) { trip->v[stepId][0] = vtxId0 + numVertices * stepId; trip->v[stepId][1] = vtxId1 + numVertices * stepId; trip->v[stepId][2] = vtxId2 + numVertices * stepId; trip->n[stepId][0] = normalId0 + numNormals * stepId; trip->n[stepId][1] = normalId1 + numNormals * stepId; trip->n[stepId][2] = normalId2 + numNormals * stepId; } if (numUvs > 0) { trip->t[0] = uvId0; trip->t[1] = uvId1; trip->t[2] = uvId2; } trip->materialId = perFaceShadingGroup; trip->edgeVis[0] = trip->edgeVis[1] = trip->edgeVis[2] = true; geom->addPrimitive(*trip); } //Logging::debug("}"); obj->perFaceAssignments.clear(); obj->meshDataList.clear(); }
void CoronaRenderer::updateLight(std::shared_ptr<MayaObject> mobj) { std::shared_ptr<mtco_MayaObject> obj(std::static_pointer_cast<mtco_MayaObject>(mobj)); if (obj->lightShader != nullptr) { if (this->context.scene->hasLightShader(obj->lightShader)) this->context.scene->deleteLightShader(obj->lightShader); } if (obj->removed) return; if (MayaTo::getWorldPtr()->renderType == MayaTo::MayaToWorld::WorldRenderType::IPRRENDER) { obj->transformMatrices.clear(); obj->transformMatrices.push_back(obj->dagPath.inclusiveMatrix()); } MFnDependencyNode rGlNode(getRenderGlobalsNode()); MObject coronaGlobals = getRenderGlobalsNode(); std::shared_ptr<RenderGlobals> renderGlobals = MayaTo::getWorldPtr()->worldRenderGlobalsPtr; std::shared_ptr<MayaScene> mayaScene = MayaTo::getWorldPtr()->worldScenePtr; MObjectArray nodeList; MStatus stat; MFnDependencyNode glFn(getRenderGlobalsNode()); Corona::Rgb bgRgb = toCorona(getColorAttr("bgColor", glFn)); int bgType = getEnumInt("bgType", glFn); MayaObject *sunLight = nullptr; 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] * 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 / renderGlobals->scaleFactor; pl->lightColor = Corona::Rgb(col.r, col.g, col.b); pl->lightIntensity = intensity; getEnum(MString("decayRate"), depFn, pl->decayType); pl->lightRadius = getFloatAttr("lightRadius", depFn, 0.0) * renderGlobals->scaleFactor; pl->doShadows = getBoolAttr("useRayTraceShadows", depFn, true); col = getColorAttr("shadowColor", depFn); pl->shadowColor = Corona::Rgb(col.r, col.g, col.b); for (auto excludedObj : obj->excludedObjects) { pl->excludeList.nodes.push(excludedObj.get()); } this->context.scene->addLightShader(pl); obj->lightShader = 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] * renderGlobals->globalConversionMatrix; lightDir *= obj->transformMatrices[0] * 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 / renderGlobals->scaleFactor; getEnum(MString("decayRate"), depFn, sl->decayType); getFloat("coneAngle", depFn, sl->angle); getFloat("penumbraAngle", depFn, sl->penumbraAngle); getFloat("dropoff", depFn, sl->dropoff); sl->lightRadius = getFloatAttr("lightRadius", depFn, 0.0) * renderGlobals->scaleFactor; sl->doShadows = getBoolAttr("useRayTraceShadows", depFn, true); col = getColorAttr("shadowColor", depFn); sl->shadowColor = Corona::Rgb(col.r, col.g, col.b); for (auto excludedObj : obj->excludedObjects) { sl->excludeList.nodes.push(excludedObj.get()); } Corona::AffineTm tm; setTransformationMatrix(sl->lightWorldInverseMatrix, m); ShadingNetwork network(obj->mobject); sl->lightColorMap = defineAttribute(MString("color"), depFn, network, oslRenderer); this->context.scene->addLightShader(sl); obj->lightShader = sl; } if (obj->mobject.hasFn(MFn::kDirectionalLight)) { if (getBoolAttr("mtco_useAsSun", depFn, false)) { if (sunLight != nullptr) { Logging::error(MString("A sun light is already defined, ignoring ") + obj->shortName); return; } sunLight = obj.get(); MVector lightDir(0, 0, 1); // default dir light dir lightDir *= obj->transformMatrices[0]; lightDir *= renderGlobals->globalConversionMatrix; lightDir.normalize(); MColor sunColor(1); MFnDependencyNode sunNode(obj->mobject); getColor("color", sunNode, sunColor); sunColor *= getFloatAttr("intensity", sunNode, 1.0f); //float colorMultiplier colorMultiplier = getFloatAttr("mtco_sun_multiplier", sunNode, 1.0f); const float intensityFactor = (1.f - cos(Corona::SUN_PROJECTED_HALF_ANGLE)) / (1.f - cos(getFloatAttr("sunSizeMulti", rGlNode, 1.0f) * Corona::SUN_PROJECTED_HALF_ANGLE)); sunColor *= intensityFactor * 1.0;// 2000000; Corona::Sun sun; Corona::ColorOrMap bgCoMap = this->context.scene->getBackground(); SkyMap *sky = dynamic_cast<SkyMap *>(bgCoMap.getMap()); Corona::Rgb avgColor(1, 1, 1); if (sky != nullptr) { avgColor = sky->sc(); } Corona::Rgb sColor(sunColor.r, sunColor.g, sunColor.b); sun.color = sColor * avgColor; 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 = getFloatAttr("sunSizeMulti", rGlNode, 1.0); this->context.scene->getSun() = sun; if (sky != nullptr) { sky->initSky(); this->context.scene->setBackground(bgCoMap); avgColor = sky->sc(); this->context.scene->getSun().color = sColor * avgColor; } } else{ MVector lightDir(0, 0, -1); MVector lightDirTangent(1, 0, 0); MVector lightDirBiTangent(0, 1, 0); MColor col; getColor("color", depFn, col); float intensity = 1.0f; getFloat("intensity", depFn, intensity); MMatrix m = obj->transformMatrices[0] * renderGlobals->globalConversionMatrix; lightDir *= m; lightDirTangent *= m; lightDirBiTangent *= 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); dl->LT = Corona::Dir(lightDirTangent.x, lightDirTangent.y, lightDirTangent.z); dl->LBT = Corona::Dir(lightDirBiTangent.x, lightDirBiTangent.y, lightDirBiTangent.z); dl->lightAngle = getFloatAttr("lightAngle", depFn, 0.0); dl->doShadows = getBoolAttr("useRayTraceShadows", depFn, true); col = getColorAttr("shadowColor", depFn); dl->shadowColor = Corona::Rgb(col.r, col.g, col.b); for (auto excludedObj : obj->excludedObjects) { dl->excludeList.nodes.push(excludedObj.get()); } this->context.scene->addLightShader(dl); obj->lightShader = dl; } } if (obj->mobject.hasFn(MFn::kAreaLight)) { MMatrix m = obj->transformMatrices[0] * renderGlobals->globalConversionMatrix; if ( obj->geom == nullptr) obj->geom = defineStdPlane(); obj->geom->deleteAllInstances(); Corona::AnimatedAffineTm atm; this->setAnimatedTransformationMatrix(atm, obj); obj->instance = obj->geom->addInstance(atm, nullptr, nullptr); if (getBoolAttr("mtco_envPortal", depFn, false)) { Corona::EnviroPortalMtlData data; Corona::SharedPtr<Corona::IMaterial> mat = data.createMaterial(); Corona::IMaterialSet ms = Corona::IMaterialSet(mat); obj->instance->addMaterial(ms); } else{ Corona::NativeMtlData data; MColor lightColor = getColorAttr("color", depFn); float intensity = getFloatAttr("intensity", depFn, 1.0f); lightColor *= intensity; Corona::ColorOrMap com; // experimental direct corona texture if (getBoolAttr("mtco_noOSL", depFn, false)) { MObject fileNode = getConnectedInNode(obj->mobject, "color"); if ((fileNode != MObject::kNullObj) && (fileNode.hasFn(MFn::kFileTexture))) { MFnDependencyNode fileDep(fileNode); mtco_MapLoader loader(fileNode); Corona::SharedPtr<Corona::Abstract::Map> texmap = loader.loadBitmap(""); com = Corona::ColorOrMap(bgRgb, texmap); } } else { com = defineAttribute(MString("color"), obj->mobject, oslRenderer); OSLMap *oslmap = (OSLMap *)com.getMap(); if (oslmap != nullptr) { oslmap->multiplier = intensity; } else{ Corona::Rgb col = com.getConstantColor() * intensity; com.setColor(col); } } data.emission.color = com; data.castsShadows = getBoolAttr("mtco_castShadows", depFn, false); for (auto excludedObj : obj->excludedObjects) { data.emission.excluded.nodes.push(excludedObj.get()); } data.emission.disableSampling = false; data.emission.useTwoSidedEmission = getBoolAttr("mtco_doubleSided", depFn, false); Corona::SharedPtr<Corona::IMaterial> mat = data.createMaterial(); Corona::IMaterialSet ms = Corona::IMaterialSet(mat); ms.visibility.direct = getBoolAttr("mtco_areaVisible", depFn, true); ms.visibility.reflect = getBoolAttr("mtco_visibleInReflection", depFn, true); ms.visibility.refract = getBoolAttr("mtco_visibleInRefraction", depFn, true); obj->instance->addMaterial(ms); } } }
void CoronaRenderer::defineCamera() { MPoint rot, pos, scale; for(int objId = 0; objId < this->mtco_scene->camList.size(); objId++) { mtco_MayaObject *cam = (mtco_MayaObject *)this->mtco_scene->camList[objId]; if( !this->mtco_scene->isCameraRenderable(cam->mobject) && (!(cam->dagPath == this->mtco_scene->uiCamera))) { continue; } logger.debug(MString("using camera ") + cam->shortName); MFnCamera camera(cam->mobject); MPoint pos, rot, scale; MMatrix camMatrix = cam->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; getMatrixComponents(camMatrix, pos, rot, scale); Corona::Pos cpos(pos.x, pos.y, pos.z); float focusDistance = 0.0; float fStop = 0.0; float focalLength = 35.0f; bool dof; float horizontalFilmAperture, verticalFilmAperture; float coi = 100.0f; getFloat(MString("horizontalFilmAperture"), camera, horizontalFilmAperture); getFloat(MString("verticalFilmAperture"), camera, verticalFilmAperture); getFloat(MString("focalLength"), camera, focalLength); getBool(MString("depthOfField"), camera, dof); getFloat(MString("focusDistance"), camera, focusDistance); getFloat(MString("fStop"), camera, fStop); getFloat(MString("centerOfInterest"), camera, coi); focusDistance *= this->mtco_renderGlobals->scaleFactor; MPoint coiBase(0,0,-coi); MPoint coiTransform = coiBase * camMatrix; //logger.debug(MString("Center of interest: ") + coi + " transformed " + coiTransform.x + " " + coiTransform.y + " " + coiTransform.z); Corona::Pos center(coiTransform.x, coiTransform.y, coiTransform.z); float fov = 2.0 * atan((horizontalFilmAperture * 0.5f) / (focalLength * 0.03937)); float fovDeg = fov * 57.29578; Corona::AnimatedFloat fieldOfView(fov); //logger.debug(MString("fov ") + fov + " deg: " + fovDeg); //Corona::AnimatedFloat fieldOfView(Corona::DEG_TO_RAD(45.f)); Corona::CameraData cameraData; //cameraData.type cameraData.createPerspective(Corona::AnimatedPos(cpos), Corona::AnimatedPos(center), Corona::AnimatedDir(Corona::Dir::UNIT_Z), fieldOfView); Corona::AnimatedFloat focalDist(focusDistance); cameraData.perspective.focalDist = focalDist; cameraData.perspective.fStop = fStop; cameraData.perspective.filmWidth = this->mtco_renderGlobals->toMillimeters(horizontalFilmAperture * 2.54f * 10.0f); //film width in mm if( dof && this->mtco_renderGlobals->doDof) cameraData.perspective.useDof = true; if (getBoolAttr("mtco_useBokeh", camera, false)) { cameraData.perspective.bokeh.use = true; cameraData.perspective.bokeh.blades = getIntAttr("mtco_blades", camera, 6); cameraData.perspective.bokeh.bladesRotation = getIntAttr("mtco_bladeRotation", camera, 0.0); MPlug bokehBitMapPlug = camera.findPlug("mtco_bokehBitmap"); if (!bokehBitMapPlug.isNull()) { if (bokehBitMapPlug.isConnected()) { MObject bitmapNode = getConnectedInNode(bokehBitMapPlug); if (bitmapNode.hasFn(MFn::kFileTexture)) { MFnDependencyNode bitMapFn(bitmapNode); MPlug texNamePlug = bitMapFn.findPlug("fileTextureName"); if (!texNamePlug.isNull()) { MString fileName = texNamePlug.asString(); logger.debug(MString("Found bokeh bitmap file: ") + fileName); Corona::Bitmap<Corona::Rgb> bokehBitmap; Corona::loadImage(fileName.asChar(), bokehBitmap); cameraData.perspective.bokeh.customShape = bokehBitmap; } } } } } this->context.scene->getCamera() = cameraData; } }
void CoronaRenderer::defineMesh(mtco_MayaObject *obj) { MObject meshObject = obj->mobject; MStatus stat = MStatus::kSuccess; bool hasDisplacement = false; Corona::Abstract::Map *displacementMap = NULL; float displacementMin = 0.0f; float displacementMax = 0.01f; // I do it here for displacement mapping, maybe we should to another place getObjectShadingGroups(obj->dagPath, obj->perFaceAssignments, obj->shadingGroups); if( obj->shadingGroups.length() > 0) { MFnDependencyNode shadingGroup(obj->shadingGroups[0]); MString sgn = shadingGroup.name(); MObject displacementObj = getConnectedInNode(obj->shadingGroups[0], "displacementShader"); MString doo = getObjectName(displacementObj); if( (displacementObj != MObject::kNullObj) && (displacementObj.hasFn(MFn::kDisplacementShader))) { MObject displacementMapObj = getConnectedInNode(displacementObj, "displacement"); if( (displacementMapObj != MObject::kNullObj) && (displacementMapObj.hasFn(MFn::kFileTexture))) { MFnDependencyNode displacmentMapNode(displacementObj); getFloat("mtco_displacementMin", displacmentMapNode, displacementMin); getFloat("mtco_displacementMax", displacmentMapNode, displacementMax); MString fileTexturePath = getConnectedFileTexturePath(MString("displacement"), displacmentMapNode); if( fileTexturePath != "") { MapLoader loader; displacementMap = loader.loadBitmap(fileTexturePath.asChar()); hasDisplacement = true; } } } } MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MItMeshPolygon faceIt(meshObject, &stat); CHECK_MSTATUS(stat); MPointArray points; meshFn.getPoints(points); MFloatVectorArray normals; meshFn.getNormals( normals, MSpace::kWorld ); MFloatArray uArray, vArray; meshFn.getUVs(uArray, vArray); //logger.debug(MString("Translating mesh object ") + meshFn.name().asChar()); MString meshFullName = makeGoodString(meshFn.fullPathName()); Corona::TriangleData td; Corona::IGeometryGroup* geom = NULL; geom = this->context.scene->addGeomGroup(); obj->geom = geom; for( uint vtxId = 0; vtxId < points.length(); vtxId++) { geom->getVertices().push(Corona::Pos(points[vtxId].x,points[vtxId].y,points[vtxId].z)); } for( uint nId = 0; nId < normals.length(); nId++) { geom->getNormals().push(Corona::Dir(normals[nId].x,normals[nId].y,normals[nId].z)); } for( uint tId = 0; tId < uArray.length(); tId++) { geom->getMapCoords().push(Corona::Pos(uArray[tId],vArray[tId],0.0f)); geom->getMapCoordIndices().push(geom->getMapCoordIndices().size()); } MPointArray triPoints; MIntArray triVtxIds; MIntArray faceVtxIds; MIntArray faceNormalIds; for(faceIt.reset(); !faceIt.isDone(); faceIt.next()) { int faceId = faceIt.index(); int numTris; faceIt.numTriangles(numTris); faceIt.getVertices(faceVtxIds); MIntArray faceUVIndices; faceNormalIds.clear(); for( uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++) { faceNormalIds.append(faceIt.normalIndex(vtxId)); int uvIndex; faceIt.getUVIndex(vtxId, uvIndex); faceUVIndices.append(uvIndex); } for( int triId = 0; triId < numTris; triId++) { int faceRelIds[3]; faceIt.getTriangle(triId, triPoints, triVtxIds); for( uint triVtxId = 0; triVtxId < 3; triVtxId++) { for(uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++) { if( faceVtxIds[faceVtxId] == triVtxIds[triVtxId]) { faceRelIds[triVtxId] = faceVtxId; } } } uint vtxId0 = faceVtxIds[faceRelIds[0]]; uint vtxId1 = faceVtxIds[faceRelIds[1]]; uint vtxId2 = faceVtxIds[faceRelIds[2]]; uint normalId0 = faceNormalIds[faceRelIds[0]]; uint normalId1 = faceNormalIds[faceRelIds[1]]; uint normalId2 = faceNormalIds[faceRelIds[2]]; uint uvId0 = faceUVIndices[faceRelIds[0]]; uint uvId1 = faceUVIndices[faceRelIds[1]]; uint uvId2 = faceUVIndices[faceRelIds[2]]; if( hasDisplacement ) { Corona::DisplacedTriangleData tri; tri.displacement.map = displacementMap; MPoint p0 = points[vtxId0]; MPoint p1 = points[vtxId1]; MPoint p2 = points[vtxId2]; tri.v[0] = Corona::AnimatedPos(Corona::Pos(p0.x, p0.y, p0.z)); tri.v[1] = Corona::AnimatedPos(Corona::Pos(p1.x, p1.y, p1.z)); tri.v[2] = Corona::AnimatedPos(Corona::Pos(p2.x, p2.y, p2.z)); MVector n0 = normals[normalId0]; MVector n1 = normals[normalId1]; MVector n2 = normals[normalId2]; Corona::Dir dir0(n0.x, n0.y, n0.z); Corona::Dir dir1(n1.x, n1.y, n1.z); Corona::Dir dir2(n2.x, n2.y, n2.z); tri.n[0] = Corona::AnimatedDir(dir0); tri.n[1] = Corona::AnimatedDir(dir1); tri.n[2] = Corona::AnimatedDir(dir2); Corona::Pos uv0(uArray[uvId0],vArray[uvId0],0.0); Corona::Pos uv1(uArray[uvId1],vArray[uvId1],0.0); Corona::Pos uv2(uArray[uvId2],vArray[uvId2],0.0); Corona::StaticArray<Corona::Pos, 3> uvp; uvp[0] = uv0; uvp[1] = uv1; uvp[2] = uv2; tri.t.push(uvp); tri.materialId = 0; tri.displacement.min = displacementMin; tri.displacement.max = displacementMax; geom->addPrimitive(tri); }else{ Corona::TriangleData tri; tri.v = Corona::AnimatedPosI3(vtxId0, vtxId1, vtxId2); tri.n = Corona::AnimatedDirI3(normalId0, normalId1, normalId2); tri.t[0] = uvId0; tri.t[1] = uvId1; tri.t[2] = uvId2; tri.materialId = 0; geom->addPrimitive(tri); } } } }