public void ConvertBsp(BspLoader bspLoader, float scaling) { Vector3 playerStart = new Vector3(0, 0, 100); if (bspLoader.FindVectorByName("info_player_start", ref playerStart) == false) { bspLoader.FindVectorByName("info_player_deathmatch", ref playerStart); } playerStart[2] += 20.0f * scaling; //start a bit higher foreach (BspLeaf leaf in bspLoader.Leaves) { bool isValidBrush = false; for (int b = 0; b < leaf.NumLeafBrushes; b++) { AlignedVector3Array planeEquations = new AlignedVector3Array(); int brushID = bspLoader.LeafBrushes[leaf.FirstLeafBrush + b]; BspBrush brush = bspLoader.Brushes[brushID]; if (brush.ShaderNum != -1) { if ((bspLoader.Shaders[brush.ShaderNum].ContentFlags & ContentFlags.Solid) == ContentFlags.Solid) { brush.ShaderNum = -1; for (int p = 0; p < brush.NumSides; p++) { int sideid = brush.FirstSide + p; BspBrushSide brushside = bspLoader.BrushSides[sideid]; int planeid = brushside.PlaneNum; BspPlane plane = bspLoader.Planes[planeid]; Vector4 planeEq = new Vector4(plane.Normal, scaling * -plane.Distance); planeEquations.Add(planeEq); isValidBrush = true; } if (isValidBrush) { AlignedVector3Array vertices; GeometryUtil.GetVerticesFromPlaneEquations(planeEquations, out vertices); bool isEntity = false; Vector3 entityTarget = Vector3.Zero; AddConvexVerticesCollider(vertices, isEntity, entityTarget); } } } } } foreach (BspEntity entity in bspLoader.Entities) { if (entity.ClassName == "trigger_push") { } } }
public bool LoadBspFile(Stream buffer) { BinaryReader reader = new BinaryReader(buffer); BspLump[] lumps = new BspLump[17]; // read header string id = Encoding.ASCII.GetString(reader.ReadBytes(4), 0, 4); int version = reader.ReadInt32(); if (id != "IBSP" || version != 0x2E) return false; for (int i = 0; i < lumps.Length; i++) { lumps[i].Offset = reader.ReadInt32(); lumps[i].Length = reader.ReadInt32(); } // read brushes buffer.Position = lumps[(int)BspLumpType.Brushes].Offset; int length = lumps[(int)BspLumpType.Brushes].Length / Marshal.SizeOf(typeof(BspBrush)); Brushes = new BspBrush[length]; for (int i = 0; i < length; i++) { Brushes[i].FirstSide = reader.ReadInt32(); Brushes[i].NumSides = reader.ReadInt32(); Brushes[i].ShaderNum = reader.ReadInt32(); } // read brush sides buffer.Position = lumps[(int)BspLumpType.BrushSides].Offset; length = lumps[(int)BspLumpType.BrushSides].Length / Marshal.SizeOf(typeof(BspBrushSide)); BrushSides = new BspBrushSide[length]; for (int i = 0; i < length; i++) { BrushSides[i].PlaneNum = reader.ReadInt32(); BrushSides[i].ShaderNum = reader.ReadInt32(); } // read entities Entities = new List<BspEntity>(); buffer.Position = lumps[(int)BspLumpType.Entities].Offset; length = lumps[(int)BspLumpType.Entities].Length; byte[] entityBytes = new byte[length]; reader.Read(entityBytes, 0, length); string entityString = Encoding.ASCII.GetString(entityBytes); string[] entityStrings = entityString.Split('\n'); BspEntity bspEntity = null; foreach (string entity in entityStrings) { switch (entity) { case "\0": continue; case "{": bspEntity = new BspEntity(); break; case "}": Entities.Add(bspEntity); break; default: string[] keyValue = entity.Trim('\"').Split(new string[] { "\" \"" }, 2, 0); if (keyValue[0] == "classname") { bspEntity.ClassName = keyValue[1]; } else if (keyValue[0] == "origin") { string[] originStrings = keyValue[1].Split(' '); bspEntity.Origin = new Vector3( float.Parse(originStrings[0], CultureInfo.InvariantCulture), float.Parse(originStrings[1], CultureInfo.InvariantCulture), float.Parse(originStrings[2], CultureInfo.InvariantCulture)); } else { bspEntity.KeyValues.Add(keyValue[0], keyValue[1]); } break; } } // read leaves buffer.Position = lumps[(int)BspLumpType.Leaves].Offset; length = lumps[(int)BspLumpType.Leaves].Length / Marshal.SizeOf(typeof(BspLeaf)); Leaves = new BspLeaf[length]; for (int i = 0; i < length; i++ ) { Leaves[i].Cluster = reader.ReadInt32(); Leaves[i].Area = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Min.X = reader.ReadInt32(); Leaves[i].Min.Z = -reader.ReadInt32(); Leaves[i].Min.Y = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Max.X = reader.ReadInt32(); Leaves[i].Max.Z = -reader.ReadInt32(); Leaves[i].Max.Y = reader.ReadInt32(); Leaves[i].FirstLeafFace = reader.ReadInt32(); Leaves[i].NumLeafFaces = reader.ReadInt32(); Leaves[i].FirstLeafBrush = reader.ReadInt32(); Leaves[i].NumLeafBrushes = reader.ReadInt32(); } // read leaf brushes buffer.Position = lumps[(int)BspLumpType.LeafBrushes].Offset; length = lumps[(int)BspLumpType.LeafBrushes].Length / sizeof(int); LeafBrushes = new int[length]; for (int i = 0; i < length; i++) { LeafBrushes[i] = reader.ReadInt32(); } // read planes buffer.Position = lumps[(int)BspLumpType.Planes].Offset; length = lumps[(int)BspLumpType.Planes].Length / Marshal.SizeOf(typeof(BspPlane)); Planes = new BspPlane[length]; for (int i = 0; i < length; i++) { Planes[i].Normal.X = reader.ReadSingle(); Planes[i].Normal.Y = reader.ReadSingle(); Planes[i].Normal.Z = reader.ReadSingle(); Planes[i].Distance = reader.ReadSingle(); } // read shaders Shaders = new List<BspShader>(); buffer.Position = lumps[(int)BspLumpType.Shaders].Offset; length = lumps[(int)BspLumpType.Shaders].Length; for (int i = 0; i < length; i += (64 + 2 * sizeof(int))) { BspShader shader = new BspShader(); byte[] shaderBytes = new byte[64]; reader.Read(shaderBytes, 0, 64); shader.Shader = Encoding.ASCII.GetString(shaderBytes); shader.SurfaceFlags = reader.ReadInt32(); shader.ContentFlags = (ContentFlags)reader.ReadInt32(); Shaders.Add(shader); } return true; }
public bool LoadBspFile(Stream buffer) { BinaryReader reader = new BinaryReader(buffer); // read header string id = Encoding.ASCII.GetString(reader.ReadBytes(4), 0, 4); int version = reader.ReadInt32(); if (id != "IBSP" && id != "VBSP") { return(false); } int nHeaderLumps; if (id == "IBSP") { if (version != 0x2E) { return(false); } nHeaderLumps = 17; } else// if (id == "VBSP") { if (version != 0x14) { return(false); } nHeaderLumps = 64; IsVbsp = true; } BspLump[] lumps = new BspLump[nHeaderLumps]; for (int i = 0; i < lumps.Length; i++) { lumps[i].Offset = reader.ReadInt32(); lumps[i].Length = reader.ReadInt32(); if (IsVbsp) { reader.ReadInt32(); // lump format version reader.ReadInt32(); // lump ident code } } // read brushes int lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.Brushes : (int)IBspLumpType.Brushes; buffer.Position = lumps[lumpHeaderOffset].Offset; int length = lumps[lumpHeaderOffset].Length / Marshal.SizeOf(typeof(BspBrush)); Brushes = new BspBrush[length]; for (int i = 0; i < length; i++) { Brushes[i].FirstSide = reader.ReadInt32(); Brushes[i].NumSides = reader.ReadInt32(); Brushes[i].ShaderNum = reader.ReadInt32(); } // read brush sides lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.BrushSides : (int)IBspLumpType.BrushSides; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length / Marshal.SizeOf(typeof(BspBrushSide)); BrushSides = new BspBrushSide[length]; for (int i = 0; i < length; i++) { if (IsVbsp) { BrushSides[i].PlaneNum = reader.ReadUInt16(); reader.ReadInt16(); // texinfo BrushSides[i].ShaderNum = reader.ReadInt16(); reader.ReadInt16(); // bevel } else { BrushSides[i].PlaneNum = reader.ReadInt32(); BrushSides[i].ShaderNum = reader.ReadInt32(); } } // read entities Entities = new List <BspEntity>(); buffer.Position = lumps[(int)IBspLumpType.Entities].Offset; length = lumps[(int)IBspLumpType.Entities].Length; byte[] entityBytes = new byte[length]; reader.Read(entityBytes, 0, length); string entityString = Encoding.ASCII.GetString(entityBytes); string[] entityStrings = entityString.Split('\n'); BspEntity bspEntity = null; foreach (string entity in entityStrings) { switch (entity) { case "\0": continue; case "{": bspEntity = new BspEntity(); break; case "}": Entities.Add(bspEntity); break; default: string[] keyValue = entity.Trim('\"').Split(new[] { "\" \"" }, 2, 0); switch (keyValue[0]) { case "classname": bspEntity.ClassName = keyValue[1]; break; case "origin": string[] originStrings = keyValue[1].Split(' '); bspEntity.Origin = new Vector3( float.Parse(originStrings[0], CultureInfo.InvariantCulture), float.Parse(originStrings[1], CultureInfo.InvariantCulture), float.Parse(originStrings[2], CultureInfo.InvariantCulture)); break; default: if (!bspEntity.KeyValues.ContainsKey(keyValue[0])) { if (keyValue.Length == 1) { bspEntity.KeyValues.Add(keyValue[0], ""); } else { bspEntity.KeyValues.Add(keyValue[0], keyValue[1]); } } break; } break; } } // read leaves lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.Leafs : (int)IBspLumpType.Leaves; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length; length /= IsVbsp ? 32 : Marshal.SizeOf(typeof(BspLeaf)); Leaves = new BspLeaf[length]; for (int i = 0; i < length; i++) { if (IsVbsp) { reader.ReadInt32(); // contents Leaves[i].Cluster = reader.ReadInt16(); Leaves[i].Area = reader.ReadInt16(); //Swap Y and Z; invert Z Leaves[i].Min.X = reader.ReadInt16(); Leaves[i].Min.Z = -reader.ReadInt16(); Leaves[i].Min.Y = reader.ReadInt16(); //Swap Y and Z; invert Z Leaves[i].Max.X = reader.ReadInt16(); Leaves[i].Max.Z = -reader.ReadInt16(); Leaves[i].Max.Y = reader.ReadInt16(); Leaves[i].FirstLeafFace = reader.ReadUInt16(); Leaves[i].NumLeafFaces = reader.ReadUInt16(); Leaves[i].FirstLeafBrush = reader.ReadUInt16(); Leaves[i].NumLeafBrushes = reader.ReadUInt16(); reader.ReadInt16(); // leafWaterDataID //reader.ReadInt16(); // ambientLighting //reader.ReadSByte(); // ambientLighting reader.ReadInt16(); // padding } else { Leaves[i].Cluster = reader.ReadInt32(); Leaves[i].Area = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Min.X = reader.ReadInt32(); Leaves[i].Min.Z = -reader.ReadInt32(); Leaves[i].Min.Y = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Max.X = reader.ReadInt32(); Leaves[i].Max.Z = -reader.ReadInt32(); Leaves[i].Max.Y = reader.ReadInt32(); Leaves[i].FirstLeafFace = reader.ReadInt32(); Leaves[i].NumLeafFaces = reader.ReadInt32(); Leaves[i].FirstLeafBrush = reader.ReadInt32(); Leaves[i].NumLeafBrushes = reader.ReadInt32(); } } // read leaf brushes lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.LeafBrushes : (int)IBspLumpType.LeafBrushes; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length; length /= IsVbsp ? sizeof(short) : sizeof(int); LeafBrushes = new int[length]; for (int i = 0; i < length; i++) { if (IsVbsp) { LeafBrushes[i] = reader.ReadInt16(); } else { LeafBrushes[i] = reader.ReadInt32(); } } // read planes lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.Planes : (int)IBspLumpType.Planes; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length; length /= IsVbsp ? (Marshal.SizeOf(typeof(BspPlane)) + sizeof(int)) : Marshal.SizeOf(typeof(BspPlane)); Planes = new BspPlane[length]; for (int i = 0; i < length; i++) { Planes[i].Normal.X = reader.ReadSingle(); Planes[i].Normal.Y = reader.ReadSingle(); Planes[i].Normal.Z = reader.ReadSingle(); Planes[i].Distance = reader.ReadSingle(); if (IsVbsp) { reader.ReadInt32(); // type } } if (!IsVbsp) { // read shaders Shaders = new List <BspShader>(); buffer.Position = lumps[(int)IBspLumpType.Shaders].Offset; length = lumps[(int)IBspLumpType.Shaders].Length / (64 + 2 * sizeof(int)); byte[] shaderBytes = new byte[64]; for (int i = 0; i < length; i++) { BspShader shader = new BspShader(); reader.Read(shaderBytes, 0, 64); shader.Shader = Encoding.ASCII.GetString(shaderBytes, 0, Array.IndexOf(shaderBytes, (byte)0)); shader.SurfaceFlags = reader.ReadInt32(); shader.ContentFlags = (ContentFlags)reader.ReadInt32(); Shaders.Add(shader); } } return(true); }
public bool LoadBspFile(Stream buffer) { BinaryReader reader = new BinaryReader(buffer); BspLump[] lumps = new BspLump[17]; // read header string id = Encoding.ASCII.GetString(reader.ReadBytes(4), 0, 4); int version = reader.ReadInt32(); if (id != "IBSP" || version != 0x2E) { return(false); } for (int i = 0; i < lumps.Length; i++) { lumps[i].Offset = reader.ReadInt32(); lumps[i].Length = reader.ReadInt32(); } // read brushes buffer.Position = lumps[(int)BspLumpType.Brushes].Offset; int length = lumps[(int)BspLumpType.Brushes].Length / Marshal.SizeOf(typeof(BspBrush)); Brushes = new BspBrush[length]; for (int i = 0; i < length; i++) { Brushes[i].FirstSide = reader.ReadInt32(); Brushes[i].NumSides = reader.ReadInt32(); Brushes[i].ShaderNum = reader.ReadInt32(); } // read brush sides buffer.Position = lumps[(int)BspLumpType.BrushSides].Offset; length = lumps[(int)BspLumpType.BrushSides].Length / Marshal.SizeOf(typeof(BspBrushSide)); BrushSides = new BspBrushSide[length]; for (int i = 0; i < length; i++) { BrushSides[i].PlaneNum = reader.ReadInt32(); BrushSides[i].ShaderNum = reader.ReadInt32(); } // read entities Entities = new List <BspEntity>(); buffer.Position = lumps[(int)BspLumpType.Entities].Offset; length = lumps[(int)BspLumpType.Entities].Length; byte[] entityBytes = new byte[length]; reader.Read(entityBytes, 0, length); string entityString = Encoding.ASCII.GetString(entityBytes); string[] entityStrings = entityString.Split('\n'); BspEntity bspEntity = null; foreach (string entity in entityStrings) { switch (entity) { case "\0": continue; case "{": bspEntity = new BspEntity(); break; case "}": Entities.Add(bspEntity); break; default: string[] keyValue = entity.Trim('\"').Split(new string[] { "\" \"" }, 2, 0); if (keyValue[0] == "classname") { bspEntity.ClassName = keyValue[1]; } else if (keyValue[0] == "origin") { string[] originStrings = keyValue[1].Split(' '); bspEntity.Origin = new Vector3( float.Parse(originStrings[0], CultureInfo.InvariantCulture), float.Parse(originStrings[1], CultureInfo.InvariantCulture), float.Parse(originStrings[2], CultureInfo.InvariantCulture)); } else { bspEntity.KeyValues.Add(keyValue[0], keyValue[1]); } break; } } // read leaves buffer.Position = lumps[(int)BspLumpType.Leaves].Offset; length = lumps[(int)BspLumpType.Leaves].Length / Marshal.SizeOf(typeof(BspLeaf)); Leaves = new BspLeaf[length]; for (int i = 0; i < length; i++) { Leaves[i].Cluster = reader.ReadInt32(); Leaves[i].Area = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Min.X = reader.ReadInt32(); Leaves[i].Min.Z = -reader.ReadInt32(); Leaves[i].Min.Y = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Max.X = reader.ReadInt32(); Leaves[i].Max.Z = -reader.ReadInt32(); Leaves[i].Max.Y = reader.ReadInt32(); Leaves[i].FirstLeafFace = reader.ReadInt32(); Leaves[i].NumLeafFaces = reader.ReadInt32(); Leaves[i].FirstLeafBrush = reader.ReadInt32(); Leaves[i].NumLeafBrushes = reader.ReadInt32(); } // read leaf brushes buffer.Position = lumps[(int)BspLumpType.LeafBrushes].Offset; length = lumps[(int)BspLumpType.LeafBrushes].Length / sizeof(int); LeafBrushes = new int[length]; for (int i = 0; i < length; i++) { LeafBrushes[i] = reader.ReadInt32(); } // read planes buffer.Position = lumps[(int)BspLumpType.Planes].Offset; length = lumps[(int)BspLumpType.Planes].Length / Marshal.SizeOf(typeof(BspPlane)); Planes = new BspPlane[length]; for (int i = 0; i < length; i++) { Planes[i].Normal.X = reader.ReadSingle(); Planes[i].Normal.Y = reader.ReadSingle(); Planes[i].Normal.Z = reader.ReadSingle(); Planes[i].Distance = reader.ReadSingle(); } // read shaders Shaders = new List <BspShader>(); buffer.Position = lumps[(int)BspLumpType.Shaders].Offset; length = lumps[(int)BspLumpType.Shaders].Length; for (int i = 0; i < length; i += (64 + 2 * sizeof(int))) { BspShader shader = new BspShader(); byte[] shaderBytes = new byte[64]; reader.Read(shaderBytes, 0, 64); shader.Shader = Encoding.ASCII.GetString(shaderBytes); shader.SurfaceFlags = reader.ReadInt32(); shader.ContentFlags = (ContentFlags)reader.ReadInt32(); Shaders.Add(shader); } return(true); }
public bool LoadBspFile(Stream buffer) { BinaryReader reader = new BinaryReader(buffer); // read header string id = Encoding.ASCII.GetString(reader.ReadBytes(4), 0, 4); int version = reader.ReadInt32(); if (id != "IBSP" && id != "VBSP") return false; int nHeaderLumps; if (id == "IBSP") { if (version != 0x2E) { return false; } nHeaderLumps = 17; } else// if (id == "VBSP") { if (version != 0x14) { return false; } nHeaderLumps = 64; IsVbsp = true; } BspLump[] lumps = new BspLump[nHeaderLumps]; for (int i = 0; i < lumps.Length; i++) { lumps[i].Offset = reader.ReadInt32(); lumps[i].Length = reader.ReadInt32(); if (IsVbsp) { reader.ReadInt32(); // lump format version reader.ReadInt32(); // lump ident code } } // read brushes int lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.Brushes : (int)IBspLumpType.Brushes; buffer.Position = lumps[lumpHeaderOffset].Offset; int length = lumps[lumpHeaderOffset].Length / Marshal.SizeOf(typeof(BspBrush)); Brushes = new BspBrush[length]; for (int i = 0; i < length; i++) { Brushes[i].FirstSide = reader.ReadInt32(); Brushes[i].NumSides = reader.ReadInt32(); Brushes[i].ShaderNum = reader.ReadInt32(); } // read brush sides lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.BrushSides : (int)IBspLumpType.BrushSides; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length / Marshal.SizeOf(typeof(BspBrushSide)); BrushSides = new BspBrushSide[length]; for (int i = 0; i < length; i++) { if (IsVbsp) { BrushSides[i].PlaneNum = reader.ReadUInt16(); reader.ReadInt16(); // texinfo BrushSides[i].ShaderNum = reader.ReadInt16(); reader.ReadInt16(); // bevel } else { BrushSides[i].PlaneNum = reader.ReadInt32(); BrushSides[i].ShaderNum = reader.ReadInt32(); } } // read entities Entities = new List<BspEntity>(); buffer.Position = lumps[(int)IBspLumpType.Entities].Offset; length = lumps[(int)IBspLumpType.Entities].Length; byte[] entityBytes = new byte[length]; reader.Read(entityBytes, 0, length); string entityString = Encoding.ASCII.GetString(entityBytes); string[] entityStrings = entityString.Split('\n'); BspEntity bspEntity = null; foreach (string entity in entityStrings) { switch (entity) { case "\0": continue; case "{": bspEntity = new BspEntity(); break; case "}": Entities.Add(bspEntity); break; default: string[] keyValue = entity.Trim('\"').Split(new[] { "\" \"" }, 2, 0); switch (keyValue[0]) { case "classname": bspEntity.ClassName = keyValue[1]; break; case "origin": string[] originStrings = keyValue[1].Split(' '); bspEntity.Origin = new Vector3( float.Parse(originStrings[0], CultureInfo.InvariantCulture), float.Parse(originStrings[1], CultureInfo.InvariantCulture), float.Parse(originStrings[2], CultureInfo.InvariantCulture)); break; default: if (!bspEntity.KeyValues.ContainsKey(keyValue[0])) { if (keyValue.Length == 1) { bspEntity.KeyValues.Add(keyValue[0], ""); } else { bspEntity.KeyValues.Add(keyValue[0], keyValue[1]); } } break; } break; } } // read leaves lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.Leafs : (int)IBspLumpType.Leaves; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length; length /= IsVbsp ? 32 : Marshal.SizeOf(typeof(BspLeaf)); Leaves = new BspLeaf[length]; for (int i = 0; i < length; i++) { if (IsVbsp) { reader.ReadInt32(); // contents Leaves[i].Cluster = reader.ReadInt16(); Leaves[i].Area = reader.ReadInt16(); //Swap Y and Z; invert Z Leaves[i].Min.X = reader.ReadInt16(); Leaves[i].Min.Z = -reader.ReadInt16(); Leaves[i].Min.Y = reader.ReadInt16(); //Swap Y and Z; invert Z Leaves[i].Max.X = reader.ReadInt16(); Leaves[i].Max.Z = -reader.ReadInt16(); Leaves[i].Max.Y = reader.ReadInt16(); Leaves[i].FirstLeafFace = reader.ReadUInt16(); Leaves[i].NumLeafFaces = reader.ReadUInt16(); Leaves[i].FirstLeafBrush = reader.ReadUInt16(); Leaves[i].NumLeafBrushes = reader.ReadUInt16(); reader.ReadInt16(); // leafWaterDataID //reader.ReadInt16(); // ambientLighting //reader.ReadSByte(); // ambientLighting reader.ReadInt16(); // padding } else { Leaves[i].Cluster = reader.ReadInt32(); Leaves[i].Area = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Min.X = reader.ReadInt32(); Leaves[i].Min.Z = -reader.ReadInt32(); Leaves[i].Min.Y = reader.ReadInt32(); //Swap Y and Z; invert Z Leaves[i].Max.X = reader.ReadInt32(); Leaves[i].Max.Z = -reader.ReadInt32(); Leaves[i].Max.Y = reader.ReadInt32(); Leaves[i].FirstLeafFace = reader.ReadInt32(); Leaves[i].NumLeafFaces = reader.ReadInt32(); Leaves[i].FirstLeafBrush = reader.ReadInt32(); Leaves[i].NumLeafBrushes = reader.ReadInt32(); } } // read leaf brushes lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.LeafBrushes : (int)IBspLumpType.LeafBrushes; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length; length /= IsVbsp ? sizeof(short) : sizeof(int); LeafBrushes = new int[length]; for (int i = 0; i < length; i++) { if (IsVbsp) { LeafBrushes[i] = reader.ReadInt16(); } else { LeafBrushes[i] = reader.ReadInt32(); } } // read planes lumpHeaderOffset = IsVbsp ? (int)VBspLumpType.Planes : (int)IBspLumpType.Planes; buffer.Position = lumps[lumpHeaderOffset].Offset; length = lumps[lumpHeaderOffset].Length; length /= IsVbsp ? (Marshal.SizeOf(typeof(BspPlane)) + sizeof(int)) : Marshal.SizeOf(typeof(BspPlane)); Planes = new BspPlane[length]; for (int i = 0; i < length; i++) { Planes[i].Normal.X = reader.ReadSingle(); Planes[i].Normal.Y = reader.ReadSingle(); Planes[i].Normal.Z = reader.ReadSingle(); Planes[i].Distance = reader.ReadSingle(); if (IsVbsp) { reader.ReadInt32(); // type } } if (!IsVbsp) { // read shaders Shaders = new List<BspShader>(); buffer.Position = lumps[(int)IBspLumpType.Shaders].Offset; length = lumps[(int)IBspLumpType.Shaders].Length / (64 + 2 * sizeof(int)); byte[] shaderBytes = new byte[64]; for (int i = 0; i < length; i++) { BspShader shader = new BspShader(); reader.Read(shaderBytes, 0, 64); shader.Shader = Encoding.ASCII.GetString(shaderBytes, 0, Array.IndexOf(shaderBytes, (byte)0)); shader.SurfaceFlags = reader.ReadInt32(); shader.ContentFlags = (ContentFlags)reader.ReadInt32(); Shaders.Add(shader); } } return true; }