BSP.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. #include <stddef.h> // offsetof
  2. #include <string.h>
  3. #include <vector>
  4. #include <map>
  5. #include <kapusha/core/Log.h>
  6. #include <kapusha/io/Stream.h>
  7. #include <kapusha/math/types.h>
  8. #include <kapusha/render/Render.h>
  9. #include <kapusha/render/Camera.h>
  10. #include "Materializer.h"
  11. #include "Entity.h"
  12. #include "CloudAtlas.h"
  13. #include "BSP.h"
  14. using namespace kapusha;
  15. namespace bsp {
  16. #pragma pack(push)
  17. #pragma pack(1)
  18. struct lump_t {
  19. int offset;
  20. int length;
  21. int version;
  22. int identifier;
  23. };
  24. enum lumpType {
  25. lumpEntities = 0,
  26. lumpTexdata = 2,
  27. lumpVertexes = 3,
  28. lumpTexinfo = 6,
  29. lumpFaces = 7,
  30. lumpLightmap = 8,
  31. lumpEdges = 12,
  32. lumpSurfedges = 13,
  33. lumpTexStrdata = 43,
  34. lumpTexStrtbl = 44,
  35. lumpLightmapHDR = 53,
  36. _lumpsCount = 64
  37. };
  38. struct header_t
  39. {
  40. char magic[4];
  41. int version;
  42. lump_t lumps[_lumpsCount];
  43. int revision;
  44. };
  45. struct texinfo_t
  46. {
  47. float textureVecs[2][4];
  48. float lightmapVecs[2][4];
  49. u32 flags;
  50. u32 ref_texdata;
  51. };
  52. struct texdata_t
  53. {
  54. vec3f reflectivity;
  55. u32 nameStrtbl;
  56. u32 width, height;
  57. u32 vwidth, vheight;
  58. };
  59. struct face_t
  60. {
  61. u16 ref_plane;
  62. u8 plane_side;
  63. u8 on_node;
  64. u32 ref_surfedge;
  65. u16 surfedges_count;
  66. u16 ref_texinfo;
  67. u16 ref_dispinfo;
  68. u16 _unknown0; // ??
  69. u8 lightstyles[4]; // ??
  70. u32 ref_lightmap_offset;
  71. float area;
  72. s32 lightmapMins[2]; // ??
  73. u32 lightmapSize[2]; // ??
  74. u32 ref_original_face;
  75. u16 primitives_count;
  76. u16 ref_primitive;
  77. u32 lightmap_smoothing_group; // ??
  78. };
  79. struct luxel_t
  80. {
  81. u8 r, g, b;
  82. s8 exp;
  83. };
  84. #pragma pack(pop)
  85. vec2f lightmapTexelAtVertex(vec3f v, const face_t &face,
  86. const texinfo_t* texinfo,
  87. rect2f atlas)
  88. {
  89. vec2f lmap_size = vec2f(face.lightmapSize[0] + 1.f, face.lightmapSize[1] + 1.f);
  90. const texinfo_t *t = &texinfo[face.ref_texinfo];
  91. vec2f l(
  92. (t->lightmapVecs[0][0]*v.x + t->lightmapVecs[0][1] * v.y +
  93. t->lightmapVecs[0][2]*v.z + t->lightmapVecs[0][3] - (float)face.lightmapMins[0]) / lmap_size.x,
  94. 1.f-(t->lightmapVecs[1][0]*v.x + t->lightmapVecs[1][1] * v.y +
  95. t->lightmapVecs[1][2]*v.z + t->lightmapVecs[1][3] - (float)face.lightmapMins[1]) / lmap_size.y);
  96. return l * atlas.size() + atlas.bottomLeft();
  97. }
  98. } // namespace bsp
  99. BSP::BSP(void)
  100. : parent_(0)
  101. , relative_(0)
  102. , translation_(0)
  103. , shift_(0)
  104. , contours_(0)
  105. {
  106. }
  107. BSP::~BSP(void)
  108. {
  109. for(auto it = objects_.begin(); it != objects_.end(); ++it)
  110. delete *it;
  111. delete contours_;
  112. }
  113. bool BSP::load(StreamSeekable* stream, Materializer* materializer)
  114. {
  115. //! \fixme check for errors
  116. bsp::header_t header;
  117. stream->copy(&header, sizeof header);
  118. //! \fixme check format
  119. //L("BSP magic: %c%c%c%c", header.magic[0], header.magic[1],
  120. // header.magic[2], header.magic[3]);
  121. //L("BSP version: %d", header.version);
  122. //L("BSP revision %d", header.revision);
  123. if (header.version != 19)
  124. {
  125. L("BSP version: %d", header.version);
  126. L("Still not sure how to load versions other than 19");
  127. //return false;
  128. }
  129. // show lightmap info
  130. bsp::luxel_t* lightmap;
  131. int lmap_luxels;
  132. {
  133. const bsp::lump_t *lump_lmap = header.lumps + ((header.version < 20)? bsp::lumpLightmap : bsp::lumpLightmapHDR);
  134. lmap_luxels = lump_lmap->length / sizeof(bsp::luxel_t);
  135. //L("Lmap size: %d (%08x)", lump_lmap->length, lump_lmap->length);
  136. stream->seek(lump_lmap->offset, StreamSeekable::ReferenceStart);
  137. lightmap = new bsp::luxel_t[lmap_luxels];
  138. stream->copy(lightmap, lump_lmap->length);
  139. // pre-compute colors
  140. for (int i = 0; i < lmap_luxels; ++i)
  141. {
  142. vec3i c = vec3i(lightmap[i].r, lightmap[i].g, lightmap[i].b);
  143. if (lightmap[i].exp > 0)
  144. {
  145. c.x <<= lightmap[i].exp;
  146. c.y <<= lightmap[i].exp;
  147. c.z <<= lightmap[i].exp;
  148. } else {
  149. c.x >>= -lightmap[i].exp;
  150. c.y >>= -lightmap[i].exp;
  151. c.z >>= -lightmap[i].exp;
  152. }
  153. #define CLAMP(f,min,max) (((f)<(min))?(min):((f)>(max)?(max):(f)))
  154. c.x = CLAMP(c.x, 0, 255);
  155. c.y = CLAMP(c.y, 0, 255);
  156. c.z = CLAMP(c.z, 0, 255);
  157. #undef CLAMP
  158. *reinterpret_cast<vec4<u8>*>(&lightmap[i]) = vec4<u8>(c);
  159. }
  160. }
  161. // guess combined lightmap size
  162. vec2i lmap_atlas_size(1);
  163. for (;lmap_atlas_size.x * lmap_atlas_size.x < lmap_luxels; lmap_atlas_size.x <<= 1);
  164. int lmap_min_height = lmap_luxels / lmap_atlas_size.x;
  165. for (;lmap_atlas_size.y < lmap_min_height; lmap_atlas_size.y <<= 1);
  166. CloudAtlas lmap_atlas(lmap_atlas_size);
  167. // find linked maps in entities
  168. {
  169. const bsp::lump_t *lump_ent = header.lumps + bsp::lumpEntities;
  170. stream->seek(lump_ent->offset, StreamSeekable::ReferenceStart);
  171. for(;;)
  172. {
  173. Entity *ent = Entity::readNextEntity(stream);
  174. if (!ent) break;
  175. const std::string *classname = ent->getParam("classname");
  176. if (classname)
  177. {
  178. if (*classname == "info_landmark")
  179. {
  180. KP_ASSERT(ent->getParam("targetname"));
  181. KP_ASSERT(ent->getParam("origin"));
  182. links_.landmarks[*ent->getParam("targetname")] = ent->getVec3Param("origin");
  183. } else if (*classname == "trigger_changelevel")
  184. {
  185. KP_ASSERT(ent->getParam("landmark"));
  186. KP_ASSERT(ent->getParam("map"));
  187. links_.maps[*ent->getParam("map")] = *ent->getParam("landmark");
  188. }
  189. }
  190. delete ent;
  191. }
  192. }
  193. // load vertices
  194. vec3f *vertices;
  195. int num_vertices;
  196. {
  197. const bsp::lump_t *lump_vtx = header.lumps + bsp::lumpVertexes;
  198. num_vertices = lump_vtx->length / sizeof(vec3f);
  199. vertices = new vec3f[num_vertices];
  200. //L("Vertices: %d", lump_vtx->length / 12);
  201. stream->seek(lump_vtx->offset, StreamSeekable::ReferenceStart);
  202. stream->copy(vertices, lump_vtx->length);
  203. }
  204. // preload surfedges
  205. // load edges
  206. const bsp::lump_t *lump_edges = header.lumps + bsp::lumpEdges;
  207. int num_edges = lump_edges->length / 4;
  208. //L("Edges: %d", num_edges);
  209. stream->seek(lump_edges->offset, StreamSeekable::ReferenceStart);
  210. struct edge_t {
  211. u16 a, b;
  212. } *edges = new edge_t[num_edges];
  213. stream->copy(edges, lump_edges->length);
  214. // load surfedges
  215. const bsp::lump_t *lump_surfedges = header.lumps + bsp::lumpSurfedges;
  216. int num_surfedges = lump_surfedges->length / 4;
  217. //L("Surfedges: %d", num_surfedges);
  218. stream->seek(lump_surfedges->offset, StreamSeekable::ReferenceStart);
  219. int *surfedges_i = new int[num_surfedges];
  220. u16 *surfedges = new u16[num_surfedges];
  221. stream->copy(surfedges_i, num_surfedges * 4);
  222. for(int i = 0; i < num_surfedges; ++i)
  223. if (surfedges_i[i] >= 0)
  224. surfedges[i] = edges[surfedges_i[i]].a;
  225. else
  226. surfedges[i] = edges[-surfedges_i[i]].b;
  227. // load texinfo
  228. const bsp::lump_t *lump_texinfo = header.lumps + bsp::lumpTexinfo;
  229. int num_texinfo = lump_texinfo->length / sizeof(bsp::texinfo_t);
  230. //L("Texinfos: %d", num_texinfo);
  231. stream->seek(lump_texinfo->offset, StreamSeekable::ReferenceStart);
  232. bsp::texinfo_t *texinfo = new bsp::texinfo_t[num_texinfo];
  233. stream->copy(texinfo, lump_texinfo->length);
  234. // load texdata
  235. const bsp::lump_t *lump_texdata = header.lumps + bsp::lumpTexdata;
  236. int num_texdata = lump_texdata->length / sizeof(bsp::texdata_t);
  237. //L("Texdatas: %d", num_texdata);
  238. stream->seek(lump_texdata->offset, StreamSeekable::ReferenceStart);
  239. bsp::texdata_t *texdata = new bsp::texdata_t[num_texdata];
  240. stream->copy(texdata, lump_texdata->length);
  241. // load texstrdata
  242. const bsp::lump_t *lump_texstrdata = header.lumps + bsp::lumpTexStrdata;
  243. //L("Texstrdata: %d", lump_texstrdata->length);
  244. stream->seek(lump_texstrdata->offset, StreamSeekable::ReferenceStart);
  245. char* texstrdata = new char[lump_texstrdata->length];
  246. stream->copy(texstrdata, lump_texstrdata->length);
  247. // load texstrtbl
  248. const bsp::lump_t *lump_texstrtbl = header.lumps + bsp::lumpTexStrtbl;
  249. //L("Texstrtbl: %d", lump_texstrtbl->length / 4);
  250. stream->seek(lump_texstrtbl->offset, StreamSeekable::ReferenceStart);
  251. int* texstrtbl = new int[lump_texstrtbl->length / 4];
  252. stream->copy(texstrtbl, lump_texstrtbl->length);
  253. // load faces
  254. const bsp::lump_t *lump_faces = header.lumps + bsp::lumpFaces;
  255. int num_faces = lump_faces->length / sizeof(bsp::face_t);
  256. //L("Faces: %d", num_faces);
  257. stream->seek(lump_faces->offset, StreamSeekable::ReferenceStart);
  258. struct MapVertex {
  259. vec3f vertex;
  260. vec2f tc_lightmap;
  261. MapVertex() {}
  262. MapVertex(vec3f _vertex, vec2f _lightmap)
  263. : vertex(_vertex), tc_lightmap(_lightmap) {}
  264. };
  265. std::vector<MapVertex> tmp_vtx;
  266. std::vector<u16> tmp_idx;
  267. std::vector<u16> tmp_idx_cont;
  268. for (int i = 0; i < num_faces; ++i)
  269. {
  270. bsp::face_t face;
  271. stream->copy(&face, sizeof(bsp::face_t));
  272. /*L("Face %d", i);
  273. L("\tedges: %d->%d", face.ref_surfedge, face.ref_surfedge+face.surfedges_count);
  274. L("\tlightmap: %d", face.ref_lightmap_offset);
  275. L("\tstyles: %d %d %d %d",
  276. face.lightstyles[0], face.lightstyles[1],
  277. face.lightstyles[2], face.lightstyles[3]);
  278. L("\tluxels: %d x %d", face.lightmapSize[0], face.lightmapSize[1]);
  279. L("\tluxels (mins ??): %d x %d", face.lightmapMins[0], face.lightmapMins[1]);
  280. */
  281. //if (face.ref_lightmap_offset < 4) continue;
  282. //if (face.ref_texinfo < 0) continue;
  283. //if (texinfo[face.ref_texinfo].ref_texdata == -1) continue;
  284. if (texinfo[face.ref_texinfo].flags & 0x401) {
  285. int tex_table_index = texdata[texinfo[face.ref_texinfo].ref_texdata].nameStrtbl;
  286. KP_ASSERT(tex_table_index < lump_texstrtbl->length / 4);
  287. int tex_data_index = texstrtbl[tex_table_index];
  288. KP_ASSERT(tex_data_index < lump_texstrdata->length);
  289. //L("%d %d %08x %s", i, face.on_node, texinfo[face.ref_texinfo].flags, texstrdata + tex_data_index);
  290. if (strstr(texstrdata + tex_data_index, "TOOL"))
  291. continue;
  292. }
  293. vec2i lmap_size = vec2i(1, 1);
  294. static u32 white = 0xffffffff;
  295. const void *luxels = &white;
  296. if (face.ref_lightmap_offset/4 < (unsigned)lmap_luxels)
  297. {
  298. lmap_size = vec2i(face.lightmapSize[0] + 1, face.lightmapSize[1] + 1);
  299. luxels = &lightmap[face.ref_lightmap_offset / 4];
  300. }
  301. rect2f lmap_region = lmap_atlas.addImage(lmap_size, luxels);
  302. KP_ASSERT(lmap_region.bottom() >= 0.f);
  303. int index_shift = static_cast<int>(tmp_vtx.size());
  304. vec3f vtx = vertices[surfedges[face.ref_surfedge]];
  305. tmp_vtx.push_back(MapVertex(vtx, bsp::lightmapTexelAtVertex(vtx, face, texinfo, lmap_region)));
  306. vtx = vertices[surfedges[face.ref_surfedge+1]];
  307. tmp_vtx.push_back(MapVertex(vtx, bsp::lightmapTexelAtVertex(vtx, face, texinfo, lmap_region)));
  308. edge_t *e = &edges[abs(surfedges_i[face.ref_surfedge])];
  309. if (e->a != e->b)
  310. {
  311. tmp_idx_cont.push_back(index_shift + 0);
  312. tmp_idx_cont.push_back(index_shift + 1);
  313. e->a = e->b; // mark as drawn
  314. }
  315. for (int j = 2; j < face.surfedges_count; ++j)
  316. {
  317. vtx = vertices[surfedges[face.ref_surfedge + j]];
  318. tmp_vtx.push_back(MapVertex(vtx, bsp::lightmapTexelAtVertex(vtx, face, texinfo, lmap_region)));
  319. tmp_idx.push_back(index_shift + 0);
  320. tmp_idx.push_back(index_shift + j-1);
  321. tmp_idx.push_back(index_shift + j);
  322. // store contours
  323. edge_t *e = &edges[abs(surfedges_i[face.ref_surfedge + j])];
  324. if (e->a != e->b)
  325. {
  326. tmp_idx_cont.push_back(index_shift + j-1);
  327. tmp_idx_cont.push_back(index_shift + j);
  328. e->a = e->b;
  329. }
  330. }
  331. }
  332. L("Map: vertices %d, indices %d", tmp_vtx.size(), tmp_idx.size());
  333. if (tmp_vtx.size() > 65535)
  334. L("WARNING: total vertices size exceeds 64k: %d", tmp_vtx.size());
  335. delete texstrtbl;
  336. delete texstrdata;
  337. delete texdata;
  338. delete texinfo;
  339. delete surfedges_i;
  340. delete edges;
  341. delete vertices;
  342. delete surfedges;
  343. delete lightmap;
  344. // common
  345. Buffer *attribs_buffer = new Buffer;
  346. attribs_buffer->load(&tmp_vtx[0], tmp_vtx.size() * sizeof(MapVertex));
  347. { // map geometry
  348. Buffer *index_buffer = new Buffer;
  349. index_buffer->load(&tmp_idx[0], tmp_idx.size() * sizeof(tmp_idx[0]));
  350. Batch* batch = new Batch();
  351. batch->setMaterial(materializer->loadMaterial("__lightmap_only"));
  352. batch->setAttribSource("av4_vertex", attribs_buffer, 3, 0, sizeof(MapVertex));
  353. batch->setAttribSource("av2_lightmap", attribs_buffer, 2, offsetof(MapVertex, tc_lightmap), sizeof(MapVertex));
  354. batch->setGeometry(Batch::GeometryTriangleList, 0, tmp_idx.size(), Batch::IndexU16, index_buffer);
  355. objects_.push_back(new Object(batch));
  356. lightmap_ = lmap_atlas.texture();
  357. }
  358. { // contours
  359. Buffer *index_buffer = new Buffer;
  360. index_buffer->load(&tmp_idx_cont[0], tmp_idx_cont.size() * sizeof(tmp_idx_cont[0]));
  361. Batch* batch = new Batch();
  362. batch->setMaterial(materializer->loadMaterial("__white"));
  363. batch->setAttribSource("av4_vertex", attribs_buffer, 3, 0, sizeof(MapVertex));
  364. batch->setGeometry(Batch::GeometryLineList, 0, tmp_idx_cont.size(), Batch::IndexU16, index_buffer);
  365. contours_ = new Object(batch);
  366. }
  367. return true;
  368. }
  369. void BSP::draw(const kapusha::Camera& cam) const
  370. {
  371. for(auto it = objects_.begin(); it != objects_.end(); ++it)
  372. {
  373. (*it)->getBatch()->getMaterial()->setUniform("uv4_trans", vec4f(translation_));
  374. (*it)->getBatch()->getMaterial()->setTexture("us2_lightmap", lightmap_);
  375. (*it)->draw(cam.getView(), cam.getProjection());
  376. }
  377. }
  378. void BSP::drawContours(const kapusha::Camera& cam) const
  379. {
  380. if (contours_)
  381. {
  382. contours_->getBatch()->getMaterial()->setUniform("uv4_trans", vec4f(translation_));
  383. contours_->draw(cam.getView(), cam.getProjection());
  384. }
  385. }
  386. void BSP::setParent(const BSP* parent, vec3f relative)
  387. {
  388. parent_ = parent;
  389. relative_ = relative;
  390. updateShift(shift_);
  391. }
  392. void BSP::updateShift(vec3f shift)
  393. {
  394. shift_ = shift;
  395. translation_ = relative_ + shift_;
  396. if (parent_)
  397. translation_ += parent_->translation();
  398. }