public static libTechMap LoadMap(Stream BSPStream) { Q3BSP Map = Q3BSP.FromStream(BSPStream); libTechMap Q3Map = new libTechMap(); Dictionary <int, List <Vertex3> > TexturedMeshes = new Dictionary <int, List <Vertex3> >(); foreach (var FaceIdx in GetFaceIndices(Map)) { Q3BSPFace Face = Map.Faces[FaceIdx]; if (!TexturedMeshes.ContainsKey(Face.Texture)) { TexturedMeshes.Add(Face.Texture, new List <Vertex3>()); } if (Face.Type == FaceType.Polygon || Face.Type == FaceType.Mesh) { Vertex3[] Vertices = new Vertex3[Face.NVerts]; for (int VertOffset = 0; VertOffset < Face.NVerts; VertOffset++) { Vertices[VertOffset] = Map.Vertices[Face.Vert + VertOffset].ToVertex3(); } for (int MeshVertOffset = 0; MeshVertOffset < Face.NMeshVerts; MeshVertOffset++) { TexturedMeshes[Face.Texture].Add(Vertices[Map.MeshVertices[Face.MeshVert + MeshVertOffset]]); } } } string[] TextureNames = Map.Textures.Select(T => T.GetName()).ToArray(); libTechModel Model = new libTechModel(); Q3Map.AddModel(Model); foreach (var KV in TexturedMeshes) { string TexName = TextureNames[KV.Key]; if (TexName == "textures/lun3dm5/lblusky2") { continue; } Model.AddMesh(new libTechMesh(KV.Value.ToArray().Reverse().ToArray(), Engine.GetMaterial(TexName))); } return(Q3Map); }
public static Q3BSP FromStream(Stream BSPStream) { Q3BSP Map = new Q3BSP(); byte[] BSPBytes = null; using (MemoryStream MS = new MemoryStream()) { BSPStream.CopyTo(MS); BSPBytes = MS.ToArray(); } fixed(byte *BSPPtr = BSPBytes) { Map.Header = *(BSPHeader *)BSPPtr; BSPDirEntry[] DirEntries = Map.Header.GetDirEntries(); for (int DirEntryIdx = 0; DirEntryIdx < DirEntries.Length; DirEntryIdx++) { BSPDirEntry DirEntry = DirEntries[DirEntryIdx]; void *LumpPtr = (void *)(BSPPtr + DirEntry.Offset); int LumpLen = DirEntry.Length; switch (DirEntryIdx) { case 0: { Map.Entities = new Q3BSPEntityLump(); Map.Entities.Ents = Encoding.ASCII.GetString((byte *)LumpPtr, LumpLen); break; } case 1: { Q3BSPTexture[] Textures = new Q3BSPTexture[LumpLen / sizeof(Q3BSPTexture)]; Q3BSPTexture * TexturesPtr = (Q3BSPTexture *)LumpPtr; for (int i = 0; i < Textures.Length; i++) { Textures[i] = TexturesPtr[i]; } Map.Textures = Textures; break; } case 4: { Q3BSPLeaf[] Leaves = new Q3BSPLeaf[LumpLen / sizeof(Q3BSPLeaf)]; Q3BSPLeaf * LeavesPtr = (Q3BSPLeaf *)LumpPtr; for (int i = 0; i < Leaves.Length; i++) { Leaves[i] = LeavesPtr[i]; } Map.Leaves = Leaves; break; } case 5: { int[] LeafFaces = new int[LumpLen / sizeof(int)]; int * LeafFacesPtr = (int *)LumpPtr; for (int i = 0; i < LeafFaces.Length; i++) { LeafFaces[i] = LeafFacesPtr[i]; } Map.LeafFaces = LeafFaces; break; } case 10: { Q3BSPVertex[] Vertices = new Q3BSPVertex[LumpLen / sizeof(Q3BSPVertex)]; Q3BSPVertex * VerticesPtr = (Q3BSPVertex *)LumpPtr; for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = VerticesPtr[i]; } Map.Vertices = Vertices; break; } case 11: { int[] MeshVertices = new int[LumpLen / sizeof(int)]; int * MeshVerticesPtr = (int *)LumpPtr; for (int i = 0; i < MeshVertices.Length; i++) { MeshVertices[i] = MeshVerticesPtr[i]; } Map.MeshVertices = MeshVertices; break; } case 13: { int BSPFaceSize = sizeof(Q3BSPFace); Q3BSPFace[] Faces = new Q3BSPFace[LumpLen / BSPFaceSize]; Q3BSPFace * FacesPtr = (Q3BSPFace *)LumpPtr; for (int i = 0; i < Faces.Length; i++) { Faces[i] = FacesPtr[i]; } Map.Faces = Faces; break; } default: break; } } } return(Map); }