Exemplo n.º 1
0
int C_BspNode::ClassifyPolygon(C_Plane* plane , poly* polygon)
{
   int front = 0, back = 0;

   for(int i = 0; i < polygon->nVertices; i++) {
      int whereIs = ClassifyVertex(plane , &(polygon->pVertices[i]));

      if(whereIs == FRONT) {
         front++;
      } else if(whereIs == BACK) {
         back++;
      }
   }

   if(front && !back) {
      return FRONT;
   } else if(!front && back) {
      return BACK;
   } else if(!front && !back) {
      return COINCIDENT;
   } else {
      return INTERSECTS;
   }
}
Exemplo n.º 2
0
void CompressTriangleCodes1( const Ty* triangles,
						     uint32_t triangleCount, 
						     uint32_t* vertexRemap, 
						     uint32_t vertexCount, 
						     WriteBitstream& output )
{
	Edge      edgeFifo[ EDGE_FIFO_SIZE ];
	uint32_t  vertexFifo[ VERTEX_FIFO_SIZE ];

	uint32_t  edgesRead      = 0;
	uint32_t  verticesRead   = 0;
	uint32_t  newVertices    = 0;
	const Ty* triangleEnd = triangles + ( triangleCount * 3 );

	assert( vertexCount < 0xFFFFFFFF );

	uint32_t* vertexRemapEnd = vertexRemap + vertexCount;

	// clear the vertex remapping to "not found" value of 0xFFFFFFFF - dirty, but low overhead.
	for ( uint32_t* remappedVertex = vertexRemap; remappedVertex < vertexRemapEnd; ++remappedVertex )
	{
		*remappedVertex = VERTEX_NOT_MAPPED;
	}

	// iterate through the triangles
	for ( const Ty* triangle = triangles; triangle < triangleEnd; triangle += 3 )
	{
		int32_t lowestEdgeCursor = edgesRead >= EDGE_FIFO_SIZE ? edgesRead - EDGE_FIFO_SIZE : 0;
		int32_t edgeCursor       = edgesRead - 1;
		bool    foundEdge        = false;

		int32_t spareVertex = 0;

		// check to make sure that there are no degenerate triangles.
		assert( triangle[ 0 ] != triangle[ 1 ] && triangle[ 1 ] != triangle[ 2 ] && triangle[ 2 ] != triangle[ 0 ] );

		// Probe back through the edge fifo to see if one of the triangle edges is in the FIFO
		for ( ; edgeCursor >= lowestEdgeCursor; --edgeCursor )
		{
			const Edge& edge = edgeFifo[ edgeCursor & EDGE_FIFO_MASK ];

			// check all the edges in order and save the free vertex.
			if ( edge.second == triangle[ 0 ] && edge.first == triangle[ 1 ] )
			{
				foundEdge   = true;
				spareVertex = 2;
				break;
			}
			else if ( edge.second == triangle[ 1 ] && edge.first == triangle[ 2 ] )
			{
				foundEdge   = true;
				spareVertex = 0;
				break;
			}
			else if ( edge.second == triangle[ 2 ] && edge.first == triangle[ 0 ] )
			{
				foundEdge   = true;
				spareVertex = 1;
				break;
			}
		}

		// we found an edge so write it out, so classify a vertex and then write out the correct code.
		if ( foundEdge )
		{
			uint32_t cachedVertex;
			
			uint32_t             spareVertexIndice = triangle[ spareVertex ];
			VertexClassification freeVertexClass   = ClassifyVertex( spareVertexIndice, vertexRemap, vertexFifo, verticesRead, cachedVertex );
			uint32_t             relativeEdge      = ( edgesRead - 1 ) - edgeCursor;

			switch ( freeVertexClass )
			{
			case NEW_VERTEX:
				
				switch ( relativeEdge )
				{
				case 0:

					output.Write( IB_EDGE_0_NEW, IB_TRIANGLE_CODE_BITS );
					break;

				case 1:

					output.Write( IB_EDGE_1_NEW, IB_TRIANGLE_CODE_BITS );
					break;

				default:

					output.Write( IB_EDGE_NEW, IB_TRIANGLE_CODE_BITS );
					output.Write( relativeEdge, CACHED_EDGE_BITS );
					break;

				}

				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ] = spareVertexIndice;
				vertexRemap[ spareVertexIndice ]              = newVertices;

				++verticesRead;
				++newVertices;
				break;

			case CACHED_VERTEX:

				output.Write( IB_EDGE_CACHED, IB_TRIANGLE_CODE_BITS );
				output.Write( relativeEdge, CACHED_EDGE_BITS );
				output.Write( cachedVertex, CACHED_VERTEX_BITS );
				break;

			case FREE_VERTEX:

				output.Write( IB_EDGE_FREE, IB_TRIANGLE_CODE_BITS );
				output.Write( relativeEdge, CACHED_EDGE_BITS );

				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ] = spareVertexIndice;

				++verticesRead;
				
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ spareVertexIndice ] );
				break;

			}

			// Populate the edge fifo with the the remaining edges
			// Note - the winding order is important as we'll need to re-produce this on decompression.
			// The edges are put in as if the found edge is the first edge in the triangle (which it will be when we
			// reconstruct).
			switch ( spareVertex )
			{
			case 0:

				edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( triangle[ 2 ], triangle[ 0 ] );

				++edgesRead;

				edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( triangle[ 0 ], triangle[ 1 ] );

				++edgesRead;
				break;

			case 1:

				edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( triangle[ 0 ], triangle[ 1 ] );

				++edgesRead;

				edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( triangle[ 1 ], triangle[ 2 ] );

				++edgesRead;
				break;

			case 2:

				edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( triangle[ 1 ], triangle[ 2 ] );

				++edgesRead;

				edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( triangle[ 2 ], triangle[ 0 ] );

				++edgesRead;
				break;
			}
		}
		else
		{
			VertexClassification classifications[ 3 ];
			uint32_t             cachedVertexIndices[ 3 ];

			// classify each vertex as new, cached or free, potentially extracting a cached indice.
			classifications[ 0 ] = ClassifyVertex( triangle[ 0 ], vertexRemap, vertexFifo, verticesRead, cachedVertexIndices[ 0 ] );
			classifications[ 1 ] = ClassifyVertex( triangle[ 1 ], vertexRemap, vertexFifo, verticesRead, cachedVertexIndices[ 1 ] );
			classifications[ 2 ] = ClassifyVertex( triangle[ 2 ], vertexRemap, vertexFifo, verticesRead, cachedVertexIndices[ 2 ] );

			// use the classifications to lookup the matching compression code and potentially rotate the order of the vertices.
			const VertexCompressionCase& compressionCase = CompressionCase[ classifications[ 0 ] ][ classifications[ 1 ] ][ classifications[ 2 ] ];
			
			// rotate the order of the vertices based on the compression classification.
			uint32_t reorderedTriangle[ 3 ];
			
			reorderedTriangle[ 0 ] = triangle[ compressionCase.vertexOrder[ 0 ] ];
			reorderedTriangle[ 1 ] = triangle[ compressionCase.vertexOrder[ 1 ] ];
			reorderedTriangle[ 2 ] = triangle[ compressionCase.vertexOrder[ 2 ] ];

			output.Write( compressionCase.code, IB_TRIANGLE_CODE_BITS );

			switch ( compressionCase.code )
			{
			case IB_NEW_NEW_NEW:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = triangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = triangle[ 1 ];
				vertexFifo[ ( verticesRead + 2 ) & VERTEX_FIFO_MASK ] = triangle[ 2 ];

				vertexRemap[ triangle[ 0 ] ] = newVertices;
				vertexRemap[ triangle[ 1 ] ] = newVertices + 1;
				vertexRemap[ triangle[ 2 ] ] = newVertices + 2;

				verticesRead += 3;
				newVertices  += 3;

				break;
			}
			case IB_NEW_NEW_CACHED:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 1 ];

				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 2 ] ], CACHED_VERTEX_BITS );

				vertexRemap[ reorderedTriangle[ 0 ] ] = newVertices;
				vertexRemap[ reorderedTriangle[ 1 ] ] = newVertices + 1;

				verticesRead += 2;
				newVertices  += 2;

				break;
			}
			case IB_NEW_NEW_FREE:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 1 ];
				vertexFifo[ ( verticesRead + 2 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 2 ];

				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 2 ] ] );

				vertexRemap[ reorderedTriangle[ 0 ] ] = newVertices;
				vertexRemap[ reorderedTriangle[ 1 ] ] = newVertices + 1;

				verticesRead += 3;
				newVertices  += 2;

				break;
			}
			case IB_NEW_CACHED_CACHED:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ] = reorderedTriangle[ 0 ];

				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 1 ] ], CACHED_VERTEX_BITS );
				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 2 ] ], CACHED_VERTEX_BITS );

				vertexRemap[ reorderedTriangle[ 0 ] ] = newVertices;
				verticesRead += 1;
				newVertices  += 1;

				break;
			}
			case IB_NEW_CACHED_FREE:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 2 ];

				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 1 ] ], CACHED_VERTEX_BITS );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 2 ] ] );

				vertexRemap[ reorderedTriangle[ 0 ] ] = newVertices;

				verticesRead += 2;
				newVertices  += 1;

				break;
			}
			case IB_NEW_FREE_CACHED:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 1 ];

				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 1 ] ] );
				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 2 ] ], CACHED_VERTEX_BITS );

				vertexRemap[ reorderedTriangle[ 0 ] ] = newVertices;

				verticesRead += 2;
				newVertices  += 1;

				break;
			}
			case IB_NEW_FREE_FREE:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 1 ];
				vertexFifo[ ( verticesRead + 2 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 2 ];

				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 1 ] ] );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 2 ] ] );

				vertexRemap[ reorderedTriangle[ 0 ] ] = newVertices;

				verticesRead += 3;
				newVertices  += 1;

				break;
			}
			case IB_CACHED_CACHED_CACHED:
			{
				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 0 ] ], CACHED_VERTEX_BITS );
				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 1 ] ], CACHED_VERTEX_BITS );
				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 2 ] ], CACHED_VERTEX_BITS );
				break;
			}
			case IB_CACHED_CACHED_FREE:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ] = reorderedTriangle[ 2 ];

				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 0 ] ], CACHED_VERTEX_BITS );
				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 1 ] ], CACHED_VERTEX_BITS );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 2 ] ] );

				verticesRead += 1;

				break;
			}
			case IB_CACHED_FREE_FREE:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 1 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 2 ];

				output.Write( cachedVertexIndices[ compressionCase.vertexOrder[ 0 ] ], CACHED_VERTEX_BITS );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 1 ] ] );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 2 ] ] );

				verticesRead += 2;

				break;
			}
			case IB_FREE_FREE_FREE:
			{
				vertexFifo[ verticesRead & VERTEX_FIFO_MASK ]         = reorderedTriangle[ 0 ];
				vertexFifo[ ( verticesRead + 1 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 1 ];
				vertexFifo[ ( verticesRead + 2 ) & VERTEX_FIFO_MASK ] = reorderedTriangle[ 2 ];

				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 0 ] ] );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 1 ] ] );
				output.WriteVInt( ( newVertices - 1 ) - vertexRemap[ reorderedTriangle[ 2 ] ] );

				verticesRead += 3;
				break;
			}
			}

			// populate the edge fifo with the 3 most recent edges
			edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( reorderedTriangle[ 0 ], reorderedTriangle[ 1 ] );

			++edgesRead;

			edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( reorderedTriangle[ 1 ], reorderedTriangle[ 2 ] );

			++edgesRead;

			edgeFifo[ edgesRead & EDGE_FIFO_MASK ].set( reorderedTriangle[ 2 ], reorderedTriangle[ 0 ] );

			++edgesRead;
		}
	}
}