protected void SplitGeometry(VertexData vd, IndexData id, SubMeshLodGeometryLink targetGeomLink) { #if !AXIOM_SAFE_ONLY unsafe #endif { if (this.logLevel <= 1) { LogManager.Instance.Write("StaticGeometry.SplitGeometry called"); } // Firstly we need to scan to see how many vertices are being used // and while we're at it, build the remap we can use later var use32bitIndexes = id.indexBuffer.Type == IndexType.Size32; var indexRemap = new Dictionary <int, int>(); var src = id.indexBuffer.Lock(BufferLocking.ReadOnly); indexRemap.Clear(); if (use32bitIndexes) { var p32 = src.ToIntPointer(); for (var i = 0; i < id.indexCount; ++i) { indexRemap[p32[i]] = indexRemap.Count; } } else { var p16 = src.ToShortPointer(); for (var i = 0; i < id.indexCount; ++i) { indexRemap[p16[i]] = indexRemap.Count; } } id.indexBuffer.Unlock(); if (indexRemap.Count == vd.vertexCount) { // ha, complete usage after all targetGeomLink.vertexData = vd; targetGeomLink.indexData = id; return; } // Create the new vertex data records targetGeomLink.vertexData = vd.Clone(false); // Convenience var newvd = targetGeomLink.vertexData; //IndexData newid = targetGeomLink.IndexData; // Update the vertex count newvd.vertexCount = indexRemap.Count; var numvbufs = vd.vertexBufferBinding.BindingCount; // Copy buffers from old to new for (short b = 0; b < numvbufs; ++b) { // Lock old buffer var oldBuf = vd.vertexBufferBinding.GetBuffer(b); // Create new buffer var newBuf = HardwareBufferManager.Instance.CreateVertexBuffer(oldBuf.VertexDeclaration, indexRemap.Count, BufferUsage.Static); // rebind newvd.vertexBufferBinding.SetBinding(b, newBuf); // Copy all the elements of the buffer across, by iterating over // the IndexRemap which describes how to move the old vertices // to the new ones. By nature of the map the remap is in order of // indexes in the old buffer, but note that we're not guaranteed to // address every vertex (which is kinda why we're here) var vdSrc = oldBuf.Lock(BufferLocking.ReadOnly); var pSrcBase = vdSrc; var vdDest = newBuf.Lock(BufferLocking.Discard); var pDstBase = vdDest; var vertexSize = oldBuf.VertexSize; // Buffers should be the same size Debug.Assert(vertexSize == newBuf.VertexSize); foreach (var pair in indexRemap) { Debug.Assert(pair.Key < oldBuf.VertexCount); Debug.Assert(pair.Value < newBuf.VertexCount); var pSrc = (pSrcBase + pair.Key * vertexSize).ToBytePointer(); var pDst = (pDstBase + pair.Value * vertexSize).ToBytePointer(); for (var i = 0; i < vertexSize; i++) { pDst[i] = pSrc[i]; } } // unlock oldBuf.Unlock(); newBuf.Unlock(); } // Now create a new index buffer var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer(id.indexBuffer.Type, id.indexCount, BufferUsage.Static); var idSrc = id.indexBuffer.Lock(BufferLocking.ReadOnly); var idDest = ibuf.Lock(BufferLocking.Discard); if (use32bitIndexes) { var pSrc32 = idSrc.ToIntPointer(); var pDst32 = idDest.ToIntPointer(); for (var i = 0; i < id.indexCount; ++i) { pDst32[i] = indexRemap[pSrc32[i]]; } } else { var pSrc16 = idSrc.ToUShortPointer(); var pDst16 = idDest.ToUShortPointer(); for (var i = 0; i < id.indexCount; ++i) { pDst16[i] = (ushort)indexRemap[pSrc16[i]]; } } id.indexBuffer.Unlock(); ibuf.Unlock(); targetGeomLink.indexData = new IndexData(); targetGeomLink.indexData.indexStart = 0; targetGeomLink.indexData.indexCount = id.indexCount; targetGeomLink.indexData.indexBuffer = ibuf; // Store optimised geometry for deallocation later var optGeom = new OptimisedSubMeshGeometry(); optGeom.indexData = targetGeomLink.indexData; optGeom.vertexData = targetGeomLink.vertexData; this.optimisedSubMeshGeometryList.Add(optGeom); } }
/// <summary> /// Split some shared geometry into dedicated geometry. /// </summary> /// <param name="vd"> </param> /// <param name="id"> </param> /// <param name="targetGeomLink"> </param> public void SplitGeometry( VertexData vd, IndexData id, ref SubMeshLodGeometryLink targetGeomLink ) { // Firstly we need to scan to see how many vertices are being used // and while we're at it, build the remap we can use later bool use32bitIndexes = id.indexBuffer.Type == IndexType.Size32; var indexRemap = new Dictionary<int, int>(); if ( use32bitIndexes ) { var p32 = id.indexBuffer.Lock( id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly ); BuildIndexRemap( p32, id.indexCount, ref indexRemap ); id.indexBuffer.Unlock(); } else { var p16 = id.indexBuffer.Lock( id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly ); BuildIndexRemap( p16, id.indexCount, ref indexRemap ); id.indexBuffer.Unlock(); } if ( indexRemap.Count == vd.vertexCount ) { // ha, complete usage after all targetGeomLink.vertexData = vd; targetGeomLink.indexData = id; return; } // Create the new vertex data records targetGeomLink.vertexData = vd.Clone( false ); // Convenience VertexData newvd = targetGeomLink.vertexData; //IndexData* newid = targetGeomLink->indexData; // Update the vertex count newvd.vertexCount = indexRemap.Count; int numvbufs = vd.vertexBufferBinding.BindingCount; // Copy buffers from old to new for ( int b = 0; b < numvbufs; ++b ) { // Lock old buffer HardwareVertexBuffer oldBuf = vd.vertexBufferBinding.GetBuffer( (short)b ); // Create new buffer HardwareVertexBuffer newBuf = HardwareBufferManager.Instance.CreateVertexBuffer( oldBuf.VertexDeclaration, indexRemap.Count, BufferUsage.Static ); // rebind newvd.vertexBufferBinding.SetBinding( (short)b, newBuf ); // Copy all the elements of the buffer across, by iterating over // the IndexRemap which describes how to move the old vertices // to the new ones. By nature of the map the remap is in order of // indexes in the old buffer, but note that we're not guaranteed to // address every vertex (which is kinda why we're here) var pSrcBase = oldBuf.Lock( BufferLocking.ReadOnly ); var pDstBase = newBuf.Lock( BufferLocking.Discard ); int vertexSize = oldBuf.VertexSize; // Buffers should be the same size Debug.Assert( vertexSize == newBuf.VertexSize ); foreach ( var r in indexRemap ) { Debug.Assert( r.Key < oldBuf.VertexCount ); Debug.Assert( r.Value < newBuf.VertexCount ); var pSrc = pSrcBase + r.Key*vertexSize; var pDst = pDstBase + r.Value*vertexSize; var pSrcPtr = pSrc; var pDstPtr = pDst; Memory.Copy( pDstPtr, pSrcPtr, vertexSize ); } // unlock oldBuf.Unlock(); newBuf.Unlock(); } // Now create a new index buffer HardwareIndexBuffer ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( id.indexBuffer.Type, id.indexCount, BufferUsage.Static ); if ( use32bitIndexes ) { uint* pSrc32, pDst32; pSrc32 = (uint*)id.indexBuffer.Lock( id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly ); pDst32 = (uint*)ibuf.Lock( BufferLocking.Discard ); RemapIndexes( pSrc32, pDst32, ref indexRemap, id.indexCount ); id.indexBuffer.Unlock(); ibuf.Unlock(); } else { ushort* pSrc16, pDst16; pSrc16 = (ushort*)id.indexBuffer.Lock( id.indexStart, id.indexCount*id.indexBuffer.IndexSize, BufferLocking.ReadOnly ); pDst16 = (ushort*)ibuf.Lock( BufferLocking.Discard ); RemapIndexes( pSrc16, pDst16, ref indexRemap, id.indexCount ); id.indexBuffer.Unlock(); ibuf.Unlock(); } targetGeomLink.indexData = new IndexData(); targetGeomLink.indexData.indexStart = 0; targetGeomLink.indexData.indexCount = id.indexCount; targetGeomLink.indexData.indexBuffer = ibuf; // Store optimised geometry for deallocation later var optGeom = new OptimisedSubMeshGeometry(); optGeom.indexData = targetGeomLink.indexData; optGeom.vertexData = targetGeomLink.vertexData; mOptimisedSubMeshGeometryList.Add( optGeom ); }
/// <summary> /// Split some shared geometry into dedicated geometry. /// </summary> /// <param name="vd"> </param> /// <param name="id"> </param> /// <param name="targetGeomLink"> </param> public void SplitGeometry(VertexData vd, IndexData id, ref SubMeshLodGeometryLink targetGeomLink) { // Firstly we need to scan to see how many vertices are being used // and while we're at it, build the remap we can use later bool use32bitIndexes = id.indexBuffer.Type == IndexType.Size32; var indexRemap = new Dictionary <int, int>(); if (use32bitIndexes) { var p32 = id.indexBuffer.Lock(id.indexStart, id.indexCount * id.indexBuffer.IndexSize, BufferLocking.ReadOnly); BuildIndexRemap(p32, id.indexCount, ref indexRemap); id.indexBuffer.Unlock(); } else { var p16 = id.indexBuffer.Lock(id.indexStart, id.indexCount * id.indexBuffer.IndexSize, BufferLocking.ReadOnly); BuildIndexRemap(p16, id.indexCount, ref indexRemap); id.indexBuffer.Unlock(); } if (indexRemap.Count == vd.vertexCount) { // ha, complete usage after all targetGeomLink.vertexData = vd; targetGeomLink.indexData = id; return; } // Create the new vertex data records targetGeomLink.vertexData = vd.Clone(false); // Convenience VertexData newvd = targetGeomLink.vertexData; //IndexData* newid = targetGeomLink->indexData; // Update the vertex count newvd.vertexCount = indexRemap.Count; int numvbufs = vd.vertexBufferBinding.BindingCount; // Copy buffers from old to new for (int b = 0; b < numvbufs; ++b) { // Lock old buffer HardwareVertexBuffer oldBuf = vd.vertexBufferBinding.GetBuffer((short)b); // Create new buffer HardwareVertexBuffer newBuf = HardwareBufferManager.Instance.CreateVertexBuffer( oldBuf.VertexDeclaration, indexRemap.Count, BufferUsage.Static); // rebind newvd.vertexBufferBinding.SetBinding((short)b, newBuf); // Copy all the elements of the buffer across, by iterating over // the IndexRemap which describes how to move the old vertices // to the new ones. By nature of the map the remap is in order of // indexes in the old buffer, but note that we're not guaranteed to // address every vertex (which is kinda why we're here) var pSrcBase = oldBuf.Lock(BufferLocking.ReadOnly); var pDstBase = newBuf.Lock(BufferLocking.Discard); int vertexSize = oldBuf.VertexSize; // Buffers should be the same size Debug.Assert(vertexSize == newBuf.VertexSize); foreach (var r in indexRemap) { Debug.Assert(r.Key < oldBuf.VertexCount); Debug.Assert(r.Value < newBuf.VertexCount); var pSrc = pSrcBase + r.Key * vertexSize; var pDst = pDstBase + r.Value * vertexSize; var pSrcPtr = pSrc; var pDstPtr = pDst; Memory.Copy(pDstPtr, pSrcPtr, vertexSize); } // unlock oldBuf.Unlock(); newBuf.Unlock(); } // Now create a new index buffer HardwareIndexBuffer ibuf = HardwareBufferManager.Instance.CreateIndexBuffer(id.indexBuffer.Type, id.indexCount, BufferUsage.Static); if (use32bitIndexes) { uint *pSrc32, pDst32; pSrc32 = (uint *)id.indexBuffer.Lock( id.indexStart, id.indexCount * id.indexBuffer.IndexSize, BufferLocking.ReadOnly); pDst32 = (uint *)ibuf.Lock(BufferLocking.Discard); RemapIndexes(pSrc32, pDst32, ref indexRemap, id.indexCount); id.indexBuffer.Unlock(); ibuf.Unlock(); } else { ushort *pSrc16, pDst16; pSrc16 = (ushort *)id.indexBuffer.Lock( id.indexStart, id.indexCount * id.indexBuffer.IndexSize, BufferLocking.ReadOnly); pDst16 = (ushort *)ibuf.Lock(BufferLocking.Discard); RemapIndexes(pSrc16, pDst16, ref indexRemap, id.indexCount); id.indexBuffer.Unlock(); ibuf.Unlock(); } targetGeomLink.indexData = new IndexData(); targetGeomLink.indexData.indexStart = 0; targetGeomLink.indexData.indexCount = id.indexCount; targetGeomLink.indexData.indexBuffer = ibuf; // Store optimised geometry for deallocation later var optGeom = new OptimisedSubMeshGeometry(); optGeom.indexData = targetGeomLink.indexData; optGeom.vertexData = targetGeomLink.vertexData; mOptimisedSubMeshGeometryList.Add(optGeom); }
protected void SplitGeometry( VertexData vd, IndexData id, SubMeshLodGeometryLink targetGeomLink ) { #if !AXIOM_SAFE_ONLY unsafe #endif { if ( this.logLevel <= 1 ) { LogManager.Instance.Write( "StaticGeometry.SplitGeometry called" ); } // Firstly we need to scan to see how many vertices are being used // and while we're at it, build the remap we can use later var use32bitIndexes = id.indexBuffer.Type == IndexType.Size32; var indexRemap = new Dictionary<int, int>(); var src = id.indexBuffer.Lock( BufferLocking.ReadOnly ); indexRemap.Clear(); if ( use32bitIndexes ) { var p32 = src.ToIntPointer(); for ( var i = 0; i < id.indexCount; ++i ) { indexRemap[ p32[ i ] ] = indexRemap.Count; } } else { var p16 = src.ToShortPointer(); for ( var i = 0; i < id.indexCount; ++i ) { indexRemap[ p16[ i ] ] = indexRemap.Count; } } id.indexBuffer.Unlock(); if ( indexRemap.Count == vd.vertexCount ) { // ha, complete usage after all targetGeomLink.vertexData = vd; targetGeomLink.indexData = id; return; } // Create the new vertex data records targetGeomLink.vertexData = vd.Clone( false ); // Convenience var newvd = targetGeomLink.vertexData; //IndexData newid = targetGeomLink.IndexData; // Update the vertex count newvd.vertexCount = indexRemap.Count; var numvbufs = vd.vertexBufferBinding.BindingCount; // Copy buffers from old to new for ( short b = 0; b < numvbufs; ++b ) { // Lock old buffer var oldBuf = vd.vertexBufferBinding.GetBuffer( b ); // Create new buffer var newBuf = HardwareBufferManager.Instance.CreateVertexBuffer( oldBuf.VertexDeclaration, indexRemap.Count, BufferUsage.Static ); // rebind newvd.vertexBufferBinding.SetBinding( b, newBuf ); // Copy all the elements of the buffer across, by iterating over // the IndexRemap which describes how to move the old vertices // to the new ones. By nature of the map the remap is in order of // indexes in the old buffer, but note that we're not guaranteed to // address every vertex (which is kinda why we're here) var vdSrc = oldBuf.Lock( BufferLocking.ReadOnly ); var pSrcBase = vdSrc; var vdDest = newBuf.Lock( BufferLocking.Discard ); var pDstBase = vdDest; var vertexSize = oldBuf.VertexSize; // Buffers should be the same size Debug.Assert( vertexSize == newBuf.VertexSize ); foreach ( var pair in indexRemap ) { Debug.Assert( pair.Key < oldBuf.VertexCount ); Debug.Assert( pair.Value < newBuf.VertexCount ); var pSrc = ( pSrcBase + pair.Key*vertexSize ).ToBytePointer(); var pDst = ( pDstBase + pair.Value*vertexSize ).ToBytePointer(); for ( var i = 0; i < vertexSize; i++ ) { pDst[ i ] = pSrc[ i ]; } } // unlock oldBuf.Unlock(); newBuf.Unlock(); } // Now create a new index buffer var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( id.indexBuffer.Type, id.indexCount, BufferUsage.Static ); var idSrc = id.indexBuffer.Lock( BufferLocking.ReadOnly ); var idDest = ibuf.Lock( BufferLocking.Discard ); if ( use32bitIndexes ) { var pSrc32 = idSrc.ToIntPointer(); var pDst32 = idDest.ToIntPointer(); for ( var i = 0; i < id.indexCount; ++i ) { pDst32[ i ] = indexRemap[ pSrc32[ i ] ]; } } else { var pSrc16 = idSrc.ToUShortPointer(); var pDst16 = idDest.ToUShortPointer(); for ( var i = 0; i < id.indexCount; ++i ) { pDst16[ i ] = (ushort)indexRemap[ pSrc16[ i ] ]; } } id.indexBuffer.Unlock(); ibuf.Unlock(); targetGeomLink.indexData = new IndexData(); targetGeomLink.indexData.indexStart = 0; targetGeomLink.indexData.indexCount = id.indexCount; targetGeomLink.indexData.indexBuffer = ibuf; // Store optimised geometry for deallocation later var optGeom = new OptimisedSubMeshGeometry(); optGeom.indexData = targetGeomLink.indexData; optGeom.vertexData = targetGeomLink.vertexData; this.optimisedSubMeshGeometryList.Add( optGeom ); } }
protected unsafe void SplitGeometry(VertexData vd, IndexData id, SubMeshLodGeometryLink targetGeomLink) { log.Info("StaticGeometry.SplitGeometry called"); // Firstly we need to scan to see how many vertices are being used // and while we're at it, build the remap we can use later bool use32bitIndexes = id.indexBuffer.Type == IndexType.Size32; Dictionary<int, int> indexRemap = new Dictionary<int, int>(); IntPtr src = id.indexBuffer.Lock(BufferLocking.ReadOnly); indexRemap.Clear(); if (use32bitIndexes) { int *p32 = (int *)src.ToPointer(); for (int i = 0; i<id.indexCount; ++i) indexRemap[*p32++] = indexRemap.Count; } else { short *p16 = (short *)src.ToPointer(); for (int i = 0; i<id.indexCount; ++i) indexRemap[*p16++] = indexRemap.Count; } id.indexBuffer.Unlock(); if (indexRemap.Count == vd.vertexCount) { // ha, complete usage after all targetGeomLink.vertexData = vd; targetGeomLink.indexData = id; return; } // Create the new vertex data records targetGeomLink.vertexData = vd.Clone(false); // Convenience VertexData newvd = targetGeomLink.vertexData; //IndexData newid = targetGeomLink.IndexData; // Update the vertex count newvd.vertexCount = indexRemap.Count; int numvbufs = vd.vertexBufferBinding.BindingCount; // Copy buffers from old to new for (ushort b = 0; b < numvbufs; ++b) { // Lock old buffer HardwareVertexBuffer oldBuf = vd.vertexBufferBinding.GetBuffer(b); // Create new buffer HardwareVertexBuffer newBuf = HardwareBufferManager.Instance.CreateVertexBuffer(oldBuf.VertexSize, indexRemap.Count, BufferUsage.Static); // rebind newvd.vertexBufferBinding.SetBinding(b, newBuf); // Copy all the elements of the buffer across, by iterating over // the IndexRemap which describes how to move the old vertices // to the new ones. By nature of the map the remap is in order of // indexes in the old buffer, but note that we're not guaranteed to // address every vertex (which is kinda why we're here) IntPtr vdSrc = oldBuf.Lock(BufferLocking.ReadOnly); byte* pSrcBase = (byte *)vdSrc.ToPointer(); IntPtr vdDest = newBuf.Lock(BufferLocking.Discard); byte* pDstBase = (byte *)vdDest.ToPointer(); int vertexSize = oldBuf.VertexSize; // Buffers should be the same size Debug.Assert (vertexSize == newBuf.VertexSize); foreach(KeyValuePair<int, int> pair in indexRemap) { Debug.Assert(pair.Key < oldBuf.VertexCount); Debug.Assert(pair.Value < newBuf.VertexCount); byte* pSrc = pSrcBase + pair.Key * vertexSize; byte* pDst = pDstBase + pair.Value * vertexSize; for (int i=0; i<vertexSize; i++) *pDst++ = *pSrc++; } // unlock oldBuf.Unlock(); newBuf.Unlock(); } // Now create a new index buffer HardwareIndexBuffer ibuf = HardwareBufferManager.Instance.CreateIndexBuffer(id.indexBuffer.Type, id.indexCount, BufferUsage.Static); IntPtr idSrc = id.indexBuffer.Lock(BufferLocking.ReadOnly); IntPtr idDest = ibuf.Lock(BufferLocking.Discard); if (use32bitIndexes) { int *pSrc32 = (int *)idSrc.ToPointer(); int *pDst32 = (int *)idDest.ToPointer(); for (int i=0; i<id.indexCount; ++i) *pDst32++ = (int)indexRemap[*pSrc32++]; } else { ushort *pSrc16 = (ushort *)idSrc.ToPointer(); ushort *pDst16 = (ushort *)idDest.ToPointer(); for (int i=0; i<id.indexCount; ++i) *pDst16++ = (ushort)indexRemap[*pSrc16++]; } id.indexBuffer.Unlock(); ibuf.Unlock(); targetGeomLink.indexData = new IndexData(); targetGeomLink.indexData.indexStart = 0; targetGeomLink.indexData.indexCount = id.indexCount; targetGeomLink.indexData.indexBuffer = ibuf; // Store optimised geometry for deallocation later OptimisedSubMeshGeometry optGeom = new OptimisedSubMeshGeometry(); optGeom.indexData = targetGeomLink.indexData; optGeom.vertexData = targetGeomLink.vertexData; optimisedSubMeshGeometryList.Add(optGeom); }
protected unsafe void SplitGeometry(VertexData vd, IndexData id, SubMeshLodGeometryLink targetGeomLink) { log.Info("StaticGeometry.SplitGeometry called"); // Firstly we need to scan to see how many vertices are being used // and while we're at it, build the remap we can use later bool use32bitIndexes = id.indexBuffer.Type == IndexType.Size32; Dictionary <int, int> indexRemap = new Dictionary <int, int>(); IntPtr src = id.indexBuffer.Lock(BufferLocking.ReadOnly); indexRemap.Clear(); if (use32bitIndexes) { int *p32 = (int *)src.ToPointer(); for (int i = 0; i < id.indexCount; ++i) { indexRemap[*p32++] = indexRemap.Count; } } else { short *p16 = (short *)src.ToPointer(); for (int i = 0; i < id.indexCount; ++i) { indexRemap[*p16++] = indexRemap.Count; } } id.indexBuffer.Unlock(); if (indexRemap.Count == vd.vertexCount) { // ha, complete usage after all targetGeomLink.vertexData = vd; targetGeomLink.indexData = id; return; } // Create the new vertex data records targetGeomLink.vertexData = vd.Clone(false); // Convenience VertexData newvd = targetGeomLink.vertexData; //IndexData newid = targetGeomLink.IndexData; // Update the vertex count newvd.vertexCount = indexRemap.Count; int numvbufs = vd.vertexBufferBinding.BindingCount; // Copy buffers from old to new for (ushort b = 0; b < numvbufs; ++b) { // Lock old buffer HardwareVertexBuffer oldBuf = vd.vertexBufferBinding.GetBuffer(b); // Create new buffer HardwareVertexBuffer newBuf = HardwareBufferManager.Instance.CreateVertexBuffer(oldBuf.VertexSize, indexRemap.Count, BufferUsage.Static); // rebind newvd.vertexBufferBinding.SetBinding(b, newBuf); // Copy all the elements of the buffer across, by iterating over // the IndexRemap which describes how to move the old vertices // to the new ones. By nature of the map the remap is in order of // indexes in the old buffer, but note that we're not guaranteed to // address every vertex (which is kinda why we're here) IntPtr vdSrc = oldBuf.Lock(BufferLocking.ReadOnly); byte * pSrcBase = (byte *)vdSrc.ToPointer(); IntPtr vdDest = newBuf.Lock(BufferLocking.Discard); byte * pDstBase = (byte *)vdDest.ToPointer(); int vertexSize = oldBuf.VertexSize; // Buffers should be the same size Debug.Assert(vertexSize == newBuf.VertexSize); foreach (KeyValuePair <int, int> pair in indexRemap) { Debug.Assert(pair.Key < oldBuf.VertexCount); Debug.Assert(pair.Value < newBuf.VertexCount); byte *pSrc = pSrcBase + pair.Key * vertexSize; byte *pDst = pDstBase + pair.Value * vertexSize; for (int i = 0; i < vertexSize; i++) { *pDst++ = *pSrc++; } } // unlock oldBuf.Unlock(); newBuf.Unlock(); } // Now create a new index buffer HardwareIndexBuffer ibuf = HardwareBufferManager.Instance.CreateIndexBuffer(id.indexBuffer.Type, id.indexCount, BufferUsage.Static); IntPtr idSrc = id.indexBuffer.Lock(BufferLocking.ReadOnly); IntPtr idDest = ibuf.Lock(BufferLocking.Discard); if (use32bitIndexes) { int *pSrc32 = (int *)idSrc.ToPointer(); int *pDst32 = (int *)idDest.ToPointer(); for (int i = 0; i < id.indexCount; ++i) { *pDst32++ = (int)indexRemap[*pSrc32++]; } } else { ushort *pSrc16 = (ushort *)idSrc.ToPointer(); ushort *pDst16 = (ushort *)idDest.ToPointer(); for (int i = 0; i < id.indexCount; ++i) { *pDst16++ = (ushort)indexRemap[*pSrc16++]; } } id.indexBuffer.Unlock(); ibuf.Unlock(); targetGeomLink.indexData = new IndexData(); targetGeomLink.indexData.indexStart = 0; targetGeomLink.indexData.indexCount = id.indexCount; targetGeomLink.indexData.indexBuffer = ibuf; // Store optimised geometry for deallocation later OptimisedSubMeshGeometry optGeom = new OptimisedSubMeshGeometry(); optGeom.indexData = targetGeomLink.indexData; optGeom.vertexData = targetGeomLink.vertexData; optimisedSubMeshGeometryList.Add(optGeom); }