/// <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 ModelDisplayObject Add(object objectToDisplay) { ModelDisplayObject displayObject = GetDisplayObject(objectToDisplay); if (displayObject != null) { Add(displayObject); displayObjects.Add(objectToDisplay, displayObject); return(displayObject); } return(null); //Couldn't add it. }
/// <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> /// 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 unsafe bool Add(ModelDisplayObject displayObject, InstancedModelDrawer drawer) { //In theory, don't need to test for duplicate entries since batch.Add //should only be called through a InstancedModelDrawer's add (which checks beforehand). if (displayObjects.Count == MaximumObjectsPerBatch || ((indexCount / 3 + displayObject.GetTriangleCountEstimate()) > MaximumPrimitiveCountPerBatch && displayObjects.Count > 0)) { return(false); } displayObjects.Add(displayObject); int instanceIndex = displayObjects.Count - 1; var textureIndex = displayObject.TextureIndex; //OUegheogh, this could just directly write into the batch's vertex/index cache rather than going through a list and recopy. displayObject.GetVertexData(vertexList, indexList, this, (ushort)vertexCount, indexCount, instanceIndex); vertexList.CopyTo(vertices, vertexCount); indexList.CopyTo(indices, indexCount); var newIndexCount = indexCount + indexList.Count; var newVertexCount = vertexCount + vertexList.Count; for (int i = vertexCount; i < newVertexCount; i++) { instancedVertices[i] = new InstancedVertex { InstanceIndex = instanceIndex, TextureIndex = textureIndex } } ; vertexBuffer.SetData(sizeof(VertexPositionNormalTexture) * vertexCount, vertices, vertexCount, vertexList.Count, sizeof(VertexPositionNormalTexture)); instancedBuffer.SetData(sizeof(InstancedVertex) * vertexCount, instancedVertices, vertexCount, vertexList.Count, sizeof(InstancedVertex)); indexBuffer.SetData(sizeof(ushort) * indexCount, indices, indexCount, indexList.Count); vertexCount = newVertexCount; indexCount = newIndexCount; vertexList.Clear(); indexList.Clear(); return(true); }
public override void Add(ModelDisplayObject 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> /// Removes a display object from the drawer. Only use this if display object was added directly. /// </summary> /// <param name="displayObject">Object to remove.</param> public abstract void Remove(ModelDisplayObject displayObject);
/// <summary> /// Adds a display object directly to the drawer without being linked to a source. /// </summary> /// <param name="displayObject">Display object to add.</param> public abstract void Add(ModelDisplayObject displayObject);
public override void Remove(ModelDisplayObject displayObject) { ModelDisplayObjectBatch batch = displayObject.BatchInformation.Batch; batch.Remove(displayObject, this); }