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 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);
        }
Пример #3
0
        /// <summary>
        /// Creates a CollisionModel bsp from a Scenario StructureBsp.
        /// This does not work for sbsps with > 65536 planes, which use a
        ///  larger encoding for their bsp related structs differing from the
        ///  struct used in common with collision model bsps.
        /// </summary>
        /// <returns></returns>
        public static BSP fromSbsp(ScenarioStructureBsp sbsp, OpenTagCache info)
        {
            // Need to work out how to do that class attribute enumeration thing
            // so all of this folds down to < 10 lines
            BSP bsp = fromSbspInit(sbsp);
            var resource = sbsp.Resource3;
            var resourceManager = new ResourceDataManager();
            try
            {
                resourceManager.LoadCachesFromDirectory(info.CacheFile.DirectoryName);
            }
            catch
            {
                Console.WriteLine("Unable to load the resource .dat files.");
                Console.WriteLine("Make sure that they all exist and are valid.");
            }

            //Create a binary reader for the resource
            Stream stream = new MemoryStream();
            resourceManager.Extract(sbsp.Resource3, stream);
            BinaryReader reader = new BinaryReader(stream);
            reader.BaseStream.Position = 0;
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Bsp3dNodes.Count; ++i)
            {
                BSP.Bsp3dNode node = new BSP.Bsp3dNode();
                node.Plane = reader.ReadInt16();
                node.BackChildLower = reader.ReadByte();
                node.BackChildMid = reader.ReadByte();
                node.BackChildUpper = reader.ReadByte();
                node.FrontChildLower = reader.ReadByte();
                node.FrontChildMid = reader.ReadByte();
                node.FrontChildUpper = reader.ReadByte();
                bsp.Bsp3dNodes[i] = node;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Planes.Count; ++i)
            {
                BSP.Plane plane = new BSP.Plane();
                plane.PlaneI = reader.ReadSingle();
                plane.PlaneJ = reader.ReadSingle();
                plane.PlaneK = reader.ReadSingle();
                plane.PlaneD = reader.ReadSingle();
                bsp.Planes[i] = plane;
            }

            //Put here for consistency
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Leaves.Count; ++i)
            {
                BSP.Leaf leaf = new BSP.Leaf();
                leaf.Flags = reader.ReadInt16();
                leaf.Bsp2dReferenceCount = reader.ReadInt16();
                leaf.Unknown = reader.ReadInt16();
                leaf.FirstBsp2dReference = reader.ReadInt16();
                bsp.Leaves[i] = leaf;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Bsp2dReferences.Count; ++i)
            {
                BSP.Bsp2dReference bsp2dref = new BSP.Bsp2dReference();
                bsp2dref.Plane = reader.ReadInt16();
                bsp2dref.Bsp2dNode = reader.ReadInt16();
                bsp.Bsp2dReferences[i] = bsp2dref;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Bsp2dNodes.Count; ++i)
            {
                BSP.Bsp2dNode node = new BSP.Bsp2dNode();
                node.PlaneI = reader.ReadSingle();
                node.PlaneJ = reader.ReadSingle();
                node.PlaneD = reader.ReadSingle();
                node.LeftChild = reader.ReadInt16();
                node.RightChild = reader.ReadInt16();
                bsp.Bsp2dNodes[i] = node;
            }

            //Put here for consistency
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Surfaces.Count; ++i)
            {
                BSP.Surface surface = new BSP.Surface();
                surface.Plane = reader.ReadUInt16();
                surface.FirstEdge = reader.ReadUInt16();
                surface.Material = reader.ReadInt16();
                surface.Unknown = reader.ReadInt16();
                surface.BreakableSurface = reader.ReadInt16();
                surface.Unknown2 = reader.ReadInt16();
                bsp.Surfaces[i] = surface;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Edges.Count; ++i)
            {
                BSP.Edge edge = new BSP.Edge();
                edge.StartVertex = reader.ReadUInt16();
                edge.EndVertex = reader.ReadUInt16();
                edge.ForwardEdge = reader.ReadUInt16();
                edge.ReverseEdge = reader.ReadUInt16();
                edge.LeftSurface = reader.ReadUInt16();
                edge.RightSurface = reader.ReadUInt16();
                bsp.Edges[i] = edge;
            }

            //Align to the next multiple of 16
            reader.BaseStream.Position = -((-reader.BaseStream.Position) & ~0xf);
            Console.WriteLine("Stream position: {0:X8}", reader.BaseStream.Position);
            for (int i = 0; i < bsp.Vertices.Count; ++i)
            {
                BSP.Vertex vert = new BSP.Vertex();
                vert.PointX = reader.ReadSingle();
                vert.PointY = reader.ReadSingle();
                vert.PointZ = reader.ReadSingle();
                vert.FirstEdge = reader.ReadInt16();
                vert.Unknown = reader.ReadInt16();
                bsp.Vertices[i] = vert;
            }

            return bsp;
        }