gl_model.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // models.c -- model loading and caching
  16. #include "gl_local.h"
  17. model_t *loadmodel;
  18. int modfilelen;
  19. void Mod_LoadSpriteModel (model_t *mod, void *buffer);
  20. void Mod_LoadBrushModel (model_t *mod, void *buffer);
  21. void Mod_LoadAliasModel (model_t *mod, void *buffer);
  22. model_t *Mod_LoadModel (model_t *mod, qboolean crash);
  23. byte mod_novis[MAX_MAP_LEAFS/8];
  24. #define MAX_MOD_KNOWN 512
  25. model_t mod_known[MAX_MOD_KNOWN];
  26. int mod_numknown;
  27. // the inline * models from the current map are kept seperate
  28. model_t mod_inline[MAX_MOD_KNOWN];
  29. int registration_sequence;
  30. /*
  31. ===============
  32. Mod_PointInLeaf
  33. ===============
  34. */
  35. mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
  36. {
  37. mnode_t *node;
  38. float d;
  39. cplane_t *plane;
  40. if (!model || !model->nodes)
  41. ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");
  42. node = model->nodes;
  43. while (1)
  44. {
  45. if (node->contents != -1)
  46. return (mleaf_t *)node;
  47. plane = node->plane;
  48. d = DotProduct (p,plane->normal) - plane->dist;
  49. if (d > 0)
  50. node = node->children[0];
  51. else
  52. node = node->children[1];
  53. }
  54. return NULL; // never reached
  55. }
  56. /*
  57. ===================
  58. Mod_DecompressVis
  59. ===================
  60. */
  61. byte *Mod_DecompressVis (byte *in, model_t *model)
  62. {
  63. static byte decompressed[MAX_MAP_LEAFS/8];
  64. int c;
  65. byte *out;
  66. int row;
  67. row = (model->vis->numclusters+7)>>3;
  68. out = decompressed;
  69. if (!in)
  70. { // no vis info, so make all visible
  71. while (row)
  72. {
  73. *out++ = 0xff;
  74. row--;
  75. }
  76. return decompressed;
  77. }
  78. do
  79. {
  80. if (*in)
  81. {
  82. *out++ = *in++;
  83. continue;
  84. }
  85. c = in[1];
  86. in += 2;
  87. while (c)
  88. {
  89. *out++ = 0;
  90. c--;
  91. }
  92. } while (out - decompressed < row);
  93. return decompressed;
  94. }
  95. /*
  96. ==============
  97. Mod_ClusterPVS
  98. ==============
  99. */
  100. byte *Mod_ClusterPVS (int cluster, model_t *model)
  101. {
  102. if (cluster == -1 || !model->vis)
  103. return mod_novis;
  104. return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS],
  105. model);
  106. }
  107. //===============================================================================
  108. /*
  109. ================
  110. Mod_Modellist_f
  111. ================
  112. */
  113. void Mod_Modellist_f (void)
  114. {
  115. int i;
  116. model_t *mod;
  117. int total;
  118. total = 0;
  119. ri.Con_Printf (PRINT_ALL,"Loaded models:\n");
  120. for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
  121. {
  122. if (!mod->name[0])
  123. continue;
  124. ri.Con_Printf (PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
  125. total += mod->extradatasize;
  126. }
  127. ri.Con_Printf (PRINT_ALL, "Total resident: %i\n", total);
  128. }
  129. /*
  130. ===============
  131. Mod_Init
  132. ===============
  133. */
  134. void Mod_Init (void)
  135. {
  136. memset (mod_novis, 0xff, sizeof(mod_novis));
  137. }
  138. /*
  139. ==================
  140. Mod_ForName
  141. Loads in a model for the given name
  142. ==================
  143. */
  144. model_t *Mod_ForName (char *name, qboolean crash)
  145. {
  146. model_t *mod;
  147. unsigned *buf;
  148. int i;
  149. if (!name[0])
  150. ri.Sys_Error (ERR_DROP, "Mod_ForName: NULL name");
  151. //
  152. // inline models are grabbed only from worldmodel
  153. //
  154. if (name[0] == '*')
  155. {
  156. i = atoi(name+1);
  157. if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
  158. ri.Sys_Error (ERR_DROP, "bad inline model number");
  159. return &mod_inline[i];
  160. }
  161. //
  162. // search the currently loaded models
  163. //
  164. for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  165. {
  166. if (!mod->name[0])
  167. continue;
  168. if (!strcmp (mod->name, name) )
  169. return mod;
  170. }
  171. //
  172. // find a free model slot spot
  173. //
  174. for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  175. {
  176. if (!mod->name[0])
  177. break; // free spot
  178. }
  179. if (i == mod_numknown)
  180. {
  181. if (mod_numknown == MAX_MOD_KNOWN)
  182. ri.Sys_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
  183. mod_numknown++;
  184. }
  185. strcpy (mod->name, name);
  186. //
  187. // load the file
  188. //
  189. modfilelen = ri.FS_LoadFile (mod->name, &buf);
  190. if (!buf)
  191. {
  192. if (crash)
  193. ri.Sys_Error (ERR_DROP, "Mod_NumForName: %s not found", mod->name);
  194. memset (mod->name, 0, sizeof(mod->name));
  195. return NULL;
  196. }
  197. loadmodel = mod;
  198. //
  199. // fill it in
  200. //
  201. // call the apropriate loader
  202. switch (LittleLong(*(unsigned *)buf))
  203. {
  204. case IDALIASHEADER:
  205. loadmodel->extradata = Hunk_Begin (0x200000);
  206. Mod_LoadAliasModel (mod, buf);
  207. break;
  208. case IDSPRITEHEADER:
  209. loadmodel->extradata = Hunk_Begin (0x10000);
  210. Mod_LoadSpriteModel (mod, buf);
  211. break;
  212. case IDBSPHEADER:
  213. loadmodel->extradata = Hunk_Begin (0x1000000);
  214. Mod_LoadBrushModel (mod, buf);
  215. break;
  216. default:
  217. ri.Sys_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name);
  218. break;
  219. }
  220. loadmodel->extradatasize = Hunk_End ();
  221. ri.FS_FreeFile (buf);
  222. return mod;
  223. }
  224. /*
  225. ===============================================================================
  226. BRUSHMODEL LOADING
  227. ===============================================================================
  228. */
  229. byte *mod_base;
  230. /*
  231. =================
  232. Mod_LoadLighting
  233. =================
  234. */
  235. void Mod_LoadLighting (lump_t *l)
  236. {
  237. if (!l->filelen)
  238. {
  239. loadmodel->lightdata = NULL;
  240. return;
  241. }
  242. loadmodel->lightdata = Hunk_Alloc ( l->filelen);
  243. memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
  244. }
  245. /*
  246. =================
  247. Mod_LoadVisibility
  248. =================
  249. */
  250. void Mod_LoadVisibility (lump_t *l)
  251. {
  252. int i;
  253. if (!l->filelen)
  254. {
  255. loadmodel->vis = NULL;
  256. return;
  257. }
  258. loadmodel->vis = Hunk_Alloc ( l->filelen);
  259. memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
  260. loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);
  261. for (i=0 ; i<loadmodel->vis->numclusters ; i++)
  262. {
  263. loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);
  264. loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);
  265. }
  266. }
  267. /*
  268. =================
  269. Mod_LoadVertexes
  270. =================
  271. */
  272. void Mod_LoadVertexes (lump_t *l)
  273. {
  274. dvertex_t *in;
  275. mvertex_t *out;
  276. int i, count;
  277. in = (void *)(mod_base + l->fileofs);
  278. if (l->filelen % sizeof(*in))
  279. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  280. count = l->filelen / sizeof(*in);
  281. out = Hunk_Alloc ( count*sizeof(*out));
  282. loadmodel->vertexes = out;
  283. loadmodel->numvertexes = count;
  284. for ( i=0 ; i<count ; i++, in++, out++)
  285. {
  286. out->position[0] = LittleFloat (in->point[0]);
  287. out->position[1] = LittleFloat (in->point[1]);
  288. out->position[2] = LittleFloat (in->point[2]);
  289. }
  290. }
  291. /*
  292. =================
  293. RadiusFromBounds
  294. =================
  295. */
  296. float RadiusFromBounds (vec3_t mins, vec3_t maxs)
  297. {
  298. int i;
  299. vec3_t corner;
  300. for (i=0 ; i<3 ; i++)
  301. {
  302. corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
  303. }
  304. return VectorLength (corner);
  305. }
  306. /*
  307. =================
  308. Mod_LoadSubmodels
  309. =================
  310. */
  311. void Mod_LoadSubmodels (lump_t *l)
  312. {
  313. dmodel_t *in;
  314. mmodel_t *out;
  315. int i, j, count;
  316. in = (void *)(mod_base + l->fileofs);
  317. if (l->filelen % sizeof(*in))
  318. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  319. count = l->filelen / sizeof(*in);
  320. out = Hunk_Alloc ( count*sizeof(*out));
  321. loadmodel->submodels = out;
  322. loadmodel->numsubmodels = count;
  323. for ( i=0 ; i<count ; i++, in++, out++)
  324. {
  325. for (j=0 ; j<3 ; j++)
  326. { // spread the mins / maxs by a pixel
  327. out->mins[j] = LittleFloat (in->mins[j]) - 1;
  328. out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
  329. out->origin[j] = LittleFloat (in->origin[j]);
  330. }
  331. out->radius = RadiusFromBounds (out->mins, out->maxs);
  332. out->headnode = LittleLong (in->headnode);
  333. out->firstface = LittleLong (in->firstface);
  334. out->numfaces = LittleLong (in->numfaces);
  335. }
  336. }
  337. /*
  338. =================
  339. Mod_LoadEdges
  340. =================
  341. */
  342. void Mod_LoadEdges (lump_t *l)
  343. {
  344. dedge_t *in;
  345. medge_t *out;
  346. int i, count;
  347. in = (void *)(mod_base + l->fileofs);
  348. if (l->filelen % sizeof(*in))
  349. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  350. count = l->filelen / sizeof(*in);
  351. out = Hunk_Alloc ( (count + 1) * sizeof(*out));
  352. loadmodel->edges = out;
  353. loadmodel->numedges = count;
  354. for ( i=0 ; i<count ; i++, in++, out++)
  355. {
  356. out->v[0] = (unsigned short)LittleShort(in->v[0]);
  357. out->v[1] = (unsigned short)LittleShort(in->v[1]);
  358. }
  359. }
  360. /*
  361. =================
  362. Mod_LoadTexinfo
  363. =================
  364. */
  365. void Mod_LoadTexinfo (lump_t *l)
  366. {
  367. texinfo_t *in;
  368. mtexinfo_t *out, *step;
  369. int i, j, count;
  370. char name[MAX_QPATH];
  371. int next;
  372. in = (void *)(mod_base + l->fileofs);
  373. if (l->filelen % sizeof(*in))
  374. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  375. count = l->filelen / sizeof(*in);
  376. out = Hunk_Alloc ( count*sizeof(*out));
  377. loadmodel->texinfo = out;
  378. loadmodel->numtexinfo = count;
  379. for ( i=0 ; i<count ; i++, in++, out++)
  380. {
  381. for (j=0 ; j<8 ; j++)
  382. out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
  383. out->flags = LittleLong (in->flags);
  384. next = LittleLong (in->nexttexinfo);
  385. if (next > 0)
  386. out->next = loadmodel->texinfo + next;
  387. else
  388. out->next = NULL;
  389. Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
  390. out->image = GL_FindImage (name, it_wall);
  391. if (!out->image)
  392. {
  393. ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name);
  394. out->image = r_notexture;
  395. }
  396. }
  397. // count animation frames
  398. for (i=0 ; i<count ; i++)
  399. {
  400. out = &loadmodel->texinfo[i];
  401. out->numframes = 1;
  402. for (step = out->next ; step && step != out ; step=step->next)
  403. out->numframes++;
  404. }
  405. }
  406. /*
  407. ================
  408. CalcSurfaceExtents
  409. Fills in s->texturemins[] and s->extents[]
  410. ================
  411. */
  412. void CalcSurfaceExtents (msurface_t *s)
  413. {
  414. float mins[2], maxs[2], val;
  415. int i,j, e;
  416. mvertex_t *v;
  417. mtexinfo_t *tex;
  418. int bmins[2], bmaxs[2];
  419. mins[0] = mins[1] = 999999;
  420. maxs[0] = maxs[1] = -99999;
  421. tex = s->texinfo;
  422. for (i=0 ; i<s->numedges ; i++)
  423. {
  424. e = loadmodel->surfedges[s->firstedge+i];
  425. if (e >= 0)
  426. v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
  427. else
  428. v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
  429. for (j=0 ; j<2 ; j++)
  430. {
  431. val = v->position[0] * tex->vecs[j][0] +
  432. v->position[1] * tex->vecs[j][1] +
  433. v->position[2] * tex->vecs[j][2] +
  434. tex->vecs[j][3];
  435. if (val < mins[j])
  436. mins[j] = val;
  437. if (val > maxs[j])
  438. maxs[j] = val;
  439. }
  440. }
  441. for (i=0 ; i<2 ; i++)
  442. {
  443. bmins[i] = floor(mins[i]/16);
  444. bmaxs[i] = ceil(maxs[i]/16);
  445. s->texturemins[i] = bmins[i] * 16;
  446. s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
  447. // if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ )
  448. // ri.Sys_Error (ERR_DROP, "Bad surface extents");
  449. }
  450. }
  451. void GL_BuildPolygonFromSurface(msurface_t *fa);
  452. void GL_CreateSurfaceLightmap (msurface_t *surf);
  453. void GL_EndBuildingLightmaps (void);
  454. void GL_BeginBuildingLightmaps (model_t *m);
  455. /*
  456. =================
  457. Mod_LoadFaces
  458. =================
  459. */
  460. void Mod_LoadFaces (lump_t *l)
  461. {
  462. dface_t *in;
  463. msurface_t *out;
  464. int i, count, surfnum;
  465. int planenum, side;
  466. int ti;
  467. in = (void *)(mod_base + l->fileofs);
  468. if (l->filelen % sizeof(*in))
  469. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  470. count = l->filelen / sizeof(*in);
  471. out = Hunk_Alloc ( count*sizeof(*out));
  472. loadmodel->surfaces = out;
  473. loadmodel->numsurfaces = count;
  474. currentmodel = loadmodel;
  475. GL_BeginBuildingLightmaps (loadmodel);
  476. for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
  477. {
  478. out->firstedge = LittleLong(in->firstedge);
  479. out->numedges = LittleShort(in->numedges);
  480. out->flags = 0;
  481. out->polys = NULL;
  482. planenum = LittleShort(in->planenum);
  483. side = LittleShort(in->side);
  484. if (side)
  485. out->flags |= SURF_PLANEBACK;
  486. out->plane = loadmodel->planes + planenum;
  487. ti = LittleShort (in->texinfo);
  488. if (ti < 0 || ti >= loadmodel->numtexinfo)
  489. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: bad texinfo number");
  490. out->texinfo = loadmodel->texinfo + ti;
  491. CalcSurfaceExtents (out);
  492. // lighting info
  493. for (i=0 ; i<MAXLIGHTMAPS ; i++)
  494. out->styles[i] = in->styles[i];
  495. i = LittleLong(in->lightofs);
  496. if (i == -1)
  497. out->samples = NULL;
  498. else
  499. out->samples = loadmodel->lightdata + i;
  500. // set the drawing flags
  501. if (out->texinfo->flags & SURF_WARP)
  502. {
  503. out->flags |= SURF_DRAWTURB;
  504. for (i=0 ; i<2 ; i++)
  505. {
  506. out->extents[i] = 16384;
  507. out->texturemins[i] = -8192;
  508. }
  509. GL_SubdivideSurface (out); // cut up polygon for warps
  510. }
  511. // create lightmaps and polygons
  512. if ( !(out->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP) ) )
  513. GL_CreateSurfaceLightmap (out);
  514. if (! (out->texinfo->flags & SURF_WARP) )
  515. GL_BuildPolygonFromSurface(out);
  516. }
  517. GL_EndBuildingLightmaps ();
  518. }
  519. /*
  520. =================
  521. Mod_SetParent
  522. =================
  523. */
  524. void Mod_SetParent (mnode_t *node, mnode_t *parent)
  525. {
  526. node->parent = parent;
  527. if (node->contents != -1)
  528. return;
  529. Mod_SetParent (node->children[0], node);
  530. Mod_SetParent (node->children[1], node);
  531. }
  532. /*
  533. =================
  534. Mod_LoadNodes
  535. =================
  536. */
  537. void Mod_LoadNodes (lump_t *l)
  538. {
  539. int i, j, count, p;
  540. dnode_t *in;
  541. mnode_t *out;
  542. in = (void *)(mod_base + l->fileofs);
  543. if (l->filelen % sizeof(*in))
  544. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  545. count = l->filelen / sizeof(*in);
  546. out = Hunk_Alloc ( count*sizeof(*out));
  547. loadmodel->nodes = out;
  548. loadmodel->numnodes = count;
  549. for ( i=0 ; i<count ; i++, in++, out++)
  550. {
  551. for (j=0 ; j<3 ; j++)
  552. {
  553. out->minmaxs[j] = LittleShort (in->mins[j]);
  554. out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  555. }
  556. p = LittleLong(in->planenum);
  557. out->plane = loadmodel->planes + p;
  558. out->firstsurface = LittleShort (in->firstface);
  559. out->numsurfaces = LittleShort (in->numfaces);
  560. out->contents = -1; // differentiate from leafs
  561. for (j=0 ; j<2 ; j++)
  562. {
  563. p = LittleLong (in->children[j]);
  564. if (p >= 0)
  565. out->children[j] = loadmodel->nodes + p;
  566. else
  567. out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
  568. }
  569. }
  570. Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
  571. }
  572. /*
  573. =================
  574. Mod_LoadLeafs
  575. =================
  576. */
  577. void Mod_LoadLeafs (lump_t *l)
  578. {
  579. dleaf_t *in;
  580. mleaf_t *out;
  581. int i, j, count, p;
  582. // glpoly_t *poly;
  583. in = (void *)(mod_base + l->fileofs);
  584. if (l->filelen % sizeof(*in))
  585. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  586. count = l->filelen / sizeof(*in);
  587. out = Hunk_Alloc ( count*sizeof(*out));
  588. loadmodel->leafs = out;
  589. loadmodel->numleafs = count;
  590. for ( i=0 ; i<count ; i++, in++, out++)
  591. {
  592. for (j=0 ; j<3 ; j++)
  593. {
  594. out->minmaxs[j] = LittleShort (in->mins[j]);
  595. out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  596. }
  597. p = LittleLong(in->contents);
  598. out->contents = p;
  599. out->cluster = LittleShort(in->cluster);
  600. out->area = LittleShort(in->area);
  601. out->firstmarksurface = loadmodel->marksurfaces +
  602. LittleShort(in->firstleafface);
  603. out->nummarksurfaces = LittleShort(in->numleaffaces);
  604. // gl underwater warp
  605. #if 0
  606. if (out->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_THINWATER) )
  607. {
  608. for (j=0 ; j<out->nummarksurfaces ; j++)
  609. {
  610. out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
  611. for (poly = out->firstmarksurface[j]->polys ; poly ; poly=poly->next)
  612. poly->flags |= SURF_UNDERWATER;
  613. }
  614. }
  615. #endif
  616. }
  617. }
  618. /*
  619. =================
  620. Mod_LoadMarksurfaces
  621. =================
  622. */
  623. void Mod_LoadMarksurfaces (lump_t *l)
  624. {
  625. int i, j, count;
  626. short *in;
  627. msurface_t **out;
  628. in = (void *)(mod_base + l->fileofs);
  629. if (l->filelen % sizeof(*in))
  630. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  631. count = l->filelen / sizeof(*in);
  632. out = Hunk_Alloc ( count*sizeof(*out));
  633. loadmodel->marksurfaces = out;
  634. loadmodel->nummarksurfaces = count;
  635. for ( i=0 ; i<count ; i++)
  636. {
  637. j = LittleShort(in[i]);
  638. if (j < 0 || j >= loadmodel->numsurfaces)
  639. ri.Sys_Error (ERR_DROP, "Mod_ParseMarksurfaces: bad surface number");
  640. out[i] = loadmodel->surfaces + j;
  641. }
  642. }
  643. /*
  644. =================
  645. Mod_LoadSurfedges
  646. =================
  647. */
  648. void Mod_LoadSurfedges (lump_t *l)
  649. {
  650. int i, count;
  651. int *in, *out;
  652. in = (void *)(mod_base + l->fileofs);
  653. if (l->filelen % sizeof(*in))
  654. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  655. count = l->filelen / sizeof(*in);
  656. if (count < 1 || count >= MAX_MAP_SURFEDGES)
  657. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: bad surfedges count in %s: %i",
  658. loadmodel->name, count);
  659. out = Hunk_Alloc ( count*sizeof(*out));
  660. loadmodel->surfedges = out;
  661. loadmodel->numsurfedges = count;
  662. for ( i=0 ; i<count ; i++)
  663. out[i] = LittleLong (in[i]);
  664. }
  665. /*
  666. =================
  667. Mod_LoadPlanes
  668. =================
  669. */
  670. void Mod_LoadPlanes (lump_t *l)
  671. {
  672. int i, j;
  673. cplane_t *out;
  674. dplane_t *in;
  675. int count;
  676. int bits;
  677. in = (void *)(mod_base + l->fileofs);
  678. if (l->filelen % sizeof(*in))
  679. ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  680. count = l->filelen / sizeof(*in);
  681. out = Hunk_Alloc ( count*2*sizeof(*out));
  682. loadmodel->planes = out;
  683. loadmodel->numplanes = count;
  684. for ( i=0 ; i<count ; i++, in++, out++)
  685. {
  686. bits = 0;
  687. for (j=0 ; j<3 ; j++)
  688. {
  689. out->normal[j] = LittleFloat (in->normal[j]);
  690. if (out->normal[j] < 0)
  691. bits |= 1<<j;
  692. }
  693. out->dist = LittleFloat (in->dist);
  694. out->type = LittleLong (in->type);
  695. out->signbits = bits;
  696. }
  697. }
  698. /*
  699. =================
  700. Mod_LoadBrushModel
  701. =================
  702. */
  703. void Mod_LoadBrushModel (model_t *mod, void *buffer)
  704. {
  705. int i;
  706. dheader_t *header;
  707. mmodel_t *bm;
  708. loadmodel->type = mod_brush;
  709. if (loadmodel != mod_known)
  710. ri.Sys_Error (ERR_DROP, "Loaded a brush model after the world");
  711. header = (dheader_t *)buffer;
  712. i = LittleLong (header->version);
  713. if (i != BSPVERSION)
  714. ri.Sys_Error (ERR_DROP, "Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
  715. // swap all the lumps
  716. mod_base = (byte *)header;
  717. for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
  718. ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
  719. // load into heap
  720. Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
  721. Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
  722. Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
  723. Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
  724. Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
  725. Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
  726. Mod_LoadFaces (&header->lumps[LUMP_FACES]);
  727. Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]);
  728. Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
  729. Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
  730. Mod_LoadNodes (&header->lumps[LUMP_NODES]);
  731. Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
  732. mod->numframes = 2; // regular and alternate animation
  733. //
  734. // set up the submodels
  735. //
  736. for (i=0 ; i<mod->numsubmodels ; i++)
  737. {
  738. model_t *starmod;
  739. bm = &mod->submodels[i];
  740. starmod = &mod_inline[i];
  741. *starmod = *loadmodel;
  742. starmod->firstmodelsurface = bm->firstface;
  743. starmod->nummodelsurfaces = bm->numfaces;
  744. starmod->firstnode = bm->headnode;
  745. if (starmod->firstnode >= loadmodel->numnodes)
  746. ri.Sys_Error (ERR_DROP, "Inline model %i has bad firstnode", i);
  747. VectorCopy (bm->maxs, starmod->maxs);
  748. VectorCopy (bm->mins, starmod->mins);
  749. starmod->radius = bm->radius;
  750. if (i == 0)
  751. *loadmodel = *starmod;
  752. starmod->numleafs = bm->visleafs;
  753. }
  754. }
  755. /*
  756. ==============================================================================
  757. ALIAS MODELS
  758. ==============================================================================
  759. */
  760. /*
  761. =================
  762. Mod_LoadAliasModel
  763. =================
  764. */
  765. void Mod_LoadAliasModel (model_t *mod, void *buffer)
  766. {
  767. int i, j;
  768. dmdl_t *pinmodel, *pheader;
  769. dstvert_t *pinst, *poutst;
  770. dtriangle_t *pintri, *pouttri;
  771. daliasframe_t *pinframe, *poutframe;
  772. int *pincmd, *poutcmd;
  773. int version;
  774. pinmodel = (dmdl_t *)buffer;
  775. version = LittleLong (pinmodel->version);
  776. if (version != ALIAS_VERSION)
  777. ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
  778. mod->name, version, ALIAS_VERSION);
  779. pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end));
  780. // byte swap the header fields and sanity check
  781. for (i=0 ; i<sizeof(dmdl_t)/4 ; i++)
  782. ((int *)pheader)[i] = LittleLong (((int *)buffer)[i]);
  783. if (pheader->skinheight > MAX_LBM_HEIGHT)
  784. ri.Sys_Error (ERR_DROP, "model %s has a skin taller than %d", mod->name,
  785. MAX_LBM_HEIGHT);
  786. if (pheader->num_xyz <= 0)
  787. ri.Sys_Error (ERR_DROP, "model %s has no vertices", mod->name);
  788. if (pheader->num_xyz > MAX_VERTS)
  789. ri.Sys_Error (ERR_DROP, "model %s has too many vertices", mod->name);
  790. if (pheader->num_st <= 0)
  791. ri.Sys_Error (ERR_DROP, "model %s has no st vertices", mod->name);
  792. if (pheader->num_tris <= 0)
  793. ri.Sys_Error (ERR_DROP, "model %s has no triangles", mod->name);
  794. if (pheader->num_frames <= 0)
  795. ri.Sys_Error (ERR_DROP, "model %s has no frames", mod->name);
  796. //
  797. // load base s and t vertices (not used in gl version)
  798. //
  799. pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
  800. poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
  801. for (i=0 ; i<pheader->num_st ; i++)
  802. {
  803. poutst[i].s = LittleShort (pinst[i].s);
  804. poutst[i].t = LittleShort (pinst[i].t);
  805. }
  806. //
  807. // load triangle lists
  808. //
  809. pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
  810. pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
  811. for (i=0 ; i<pheader->num_tris ; i++)
  812. {
  813. for (j=0 ; j<3 ; j++)
  814. {
  815. pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
  816. pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
  817. }
  818. }
  819. //
  820. // load the frames
  821. //
  822. for (i=0 ; i<pheader->num_frames ; i++)
  823. {
  824. pinframe = (daliasframe_t *) ((byte *)pinmodel
  825. + pheader->ofs_frames + i * pheader->framesize);
  826. poutframe = (daliasframe_t *) ((byte *)pheader
  827. + pheader->ofs_frames + i * pheader->framesize);
  828. memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
  829. for (j=0 ; j<3 ; j++)
  830. {
  831. poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
  832. poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
  833. }
  834. // verts are all 8 bit, so no swapping needed
  835. memcpy (poutframe->verts, pinframe->verts,
  836. pheader->num_xyz*sizeof(dtrivertx_t));
  837. }
  838. mod->type = mod_alias;
  839. //
  840. // load the glcmds
  841. //
  842. pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
  843. poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds);
  844. for (i=0 ; i<pheader->num_glcmds ; i++)
  845. poutcmd[i] = LittleLong (pincmd[i]);
  846. // register all skins
  847. memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
  848. pheader->num_skins*MAX_SKINNAME);
  849. for (i=0 ; i<pheader->num_skins ; i++)
  850. {
  851. mod->skins[i] = GL_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME
  852. , it_skin);
  853. }
  854. mod->mins[0] = -32;
  855. mod->mins[1] = -32;
  856. mod->mins[2] = -32;
  857. mod->maxs[0] = 32;
  858. mod->maxs[1] = 32;
  859. mod->maxs[2] = 32;
  860. }
  861. /*
  862. ==============================================================================
  863. SPRITE MODELS
  864. ==============================================================================
  865. */
  866. /*
  867. =================
  868. Mod_LoadSpriteModel
  869. =================
  870. */
  871. void Mod_LoadSpriteModel (model_t *mod, void *buffer)
  872. {
  873. dsprite_t *sprin, *sprout;
  874. int i;
  875. sprin = (dsprite_t *)buffer;
  876. sprout = Hunk_Alloc (modfilelen);
  877. sprout->ident = LittleLong (sprin->ident);
  878. sprout->version = LittleLong (sprin->version);
  879. sprout->numframes = LittleLong (sprin->numframes);
  880. if (sprout->version != SPRITE_VERSION)
  881. ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
  882. mod->name, sprout->version, SPRITE_VERSION);
  883. if (sprout->numframes > MAX_MD2SKINS)
  884. ri.Sys_Error (ERR_DROP, "%s has too many frames (%i > %i)",
  885. mod->name, sprout->numframes, MAX_MD2SKINS);
  886. // byte swap everything
  887. for (i=0 ; i<sprout->numframes ; i++)
  888. {
  889. sprout->frames[i].width = LittleLong (sprin->frames[i].width);
  890. sprout->frames[i].height = LittleLong (sprin->frames[i].height);
  891. sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x);
  892. sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y);
  893. memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME);
  894. mod->skins[i] = GL_FindImage (sprout->frames[i].name,
  895. it_sprite);
  896. }
  897. mod->type = mod_sprite;
  898. }
  899. //=============================================================================
  900. /*
  901. @@@@@@@@@@@@@@@@@@@@@
  902. R_BeginRegistration
  903. Specifies the model that will be used as the world
  904. @@@@@@@@@@@@@@@@@@@@@
  905. */
  906. void R_BeginRegistration (char *model)
  907. {
  908. char fullname[MAX_QPATH];
  909. cvar_t *flushmap;
  910. registration_sequence++;
  911. r_oldviewcluster = -1; // force markleafs
  912. Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model);
  913. // explicitly free the old map if different
  914. // this guarantees that mod_known[0] is the world map
  915. flushmap = ri.Cvar_Get ("flushmap", "0", 0);
  916. if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
  917. Mod_Free (&mod_known[0]);
  918. r_worldmodel = Mod_ForName(fullname, true);
  919. r_viewcluster = -1;
  920. }
  921. /*
  922. @@@@@@@@@@@@@@@@@@@@@
  923. R_RegisterModel
  924. @@@@@@@@@@@@@@@@@@@@@
  925. */
  926. struct model_s *R_RegisterModel (char *name)
  927. {
  928. model_t *mod;
  929. int i;
  930. dsprite_t *sprout;
  931. dmdl_t *pheader;
  932. mod = Mod_ForName (name, false);
  933. if (mod)
  934. {
  935. mod->registration_sequence = registration_sequence;
  936. // register any images used by the models
  937. if (mod->type == mod_sprite)
  938. {
  939. sprout = (dsprite_t *)mod->extradata;
  940. for (i=0 ; i<sprout->numframes ; i++)
  941. mod->skins[i] = GL_FindImage (sprout->frames[i].name, it_sprite);
  942. }
  943. else if (mod->type == mod_alias)
  944. {
  945. pheader = (dmdl_t *)mod->extradata;
  946. for (i=0 ; i<pheader->num_skins ; i++)
  947. mod->skins[i] = GL_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
  948. //PGM
  949. mod->numframes = pheader->num_frames;
  950. //PGM
  951. }
  952. else if (mod->type == mod_brush)
  953. {
  954. for (i=0 ; i<mod->numtexinfo ; i++)
  955. mod->texinfo[i].image->registration_sequence = registration_sequence;
  956. }
  957. }
  958. return mod;
  959. }
  960. /*
  961. @@@@@@@@@@@@@@@@@@@@@
  962. R_EndRegistration
  963. @@@@@@@@@@@@@@@@@@@@@
  964. */
  965. void R_EndRegistration (void)
  966. {
  967. int i;
  968. model_t *mod;
  969. for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
  970. {
  971. if (!mod->name[0])
  972. continue;
  973. if (mod->registration_sequence != registration_sequence)
  974. { // don't need this model
  975. Mod_Free (mod);
  976. }
  977. }
  978. GL_FreeUnusedImages ();
  979. }
  980. //=============================================================================
  981. /*
  982. ================
  983. Mod_Free
  984. ================
  985. */
  986. void Mod_Free (model_t *mod)
  987. {
  988. Hunk_Free (mod->extradata);
  989. memset (mod, 0, sizeof(*mod));
  990. }
  991. /*
  992. ================
  993. Mod_FreeAll
  994. ================
  995. */
  996. void Mod_FreeAll (void)
  997. {
  998. int i;
  999. for (i=0 ; i<mod_numknown ; i++)
  1000. {
  1001. if (mod_known[i].extradatasize)
  1002. Mod_Free (&mod_known[i]);
  1003. }
  1004. }