///
/// The CollisionMesh class stores a list of CollisionTriangle objects that compose the mesh.
/// The mesh keeps a quick access array of vertex positions in world coordinates that is used
/// to define the CollisionTriangles. This class also stores the CollisionTree that contains
/// this mesh.
///
public class CollisionMesh : AccessibleMesh
{
/*
* CLASS PROPERTIES
*/
///
/// the collision tree for optimized collision detection
///
protected CollisionTree collisionTree;
///
/// the array of vertices in world coordinates
///
private Vector3[] worldPositions;
///
/// the array of triangular collidable faces that compose this mesh
///
private CollisionTriangle[] collisionTris;
///
/// a bounding box defined in world aligned coordinate space
///
private BoundingBox worldBounds;
/*
* CONSTRUCTORS
*/
///
/// Constructor for a collideable mesh. This constructor
/// simply relies on its parent class's constructor.
///
///
///
///
public CollisionMesh(string meshName, TwelveCylinderGame newGame, ModelMesh mesh)
: base(meshName, newGame, mesh)
{
}
///
/// gets the world position of the vertex at index i
///
/// a vertex index
/// the world coordinate position of the vertex
public override Vector3 getWorldPosition(int i)
{
return worldPositions[i];
}
/*
* COLLISION DATA UPDATES
*/
///
/// update the array of collision faces to the current world coordinates
///
public void updateCollisionFaces()
{
foreach(CollisionTriangle triangle in collisionTris)
triangle.updateAll();
}
///
/// updates the array of vertex positions in world coordinates
///
public void updateWorldPositions()
{
if (worldPositions == null || worldPositions.Length != vertices.Length)
worldPositions = new Vector3[vertices.Length]; //create array of vertices
//transform each vertex in mesh from local coordinates to worlds coordinates
for (int i = 0; i < vertices.Length; i++)
worldPositions[i] = Vector3.Transform(vertices[i].Position, WorldMatrix);
//update the world bounding box
worldBounds = BoundingBox.CreateFromPoints(worldPositions);
}
///
/// Creates the collision tree used for
/// collision detection for this mesh.
///
/// the maximum number of divisions for the tree
/// the minimum volume threshold for a tree node
public void createCollisionTree(uint maxNumDivisions, float minTreeNodeVolume)
{
if (collisionTree != null)
collisionTree.unload(false); //unload existing collision tree
//create new collision tree definition
collisionTree = new CollisionTree(curGame, this.Name + " collision tree",
new Bounds(curGame, worldBounds.Min, worldBounds.Max),
collisionTris, maxNumDivisions, minTreeNodeVolume);
this.addChild(collisionTree); //add the collision tree to scene hiearchy
}
///
/// Creates the array of collideable faces from the
/// array of vertices and input vertex index array.
///
/// the array of vertex indices taht define the mesh triangles
/// called from within the SimpleMesh parseMesh method
protected override void createTriangleDefinitions(int[] indices)
{
//collision triangles defined used world coordinate vertices
updateWorldPositions();
//create new array of collision triangles
if(collisionTris == null || collisionTris.Length != triangleCount)
collisionTris = new CollisionTriangle[triangleCount];
int faceIndex = 0;
//create each collision triangle in this mesh
for (int i = 0; i < indices.Length; i += 3)
collisionTris[faceIndex++] = new CollisionTriangle(curGame, indices[i], indices[i + 1], indices[i + 2], this);
}
}