void AddWorkingData( VertexData vertexData, IndexData indexData )
{
// Insert blank working data, then fill
PMWorkingData work = new PMWorkingData();
this.workingDataList.Add( work );
// Build vertex list
// Resize face list (this will always be this big)
work.faceVertList = new PMFaceVertex[ vertexData.vertexCount ];
// Also resize common vert list to max, to avoid reallocations
work.vertList = new PMVertex[ vertexData.vertexCount ];
// locate position element & the buffer to go with it
VertexElement posElem =
vertexData.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.Position );
HardwareVertexBuffer vbuf =
vertexData.vertexBufferBinding.GetBuffer( posElem.Source );
// lock the buffer for reading
IntPtr bufPtr = vbuf.Lock( BufferLocking.ReadOnly );
uint numCommon = 0;
unsafe
{
byte* pVertex = (byte*)bufPtr.ToPointer();
float* pFloat;
Vector3 pos;
// Map for identifying duplicate position vertices
Dictionary<Vector3, uint> commonVertexMap = new Dictionary<Vector3, uint>();
for ( uint i = 0; i < vertexData.vertexCount; ++i, pVertex += vbuf.VertexSize )
{
pFloat = (float*)( pVertex + posElem.Offset );
pos.x = *pFloat++;
pos.y = *pFloat++;
pos.z = *pFloat++;
work.faceVertList[ (int)i ] = new PMFaceVertex();
// Try to find this position in the existing map
if ( !commonVertexMap.ContainsKey( pos ) )
{
// Doesn't exist, so create it
PMVertex commonVert = new PMVertex();
commonVert.SetDetails( pos, numCommon );
commonVert.removed = false;
commonVert.toBeRemoved = false;
commonVert.seam = false;
// Add it to our working set
work.vertList[ (int)numCommon ] = commonVert;
// Enter it in the map
commonVertexMap.Add( pos, numCommon );
// Increment common index
++numCommon;
work.faceVertList[ (int)i ].commonVertex = commonVert;
work.faceVertList[ (int)i ].realIndex = i;
}
else
{
// Exists already, reference it
PMVertex existingVert = work.vertList[ (int)commonVertexMap[ pos ] ];
work.faceVertList[ (int)i ].commonVertex = existingVert;
work.faceVertList[ (int)i ].realIndex = i;
// Also tag original as a seam since duplicates at this location
work.faceVertList[ (int)i ].commonVertex.seam = true;
}
}
}
vbuf.Unlock();
numCommonVertices = numCommon;
// Build tri list
uint numTris = (uint)indexData.indexCount / 3;
HardwareIndexBuffer ibuf = indexData.indexBuffer;
bool use32bitindexes = ( ibuf.Type == IndexType.Size32 );
IntPtr indexBufferPtr = ibuf.Lock( BufferLocking.ReadOnly );
unsafe
{
ushort* pShort = null;
uint* pInt = null;
if ( use32bitindexes )
{
pInt = (uint*)indexBufferPtr.ToPointer();
}
else
{
pShort = (ushort*)indexBufferPtr.ToPointer();
}
work.triList = new PMTriangle[ (int)numTris ]; // assumed tri list
for ( uint i = 0; i < numTris; ++i )
{
// use 32-bit index always since we're not storing
uint vindex = use32bitindexes ? *pInt++ : *pShort++;
PMFaceVertex v0 = work.faceVertList[ (int)vindex ];
vindex = use32bitindexes ? *pInt++ : *pShort++;
PMFaceVertex v1 = work.faceVertList[ (int)vindex ];
vindex = use32bitindexes ? *pInt++ : *pShort++;
PMFaceVertex v2 = work.faceVertList[ (int)vindex ];
work.triList[ (int)i ] = new PMTriangle();
work.triList[ (int)i ].SetDetails( i, v0, v1, v2 );
work.triList[ (int)i ].removed = false;
}
}
ibuf.Unlock();
}