static bool MakeNormalMesh(plMaxNode *node, plMaxMeshExtractor::NeutralMesh& mesh, Matrix3* w2l)
{
    TriObject *pDeleteMe = nil;
    Mesh *pMesh = ExtractMesh(node, &pDeleteMe);    // allocates *sometimes*; check pDeleteMe

    if (!pMesh)
        return false;

    Matrix3 fullTM = node->GetObjectTM(0);
    int parity = fullTM.Parity();

    mesh.fNumVerts = pMesh->numVerts;
    mesh.fVerts = new hsPoint3[mesh.fNumVerts];

    for (int i = 0; i < mesh.fNumVerts; i++)
    {
        // convert the vertex to global coordinates
        Point3 newVert = fullTM * pMesh->verts[i];
        // convert the vertex to the new (requested) coordinate system
        if (w2l)
            newVert = (*w2l) * newVert;

        mesh.fVerts[i].Set(newVert.x, newVert.y, newVert.z);
    }

    mesh.fNumFaces = pMesh->numFaces;
    mesh.fFaces = new uint16_t[mesh.fNumFaces*3];
    for (int i = 0; i < mesh.fNumFaces; i++)
    {
        Face* pFace = &pMesh->faces[i];
        uint16_t* pNFace = &mesh.fFaces[i * 3];

        pNFace[0] = pFace->v[ parity ? 2 : 0 ]; // reverse winding if parity backwards
        pNFace[1] = pFace->v[1];
        pNFace[2] = pFace->v[ parity ? 0 : 2 ]; // ''
    }

    if (pDeleteMe)
        delete pDeleteMe;

    return true;
}
Example #2
0
void LightMesh::AddMesh(Mesh *m,  Matrix3 basetm,  ViewExp *vpt, BOOL buildVNorms)
	{


	//copy over the vert and face data
	vertsViewSpace.SetCount(m->numVerts);
	for (int i =0; i < m->numVerts; i++)
		vertsViewSpace[i] = m->verts[i];
	
	vertsWorldSpace = vertsViewSpace;
	
	BOOL flip = basetm.Parity();//check to see if the mesh has been mirrored if so flip stuff;
	faces.SetCount(m->numFaces);
	for (i =0; i < m->numFaces; i++)
		{
		faces[i] = m->faces[i];
		if (flip)
			{
			int a = faces[i].v[0];
			int b = faces[i].v[1];
			int c = faces[i].v[2];
			faces[i].v[0] = c;
			faces[i].v[1] = b;
			faces[i].v[2] = a;
			}
		}

	toWorldSpace = basetm;
	toLocalSpace = Inverse(basetm);

	for (i =0; i < m->numVerts; i++)
		vertsWorldSpace[i] = vertsWorldSpace[i]*basetm;


	bb.Init();

//build vnorms and fnorms
	Mesh *mesh;
	mesh = m;
	Face *face;	
	Point3 v0, v1, v2;


//	face = m->faces;
	face = faces.Addr(0);
	

//	fnorms.SetCount(m->getNumFaces());

	GraphicsWindow *gw = vpt->getGW();

	Matrix3 tm;
	vpt->GetAffineTM(tm);
	
	gw->setTransform(Matrix3(1));

	Point3 *verts = vertsViewSpace.Addr(0);
	int vertCount = vertsViewSpace.Count();
	for (i =0; i < vertCount; i++)
		{
		Point3 inPoint,outPoint;
		inPoint = *verts * basetm;
		DWORD flag = gw->transPoint(&inPoint, &outPoint);
		inPoint = inPoint * tm;
		*verts = outPoint ;
		(*verts).z = inPoint.z;
		bb += *verts;
		verts++;
		}

	// Compute face and vertex surface normals
	faceVisible.SetSize(m->getNumFaces());
	faceVisible.ClearAll();
	for (i = 0; i < m->getNumFaces(); i++, face++) 
		{

// Calculate the surface normal
		Point3 norm;
		v0 = vertsViewSpace[face->v[0]];
		v1 = vertsViewSpace[face->v[1]];
		v2 = vertsViewSpace[face->v[2]];
		norm = (v1-v0)^(v2-v1);
		if (norm.z < 0.0f)
			{
			if (face->Hidden())
				faceVisible.Set(i,FALSE);
			else faceVisible.Set(i,TRUE);
			}
		else faceVisible.Set(i,FALSE);
			
		}
	if (buildVNorms)
		{
		face = faces.Addr(0);
		Tab<int> normCount;
		normCount.SetCount(m->numVerts);
		vnorms.SetCount(m->numVerts);
		for (i = 0; i < m->numVerts; i++) 
			{
			vnorms[i] = Point3(0.0f,0.0f,0.0f);
			normCount[i] = 0;
			}
		for (i = 0; i < mesh->getNumFaces(); i++, face++) 
			{

// Calculate the surface normal
			v0 = vertsWorldSpace[face->v[0]];
			v1 = vertsWorldSpace[face->v[1]];
			v2 = vertsWorldSpace[face->v[2]];
			
			for (int j=0; j<3; j++) 
				{		
				vnorms[face->v[j]]+=Normalize((v1-v0)^(v2-v1));
				normCount[face->v[j]]++;
				}
			
			}
		for (i = 0; i < m->numVerts; i++) 
			{
			if (normCount[i]!=0)
				vnorms[i] = Normalize(vnorms[i]/(float)normCount[i]);
			 
			}		
		
		}
	else
		{
		vnorms.ZeroCount();
		vnorms.Resize(0);
		}

	}