diff --git a/src/obj/NiTriShapeData.cpp b/src/obj/NiTriShapeData.cpp
index ec9517f6d735736dded94fe51ffd1050e9f0752a..8ef3f8f14365d08c3dcc03e5aa8d56a3f77cf878 100644
--- a/src/obj/NiTriShapeData.cpp
+++ b/src/obj/NiTriShapeData.cpp
@@ -200,15 +200,51 @@ void NiTriShapeData::SetVertices( const vector<Vector3> & in ) {
 	matchGroups.clear();
 }
 
-void NiTriShapeData::DoMatchDetection() { 
-	matchGroups.resize( vertices.size() );
+void NiTriShapeData::DoMatchDetection() {
+	/* minimum number of groups of shared normals */
+	matchGroups.resize( 0 );
+	/* counting sharing */
+	vector<int> sharing( vertices.size(), 0 );
+
+	for ( unsigned int i = 0; i < vertices.size() - 1; ++i ) {
+		/* this index belongs to a group already */
+		if ( sharing [i] != 0 )
+			continue;
+
+		/* we may find a valid group for this vertex */
+		MatchGroup group;
 
-	for ( unsigned int i = 0; i < matchGroups.size(); ++i ){
 		// Find all vertices that match this one.
-		for ( unsigned short j = 0; j < vertices.size(); ++j ) {
-			if ( vertices[i] == vertices[j] ) {
-				matchGroups[i].vertexIndices.push_back(j);
-			}
+		for ( unsigned short j = i + 1; j < vertices.size(); ++j ) {
+			/* for automatic regeneration we just consider
+			 * identical positions, though the format would
+			 * allow distinct positions to share a normal
+			 */
+			if ( vertices[j] != vertices[i] )
+				continue;
+			if ( normals [j] != normals [i] )
+				continue;
+
+			/* this index belongs to a group already */
+			if ( sharing [i] != 0 )
+				continue;
+
+			/* remember this vertex' index */
+			group.vertexIndices.push_back(j);
+		}
+
+		/* the currently observed vertex shares a normal with others */
+		if ( ( group.numVertices = group.vertexIndices.size() ) > 0 ) {
+			/* this vertex belongs to the group as well */
+			group.vertexIndices.push_back(i);
+			
+			/* mark all of the participating vertices to belong to a group */
+			int groupid = matchGroups.size() + 1;
+			for ( int n = 0; n < group.numVertices; n++ )
+				sharing[group.vertexIndices[n]] = groupid;
+
+			/* register the group */
+			matchGroups.push_back(group);
 		}
 	}
 }