示例#1
0
Mesh* TriPatchObject::GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete) {
	UpdatePatchMesh(t);
	TessApprox tess = patch.GetProdTess();
	if (tess.type == TESS_SET) {
		needDelete = FALSE;
		patch.InvalidateMesh(); // force this...
		// temporarlily set the view tess to prod tess
		TessApprox tempTess = patch.GetViewTess();
		patch.SetViewTess(tess);
		PrepareMesh(t);
		patch.SetViewTess(tempTess);
		return &patch.GetMesh();
	} else {
		Mesh *nmesh = new Mesh/*(mesh)*/;
		Matrix3 otm = inode->GetObjectTM(t);

		Box3 bbox;
		GetDeformBBox(t, bbox);
		tess.merge *= Length(bbox.Width())/1000.0f;
		TessApprox disp = patch.GetDispTess();
		disp.merge *= Length(bbox.Width())/1000.0f;

		GetGTessFunction();
		(*psGTessFunc)(&patch, BEZIER_PATCH, &otm, nmesh, &tess, &disp, &view, inode->GetMtl(), FALSE, FALSE);
		if (tess.merge > 0.0f && patch.GetProdTessWeld())
			WeldMesh(nmesh, tess.merge);
		needDelete = TRUE;
		return nmesh;
	}
}
示例#2
0
BOOL
TriObject::CanDoDisplacementMapping()
{
	GetGTessFunction();
	if (psGTessFunc && !mDisableDisplacement)
		return TRUE;
	return FALSE;
}
示例#3
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;
}