diff --git a/obj/NiTriBasedGeomData.cpp b/obj/NiTriBasedGeomData.cpp
index 3a09567f83dc7e09b8ebd03a6f43e77dcde30363..8b8f7daf829defab1296e58bc8bfca284b78879a 100644
--- a/obj/NiTriBasedGeomData.cpp
+++ b/obj/NiTriBasedGeomData.cpp
@@ -35,7 +35,26 @@ const Type & NiTriBasedGeomData::GetType() const {
 	return TYPE;
 };
 
-void NiTriBasedGeomData::CalcCentAndRad( Vector3 & center, float & radius ) const {
+void NiTriBasedGeomData::SetUVSetCount(int n) {
+	uvSets.resize(n);
+	hasUv = ( vertexColors.size() != 0 );
+}
+
+//--Setters--//
+void NiTriBasedGeomData::SetVertices( const vector<Vector3> & in ) {
+	vertices = in;
+	hasVertices = ( vertices.size() != 0 );
+
+	//Clear out all other data as it is now based on old vertex information
+	normals.clear();
+	hasNormals = false;
+	vertexColors.clear();
+	this->hasVertexColors = false;
+	for (uint i = 0; i < uvSets.size(); ++i ) {
+		uvSets[i].clear();
+	}
+
+	//If any vertices were given, calculate the new center and radius
 	//Check if there are no vertices
 	if ( vertices.size() == 0 ) {
 		center.Set(0.0f, 0.0f, 0.0f);
@@ -79,62 +98,41 @@ void NiTriBasedGeomData::CalcCentAndRad( Vector3 & center, float & radius ) cons
 	radius = sqrt(maxdist2);
 }
 
-void NiTriBasedGeomData::SetVertexCount(int n) {
-	if ( n > 65535 || n < 0 )
-		throw runtime_error("Invalid Vertex Count: must be between 0 and 65535.");
-
-	if ( n == 0 ) {
-		vertices.clear();
-		normals.clear();
-		vertexColors.clear();
-		for (uint i = 0; i < uvSets.size(); ++i) {
-			uvSets[i].clear();
-		}
-		return;
-	}
-	
-	//n != 0
-	vertices.resize(n);
-
-	if ( normals.size() != 0 ) { 
-		normals.resize(n);
-	}
-	if ( vertexColors.size() != 0 ) {
-		vertexColors.resize(n);
-	}
-	for (uint i = 0; i < uvSets.size(); ++i) {	
-		uvSets[i].resize(n);
-	}
-}
-
-void NiTriBasedGeomData::SetUVSetCount(int n) {
-	uvSets.resize(n);
-}
-
-//--Setters--//
-void NiTriBasedGeomData::SetVertices( const vector<Vector3> & in ) {
-	if (in.size() != vertices.size() && in.size() != 0 )
-		throw runtime_error("Vector size must equal Vertex Count or zero.  Call SetVertexCount() to resize.");
-	vertices = in;
-}
-
 void NiTriBasedGeomData::SetNormals( const vector<Vector3> & in ) {
 	if (in.size() != vertices.size() && in.size() != 0 )
-		throw runtime_error("Vector size must equal Vertex Count or zero.  Call SetVertexCount() to resize.");
+		throw runtime_error("Vector size must equal Vertex Count or zero.");
 	normals = in;
+	hasNormals = ( normals.size() != 0 );
 }
 
 void NiTriBasedGeomData::SetVertexColors( const vector<Color4> & in ) {
 	if (in.size() != vertices.size() && in.size() != 0 )
-		throw runtime_error("Vector size must equal Vertex Count or zero.  Call SetVertexCount() to resize.");
+		throw runtime_error("Vector size must equal Vertex Count or zero.");
 	vertexColors = in;
+	hasVertexColors = ( vertexColors.size() != 0 );
 }
 
 void NiTriBasedGeomData::SetUVSet( int index, const vector<TexCoord> & in ) {
 	if (in.size() != vertices.size())
-		throw runtime_error("Vector size must equal Vertex Count.  Call SetVertexCount() to resize.");
+		throw runtime_error("Vector size must equal Vertex Count.");
 	uvSets[index] = in;
 }
 
-Vector3 NiTriBasedGeomData::Center() const { return Vector3(); }
-float NiTriBasedGeomData::Radius() const { return float(); }
+/*! Returns the 3D center of the mesh.
+ * \return The center of this mesh.
+ */
+Vector3 NiTriBasedGeomData::GetCenter() const {
+	return center;
+}
+
+/*! Returns the radius of the mesh.  That is the distance from the center to
+ * the farthest point from the center.
+ * \return The radius of this mesh.
+ */
+float NiTriBasedGeomData::GetRadius() const {
+	return radius;
+}
+
+//TODO: Remove these
+Vector3 NiTriBasedGeomData::Center() const { return center; }
+float NiTriBasedGeomData::Radius() const { return radius; }
diff --git a/obj/NiTriBasedGeomData.h b/obj/NiTriBasedGeomData.h
index 8f1011bb7fe66287a44c9d2e4431fcd40b481d70..98d1b8925cd5ee3f2a0370f4e1b6b93a318cfdfe 100644
--- a/obj/NiTriBasedGeomData.h
+++ b/obj/NiTriBasedGeomData.h
@@ -46,12 +46,6 @@ public:
 	 */
 	short GetUVSetCount() const { return short(uvSets.size()); }
 
-	/*! Changes the number of vertices used by this mesh.  If the mesh already contains data, it will be retained so long as the new number is higher than the old number.  Otherwise any verticies above the new number will be deleted.  This also resizes any normal, color, or UV data associated with these verticies.  Triangles and triangle strips that may be attached via other interfaces are not culled of references to newly invalid vertices, however.
-	 * \param n The new size of the vertex array.
-	 * \sa IShapeData::GetVertexCount
-	 */
-	void SetVertexCount(int n);
-
 	/*! Changes the number of UV sets used by this mesh.  If he new size is smaller, data at the end of the array will be lost.  Otherwise it will be retained.  The number of UV sets must correspond with the number of textures defined in the corresponding NiTexturingProperty block.
 	 * \param n The new size of the uv set array.
 	 * \sa IShapeData::GetUVSetCount, ITexturingProperty
@@ -60,6 +54,23 @@ public:
 
 	//--Getters--//
 
+	/*! Returns the 3D center of the mesh.
+	 * \return The center of this mesh.
+	 */
+	Vector3 GetCenter() const;
+
+	/*! Returns the radius of the mesh.  That is the distance from the center to
+	 * the farthest point from the center.
+	 * \return The radius of this mesh.
+	 */
+	float GetRadius() const;
+
+	/*! Returns the triangle faces that make up this mesh.
+	 * \return A vector containing the triangle faces that make up this mesh.
+	 * \sa ITriShapeData::SetTriangles
+	 */
+	virtual vector<Triangle> GetTriangles() const { return vector<Triangle>(); }  //TODO:  Make this pure virtual?
+
 	/*! Used to retrive the vertices used by this mesh.  The size of the vector will be the same as the vertex count retrieved with the IShapeData::GetVertexCount function.
 	 * \return A vector cntaining the vertices used by this mesh.
 	 * \sa IShapeData::SetVertices, IShapeData::GetVertexCount, IShapeData::SetVertexCount.
@@ -87,11 +98,11 @@ public:
 	
 //--Setters--//
 
-	/*! Used to set the vertex data used by this mesh.  The size of the vector must be the same as the vertex count retrieved with the IShapeData::GetVertexCount function or the function will throw an exception.
+	/*! Used to set the vertex data used by this mesh.  Calling this function will clear all other data in this object.
 	 * \param in A vector containing the vertices to replace those in the mesh with.  Note that there is no way to set vertices one at a time, they must be sent in one batch.
-	 * \sa IShapeData::GetVertices, IShapeData::GetVertexCount, IShapeData::SetVertexCount.
+	 * \sa IShapeData::GetVertices, IShapeData::GetVertexCount
 	 */
-	void SetVertices( const vector<Vector3> & in );
+	virtual void SetVertices( const vector<Vector3> & in );
 
 	/*! Used to set the normal data used by this mesh.  The size of the vector must either be zero, or the same as the vertex count retrieved with the IShapeData::GetVertexCount function or the function will throw an exception.
 	 * \param in A vector containing the normals to replace those in the mesh with.  Note that there is no way to set normals one at a time, they must be sent in one batch.  Use an empty vector to signify that this mesh will not be using normals.
@@ -115,7 +126,6 @@ public:
 protected:
 	Vector3 Center() const;
 	float Radius() const;
-	void CalcCentAndRad( Vector3 & center, float & radius ) const;
 	NI_TRI_BASED_GEOM_DATA_MEMBERS
 };
 
diff --git a/obj/NiTriShapeData.cpp b/obj/NiTriShapeData.cpp
index 735a952fbbd139f67fa8cb11ef95533b4972e4b4..be1c084d981be2019aaafdda63e5fe0846bcf8fe 100644
--- a/obj/NiTriShapeData.cpp
+++ b/obj/NiTriShapeData.cpp
@@ -35,3 +35,45 @@ const Type & NiTriShapeData::GetType() const {
 	return TYPE;
 };
 
+void NiTriShapeData::SetVertices( const vector<Vector3> & in ) {
+	//Take normal action
+	NiTriBasedGeomData::SetVertices( in );
+
+	//Also, clear match detection data
+	matchGroups.clear();
+}
+
+void NiTriShapeData::DoMatchDetection() { 
+	matchGroups.resize( vertices.size() );
+
+	for ( uint i = 0; i < matchGroups.size(); ++i ){
+		// Find all vertices that match this one.
+		for ( ushort j = 0; j < vertices.size(); ++j ) {
+			if ( vertices[i] == vertices[j] ) {
+				matchGroups[i].vertexIndices.push_back(j);
+			}
+		}
+	}
+}
+
+bool NiTriShapeData::HasMatchData() {
+	return ( matchGroups.size() > 0 );
+}
+
+vector<Triangle> NiTriShapeData::GetTriangles() const {
+	return triangles;
+}
+
+void NiTriShapeData::SetTriangles( const vector<Triangle> & in ) {
+	if ( in.size() > 65535 || in.size() < 0 ) {
+		throw runtime_error("Invalid Triangle Count: must be between 0 and 65535.");
+	}
+
+	triangles = in;
+
+	hasTriangles = ( triangles.size() != 0 );
+
+	//Set number of trianble points to the number of triangles times 3
+	numTrianglePoints = uint(triangles.size()) * 3;
+}
+
diff --git a/obj/NiTriShapeData.h b/obj/NiTriShapeData.h
index 34186db794a5828cfdffe0d7a135e2fb9c05d790..62bac805ddd10d07b2a6243a7667405ab46c75cc 100644
--- a/obj/NiTriShapeData.h
+++ b/obj/NiTriShapeData.h
@@ -31,6 +31,44 @@ public:
 	virtual const Type & GetType() const;
 protected:
 	NI_TRI_SHAPE_DATA_MEMBERS
+
+	//--Match Detection--//
+	
+	//Re-implemented only to casue match detection data to be cleared
+	//when vertices are updated.
+	virtual void SetVertices( const vector<Vector3> & in );
+
+	/*! This function generates match detection data based on the current
+	 * vertex list.  The function of this data is unknown and appears to be
+	 * optional.  The data contains a list of all the vertices that have
+	 * identical positions are stored in the file.  If the vertex data is
+	 * updated, match detection data will be cleared.
+	 * \sa NiTriShapeData::HasMatchData
+	 */
+	void DoMatchDetection();
+
+	/*! Used to determine whether current match detection data has been previously
+	 * generated.
+	 * \return true if there is current match data, false otherwise.
+	 * \sa NiTriShapeData::DoMatchDetection
+	 */
+	bool HasMatchData();
+
+	//--Getters--//
+
+	/*! Returns the triangle faces that make up this mesh.
+	 * \return A vector containing the triangle faces that make up this mesh.
+	 * \sa ITriShapeData::SetTriangles
+	 */
+	virtual vector<Triangle> GetTriangles() const;
+
+	//--Setters--//
+
+	/*! Replaces the triangle face data in this mesh with new data.
+	 * \param in A vector containing the new face data.  Maximum size is 65,535.
+	 * \sa ITriShapeData::GetTriangles
+	 */
+	void SetTriangles( const vector<Triangle> & in );
 };
 
 #endif