public long ParseLeaves(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Leaves = new List <BSP.Leaf>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * LEAF_SIZE);
                var flags         = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                var bsp2dRefCount = BitConverter.ToUInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                var Unknown       = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var first2dRef    = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);

                var leaf = new BSP.Leaf();

                leaf.Flags = flags;
                leaf.Bsp2dReferenceCount = (short)bsp2dRefCount;
                leaf.Unknown             = (short)Unknown;
                leaf.FirstBsp2dReference = first2dRef;

                bsp.Leaves.Add(leaf);
            }

            return(originalPos + (count * LEAF_SIZE));
        }
        public long ParsePlanes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Planes = new List <BSP.Plane>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * PLANE_SIZE);
                var plane_i = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_j = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_k = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_d = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var plane = new BSP.Plane();

                plane.PlaneI = plane_i;
                plane.PlaneJ = plane_j;
                plane.PlaneK = plane_k;
                plane.PlaneD = plane_d;

                bsp.Planes.Add(plane);
            }

            return(originalPos + (count * PLANE_SIZE));
        }
        public long ParseBSP2DReferences(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Bsp2dReferences = new List <BSP.Bsp2dReference>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * BSP2DREFERENCE_SIZE);
                var plane_idx     = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var bsp2dnode_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var bsp2dRef = new BSP.Bsp2dReference();

                //truncate and preserve sign
                var uplane_idx = (plane_idx & 0x7fff);
                if (plane_idx < 0)
                {
                    uplane_idx |= 0x8000;
                }

                bsp2dRef.Plane = (short)uplane_idx;

                var ubsp2dnode_idx = (bsp2dnode_idx & 0x7fff);
                if (bsp2dnode_idx < 0)
                {
                    ubsp2dnode_idx |= 0x8000;
                }

                bsp2dRef.Bsp2dNode = (short)ubsp2dnode_idx;

                bsp.Bsp2dReferences.Add(bsp2dRef);
            }

            return(originalPos + (count * BSP2DREFERENCE_SIZE));
        }
        public long ParseSurfaces(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Surfaces = new List <BSP.Surface>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * SURFACE_SIZE);
                var plane_idx         = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var first_edge        = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var flags             = reader.ReadByte();
                var breakable_surface = reader.ReadByte();
                var material          = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);

                var surface = new BSP.Surface();

                //sign-compress the plane index
                var uplane_idx = (plane_idx & 0x7fff);
                if (plane_idx < 0)
                {
                    uplane_idx |= 0x8000;
                }

                surface.Plane = (short)uplane_idx;

                surface.FirstEdge        = (short)first_edge;
                surface.Material         = material;
                surface.BreakableSurface = breakable_surface;
                surface.Unknown2         = flags;

                bsp.Surfaces.Add(surface);
            }
            return(originalPos + (count * SURFACE_SIZE));
        }
        public long ParseEdges(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Edges = new List <BSP.Edge>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * EDGE_SIZE);
                var start_vert_idx    = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var end_vert_idx      = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var forward_edge_idx  = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var reverse_edge_idx  = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var left_surface_idx  = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var right_surface_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var edge = new BSP.Edge();

                edge.StartVertex  = (short)start_vert_idx;
                edge.EndVertex    = (short)end_vert_idx;
                edge.ForwardEdge  = (short)forward_edge_idx;
                edge.ReverseEdge  = (short)reverse_edge_idx;
                edge.LeftSurface  = (short)left_surface_idx;
                edge.RightSurface = (short)right_surface_idx;

                bsp.Edges.Add(edge);
            }

            return(originalPos + (count * EDGE_SIZE));
        }
        public long ParseVertices(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Vertices = new List <BSP.Vertex>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * VERTEX_SIZE);
                var point_x    = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var point_y    = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var point_z    = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var first_edge = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var vert = new BSP.Vertex();

                vert.PointX = point_x;
                vert.PointY = point_y;
                vert.PointZ = point_z;

                vert.FirstEdge = (short)first_edge;

                bsp.Vertices.Add(vert);
            }

            return(originalPos + (count * VERTEX_SIZE));
        }
        public long ParseBSP3DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Bsp3dNodes = new List <BSP.Bsp3dNode>();
            long originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                var bsp3dNode = new BSP.Bsp3dNode();
                reader.BaseStream.Position = originalPos + (i * BSP3DNODE_SIZE);
                var plane_idx   = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var back_child  = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var front_child = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                //compress back and front children to int24.

                //remove bits 24 and above
                var back_child_trun  = back_child & 0x7fffff;
                var front_child_trun = front_child & 0x7fffff;

                //add the new signs
                if (back_child < 0)
                {
                    back_child_trun |= 0x800000;
                }
                if (front_child < 0)
                {
                    front_child_trun |= 0x800000;
                }

                //truncate the plane index with control over the result
                int uplane_idx = (plane_idx & 0x7fff);
                if (plane_idx < 0)
                {
                    uplane_idx |= 0x8000;
                }

                //perhaps put message here to notify that plane index was out of the range

                bsp3dNode.Plane = (short)uplane_idx;

                bsp3dNode.BackChildLower = (byte)(back_child_trun & 0xff);
                bsp3dNode.BackChildMid   = (byte)((back_child_trun >> 8) & 0xff);
                bsp3dNode.BackChildUpper = (byte)((back_child_trun >> 16) & 0xff);

                bsp3dNode.FrontChildLower = (byte)(front_child_trun & 0xff);
                bsp3dNode.FrontChildMid   = (byte)((front_child_trun >> 8) & 0xff);
                bsp3dNode.FrontChildUpper = (byte)((front_child_trun >> 16) & 0xff);

                bsp.Bsp3dNodes.Add(bsp3dNode);
            }

            return(originalPos + (count * BSP3DNODE_SIZE));
        }
        public long ParseBSP(CollisionModel.Region.Permutation permutation, BinaryReader reader)
        {
            long originalPos = reader.BaseStream.Position;
            var  bsp         = new BSP();

            permutation.Bsps.Add(bsp);

            reader.BaseStream.Position = originalPos + BSP_BSP3DNODES_OFFSET;
            int n_3dnodes = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_PLANES_OFFSET;
            int n_planes = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_LEAVES_OFFSET;
            int n_leaves = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_BSP2DREFERENCES_OFFSET;
            int n_2dreferences = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_BSP2DNODES_OFFSET;
            int n_2dnodes = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_SURFACES_OFFSET;
            int n_surfaces = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_EDGES_OFFSET;
            int n_edges = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_VERTICES_OFFSET;
            int n_vertices = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_SIZE;
            reader.BaseStream.Position = ParseBSP3DNodes(bsp, reader, n_3dnodes);
            reader.BaseStream.Position = ParsePlanes(bsp, reader, n_planes);
            reader.BaseStream.Position = ParseLeaves(bsp, reader, n_leaves);
            reader.BaseStream.Position = ParseBSP2DReferences(bsp, reader, n_2dreferences);
            reader.BaseStream.Position = ParseBSP2DNodes(bsp, reader, n_2dnodes);
            reader.BaseStream.Position = ParseSurfaces(bsp, reader, n_surfaces);
            reader.BaseStream.Position = ParseEdges(bsp, reader, n_edges);
            return(ParseVertices(bsp, reader, n_vertices));
        }
        public long ParseBSP2DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Bsp2dNodes = new List <BSP.Bsp2dNode>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * BSP2DNODE_SIZE);
                var plane_i     = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_j     = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_d     = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var left_child  = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var right_child = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var bsp2dNode = new BSP.Bsp2dNode();
                bsp2dNode.PlaneI = plane_i;
                bsp2dNode.PlaneJ = plane_j;
                bsp2dNode.PlaneD = plane_d;

                //sign-compress left and right children to int16
                var uleft_child = left_child & 0x7fff;
                if (left_child < 0)
                {
                    uleft_child |= 0x8000;
                }

                bsp2dNode.LeftChild = (short)uleft_child;

                var uright_child = right_child & 0x7fff;
                if (right_child < 0)
                {
                    uright_child |= 0x8000;
                }

                bsp2dNode.RightChild = (short)uright_child;

                bsp.Bsp2dNodes.Add(bsp2dNode);
            }

            return(originalPos + (count * BSP2DNODE_SIZE));
        }
        public long ParseBSP(CollisionModel.Region.Permutation permutation, BinaryReader reader)
        {
            long originalPos = reader.BaseStream.Position;
            var bsp = new BSP();
            permutation.Bsps.Add(bsp);

            reader.BaseStream.Position = originalPos + BSP_BSP3DNODES_OFFSET;
            int n_3dnodes = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_PLANES_OFFSET;
            int n_planes = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_LEAVES_OFFSET;
            int n_leaves = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_BSP2DREFERENCES_OFFSET;
            int n_2dreferences = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_BSP2DNODES_OFFSET;
            int n_2dnodes = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_SURFACES_OFFSET;
            int n_surfaces = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_EDGES_OFFSET;
            int n_edges = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_VERTICES_OFFSET;
            int n_vertices = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

            reader.BaseStream.Position = originalPos + BSP_SIZE;
            reader.BaseStream.Position = ParseBSP3DNodes(bsp, reader, n_3dnodes);
            reader.BaseStream.Position = ParsePlanes(bsp, reader, n_planes);
            reader.BaseStream.Position = ParseLeaves(bsp, reader, n_leaves);
            reader.BaseStream.Position = ParseBSP2DReferences(bsp, reader, n_2dreferences);
            reader.BaseStream.Position = ParseBSP2DNodes(bsp, reader, n_2dnodes);
            reader.BaseStream.Position = ParseSurfaces(bsp, reader, n_surfaces);
            reader.BaseStream.Position = ParseEdges(bsp, reader, n_edges);
            return ParseVertices(bsp, reader, n_vertices);
        }
        public long ParsePlanes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Planes = new List<BSP.Plane>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * PLANE_SIZE);
                var plane_i = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_j = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_k = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_d = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var plane = new BSP.Plane();

                plane.PlaneI = plane_i;
                plane.PlaneJ = plane_j;
                plane.PlaneK = plane_k;
                plane.PlaneD = plane_d;

                bsp.Planes.Add(plane);
            }

            return originalPos + (count * PLANE_SIZE);
        }
        public long ParseLeaves(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Leaves = new List<BSP.Leaf>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * LEAF_SIZE);
                var flags = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                var bsp2dRefCount = BitConverter.ToUInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                var Unknown = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var first2dRef = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);

                var leaf = new BSP.Leaf();

                leaf.Flags = flags;
                leaf.Bsp2dReferenceCount = (short)bsp2dRefCount;
                leaf.Unknown = (short)Unknown;
                leaf.FirstBsp2dReference = first2dRef;

                bsp.Leaves.Add(leaf);
            }

            return originalPos + (count * LEAF_SIZE);
        }
        public long ParseBSP2DReferences(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Bsp2dReferences = new List<BSP.Bsp2dReference>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * BSP2DREFERENCE_SIZE);
                var plane_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var bsp2dnode_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var bsp2dRef = new BSP.Bsp2dReference();

                //truncate and preserve sign
                var uplane_idx = (plane_idx & 0x7fff);
                if (plane_idx < 0)
                    uplane_idx |= 0x8000;

                bsp2dRef.Plane = (short)uplane_idx;

                var ubsp2dnode_idx = (bsp2dnode_idx & 0x7fff);
                if (bsp2dnode_idx < 0)
                    ubsp2dnode_idx |= 0x8000;

                bsp2dRef.Bsp2dNode = (short)ubsp2dnode_idx;

                bsp.Bsp2dReferences.Add(bsp2dRef);
            }

            return originalPos + (count * BSP2DREFERENCE_SIZE);
        }
        public long ParseBSP2DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Bsp2dNodes = new List<BSP.Bsp2dNode>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * BSP2DNODE_SIZE);
                var plane_i = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_j = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var plane_d = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var left_child = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var right_child = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var bsp2dNode = new BSP.Bsp2dNode();
                bsp2dNode.PlaneI = plane_i;
                bsp2dNode.PlaneJ = plane_j;
                bsp2dNode.PlaneD = plane_d;

                //sign-compress left and right children to int16
                var uleft_child = left_child & 0x7fff;
                if (left_child < 0)
                    uleft_child |= 0x8000;

                bsp2dNode.LeftChild = (short)uleft_child;

                var uright_child = right_child & 0x7fff;
                if (right_child < 0)
                    uright_child |= 0x8000;

                bsp2dNode.RightChild = (short)uright_child;

                bsp.Bsp2dNodes.Add(bsp2dNode);
            }

            return originalPos + (count * BSP2DNODE_SIZE);
        }
        public long ParseSurfaces(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Surfaces = new List<BSP.Surface>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * SURFACE_SIZE);
                var plane_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var first_edge = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var flags = reader.ReadByte();
                var breakable_surface = reader.ReadByte();
                var material = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);

                var surface = new BSP.Surface();

                //sign-compress the plane index
                var uplane_idx = (plane_idx & 0x7fff);
                if (plane_idx < 0)
                    uplane_idx |= 0x8000;

                surface.Plane = (short)uplane_idx;

                surface.FirstEdge = (short)first_edge;
                surface.Material = material;
                surface.BreakableSurface = breakable_surface;
                surface.Unknown2 = flags;

                bsp.Surfaces.Add(surface);
            }
            return originalPos + (count * SURFACE_SIZE);
        }
        public long ParseEdges(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Edges = new List<BSP.Edge>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * EDGE_SIZE);
                var start_vert_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var end_vert_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var forward_edge_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var reverse_edge_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var left_surface_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var right_surface_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var edge = new BSP.Edge();

                edge.StartVertex = (short)start_vert_idx;
                edge.EndVertex = (short)end_vert_idx;
                edge.ForwardEdge = (short)forward_edge_idx;
                edge.ReverseEdge = (short)reverse_edge_idx;
                edge.LeftSurface = (short)left_surface_idx;
                edge.RightSurface = (short)right_surface_idx;

                bsp.Edges.Add(edge);
            }

            return originalPos + (count * EDGE_SIZE);
        }
        public long ParseBSP3DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Bsp3dNodes = new List<BSP.Bsp3dNode>();
            long originalPos = reader.BaseStream.Position;
            for (uint i = 0; i < count; ++i)
            {
                var bsp3dNode = new BSP.Bsp3dNode();
                reader.BaseStream.Position = originalPos + (i * BSP3DNODE_SIZE);
                var plane_idx = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var back_child = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var front_child = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                //compress back and front children to int24.

                //remove bits 24 and above
                var back_child_trun = back_child & 0x7fffff;
                var front_child_trun = front_child & 0x7fffff;

                //add the new signs
                if (back_child < 0)
                    back_child_trun |= 0x800000;
                if (front_child < 0)
                    front_child_trun |= 0x800000;

                //truncate the plane index with control over the result
                int uplane_idx = (plane_idx & 0x7fff);
                if (plane_idx < 0)
                    uplane_idx |= 0x8000;

                //perhaps put message here to notify that plane index was out of the range

                bsp3dNode.Plane = (short)uplane_idx;

                bsp3dNode.BackChildLower = (byte)(back_child_trun & 0xff);
                bsp3dNode.BackChildMid = (byte)((back_child_trun >> 8) & 0xff);
                bsp3dNode.BackChildUpper = (byte)((back_child_trun >> 16) & 0xff);

                bsp3dNode.FrontChildLower = (byte)(front_child_trun & 0xff);
                bsp3dNode.FrontChildMid = (byte)((front_child_trun >> 8) & 0xff);
                bsp3dNode.FrontChildUpper = (byte)((front_child_trun >> 16) & 0xff);

                bsp.Bsp3dNodes.Add(bsp3dNode);
            }

            return originalPos + (count * BSP3DNODE_SIZE);
        }
        public long ParseVertices(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Vertices = new List<BSP.Vertex>();
            var originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                reader.BaseStream.Position = originalPos + (i * VERTEX_SIZE);
                var point_x = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var point_y = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var point_z = BitConverter.ToSingle(reader.ReadBytes(4).Reverse().ToArray(), 0);
                var first_edge = BitConverter.ToInt32(reader.ReadBytes(4).Reverse().ToArray(), 0);

                var vert = new BSP.Vertex();

                vert.PointX = point_x;
                vert.PointY = point_y;
                vert.PointZ = point_z;

                vert.FirstEdge = (short)first_edge;

                bsp.Vertices.Add(vert);
            }

            return originalPos + (count * VERTEX_SIZE);
        }