Exemple #1
0
        /// <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.
        }
Exemple #2
0
        /// <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);
            }
        }
Exemple #3
0
        /// <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);
        }
Exemple #5
0
 /// <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);
Exemple #6
0
 /// <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);
        }