Esempio n. 1
0
        /// <summary>
        /// Initializes the topmost root node within the quadnode hierarchy.
        /// </summary>
        private void InitializeRootNode()
        {
            // Allocate the Quadnode.
            Quadnode node = new Quadnode();

            // Set defaults for first node.
            node.NodeIndices    = new NodeIndices();
            node.NodeNeighbours = new NodeNeighbours();

            node.NodeIndices.NodeIndex  = 0;
            node.NodeIndices.NodeParent = 0;
            node.NodeIndices.NodeChild  = 1;
            node.NodeNeighbours.RightNeightbourIndex = 0;
            node.NodeNeighbours.LeftNeightbourIndex  = 0;
            node.NodeNeighbours.BottomNeighbourIndex = 0;
            node.NodeNeighbours.TopNeighbourIndex    = 0;
            node.TriangleListOffset          = 0;
            node.PositioningHorizontalOffset = 0;
            node.PositioningVerticalOffset   = 0;
            node.DepthLevel = 0;

            // Add all triangles to initial node.
            node.TrianglesInNode = GeometryData.Triangles;

            // Add the individual node onto the nodes list.
            _quadNodesLocal.Add(node);
        }
        /// <summary>
        /// Finds each adjacent triangle within a quadnode.
        /// </summary>
        private static void QuadnodeFindTriangleAdjacents(Quadnode quadNode)
        {
            // Retrieve triangle list for the quadnodes.
            HeroesTriangle[] triangleList = quadNode.TrianglesInNode.ToArray();

            // For each triangle in node, find another triangle sharing the same two vertices.
            // Source of Comparison: Triangles in node.
            for (int y = 0; y < triangleList.Length; y++)
            {
                // Comparison Target: Triangles in node.
                for (int z = 0; z < triangleList.Length; z++)
                {
                    // Disallow triangle comparison with self.
                    if (z == y)
                    {
                        continue;
                    }

                    // Check each set of edges, 1-2, 2-3, 3-1 for common vertices used.
                    CheckAdjacent(triangleList[z], triangleList[y].VertexOne, triangleList[y].VertexTwo, triangleList[y].TriangleIndex, triangleList[z].TriangleIndex, 0);
                    CheckAdjacent(triangleList[z], triangleList[y].VertexTwo, triangleList[y].VertexThree, triangleList[y].TriangleIndex, triangleList[z].TriangleIndex, 1);
                    CheckAdjacent(triangleList[z], triangleList[y].VertexThree, triangleList[y].VertexOne, triangleList[y].TriangleIndex, triangleList[z].TriangleIndex, 2);
                }
            }
        }
Esempio n. 3
0
 public Quadnode(T value, Quadnode <T> left = null, Quadnode <T> right = null, Quadnode <T> up = null, Quadnode <T> down = null)
 {
     Value      = value;
     this.left  = left;
     this.right = right;
     this.up    = up;
     this.down  = down;
 }
Esempio n. 4
0
 public void RemoveVertical()
 {
     if (up != null)
     {
         up.down = down;
     }
     if (down != null)
     {
         down.up = up;
     }
     up   = null;
     down = null;
 }
Esempio n. 5
0
 public void SetHorizontal(Quadnode <T> left, Quadnode <T> right)
 {
     if (left != null)
     {
         left.right = this;
     }
     if (right != null)
     {
         right.left = this;
     }
     this.left  = left;
     this.right = right;
 }
Esempio n. 6
0
 public void SetVertical(Quadnode <T> up, Quadnode <T> down)
 {
     if (up != null)
     {
         up.down = this;
     }
     if (down != null)
     {
         down.up = this;
     }
     this.up   = up;
     this.down = down;
 }
Esempio n. 7
0
 public void RemoveHorizontal()
 {
     if (left != null)
     {
         left.right = right;
     }
     if (right != null)
     {
         right.left = left;
     }
     left  = null;
     right = null;
 }
Esempio n. 8
0
        /* Construction/Destruction */
        public RandomQuadnodeGenerator(int megabytes)
        {
            int totalBytes = Mathematics.MegaBytesToBytes(megabytes);
            int structs    = Mathematics.BytesToStructCount <int>(totalBytes);

            Structs = new Quadnode[structs];

            for (int x = 0; x < structs; x++)
            {
                Structs[x] = Quadnode.BuildRandomStruct();
            }

            Bytes = StructArray.GetBytes(Structs);
            File.WriteAllBytes(TestFileName, Bytes);
        }
        public Quadnode ReloadedStreamReader()
        {
            using (var fileStream = _generator.GetMemoryStream())
            {
                var      reloadedReader = new BufferedStreamReader(fileStream, BufferSize);
                Quadnode randomQuadnode = new Quadnode();

                for (int x = 0; x < _generator.Structs.Length; x++)
                {
                    BufferedStreamReaderGetStruct(reloadedReader, out randomQuadnode);
                }

                return(randomQuadnode);
            }
        }
        public Quadnode BinaryReaderCustomBufferSize()
        {
            using (var fileStream = _generator.GetFileStreamWithBufferSize(BufferSize))
            {
                var      binaryReader   = new BinaryReader(fileStream);
                Quadnode randomQuadnode = new Quadnode();

                for (int x = 0; x < _generator.Structs.Length; x++)
                {
                    BinaryReaderGetStruct(binaryReader, out randomQuadnode);
                }

                return(randomQuadnode);
            }
        }
Esempio n. 11
0
        public Quadnode BinaryReader()
        {
            using (var fileStream = _generator.GetMemoryStream())
            {
                var      binaryReader   = new BinaryReader(fileStream);
                Quadnode randomQuadnode = new Quadnode();

                for (int x = 0; x < _generator.Structs.Length; x++)
                {
                    BinaryReaderGetStruct(binaryReader, out randomQuadnode);
                }

                return(randomQuadnode);
            }
        }
Esempio n. 12
0
 /* Create */
 public void BinaryReaderGetStruct(BinaryReader binaryReader, out Quadnode randomQuadnode)
 {
     randomQuadnode.NodeIndex                = binaryReader.ReadUInt16();
     randomQuadnode.NodeParent               = binaryReader.ReadUInt16();
     randomQuadnode.NodeChild                = binaryReader.ReadUInt16();
     randomQuadnode.RightNodeNeighbour       = binaryReader.ReadUInt16();
     randomQuadnode.LeftNodeNeighbour        = binaryReader.ReadUInt16();
     randomQuadnode.BottomNodeNeighbour      = binaryReader.ReadUInt16();
     randomQuadnode.TopNodeNeighbour         = binaryReader.ReadUInt16();
     randomQuadnode.NumberOfTriangles        = binaryReader.ReadUInt16();
     randomQuadnode.OffsetTriangleList       = binaryReader.ReadUInt32();
     randomQuadnode.PositioningOffsetValueLR = binaryReader.ReadUInt16();
     randomQuadnode.PositioningOffsetValueTB = binaryReader.ReadUInt16();
     randomQuadnode.NodeDepthLevel           = binaryReader.ReadByte();
     randomQuadnode.Null1 = binaryReader.ReadByte();
     randomQuadnode.Null2 = binaryReader.ReadUInt16();
     randomQuadnode.Null3 = binaryReader.ReadUInt32();
 }
Esempio n. 13
0
        /// <summary>
        /// Returns an array of Quadnodes at a specified depth level
        /// </summary>
        public Quadnode[] GetQuadnodesAtDepth(int depthLevel)
        {
            // Find the amount of quadnodes which has the requested depth level.
            int quadNodeCount = 0;

            for (int x = 0; x < QuadNodes.Length; x++)
            {
                if (QuadNodes[x].DepthLevel == depthLevel)
                {
                    quadNodeCount += 1;
                }
            }

            // Return null if there are no nodes.
            if (quadNodeCount == 0)
            {
                return(null);
            }

            // Allocate the list of quadNodes used for storage of nodes.
            Quadnode[] nodeList = new Quadnode[quadNodeCount];

            // Loop again to find the relevant nodes and assign them to the array.
            int nodeListIndex = 0;

            for (int x = 0; x < QuadNodes.Length; x++)
            {
                if (QuadNodes[x].DepthLevel == depthLevel)
                {
                    nodeList[nodeListIndex] = QuadNodes[x];
                    nodeListIndex          += 1;
                }
            }

            // Return the quadnodes.
            return(nodeList);
        }
Esempio n. 14
0
        /// <summary>
        /// Generates an individual child node and its properties based off of the parent node.
        /// </summary>
        /// <param name="parentNode"></param>
        /// <param name="nodePosition"></param>
        private void GenerateChildNodesRecursive(Quadnode parentNode)
        {
            // Allocate new quadNodes
            #region Allocate New Quadnodes
            Quadnode topLeftNode     = new Quadnode();
            Quadnode topRightNode    = new Quadnode();
            Quadnode bottomLeftNode  = new Quadnode();
            Quadnode bottomRightNode = new Quadnode();
            #endregion

            // Allocate index and neighbour location.
            #region Allocate Index & Neighbour Structs
            topLeftNode.NodeIndices        = new NodeIndices();
            topLeftNode.NodeNeighbours     = new NodeNeighbours();
            topRightNode.NodeIndices       = new NodeIndices();
            topRightNode.NodeNeighbours    = new NodeNeighbours();
            bottomLeftNode.NodeIndices     = new NodeIndices();
            bottomLeftNode.NodeNeighbours  = new NodeNeighbours();
            bottomRightNode.NodeIndices    = new NodeIndices();
            bottomRightNode.NodeNeighbours = new NodeNeighbours();
            #endregion

            // Only for the 4 quadnodes which stem from the root of the function.
            #region Set Node Index
            topLeftNode.NodeIndices.NodeIndex     = (ushort)_quadNodesLocal.Count();
            topRightNode.NodeIndices.NodeIndex    = (ushort)(_quadNodesLocal.Count() + 1);
            bottomLeftNode.NodeIndices.NodeIndex  = (ushort)(_quadNodesLocal.Count() + 2);
            bottomRightNode.NodeIndices.NodeIndex = (ushort)(_quadNodesLocal.Count() + 3);
            #endregion Set Node Index

            // Set parent node of nodes 1-2-3-4
            #region Set Node Parent
            topLeftNode.NodeIndices.NodeParent     = parentNode.NodeIndices.NodeIndex;
            topRightNode.NodeIndices.NodeParent    = parentNode.NodeIndices.NodeIndex;
            bottomLeftNode.NodeIndices.NodeParent  = parentNode.NodeIndices.NodeIndex;
            bottomRightNode.NodeIndices.NodeParent = parentNode.NodeIndices.NodeIndex;
            #endregion Set Node Parent

            // Set default child node of nodes 1-2-3-4
            #region Default Child Node Pointer
            topLeftNode.NodeIndices.NodeChild     = 0;
            topRightNode.NodeIndices.NodeChild    = 0;
            bottomLeftNode.NodeIndices.NodeChild  = 0;
            bottomRightNode.NodeIndices.NodeChild = 0;
            #endregion

            // Specify node depth level of the child node.
            #region Set Node Depth Level
            topLeftNode.DepthLevel     = (byte)(parentNode.DepthLevel + 1);
            topRightNode.DepthLevel    = (byte)(parentNode.DepthLevel + 1);
            bottomLeftNode.DepthLevel  = (byte)(parentNode.DepthLevel + 1);
            bottomRightNode.DepthLevel = (byte)(parentNode.DepthLevel + 1);
            #endregion

            // Set child node for parent.
            #region Parent Node: Set Child Node
            Quadnode tempNode = _quadNodesLocal[parentNode.NodeIndices.NodeIndex];
            tempNode.NodeIndices.NodeChild = topLeftNode.NodeIndices.NodeIndex;
            _quadNodesLocal[parentNode.NodeIndices.NodeIndex] = tempNode;
            #endregion

            // Calculate the positioning horizontal and vertical offsets.
            // If a node is physically further right of the first node, add (2^basePower - depthLevel)
            #region Calculate Horizontal and Vertical Offset Values
            // Node 1
            topLeftNode.PositioningHorizontalOffset = parentNode.PositioningHorizontalOffset;
            topLeftNode.PositioningVerticalOffset   = parentNode.PositioningVerticalOffset;

            // Node 2
            topRightNode.PositioningHorizontalOffset = (ushort)(parentNode.PositioningHorizontalOffset + Math.Pow(2, (BasePower - topRightNode.DepthLevel)));
            topRightNode.PositioningVerticalOffset   = parentNode.PositioningVerticalOffset;

            // Node 3
            bottomLeftNode.PositioningHorizontalOffset = parentNode.PositioningHorizontalOffset;
            bottomLeftNode.PositioningVerticalOffset   = (ushort)(parentNode.PositioningVerticalOffset + Math.Pow(2, (BasePower - bottomLeftNode.DepthLevel)));

            // Node 4
            bottomRightNode.PositioningHorizontalOffset = (ushort)(parentNode.PositioningHorizontalOffset + Math.Pow(2, (BasePower - bottomRightNode.DepthLevel)));
            bottomRightNode.PositioningVerticalOffset   = (ushort)(parentNode.PositioningVerticalOffset + Math.Pow(2, (BasePower - bottomRightNode.DepthLevel)));
            #endregion

            // Set the local neighbours.
            #region Set Local Neighbours (Within Same Node)
            topLeftNode.NodeNeighbours.RightNeightbourIndex = topRightNode.NodeIndices.NodeIndex;
            topLeftNode.NodeNeighbours.BottomNeighbourIndex = bottomLeftNode.NodeIndices.NodeIndex;

            topRightNode.NodeNeighbours.LeftNeightbourIndex  = topLeftNode.NodeIndices.NodeIndex;
            topRightNode.NodeNeighbours.BottomNeighbourIndex = bottomRightNode.NodeIndices.NodeIndex;

            bottomLeftNode.NodeNeighbours.TopNeighbourIndex    = topLeftNode.NodeIndices.NodeIndex;
            bottomLeftNode.NodeNeighbours.RightNeightbourIndex = bottomRightNode.NodeIndices.NodeIndex;

            bottomRightNode.NodeNeighbours.TopNeighbourIndex   = topRightNode.NodeIndices.NodeIndex;
            bottomRightNode.NodeNeighbours.LeftNeightbourIndex = bottomLeftNode.NodeIndices.NodeIndex;
            #endregion

            // Find triangle-node collisions for each node.
            #region Find Triangles Stored by Node
            QuadnodeUtilities.FindTriangles(ref topLeftNode, parentNode);
            QuadnodeUtilities.FindTriangles(ref topRightNode, parentNode);
            QuadnodeUtilities.FindTriangles(ref bottomLeftNode, parentNode);
            QuadnodeUtilities.FindTriangles(ref bottomRightNode, parentNode);
            #endregion

            // Add the nodes 1-2-3-4 onto the quadnodes list.
            _quadNodesLocal.Add(topLeftNode);
            _quadNodesLocal.Add(topRightNode);
            _quadNodesLocal.Add(bottomLeftNode);
            _quadNodesLocal.Add(bottomRightNode);

            // Recursively generate nodes down the tree until the target depth level.
            // Do so only if the child node has any triangles.
            if (topLeftNode.DepthLevel >= DepthLevel)
            {
                return;
            }

            // Recursively generate all children of top left first, then top right, then bottom left and bottom right.
            if (topLeftNode.TrianglesInNode.Count > 0)
            {
                GenerateChildNodesRecursive(topLeftNode);
            }
            if (topRightNode.TrianglesInNode.Count > 0)
            {
                GenerateChildNodesRecursive(topRightNode);
            }
            if (bottomLeftNode.TrianglesInNode.Count > 0)
            {
                GenerateChildNodesRecursive(bottomLeftNode);
            }
            if (bottomRightNode.TrianglesInNode.Count > 0)
            {
                GenerateChildNodesRecursive(bottomRightNode);
            }
        }
Esempio n. 15
0
 public void BufferedStreamReaderGetStruct(BufferedStreamReader bufferedStreamReader, out Quadnode randomQuadnode)
 {
     bufferedStreamReader.Read(out randomQuadnode);
 }
Esempio n. 16
0
        /// <summary>
        /// Finds the neighbour nodes for the child nodes of the current nodes recursively.
        /// </summary>
        /// <param name="quadNode"></param>
        private void FindNeighbourNodesRecursive(Quadnode quadNode)
        {
            // Set the non-local neighbours.
            #region Set Non Local Neighbours (Relative to Parent - Optimization)

            // Obtain the children nodes to the current node.
            QuadnodeChildren childNodes = new QuadnodeChildren(quadNode);

            // If the current node has no children then return.
            if (childNodes.TopLeftNode == null)
            {
                return;
            }

            // Obtain the children for the children nodes.
            QuadnodeChildren topLeftChildren     = new QuadnodeChildren(childNodes.TopLeftNode);
            QuadnodeChildren topRightChildren    = new QuadnodeChildren(childNodes.TopRightNode);
            QuadnodeChildren bottomLeftChildren  = new QuadnodeChildren(childNodes.BottomLeftNode);
            QuadnodeChildren bottomRightChildren = new QuadnodeChildren(childNodes.BottomRightNode);

            // Set relative neighbour relations for nodes in the quadtree struct.
            // NB: Looking at this code and are confused? You are just as I was when I was writing it.
            // Basically we are going down 2 depth levels from the current nodes, where the node total at the specified depth level
            // would be 16, and we are connecting the right side child nodes of the top left quadnodes to the left side child nodes
            // of the top right quadnodes. In the same way, we connect the bottom two quadnodes of the top left quadnode with the top
            // two quadnodes of the bottom left quadnode etc. Fast neighbour finding.

            // The format of these statements
            // If (Node) Exists
            // Set the neighbour index to:
            // If exists, appropriate node, else parent of node (passed in ThisNode object).

            // Left-Right (Should be 4 sets)
            if (topLeftChildren.TopRightNode != null)
            {
                topLeftChildren.TopRightNode.NodeNeighbours.RightNeightbourIndex = topRightChildren.TopLeftNode != null ? topRightChildren.TopLeftNode.NodeIndices.NodeIndex : topRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (topRightChildren.TopLeftNode != null)
            {
                topRightChildren.TopLeftNode.NodeNeighbours.LeftNeightbourIndex = topLeftChildren.TopRightNode != null ? topLeftChildren.TopRightNode.NodeIndices.NodeIndex : topLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }


            if (topLeftChildren.BottomRightNode != null)
            {
                topLeftChildren.BottomRightNode.NodeNeighbours.RightNeightbourIndex = topRightChildren.BottomLeftNode != null ? topRightChildren.BottomLeftNode.NodeIndices.NodeIndex : topRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (topRightChildren.BottomLeftNode != null)
            {
                topRightChildren.BottomLeftNode.NodeNeighbours.LeftNeightbourIndex = topLeftChildren.BottomRightNode != null ? topLeftChildren.BottomRightNode.NodeIndices.NodeIndex : topLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }


            if (bottomLeftChildren.BottomRightNode != null)
            {
                bottomLeftChildren.BottomRightNode.NodeNeighbours.RightNeightbourIndex = bottomRightChildren.BottomLeftNode != null ? bottomRightChildren.BottomLeftNode.NodeIndices.NodeIndex : bottomRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (bottomRightChildren.BottomLeftNode != null)
            {
                bottomRightChildren.BottomLeftNode.NodeNeighbours.LeftNeightbourIndex = bottomLeftChildren.BottomRightNode != null ? bottomLeftChildren.BottomRightNode.NodeIndices.NodeIndex : bottomLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }


            if (bottomRightChildren.TopLeftNode != null)
            {
                bottomRightChildren.TopLeftNode.NodeNeighbours.LeftNeightbourIndex = bottomLeftChildren.TopRightNode != null ? bottomLeftChildren.TopRightNode.NodeIndices.NodeIndex : bottomLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (bottomLeftChildren.TopRightNode != null)
            {
                bottomLeftChildren.TopRightNode.NodeNeighbours.RightNeightbourIndex = bottomRightChildren.TopLeftNode != null ? bottomRightChildren.TopLeftNode.NodeIndices.NodeIndex : bottomRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            // Top-bottom (Should be 4 sets)
            if (topLeftChildren.BottomRightNode != null)
            {
                topLeftChildren.BottomRightNode.NodeNeighbours.BottomNeighbourIndex = bottomLeftChildren.TopRightNode != null ? bottomLeftChildren.TopRightNode.NodeIndices.NodeIndex : bottomLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (bottomLeftChildren.TopRightNode != null)
            {
                bottomLeftChildren.TopRightNode.NodeNeighbours.TopNeighbourIndex = topLeftChildren.BottomRightNode != null ? topLeftChildren.BottomRightNode.NodeIndices.NodeIndex : topLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }


            if (topLeftChildren.BottomLeftNode != null)
            {
                topLeftChildren.BottomLeftNode.NodeNeighbours.BottomNeighbourIndex = bottomLeftChildren.TopLeftNode != null ? bottomLeftChildren.TopLeftNode.NodeIndices.NodeIndex : bottomLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (bottomLeftChildren.TopLeftNode != null)
            {
                bottomLeftChildren.TopLeftNode.NodeNeighbours.TopNeighbourIndex = topLeftChildren.BottomLeftNode != null ? topLeftChildren.BottomLeftNode.NodeIndices.NodeIndex : topLeftChildren.ThisNode.NodeIndices.NodeIndex;
            }


            if (topRightChildren.BottomRightNode != null)
            {
                topRightChildren.BottomRightNode.NodeNeighbours.BottomNeighbourIndex = bottomRightChildren.TopRightNode != null ? bottomRightChildren.TopRightNode.NodeIndices.NodeIndex : bottomRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (bottomRightChildren.TopRightNode != null)
            {
                bottomRightChildren.TopRightNode.NodeNeighbours.TopNeighbourIndex = topRightChildren.BottomRightNode != null ? topRightChildren.BottomRightNode.NodeIndices.NodeIndex : topRightChildren.ThisNode.NodeIndices.NodeIndex;
            }


            if (bottomRightChildren.TopLeftNode != null)
            {
                bottomRightChildren.TopLeftNode.NodeNeighbours.TopNeighbourIndex = topRightChildren.BottomLeftNode != null ? topRightChildren.BottomLeftNode.NodeIndices.NodeIndex : topRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            if (topRightChildren.BottomLeftNode != null)
            {
                topRightChildren.BottomLeftNode.NodeNeighbours.BottomNeighbourIndex = bottomRightChildren.TopLeftNode != null ? bottomRightChildren.TopLeftNode.NodeIndices.NodeIndex : bottomRightChildren.ThisNode.NodeIndices.NodeIndex;
            }

            // Write new quadnodes back to quadnodes array.
            topLeftChildren.ReplaceQuadnodes();
            topRightChildren.ReplaceQuadnodes();
            bottomLeftChildren.ReplaceQuadnodes();
            bottomRightChildren.ReplaceQuadnodes();
            #endregion

            // Find children.
            if (childNodes.TopLeftNode != null)
            {
                FindNeighbourNodesRecursive(childNodes.TopLeftNode);
            }
            if (childNodes.TopRightNode != null)
            {
                FindNeighbourNodesRecursive(childNodes.TopRightNode);
            }
            if (childNodes.BottomLeftNode != null)
            {
                FindNeighbourNodesRecursive(childNodes.BottomLeftNode);
            }
            if (childNodes.BottomRightNode != null)
            {
                FindNeighbourNodesRecursive(childNodes.BottomRightNode);
            }
        }
 public void BufferedStreamReaderGetStructManaged(BufferedStreamReader bufferedStreamReader, out Quadnode randomInt)
 {
     bufferedStreamReader.Read(out randomInt, true);
 }