Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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";
	}
}
Ejemplo n.º 3
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();
}
Ejemplo n.º 4
0
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);
	}
}
Ejemplo n.º 5
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);			
			}

		}		
	}
}