| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- //
- // This unit is part of the GLScene Engine, http://glscene.org
- //
- unit FileQ3BSP;
- (* Simple Quake III BSP file loader. *)
- interface
- uses
- System.Classes,
- System.SysUtils,
- GLVectorTypes;
- 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.
|