/// <summary> /// Removes a display object from the batch. /// </summary> /// <param name="displayObject">Display object to remove.</param> /// <param name="drawer">Instanced model drawer doing the removal.</param> public unsafe void Remove(ModelDisplayObject displayObject, InstancedModelDrawer drawer) { //Copy the end of the list over the top of the part back (after the display object) var vertexCopySource = displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount; var vertexCopyTarget = displayObject.BatchInformation.BaseVertexBufferIndex; var vertexCopyLength = vertexCount - vertexCopySource; Array.Copy(vertices, vertexCopySource, vertices, vertexCopyTarget, vertexCopyLength); Array.Copy(instancedVertices, vertexCopySource, instancedVertices, vertexCopyTarget, vertexCopyLength); vertexCount -= displayObject.BatchInformation.VertexCount; //Copy the first part back (before the display object) var indexCopySource = displayObject.BatchInformation.BaseIndexBufferIndex + displayObject.BatchInformation.IndexCount; var indexCopyTarget = displayObject.BatchInformation.BaseIndexBufferIndex; var indexCopyLength = indexCount - indexCopySource; Array.Copy(indices, indexCopySource, indices, indexCopyTarget, indexCopyLength); indexCount -= displayObject.BatchInformation.IndexCount; //The index buffer's data is now wrong. We deleted a bunch of vertices. //So go through the index buffer starting at the point of deletion and decrease the values appropriately. for (int i = displayObject.BatchInformation.BaseIndexBufferIndex; i < indexCount; i++) { indices[i] -= (ushort)displayObject.BatchInformation.VertexCount; } //Like with the index buffer, go through the buffer starting at the point of deletion and decrease the instance index values. for (int i = displayObject.BatchInformation.BaseVertexBufferIndex; i < vertexCount; i++) { instancedVertices[i].InstanceIndex--; } displayObjects.Remove(displayObject); //Move the subsequent display objects list indices and base vertices/indices. for (int i = displayObject.BatchInformation.BatchListIndex; i < DisplayObjects.Count; i++) { DisplayObjects[i].BatchInformation.BatchListIndex--; DisplayObjects[i].BatchInformation.BaseVertexBufferIndex -= displayObject.BatchInformation.VertexCount; DisplayObjects[i].BatchInformation.BaseIndexBufferIndex -= displayObject.BatchInformation.IndexCount; } // Tell ModelDisplayObject that it got removed (batch, indices). var batchListIndex = displayObject.BatchInformation.BatchListIndex; displayObject.ClearBatchReferences(); if (displayObjects.Count > 0 && batchListIndex < displayObjects.Count) { vertexBuffer.SetData(sizeof(VertexPositionNormalTexture) * vertexCopyTarget, vertices, vertexCopyTarget, vertexCopyLength, sizeof(VertexPositionNormalTexture)); instancedBuffer.SetData(sizeof(InstancedVertex) * vertexCopyTarget, instancedVertices, vertexCopyTarget, vertexCopyLength, sizeof(InstancedVertex)); indexBuffer.SetData(sizeof(ushort) * indexCopyTarget, indices, indexCopyTarget, indexCopyLength); } }
/// <summary> /// Removes a display object from the batch. /// </summary> /// <param name="displayObject">Display object to remove.</param> /// <param name="drawer">Instanced model drawer doing the removal.</param> public void Remove(ModelDisplayObject displayObject, InstancedModelDrawer drawer) { //Modify vertex buffer var newVertices = new VertexPositionNormalTexture[vertices.Length - displayObject.BatchInformation.VertexCount]; //Copy the first part back (before the display object) Array.Copy(vertices, 0, newVertices, 0, displayObject.BatchInformation.BaseVertexBufferIndex); //Copy the second part back (after the display object) Array.Copy(vertices, displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount, newVertices, displayObject.BatchInformation.BaseVertexBufferIndex, vertices.Length - (displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount)); vertices = newVertices; //Modify index buffer var newIndices = new ushort[indices.Length - displayObject.BatchInformation.IndexCount]; //Copy the first part back (before the display object) Array.Copy(indices, 0, newIndices, 0, displayObject.BatchInformation.BaseIndexBufferIndex); //Copy the second part back (after the display object) Array.Copy(indices, displayObject.BatchInformation.BaseIndexBufferIndex + displayObject.BatchInformation.IndexCount, newIndices, displayObject.BatchInformation.BaseIndexBufferIndex, indices.Length - (displayObject.BatchInformation.BaseIndexBufferIndex + displayObject.BatchInformation.IndexCount)); indices = newIndices; //The index buffer's data is now wrong though. We deleted a bunch of vertices. //So go through the index buffer starting at the point of deletion and decrease the values appropriately. for (int i = displayObject.BatchInformation.BaseIndexBufferIndex; i < indices.Length; i++) indices[i] -= (ushort)displayObject.BatchInformation.VertexCount; //Modify instancing indices var newInstancedVertices = new InstancedVertex[instancedVertices.Length - displayObject.BatchInformation.VertexCount]; //Copy the first part back (before the display object) Array.Copy(instancedVertices, 0, newInstancedVertices, 0, displayObject.BatchInformation.BaseVertexBufferIndex); //Copy the second part back (after the display object) Array.Copy(instancedVertices, displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount, newInstancedVertices, displayObject.BatchInformation.BaseVertexBufferIndex, instancedVertices.Length - (displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount)); instancedVertices = newInstancedVertices; //Like with the index buffer, go through the buffer starting at the point of deletion and decrease the values appropriately. for (int i = displayObject.BatchInformation.BaseVertexBufferIndex; i < instancedVertices.Length; i++) instancedVertices[i].InstanceIndex--; displayObjects.Remove(displayObject); //Move the subsequent display objects list indices and base vertices/indices. for (int i = displayObject.BatchInformation.BatchListIndex; i < DisplayObjects.Count; i++) { DisplayObjects[i].BatchInformation.BatchListIndex--; DisplayObjects[i].BatchInformation.BaseVertexBufferIndex -= displayObject.BatchInformation.VertexCount; DisplayObjects[i].BatchInformation.BaseIndexBufferIndex -= displayObject.BatchInformation.IndexCount; } // Tell ModelDisplayObject that it got removed (batch, indices). displayObject.ClearBatchReferences(); //If there weren't any vertices, this batch is about to die. if (displayObjects.Count > 0) { vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); instancingBuffer = new VertexBuffer(graphicsDevice, InstancedVertex.VertexDeclaration, instancedVertices.Length, BufferUsage.WriteOnly); instancingBuffer.SetData(instancedVertices); indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); bindings = new VertexBufferBinding[] { vertexBuffer, instancingBuffer }; } }
/// <summary> /// Removes a display object from the batch. /// </summary> /// <param name="displayObject">Display object to remove.</param> /// <param name="drawer">Instanced model drawer doing the removal.</param> public void Remove(ModelDisplayObject displayObject, InstancedModelDrawer drawer) { //Modify vertex buffer var newVertices = new VertexPositionNormalTexture[vertices.Length - displayObject.BatchInformation.VertexCount]; //Copy the first part back (before the display object) Array.Copy(vertices, 0, newVertices, 0, displayObject.BatchInformation.BaseVertexBufferIndex); //Copy the second part back (after the display object) Array.Copy(vertices, displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount, newVertices, displayObject.BatchInformation.BaseVertexBufferIndex, vertices.Length - (displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount)); vertices = newVertices; //Modify index buffer var newIndices = new ushort[indices.Length - displayObject.BatchInformation.IndexCount]; //Copy the first part back (before the display object) Array.Copy(indices, 0, newIndices, 0, displayObject.BatchInformation.BaseIndexBufferIndex); //Copy the second part back (after the display object) Array.Copy(indices, displayObject.BatchInformation.BaseIndexBufferIndex + displayObject.BatchInformation.IndexCount, newIndices, displayObject.BatchInformation.BaseIndexBufferIndex, indices.Length - (displayObject.BatchInformation.BaseIndexBufferIndex + displayObject.BatchInformation.IndexCount)); indices = newIndices; //The index buffer's data is now wrong though. We deleted a bunch of vertices. //So go through the index buffer starting at the point of deletion and decrease the values appropriately. for (int i = displayObject.BatchInformation.BaseIndexBufferIndex; i < indices.Length; i++) { indices[i] -= (ushort)displayObject.BatchInformation.VertexCount; } //Modify instancing indices var newInstancedVertices = new InstancedVertex[instancedVertices.Length - displayObject.BatchInformation.VertexCount]; //Copy the first part back (before the display object) Array.Copy(instancedVertices, 0, newInstancedVertices, 0, displayObject.BatchInformation.BaseVertexBufferIndex); //Copy the second part back (after the display object) Array.Copy(instancedVertices, displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount, newInstancedVertices, displayObject.BatchInformation.BaseVertexBufferIndex, instancedVertices.Length - (displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount)); instancedVertices = newInstancedVertices; //Like with the index buffer, go through the buffer starting at the point of deletion and decrease the values appropriately. for (int i = displayObject.BatchInformation.BaseVertexBufferIndex; i < instancedVertices.Length; i++) { instancedVertices[i].InstanceIndex--; } displayObjects.Remove(displayObject); //Move the subsequent display objects list indices and base vertices/indices. for (int i = displayObject.BatchInformation.BatchListIndex; i < DisplayObjects.Count; i++) { DisplayObjects[i].BatchInformation.BatchListIndex--; DisplayObjects[i].BatchInformation.BaseVertexBufferIndex -= displayObject.BatchInformation.VertexCount; DisplayObjects[i].BatchInformation.BaseIndexBufferIndex -= displayObject.BatchInformation.IndexCount; } // Tell ModelDisplayObject that it got removed (batch, indices). displayObject.ClearBatchReferences(); //If there weren't any vertices, this batch is about to die. if (displayObjects.Count > 0) { vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); instancingBuffer = new VertexBuffer(graphicsDevice, InstancedVertex.VertexDeclaration, instancedVertices.Length, BufferUsage.WriteOnly); instancingBuffer.SetData(instancedVertices); indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); bindings = new VertexBufferBinding[] { vertexBuffer, instancingBuffer }; } }