123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- //
- // The graphics engine GXScene
- //
- unit Formatx.Q3BSP;
- (* Simple Quake III BSP file loader. *)
- interface
- uses
- System.Classes,
- System.SysUtils,
- Stage.VectorTypes;
- const
- FACE_POLYGON = 1;
- const
- MAX_TEXTURES = 1000;
- type
- TBSPHeader = record
- StrID: array [0 .. 3] of AnsiChar; // This should always be 'IBSP'
- Version: Integer; // This should be 0x2e for Quake 3 files
- end;
- TBSPLump = record
- Offset: Integer; // The offset into the file for the start of this lump
- Length: Integer; // The length in bytes for this lump
- end;
- TBSPBBox = array [0 .. 5] of Integer;
- TBSPNode = record
- Plane: Integer; // Space partitioning plane
- Children: array [0 .. 1] of Integer; // Back and front child nodes
- BBox: TBSPBBox; // Bounding box of node
- end;
- TBSPLeaf = record
- Cluster: Integer; // Visibility cluster number
- Area: Integer; // Volume of the leaf
- BBox: TBSPBBox; // Bounding box of leaf
- FirstFace, NumFaces: Integer;
- // Lookup for the face list (indexes are for faces)
- FirstBrush, NumBrushes: Integer;
- // Lookup for the brush list (indexes are for brushes)
- end;
- TBSPModel = record
- BBox: TBSPBBox; // Bounding box of model
- FirstFace, NumFaces: Integer;
- // Lookup for the face list (indexes are for faces)
- FirstBrush, NumBrushes: Integer;
- // Lookup for the brush list (indexes are for brushes)
- end;
- TBSPVertex = record
- Position: TVector3f; // (x, y, z) position.
- TextureCoord: TVector2f; // (u, v) texture coordinate
- LightmapCoord: TVector2f; // (u, v) lightmap coordinate
- Normal: TVector3f; // (x, y, z) normal vector
- Color: array [0 .. 3] of Byte // RGBA color for the vertex
- end;
- PBSPVertex = ^TBSPVertex;
- TBSPFace = record textureID: Integer; // The index into the texture array
- effect: Integer; // The index for the effects (or -1 = n/a)
- FaceType: Integer; // 1=polygon, 2=patch, 3=mesh, 4=billboard
- startVertIndex: Integer; // The starting index into this face's first vertex
- numOfVerts: Integer; // The number of vertices for this face
- meshVertIndex: Integer; // The index into the first meshvertex
- numMeshVerts: Integer; // The number of mesh vertices
- lightmapID: Integer; // The texture index for the lightmap
- lMapCorner: array [0 .. 1] of Integer;
- // The face's lightmap corner in the image
- lMapSize: array [0 .. 1] of Integer; // The size of the lightmap section
- lMapPos: TVector3f; // The 3D origin of lightmap.
- lMapVecs: array [0 .. 1] of TVector3f;
- // The 3D space for s and t unit vectors.
- vNormal: TVector3f; // The face normal.
- Size: array [0 .. 1] of Integer; // The bezier patch dimensions.
- end;
- PBSPFace = ^TBSPFace;
- TBSPTexture = record
- TextureName: array [0 .. 63] of WideChar;
- // The name of the texture w/o the extension
- flags: Integer; // The surface flags (unknown)
- contents: Integer; // The content flags (unknown)
- end;
- PBSPTexture = ^TBSPTexture;
- TBSPLightmap = record
- imageBits: array [0 .. 49151] of Byte; // The RGB data in a 128x128 image
- end;
- PBSPLightmap = ^TBSPLightmap;
- TBSPVisData = record
- numOfClusters: Integer;
- bytesPerCluster: Integer;
- bitSets: array of Byte;
- end;
- TQ3BSP = class(TObject)
- public
- Header: TBSPHeader;
- Lumps: array of TBSPLump;
- numOfVerts: Integer;
- NumOfNodes: Integer;
- NumOfPlanes: Integer;
- NumOfLeaves: Integer;
- NumOfFaces: Integer;
- NumOfTextures: Integer;
- NumOfLightmaps: Integer;
- Vertices: array of TBSPVertex;
- Nodes: array of TBSPNode;
- Planes: array of TVector4f;
- Leaves: array of TBSPLeaf;
- Faces: array of TBSPFace;
- Textures: array of TBSPTexture; // texture names (without extension)
- Lightmaps: array of TBSPLightmap;
- VisData: TBSPVisData;
- constructor Create(bspStream: TStream);
- end;
- const
- kEntities = 0; // Stores player/object positions, etc...
- kTextures = 1; // Stores texture information
- kPlanes = 2; // Stores the splitting planes
- kNodes = 3; // Stores the BSP nodes
- kLeafs = 4; // Stores the leafs of the nodes
- kLeafFaces = 5; // Stores the leaf's indices into the faces
- kLeafBrushes = 6; // Stores the leaf's indices into the brushes
- kModels = 7; // Stores the info of world models
- kBrushes = 8; // Stores the brushes info (for collision)
- kBrushSides = 9; // Stores the brush surfaces info
- kVertices = 10; // Stores the level vertices
- kMeshVerts = 11; // Stores the model vertices offsets
- kShaders = 12; // Stores the shader files (blending, anims..)
- kFaces = 13; // Stores the faces for the level
- kLightmaps = 14; // Stores the lightmaps for the level
- kLightVolumes = 15; // Stores extra world lighting information
- kVisData = 16; // Stores PVS and cluster info (visibility)
- kMaxLumps = 17; // A constant to store the number of lumps
- implementation // -----------------------------------------------------------
- // ------------------
- // ------------------ TQ3BSP ------------------
- // ------------------
- constructor TQ3BSP.Create(bspStream: TStream);
- begin
- SetLength(Lumps, kMaxLumps);
- // Read in the header and lump data
- bspStream.Read(Header, SizeOf(Header));
- bspStream.Read(Lumps[0], kMaxLumps * SizeOf(TBSPLump));
- NumOfNodes := Round(Lumps[kNodes].Length / SizeOf(TBSPNode));
- SetLength(Nodes, NumOfNodes);
- bspStream.Position := Lumps[kNodes].Offset;
- bspStream.Read(Nodes[0], NumOfNodes * SizeOf(TBSPNode));
- NumOfPlanes := Round(Lumps[kPlanes].Length / SizeOf(TVector4f));
- SetLength(Planes, NumOfPlanes);
- bspStream.Position := Lumps[kPlanes].Offset;
- bspStream.Read(Planes[0], NumOfPlanes * SizeOf(TVector4f));
- NumOfLeaves := Round(Lumps[kLeafs].Length / SizeOf(TBSPLeaf));
- SetLength(Leaves, NumOfLeaves);
- bspStream.Position := Lumps[kLeafs].Offset;
- bspStream.Read(Leaves[0], NumOfLeaves * SizeOf(TBSPLeaf));
- numOfVerts := Round(Lumps[kVertices].Length / SizeOf(TBSPVertex));
- SetLength(Vertices, numOfVerts);
- bspStream.Position := Lumps[kVertices].Offset;
- bspStream.Read(Vertices[0], numOfVerts * SizeOf(TBSPVertex));
- NumOfFaces := Round(Lumps[kFaces].Length / SizeOf(TBSPFace));
- SetLength(Faces, NumOfFaces);
- bspStream.Position := Lumps[kFaces].Offset;
- bspStream.Read(Faces[0], NumOfFaces * SizeOf(TBSPFace));
- NumOfTextures := Round(Lumps[kTextures].Length / SizeOf(TBSPTexture));
- SetLength(Textures, NumOfTextures);
- bspStream.Position := Lumps[kTextures].Offset;
- bspStream.Read(Textures[0], NumOfTextures * SizeOf(TBSPTexture));
- NumOfLightmaps := Round(Lumps[kLightmaps].Length / SizeOf(TBSPLightmap));
- SetLength(Lightmaps, NumOfLightmaps);
- bspStream.Position := Lumps[kLightmaps].Offset;
- bspStream.Read(Lightmaps[0], NumOfLightmaps * SizeOf(TBSPLightmap));
- bspStream.Position := Lumps[kVisData].Offset;
- bspStream.Read(VisData.numOfClusters, SizeOf(Integer));
- bspStream.Read(VisData.bytesPerCluster, SizeOf(Integer));
- if VisData.numOfClusters * VisData.bytesPerCluster > 0 then
- begin
- SetLength(VisData.bitSets, VisData.numOfClusters * VisData.bytesPerCluster);
- bspStream.Read(VisData.bitSets[0], VisData.numOfClusters *
- VisData.bytesPerCluster);
- end;
- end;
- end.
|