예제 #1
0
        /// <summary>
        /// Allows future reuse of spare instance, by putting it into the end of spares store.
        /// </summary>
        /// <param name="i_instanceIndex">Instance index, to pu back into spares of instances.</param>
        /// <param name="i_nodeIntstanceIndex">Node instance index holder, to be reset.</param>
        static public void _PutBackSpareInstance(ref RootNodeData rootNodeData, int i_instanceIndex, int i_nodeIntstanceIndex, ref DynamicBuffer <NodeInstancesIndexBufferElement> a_nodeInstancesIndexBuffer, ref DynamicBuffer <InstancesSpareIndexBufferElement> a_instancesSpareIndexBuffer)
        {
            if (i_instanceIndex < 0)
            {
                return;                               // This instance index has not been used.
            }
            rootNodeData.i_instancesSpareLastIndex++; // Put back to spare

            InstancesSpareIndexBufferElement instancesSpareIndexBuffer = new InstancesSpareIndexBufferElement();

            instancesSpareIndexBuffer.i = i_instanceIndex;
            a_instancesSpareIndexBuffer [rootNodeData.i_instancesSpareLastIndex] = instancesSpareIndexBuffer;

            // Is assumed, that size of spares store, is appropriate.
            NodeInstancesIndexBufferElement nodeInstancesIndexBuffer = new NodeInstancesIndexBufferElement();

            nodeInstancesIndexBuffer.i = -1;  // Reset instance index.
            a_nodeInstancesIndexBuffer [i_nodeIntstanceIndex] = nodeInstancesIndexBuffer;
        }
        /// <summary>
        /// Assign instance to node.
        /// </summary>
        /// <param name="i_nodeIndex">Internal octree node index.</param>
        /// <param name="i_instanceID">External instance index, ot unique entity index.</param>
        /// <param name="i_entityVersion">Optional, used when Id is used as entity index.</param>
        /// // Optional, used when Id is used as entity index
        /// <param name="instanceBounds">Boundary of external instance index.</param>
        static private void _AssingInstance2Node(RootNodeData rootNodeData, int i_nodeIndex, int i_instanceID, int i_entityVersion, Bounds instanceBounds, ref DynamicBuffer <NodeBufferElement> a_nodesBuffer, ref DynamicBuffer <InstanceBufferElement> a_instanceBuffer, ref DynamicBuffer <NodeInstancesIndexBufferElement> a_nodeInstancesIndexBuffer, DynamicBuffer <InstancesSpareIndexBufferElement> a_instancesSpareIndexBuffer)
        {
            int i_nodeInstanceIndexOffset = i_nodeIndex * rootNodeData.i_instancesAllowedCount;

            // Reuse spare store
            InstancesSpareIndexBufferElement instancesSpareIndexBuffer = a_instancesSpareIndexBuffer [rootNodeData.i_instancesSpareLastIndex];

            NodeInstancesIndexBufferElement nodeInstancesIndexBuffer;

            // Find next spare instance allocation for this node.
            for (int i = 0; i < rootNodeData.i_instancesAllowedCount; i++)
            {
                int i_instanceIndexOffset = i_nodeInstanceIndexOffset + i;

                nodeInstancesIndexBuffer = a_nodeInstancesIndexBuffer [i_instanceIndexOffset];

                // Is spare.
                if (nodeInstancesIndexBuffer.i == -1)
                {
                    // Assign instance index.
                    nodeInstancesIndexBuffer.i = instancesSpareIndexBuffer.i;
                    a_nodeInstancesIndexBuffer [i_instanceIndexOffset] = nodeInstancesIndexBuffer;  // Set back.
                    break;
                }
            }

            NodeBufferElement nodeBuffer = a_nodesBuffer [i_nodeIndex];

            nodeBuffer.i_instancesCount++;
            a_nodesBuffer [i_nodeIndex] = nodeBuffer;  // Set back.

            InstanceBufferElement instanceBuffer = new InstanceBufferElement()
            {
                i_ID            = i_instanceID,
                i_entityVersion = i_entityVersion, // Optional, used when Id is used as entity index.
                bounds          = instanceBounds
            };

            a_instanceBuffer [instancesSpareIndexBuffer.i] = instanceBuffer;
        }
예제 #3
0
        /// <summary>
        /// Add required new spare instances.
        /// </summary>
        static public void _AddInstanceSpares(ref RootNodeData rootNodeData, ref DynamicBuffer <InstanceBufferElement> a_instanceBuffer, ref DynamicBuffer <InstancesSpareIndexBufferElement> a_instancesSpareIndexBuffer, int i_requiredNumberOfInstances)
        {
            rootNodeData.i_instancesSpareLastIndex--;

            int i_initialSparesCount      = a_instanceBuffer.Length;
            int i_spareInstances2AddCount = i_requiredNumberOfInstances - i_initialSparesCount;

            InstancesSpareIndexBufferElement instancesSpareIndexBuffer = new InstancesSpareIndexBufferElement();

            instancesSpareIndexBuffer.i = -1;

            InstanceBufferElement instanceBuffer = new InstanceBufferElement();

            instanceBuffer.bounds          = new Bounds();
            instanceBuffer.i_ID            = -1;
            instanceBuffer.i_entityVersion = -1;                                    // Optional, used when Id is used as entity index


            // Add new spares, from the end of storage.
            for (int i = 0; i < i_spareInstances2AddCount; i++)
            {
                // Need to expand spare store.
                a_instancesSpareIndexBuffer.Add(instancesSpareIndexBuffer);
                a_instanceBuffer.Add(instanceBuffer);
            }

            // Populate indexes references, with new spares.
            for (int i = 0; i < i_spareInstances2AddCount; i++)
            {
                rootNodeData.i_instancesSpareLastIndex++;

                // Add new spares.
                // Add spares in reversed order, from higher index, to lower index.
                instancesSpareIndexBuffer.i = i_initialSparesCount + i_spareInstances2AddCount - i - 1;
                a_instancesSpareIndexBuffer [rootNodeData.i_instancesSpareLastIndex] = instancesSpareIndexBuffer;
            }
        }
예제 #4
0
        /// <summary>
        /// Assign instance to node.
        /// </summary>
        /// <param name="i_nodeIndex">Internal octree node index.</param>
        /// <param name="i_instanceID">External instance index, ot unique entity index.</param>
        /// <param name="i_entityVersion">Optional, used when Id is used as entity index.</param>
        /// // Optional, used when Id is used as entity index
        /// <param name="instanceBounds">Boundary of external instance index.</param>
        static private bool _AssingInstance2Node(ref RootNodeData rootNodeData, int i_nodeIndex, int i_instanceID, int i_entityVersion, Bounds instanceBounds, ref DynamicBuffer <NodeBufferElement> a_nodesBuffer, ref DynamicBuffer <NodeSparesBufferElement> a_nodeSparesBuffer, ref DynamicBuffer <NodeChildrenBufferElement> a_nodeChildrenBuffer, ref DynamicBuffer <InstanceBufferElement> a_instanceBuffer, ref DynamicBuffer <NodeInstancesIndexBufferElement> a_nodeInstancesIndexBuffer, ref DynamicBuffer <InstancesSpareIndexBufferElement> a_instancesSpareIndexBuffer)
        {
            int i_nodeInstanceIndexOffset = i_nodeIndex * rootNodeData.i_instancesAllowedCount;

            // Reuse spare store
            InstancesSpareIndexBufferElement instancesSpareIndexBuffer = a_instancesSpareIndexBuffer [rootNodeData.i_instancesSpareLastIndex];

            NodeInstancesIndexBufferElement nodeInstancesIndexBuffer;

            bool isInstanceAdded = false;

            // Find next spare instance allocation for this node.
            // Find next spare instance allocation for this node.
            for (int i = 0; i < rootNodeData.i_instancesAllowedCount; i++)
            {
                int i_instanceIndexOffset = i_nodeInstanceIndexOffset + i;

                nodeInstancesIndexBuffer = a_nodeInstancesIndexBuffer [i_instanceIndexOffset];

                // Is spare.
                if (nodeInstancesIndexBuffer.i == -1)
                {
                    // Assign instance index.
                    nodeInstancesIndexBuffer.i = instancesSpareIndexBuffer.i;
                    a_nodeInstancesIndexBuffer [i_instanceIndexOffset] = nodeInstancesIndexBuffer;  // Set back.

                    isInstanceAdded = true;

                    break;
                }
            } // for

            if (!isInstanceAdded)
            {
                // Node has 8 children and an more instances, than capacity.
                // Try to move instance to child, with instance space.
                // if ( i_instancesCount < rootNodeData.i_instancesAllowedCount && i_childrenCount > 0 )

                // Iterate though node's children
                for (int i_childIndex = 0; i_childIndex < 8; i_childIndex++)
                {
                    int i_childIndexOffset = i_nodeIndex * 8 + i_childIndex;

                    NodeChildrenBufferElement nodeChildrenBuffer = a_nodeChildrenBuffer [i_childIndexOffset];

                    // Check if instance bounds fit in child
                    if (CommonMethods._Encapsulates(nodeChildrenBuffer.bounds, instanceBounds))
                    {
                        //NodeBufferElement childNode = a_nodesBuffer [nodeChildrenBuffer.i_nodesIndex] ;

                        // Debug.LogWarning ( "ChNode: " + childNode.i_instancesCount + "; " + childNode.bounds ) ;


                        int i_requiredNumberOfInstances = a_nodeInstancesIndexBuffer.Length;   // l_nodeBounds.Count ;

                        isInstanceAdded = _NodeInstanceSubAdd(
                            ref rootNodeData,
                            nodeChildrenBuffer.i_nodesIndex,
                            i_instanceID,
                            i_entityVersion,
                            instanceBounds,
                            ref a_nodesBuffer,
                            ref a_nodeSparesBuffer,
                            ref a_nodeChildrenBuffer,
                            ref a_nodeInstancesIndexBuffer,
                            ref a_instanceBuffer,
                            ref a_instancesSpareIndexBuffer,
                            i_requiredNumberOfInstances
                            );

                        if (isInstanceAdded)
                        {
                            return(true);                    // Added instance
                        }
                    }
                }

// Debug.LogError ( "Found no child node, to fit instance. Try grow octree." ) ;

                NodeBufferElement nodeBufferElement = a_nodesBuffer [rootNodeData.i_rootNodeIndex];

                // Try add node at the root

// Debug.LogError ( "Grow again." ) ;
                _GrowOctree(ref rootNodeData,
                            (float3)instanceBounds.center - nodeBufferElement.f3_center,
                            ref a_nodesBuffer,
                            ref a_nodeSparesBuffer,
                            ref a_nodeChildrenBuffer,
                            ref a_nodeInstancesIndexBuffer,
                            ref a_instanceBuffer,
                            ref a_instancesSpareIndexBuffer
                            );

                _AddNodeInstance(ref rootNodeData,
                                 i_instanceID,
                                 i_entityVersion,
                                 instanceBounds,
                                 ref a_nodesBuffer,
                                 ref a_nodeSparesBuffer,
                                 ref a_nodeChildrenBuffer,
                                 ref a_nodeInstancesIndexBuffer,
                                 ref a_instanceBuffer,
                                 ref a_instancesSpareIndexBuffer,
                                 out isInstanceAdded
                                 );

// Debug.LogWarning ( "Is instant added? " + (isInstanceAdded? "y" : "n") ) ;
                return(isInstanceAdded);
            } // if


            NodeBufferElement nodeBuffer = a_nodesBuffer [i_nodeIndex];

            nodeBuffer.i_instancesCount++;
            a_nodesBuffer [i_nodeIndex] = nodeBuffer;  // Set back.

            InstanceBufferElement instanceBuffer = new InstanceBufferElement()
            {
                i_ID            = i_instanceID,
                i_entityVersion = i_entityVersion, // Optional, used when Id is used as entity index.
                bounds          = instanceBounds
            };

            a_instanceBuffer [instancesSpareIndexBuffer.i] = instanceBuffer;

            return(true);
        }