Ejemplo n.º 1
0
Mesh*
TriObject::GetRenderMesh(TimeValue t, INode *inode, View &view, BOOL& needDelete)
{
	if (mDisableDisplacement || !(view.flags & RENDER_MESH_DISPLACEMENT_MAP)) {
		needDelete = FALSE;
		return &mesh;
	}
	// need to check the mesh and see if any face has a matId the requires displacment mapping
	BOOL needDisp = FALSE;

	// Get the material
	Mtl* pMtl = inode ? inode->GetMtl() : NULL;

	if (pMtl) {
		// does the mesh as a whole need it
		if (pMtl->Requirements(mesh.mtlIndex)&MTLREQ_DISPLACEMAP)
			needDisp = TRUE;

		if (!needDisp) {
			for (int f = 0; f < mesh.numFaces; f++) {
				if (pMtl->Requirements(mesh.getFaceMtlIndex(f))&MTLREQ_DISPLACEMAP) {
					needDisp = TRUE;
					break;
				}
			}
		}

		if (needDisp) {
            if (mesh.getNumFaces() == 0)
                return &mesh;

			Matrix3 otm;
			if (inode)
				otm = inode->GetObjectTM(t);
			else
				otm.IdentityMatrix();
			GetGTessFunction();
			if (mSubDivideDisplacement && psGTessFunc) {
				// if we have a material that does displacement mapping and if we can do it
				Mesh *pMesh = new Mesh();
				needDelete = TRUE;
				(*psGTessFunc)((void *)&mesh, MAX_MESH, &otm, pMesh, NULL,
								&mDispApprox, &view, pMtl, FALSE, mSplitMesh);
				needDelete = TRUE;
				return pMesh;
			} else {
				Mesh *pMesh = new Mesh(mesh);
				needDelete = TRUE;

                BOOL hasUVs = pMesh->tvFace != NULL;
				pMesh->buildRenderNormals();

				// now displace the verts
				BitArray vertsSet;
				vertsSet.SetSize(pMesh->numVerts);

				for (int f = 0; f < pMesh->numFaces; f++) {
					Face *pFace = &pMesh->faces[f];
					TVFace *pTVFace = &pMesh->tvFace[f];
					int matid = pFace->getMatID();
					for (int v = 0; v < 3; v++) {
						int vidx = pFace->v[v];
						if (vertsSet[vidx])
							continue; // displace only once
						Point3 norm = pMesh->getNormal(vidx);
						norm.Normalize();
						Point3& vert = pMesh->getVert(vidx);

						UVVert uvvert;
                        if (hasUVs)
                            uvvert = pMesh->getTVert(pTVFace->t[v]);
                        else {
                            uvvert.x = 0.0;
                            uvvert.y = 0.0;
                        }

						pMesh->buildBoundingBox();
						Box3 bbox = pMesh->getBoundingBox();
						float dispScale = Length(bbox.pmax - bbox.pmin)/10.0f;

						float disp = GetDisp(pMtl, pMesh, f, pFace->getMatID(), vert, uvvert.x, uvvert.y, otm) * dispScale;
						vert += (norm * disp);
						vertsSet.Set(vidx);
					}
				}
				return pMesh;
			}
		}
	}

	needDelete = FALSE;
	return &mesh;
}
Ejemplo n.º 2
0
void XsiExp::ExportMesh( INode * node, TimeValue t, int indentLevel)
{
	ObjectState os = node->EvalWorldState(t);
	if (!os.obj || os.obj->SuperClassID() != GEOMOBJECT_CLASS_ID)
  {
		return; // Safety net. This shouldn't happen.
	}
	BOOL needDel;
	TriObject * tri = GetTriObjectFromNode(node, t, needDel);
	if (!tri)
  {
    // no tri object
		return;
	}
  // prepare mesh
  Mesh * mesh = &tri->GetMesh();
  mesh->buildNormals();

  // object offset matrix; apply to verts
  // swap y and z; max to soft correction
  Matrix3 matrix(1);
  //  translate
  matrix.PreTranslate( Point3( node->GetObjOffsetPos().x, node->GetObjOffsetPos().z, -node->GetObjOffsetPos().y));

  // rotate
  AngAxis aa( node->GetObjOffsetRot());
  float temp = aa.axis.z;
  aa.axis.z = -aa.axis.y;
  aa.axis.y = temp;
  PreRotateMatrix(matrix, Quat( aa));

  // scale
  ScaleValue scale = node->GetObjOffsetScale();
  aa.Set( scale.q);
  temp = aa.axis.z;
  aa.axis.z = -aa.axis.y;
  aa.axis.y = temp;
  scale.q.Set( aa);
  temp = scale.s.z;
  scale.s.z = scale.s.y;
  scale.s.y = temp;
  ApplyScaling(matrix, scale);

  // apply root transform
  matrix = matrix * topMatrix;
  // only rotation for normals
  AffineParts ap;
  Matrix3 rotMatrix(1);
  decomp_affine( matrix, &ap);
  PreRotateMatrix( rotMatrix, ap.q);

  // set winding order
	int vx1 = 0, vx2 = 1, vx3 = 2;
	if (TMNegParity( node->GetNodeTM(GetStaticFrame())) != TMNegParity( matrix) )
  {
    // negative scaling; invert winding order and normal rotation
		vx1 = 2;	vx2 = 1;	vx3 = 0;
    rotMatrix = rotMatrix * Matrix3( Point3(-1,0,0), Point3(0,-1,0), Point3(0,0,-1), Point3(0,0,0));
	}

  // header
	TSTR indent = GetIndent(indentLevel+1);
	fprintf(pStream, "%s%s %s {\n",indent.data(), "Mesh", FixupName(node->GetName()));

  // write number of verts
  int numLoop = mesh->getNumVerts();
	fprintf(pStream, "%s\t%d;\n",indent.data(), numLoop);

  // write verts
	for (int i = 0; i < numLoop; i++)
  {
		Point3 v = mesh->verts[i];
		float temp = v.z;
    v.z = -v.y;
    v.y = temp;
		v = matrix * v;
		fprintf(pStream, "%s\t%.6f;%.6f;%.6f;%s\n", indent.data(), v.x, v.y, v.z, 
      i == numLoop - 1 ? ";\n" : ",");
	}
  // write number of faces
  numLoop = mesh->getNumFaces();
  fprintf(pStream, "%s\t%d;\n", indent.data(), numLoop);

  // write faces
	for (i = 0; i < numLoop; i++)
  {
		fprintf(pStream, "%s\t3;%d,%d,%d;%s\n",
			indent.data(),
			mesh->faces[i].v[vx1],
			mesh->faces[i].v[vx2],
			mesh->faces[i].v[vx3], 
      i == numLoop - 1 ? ";\n" : ",");
	}

  // face materials
	Mtl * nodeMtl = node->GetMtl();
  int numMtls = !nodeMtl || !nodeMtl->NumSubMtls() ? 1 : nodeMtl->NumSubMtls();

	// write face material list header	
	fprintf(pStream, "%s\tMeshMaterialList {\n", indent.data());
  // write number of materials
	fprintf(pStream, "%s\t\t%d;\n", indent.data(), numMtls);
  // write number of faces
  fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop);

  // write face material indices (1 for each face)
  for (i = 0; i < numLoop; i++)
  {
    int index = numMtls ? mesh->faces[i].getMatID() % numMtls : 0;
		fprintf(pStream,"%s\t\t%d%s\n",
			indent.data(),
      index,
      i == numLoop - 1 ? ";\n" : ",");
	}

  // write the materials
  ExportMaterial( node, indentLevel+2);

  // verts close brace
	fprintf(pStream, "%s\t}\n\n",indent.data());

  // write normals header
	fprintf(pStream, "%s\t%s {\n", indent.data(), "SI_MeshNormals");
	// write number of normals
  fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop * 3);

  // write normals (3 for each face)
	for (i = 0; i < numLoop; i++)
  {
		Face * f = &mesh->faces[i];
		int vert = f->getVert(vx1);

		Point3 vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert));
    float temp = vn.z;
    vn.z = -vn.y;
    vn.y = temp;
		vn = rotMatrix * vn;
		fprintf(pStream,"%s\t\t%.6f;%.6f;%.6f;,\n", indent.data(), vn.x, vn.y, vn.z);

		vert = f->getVert(vx2);
		vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert));
    temp = vn.z;
    vn.z = -vn.y;
    vn.y = temp;
		vn = rotMatrix * vn;
		fprintf(pStream,"%s\t\t%.6f;%.6f;%.6f;,\n", indent.data(), vn.x, vn.y, vn.z);
    
		vert = f->getVert(vx3);
		vn = GetVertexNormal(mesh, i, mesh->getRVertPtr(vert));
    temp = vn.z;
    vn.z = -vn.y;
    vn.y = temp;
		vn = rotMatrix * vn;
		fprintf(pStream,"%s\t\t%.6f;%.6f;%.6f;%s\n", indent.data(), vn.x, vn.y, vn.z,
      i == numLoop - 1 ? ";\n" : ",");
	}
  // write number of faces
  fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop);

  // write faces
  for (i = 0; i < numLoop; i++)
  {
	  fprintf(pStream, "%s\t\t%d;3;%d,%d,%d;%s\n",
		  indent.data(),
      i,
      i * 3 + vx1, i * 3 + vx2, i * 3 + vx3,
      i == numLoop - 1 ? ";\n" : ",");
  }
  // normals close brace
	fprintf(pStream, "%s\t}\n\n",indent.data());

	// texcoords
	if (nodeMtl && mesh && (nodeMtl->Requirements(-1) & MTLREQ_FACEMAP))
  {
    // facemapping
    numLoop = mesh->getNumFaces() * 3;

    // write texture coords header
    fprintf(pStream, "%s\tSI_MeshTextureCoords {\n", indent.data());
    // write number of texture coords
    fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop);

    // write texture coords
	  for (int i = 0; i < numLoop; i++)
    {
		  Point3 tv[3];
		  Face * f = &mesh->faces[i];
		  make_face_uv( f, tv);
		  fprintf(pStream, "%s\t\t%.6f;%.6f;,\n",  indent.data(), tv[0].x, tv[0].y);
		  fprintf(pStream, "%s\t\t%.6f;%.6f;,\n",  indent.data(), tv[1].x, tv[1].y);
		  fprintf(pStream, "%s\t\t%.6f;%.6f;%s\n", indent.data(), tv[2].x, tv[2].y,
        i == numLoop - 1 ? ";\n" : ",");
	  }
    // write number of faces
    numLoop = mesh->getNumFaces();
	  fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop);

    // write faces
	  for (i = 0; i < numLoop; i++)
    {
		  fprintf(pStream,"%s\t\t%d;3;%d,%d,%d;%s\n",
			  indent.data(),
			  i,
			  mesh->tvFace[i].t[vx1],
			  mesh->tvFace[i].t[vx2],
			  mesh->tvFace[i].t[vx3],
        i == numLoop - 1 ? ";\n" : ",");
	  }
    // texture coords close brace
	  fprintf(pStream, "%s\t}\n\n", indent.data());
  }
  else
  {
		numLoop = mesh->getNumTVerts();

		if (numLoop)
    {
      // write texture coords header
  		fprintf(pStream, "%s\tSI_MeshTextureCoords {\n", indent.data());
      // write number of texture coords
  		fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop);

      // write texture coords
			for (i = 0; i < numLoop; i++)
      {
				UVVert tv = mesh->tVerts[i];
				fprintf(pStream, "%s\t\t%.6f;%.6f;%s\n", indent.data(), tv.x, tv.y,
        i == numLoop - 1 ? ";\n" : ",");
			}
      // write number of faces
      numLoop = mesh->getNumFaces();
			fprintf(pStream, "%s\t\t%d;\n", indent.data(), numLoop);

      // write faces
			for (i = 0; i < numLoop; i++)
      {
				fprintf(pStream,"%s\t\t%d;3;%d,%d,%d;%s\n",
					indent.data(),
					i,
					mesh->tvFace[i].t[vx1],
					mesh->tvFace[i].t[vx2],
					mesh->tvFace[i].t[vx3],
          i == numLoop - 1 ? ";\n" : ",");
			}
      // texture coords close brace
			fprintf(pStream, "%s\t}\n\n", indent.data());
		}
  }

/*
	// Export color per vertex info
	if (GetIncludeVertexColors()) {
		int numCVx = mesh->numCVerts;

		fprintf(pStream, "%s\t%s %d\n",indent.data(), ID_MESH_NUMCVERTEX, numCVx);
		if (numCVx) {
			fprintf(pStream,"%s\t%s {\n",indent.data(), ID_MESH_CVERTLIST);
			for (i=0; i<numCVx; i++) {
				Point3 vc = mesh->vertCol[i];
				fprintf(pStream, "%s\t\t%s %d\t%s\n",indent.data(), ID_MESH_VERTCOL, i, Format(vc));
			}
			fprintf(pStream,"%s\t}\n",indent.data());
			
			fprintf(pStream, "%s\t%s %d\n",indent.data(), ID_MESH_NUMCVFACES, mesh->getNumFaces());

			fprintf(pStream, "%s\t%s {\n",indent.data(), ID_MESH_CFACELIST);
			for (i=0; i<mesh->getNumFaces(); i++) {
				fprintf(pStream,"%s\t\t%s %d\t%d\t%d\t%d\n",
					indent.data(),
					ID_MESH_CFACE, i,
					mesh->vcFace[i].t[vx1],
					mesh->vcFace[i].t[vx2],
					mesh->vcFace[i].t[vx3]);
			}
			fprintf(pStream, "%s\t}\n",indent.data());
		}
	}
*/

  // Mesh close brace
	fprintf(pStream, "%s}\n",indent.data());
  
  // dispose of tri object
  if (needDel)
  {
		delete tri;
	}
}
Ejemplo n.º 3
0
void MeshExporter::_dumpMaterial(Rad::Material * m, IGameMaterial * mtl)
{
	Point4 val4;
	Point3 val3;
	PropType pt;
	IGameProperty* p = NULL;

	p = mtl->GetAmbientData();
	if (p)
	{
		pt = p->GetType();
		if (pt == IGAME_POINT3_PROP && p->GetPropertyValue(val3)) 
		{
			m->ambient = Float3(val3.x, val3.y, val3.z);
		}
	}

	p = mtl->GetDiffuseData();
	if (p)
	{
		pt = p->GetType();
		if (pt == IGAME_POINT3_PROP && p->GetPropertyValue(val3))
		{
			m->diffuse = Float3(val3.x, val3.y, val3.z);
		}
	}

	p = mtl->GetSpecularData();
	if (p)
	{
		pt = p->GetType();
		if (pt == IGAME_POINT3_PROP && p->GetPropertyValue(val3))
		{
			m->specular = Float3(val3.x, val3.y, val3.z);
		}
	}

	p = mtl->GetSpecularLevelData();
	if (p)
	{
		float specularPower;
		if (p->GetPropertyValue(specularPower))
		{
			m->shininess = specularPower;
		}
	}

	p = mtl->GetEmissiveData();
	if (p)
	{
		pt = p->GetType();
		if (pt == IGAME_POINT3_PROP && p->GetPropertyValue(val3))
		{
			m->emissive = Float3(val3.x, val3.y, val3.z);
		}
	}

	Mtl * maxMtl = mtl->GetMaxMaterial();

	ULONG flag = maxMtl->Requirements(0);

	if (flag & MTLREQ_2SIDE)
	{
		m->cullMode = eCullMode::NONE;
	}

	d_assert (!mtl->IsMultiType());

	int numTextures = mtl->GetNumberOfTextureMaps();

	for ( int index = 0; index < numTextures; ++index )
	{
		IGameTextureMap * pMap = mtl->GetIGameTextureMap(index);

		if (!pMap)
			continue;

		const int type = pMap->GetStdMapSlot();
		const char * tex = pMap->GetBitmapFileName();
		const char * ttt = pMap->GetTextureName();
		std::string bmap = tex;
		bmap = bmap.substr(bmap.find_last_of('\\') + 1);

		if (type == ID_DI)
			m->maps[eMapType::DIFFUSE] = HWBufferManager::Instance()->LoadTexture(bmap.c_str());
		else if (type == ID_BU)
			m->maps[eMapType::NORMAL] = HWBufferManager::Instance()->LoadTexture(bmap.c_str());
		else if (type == ID_SP)
			m->maps[eMapType::SPECULAR] = HWBufferManager::Instance()->LoadTexture(bmap.c_str());
		else if (type == ID_SI)
			m->maps[eMapType::EMISSIVE] = HWBufferManager::Instance()->LoadTexture(bmap.c_str());

		if (type == ID_OP)
			m->blendMode = eBlendMode::ALPHA_TEST;

		TextureExporter::Instance()->Push(pMap->GetBitmapFileName());
	}
}