Add BSP tree and LightTable parsing
This commit is contained in:
		
							parent
							
								
									d7fcf7a2d8
								
							
						
					
					
						commit
						bcc60eff52
					
				| 
						 | 
					@ -1,5 +1,3 @@
 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using System.Numerics;
 | 
					using System.Numerics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace KeepersCompound.LGS.Database.Chunks;
 | 
					namespace KeepersCompound.LGS.Database.Chunks;
 | 
				
			||||||
| 
						 | 
					@ -419,9 +417,179 @@ public class WorldRep : IChunk
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public struct BspTree
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public struct Node
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int parentIndex; // TODO: Split the flags out of this
 | 
				
			||||||
 | 
					            int cellId;
 | 
				
			||||||
 | 
					            int planeId;
 | 
				
			||||||
 | 
					            uint insideIndex;
 | 
				
			||||||
 | 
					            uint outsideIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public Node(BinaryReader reader)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                parentIndex = reader.ReadInt32();
 | 
				
			||||||
 | 
					                cellId = reader.ReadInt32();
 | 
				
			||||||
 | 
					                planeId = reader.ReadInt32();
 | 
				
			||||||
 | 
					                insideIndex = reader.ReadUInt32();
 | 
				
			||||||
 | 
					                outsideIndex = reader.ReadUInt32();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public readonly void Write(BinaryWriter writer)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                writer.Write(parentIndex);
 | 
				
			||||||
 | 
					                writer.Write(cellId);
 | 
				
			||||||
 | 
					                writer.Write(planeId);
 | 
				
			||||||
 | 
					                writer.Write(insideIndex);
 | 
				
			||||||
 | 
					                writer.Write(outsideIndex);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public uint PlaneCount;
 | 
				
			||||||
 | 
					        public uint NodeCount;
 | 
				
			||||||
 | 
					        public Plane[] Planes;
 | 
				
			||||||
 | 
					        public Node[] Nodes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BspTree(BinaryReader reader)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            PlaneCount = reader.ReadUInt32();
 | 
				
			||||||
 | 
					            Planes = new Plane[PlaneCount];
 | 
				
			||||||
 | 
					            for (var i = 0; i < PlaneCount; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Planes[i] = new Plane(reader.ReadVec3(), reader.ReadSingle());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            NodeCount = reader.ReadUInt32();
 | 
				
			||||||
 | 
					            Nodes = new Node[NodeCount];
 | 
				
			||||||
 | 
					            for (var i = 0; i < NodeCount; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Nodes[i] = new Node(reader);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public readonly void Write(BinaryWriter writer)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            writer.Write(PlaneCount);
 | 
				
			||||||
 | 
					            foreach (var plane in Planes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                writer.WriteVec3(plane.Normal);
 | 
				
			||||||
 | 
					                writer.Write(plane.D);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            writer.Write(NodeCount);
 | 
				
			||||||
 | 
					            foreach (var node in Nodes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                node.Write(writer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public struct LightTable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public struct LightData
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public Vector3 Location;
 | 
				
			||||||
 | 
					            public Vector3 Direction;
 | 
				
			||||||
 | 
					            public Vector3 Color;
 | 
				
			||||||
 | 
					            float InnerAngle; // I'm pretty sure these are the spotlight angles
 | 
				
			||||||
 | 
					            float OuterAngle;
 | 
				
			||||||
 | 
					            float Radius;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public LightData(BinaryReader reader)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Location = reader.ReadVec3();
 | 
				
			||||||
 | 
					                Direction = reader.ReadVec3();
 | 
				
			||||||
 | 
					                Color = reader.ReadVec3();
 | 
				
			||||||
 | 
					                InnerAngle = reader.ReadSingle();
 | 
				
			||||||
 | 
					                OuterAngle = reader.ReadSingle();
 | 
				
			||||||
 | 
					                Radius = reader.ReadSingle();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public readonly void Write(BinaryWriter writer)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                writer.WriteVec3(Location);
 | 
				
			||||||
 | 
					                writer.WriteVec3(Direction);
 | 
				
			||||||
 | 
					                writer.WriteVec3(Color);
 | 
				
			||||||
 | 
					                writer.Write(InnerAngle);
 | 
				
			||||||
 | 
					                writer.Write(OuterAngle);
 | 
				
			||||||
 | 
					                writer.Write(Radius);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public struct AnimCellMap
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public ushort CellIndex;
 | 
				
			||||||
 | 
					            public ushort LightIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public AnimCellMap(BinaryReader reader)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CellIndex = reader.ReadUInt16();
 | 
				
			||||||
 | 
					                LightIndex = reader.ReadUInt16();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public readonly void Write(BinaryWriter writer)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                writer.Write(CellIndex);
 | 
				
			||||||
 | 
					                writer.Write(LightIndex);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int LightCount;
 | 
				
			||||||
 | 
					        public int DynamicLightCount;
 | 
				
			||||||
 | 
					        public int AnimMapCount;
 | 
				
			||||||
 | 
					        public LightData[] Lights;
 | 
				
			||||||
 | 
					        public LightData[] ScratchpadLights;
 | 
				
			||||||
 | 
					        public AnimCellMap[] AnimCellMaps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: Support olddark
 | 
				
			||||||
 | 
					        public LightTable(BinaryReader reader)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LightCount = reader.ReadInt32();
 | 
				
			||||||
 | 
					            DynamicLightCount = reader.ReadInt32();
 | 
				
			||||||
 | 
					            Lights = new LightData[LightCount + DynamicLightCount];
 | 
				
			||||||
 | 
					            for (var i = 0; i < Lights.Length; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Lights[i] = new LightData(reader);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ScratchpadLights = new LightData[32];
 | 
				
			||||||
 | 
					            for (var i = 0; i < ScratchpadLights.Length; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ScratchpadLights[i] = new LightData(reader);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            AnimMapCount = reader.ReadInt32();
 | 
				
			||||||
 | 
					            AnimCellMaps = new AnimCellMap[AnimMapCount];
 | 
				
			||||||
 | 
					            for (var i = 0; i < AnimCellMaps.Length; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                AnimCellMaps[i] = new AnimCellMap(reader);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public readonly void Write(BinaryWriter writer)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            writer.Write(LightCount);
 | 
				
			||||||
 | 
					            writer.Write(DynamicLightCount);
 | 
				
			||||||
 | 
					            foreach (var light in Lights)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                light.Write(writer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            foreach (var light in ScratchpadLights)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                light.Write(writer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            writer.Write(AnimMapCount);
 | 
				
			||||||
 | 
					            foreach (var map in AnimCellMaps)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                map.Write(writer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ChunkHeader Header { get; set; }
 | 
					    public ChunkHeader Header { get; set; }
 | 
				
			||||||
    public WrHeader DataHeader { get; set; }
 | 
					    public WrHeader DataHeader { get; set; }
 | 
				
			||||||
    public Cell[] Cells { get; set; }
 | 
					    public Cell[] Cells { get; set; }
 | 
				
			||||||
 | 
					    public BspTree Bsp { get; set; }
 | 
				
			||||||
 | 
					    public LightTable LightingTable { get; set; }
 | 
				
			||||||
 | 
					    private byte[] _unknown;
 | 
				
			||||||
    private byte[] _unreadData;
 | 
					    private byte[] _unreadData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void ReadData(BinaryReader reader, DbFile.TableOfContents.Entry entry)
 | 
					    public void ReadData(BinaryReader reader, DbFile.TableOfContents.Entry entry)
 | 
				
			||||||
| 
						 | 
					@ -435,6 +603,12 @@ public class WorldRep : IChunk
 | 
				
			||||||
            Cells[i] = new Cell(reader, bpp);
 | 
					            Cells[i] = new Cell(reader, bpp);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Bsp = new BspTree(reader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: Work out what this is
 | 
				
			||||||
 | 
					        _unknown = reader.ReadBytes(Cells.Length);
 | 
				
			||||||
 | 
					        LightingTable = new LightTable(reader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO: All the other info lol
 | 
					        // TODO: All the other info lol
 | 
				
			||||||
        var length = entry.Offset + entry.Size + 24 - reader.BaseStream.Position;
 | 
					        var length = entry.Offset + entry.Size + 24 - reader.BaseStream.Position;
 | 
				
			||||||
        _unreadData = reader.ReadBytes((int)length);
 | 
					        _unreadData = reader.ReadBytes((int)length);
 | 
				
			||||||
| 
						 | 
					@ -447,6 +621,9 @@ public class WorldRep : IChunk
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            cell.Write(writer);
 | 
					            cell.Write(writer);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        Bsp.Write(writer);
 | 
				
			||||||
 | 
					        writer.Write(_unknown);
 | 
				
			||||||
 | 
					        LightingTable.Write(writer);
 | 
				
			||||||
        writer.Write(_unreadData);
 | 
					        writer.Write(_unreadData);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue