Formatx.Q3BSP.pas 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. //
  2. // The graphics engine GXScene
  3. //
  4. unit Formatx.Q3BSP;
  5. (* Simple Quake III BSP file loader. *)
  6. interface
  7. uses
  8. System.Classes,
  9. System.SysUtils,
  10. Stage.VectorTypes;
  11. const
  12. FACE_POLYGON = 1;
  13. const
  14. MAX_TEXTURES = 1000;
  15. type
  16. TBSPHeader = record
  17. StrID: array [0 .. 3] of AnsiChar; // This should always be 'IBSP'
  18. Version: Integer; // This should be 0x2e for Quake 3 files
  19. end;
  20. TBSPLump = record
  21. Offset: Integer; // The offset into the file for the start of this lump
  22. Length: Integer; // The length in bytes for this lump
  23. end;
  24. TBSPBBox = array [0 .. 5] of Integer;
  25. TBSPNode = record
  26. Plane: Integer; // Space partitioning plane
  27. Children: array [0 .. 1] of Integer; // Back and front child nodes
  28. BBox: TBSPBBox; // Bounding box of node
  29. end;
  30. TBSPLeaf = record
  31. Cluster: Integer; // Visibility cluster number
  32. Area: Integer; // Volume of the leaf
  33. BBox: TBSPBBox; // Bounding box of leaf
  34. FirstFace, NumFaces: Integer;
  35. // Lookup for the face list (indexes are for faces)
  36. FirstBrush, NumBrushes: Integer;
  37. // Lookup for the brush list (indexes are for brushes)
  38. end;
  39. TBSPModel = record
  40. BBox: TBSPBBox; // Bounding box of model
  41. FirstFace, NumFaces: Integer;
  42. // Lookup for the face list (indexes are for faces)
  43. FirstBrush, NumBrushes: Integer;
  44. // Lookup for the brush list (indexes are for brushes)
  45. end;
  46. TBSPVertex = record
  47. Position: TVector3f; // (x, y, z) position.
  48. TextureCoord: TVector2f; // (u, v) texture coordinate
  49. LightmapCoord: TVector2f; // (u, v) lightmap coordinate
  50. Normal: TVector3f; // (x, y, z) normal vector
  51. Color: array [0 .. 3] of Byte // RGBA color for the vertex
  52. end;
  53. PBSPVertex = ^TBSPVertex;
  54. TBSPFace = record textureID: Integer; // The index into the texture array
  55. effect: Integer; // The index for the effects (or -1 = n/a)
  56. FaceType: Integer; // 1=polygon, 2=patch, 3=mesh, 4=billboard
  57. startVertIndex: Integer; // The starting index into this face's first vertex
  58. numOfVerts: Integer; // The number of vertices for this face
  59. meshVertIndex: Integer; // The index into the first meshvertex
  60. numMeshVerts: Integer; // The number of mesh vertices
  61. lightmapID: Integer; // The texture index for the lightmap
  62. lMapCorner: array [0 .. 1] of Integer;
  63. // The face's lightmap corner in the image
  64. lMapSize: array [0 .. 1] of Integer; // The size of the lightmap section
  65. lMapPos: TVector3f; // The 3D origin of lightmap.
  66. lMapVecs: array [0 .. 1] of TVector3f;
  67. // The 3D space for s and t unit vectors.
  68. vNormal: TVector3f; // The face normal.
  69. Size: array [0 .. 1] of Integer; // The bezier patch dimensions.
  70. end;
  71. PBSPFace = ^TBSPFace;
  72. TBSPTexture = record
  73. TextureName: array [0 .. 63] of WideChar;
  74. // The name of the texture w/o the extension
  75. flags: Integer; // The surface flags (unknown)
  76. contents: Integer; // The content flags (unknown)
  77. end;
  78. PBSPTexture = ^TBSPTexture;
  79. TBSPLightmap = record
  80. imageBits: array [0 .. 49151] of Byte; // The RGB data in a 128x128 image
  81. end;
  82. PBSPLightmap = ^TBSPLightmap;
  83. TBSPVisData = record
  84. numOfClusters: Integer;
  85. bytesPerCluster: Integer;
  86. bitSets: array of Byte;
  87. end;
  88. TQ3BSP = class(TObject)
  89. public
  90. Header: TBSPHeader;
  91. Lumps: array of TBSPLump;
  92. numOfVerts: Integer;
  93. NumOfNodes: Integer;
  94. NumOfPlanes: Integer;
  95. NumOfLeaves: Integer;
  96. NumOfFaces: Integer;
  97. NumOfTextures: Integer;
  98. NumOfLightmaps: Integer;
  99. Vertices: array of TBSPVertex;
  100. Nodes: array of TBSPNode;
  101. Planes: array of TVector4f;
  102. Leaves: array of TBSPLeaf;
  103. Faces: array of TBSPFace;
  104. Textures: array of TBSPTexture; // texture names (without extension)
  105. Lightmaps: array of TBSPLightmap;
  106. VisData: TBSPVisData;
  107. constructor Create(bspStream: TStream);
  108. end;
  109. const
  110. kEntities = 0; // Stores player/object positions, etc...
  111. kTextures = 1; // Stores texture information
  112. kPlanes = 2; // Stores the splitting planes
  113. kNodes = 3; // Stores the BSP nodes
  114. kLeafs = 4; // Stores the leafs of the nodes
  115. kLeafFaces = 5; // Stores the leaf's indices into the faces
  116. kLeafBrushes = 6; // Stores the leaf's indices into the brushes
  117. kModels = 7; // Stores the info of world models
  118. kBrushes = 8; // Stores the brushes info (for collision)
  119. kBrushSides = 9; // Stores the brush surfaces info
  120. kVertices = 10; // Stores the level vertices
  121. kMeshVerts = 11; // Stores the model vertices offsets
  122. kShaders = 12; // Stores the shader files (blending, anims..)
  123. kFaces = 13; // Stores the faces for the level
  124. kLightmaps = 14; // Stores the lightmaps for the level
  125. kLightVolumes = 15; // Stores extra world lighting information
  126. kVisData = 16; // Stores PVS and cluster info (visibility)
  127. kMaxLumps = 17; // A constant to store the number of lumps
  128. implementation // -----------------------------------------------------------
  129. // ------------------
  130. // ------------------ TQ3BSP ------------------
  131. // ------------------
  132. constructor TQ3BSP.Create(bspStream: TStream);
  133. begin
  134. SetLength(Lumps, kMaxLumps);
  135. // Read in the header and lump data
  136. bspStream.Read(Header, SizeOf(Header));
  137. bspStream.Read(Lumps[0], kMaxLumps * SizeOf(TBSPLump));
  138. NumOfNodes := Round(Lumps[kNodes].Length / SizeOf(TBSPNode));
  139. SetLength(Nodes, NumOfNodes);
  140. bspStream.Position := Lumps[kNodes].Offset;
  141. bspStream.Read(Nodes[0], NumOfNodes * SizeOf(TBSPNode));
  142. NumOfPlanes := Round(Lumps[kPlanes].Length / SizeOf(TVector4f));
  143. SetLength(Planes, NumOfPlanes);
  144. bspStream.Position := Lumps[kPlanes].Offset;
  145. bspStream.Read(Planes[0], NumOfPlanes * SizeOf(TVector4f));
  146. NumOfLeaves := Round(Lumps[kLeafs].Length / SizeOf(TBSPLeaf));
  147. SetLength(Leaves, NumOfLeaves);
  148. bspStream.Position := Lumps[kLeafs].Offset;
  149. bspStream.Read(Leaves[0], NumOfLeaves * SizeOf(TBSPLeaf));
  150. numOfVerts := Round(Lumps[kVertices].Length / SizeOf(TBSPVertex));
  151. SetLength(Vertices, numOfVerts);
  152. bspStream.Position := Lumps[kVertices].Offset;
  153. bspStream.Read(Vertices[0], numOfVerts * SizeOf(TBSPVertex));
  154. NumOfFaces := Round(Lumps[kFaces].Length / SizeOf(TBSPFace));
  155. SetLength(Faces, NumOfFaces);
  156. bspStream.Position := Lumps[kFaces].Offset;
  157. bspStream.Read(Faces[0], NumOfFaces * SizeOf(TBSPFace));
  158. NumOfTextures := Round(Lumps[kTextures].Length / SizeOf(TBSPTexture));
  159. SetLength(Textures, NumOfTextures);
  160. bspStream.Position := Lumps[kTextures].Offset;
  161. bspStream.Read(Textures[0], NumOfTextures * SizeOf(TBSPTexture));
  162. NumOfLightmaps := Round(Lumps[kLightmaps].Length / SizeOf(TBSPLightmap));
  163. SetLength(Lightmaps, NumOfLightmaps);
  164. bspStream.Position := Lumps[kLightmaps].Offset;
  165. bspStream.Read(Lightmaps[0], NumOfLightmaps * SizeOf(TBSPLightmap));
  166. bspStream.Position := Lumps[kVisData].Offset;
  167. bspStream.Read(VisData.numOfClusters, SizeOf(Integer));
  168. bspStream.Read(VisData.bytesPerCluster, SizeOf(Integer));
  169. if VisData.numOfClusters * VisData.bytesPerCluster > 0 then
  170. begin
  171. SetLength(VisData.bitSets, VisData.numOfClusters * VisData.bytesPerCluster);
  172. bspStream.Read(VisData.bitSets[0], VisData.numOfClusters *
  173. VisData.bytesPerCluster);
  174. end;
  175. end;
  176. end.