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));
        }
Ejemplo n.º 2
0
        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 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 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);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Gets the vertex indices for a polygon of a surface of a BSP
        /// </summary>
        /// <param name="surface_idx"></param>
        /// <param name="edges"></param>
        /// <param name="current_edge_idx"></param>
        /// <returns></returns>
        private static List<ushort> vertLoopFromSurface(int surface_idx, BSP bsp)
        {
            //Variables
            ushort current_edge_idx = bsp.Surfaces[surface_idx].FirstEdge;

            //Get the indexed 'first edge' of the surface
            BSP.Edge edge = bsp.Edges[current_edge_idx];
            //A loop will have been completed when the first edge is encountered again
            BSP.Edge first_edge = edge;
            //The indices of the n-gon's loop of vertex
            List<ushort> loop_indices = new List<ushort>();
            //The last vertex index encountered
            int last_vertex_idx;

            //A special case for the first edge- must add start and end vertices

            //When the current surface is to the right of the edge then moving from
            // the start-vertex to the end-vertex is done automatically in a clockwise
            // order.
            if (surface_idx == edge.RightSurface)
            {
                loop_indices.Add(edge.StartVertex);
                loop_indices.Add(edge.EndVertex);
                last_vertex_idx = edge.EndVertex;
                edge = bsp.Edges[edge.ForwardEdge];
            }
            else
            //However if the current surface is to the left of the edge then it is
            // anti-clockwise and the ordering must be changed manually.
            {
                loop_indices.Add(edge.EndVertex);
                loop_indices.Add(edge.StartVertex);
                last_vertex_idx = edge.StartVertex;
                edge = bsp.Edges[edge.ReverseEdge];
            }

            //Complete a traversal of edges around a surface to get the indices
            // of all the vertices. This will make a n-gon that can be reduced
            // to tris.
            while (edge != first_edge)
            {
                /*
                if (edge.ForwardEdge >= bsp.Edges.Count || edge.ForwardEdge < 0
                    || edge.ReverseEdge >= bsp.Edges.Count || edge.ReverseEdge < 0)
                {
                    Console.WriteLine("Degenerate edge detected:\nForward: {0}, Reverse: {1}.", edge.ForwardEdge, edge.ReverseEdge);

                    if (edge.ReverseEdge < 0)
                        edge.ReverseEdge = (short)-edge.ReverseEdge;

                    if (edge.ForwardEdge < 0)
                        edge.ForwardEdge = (short)-edge.ForwardEdge;
                }
                */
                if (edge.RightSurface == surface_idx)
                {
                    loop_indices.Add(edge.EndVertex);
                    last_vertex_idx = edge.EndVertex;
                    edge = bsp.Edges[edge.ForwardEdge];
                }
                else if (edge.LeftSurface == surface_idx)
                {
                    loop_indices.Add(edge.StartVertex);
                    last_vertex_idx = edge.StartVertex;
                    edge = bsp.Edges[edge.ReverseEdge];
                }
                else {
                    if (edge.StartVertex == last_vertex_idx)
                    {
                        edge = bsp.Edges[edge.ReverseEdge]; //the previous edge must have ended on the vertex
                    }
                    else if (edge.EndVertex == last_vertex_idx)
                    {
                        edge = bsp.Edges[edge.ForwardEdge]; //the next edge must begin on the vertex
                    }
                    else {
                        //Neither are the last vertex index. This means
                        // the traversal went off the loop mysteriously,
                        // perhaps due to incorrect data.
                        //Console.WriteLine("'vertLoopFromSurface' traversal left edge loop with no way back");
                        return loop_indices;
                    }
                }
            }
            return loop_indices;
        }
        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 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 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 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);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Uses the winged edge adjacency model of the BSP
        /// to output a visual representation as an OBJ file.
        /// </summary>
        public static void toOBJ(BSP bsp, string fpath)
        {
            using (var objFile = new StreamWriter(File.Open(fpath, FileMode.Create, FileAccess.Write)))
            {

                List<Tuple<int, int, int>> triples = new List<Tuple<int, int, int>>();
                for (int i = 0; i < bsp.Surfaces.Count; ++i)
                {
                    List<ushort> loop = vertLoopFromSurface(i, bsp);
                    if (loop == null)
                    {
                        Console.WriteLine("Failed to get loop for surface {0}.", i);
                        return;
                    }
                    if (loop.Count == 0)
                    {
                        Console.WriteLine("Failed to get loop for surface {0}. Skipping.", i);
                    }

                    //Below is how to triangulate an n-gon where the first vertex index
                    // is also the last. If the last index was not the first, one more
                    // loop would have to occur (i.e  condition: 'j < loop.Count -2')
                    for (int j = 0; j < loop.Count - 3; ++j)
                    {
                        //Tuple indices are ordered so that the surfaces face outward
                        triples.Add(new Tuple<int, int, int>(loop[j + 1], loop[0], loop[j + 2]));
                    }
                }

                objFile.WriteLine("o bsp");
                foreach(BSP.Vertex v in bsp.Vertices)
                {
                    objFile.WriteLine("v {0} {1} {2}", v.PointX, v.PointY, v.PointZ);
                }
                objFile.WriteLine("s off");

                foreach (Tuple<int, int, int> f in triples)
                {
                    //obj files begin numbering at 1 for vertices. Must add 1 to each index
                    objFile.WriteLine("f {0} {1} {2}", f.Item1+1, f.Item2+1, f.Item3+1);
                }

                objFile.Close();
            }
        }
        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 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);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Initialises a BSP with the correct number of elements for each
        /// of the eight lists.
        /// </summary>
        /// <param name="sbsp"></param>
        /// <returns></returns>
        private static BSP fromSbspInit(ScenarioStructureBsp sbsp)
        {
            BSP bsp = new BSP();
            //Resource 3 of the sbsp tag has bsp data
            var resource = sbsp.Resource3;
            BinaryReader rsrcDef = new BinaryReader(new MemoryStream(resource.DefinitionData));

            //The position in the resource definition for the number of bsp3dnodes
            rsrcDef.BaseStream.Position = 0;
            //set initial size (not capacity) to the number read from the reader
            bsp.Bsp3dNodes = new List<BSP.Bsp3dNode>(new BSP.Bsp3dNode[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Bsp3dNodes", bsp.Bsp3dNodes.Count);

            //Position for number of planes
            rsrcDef.BaseStream.Position = 12;
            bsp.Planes = new List<BSP.Plane>(new BSP.Plane[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Planes", bsp.Planes.Count);

            //Position for number of leaves
            rsrcDef.BaseStream.Position = 24;
            bsp.Leaves = new List<BSP.Leaf>(new BSP.Leaf[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Leaves", bsp.Leaves.Count);

            //Position for number of bsp2dreferences
            rsrcDef.BaseStream.Position = 36;
            bsp.Bsp2dReferences = new List<BSP.Bsp2dReference>(new BSP.Bsp2dReference[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Bsp2dReferences", bsp.Bsp2dReferences.Count);

            //Position for number of bsp2dnodes
            rsrcDef.BaseStream.Position = 48;
            bsp.Bsp2dNodes = new List<BSP.Bsp2dNode>(new BSP.Bsp2dNode[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Bsp2dNodes", bsp.Bsp2dNodes.Count);

            //Position for number of surfaces
            rsrcDef.BaseStream.Position = 60;
            bsp.Surfaces = new List<BSP.Surface>(new BSP.Surface[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Surfaces", bsp.Surfaces.Count);

            //Position for number of edges
            rsrcDef.BaseStream.Position = 72;
            bsp.Edges = new List<BSP.Edge>(new BSP.Edge[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Edges", bsp.Edges.Count);

            //Position for number of vertices
            rsrcDef.BaseStream.Position = 84;
            bsp.Vertices = new List<BSP.Vertex>(new BSP.Vertex[rsrcDef.ReadInt32()]);
            Console.WriteLine("{0} Vertices", bsp.Vertices.Count);

            return bsp;
        }