tr_bsp.c 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. // tr_map.c
  19. #include "tr_local.h"
  20. /*
  21. Loads and prepares a map file for scene rendering.
  22. A single entry point:
  23. void RE_LoadWorldMap( const char *name );
  24. */
  25. static world_t s_worldData;
  26. static byte *fileBase;
  27. int c_subdivisions;
  28. int c_gridVerts;
  29. //===============================================================================
  30. static void HSVtoRGB( float h, float s, float v, float rgb[3] )
  31. {
  32. int i;
  33. float f;
  34. float p, q, t;
  35. h *= 5;
  36. i = floor( h );
  37. f = h - i;
  38. p = v * ( 1 - s );
  39. q = v * ( 1 - s * f );
  40. t = v * ( 1 - s * ( 1 - f ) );
  41. switch ( i )
  42. {
  43. case 0:
  44. rgb[0] = v;
  45. rgb[1] = t;
  46. rgb[2] = p;
  47. break;
  48. case 1:
  49. rgb[0] = q;
  50. rgb[1] = v;
  51. rgb[2] = p;
  52. break;
  53. case 2:
  54. rgb[0] = p;
  55. rgb[1] = v;
  56. rgb[2] = t;
  57. break;
  58. case 3:
  59. rgb[0] = p;
  60. rgb[1] = q;
  61. rgb[2] = v;
  62. break;
  63. case 4:
  64. rgb[0] = t;
  65. rgb[1] = p;
  66. rgb[2] = v;
  67. break;
  68. case 5:
  69. rgb[0] = v;
  70. rgb[1] = p;
  71. rgb[2] = q;
  72. break;
  73. }
  74. }
  75. /*
  76. ===============
  77. R_ColorShiftLightingBytes
  78. ===============
  79. */
  80. static void R_ColorShiftLightingBytes( byte in[4], byte out[4] ) {
  81. int shift, r, g, b;
  82. // shift the color data based on overbright range
  83. shift = r_mapOverBrightBits->integer - tr.overbrightBits;
  84. // shift the data based on overbright range
  85. r = in[0] << shift;
  86. g = in[1] << shift;
  87. b = in[2] << shift;
  88. // normalize by color instead of saturating to white
  89. if ( ( r | g | b ) > 255 ) {
  90. int max;
  91. max = r > g ? r : g;
  92. max = max > b ? max : b;
  93. r = r * 255 / max;
  94. g = g * 255 / max;
  95. b = b * 255 / max;
  96. }
  97. out[0] = r;
  98. out[1] = g;
  99. out[2] = b;
  100. out[3] = in[3];
  101. }
  102. /*
  103. ===============
  104. R_LoadLightmaps
  105. ===============
  106. */
  107. #define LIGHTMAP_SIZE 128
  108. static void R_LoadLightmaps( lump_t *l ) {
  109. byte *buf, *buf_p;
  110. int len;
  111. MAC_STATIC byte image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4];
  112. int i, j;
  113. float maxIntensity = 0;
  114. double sumIntensity = 0;
  115. len = l->filelen;
  116. if ( !len ) {
  117. return;
  118. }
  119. buf = fileBase + l->fileofs;
  120. // we are about to upload textures
  121. R_SyncRenderThread();
  122. // create all the lightmaps
  123. tr.numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);
  124. if ( tr.numLightmaps == 1 ) {
  125. //FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
  126. //this avoids this, but isn't the correct solution.
  127. tr.numLightmaps++;
  128. }
  129. // if we are in r_vertexLight mode, we don't need the lightmaps at all
  130. if ( r_vertexLight->integer || glConfig.hardwareType == GLHW_PERMEDIA2 ) {
  131. return;
  132. }
  133. for ( i = 0 ; i < tr.numLightmaps ; i++ ) {
  134. // expand the 24 bit on-disk to 32 bit
  135. buf_p = buf + i * LIGHTMAP_SIZE*LIGHTMAP_SIZE * 3;
  136. if ( r_lightmap->integer == 2 )
  137. { // color code by intensity as development tool (FIXME: check range)
  138. for ( j = 0; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ )
  139. {
  140. float r = buf_p[j*3+0];
  141. float g = buf_p[j*3+1];
  142. float b = buf_p[j*3+2];
  143. float intensity;
  144. float out[3];
  145. intensity = 0.33f * r + 0.685f * g + 0.063f * b;
  146. if ( intensity > 255 )
  147. intensity = 1.0f;
  148. else
  149. intensity /= 255.0f;
  150. if ( intensity > maxIntensity )
  151. maxIntensity = intensity;
  152. HSVtoRGB( intensity, 1.00, 0.50, out );
  153. image[j*4+0] = out[0] * 255;
  154. image[j*4+1] = out[1] * 255;
  155. image[j*4+2] = out[2] * 255;
  156. image[j*4+3] = 255;
  157. sumIntensity += intensity;
  158. }
  159. } else {
  160. for ( j = 0 ; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ ) {
  161. R_ColorShiftLightingBytes( &buf_p[j*3], &image[j*4] );
  162. image[j*4+3] = 255;
  163. }
  164. }
  165. tr.lightmaps[i] = R_CreateImage( va("*lightmap%d",i), image,
  166. LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP );
  167. }
  168. if ( r_lightmap->integer == 2 ) {
  169. ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) );
  170. }
  171. }
  172. /*
  173. =================
  174. RE_SetWorldVisData
  175. This is called by the clipmodel subsystem so we can share the 1.8 megs of
  176. space in big maps...
  177. =================
  178. */
  179. void RE_SetWorldVisData( const byte *vis ) {
  180. tr.externalVisData = vis;
  181. }
  182. /*
  183. =================
  184. R_LoadVisibility
  185. =================
  186. */
  187. static void R_LoadVisibility( lump_t *l ) {
  188. int len;
  189. byte *buf;
  190. len = ( s_worldData.numClusters + 63 ) & ~63;
  191. s_worldData.novis = ri.Hunk_Alloc( len, h_low );
  192. Com_Memset( s_worldData.novis, 0xff, len );
  193. len = l->filelen;
  194. if ( !len ) {
  195. return;
  196. }
  197. buf = fileBase + l->fileofs;
  198. s_worldData.numClusters = LittleLong( ((int *)buf)[0] );
  199. s_worldData.clusterBytes = LittleLong( ((int *)buf)[1] );
  200. // CM_Load should have given us the vis data to share, so
  201. // we don't need to allocate another copy
  202. if ( tr.externalVisData ) {
  203. s_worldData.vis = tr.externalVisData;
  204. } else {
  205. byte *dest;
  206. dest = ri.Hunk_Alloc( len - 8, h_low );
  207. Com_Memcpy( dest, buf + 8, len - 8 );
  208. s_worldData.vis = dest;
  209. }
  210. }
  211. //===============================================================================
  212. /*
  213. ===============
  214. ShaderForShaderNum
  215. ===============
  216. */
  217. static shader_t *ShaderForShaderNum( int shaderNum, int lightmapNum ) {
  218. shader_t *shader;
  219. dshader_t *dsh;
  220. shaderNum = LittleLong( shaderNum );
  221. if ( shaderNum < 0 || shaderNum >= s_worldData.numShaders ) {
  222. ri.Error( ERR_DROP, "ShaderForShaderNum: bad num %i", shaderNum );
  223. }
  224. dsh = &s_worldData.shaders[ shaderNum ];
  225. if ( r_vertexLight->integer || glConfig.hardwareType == GLHW_PERMEDIA2 ) {
  226. lightmapNum = LIGHTMAP_BY_VERTEX;
  227. }
  228. if ( r_fullbright->integer ) {
  229. lightmapNum = LIGHTMAP_WHITEIMAGE;
  230. }
  231. shader = R_FindShader( dsh->shader, lightmapNum, qtrue );
  232. // if the shader had errors, just use default shader
  233. if ( shader->defaultShader ) {
  234. return tr.defaultShader;
  235. }
  236. return shader;
  237. }
  238. /*
  239. ===============
  240. ParseFace
  241. ===============
  242. */
  243. static void ParseFace( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int *indexes ) {
  244. int i, j;
  245. srfSurfaceFace_t *cv;
  246. int numPoints, numIndexes;
  247. int lightmapNum;
  248. int sfaceSize, ofsIndexes;
  249. lightmapNum = LittleLong( ds->lightmapNum );
  250. // get fog volume
  251. surf->fogIndex = LittleLong( ds->fogNum ) + 1;
  252. // get shader value
  253. surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapNum );
  254. if ( r_singleShader->integer && !surf->shader->isSky ) {
  255. surf->shader = tr.defaultShader;
  256. }
  257. numPoints = LittleLong( ds->numVerts );
  258. if (numPoints > MAX_FACE_POINTS) {
  259. ri.Printf( PRINT_WARNING, "WARNING: MAX_FACE_POINTS exceeded: %i\n", numPoints);
  260. numPoints = MAX_FACE_POINTS;
  261. surf->shader = tr.defaultShader;
  262. }
  263. numIndexes = LittleLong( ds->numIndexes );
  264. // create the srfSurfaceFace_t
  265. sfaceSize = ( int ) &((srfSurfaceFace_t *)0)->points[numPoints];
  266. ofsIndexes = sfaceSize;
  267. sfaceSize += sizeof( int ) * numIndexes;
  268. cv = ri.Hunk_Alloc( sfaceSize, h_low );
  269. cv->surfaceType = SF_FACE;
  270. cv->numPoints = numPoints;
  271. cv->numIndices = numIndexes;
  272. cv->ofsIndices = ofsIndexes;
  273. verts += LittleLong( ds->firstVert );
  274. for ( i = 0 ; i < numPoints ; i++ ) {
  275. for ( j = 0 ; j < 3 ; j++ ) {
  276. cv->points[i][j] = LittleFloat( verts[i].xyz[j] );
  277. }
  278. for ( j = 0 ; j < 2 ; j++ ) {
  279. cv->points[i][3+j] = LittleFloat( verts[i].st[j] );
  280. cv->points[i][5+j] = LittleFloat( verts[i].lightmap[j] );
  281. }
  282. R_ColorShiftLightingBytes( verts[i].color, (byte *)&cv->points[i][7] );
  283. }
  284. indexes += LittleLong( ds->firstIndex );
  285. for ( i = 0 ; i < numIndexes ; i++ ) {
  286. ((int *)((byte *)cv + cv->ofsIndices ))[i] = LittleLong( indexes[ i ] );
  287. }
  288. // take the plane information from the lightmap vector
  289. for ( i = 0 ; i < 3 ; i++ ) {
  290. cv->plane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
  291. }
  292. cv->plane.dist = DotProduct( cv->points[0], cv->plane.normal );
  293. SetPlaneSignbits( &cv->plane );
  294. cv->plane.type = PlaneTypeForNormal( cv->plane.normal );
  295. surf->data = (surfaceType_t *)cv;
  296. }
  297. /*
  298. ===============
  299. ParseMesh
  300. ===============
  301. */
  302. static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, msurface_t *surf ) {
  303. srfGridMesh_t *grid;
  304. int i, j;
  305. int width, height, numPoints;
  306. MAC_STATIC drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE];
  307. int lightmapNum;
  308. vec3_t bounds[2];
  309. vec3_t tmpVec;
  310. static surfaceType_t skipData = SF_SKIP;
  311. lightmapNum = LittleLong( ds->lightmapNum );
  312. // get fog volume
  313. surf->fogIndex = LittleLong( ds->fogNum ) + 1;
  314. // get shader value
  315. surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapNum );
  316. if ( r_singleShader->integer && !surf->shader->isSky ) {
  317. surf->shader = tr.defaultShader;
  318. }
  319. // we may have a nodraw surface, because they might still need to
  320. // be around for movement clipping
  321. if ( s_worldData.shaders[ LittleLong( ds->shaderNum ) ].surfaceFlags & SURF_NODRAW ) {
  322. surf->data = &skipData;
  323. return;
  324. }
  325. width = LittleLong( ds->patchWidth );
  326. height = LittleLong( ds->patchHeight );
  327. verts += LittleLong( ds->firstVert );
  328. numPoints = width * height;
  329. for ( i = 0 ; i < numPoints ; i++ ) {
  330. for ( j = 0 ; j < 3 ; j++ ) {
  331. points[i].xyz[j] = LittleFloat( verts[i].xyz[j] );
  332. points[i].normal[j] = LittleFloat( verts[i].normal[j] );
  333. }
  334. for ( j = 0 ; j < 2 ; j++ ) {
  335. points[i].st[j] = LittleFloat( verts[i].st[j] );
  336. points[i].lightmap[j] = LittleFloat( verts[i].lightmap[j] );
  337. }
  338. R_ColorShiftLightingBytes( verts[i].color, points[i].color );
  339. }
  340. // pre-tesseleate
  341. grid = R_SubdividePatchToGrid( width, height, points );
  342. surf->data = (surfaceType_t *)grid;
  343. // copy the level of detail origin, which is the center
  344. // of the group of all curves that must subdivide the same
  345. // to avoid cracking
  346. for ( i = 0 ; i < 3 ; i++ ) {
  347. bounds[0][i] = LittleFloat( ds->lightmapVecs[0][i] );
  348. bounds[1][i] = LittleFloat( ds->lightmapVecs[1][i] );
  349. }
  350. VectorAdd( bounds[0], bounds[1], bounds[1] );
  351. VectorScale( bounds[1], 0.5f, grid->lodOrigin );
  352. VectorSubtract( bounds[0], grid->lodOrigin, tmpVec );
  353. grid->lodRadius = VectorLength( tmpVec );
  354. }
  355. /*
  356. ===============
  357. ParseTriSurf
  358. ===============
  359. */
  360. static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int *indexes ) {
  361. srfTriangles_t *tri;
  362. int i, j;
  363. int numVerts, numIndexes;
  364. // get fog volume
  365. surf->fogIndex = LittleLong( ds->fogNum ) + 1;
  366. // get shader
  367. surf->shader = ShaderForShaderNum( ds->shaderNum, LIGHTMAP_BY_VERTEX );
  368. if ( r_singleShader->integer && !surf->shader->isSky ) {
  369. surf->shader = tr.defaultShader;
  370. }
  371. numVerts = LittleLong( ds->numVerts );
  372. numIndexes = LittleLong( ds->numIndexes );
  373. tri = ri.Hunk_Alloc( sizeof( *tri ) + numVerts * sizeof( tri->verts[0] )
  374. + numIndexes * sizeof( tri->indexes[0] ), h_low );
  375. tri->surfaceType = SF_TRIANGLES;
  376. tri->numVerts = numVerts;
  377. tri->numIndexes = numIndexes;
  378. tri->verts = (drawVert_t *)(tri + 1);
  379. tri->indexes = (int *)(tri->verts + tri->numVerts );
  380. surf->data = (surfaceType_t *)tri;
  381. // copy vertexes
  382. ClearBounds( tri->bounds[0], tri->bounds[1] );
  383. verts += LittleLong( ds->firstVert );
  384. for ( i = 0 ; i < numVerts ; i++ ) {
  385. for ( j = 0 ; j < 3 ; j++ ) {
  386. tri->verts[i].xyz[j] = LittleFloat( verts[i].xyz[j] );
  387. tri->verts[i].normal[j] = LittleFloat( verts[i].normal[j] );
  388. }
  389. AddPointToBounds( tri->verts[i].xyz, tri->bounds[0], tri->bounds[1] );
  390. for ( j = 0 ; j < 2 ; j++ ) {
  391. tri->verts[i].st[j] = LittleFloat( verts[i].st[j] );
  392. tri->verts[i].lightmap[j] = LittleFloat( verts[i].lightmap[j] );
  393. }
  394. R_ColorShiftLightingBytes( verts[i].color, tri->verts[i].color );
  395. }
  396. // copy indexes
  397. indexes += LittleLong( ds->firstIndex );
  398. for ( i = 0 ; i < numIndexes ; i++ ) {
  399. tri->indexes[i] = LittleLong( indexes[i] );
  400. if ( tri->indexes[i] < 0 || tri->indexes[i] >= numVerts ) {
  401. ri.Error( ERR_DROP, "Bad index in triangle surface" );
  402. }
  403. }
  404. }
  405. /*
  406. ===============
  407. ParseFlare
  408. ===============
  409. */
  410. static void ParseFlare( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int *indexes ) {
  411. srfFlare_t *flare;
  412. int i;
  413. // get fog volume
  414. surf->fogIndex = LittleLong( ds->fogNum ) + 1;
  415. // get shader
  416. surf->shader = ShaderForShaderNum( ds->shaderNum, LIGHTMAP_BY_VERTEX );
  417. if ( r_singleShader->integer && !surf->shader->isSky ) {
  418. surf->shader = tr.defaultShader;
  419. }
  420. flare = ri.Hunk_Alloc( sizeof( *flare ), h_low );
  421. flare->surfaceType = SF_FLARE;
  422. surf->data = (surfaceType_t *)flare;
  423. for ( i = 0 ; i < 3 ; i++ ) {
  424. flare->origin[i] = LittleFloat( ds->lightmapOrigin[i] );
  425. flare->color[i] = LittleFloat( ds->lightmapVecs[0][i] );
  426. flare->normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
  427. }
  428. }
  429. /*
  430. =================
  431. R_MergedWidthPoints
  432. returns true if there are grid points merged on a width edge
  433. =================
  434. */
  435. int R_MergedWidthPoints(srfGridMesh_t *grid, int offset) {
  436. int i, j;
  437. for (i = 1; i < grid->width-1; i++) {
  438. for (j = i + 1; j < grid->width-1; j++) {
  439. if ( fabs(grid->verts[i + offset].xyz[0] - grid->verts[j + offset].xyz[0]) > .1) continue;
  440. if ( fabs(grid->verts[i + offset].xyz[1] - grid->verts[j + offset].xyz[1]) > .1) continue;
  441. if ( fabs(grid->verts[i + offset].xyz[2] - grid->verts[j + offset].xyz[2]) > .1) continue;
  442. return qtrue;
  443. }
  444. }
  445. return qfalse;
  446. }
  447. /*
  448. =================
  449. R_MergedHeightPoints
  450. returns true if there are grid points merged on a height edge
  451. =================
  452. */
  453. int R_MergedHeightPoints(srfGridMesh_t *grid, int offset) {
  454. int i, j;
  455. for (i = 1; i < grid->height-1; i++) {
  456. for (j = i + 1; j < grid->height-1; j++) {
  457. if ( fabs(grid->verts[grid->width * i + offset].xyz[0] - grid->verts[grid->width * j + offset].xyz[0]) > .1) continue;
  458. if ( fabs(grid->verts[grid->width * i + offset].xyz[1] - grid->verts[grid->width * j + offset].xyz[1]) > .1) continue;
  459. if ( fabs(grid->verts[grid->width * i + offset].xyz[2] - grid->verts[grid->width * j + offset].xyz[2]) > .1) continue;
  460. return qtrue;
  461. }
  462. }
  463. return qfalse;
  464. }
  465. /*
  466. =================
  467. R_FixSharedVertexLodError_r
  468. NOTE: never sync LoD through grid edges with merged points!
  469. FIXME: write generalized version that also avoids cracks between a patch and one that meets half way?
  470. =================
  471. */
  472. void R_FixSharedVertexLodError_r( int start, srfGridMesh_t *grid1 ) {
  473. int j, k, l, m, n, offset1, offset2, touch;
  474. srfGridMesh_t *grid2;
  475. for ( j = start; j < s_worldData.numsurfaces; j++ ) {
  476. //
  477. grid2 = (srfGridMesh_t *) s_worldData.surfaces[j].data;
  478. // if this surface is not a grid
  479. if ( grid2->surfaceType != SF_GRID ) continue;
  480. // if the LOD errors are already fixed for this patch
  481. if ( grid2->lodFixed == 2 ) continue;
  482. // grids in the same LOD group should have the exact same lod radius
  483. if ( grid1->lodRadius != grid2->lodRadius ) continue;
  484. // grids in the same LOD group should have the exact same lod origin
  485. if ( grid1->lodOrigin[0] != grid2->lodOrigin[0] ) continue;
  486. if ( grid1->lodOrigin[1] != grid2->lodOrigin[1] ) continue;
  487. if ( grid1->lodOrigin[2] != grid2->lodOrigin[2] ) continue;
  488. //
  489. touch = qfalse;
  490. for (n = 0; n < 2; n++) {
  491. //
  492. if (n) offset1 = (grid1->height-1) * grid1->width;
  493. else offset1 = 0;
  494. if (R_MergedWidthPoints(grid1, offset1)) continue;
  495. for (k = 1; k < grid1->width-1; k++) {
  496. for (m = 0; m < 2; m++) {
  497. if (m) offset2 = (grid2->height-1) * grid2->width;
  498. else offset2 = 0;
  499. if (R_MergedWidthPoints(grid2, offset2)) continue;
  500. for ( l = 1; l < grid2->width-1; l++) {
  501. //
  502. if ( fabs(grid1->verts[k + offset1].xyz[0] - grid2->verts[l + offset2].xyz[0]) > .1) continue;
  503. if ( fabs(grid1->verts[k + offset1].xyz[1] - grid2->verts[l + offset2].xyz[1]) > .1) continue;
  504. if ( fabs(grid1->verts[k + offset1].xyz[2] - grid2->verts[l + offset2].xyz[2]) > .1) continue;
  505. // ok the points are equal and should have the same lod error
  506. grid2->widthLodError[l] = grid1->widthLodError[k];
  507. touch = qtrue;
  508. }
  509. }
  510. for (m = 0; m < 2; m++) {
  511. if (m) offset2 = grid2->width-1;
  512. else offset2 = 0;
  513. if (R_MergedHeightPoints(grid2, offset2)) continue;
  514. for ( l = 1; l < grid2->height-1; l++) {
  515. //
  516. if ( fabs(grid1->verts[k + offset1].xyz[0] - grid2->verts[grid2->width * l + offset2].xyz[0]) > .1) continue;
  517. if ( fabs(grid1->verts[k + offset1].xyz[1] - grid2->verts[grid2->width * l + offset2].xyz[1]) > .1) continue;
  518. if ( fabs(grid1->verts[k + offset1].xyz[2] - grid2->verts[grid2->width * l + offset2].xyz[2]) > .1) continue;
  519. // ok the points are equal and should have the same lod error
  520. grid2->heightLodError[l] = grid1->widthLodError[k];
  521. touch = qtrue;
  522. }
  523. }
  524. }
  525. }
  526. for (n = 0; n < 2; n++) {
  527. //
  528. if (n) offset1 = grid1->width-1;
  529. else offset1 = 0;
  530. if (R_MergedHeightPoints(grid1, offset1)) continue;
  531. for (k = 1; k < grid1->height-1; k++) {
  532. for (m = 0; m < 2; m++) {
  533. if (m) offset2 = (grid2->height-1) * grid2->width;
  534. else offset2 = 0;
  535. if (R_MergedWidthPoints(grid2, offset2)) continue;
  536. for ( l = 1; l < grid2->width-1; l++) {
  537. //
  538. if ( fabs(grid1->verts[grid1->width * k + offset1].xyz[0] - grid2->verts[l + offset2].xyz[0]) > .1) continue;
  539. if ( fabs(grid1->verts[grid1->width * k + offset1].xyz[1] - grid2->verts[l + offset2].xyz[1]) > .1) continue;
  540. if ( fabs(grid1->verts[grid1->width * k + offset1].xyz[2] - grid2->verts[l + offset2].xyz[2]) > .1) continue;
  541. // ok the points are equal and should have the same lod error
  542. grid2->widthLodError[l] = grid1->heightLodError[k];
  543. touch = qtrue;
  544. }
  545. }
  546. for (m = 0; m < 2; m++) {
  547. if (m) offset2 = grid2->width-1;
  548. else offset2 = 0;
  549. if (R_MergedHeightPoints(grid2, offset2)) continue;
  550. for ( l = 1; l < grid2->height-1; l++) {
  551. //
  552. if ( fabs(grid1->verts[grid1->width * k + offset1].xyz[0] - grid2->verts[grid2->width * l + offset2].xyz[0]) > .1) continue;
  553. if ( fabs(grid1->verts[grid1->width * k + offset1].xyz[1] - grid2->verts[grid2->width * l + offset2].xyz[1]) > .1) continue;
  554. if ( fabs(grid1->verts[grid1->width * k + offset1].xyz[2] - grid2->verts[grid2->width * l + offset2].xyz[2]) > .1) continue;
  555. // ok the points are equal and should have the same lod error
  556. grid2->heightLodError[l] = grid1->heightLodError[k];
  557. touch = qtrue;
  558. }
  559. }
  560. }
  561. }
  562. if (touch) {
  563. grid2->lodFixed = 2;
  564. R_FixSharedVertexLodError_r ( start, grid2 );
  565. //NOTE: this would be correct but makes things really slow
  566. //grid2->lodFixed = 1;
  567. }
  568. }
  569. }
  570. /*
  571. =================
  572. R_FixSharedVertexLodError
  573. This function assumes that all patches in one group are nicely stitched together for the highest LoD.
  574. If this is not the case this function will still do its job but won't fix the highest LoD cracks.
  575. =================
  576. */
  577. void R_FixSharedVertexLodError( void ) {
  578. int i;
  579. srfGridMesh_t *grid1;
  580. for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
  581. //
  582. grid1 = (srfGridMesh_t *) s_worldData.surfaces[i].data;
  583. // if this surface is not a grid
  584. if ( grid1->surfaceType != SF_GRID )
  585. continue;
  586. //
  587. if ( grid1->lodFixed )
  588. continue;
  589. //
  590. grid1->lodFixed = 2;
  591. // recursively fix other patches in the same LOD group
  592. R_FixSharedVertexLodError_r( i + 1, grid1);
  593. }
  594. }
  595. /*
  596. ===============
  597. R_StitchPatches
  598. ===============
  599. */
  600. int R_StitchPatches( int grid1num, int grid2num ) {
  601. float *v1, *v2;
  602. srfGridMesh_t *grid1, *grid2;
  603. int k, l, m, n, offset1, offset2, row, column;
  604. grid1 = (srfGridMesh_t *) s_worldData.surfaces[grid1num].data;
  605. grid2 = (srfGridMesh_t *) s_worldData.surfaces[grid2num].data;
  606. for (n = 0; n < 2; n++) {
  607. //
  608. if (n) offset1 = (grid1->height-1) * grid1->width;
  609. else offset1 = 0;
  610. if (R_MergedWidthPoints(grid1, offset1))
  611. continue;
  612. for (k = 0; k < grid1->width-2; k += 2) {
  613. for (m = 0; m < 2; m++) {
  614. if ( grid2->width >= MAX_GRID_SIZE )
  615. break;
  616. if (m) offset2 = (grid2->height-1) * grid2->width;
  617. else offset2 = 0;
  618. for ( l = 0; l < grid2->width-1; l++) {
  619. //
  620. v1 = grid1->verts[k + offset1].xyz;
  621. v2 = grid2->verts[l + offset2].xyz;
  622. if ( fabs(v1[0] - v2[0]) > .1)
  623. continue;
  624. if ( fabs(v1[1] - v2[1]) > .1)
  625. continue;
  626. if ( fabs(v1[2] - v2[2]) > .1)
  627. continue;
  628. v1 = grid1->verts[k + 2 + offset1].xyz;
  629. v2 = grid2->verts[l + 1 + offset2].xyz;
  630. if ( fabs(v1[0] - v2[0]) > .1)
  631. continue;
  632. if ( fabs(v1[1] - v2[1]) > .1)
  633. continue;
  634. if ( fabs(v1[2] - v2[2]) > .1)
  635. continue;
  636. //
  637. v1 = grid2->verts[l + offset2].xyz;
  638. v2 = grid2->verts[l + 1 + offset2].xyz;
  639. if ( fabs(v1[0] - v2[0]) < .01 &&
  640. fabs(v1[1] - v2[1]) < .01 &&
  641. fabs(v1[2] - v2[2]) < .01)
  642. continue;
  643. //
  644. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  645. // insert column into grid2 right after after column l
  646. if (m) row = grid2->height-1;
  647. else row = 0;
  648. grid2 = R_GridInsertColumn( grid2, l+1, row,
  649. grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k+1]);
  650. grid2->lodStitched = qfalse;
  651. s_worldData.surfaces[grid2num].data = (void *) grid2;
  652. return qtrue;
  653. }
  654. }
  655. for (m = 0; m < 2; m++) {
  656. if (grid2->height >= MAX_GRID_SIZE)
  657. break;
  658. if (m) offset2 = grid2->width-1;
  659. else offset2 = 0;
  660. for ( l = 0; l < grid2->height-1; l++) {
  661. //
  662. v1 = grid1->verts[k + offset1].xyz;
  663. v2 = grid2->verts[grid2->width * l + offset2].xyz;
  664. if ( fabs(v1[0] - v2[0]) > .1)
  665. continue;
  666. if ( fabs(v1[1] - v2[1]) > .1)
  667. continue;
  668. if ( fabs(v1[2] - v2[2]) > .1)
  669. continue;
  670. v1 = grid1->verts[k + 2 + offset1].xyz;
  671. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  672. if ( fabs(v1[0] - v2[0]) > .1)
  673. continue;
  674. if ( fabs(v1[1] - v2[1]) > .1)
  675. continue;
  676. if ( fabs(v1[2] - v2[2]) > .1)
  677. continue;
  678. //
  679. v1 = grid2->verts[grid2->width * l + offset2].xyz;
  680. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  681. if ( fabs(v1[0] - v2[0]) < .01 &&
  682. fabs(v1[1] - v2[1]) < .01 &&
  683. fabs(v1[2] - v2[2]) < .01)
  684. continue;
  685. //
  686. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  687. // insert row into grid2 right after after row l
  688. if (m) column = grid2->width-1;
  689. else column = 0;
  690. grid2 = R_GridInsertRow( grid2, l+1, column,
  691. grid1->verts[k + 1 + offset1].xyz, grid1->widthLodError[k+1]);
  692. grid2->lodStitched = qfalse;
  693. s_worldData.surfaces[grid2num].data = (void *) grid2;
  694. return qtrue;
  695. }
  696. }
  697. }
  698. }
  699. for (n = 0; n < 2; n++) {
  700. //
  701. if (n) offset1 = grid1->width-1;
  702. else offset1 = 0;
  703. if (R_MergedHeightPoints(grid1, offset1))
  704. continue;
  705. for (k = 0; k < grid1->height-2; k += 2) {
  706. for (m = 0; m < 2; m++) {
  707. if ( grid2->width >= MAX_GRID_SIZE )
  708. break;
  709. if (m) offset2 = (grid2->height-1) * grid2->width;
  710. else offset2 = 0;
  711. for ( l = 0; l < grid2->width-1; l++) {
  712. //
  713. v1 = grid1->verts[grid1->width * k + offset1].xyz;
  714. v2 = grid2->verts[l + offset2].xyz;
  715. if ( fabs(v1[0] - v2[0]) > .1)
  716. continue;
  717. if ( fabs(v1[1] - v2[1]) > .1)
  718. continue;
  719. if ( fabs(v1[2] - v2[2]) > .1)
  720. continue;
  721. v1 = grid1->verts[grid1->width * (k + 2) + offset1].xyz;
  722. v2 = grid2->verts[l + 1 + offset2].xyz;
  723. if ( fabs(v1[0] - v2[0]) > .1)
  724. continue;
  725. if ( fabs(v1[1] - v2[1]) > .1)
  726. continue;
  727. if ( fabs(v1[2] - v2[2]) > .1)
  728. continue;
  729. //
  730. v1 = grid2->verts[l + offset2].xyz;
  731. v2 = grid2->verts[(l + 1) + offset2].xyz;
  732. if ( fabs(v1[0] - v2[0]) < .01 &&
  733. fabs(v1[1] - v2[1]) < .01 &&
  734. fabs(v1[2] - v2[2]) < .01)
  735. continue;
  736. //
  737. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  738. // insert column into grid2 right after after column l
  739. if (m) row = grid2->height-1;
  740. else row = 0;
  741. grid2 = R_GridInsertColumn( grid2, l+1, row,
  742. grid1->verts[grid1->width * (k + 1) + offset1].xyz, grid1->heightLodError[k+1]);
  743. grid2->lodStitched = qfalse;
  744. s_worldData.surfaces[grid2num].data = (void *) grid2;
  745. return qtrue;
  746. }
  747. }
  748. for (m = 0; m < 2; m++) {
  749. if (grid2->height >= MAX_GRID_SIZE)
  750. break;
  751. if (m) offset2 = grid2->width-1;
  752. else offset2 = 0;
  753. for ( l = 0; l < grid2->height-1; l++) {
  754. //
  755. v1 = grid1->verts[grid1->width * k + offset1].xyz;
  756. v2 = grid2->verts[grid2->width * l + offset2].xyz;
  757. if ( fabs(v1[0] - v2[0]) > .1)
  758. continue;
  759. if ( fabs(v1[1] - v2[1]) > .1)
  760. continue;
  761. if ( fabs(v1[2] - v2[2]) > .1)
  762. continue;
  763. v1 = grid1->verts[grid1->width * (k + 2) + offset1].xyz;
  764. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  765. if ( fabs(v1[0] - v2[0]) > .1)
  766. continue;
  767. if ( fabs(v1[1] - v2[1]) > .1)
  768. continue;
  769. if ( fabs(v1[2] - v2[2]) > .1)
  770. continue;
  771. //
  772. v1 = grid2->verts[grid2->width * l + offset2].xyz;
  773. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  774. if ( fabs(v1[0] - v2[0]) < .01 &&
  775. fabs(v1[1] - v2[1]) < .01 &&
  776. fabs(v1[2] - v2[2]) < .01)
  777. continue;
  778. //
  779. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  780. // insert row into grid2 right after after row l
  781. if (m) column = grid2->width-1;
  782. else column = 0;
  783. grid2 = R_GridInsertRow( grid2, l+1, column,
  784. grid1->verts[grid1->width * (k + 1) + offset1].xyz, grid1->heightLodError[k+1]);
  785. grid2->lodStitched = qfalse;
  786. s_worldData.surfaces[grid2num].data = (void *) grid2;
  787. return qtrue;
  788. }
  789. }
  790. }
  791. }
  792. for (n = 0; n < 2; n++) {
  793. //
  794. if (n) offset1 = (grid1->height-1) * grid1->width;
  795. else offset1 = 0;
  796. if (R_MergedWidthPoints(grid1, offset1))
  797. continue;
  798. for (k = grid1->width-1; k > 1; k -= 2) {
  799. for (m = 0; m < 2; m++) {
  800. if ( grid2->width >= MAX_GRID_SIZE )
  801. break;
  802. if (m) offset2 = (grid2->height-1) * grid2->width;
  803. else offset2 = 0;
  804. for ( l = 0; l < grid2->width-1; l++) {
  805. //
  806. v1 = grid1->verts[k + offset1].xyz;
  807. v2 = grid2->verts[l + offset2].xyz;
  808. if ( fabs(v1[0] - v2[0]) > .1)
  809. continue;
  810. if ( fabs(v1[1] - v2[1]) > .1)
  811. continue;
  812. if ( fabs(v1[2] - v2[2]) > .1)
  813. continue;
  814. v1 = grid1->verts[k - 2 + offset1].xyz;
  815. v2 = grid2->verts[l + 1 + offset2].xyz;
  816. if ( fabs(v1[0] - v2[0]) > .1)
  817. continue;
  818. if ( fabs(v1[1] - v2[1]) > .1)
  819. continue;
  820. if ( fabs(v1[2] - v2[2]) > .1)
  821. continue;
  822. //
  823. v1 = grid2->verts[l + offset2].xyz;
  824. v2 = grid2->verts[(l + 1) + offset2].xyz;
  825. if ( fabs(v1[0] - v2[0]) < .01 &&
  826. fabs(v1[1] - v2[1]) < .01 &&
  827. fabs(v1[2] - v2[2]) < .01)
  828. continue;
  829. //
  830. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  831. // insert column into grid2 right after after column l
  832. if (m) row = grid2->height-1;
  833. else row = 0;
  834. grid2 = R_GridInsertColumn( grid2, l+1, row,
  835. grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k+1]);
  836. grid2->lodStitched = qfalse;
  837. s_worldData.surfaces[grid2num].data = (void *) grid2;
  838. return qtrue;
  839. }
  840. }
  841. for (m = 0; m < 2; m++) {
  842. if (grid2->height >= MAX_GRID_SIZE)
  843. break;
  844. if (m) offset2 = grid2->width-1;
  845. else offset2 = 0;
  846. for ( l = 0; l < grid2->height-1; l++) {
  847. //
  848. v1 = grid1->verts[k + offset1].xyz;
  849. v2 = grid2->verts[grid2->width * l + offset2].xyz;
  850. if ( fabs(v1[0] - v2[0]) > .1)
  851. continue;
  852. if ( fabs(v1[1] - v2[1]) > .1)
  853. continue;
  854. if ( fabs(v1[2] - v2[2]) > .1)
  855. continue;
  856. v1 = grid1->verts[k - 2 + offset1].xyz;
  857. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  858. if ( fabs(v1[0] - v2[0]) > .1)
  859. continue;
  860. if ( fabs(v1[1] - v2[1]) > .1)
  861. continue;
  862. if ( fabs(v1[2] - v2[2]) > .1)
  863. continue;
  864. //
  865. v1 = grid2->verts[grid2->width * l + offset2].xyz;
  866. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  867. if ( fabs(v1[0] - v2[0]) < .01 &&
  868. fabs(v1[1] - v2[1]) < .01 &&
  869. fabs(v1[2] - v2[2]) < .01)
  870. continue;
  871. //
  872. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  873. // insert row into grid2 right after after row l
  874. if (m) column = grid2->width-1;
  875. else column = 0;
  876. grid2 = R_GridInsertRow( grid2, l+1, column,
  877. grid1->verts[k - 1 + offset1].xyz, grid1->widthLodError[k+1]);
  878. if (!grid2)
  879. break;
  880. grid2->lodStitched = qfalse;
  881. s_worldData.surfaces[grid2num].data = (void *) grid2;
  882. return qtrue;
  883. }
  884. }
  885. }
  886. }
  887. for (n = 0; n < 2; n++) {
  888. //
  889. if (n) offset1 = grid1->width-1;
  890. else offset1 = 0;
  891. if (R_MergedHeightPoints(grid1, offset1))
  892. continue;
  893. for (k = grid1->height-1; k > 1; k -= 2) {
  894. for (m = 0; m < 2; m++) {
  895. if ( grid2->width >= MAX_GRID_SIZE )
  896. break;
  897. if (m) offset2 = (grid2->height-1) * grid2->width;
  898. else offset2 = 0;
  899. for ( l = 0; l < grid2->width-1; l++) {
  900. //
  901. v1 = grid1->verts[grid1->width * k + offset1].xyz;
  902. v2 = grid2->verts[l + offset2].xyz;
  903. if ( fabs(v1[0] - v2[0]) > .1)
  904. continue;
  905. if ( fabs(v1[1] - v2[1]) > .1)
  906. continue;
  907. if ( fabs(v1[2] - v2[2]) > .1)
  908. continue;
  909. v1 = grid1->verts[grid1->width * (k - 2) + offset1].xyz;
  910. v2 = grid2->verts[l + 1 + offset2].xyz;
  911. if ( fabs(v1[0] - v2[0]) > .1)
  912. continue;
  913. if ( fabs(v1[1] - v2[1]) > .1)
  914. continue;
  915. if ( fabs(v1[2] - v2[2]) > .1)
  916. continue;
  917. //
  918. v1 = grid2->verts[l + offset2].xyz;
  919. v2 = grid2->verts[(l + 1) + offset2].xyz;
  920. if ( fabs(v1[0] - v2[0]) < .01 &&
  921. fabs(v1[1] - v2[1]) < .01 &&
  922. fabs(v1[2] - v2[2]) < .01)
  923. continue;
  924. //
  925. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  926. // insert column into grid2 right after after column l
  927. if (m) row = grid2->height-1;
  928. else row = 0;
  929. grid2 = R_GridInsertColumn( grid2, l+1, row,
  930. grid1->verts[grid1->width * (k - 1) + offset1].xyz, grid1->heightLodError[k+1]);
  931. grid2->lodStitched = qfalse;
  932. s_worldData.surfaces[grid2num].data = (void *) grid2;
  933. return qtrue;
  934. }
  935. }
  936. for (m = 0; m < 2; m++) {
  937. if (grid2->height >= MAX_GRID_SIZE)
  938. break;
  939. if (m) offset2 = grid2->width-1;
  940. else offset2 = 0;
  941. for ( l = 0; l < grid2->height-1; l++) {
  942. //
  943. v1 = grid1->verts[grid1->width * k + offset1].xyz;
  944. v2 = grid2->verts[grid2->width * l + offset2].xyz;
  945. if ( fabs(v1[0] - v2[0]) > .1)
  946. continue;
  947. if ( fabs(v1[1] - v2[1]) > .1)
  948. continue;
  949. if ( fabs(v1[2] - v2[2]) > .1)
  950. continue;
  951. v1 = grid1->verts[grid1->width * (k - 2) + offset1].xyz;
  952. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  953. if ( fabs(v1[0] - v2[0]) > .1)
  954. continue;
  955. if ( fabs(v1[1] - v2[1]) > .1)
  956. continue;
  957. if ( fabs(v1[2] - v2[2]) > .1)
  958. continue;
  959. //
  960. v1 = grid2->verts[grid2->width * l + offset2].xyz;
  961. v2 = grid2->verts[grid2->width * (l + 1) + offset2].xyz;
  962. if ( fabs(v1[0] - v2[0]) < .01 &&
  963. fabs(v1[1] - v2[1]) < .01 &&
  964. fabs(v1[2] - v2[2]) < .01)
  965. continue;
  966. //
  967. //ri.Printf( PRINT_ALL, "found highest LoD crack between two patches\n" );
  968. // insert row into grid2 right after after row l
  969. if (m) column = grid2->width-1;
  970. else column = 0;
  971. grid2 = R_GridInsertRow( grid2, l+1, column,
  972. grid1->verts[grid1->width * (k - 1) + offset1].xyz, grid1->heightLodError[k+1]);
  973. grid2->lodStitched = qfalse;
  974. s_worldData.surfaces[grid2num].data = (void *) grid2;
  975. return qtrue;
  976. }
  977. }
  978. }
  979. }
  980. return qfalse;
  981. }
  982. /*
  983. ===============
  984. R_TryStitchPatch
  985. This function will try to stitch patches in the same LoD group together for the highest LoD.
  986. Only single missing vertice cracks will be fixed.
  987. Vertices will be joined at the patch side a crack is first found, at the other side
  988. of the patch (on the same row or column) the vertices will not be joined and cracks
  989. might still appear at that side.
  990. ===============
  991. */
  992. int R_TryStitchingPatch( int grid1num ) {
  993. int j, numstitches;
  994. srfGridMesh_t *grid1, *grid2;
  995. numstitches = 0;
  996. grid1 = (srfGridMesh_t *) s_worldData.surfaces[grid1num].data;
  997. for ( j = 0; j < s_worldData.numsurfaces; j++ ) {
  998. //
  999. grid2 = (srfGridMesh_t *) s_worldData.surfaces[j].data;
  1000. // if this surface is not a grid
  1001. if ( grid2->surfaceType != SF_GRID ) continue;
  1002. // grids in the same LOD group should have the exact same lod radius
  1003. if ( grid1->lodRadius != grid2->lodRadius ) continue;
  1004. // grids in the same LOD group should have the exact same lod origin
  1005. if ( grid1->lodOrigin[0] != grid2->lodOrigin[0] ) continue;
  1006. if ( grid1->lodOrigin[1] != grid2->lodOrigin[1] ) continue;
  1007. if ( grid1->lodOrigin[2] != grid2->lodOrigin[2] ) continue;
  1008. //
  1009. while (R_StitchPatches(grid1num, j))
  1010. {
  1011. numstitches++;
  1012. }
  1013. }
  1014. return numstitches;
  1015. }
  1016. /*
  1017. ===============
  1018. R_StitchAllPatches
  1019. ===============
  1020. */
  1021. void R_StitchAllPatches( void ) {
  1022. int i, stitched, numstitches;
  1023. srfGridMesh_t *grid1;
  1024. numstitches = 0;
  1025. do
  1026. {
  1027. stitched = qfalse;
  1028. for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
  1029. //
  1030. grid1 = (srfGridMesh_t *) s_worldData.surfaces[i].data;
  1031. // if this surface is not a grid
  1032. if ( grid1->surfaceType != SF_GRID )
  1033. continue;
  1034. //
  1035. if ( grid1->lodStitched )
  1036. continue;
  1037. //
  1038. grid1->lodStitched = qtrue;
  1039. stitched = qtrue;
  1040. //
  1041. numstitches += R_TryStitchingPatch( i );
  1042. }
  1043. }
  1044. while (stitched);
  1045. ri.Printf( PRINT_ALL, "stitched %d LoD cracks\n", numstitches );
  1046. }
  1047. /*
  1048. ===============
  1049. R_MovePatchSurfacesToHunk
  1050. ===============
  1051. */
  1052. void R_MovePatchSurfacesToHunk(void) {
  1053. int i, size;
  1054. srfGridMesh_t *grid, *hunkgrid;
  1055. for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
  1056. //
  1057. grid = (srfGridMesh_t *) s_worldData.surfaces[i].data;
  1058. // if this surface is not a grid
  1059. if ( grid->surfaceType != SF_GRID )
  1060. continue;
  1061. //
  1062. size = (grid->width * grid->height - 1) * sizeof( drawVert_t ) + sizeof( *grid );
  1063. hunkgrid = ri.Hunk_Alloc( size, h_low );
  1064. Com_Memcpy(hunkgrid, grid, size);
  1065. hunkgrid->widthLodError = ri.Hunk_Alloc( grid->width * 4, h_low );
  1066. Com_Memcpy( hunkgrid->widthLodError, grid->widthLodError, grid->width * 4 );
  1067. hunkgrid->heightLodError = ri.Hunk_Alloc( grid->height * 4, h_low );
  1068. Com_Memcpy( grid->heightLodError, grid->heightLodError, grid->height * 4 );
  1069. R_FreeSurfaceGridMesh( grid );
  1070. s_worldData.surfaces[i].data = (void *) hunkgrid;
  1071. }
  1072. }
  1073. /*
  1074. ===============
  1075. R_LoadSurfaces
  1076. ===============
  1077. */
  1078. static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) {
  1079. dsurface_t *in;
  1080. msurface_t *out;
  1081. drawVert_t *dv;
  1082. int *indexes;
  1083. int count;
  1084. int numFaces, numMeshes, numTriSurfs, numFlares;
  1085. int i;
  1086. numFaces = 0;
  1087. numMeshes = 0;
  1088. numTriSurfs = 0;
  1089. numFlares = 0;
  1090. in = (void *)(fileBase + surfs->fileofs);
  1091. if (surfs->filelen % sizeof(*in))
  1092. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1093. count = surfs->filelen / sizeof(*in);
  1094. dv = (void *)(fileBase + verts->fileofs);
  1095. if (verts->filelen % sizeof(*dv))
  1096. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1097. indexes = (void *)(fileBase + indexLump->fileofs);
  1098. if ( indexLump->filelen % sizeof(*indexes))
  1099. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1100. out = ri.Hunk_Alloc ( count * sizeof(*out), h_low );
  1101. s_worldData.surfaces = out;
  1102. s_worldData.numsurfaces = count;
  1103. for ( i = 0 ; i < count ; i++, in++, out++ ) {
  1104. switch ( LittleLong( in->surfaceType ) ) {
  1105. case MST_PATCH:
  1106. ParseMesh ( in, dv, out );
  1107. numMeshes++;
  1108. break;
  1109. case MST_TRIANGLE_SOUP:
  1110. ParseTriSurf( in, dv, out, indexes );
  1111. numTriSurfs++;
  1112. break;
  1113. case MST_PLANAR:
  1114. ParseFace( in, dv, out, indexes );
  1115. numFaces++;
  1116. break;
  1117. case MST_FLARE:
  1118. ParseFlare( in, dv, out, indexes );
  1119. numFlares++;
  1120. break;
  1121. default:
  1122. ri.Error( ERR_DROP, "Bad surfaceType" );
  1123. }
  1124. }
  1125. #ifdef PATCH_STITCHING
  1126. R_StitchAllPatches();
  1127. #endif
  1128. R_FixSharedVertexLodError();
  1129. #ifdef PATCH_STITCHING
  1130. R_MovePatchSurfacesToHunk();
  1131. #endif
  1132. ri.Printf( PRINT_ALL, "...loaded %d faces, %i meshes, %i trisurfs, %i flares\n",
  1133. numFaces, numMeshes, numTriSurfs, numFlares );
  1134. }
  1135. /*
  1136. =================
  1137. R_LoadSubmodels
  1138. =================
  1139. */
  1140. static void R_LoadSubmodels( lump_t *l ) {
  1141. dmodel_t *in;
  1142. bmodel_t *out;
  1143. int i, j, count;
  1144. in = (void *)(fileBase + l->fileofs);
  1145. if (l->filelen % sizeof(*in))
  1146. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1147. count = l->filelen / sizeof(*in);
  1148. s_worldData.bmodels = out = ri.Hunk_Alloc( count * sizeof(*out), h_low );
  1149. for ( i=0 ; i<count ; i++, in++, out++ ) {
  1150. model_t *model;
  1151. model = R_AllocModel();
  1152. assert( model != NULL ); // this should never happen
  1153. model->type = MOD_BRUSH;
  1154. model->bmodel = out;
  1155. Com_sprintf( model->name, sizeof( model->name ), "*%d", i );
  1156. for (j=0 ; j<3 ; j++) {
  1157. out->bounds[0][j] = LittleFloat (in->mins[j]);
  1158. out->bounds[1][j] = LittleFloat (in->maxs[j]);
  1159. }
  1160. out->firstSurface = s_worldData.surfaces + LittleLong( in->firstSurface );
  1161. out->numSurfaces = LittleLong( in->numSurfaces );
  1162. }
  1163. }
  1164. //==================================================================
  1165. /*
  1166. =================
  1167. R_SetParent
  1168. =================
  1169. */
  1170. static void R_SetParent (mnode_t *node, mnode_t *parent)
  1171. {
  1172. node->parent = parent;
  1173. if (node->contents != -1)
  1174. return;
  1175. R_SetParent (node->children[0], node);
  1176. R_SetParent (node->children[1], node);
  1177. }
  1178. /*
  1179. =================
  1180. R_LoadNodesAndLeafs
  1181. =================
  1182. */
  1183. static void R_LoadNodesAndLeafs (lump_t *nodeLump, lump_t *leafLump) {
  1184. int i, j, p;
  1185. dnode_t *in;
  1186. dleaf_t *inLeaf;
  1187. mnode_t *out;
  1188. int numNodes, numLeafs;
  1189. in = (void *)(fileBase + nodeLump->fileofs);
  1190. if (nodeLump->filelen % sizeof(dnode_t) ||
  1191. leafLump->filelen % sizeof(dleaf_t) ) {
  1192. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1193. }
  1194. numNodes = nodeLump->filelen / sizeof(dnode_t);
  1195. numLeafs = leafLump->filelen / sizeof(dleaf_t);
  1196. out = ri.Hunk_Alloc ( (numNodes + numLeafs) * sizeof(*out), h_low);
  1197. s_worldData.nodes = out;
  1198. s_worldData.numnodes = numNodes + numLeafs;
  1199. s_worldData.numDecisionNodes = numNodes;
  1200. // load nodes
  1201. for ( i=0 ; i<numNodes; i++, in++, out++)
  1202. {
  1203. for (j=0 ; j<3 ; j++)
  1204. {
  1205. out->mins[j] = LittleLong (in->mins[j]);
  1206. out->maxs[j] = LittleLong (in->maxs[j]);
  1207. }
  1208. p = LittleLong(in->planeNum);
  1209. out->plane = s_worldData.planes + p;
  1210. out->contents = CONTENTS_NODE; // differentiate from leafs
  1211. for (j=0 ; j<2 ; j++)
  1212. {
  1213. p = LittleLong (in->children[j]);
  1214. if (p >= 0)
  1215. out->children[j] = s_worldData.nodes + p;
  1216. else
  1217. out->children[j] = s_worldData.nodes + numNodes + (-1 - p);
  1218. }
  1219. }
  1220. // load leafs
  1221. inLeaf = (void *)(fileBase + leafLump->fileofs);
  1222. for ( i=0 ; i<numLeafs ; i++, inLeaf++, out++)
  1223. {
  1224. for (j=0 ; j<3 ; j++)
  1225. {
  1226. out->mins[j] = LittleLong (inLeaf->mins[j]);
  1227. out->maxs[j] = LittleLong (inLeaf->maxs[j]);
  1228. }
  1229. out->cluster = LittleLong(inLeaf->cluster);
  1230. out->area = LittleLong(inLeaf->area);
  1231. if ( out->cluster >= s_worldData.numClusters ) {
  1232. s_worldData.numClusters = out->cluster + 1;
  1233. }
  1234. out->firstmarksurface = s_worldData.marksurfaces +
  1235. LittleLong(inLeaf->firstLeafSurface);
  1236. out->nummarksurfaces = LittleLong(inLeaf->numLeafSurfaces);
  1237. }
  1238. // chain decendants
  1239. R_SetParent (s_worldData.nodes, NULL);
  1240. }
  1241. //=============================================================================
  1242. /*
  1243. =================
  1244. R_LoadShaders
  1245. =================
  1246. */
  1247. static void R_LoadShaders( lump_t *l ) {
  1248. int i, count;
  1249. dshader_t *in, *out;
  1250. in = (void *)(fileBase + l->fileofs);
  1251. if (l->filelen % sizeof(*in))
  1252. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1253. count = l->filelen / sizeof(*in);
  1254. out = ri.Hunk_Alloc ( count*sizeof(*out), h_low );
  1255. s_worldData.shaders = out;
  1256. s_worldData.numShaders = count;
  1257. Com_Memcpy( out, in, count*sizeof(*out) );
  1258. for ( i=0 ; i<count ; i++ ) {
  1259. out[i].surfaceFlags = LittleLong( out[i].surfaceFlags );
  1260. out[i].contentFlags = LittleLong( out[i].contentFlags );
  1261. }
  1262. }
  1263. /*
  1264. =================
  1265. R_LoadMarksurfaces
  1266. =================
  1267. */
  1268. static void R_LoadMarksurfaces (lump_t *l)
  1269. {
  1270. int i, j, count;
  1271. int *in;
  1272. msurface_t **out;
  1273. in = (void *)(fileBase + l->fileofs);
  1274. if (l->filelen % sizeof(*in))
  1275. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1276. count = l->filelen / sizeof(*in);
  1277. out = ri.Hunk_Alloc ( count*sizeof(*out), h_low);
  1278. s_worldData.marksurfaces = out;
  1279. s_worldData.nummarksurfaces = count;
  1280. for ( i=0 ; i<count ; i++)
  1281. {
  1282. j = LittleLong(in[i]);
  1283. out[i] = s_worldData.surfaces + j;
  1284. }
  1285. }
  1286. /*
  1287. =================
  1288. R_LoadPlanes
  1289. =================
  1290. */
  1291. static void R_LoadPlanes( lump_t *l ) {
  1292. int i, j;
  1293. cplane_t *out;
  1294. dplane_t *in;
  1295. int count;
  1296. int bits;
  1297. in = (void *)(fileBase + l->fileofs);
  1298. if (l->filelen % sizeof(*in))
  1299. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1300. count = l->filelen / sizeof(*in);
  1301. out = ri.Hunk_Alloc ( count*2*sizeof(*out), h_low);
  1302. s_worldData.planes = out;
  1303. s_worldData.numplanes = count;
  1304. for ( i=0 ; i<count ; i++, in++, out++) {
  1305. bits = 0;
  1306. for (j=0 ; j<3 ; j++) {
  1307. out->normal[j] = LittleFloat (in->normal[j]);
  1308. if (out->normal[j] < 0) {
  1309. bits |= 1<<j;
  1310. }
  1311. }
  1312. out->dist = LittleFloat (in->dist);
  1313. out->type = PlaneTypeForNormal( out->normal );
  1314. out->signbits = bits;
  1315. }
  1316. }
  1317. /*
  1318. =================
  1319. R_LoadFogs
  1320. =================
  1321. */
  1322. static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump ) {
  1323. int i;
  1324. fog_t *out;
  1325. dfog_t *fogs;
  1326. dbrush_t *brushes, *brush;
  1327. dbrushside_t *sides;
  1328. int count, brushesCount, sidesCount;
  1329. int sideNum;
  1330. int planeNum;
  1331. shader_t *shader;
  1332. float d;
  1333. int firstSide;
  1334. fogs = (void *)(fileBase + l->fileofs);
  1335. if (l->filelen % sizeof(*fogs)) {
  1336. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1337. }
  1338. count = l->filelen / sizeof(*fogs);
  1339. // create fog strucutres for them
  1340. s_worldData.numfogs = count + 1;
  1341. s_worldData.fogs = ri.Hunk_Alloc ( s_worldData.numfogs*sizeof(*out), h_low);
  1342. out = s_worldData.fogs + 1;
  1343. if ( !count ) {
  1344. return;
  1345. }
  1346. brushes = (void *)(fileBase + brushesLump->fileofs);
  1347. if (brushesLump->filelen % sizeof(*brushes)) {
  1348. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1349. }
  1350. brushesCount = brushesLump->filelen / sizeof(*brushes);
  1351. sides = (void *)(fileBase + sidesLump->fileofs);
  1352. if (sidesLump->filelen % sizeof(*sides)) {
  1353. ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
  1354. }
  1355. sidesCount = sidesLump->filelen / sizeof(*sides);
  1356. for ( i=0 ; i<count ; i++, fogs++) {
  1357. out->originalBrushNumber = LittleLong( fogs->brushNum );
  1358. if ( (unsigned)out->originalBrushNumber >= brushesCount ) {
  1359. ri.Error( ERR_DROP, "fog brushNumber out of range" );
  1360. }
  1361. brush = brushes + out->originalBrushNumber;
  1362. firstSide = LittleLong( brush->firstSide );
  1363. if ( (unsigned)firstSide > sidesCount - 6 ) {
  1364. ri.Error( ERR_DROP, "fog brush sideNumber out of range" );
  1365. }
  1366. // brushes are always sorted with the axial sides first
  1367. sideNum = firstSide + 0;
  1368. planeNum = LittleLong( sides[ sideNum ].planeNum );
  1369. out->bounds[0][0] = -s_worldData.planes[ planeNum ].dist;
  1370. sideNum = firstSide + 1;
  1371. planeNum = LittleLong( sides[ sideNum ].planeNum );
  1372. out->bounds[1][0] = s_worldData.planes[ planeNum ].dist;
  1373. sideNum = firstSide + 2;
  1374. planeNum = LittleLong( sides[ sideNum ].planeNum );
  1375. out->bounds[0][1] = -s_worldData.planes[ planeNum ].dist;
  1376. sideNum = firstSide + 3;
  1377. planeNum = LittleLong( sides[ sideNum ].planeNum );
  1378. out->bounds[1][1] = s_worldData.planes[ planeNum ].dist;
  1379. sideNum = firstSide + 4;
  1380. planeNum = LittleLong( sides[ sideNum ].planeNum );
  1381. out->bounds[0][2] = -s_worldData.planes[ planeNum ].dist;
  1382. sideNum = firstSide + 5;
  1383. planeNum = LittleLong( sides[ sideNum ].planeNum );
  1384. out->bounds[1][2] = s_worldData.planes[ planeNum ].dist;
  1385. // get information from the shader for fog parameters
  1386. shader = R_FindShader( fogs->shader, LIGHTMAP_NONE, qtrue );
  1387. out->parms = shader->fogParms;
  1388. out->colorInt = ColorBytes4 ( shader->fogParms.color[0] * tr.identityLight,
  1389. shader->fogParms.color[1] * tr.identityLight,
  1390. shader->fogParms.color[2] * tr.identityLight, 1.0 );
  1391. d = shader->fogParms.depthForOpaque < 1 ? 1 : shader->fogParms.depthForOpaque;
  1392. out->tcScale = 1.0f / ( d * 8 );
  1393. // set the gradient vector
  1394. sideNum = LittleLong( fogs->visibleSide );
  1395. if ( sideNum == -1 ) {
  1396. out->hasSurface = qfalse;
  1397. } else {
  1398. out->hasSurface = qtrue;
  1399. planeNum = LittleLong( sides[ firstSide + sideNum ].planeNum );
  1400. VectorSubtract( vec3_origin, s_worldData.planes[ planeNum ].normal, out->surface );
  1401. out->surface[3] = -s_worldData.planes[ planeNum ].dist;
  1402. }
  1403. out++;
  1404. }
  1405. }
  1406. /*
  1407. ================
  1408. R_LoadLightGrid
  1409. ================
  1410. */
  1411. void R_LoadLightGrid( lump_t *l ) {
  1412. int i;
  1413. vec3_t maxs;
  1414. int numGridPoints;
  1415. world_t *w;
  1416. float *wMins, *wMaxs;
  1417. w = &s_worldData;
  1418. w->lightGridInverseSize[0] = 1.0f / w->lightGridSize[0];
  1419. w->lightGridInverseSize[1] = 1.0f / w->lightGridSize[1];
  1420. w->lightGridInverseSize[2] = 1.0f / w->lightGridSize[2];
  1421. wMins = w->bmodels[0].bounds[0];
  1422. wMaxs = w->bmodels[0].bounds[1];
  1423. for ( i = 0 ; i < 3 ; i++ ) {
  1424. w->lightGridOrigin[i] = w->lightGridSize[i] * ceil( wMins[i] / w->lightGridSize[i] );
  1425. maxs[i] = w->lightGridSize[i] * floor( wMaxs[i] / w->lightGridSize[i] );
  1426. w->lightGridBounds[i] = (maxs[i] - w->lightGridOrigin[i])/w->lightGridSize[i] + 1;
  1427. }
  1428. numGridPoints = w->lightGridBounds[0] * w->lightGridBounds[1] * w->lightGridBounds[2];
  1429. if ( l->filelen != numGridPoints * 8 ) {
  1430. ri.Printf( PRINT_WARNING, "WARNING: light grid mismatch\n" );
  1431. w->lightGridData = NULL;
  1432. return;
  1433. }
  1434. w->lightGridData = ri.Hunk_Alloc( l->filelen, h_low );
  1435. Com_Memcpy( w->lightGridData, (void *)(fileBase + l->fileofs), l->filelen );
  1436. // deal with overbright bits
  1437. for ( i = 0 ; i < numGridPoints ; i++ ) {
  1438. R_ColorShiftLightingBytes( &w->lightGridData[i*8], &w->lightGridData[i*8] );
  1439. R_ColorShiftLightingBytes( &w->lightGridData[i*8+3], &w->lightGridData[i*8+3] );
  1440. }
  1441. }
  1442. /*
  1443. ================
  1444. R_LoadEntities
  1445. ================
  1446. */
  1447. void R_LoadEntities( lump_t *l ) {
  1448. char *p, *token, *s;
  1449. char keyname[MAX_TOKEN_CHARS];
  1450. char value[MAX_TOKEN_CHARS];
  1451. world_t *w;
  1452. w = &s_worldData;
  1453. w->lightGridSize[0] = 64;
  1454. w->lightGridSize[1] = 64;
  1455. w->lightGridSize[2] = 128;
  1456. p = (char *)(fileBase + l->fileofs);
  1457. // store for reference by the cgame
  1458. w->entityString = ri.Hunk_Alloc( l->filelen + 1, h_low );
  1459. strcpy( w->entityString, p );
  1460. w->entityParsePoint = w->entityString;
  1461. token = COM_ParseExt( &p, qtrue );
  1462. if (!*token || *token != '{') {
  1463. return;
  1464. }
  1465. // only parse the world spawn
  1466. while ( 1 ) {
  1467. // parse key
  1468. token = COM_ParseExt( &p, qtrue );
  1469. if ( !*token || *token == '}' ) {
  1470. break;
  1471. }
  1472. Q_strncpyz(keyname, token, sizeof(keyname));
  1473. // parse value
  1474. token = COM_ParseExt( &p, qtrue );
  1475. if ( !*token || *token == '}' ) {
  1476. break;
  1477. }
  1478. Q_strncpyz(value, token, sizeof(value));
  1479. // check for remapping of shaders for vertex lighting
  1480. s = "vertexremapshader";
  1481. if (!Q_strncmp(keyname, s, strlen(s)) ) {
  1482. s = strchr(value, ';');
  1483. if (!s) {
  1484. ri.Printf( PRINT_WARNING, "WARNING: no semi colon in vertexshaderremap '%s'\n", value );
  1485. break;
  1486. }
  1487. *s++ = 0;
  1488. if (r_vertexLight->integer) {
  1489. R_RemapShader(value, s, "0");
  1490. }
  1491. continue;
  1492. }
  1493. // check for remapping of shaders
  1494. s = "remapshader";
  1495. if (!Q_strncmp(keyname, s, strlen(s)) ) {
  1496. s = strchr(value, ';');
  1497. if (!s) {
  1498. ri.Printf( PRINT_WARNING, "WARNING: no semi colon in shaderremap '%s'\n", value );
  1499. break;
  1500. }
  1501. *s++ = 0;
  1502. R_RemapShader(value, s, "0");
  1503. continue;
  1504. }
  1505. // check for a different grid size
  1506. if (!Q_stricmp(keyname, "gridsize")) {
  1507. sscanf(value, "%f %f %f", &w->lightGridSize[0], &w->lightGridSize[1], &w->lightGridSize[2] );
  1508. continue;
  1509. }
  1510. }
  1511. }
  1512. /*
  1513. =================
  1514. R_GetEntityToken
  1515. =================
  1516. */
  1517. qboolean R_GetEntityToken( char *buffer, int size ) {
  1518. const char *s;
  1519. s = COM_Parse( &s_worldData.entityParsePoint );
  1520. Q_strncpyz( buffer, s, size );
  1521. if ( !s_worldData.entityParsePoint || !s[0] ) {
  1522. s_worldData.entityParsePoint = s_worldData.entityString;
  1523. return qfalse;
  1524. } else {
  1525. return qtrue;
  1526. }
  1527. }
  1528. /*
  1529. =================
  1530. RE_LoadWorldMap
  1531. Called directly from cgame
  1532. =================
  1533. */
  1534. void RE_LoadWorldMap( const char *name ) {
  1535. int i;
  1536. dheader_t *header;
  1537. byte *buffer;
  1538. byte *startMarker;
  1539. if ( tr.worldMapLoaded ) {
  1540. ri.Error( ERR_DROP, "ERROR: attempted to redundantly load world map\n" );
  1541. }
  1542. // set default sun direction to be used if it isn't
  1543. // overridden by a shader
  1544. tr.sunDirection[0] = 0.45f;
  1545. tr.sunDirection[1] = 0.3f;
  1546. tr.sunDirection[2] = 0.9f;
  1547. VectorNormalize( tr.sunDirection );
  1548. tr.worldMapLoaded = qtrue;
  1549. // load it
  1550. ri.FS_ReadFile( name, (void **)&buffer );
  1551. if ( !buffer ) {
  1552. ri.Error (ERR_DROP, "RE_LoadWorldMap: %s not found", name);
  1553. }
  1554. // clear tr.world so if the level fails to load, the next
  1555. // try will not look at the partially loaded version
  1556. tr.world = NULL;
  1557. Com_Memset( &s_worldData, 0, sizeof( s_worldData ) );
  1558. Q_strncpyz( s_worldData.name, name, sizeof( s_worldData.name ) );
  1559. Q_strncpyz( s_worldData.baseName, COM_SkipPath( s_worldData.name ), sizeof( s_worldData.name ) );
  1560. COM_StripExtension( s_worldData.baseName, s_worldData.baseName );
  1561. startMarker = ri.Hunk_Alloc(0, h_low);
  1562. c_gridVerts = 0;
  1563. header = (dheader_t *)buffer;
  1564. fileBase = (byte *)header;
  1565. i = LittleLong (header->version);
  1566. if ( i != BSP_VERSION ) {
  1567. ri.Error (ERR_DROP, "RE_LoadWorldMap: %s has wrong version number (%i should be %i)",
  1568. name, i, BSP_VERSION);
  1569. }
  1570. // swap all the lumps
  1571. for (i=0 ; i<sizeof(dheader_t)/4 ; i++) {
  1572. ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
  1573. }
  1574. // load into heap
  1575. R_LoadShaders( &header->lumps[LUMP_SHADERS] );
  1576. R_LoadLightmaps( &header->lumps[LUMP_LIGHTMAPS] );
  1577. R_LoadPlanes (&header->lumps[LUMP_PLANES]);
  1578. R_LoadFogs( &header->lumps[LUMP_FOGS], &header->lumps[LUMP_BRUSHES], &header->lumps[LUMP_BRUSHSIDES] );
  1579. R_LoadSurfaces( &header->lumps[LUMP_SURFACES], &header->lumps[LUMP_DRAWVERTS], &header->lumps[LUMP_DRAWINDEXES] );
  1580. R_LoadMarksurfaces (&header->lumps[LUMP_LEAFSURFACES]);
  1581. R_LoadNodesAndLeafs (&header->lumps[LUMP_NODES], &header->lumps[LUMP_LEAFS]);
  1582. R_LoadSubmodels (&header->lumps[LUMP_MODELS]);
  1583. R_LoadVisibility( &header->lumps[LUMP_VISIBILITY] );
  1584. R_LoadEntities( &header->lumps[LUMP_ENTITIES] );
  1585. R_LoadLightGrid( &header->lumps[LUMP_LIGHTGRID] );
  1586. s_worldData.dataSize = (byte *)ri.Hunk_Alloc(0, h_low) - startMarker;
  1587. // only set tr.world now that we know the entire level has loaded properly
  1588. tr.world = &s_worldData;
  1589. ri.FS_FreeFile( buffer );
  1590. }