public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, UInt64 newMeshKey,
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape)
{
BulletShape newShape = new BulletShape();
IMesh meshData;
lock (physicsScene.mesher)
{
meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
false, // say it is not physical so a bounding box is not built
false // do not cache the mesh and do not use previously built versions
);
}
if (meshData != null)
{
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
{
// Release the fetched asset data once it has been used.
pbs.SculptData = new byte[0];
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
}
int[] indices = meshData.getIndexListAsInt();
int realIndicesIndex = indices.Length;
float[] verticesAsFloats = meshData.getVertexListAsFloat();
if (BSParam.ShouldRemoveZeroWidthTriangles)
{
// Remove degenerate triangles. These are triangles with two of the vertices
// are the same. This is complicated by the problem that vertices are not
// made unique in sculpties so we have to compare the values in the vertex.
realIndicesIndex = 0;
for (int tri = 0; tri < indices.Length; tri += 3)
{
// Compute displacements into vertex array for each vertex of the triangle
int v1 = indices[tri + 0]*3;
int v2 = indices[tri + 1]*3;
int v3 = indices[tri + 2]*3;
// Check to see if any two of the vertices are the same
if (!((verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0]
&& verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1]
&& verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2])
|| (verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0]
&& verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1]
&& verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2])
|| (verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0]
&& verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1]
&& verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]))
)
{
// None of the vertices of the triangles are the same. This is a good triangle;
indices[realIndicesIndex + 0] = indices[tri + 0];
indices[realIndicesIndex + 1] = indices[tri + 1];
indices[realIndicesIndex + 2] = indices[tri + 2];
realIndicesIndex += 3;
}
}
}
physicsScene.DetailLog(
"{0},BSShapeMesh.CreatePhysicalMesh,key={1},origTri={2},realTri={3},numVerts={4}",
BSScene.DetailLogZero, newMeshKey.ToString("X"), indices.Length/3, realIndicesIndex/3,
verticesAsFloats.Length/3);
if (realIndicesIndex != 0)
{
newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length/3,
verticesAsFloats);
}
else
{
// Force the asset condition to 'failed' so we won't try to keep fetching and processing this mesh.
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedMeshing;
physicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim={1}", LogHeader,
UsefulPrimInfo(physicsScene, prim));
physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,allDegenerate,key={1}", prim.LocalID,
newMeshKey);
}
}
newShape.shapeKey = newMeshKey;
return newShape;
}
}