示例#1
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);			
			}

		}		
	}
}
示例#2
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();
}
示例#3
0
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;
		}
	}
}