public long ParseBSP2DReferences(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Bsp2dReferences = new List <CollisionGeometry.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 CollisionGeometry.Bsp2dReference();

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

                bsp2dRef.PlaneIndex = (short)uplane_idx;

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

                bsp2dRef.Bsp2dNodeIndex = (short)ubsp2dnode_idx;

                bsp.Geometry.Bsp2dReferences.Add(bsp2dRef);
            }

            return(originalPos + (count * BSP2DREFERENCE_SIZE));
        }
        public long ParseEdges(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Edges = new List <CollisionGeometry.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 CollisionGeometry.Edge();

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

                bsp.Geometry.Edges.Add(edge);
            }

            return(originalPos + (count * EDGE_SIZE));
        }
        public long ParseLeaves(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Leaves = new List <CollisionGeometry.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 CollisionGeometry.Leaf();

                leaf.Flags = (CollisionGeometry.LeafFlags)flags;
                leaf.Bsp2dReferenceCount = (short)bsp2dRefCount;
                // ReForge change:
                // leaf.FirstBsp2dReference = (int)(((ushort)Unknown << 16) | (ushort)first2dRef);
                leaf.FirstBsp2dReference = (int)((ushort)first2dRef | (ushort)Unknown);

                bsp.Geometry.Leaves.Add(leaf);
            }

            return(originalPos + (count * LEAF_SIZE));
        }
        public long ParsePlanes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Planes = new List <CollisionGeometry.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 CollisionGeometry.Plane();

                // ReForge change:
                // plane.Value.I = plane_i;
                // plane.Value.J = plane_j;
                // plane.Value.K = plane_k;
                // plane.Value.D = plane_d;

                plane.Value = new RealPlane3d {
                    Normal = new RealVector3d(plane_i, plane_j, plane_k), Distance = plane_d
                };

                bsp.Geometry.Planes.Add(plane);
            }

            return(originalPos + (count * PLANE_SIZE));
        }
        public long ParseBSP3DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry            = new CollisionGeometry(); // adjusted to current struct
            bsp.Geometry.Bsp3dNodes = new List <CollisionGeometry.Bsp3dNode>();
            long originalPos = reader.BaseStream.Position;

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

                //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.Geometry.Bsp3dNodes.Add(bsp3dNode);
            }

            return(originalPos + (count * BSP3DNODE_SIZE));
        }
        public long ParseBSP2DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Bsp2dNodes = new List <CollisionGeometry.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 CollisionGeometry.Bsp2dNode();
                bsp2dNode.Plane.I = plane_i;
                bsp2dNode.Plane.J = plane_j;
                bsp2dNode.Plane.D = 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.Geometry.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 ParseVertices(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Vertices = new List <CollisionGeometry.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 CollisionGeometry.Vertex();

                vert.Point     = new RealPoint3d(point_x, point_y, point_z);
                vert.FirstEdge = (short)first_edge;

                bsp.Geometry.Vertices.Add(vert);
            }

            return(originalPos + (count * VERTEX_SIZE));
        }
        public long ParseSurfaces(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry.Surfaces = new List <CollisionGeometry.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();

                // ReForge change
                // var material = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                var material = (short)0;

                var surface = new CollisionGeometry.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             = (ushort)first_edge;
                surface.MaterialIndex         = material;
                surface.BreakableSurfaceIndex = breakable_surface;
                surface.Flags = (CollisionGeometry.SurfaceFlags)flags;

                bsp.Geometry.Surfaces.Add(surface);
            }
            return(originalPos + (count * SURFACE_SIZE));
        }
Exemplo n.º 10
0
        public long ParseBSP3DNodes(BSP bsp, BinaryReader reader, int count)
        {
            bsp.Geometry            = new CollisionGeometry(); // adjusted to current struct
            bsp.Geometry.Bsp3dNodes = new TagBlock <Bsp3dNode>();
            long originalPos = reader.BaseStream.Position;

            for (uint i = 0; i < count; ++i)
            {
                var bsp3dNode = new Bsp3dNode();
                reader.BaseStream.Position = originalPos + (i * BSP3DNODE_SIZE);

                bsp3dNode.Plane           = BitConverter.ToInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                bsp3dNode.FrontChildLower = reader.ReadBytes(1)[0];
                bsp3dNode.FrontChildMid   = reader.ReadBytes(1)[0];
                bsp3dNode.FrontChildUpper = reader.ReadBytes(1)[0];
                bsp3dNode.BackChildLower  = reader.ReadBytes(1)[0];
                bsp3dNode.BackChildMid    = reader.ReadBytes(1)[0];
                bsp3dNode.BackChildUpper  = reader.ReadBytes(1)[0];

                bsp.Geometry.Bsp3dNodes.Add(bsp3dNode);
            }

            return(originalPos + (count * BSP3DNODE_SIZE));
        }