RenderWorld_load.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "tr_local.h"
  23. /*
  24. ================
  25. idRenderWorldLocal::FreeWorld
  26. ================
  27. */
  28. void idRenderWorldLocal::FreeWorld() {
  29. int i;
  30. // this will free all the lightDefs and entityDefs
  31. FreeDefs();
  32. // free all the portals and check light/model references
  33. for ( i = 0 ; i < numPortalAreas ; i++ ) {
  34. portalArea_t *area;
  35. portal_t *portal, *nextPortal;
  36. area = &portalAreas[i];
  37. for ( portal = area->portals ; portal ; portal = nextPortal ) {
  38. nextPortal = portal->next;
  39. delete portal->w;
  40. R_StaticFree( portal );
  41. }
  42. // there shouldn't be any remaining lightRefs or entityRefs
  43. if ( area->lightRefs.areaNext != &area->lightRefs ) {
  44. common->Error( "FreeWorld: unexpected remaining lightRefs" );
  45. }
  46. if ( area->entityRefs.areaNext != &area->entityRefs ) {
  47. common->Error( "FreeWorld: unexpected remaining entityRefs" );
  48. }
  49. }
  50. if ( portalAreas ) {
  51. R_StaticFree( portalAreas );
  52. portalAreas = NULL;
  53. numPortalAreas = 0;
  54. R_StaticFree( areaScreenRect );
  55. areaScreenRect = NULL;
  56. }
  57. if ( doublePortals ) {
  58. R_StaticFree( doublePortals );
  59. doublePortals = NULL;
  60. numInterAreaPortals = 0;
  61. }
  62. if ( areaNodes ) {
  63. R_StaticFree( areaNodes );
  64. areaNodes = NULL;
  65. }
  66. // free all the inline idRenderModels
  67. for ( i = 0 ; i < localModels.Num() ; i++ ) {
  68. renderModelManager->RemoveModel( localModels[i] );
  69. delete localModels[i];
  70. }
  71. localModels.Clear();
  72. areaReferenceAllocator.Shutdown();
  73. interactionAllocator.Shutdown();
  74. areaNumRefAllocator.Shutdown();
  75. mapName = "<FREED>";
  76. }
  77. /*
  78. ================
  79. idRenderWorldLocal::TouchWorldModels
  80. ================
  81. */
  82. void idRenderWorldLocal::TouchWorldModels( void ) {
  83. int i;
  84. for ( i = 0 ; i < localModels.Num() ; i++ ) {
  85. renderModelManager->CheckModel( localModels[i]->Name() );
  86. }
  87. }
  88. /*
  89. ================
  90. idRenderWorldLocal::ParseModel
  91. ================
  92. */
  93. idRenderModel *idRenderWorldLocal::ParseModel( idLexer *src ) {
  94. idRenderModel *model;
  95. idToken token;
  96. int i, j;
  97. srfTriangles_t *tri;
  98. modelSurface_t surf;
  99. src->ExpectTokenString( "{" );
  100. // parse the name
  101. src->ExpectAnyToken( &token );
  102. model = renderModelManager->AllocModel();
  103. model->InitEmpty( token );
  104. int numSurfaces = src->ParseInt();
  105. if ( numSurfaces < 0 ) {
  106. src->Error( "R_ParseModel: bad numSurfaces" );
  107. }
  108. for ( i = 0 ; i < numSurfaces ; i++ ) {
  109. src->ExpectTokenString( "{" );
  110. src->ExpectAnyToken( &token );
  111. surf.shader = declManager->FindMaterial( token );
  112. ((idMaterial*)surf.shader)->AddReference();
  113. tri = R_AllocStaticTriSurf();
  114. surf.geometry = tri;
  115. tri->numVerts = src->ParseInt();
  116. tri->numIndexes = src->ParseInt();
  117. R_AllocStaticTriSurfVerts( tri, tri->numVerts );
  118. for ( j = 0 ; j < tri->numVerts ; j++ ) {
  119. float vec[8];
  120. src->Parse1DMatrix( 8, vec );
  121. tri->verts[j].xyz[0] = vec[0];
  122. tri->verts[j].xyz[1] = vec[1];
  123. tri->verts[j].xyz[2] = vec[2];
  124. tri->verts[j].st[0] = vec[3];
  125. tri->verts[j].st[1] = vec[4];
  126. tri->verts[j].normal[0] = vec[5];
  127. tri->verts[j].normal[1] = vec[6];
  128. tri->verts[j].normal[2] = vec[7];
  129. }
  130. R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
  131. for ( j = 0 ; j < tri->numIndexes ; j++ ) {
  132. tri->indexes[j] = src->ParseInt();
  133. }
  134. src->ExpectTokenString( "}" );
  135. // add the completed surface to the model
  136. model->AddSurface( surf );
  137. }
  138. src->ExpectTokenString( "}" );
  139. model->FinishSurfaces();
  140. return model;
  141. }
  142. /*
  143. ================
  144. idRenderWorldLocal::ParseShadowModel
  145. ================
  146. */
  147. idRenderModel *idRenderWorldLocal::ParseShadowModel( idLexer *src ) {
  148. idRenderModel *model;
  149. idToken token;
  150. int j;
  151. srfTriangles_t *tri;
  152. modelSurface_t surf;
  153. src->ExpectTokenString( "{" );
  154. // parse the name
  155. src->ExpectAnyToken( &token );
  156. model = renderModelManager->AllocModel();
  157. model->InitEmpty( token );
  158. surf.shader = tr.defaultMaterial;
  159. tri = R_AllocStaticTriSurf();
  160. surf.geometry = tri;
  161. tri->numVerts = src->ParseInt();
  162. tri->numShadowIndexesNoCaps = src->ParseInt();
  163. tri->numShadowIndexesNoFrontCaps = src->ParseInt();
  164. tri->numIndexes = src->ParseInt();
  165. tri->shadowCapPlaneBits = src->ParseInt();
  166. R_AllocStaticTriSurfShadowVerts( tri, tri->numVerts );
  167. tri->bounds.Clear();
  168. for ( j = 0 ; j < tri->numVerts ; j++ ) {
  169. float vec[8];
  170. src->Parse1DMatrix( 3, vec );
  171. tri->shadowVertexes[j].xyz[0] = vec[0];
  172. tri->shadowVertexes[j].xyz[1] = vec[1];
  173. tri->shadowVertexes[j].xyz[2] = vec[2];
  174. tri->shadowVertexes[j].xyz[3] = 1; // no homogenous value
  175. tri->bounds.AddPoint( tri->shadowVertexes[j].xyz.ToVec3() );
  176. }
  177. R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
  178. for ( j = 0 ; j < tri->numIndexes ; j++ ) {
  179. tri->indexes[j] = src->ParseInt();
  180. }
  181. // add the completed surface to the model
  182. model->AddSurface( surf );
  183. src->ExpectTokenString( "}" );
  184. // we do NOT do a model->FinishSurfaceces, because we don't need sil edges, planes, tangents, etc.
  185. // model->FinishSurfaces();
  186. return model;
  187. }
  188. /*
  189. ================
  190. idRenderWorldLocal::SetupAreaRefs
  191. ================
  192. */
  193. void idRenderWorldLocal::SetupAreaRefs() {
  194. int i;
  195. connectedAreaNum = 0;
  196. for ( i = 0 ; i < numPortalAreas ; i++ ) {
  197. portalAreas[i].areaNum = i;
  198. portalAreas[i].lightRefs.areaNext =
  199. portalAreas[i].lightRefs.areaPrev =
  200. &portalAreas[i].lightRefs;
  201. portalAreas[i].entityRefs.areaNext =
  202. portalAreas[i].entityRefs.areaPrev =
  203. &portalAreas[i].entityRefs;
  204. }
  205. }
  206. /*
  207. ================
  208. idRenderWorldLocal::ParseInterAreaPortals
  209. ================
  210. */
  211. void idRenderWorldLocal::ParseInterAreaPortals( idLexer *src ) {
  212. int i, j;
  213. src->ExpectTokenString( "{" );
  214. numPortalAreas = src->ParseInt();
  215. if ( numPortalAreas < 0 ) {
  216. src->Error( "R_ParseInterAreaPortals: bad numPortalAreas" );
  217. return;
  218. }
  219. portalAreas = (portalArea_t *)R_ClearedStaticAlloc( numPortalAreas * sizeof( portalAreas[0] ) );
  220. areaScreenRect = (idScreenRect *) R_ClearedStaticAlloc( numPortalAreas * sizeof( idScreenRect ) );
  221. // set the doubly linked lists
  222. SetupAreaRefs();
  223. numInterAreaPortals = src->ParseInt();
  224. if ( numInterAreaPortals < 0 ) {
  225. src->Error( "R_ParseInterAreaPortals: bad numInterAreaPortals" );
  226. return;
  227. }
  228. doublePortals = (doublePortal_t *)R_ClearedStaticAlloc( numInterAreaPortals *
  229. sizeof( doublePortals [0] ) );
  230. for ( i = 0 ; i < numInterAreaPortals ; i++ ) {
  231. int numPoints, a1, a2;
  232. idWinding *w;
  233. portal_t *p;
  234. numPoints = src->ParseInt();
  235. a1 = src->ParseInt();
  236. a2 = src->ParseInt();
  237. w = new idWinding( numPoints );
  238. w->SetNumPoints( numPoints );
  239. for ( j = 0 ; j < numPoints ; j++ ) {
  240. src->Parse1DMatrix( 3, (*w)[j].ToFloatPtr() );
  241. // no texture coordinates
  242. (*w)[j][3] = 0;
  243. (*w)[j][4] = 0;
  244. }
  245. // add the portal to a1
  246. p = (portal_t *)R_ClearedStaticAlloc( sizeof( *p ) );
  247. p->intoArea = a2;
  248. p->doublePortal = &doublePortals[i];
  249. p->w = w;
  250. p->w->GetPlane( p->plane );
  251. p->next = portalAreas[a1].portals;
  252. portalAreas[a1].portals = p;
  253. doublePortals[i].portals[0] = p;
  254. // reverse it for a2
  255. p = (portal_t *)R_ClearedStaticAlloc( sizeof( *p ) );
  256. p->intoArea = a1;
  257. p->doublePortal = &doublePortals[i];
  258. p->w = w->Reverse();
  259. p->w->GetPlane( p->plane );
  260. p->next = portalAreas[a2].portals;
  261. portalAreas[a2].portals = p;
  262. doublePortals[i].portals[1] = p;
  263. }
  264. src->ExpectTokenString( "}" );
  265. }
  266. /*
  267. ================
  268. idRenderWorldLocal::ParseNodes
  269. ================
  270. */
  271. void idRenderWorldLocal::ParseNodes( idLexer *src ) {
  272. int i;
  273. src->ExpectTokenString( "{" );
  274. numAreaNodes = src->ParseInt();
  275. if ( numAreaNodes < 0 ) {
  276. src->Error( "R_ParseNodes: bad numAreaNodes" );
  277. }
  278. areaNodes = (areaNode_t *)R_ClearedStaticAlloc( numAreaNodes * sizeof( areaNodes[0] ) );
  279. for ( i = 0 ; i < numAreaNodes ; i++ ) {
  280. areaNode_t *node;
  281. node = &areaNodes[i];
  282. src->Parse1DMatrix( 4, node->plane.ToFloatPtr() );
  283. node->children[0] = src->ParseInt();
  284. node->children[1] = src->ParseInt();
  285. }
  286. src->ExpectTokenString( "}" );
  287. }
  288. /*
  289. ================
  290. idRenderWorldLocal::CommonChildrenArea_r
  291. ================
  292. */
  293. int idRenderWorldLocal::CommonChildrenArea_r( areaNode_t *node ) {
  294. int nums[2];
  295. for ( int i = 0 ; i < 2 ; i++ ) {
  296. if ( node->children[i] <= 0 ) {
  297. nums[i] = -1 - node->children[i];
  298. } else {
  299. nums[i] = CommonChildrenArea_r( &areaNodes[ node->children[i] ] );
  300. }
  301. }
  302. // solid nodes will match any area
  303. if ( nums[0] == AREANUM_SOLID ) {
  304. nums[0] = nums[1];
  305. }
  306. if ( nums[1] == AREANUM_SOLID ) {
  307. nums[1] = nums[0];
  308. }
  309. int common;
  310. if ( nums[0] == nums[1] ) {
  311. common = nums[0];
  312. } else {
  313. common = CHILDREN_HAVE_MULTIPLE_AREAS;
  314. }
  315. node->commonChildrenArea = common;
  316. return common;
  317. }
  318. /*
  319. =================
  320. idRenderWorldLocal::ClearWorld
  321. Sets up for a single area world
  322. =================
  323. */
  324. void idRenderWorldLocal::ClearWorld() {
  325. numPortalAreas = 1;
  326. portalAreas = (portalArea_t *)R_ClearedStaticAlloc( sizeof( portalAreas[0] ) );
  327. areaScreenRect = (idScreenRect *) R_ClearedStaticAlloc( sizeof( idScreenRect ) );
  328. SetupAreaRefs();
  329. // even though we only have a single area, create a node
  330. // that has both children pointing at it so we don't need to
  331. //
  332. areaNodes = (areaNode_t *)R_ClearedStaticAlloc( sizeof( areaNodes[0] ) );
  333. areaNodes[0].plane[3] = 1;
  334. areaNodes[0].children[0] = -1;
  335. areaNodes[0].children[1] = -1;
  336. }
  337. /*
  338. =================
  339. idRenderWorldLocal::FreeDefs
  340. dump all the interactions
  341. =================
  342. */
  343. void idRenderWorldLocal::FreeDefs() {
  344. int i;
  345. generateAllInteractionsCalled = false;
  346. if ( interactionTable ) {
  347. R_StaticFree( interactionTable );
  348. interactionTable = NULL;
  349. }
  350. // free all lightDefs
  351. for ( i = 0 ; i < lightDefs.Num() ; i++ ) {
  352. idRenderLightLocal *light;
  353. light = lightDefs[i];
  354. if ( light && light->world == this ) {
  355. FreeLightDef( i );
  356. lightDefs[i] = NULL;
  357. }
  358. }
  359. // free all entityDefs
  360. for ( i = 0 ; i < entityDefs.Num() ; i++ ) {
  361. idRenderEntityLocal *mod;
  362. mod = entityDefs[i];
  363. if ( mod && mod->world == this ) {
  364. FreeEntityDef( i );
  365. entityDefs[i] = NULL;
  366. }
  367. }
  368. }
  369. /*
  370. =================
  371. idRenderWorldLocal::InitFromMap
  372. A NULL or empty name will make a world without a map model, which
  373. is still useful for displaying a bare model
  374. =================
  375. */
  376. bool idRenderWorldLocal::InitFromMap( const char *name ) {
  377. idLexer * src;
  378. idToken token;
  379. idStr filename;
  380. idRenderModel * lastModel;
  381. // if this is an empty world, initialize manually
  382. if ( !name || !name[0] ) {
  383. FreeWorld();
  384. mapName.Clear();
  385. ClearWorld();
  386. return true;
  387. }
  388. // load it
  389. filename = name;
  390. filename.SetFileExtension( PROC_FILE_EXT );
  391. // if we are reloading the same map, check the timestamp
  392. // and try to skip all the work
  393. ID_TIME_T currentTimeStamp;
  394. fileSystem->ReadFile( filename, NULL, &currentTimeStamp );
  395. if ( name == mapName ) {
  396. if ( currentTimeStamp != FILE_NOT_FOUND_TIMESTAMP && currentTimeStamp == mapTimeStamp ) {
  397. common->Printf( "idRenderWorldLocal::InitFromMap: retaining existing map\n" );
  398. FreeDefs();
  399. TouchWorldModels();
  400. AddWorldModelEntities();
  401. ClearPortalStates();
  402. return true;
  403. }
  404. common->Printf( "idRenderWorldLocal::InitFromMap: timestamp has changed, reloading.\n" );
  405. }
  406. FreeWorld();
  407. src = new idLexer( filename, LEXFL_NOSTRINGCONCAT | LEXFL_NODOLLARPRECOMPILE );
  408. if ( !src->IsLoaded() ) {
  409. common->Printf( "idRenderWorldLocal::InitFromMap: %s not found\n", filename.c_str() );
  410. ClearWorld();
  411. return false;
  412. }
  413. mapName = name;
  414. mapTimeStamp = currentTimeStamp;
  415. // if we are writing a demo, archive the load command
  416. if ( session->writeDemo ) {
  417. WriteLoadMap();
  418. }
  419. if ( !src->ReadToken( &token ) || token.Icmp( PROC_FILE_ID ) ) {
  420. common->Printf( "idRenderWorldLocal::InitFromMap: bad id '%s' instead of '%s'\n", token.c_str(), PROC_FILE_ID );
  421. delete src;
  422. return false;
  423. }
  424. // parse the file
  425. while ( 1 ) {
  426. if ( !src->ReadToken( &token ) ) {
  427. break;
  428. }
  429. if ( token == "model" ) {
  430. lastModel = ParseModel( src );
  431. // add it to the model manager list
  432. renderModelManager->AddModel( lastModel );
  433. // save it in the list to free when clearing this map
  434. localModels.Append( lastModel );
  435. continue;
  436. }
  437. if ( token == "shadowModel" ) {
  438. lastModel = ParseShadowModel( src );
  439. // add it to the model manager list
  440. renderModelManager->AddModel( lastModel );
  441. // save it in the list to free when clearing this map
  442. localModels.Append( lastModel );
  443. continue;
  444. }
  445. if ( token == "interAreaPortals" ) {
  446. ParseInterAreaPortals( src );
  447. continue;
  448. }
  449. if ( token == "nodes" ) {
  450. ParseNodes( src );
  451. continue;
  452. }
  453. src->Error( "idRenderWorldLocal::InitFromMap: bad token \"%s\"", token.c_str() );
  454. }
  455. delete src;
  456. // if it was a trivial map without any areas, create a single area
  457. if ( !numPortalAreas ) {
  458. ClearWorld();
  459. }
  460. // find the points where we can early-our of reference pushing into the BSP tree
  461. CommonChildrenArea_r( &areaNodes[0] );
  462. AddWorldModelEntities();
  463. ClearPortalStates();
  464. // done!
  465. return true;
  466. }
  467. /*
  468. =====================
  469. idRenderWorldLocal::ClearPortalStates
  470. =====================
  471. */
  472. void idRenderWorldLocal::ClearPortalStates() {
  473. int i, j;
  474. // all portals start off open
  475. for ( i = 0 ; i < numInterAreaPortals ; i++ ) {
  476. doublePortals[i].blockingBits = PS_BLOCK_NONE;
  477. }
  478. // flood fill all area connections
  479. for ( i = 0 ; i < numPortalAreas ; i++ ) {
  480. for ( j = 0 ; j < NUM_PORTAL_ATTRIBUTES ; j++ ) {
  481. connectedAreaNum++;
  482. FloodConnectedAreas( &portalAreas[i], j );
  483. }
  484. }
  485. }
  486. /*
  487. =====================
  488. idRenderWorldLocal::AddWorldModelEntities
  489. =====================
  490. */
  491. void idRenderWorldLocal::AddWorldModelEntities() {
  492. int i;
  493. // add the world model for each portal area
  494. // we can't just call AddEntityDef, because that would place the references
  495. // based on the bounding box, rather than explicitly into the correct area
  496. for ( i = 0 ; i < numPortalAreas ; i++ ) {
  497. idRenderEntityLocal *def;
  498. int index;
  499. def = new idRenderEntityLocal;
  500. // try and reuse a free spot
  501. index = entityDefs.FindNull();
  502. if ( index == -1 ) {
  503. index = entityDefs.Append(def);
  504. } else {
  505. entityDefs[index] = def;
  506. }
  507. def->index = index;
  508. def->world = this;
  509. def->parms.hModel = renderModelManager->FindModel( va("_area%i", i ) );
  510. if ( def->parms.hModel->IsDefaultModel() || !def->parms.hModel->IsStaticWorldModel() ) {
  511. common->Error( "idRenderWorldLocal::InitFromMap: bad area model lookup" );
  512. }
  513. idRenderModel *hModel = def->parms.hModel;
  514. for ( int j = 0; j < hModel->NumSurfaces(); j++ ) {
  515. const modelSurface_t *surf = hModel->Surface( j );
  516. if ( surf->shader->GetName() == idStr( "textures/skies/skyportal" ) ) {
  517. def->needsPortalSky = true;
  518. }
  519. }
  520. def->referenceBounds = def->parms.hModel->Bounds();
  521. def->parms.axis[0][0] = 1;
  522. def->parms.axis[1][1] = 1;
  523. def->parms.axis[2][2] = 1;
  524. R_AxisToModelMatrix( def->parms.axis, def->parms.origin, def->modelMatrix );
  525. // in case an explicit shader is used on the world, we don't
  526. // want it to have a 0 alpha or color
  527. def->parms.shaderParms[0] =
  528. def->parms.shaderParms[1] =
  529. def->parms.shaderParms[2] =
  530. def->parms.shaderParms[3] = 1;
  531. AddEntityRefToArea( def, &portalAreas[i] );
  532. }
  533. }
  534. /*
  535. =====================
  536. CheckAreaForPortalSky
  537. =====================
  538. */
  539. bool idRenderWorldLocal::CheckAreaForPortalSky( int areaNum ) {
  540. areaReference_t *ref;
  541. assert( areaNum >= 0 && areaNum < numPortalAreas );
  542. for ( ref = portalAreas[areaNum].entityRefs.areaNext; ref->entity; ref = ref->areaNext ) {
  543. assert( ref->area == &portalAreas[areaNum] );
  544. if ( ref->entity && ref->entity->needsPortalSky ) {
  545. return true;
  546. }
  547. }
  548. return false;
  549. }