protected override void Remove(ModelDisplayObjectBase displayObject) { ModelDisplayObjectBatch batch = displayObject.BatchInformation.Batch; batch.Remove(displayObject, this); //If it's an empty batch, just throw it away. if (batch.DisplayObjects.Count == 0) batches.Remove(batch); }
protected override void Remove(ModelDisplayObjectBase displayObject) { for (int i = 0; i < displayObjects.Count; i++) { if (displayObjects[i].displayObject == displayObject) { displayObjects.RemoveAt(i); break; } } }
protected override void Remove(ModelDisplayObjectBase displayObject) { ModelDisplayObjectBatch batch = displayObject.BatchInformation.Batch; batch.Remove(displayObject, this); //If it's an empty batch, just throw it away. if (batch.DisplayObjects.Count == 0) { batches.Remove(batch); } }
/// <summary> /// Attempts to add an object to the ModelDrawer. /// </summary> /// <param name="objectToDisplay">Object to be added to the model drawer.</param> /// <returns>ModelDisplayObject created for the object. Null if it couldn't be added.</returns> public ModelDisplayObjectBase Add(object objectToDisplay) { ModelDisplayObjectBase displayObject = GetDisplayObject(objectToDisplay); if (displayObject != null) { Add(displayObject); displayObjects.Add(objectToDisplay, displayObject); return(displayObject); } return(null); //Couldn't add it. }
/// <summary> /// Adds a display object to the batch. /// </summary> /// <param name="displayObject">Display object to add.</param> /// <param name="drawer">Drawer of the batch.</param> public bool Add(ModelDisplayObjectBase displayObject, InstancedModelDrawer drawer) { //In theory, don't need to test for dupliate entries since batch.Add //should only be called through a InstancedModelDrawer's add (which checks beforehand). if (displayObjects.Count == MaximumObjectsPerBatch || ((indices.Length / 3 + displayObject.GetTriangleCountEstimate()) > MaximumPrimitiveCountPerBatch && displayObjects.Count > 0)) { return(false); } displayObjects.Add(displayObject); int instanceIndex = displayObjects.Count - 1; displayObject.GetVertexData(vertexList, indexList, this, (ushort)vertices.Length, indices.Length, instanceIndex); //Add the data to the batch. var newVertices = new VertexPositionNormalTexture[vertices.Length + vertexList.Count]; vertices.CopyTo(newVertices, 0); vertexList.CopyTo(newVertices, vertices.Length); vertices = newVertices; var newIndices = new ushort[indices.Length + indexList.Count]; indices.CopyTo(newIndices, 0); indexList.CopyTo(newIndices, indices.Length); indices = newIndices; var newInstancingIndices = new float[instancingIndices.Length + vertexList.Count]; instancingIndices.CopyTo(newInstancingIndices, 0); for (int i = instancingIndices.Length; i < newInstancingIndices.Length; i++) { newInstancingIndices[i] = instanceIndex; } instancingIndices = newInstancingIndices; vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); instancingBuffer = new VertexBuffer(graphicsDevice, drawer.instancingVertexDeclaration, instancingIndices.Length, BufferUsage.WriteOnly); instancingBuffer.SetData(instancingIndices); bindings = new VertexBufferBinding[] { vertexBuffer, instancingBuffer }; indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); vertexList.Clear(); indexList.Clear(); return(true); }
internal BruteDisplayObjectEntry(BruteModelDrawer drawer, ModelDisplayObjectBase displayObject) { this.drawer = drawer; this.displayObject = displayObject; var tempVertices = new List<VertexPositionNormalTexture>(); var tempIndices = new List<ushort>(); displayObject.GetMeshData(tempVertices, tempIndices); vertices = new VertexPositionNormalTexture[tempVertices.Count]; indices = new ushort[tempIndices.Count]; tempVertices.CopyTo(vertices); tempIndices.CopyTo(indices); vertexBuffer = new VertexBuffer(displayObject.Drawer.Game.GraphicsDevice, typeof (VertexPositionNormalTexture), vertices.Length, BufferUsage.WriteOnly); indexBuffer = new IndexBuffer(displayObject.Drawer.Game.GraphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); indexBuffer.SetData(indices); }
protected override void Add(ModelDisplayObjectBase displayObject) { foreach (ModelDisplayObjectBatch batch in batches) { if (batch.Add(displayObject, this)) return; } //If we made it here, that means there was no batch that could handle the display object. //This could be because the batches were full, or it could be that this //display object is just really large (like a terrain) and violated the //primitive count limit. //So throw the object in a new batch. //This will also allow a display object that is too large (like a 512x512 terrain) to be added to a batch, //so long as it is alone. var batchToAdd = new ModelDisplayObjectBatch(Game.GraphicsDevice); batches.Add(batchToAdd); batchToAdd.Add(displayObject, this); }
internal BruteDisplayObjectEntry(BruteModelDrawer drawer, ModelDisplayObjectBase displayObject) { this.drawer = drawer; this.displayObject = displayObject; var tempVertices = new List <VertexPositionNormalTexture>(); var tempIndices = new List <ushort>(); displayObject.GetMeshData(tempVertices, tempIndices); vertices = new VertexPositionNormalTexture[tempVertices.Count]; indices = new ushort[tempIndices.Count]; tempVertices.CopyTo(vertices); tempIndices.CopyTo(indices); vertexBuffer = new VertexBuffer(displayObject.Drawer.Game.GraphicsDevice, typeof(VertexPositionNormalTexture), vertices.Length, BufferUsage.WriteOnly); indexBuffer = new IndexBuffer(displayObject.Drawer.Game.GraphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); indexBuffer.SetData(indices); }
/// <summary> /// Adds a display object to the batch. /// </summary> /// <param name="displayObject">Display object to add.</param> /// <param name="drawer">Drawer of the batch.</param> public bool Add(ModelDisplayObjectBase displayObject, InstancedModelDrawer drawer) { //In theory, don't need to test for dupliate entries since batch.Add //should only be called through a InstancedModelDrawer's add (which checks beforehand). if (displayObjects.Count == MaximumObjectsPerBatch || ((indices.Length / 3 + displayObject.GetTriangleCountEstimate()) > MaximumPrimitiveCountPerBatch && displayObjects.Count > 0)) return false; displayObjects.Add(displayObject); int instanceIndex = displayObjects.Count - 1; displayObject.GetVertexData(vertexList, indexList, this, (ushort) vertices.Length, indices.Length, instanceIndex); //Add the data to the batch. var newVertices = new VertexPositionNormalTexture[vertices.Length + vertexList.Count]; vertices.CopyTo(newVertices, 0); vertexList.CopyTo(newVertices, vertices.Length); vertices = newVertices; var newIndices = new ushort[indices.Length + indexList.Count]; indices.CopyTo(newIndices, 0); indexList.CopyTo(newIndices, indices.Length); indices = newIndices; var newInstancingIndices = new float[instancingIndices.Length + vertexList.Count]; instancingIndices.CopyTo(newInstancingIndices, 0); for (int i = instancingIndices.Length; i < newInstancingIndices.Length; i++) newInstancingIndices[i] = instanceIndex; instancingIndices = newInstancingIndices; vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); instancingBuffer = new VertexBuffer(graphicsDevice, drawer.instancingVertexDeclaration, instancingIndices.Length, BufferUsage.WriteOnly); instancingBuffer.SetData(instancingIndices); bindings = new VertexBufferBinding[] { vertexBuffer, instancingBuffer }; indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); vertexList.Clear(); indexList.Clear(); return true; }
protected override void Add(ModelDisplayObjectBase displayObject) { foreach (ModelDisplayObjectBatch batch in batches) { if (batch.Add(displayObject, this)) { return; } } //If we made it here, that means there was no batch that could handle the display object. //This could be because the batches were full, or it could be that this //display object is just really large (like a terrain) and violated the //primitive count limit. //So throw the object in a new batch. //This will also allow a display object that is too large (like a 512x512 terrain) to be added to a batch, //so long as it is alone. var batchToAdd = new ModelDisplayObjectBatch(Game.GraphicsDevice); batches.Add(batchToAdd); batchToAdd.Add(displayObject, this); }
/// <summary> /// Adds a display object to the drawer. /// </summary> /// <param name="displayObject">Display object to add.</param> protected abstract void Add(ModelDisplayObjectBase displayObject);
protected override void Add(ModelDisplayObjectBase displayObject) { displayObjects.Add(new BruteDisplayObjectEntry(this, displayObject)); }
/// <summary> /// Removes a display object from the drawer. /// </summary> /// <param name="displayObject">Object to remove.</param> protected abstract void Remove(ModelDisplayObjectBase displayObject);
/// <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(ModelDisplayObjectBase 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 newInstancingIndices = new float[instancingIndices.Length - displayObject.BatchInformation.VertexCount]; //Copy the first part back (before the display object) Array.Copy(instancingIndices, 0, newInstancingIndices, 0, displayObject.BatchInformation.BaseVertexBufferIndex); //Copy the second part back (after the display object) Array.Copy(instancingIndices, displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount, newInstancingIndices, displayObject.BatchInformation.BaseVertexBufferIndex, instancingIndices.Length - (displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount)); instancingIndices = newInstancingIndices; //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 < instancingIndices.Length; i++) { instancingIndices[i]--; } 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, drawer.instancingVertexDeclaration, instancingIndices.Length, BufferUsage.WriteOnly); instancingBuffer.SetData(instancingIndices); 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(ModelDisplayObjectBase 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 newInstancingIndices = new float[instancingIndices.Length - displayObject.BatchInformation.VertexCount]; //Copy the first part back (before the display object) Array.Copy(instancingIndices, 0, newInstancingIndices, 0, displayObject.BatchInformation.BaseVertexBufferIndex); //Copy the second part back (after the display object) Array.Copy(instancingIndices, displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount, newInstancingIndices, displayObject.BatchInformation.BaseVertexBufferIndex, instancingIndices.Length - (displayObject.BatchInformation.BaseVertexBufferIndex + displayObject.BatchInformation.VertexCount)); instancingIndices = newInstancingIndices; //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 < instancingIndices.Length; i++) instancingIndices[i]--; 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, drawer.instancingVertexDeclaration, instancingIndices.Length, BufferUsage.WriteOnly); instancingBuffer.SetData(instancingIndices); indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly); indexBuffer.SetData(indices); bindings = new VertexBufferBinding[] { vertexBuffer, instancingBuffer }; } }