foundation::auto_release_ptr<renderer::MeshObject> createMesh(const MObject& mobject) { MStatus stat = MStatus::kSuccess; MFnMesh meshFn(mobject, &stat); CHECK_MSTATUS(stat); MPointArray points; MFloatVectorArray normals; MFloatArray uArray, vArray; MIntArray triPointIds, triNormalIds, triUvIds, triMatIds, perFaceAssignments; getMeshData(mobject, points, normals, uArray, vArray, triPointIds, triNormalIds, triUvIds, triMatIds, perFaceAssignments); foundation::auto_release_ptr<renderer::MeshObject> mesh( renderer::MeshObjectFactory::create( makeGoodString(meshFn.fullPathName()).asChar(), renderer::ParamArray())); for (unsigned int i = 0; i < points.length(); i++) mesh->push_vertex(mPointToGVector3(points[i])); for (unsigned int i = 0; i < normals.length(); i++) mesh->push_vertex_normal(mPointToGVector3(normals[i])); for (unsigned int i = 0; i < uArray.length(); i++) { mesh->push_tex_coords( renderer::GVector2( static_cast<float>(uArray[i]), static_cast<float>(vArray[i]))); } const unsigned int numTris = triPointIds.length() / 3; for (unsigned int i = 0; i < numTris; i++) { const int perFaceShadingGroup = triMatIds[i]; const int vtxId0 = triPointIds[i * 3 + 0]; const int vtxId1 = triPointIds[i * 3 + 1]; const int vtxId2 = triPointIds[i * 3 + 2]; const int normalId0 = triNormalIds[i * 3 + 0]; const int normalId1 = triNormalIds[i * 3 + 1]; const int normalId2 = triNormalIds[i * 3 + 2]; const int uvId0 = triUvIds[i * 3 + 0]; const int uvId1 = triUvIds[i * 3 + 1]; const int uvId2 = triUvIds[i * 3 + 2]; mesh->push_triangle( renderer::Triangle( vtxId0, vtxId1, vtxId2, normalId0, normalId1, normalId2, uvId0, uvId1, uvId2, perFaceShadingGroup)); } return mesh; }
void MayaObject::initialize() { this->isInstancerObject = false; this->instancerParticleId = -1; this->instanceNumber = 0; this->attributes = nullptr; this->origObject = nullptr; this->shortName = getObjectName(mobject); this->fullName = this->dagPath.fullPathName(); this->fullNiceName = makeGoodString(this->fullName); this->transformMatrices.push_back(this->dagPath.inclusiveMatrix()); this->instanceNumber = dagPath.instanceNumber(); MFnDependencyNode depFn(mobject); this->motionBlurred = true; this->geometryMotionblur = false; bool mb = true; if( getBool(MString("motionBlur"), depFn, mb) ) this->motionBlurred = mb; // cameras have motionBlur attribute but it is set to false by default and it is not accessible via UI // but we want to have a blurred camera by default. if( this->mobject.hasFn(MFn::kCamera)) this->motionBlurred = true; this->perObjectTransformSteps = 1; this->perObjectDeformSteps = 1; this->index = -1; this->shapeConnected = false; this->lightExcludeList = true; // In most cases only a few lights are ignored, so the list is shorter with excluded lights this->shadowExcludeList = true; // in most cases only a few objects ignore shadows, so the list is shorter with ignoring objects this->animated = this->isObjAnimated(); this->shapeConnected = this->isShapeConnected(); this->parent = nullptr; this->visible = true; this->hasInstancerConnection = false; MDagPath dp; dp = dagPath; MFnDagNode dagNode(this->mobject); if (!IsVisible(dagNode) || IsTemplated(dagNode) || !IsInRenderLayer(dp) || !IsPathVisible(dp) || !IsLayerVisible(this->dagPath)) this->visible = false; // get instancer connection MStatus stat; MPlug matrixPlug = depFn.findPlug(MString("matrix"), &stat); if( !stat) Logging::debug(MString("Could not find matrix plug")); else{ MPlugArray outputs; if( matrixPlug.isConnected()) { matrixPlug.connectedTo(outputs, false, true); for( uint i = 0; i < outputs.length(); i++) { MObject otherSide = outputs[i].node(); Logging::debug(MString("matrix is connected to ") + getObjectName(otherSide)); if( otherSide.hasFn(MFn::kInstancer)) { Logging::debug(MString("other side is instancer")); this->hasInstancerConnection = true; } } } } if( this->mobject.hasFn(MFn::kWorld)) { this->shortName = this->fullName = this->fullNiceName = "world"; } }
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 defineMesh(Corona::IGeometryGroup *group, const MObject& meshObject) { MStatus stat = MStatus::kSuccess; bool hasDisplacement = false; Corona::SharedPtr<Corona::Abstract::Map> displacementMap = nullptr; float displacementMin = 0.0f; float displacementMax = 0.01f; MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MPointArray points; MFloatVectorArray normals; MFloatArray uArray, vArray; MIntArray triPointIds, triNormalIds, triUvIds, triMatIds, perFaceAssignments; MObject mo = meshObject; getMeshData(mo, points, normals, uArray, vArray, triPointIds, triNormalIds, triUvIds, triMatIds, perFaceAssignments); Logging::debug(MString("Translating mesh object ") + meshFn.name().asChar()); MString meshFullName = makeGoodString(meshFn.fullPathName()); uint numVertices = points.length(); uint numNormals = normals.length(); uint numUvs = uArray.length(); Corona::TriangleData td; Corona::IGeometryGroup* geom = group; geom->setMapChannelCount(1); uint npts = 0; for (uint vtxId = 0; vtxId < numVertices; vtxId++) { MPoint& p = points[vtxId]; geom->getVertices().push(Corona::Pos(p.x, p.y, p.z)); } for (uint nId = 0; nId < numNormals; nId++) { MFloatVector& n = normals[nId]; geom->getNormals().push(Corona::Dir(n.x, n.y, n.z)); } for (uint tId = 0; tId < numUvs; tId++) { size_t mcl = geom->getMapCoordIndices().size(); geom->getMapCoordIndices().push(mcl); geom->getMapCoords().push(Corona::Pos(uArray[tId], vArray[tId], 0.0f)); } 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]; std::auto_ptr<Corona::TriangleData> trip; if (hasDisplacement) { trip = std::auto_ptr<Corona::TriangleData>(new Corona::DisplacedTriangleData); Corona::DisplacedTriangleData *dtri = (Corona::DisplacedTriangleData *)trip.get(); dtri->displacement.map = displacementMap; dtri->displacement.waterLevel = -Corona::INFINITY; dtri->displacement.min = displacementMin; dtri->displacement.max = displacementMax; } else{ trip = std::auto_ptr<Corona::TriangleData>(new Corona::TriangleData); } trip->v.setSegments(1 - 1); trip->n.setSegments(1 - 1); 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); } }
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); } } } }