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); }
/// <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; }