@ -89,6 +89,7 @@ int process_faces(const world_t* world, const TextureList& textures)
// Traverse the list of face edges to collect all of the face's vertices
// Traverse the list of face edges to collect all of the face's vertices
Vec3 vertexSum ;
Vec3 vertexSum ;
std : : vector < Vec3 > faceVertices ;
for ( int edgeListIdx = 0 ; edgeListIdx < face - > ledge_num ; + + edgeListIdx )
for ( int edgeListIdx = 0 ; edgeListIdx < face - > ledge_num ; + + edgeListIdx )
{
{
int edgeIdx = world - > edgeList [ face - > ledge_id + edgeListIdx ] ;
int edgeIdx = world - > edgeList [ face - > ledge_id + edgeListIdx ] ;
@ -97,8 +98,10 @@ int process_faces(const world_t* world, const TextureList& textures)
world - > edges [ edgeIdx ] . vertex0 :
world - > edges [ edgeIdx ] . vertex0 :
world - > edges [ - edgeIdx ] . vertex1 ;
world - > edges [ - edgeIdx ] . vertex1 ;
// TODO: some faces have redundant/degenerate vertices. We could optimize those by passing their polygons through GPC.
const vertex_t * vertex = & world - > vertices [ vertIndex ] ;
const vertex_t * vertex = & world - > vertices [ vertIndex ] ;
Vec3 vertexPoint = vertex - > toVec ( ) ;
Vec3 vertexPoint = vertex - > toVec ( ) ;
faceVertices . push_back ( vertexPoint ) ;
// Calculate bounding boxes of this face
// Calculate bounding boxes of this face
Vec3 texturePoint = bounds . textureTransform . TransformPoint ( vertexPoint ) ;
Vec3 texturePoint = bounds . textureTransform . TransformPoint ( vertexPoint ) ;
@ -117,6 +120,30 @@ int process_faces(const world_t* world, const TextureList& textures)
//if (face->ledge_num >= 10)
//if (face->ledge_num >= 10)
// export_lightmap(world, face, bounds, faceIdx);
// export_lightmap(world, face, bounds, faceIdx);
// Determine the face's bounding rectangle in world space (only four vertices, on the face's plane)
switch ( faceVertices . size ( ) )
{
case 3 : // Special case: a triangle
for ( int i = 0 ; i < 3 ; + + i )
outFace . bounds [ i ] = ( unsigned short ) tesselator . addVertex ( faceVertices [ i ] ) ;
outFace . bounds [ 3 ] = outFace . bounds [ 2 ] ;
break ;
case 4 : // Special case: a quad
for ( int i = 0 ; i < 4 ; + + i )
outFace . bounds [ i ] = ( unsigned short ) tesselator . addVertex ( faceVertices [ i ] ) ;
break ;
default :
// TODO: this is far from optimal. We don't need a bounding rectangle, but a minimal bounding quad of any shape. Solve this problem: https://mathoverflow.net/questions/11580/minimum-area-bounding-quadrilateral-algorithm
bounds . textureTransform . Invert ( ) ;
outFace . bounds [ 0 ] = ( unsigned short ) tesselator . addVertex ( bounds . textureTransform . TransformPoint ( Vec3 ( bounds . textureBounds . min . x , bounds . textureBounds . min . y , 0.0f ) ) ) ;
outFace . bounds [ 1 ] = ( unsigned short ) tesselator . addVertex ( bounds . textureTransform . TransformPoint ( Vec3 ( bounds . textureBounds . min . x , bounds . textureBounds . max . y , 0.0f ) ) ) ;
outFace . bounds [ 2 ] = ( unsigned short ) tesselator . addVertex ( bounds . textureTransform . TransformPoint ( Vec3 ( bounds . textureBounds . max . x , bounds . textureBounds . max . y , 0.0f ) ) ) ;
outFace . bounds [ 3 ] = ( unsigned short ) tesselator . addVertex ( bounds . textureTransform . TransformPoint ( Vec3 ( bounds . textureBounds . max . x , bounds . textureBounds . min . y , 0.0f ) ) ) ;
break ;
}
outFace . numFaceVertices = ( unsigned char ) ( outFaceVertices . size ( ) - outFace . firstFaceVertex ) ;
outFace . numFaceVertices = ( unsigned char ) ( outFaceVertices . size ( ) - outFace . firstFaceVertex ) ;
outFace . center = ( vertexSum / face - > ledge_num ) . convertWorldPosition ( ) ;
outFace . center = ( vertexSum / face - > ledge_num ) . convertWorldPosition ( ) ;
double area = face_computeArea ( world , face ) ;
double area = face_computeArea ( world , face ) ;
@ -124,7 +151,7 @@ int process_faces(const world_t* world, const TextureList& textures)
outFaces . push_back ( outFace ) ;
outFaces . push_back ( outFace ) ;
}
}
printf ( " Tesselating faces... \n " ) ;
printf ( " Tessell ating faces... \n " ) ;
std : : vector < ps1bsp_polyvertex_t > outPolyVertices ;
std : : vector < ps1bsp_polyvertex_t > outPolyVertices ;
std : : vector < ps1bsp_polygon_t > outPolygons ;
std : : vector < ps1bsp_polygon_t > outPolygons ;
@ -248,7 +275,7 @@ int process_faces(const world_t* world, const TextureList& textures)
outPoly . numPolyVertices = ( unsigned short ) ( outPolyVertices . size ( ) - outPoly . firstPolyVertex ) ;
outPoly . numPolyVertices = ( unsigned short ) ( outPolyVertices . size ( ) - outPoly . firstPolyVertex ) ;
outPolygons . push_back ( outPoly ) ;
outPolygons . push_back ( outPoly ) ;
outFace - > totalQuad s + = ( outPoly . numPolyVertices - 1 ) / 2 ;
outFace - > totalPrimitive s + = ( outPoly . numPolyVertices - 1 ) / 2 ;
}
}
outFace - > numPolygons = ( unsigned char ) ( outPolygons . size ( ) - outFace - > firstPolygon ) ;
outFace - > numPolygons = ( unsigned char ) ( outPolygons . size ( ) - outFace - > firstPolygon ) ;