コード例 #1
0
 /// <summary>
 /// Returns the intersection bounding box between the two bounds.
 /// The intersection bounds is the volume which is inside both bounds.
 /// If the rects do not have an intersection, an invalid rect is returned.
 /// See: IsValid
 /// </summary>
 public static IntBounds Intersection(IntBounds a, IntBounds b)
 {
     return(new IntBounds(
                math.max(a.min, b.min),
                math.min(a.max, b.max)
                ));
 }
コード例 #2
0
        public static void ForEachNode <T>(IntBounds bounds, ref T callback) where T : struct, INodeModifier
        {
            var size = bounds.size;

            int i = 0;

            for (int y = 0; y < size.y; y++)
            {
                for (int z = 0; z < size.z; z++)
                {
                    for (int x = 0; x < size.x; x++, i++)
                    {
                        callback.ModifyNode(i, x, z);
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Returns the data index for a node's neighbour in the given direction.
        ///
        /// The bounds, nodeConnections and layeredDataLayout fields can be retrieved from the \reflink{GridGraphRules.Context}.data object.
        ///
        /// Returns: Null if the node has no connection in that direction. Otherwise the data index for that node is returned.
        ///
        /// See: gridgraphrule-connection-filter (view in online documentation for working links) for example usage.
        /// </summary>
        /// <param name="bounds">Sub-rectangle of the grid graph that is being updated/scanned</param>
        /// <param name="nodeConnections">Data for all node connections</param>
        /// <param name="layeredDataLayout">True if this is a layered grid graph</param>
        /// <param name="dataX">X coordinate in the data arrays for the node for which you want to get a neighbour</param>
        /// <param name="dataLayer">Layer (Y) coordinate in the data arrays for the node for which you want to get a neighbour</param>
        /// <param name="dataZ">Z coordinate in the data arrays for the node for which you want to get a neighbour</param>
        /// <param name="direction">Direction to the neighbour. See \reflink{GridNode.HasConnectionInDirection}.</param>
        public static int?GetNeighbourDataIndex(IntBounds bounds, NativeArray <int> nodeConnections, bool layeredDataLayout, int dataX, int dataLayer, int dataZ, int direction)
        {
            // Find the coordinates of the adjacent node
            var dx = GridGraph.neighbourXOffsets[direction];
            var dz = GridGraph.neighbourZOffsets[direction];

            int nx = dataX + dx;
            int nz = dataZ + dz;

            // For valid nodeConnections arrays this is not necessary as out of bounds connections are not valid and it will thus be caught below in the 'has connection' check.
            // But let's be safe in case users do something weird
            if (nx < 0 || nz < 0 || nx >= bounds.size.x || nz >= bounds.size.z)
            {
                return(null);
            }

            // The data arrays are laid out row by row
            const int xstride = 1;
            var       zstride = bounds.size.x;
            var       ystride = bounds.size.x * bounds.size.z;

            var dataIndex          = dataLayer * ystride + dataZ * zstride + dataX * xstride;
            var neighbourDataIndex = nz * zstride + nx * xstride;

            if (layeredDataLayout)
            {
                // In a layered grid graph we need to account for nodes in different layers
                var ny = nodeConnections[dataIndex] >> LevelGridNode.ConnectionStride * direction & LevelGridNode.ConnectionMask;
                if (ny == LevelGridNode.NoConnection)
                {
                    return(null);
                }
                neighbourDataIndex += ny * ystride;
            }
            else
            if ((nodeConnections[dataIndex] & (1 << direction)) == 0)
            {
                return(null);
            }

            return(neighbourDataIndex);
        }
コード例 #4
0
        /// <summary>Returns the data index for a node's neighbour in the given direction</summary>
        public static int GetNeighbourDataIndex(IntBounds bounds, NativeArray <int> nodeConnections, bool layeredDataLayout, int dataIndex, int direction)
        {
            // Find the coordinates of the adjacent node
            var dx = GridGraph.neighbourXOffsets[direction];
            var dz = GridGraph.neighbourZOffsets[direction];

            // The data arrays are laid out row by row
            const int xstride            = 1;
            var       zstride            = bounds.size.x;
            var       neighbourDataIndex = dataIndex + dz * zstride + dx * xstride;

            if (layeredDataLayout)
            {
                // In a layered grid graph we need to account for nodes in different layers
                var y          = dataIndex / (bounds.size.x * bounds.size.z);
                var neighbourY = nodeConnections[dataIndex] >> LevelGridNode.ConnectionStride * direction & LevelGridNode.ConnectionMask;
                neighbourDataIndex += (neighbourY - y) * bounds.size.x * bounds.size.z;
            }
            return(neighbourDataIndex);
        }
コード例 #5
0
        public static void FilterNodeConnections <T>(IntBounds bounds, NativeArray <int> nodeConnections, bool layeredDataLayout, ref T filter) where T : struct, IConnectionFilter
        {
            var size      = bounds.size;
            int nodeIndex = 0;


            for (int y = 0; y < size.y; y++)
            {
                for (int z = 0; z < size.z; z++)
                {
                    for (int x = 0; x < size.x; x++, nodeIndex++)
                    {
                        var conn = nodeConnections[nodeIndex];
                        if (layeredDataLayout)
                        {
                            // Layered grid graph
                            for (int i = 0; i < 8; i++)
                            {
                                if (((conn >> LevelGridNode.ConnectionStride * i) & LevelGridNode.ConnectionMask) != LevelGridNode.NoConnection && !filter.IsValidConnection(nodeIndex, x, z, i))
                                {
                                    conn |= LevelGridNode.NoConnection << LevelGridNode.ConnectionStride * i;
                                }
                            }
                        }
                        else
                        {
                            // Normal grid graph
                            // Iterate through all connections on the node
                            for (int i = 0; i < 8; i++)
                            {
                                if ((conn & (1 << i)) != 0 && !filter.IsValidConnection(nodeIndex, x, z, i))
                                {
                                    conn &= ~(1 << i);
                                }
                            }
                        }
                        nodeConnections[nodeIndex] = conn;
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>Iterate through all nodes.</summary>
        /// <param name="bounds">Sub-rectangle of the grid graph that is being updated/scanned</param>
        /// <param name="nodeNormals">Data for all node normals. This is used to determine if a node exists (important for layered grid graphs).</param>
        /// <param name="callback">The ModifyNode method on the callback struct will be called for each node.</param>
        public static void ForEachNode <T>(IntBounds bounds, NativeArray <float4> nodeNormals, ref T callback) where T : struct, INodeModifier
        {
            var size = bounds.size;

            int i = 0;

            for (int y = 0; y < size.y; y++)
            {
                for (int z = 0; z < size.z; z++)
                {
                    for (int x = 0; x < size.x; x++, i++)
                    {
                        // Check if the node exists at all
                        // This is important for layered grid graphs
                        // A normal is never zero otherwise
                        if (math.any(nodeNormals[i]))
                        {
                            callback.ModifyNode(i, x, y, z);
                        }
                    }
                }
            }
        }
コード例 #7
0
 public bool Contains(IntBounds other)
 {
     return(math.all(other.min >= min & other.max <= max));
 }