/*
         *  Checks whether two axis aligned bounding boxes overlap.
         */
        public bool Overlaps(AxisBBox other)
        {
            //component entirely left of other bounding box
            if (highestX < other.lowestX)
            {
                return(false);
            }
            //component entirely right of other bounding box
            if (lowestX > other.highestX)
            {
                return(false);
            }

            //component entirely below other bounding box
            if (highestY < other.lowestY)
            {
                return(false);
            }
            //component entirely above other bounding box
            if (lowestY > other.highestY)
            {
                return(false);
            }

            //component entirely behind other bounding box
            if (highestZ < other.lowestZ)
            {
                return(false);
            }
            //component entirely ahead of other bounding box
            return(!(lowestZ > other.highestZ));
        }
        /*
         * Check if two edges collide with eachother.
         */
        public static bool EdgesCollide(Edge edge1, Edge edge2, NodeGraph nodeGraph1, NodeGraph nodeGraph2)
        {
            // Set up Edge1
            Node     edge1Node1   = nodeGraph1.GetNode(edge1.nodeIndex1);
            Node     edge1Node2   = nodeGraph1.GetNode(edge1.nodeIndex2);
            Vect3    edge1Forward = (edge1Node2.coordinate - edge1Node1.coordinate).GetNormalized();
            Vect3    edge1Right   = Vect3.Cross(edge1Forward, Vect3.Up).GetNormalized();
            Vect3    edge1Up      = Vect3.Cross(edge1Right, edge1Forward).GetNormalized();
            AxisBBox bBox1        = GetEdgeBoundingBox(edge1, edge1Node1.coordinate, edge1Node2.coordinate,
                                                       edge1Right, edge1Up);
            // Set up Edge2
            Node     edge2Node1   = nodeGraph2.GetNode(edge2.nodeIndex1);
            Node     edge2Node2   = nodeGraph2.GetNode(edge2.nodeIndex2);
            Vect3    edge2Forward = (edge2Node2.coordinate - edge2Node1.coordinate).GetNormalized();
            Vect3    edge2Right   = Vect3.Cross(edge2Forward, Vect3.Up).GetNormalized();
            Vect3    edge2Up      = Vect3.Cross(edge2Right, edge2Forward).GetNormalized();
            AxisBBox bBox2        = GetEdgeBoundingBox(edge2, edge2Node1.coordinate, edge2Node2.coordinate,
                                                       edge2Right, edge2Up);

            // Check BoundingBoxes
            if (bBox1.Overlaps(bBox2))
            {
                if (IsParallel2D((edge1Node1.coordinate.x, edge1Node1.coordinate.z), (edge1Node2.coordinate.x, edge1Node2.coordinate.z),
                                 (edge2Node1.coordinate.x, edge2Node1.coordinate.z), (edge2Node2.coordinate.x, edge2Node2.coordinate.z)))
                {
                    return(ParallelEdgesCollide(edge1, edge2, nodeGraph1, nodeGraph2));
                }
                else
                {
                    Vect3 edge1RightWall1 = edge1Node1.coordinate + ((edge1.width / 2) * edge1Right);
                    Vect3 edge1RightWall2 = edge1Node2.coordinate + ((edge1.width / 2) * edge1Right);
                    Vect3 edge2RightWall1 = edge2Node1.coordinate + ((edge2.width / 2) * edge2Right);
                    Vect3 edge2RightWall2 = edge2Node2.coordinate + ((edge2.width / 2) * edge2Right);

                    Vect3 edge1LeftWall1 = edge1Node1.coordinate - ((edge1.width / 2) * edge1Right);
                    Vect3 edge1LeftWall2 = edge1Node2.coordinate - ((edge1.width / 2) * edge1Right);
                    Vect3 edge2LeftWall1 = edge2Node1.coordinate - ((edge2.width / 2) * edge2Right);
                    Vect3 edge2LeftWall2 = edge2Node2.coordinate - ((edge2.width / 2) * edge2Right);
                    // Check all Possible wall collisions.
                    return(WallsIntersect(edge1, edge2, edge1RightWall1, edge1RightWall2, edge2RightWall1, edge2RightWall2) ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1RightWall2, edge2LeftWall1, edge2LeftWall2) ||
                           WallsIntersect(edge1, edge2, edge1LeftWall1, edge1LeftWall2, edge2RightWall1, edge2RightWall2) ||
                           WallsIntersect(edge1, edge2, edge1LeftWall1, edge1LeftWall2, edge2LeftWall1, edge2LeftWall2)
                           ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1LeftWall1, edge2RightWall1, edge2RightWall2) ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1LeftWall1, edge2LeftWall1, edge2LeftWall2) ||
                           WallsIntersect(edge1, edge2, edge1RightWall2, edge1LeftWall2, edge2RightWall1, edge2RightWall2) ||
                           WallsIntersect(edge1, edge2, edge1RightWall2, edge1LeftWall2, edge2LeftWall1, edge2LeftWall2)
                           ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1RightWall2, edge2RightWall1, edge2LeftWall1) ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1RightWall2, edge2RightWall2, edge2LeftWall2) ||
                           WallsIntersect(edge1, edge2, edge1LeftWall1, edge1LeftWall2, edge2RightWall1, edge2LeftWall1) ||
                           WallsIntersect(edge1, edge2, edge1LeftWall1, edge1LeftWall2, edge2RightWall2, edge2LeftWall2)
                           ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1LeftWall1, edge2RightWall1, edge2LeftWall1) ||
                           WallsIntersect(edge1, edge2, edge1RightWall1, edge1LeftWall1, edge2RightWall2, edge2LeftWall2) ||
                           WallsIntersect(edge1, edge2, edge1RightWall2, edge1LeftWall2, edge2RightWall1, edge2LeftWall1) ||
                           WallsIntersect(edge1, edge2, edge1RightWall2, edge1LeftWall2, edge2RightWall2, edge2LeftWall2));
                }
            }
        public void Expand(AxisBBox other)
        {
            this.highestX = this.highestX > other.highestX ? this.highestX : other.highestX;
            this.highestY = this.highestY > other.highestY ? this.highestY : other.highestY;
            this.highestZ = this.highestZ > other.highestZ ? this.highestZ : other.highestZ;

            this.lowestX = this.lowestX < other.lowestX ? this.lowestX : other.lowestX;
            this.lowestY = this.lowestY < other.lowestY ? this.lowestY : other.lowestY;
            this.lowestZ = this.lowestZ < other.lowestZ ? this.lowestZ : other.lowestZ;

            generatedCornerCoordinates = false;
        }
 /*
  *  Checks if a box contains an other box
  */
 public bool Contains(AxisBBox other)
 {
     return(lowestX <= other.lowestX && other.highestX <= highestX &&
            lowestY <= other.lowestY && other.highestY <= highestY &&
            lowestZ <= other.lowestZ && other.highestZ <= highestZ);
 }