Beispiel #1
0
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();
}
Beispiel #2
0
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);			
			}

		}		
	}
}