Exemplo n.º 1
0
//-----------------------------------------------------------------------------
// Recursively checks the scene's leaves against the given object.
//-----------------------------------------------------------------------------
void SceneManager::RecursiveBuildCollisionArray( SceneLeaf *leaf, SceneObject *object )
{
	// Only process the leaves if the object's bounding box intesects with it.
	// NOTE: Test both ways to ensure smaller nodes are accepted for intersection.
	if( !IsBoxInBox( object->GetBoundingBox()->min, object->GetBoundingBox()->max, leaf->GetBoundingBox()->min, leaf->GetBoundingBox()->max ) && !IsBoxInBox( leaf->GetBoundingBox()->min, leaf->GetBoundingBox()->max, object->GetBoundingBox()->min, object->GetBoundingBox()->max ) )
		return;

	// Recursively build collision array from each of the leaf's children.
	for( char c = 0; c < 8; c++ )
		if( leaf->children[c] != NULL )
			RecursiveBuildCollisionArray( leaf->children[c], object );

	// Add the faces in this leaf to the array of possible collision faces.
	for( unsigned long f = 0; f < leaf->totalFaces; f++ )
	{
		if( m_totalCollisionFaces == m_totalFaces )
			return;

		m_collisionFaces[m_totalCollisionFaces] = &m_faces[leaf->faces[f]];
		m_totalCollisionFaces++;
	}
}
Exemplo n.º 2
0
//-----------------------------------------------------------------------------
// Recursively builds the scene.
//-----------------------------------------------------------------------------
void SceneManager::RecursiveSceneBuild( SceneLeaf *leaf, D3DXVECTOR3 translation, float halfSize )
{
	// Build a bounding volume around this leaf.
	leaf->SetBoundingBox( D3DXVECTOR3( translation.x - halfSize, translation.y - halfSize, translation.z - halfSize ), D3DXVECTOR3( translation.x + halfSize, translation.y + halfSize, translation.z + halfSize ) );
	leaf->SetBoundingSphere( translation, (float)sqrt( halfSize * halfSize + halfSize * halfSize + halfSize * halfSize ) );

	// Count the number of face in this leaf.
	unsigned long totalFaces = 0;
	for( unsigned long f = 0; f < m_totalFaces; f++ )
		if( IsFaceInBox( &m_vertices[m_faces[f].vertex0], &m_vertices[m_faces[f].vertex1], &m_vertices[m_faces[f].vertex2], leaf->GetBoundingBox()->min, leaf->GetBoundingBox()->max ) == true )
			totalFaces++;

	// Only divide the leaf up if it is too big and contains too many faces.
	if( halfSize > m_maxHalfSize && totalFaces > m_maxFaces )
	{
		// Go through all the child leaves.
		for( char c = 0; c < 8; c++ )
		{
			D3DXVECTOR3 newTranslation, newMin, newMax;
			float newHalfSize = halfSize / 2.0f;
			float mod;

			// Calculate the translation of the new leaf on the x axis.
			mod = 1.0f;
			if( c % 2 < 1 )
				mod = -1.0f;
			newTranslation.x = translation.x + newHalfSize * mod;

			// Calculate the translation of the new leaf on the y axis.
			mod = 1.0f;
			if( c % 4 < 2 )
				mod = -1.0f;
			newTranslation.y = translation.y + newHalfSize * mod;

			// Calculate the translation of the new leaf on the z axis.
			mod = 1.0f;
			if( c % 8 < 4 )
				mod = -1.0f;
			newTranslation.z = translation.z + newHalfSize * mod;

			// Calculate the bounding box around the new leaf.
			newMin = D3DXVECTOR3( newTranslation.x - newHalfSize, newTranslation.y - newHalfSize, newTranslation.z - newHalfSize );
			newMax = D3DXVECTOR3( newTranslation.x + newHalfSize, newTranslation.y + newHalfSize, newTranslation.z + newHalfSize );

			// Check if the new scene leaf will have at least one face in it.
			for( f = 0; f < m_totalFaces; f++ )
			{
				if( IsFaceInBox( &m_vertices[m_faces[f].vertex0], &m_vertices[m_faces[f].vertex1], &m_vertices[m_faces[f].vertex2], newMin, newMax ) == true )
				{
					// A face has been found that is inside the new child scene
					// leaf, so create the scene leaf. Then recurse through the
					// scene leaf's branch of the scene hierarchy.
					leaf->children[c] = new SceneLeaf;
					RecursiveSceneBuild( leaf->children[c], newTranslation, halfSize / 2.0f );

					break;
				}
			}
		}

		return;
	}

	// Create the leaf's array of face indices.
	leaf->totalFaces = totalFaces;
	leaf->faces = new unsigned long[totalFaces];

	// If any face is contained in the leaf's bounding box, then store
	// the index of the face in the leaf's face index array.
	totalFaces = 0;
	for( f = 0; f < m_totalFaces; f++ )
		if( IsFaceInBox( &m_vertices[m_faces[f].vertex0], &m_vertices[m_faces[f].vertex1], &m_vertices[m_faces[f].vertex2], leaf->GetBoundingBox()->min, leaf->GetBoundingBox()->max ) == true )
			leaf->faces[totalFaces++] = f;

	// Store pointers to any occluding objects in the leaf.
	m_occludingObjects->Iterate( true );
	while( m_occludingObjects->Iterate() )
		if( IsBoxInBox( m_occludingObjects->GetCurrent()->GetBoundingBox()->min, m_occludingObjects->GetCurrent()->GetBoundingBox()->max, leaf->GetBoundingBox()->min, leaf->GetBoundingBox()->max ) == true )
			leaf->occluders->Add( m_occludingObjects->GetCurrent() );
}