Example #1
0
void CBSPMapData_LW::SetFace(vector<CMapFace>* pvecFace, list<LWO2_Layer>::iterator thislayer)
{
	int i;
	WORD j;
	DWORD pnt_index;
	MAPVERTEX vDest;
	SPlane plane;
	LWO2_Object& lwobject = this->m_LWO2Object;
	LWO2_TextureUVMap* pTexuvmap = NULL;
	LWO2_VertexColorMap* pVertexColorMap = NULL;

	int iSurfaceIndex;

	int offset = pvecFace->size();

	// caution : this is a temporary solution. this will not work when multiple PNTS chunks exist
	// in a single layer.
	LWO2_TextureUVMap *pLightmapTextureUVMap = lwobject.FindTextureUVMapByName( "TUV_Lightmap", *thislayer );

	vector<LWO2_Face>& rvecPolygon = thislayer->GetFace();
	int iNumFaces = rvecPolygon.size();

	for(i=0; i<iNumFaces; i++)  // How many faces in the layer
	{
		LWO2_Face& rSrcFace = rvecPolygon[i];

		if( rSrcFace.GetNumPoints() <= 2 )
			continue;

		CMapFace new_face;

		// Find the surface mapped on this face
		LWO2_Surface& rSurf = lwobject.FindSurfaceFromTAG( rSrcFace.GetSurfaceIndex() );
		iSurfaceIndex = lwobject.GetSurfaceIndexFromSurfaceTAG( rSrcFace.GetSurfaceIndex() );

		strcpy( new_face.m_acSurfaceName, rSurf.GetName().c_str() );

		// set material index
		new_face.m_iSurfaceMaterialIndex = GetMaterialIndex( rSurf );


		// if the surface name contains "_NoClip"		
		if( strstr(rSurf.GetName().c_str(),"_NoClip") )
			new_face.RaiseTypeFlag(CMapFace::TYPE_NOCLIP);		// no collision detection against this face
		else
			new_face.ClearTypeFlag(CMapFace::TYPE_NOCLIP);	// usual case

		if( strstr(rSurf.GetName().c_str(),"_Invisible") )	//if the surface name contains "_Invisible"
			new_face.RaiseTypeFlag(CMapFace::TYPE_INVISIBLE);	// this face is not rendered
		else
			new_face.ClearTypeFlag(CMapFace::TYPE_INVISIBLE);	// usual case

		// find the image mapped on this face and get its index
		new_face.m_sTextureID = iSurfaceIndex;

		// The value of TextureID is given as the order of the still image 
		// in vector<m_clipstill> 
		// If a still image is the first element in vector<m_clipstill>, 
		// the TextureID of its owner face is 0

		// The image index of CLIP chunk in LWO2 file starts from 1. Therefore, if a surface doesn't
		// have any image, imagetag of the surface should be 0.  << Is this right?
		// And the 'm_sTextureID' remains -1

		// find the texture uvmap of this face	
		pTexuvmap = lwobject.FindTextureUVMapFromSurface(rSurf, ID_COLR, *thislayer);

		// find the vertex color map applied to this face		
		pVertexColorMap= lwobject.FindVertexColorMapFromSurface(rSurf, *thislayer);

		int iNumPoints = rSrcFace.GetNumPoints();
		for(j=0; j<iNumPoints ;j++)  // the number of points in this face
		{
			memset(&vDest, 0, sizeof(MAPVERTEX));
			vDest.color = 0xFFFFFFFF;	//default vertex color: white and opaque

			pnt_index = rSrcFace.GetVertexIndex()[j];   // the index to a point in the PNTS chunk
			vDest.vPosition = thislayer->GetVertex().at( pnt_index );

			// set texture-uv to the vertex
			// search uv map (VMAP chunk) until the corresponding uv-point is found
			if( pTexuvmap )  // if (pTexuvmap == NULL), we have no uv points for this face
			{
				if( !thislayer->GetUV( vDest.vTex0.u, vDest.vTex0.v, pnt_index, pTexuvmap ) )
				{
					vDest.vTex0.u = 32767;
					vDest.vTex0.v = 32767;
				}
			}

			new_face.m_sLightMapID = -1;
/*			if( pLightmapTextureUVMap )
			{
				if( !thislayer->GetUV( vDest.vTex1.u, vDest.vTex1.v, pnt_index, pLightmapTextureUVMap ) )
				{
					vDest.vTex1.u = -1;
					vDest.vTex1.v = -1;
				}
				else
					new_face.m_sLightMapID = 0;	// TODO: support for multiple lightmap textures
			}*/

			if( pVertexColorMap )
				SetVertexColor( vDest, pnt_index, (DWORD)i, pVertexColorMap );

			if( rSurf.GetMaxSmoothingAngle() < 3.141592f / 2.0f * 89.9f / 90.0f )
				vDest.vNormal = thislayer->GetInterpolatedNormal( rSrcFace, pnt_index );	// smooth shadeing
			else
				vDest.vNormal = rSrcFace.GetFaceNormal();	// flat shading

		//========== normal direction check (visual debugging) =============================================
//			vDest.color = D3DCOLOR_XRGB( abs((int)(vDest.vNormal.x * 250.0f)),
//				                         abs((int)(vDest.vNormal.y * 250.0f)),
//										 abs((int)(vDest.vNormal.z * 250.0f)) );
		//========== normal direction check (visual debugging) =============================================


			new_face.AddMAPVERTEX(vDest);
		}

		new_face.m_sNode = 0;
		new_face.m_bFlag = false;

		if( strstr(rSurf.GetName().c_str(),"_LightSource") )
		{	// mark as a light source
			new_face.RaiseTypeFlag( CMapFace::TYPE_LIGHTSOURCE );
			new_face.RaiseTypeFlag( CMapFace::TYPE_NOCLIP );		// light source faces are not used for collision detection - actually, this is not a good solution
		}


		//========== normal direction check =============================================
//		for(j=0; j<new_face.GetNumVertices()-1; j++)
//		{
//			if( 0.001f < D3DXVec3LengthSq( &(new_face.GetMapVertex(j).vNormal - new_face.GetMapVertex(j+1).vNormal) ) )
//				int iSmoothShadingPolygon = 1;
//		}
		//========== normal direction check =============================================


		pvecFace->push_back( new_face );

	}
}