Model.cpp 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329
  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. #include "Model_local.h"
  24. #include "Model_ase.h"
  25. #include "Model_lwo.h"
  26. #include "Model_ma.h"
  27. idCVar idRenderModelStatic::r_mergeModelSurfaces( "r_mergeModelSurfaces", "1", CVAR_BOOL|CVAR_RENDERER, "combine model surfaces with the same material" );
  28. idCVar idRenderModelStatic::r_slopVertex( "r_slopVertex", "0.01", CVAR_RENDERER, "merge xyz coordinates this far apart" );
  29. idCVar idRenderModelStatic::r_slopTexCoord( "r_slopTexCoord", "0.001", CVAR_RENDERER, "merge texture coordinates this far apart" );
  30. idCVar idRenderModelStatic::r_slopNormal( "r_slopNormal", "0.02", CVAR_RENDERER, "merge normals that dot less than this" );
  31. /*
  32. ================
  33. idRenderModelStatic::idRenderModelStatic
  34. ================
  35. */
  36. idRenderModelStatic::idRenderModelStatic() {
  37. name = "<undefined>";
  38. bounds.Clear();
  39. lastModifiedFrame = 0;
  40. lastArchivedFrame = 0;
  41. overlaysAdded = 0;
  42. shadowHull = NULL;
  43. isStaticWorldModel = false;
  44. defaulted = false;
  45. purged = false;
  46. fastLoad = false;
  47. reloadable = true;
  48. levelLoadReferenced = false;
  49. timeStamp = 0;
  50. }
  51. /*
  52. ================
  53. idRenderModelStatic::~idRenderModelStatic
  54. ================
  55. */
  56. idRenderModelStatic::~idRenderModelStatic() {
  57. PurgeModel();
  58. }
  59. /*
  60. ==============
  61. idRenderModelStatic::Print
  62. ==============
  63. */
  64. void idRenderModelStatic::Print() const {
  65. common->Printf( "%s\n", name.c_str() );
  66. common->Printf( "Static model.\n" );
  67. common->Printf( "bounds: (%f %f %f) to (%f %f %f)\n",
  68. bounds[0][0], bounds[0][1], bounds[0][2],
  69. bounds[1][0], bounds[1][1], bounds[1][2] );
  70. common->Printf( " verts tris material\n" );
  71. for ( int i = 0 ; i < NumSurfaces() ; i++ ) {
  72. const modelSurface_t *surf = Surface( i );
  73. srfTriangles_t *tri = surf->geometry;
  74. const idMaterial *material = surf->shader;
  75. if ( !tri ) {
  76. common->Printf( "%2i: %s, NULL surface geometry\n", i, material->GetName() );
  77. continue;
  78. }
  79. common->Printf( "%2i: %5i %5i %s", i, tri->numVerts, tri->numIndexes / 3, material->GetName() );
  80. if ( tri->generateNormals ) {
  81. common->Printf( " (smoothed)\n" );
  82. } else {
  83. common->Printf( "\n" );
  84. }
  85. }
  86. }
  87. /*
  88. ==============
  89. idRenderModelStatic::Memory
  90. ==============
  91. */
  92. int idRenderModelStatic::Memory() const {
  93. int totalBytes = 0;
  94. totalBytes += sizeof( *this );
  95. totalBytes += name.DynamicMemoryUsed();
  96. totalBytes += surfaces.MemoryUsed();
  97. if ( shadowHull ) {
  98. totalBytes += R_TriSurfMemory( shadowHull );
  99. }
  100. for ( int j = 0 ; j < NumSurfaces() ; j++ ) {
  101. const modelSurface_t *surf = Surface( j );
  102. if ( !surf->geometry ) {
  103. continue;
  104. }
  105. totalBytes += R_TriSurfMemory( surf->geometry );
  106. }
  107. return totalBytes;
  108. }
  109. /*
  110. ==============
  111. idRenderModelStatic::List
  112. ==============
  113. */
  114. void idRenderModelStatic::List() const {
  115. int totalTris = 0;
  116. int totalVerts = 0;
  117. int totalBytes = 0;
  118. totalBytes = Memory();
  119. char closed = 'C';
  120. for ( int j = 0 ; j < NumSurfaces() ; j++ ) {
  121. const modelSurface_t *surf = Surface( j );
  122. if ( !surf->geometry ) {
  123. continue;
  124. }
  125. if ( !surf->geometry->perfectHull ) {
  126. closed = ' ';
  127. }
  128. totalTris += surf->geometry->numIndexes / 3;
  129. totalVerts += surf->geometry->numVerts;
  130. }
  131. common->Printf( "%c%4ik %3i %4i %4i %s", closed, totalBytes/1024, NumSurfaces(), totalVerts, totalTris, Name() );
  132. if ( IsDynamicModel() == DM_CACHED ) {
  133. common->Printf( " (DM_CACHED)" );
  134. }
  135. if ( IsDynamicModel() == DM_CONTINUOUS ) {
  136. common->Printf( " (DM_CONTINUOUS)" );
  137. }
  138. if ( defaulted ) {
  139. common->Printf( " (DEFAULTED)" );
  140. }
  141. if ( bounds[0][0] >= bounds[1][0] ) {
  142. common->Printf( " (EMPTY BOUNDS)" );
  143. }
  144. if ( bounds[1][0] - bounds[0][0] > 100000 ) {
  145. common->Printf( " (HUGE BOUNDS)" );
  146. }
  147. common->Printf( "\n" );
  148. }
  149. /*
  150. ================
  151. idRenderModelStatic::IsDefaultModel
  152. ================
  153. */
  154. bool idRenderModelStatic::IsDefaultModel() const {
  155. return defaulted;
  156. }
  157. /*
  158. ================
  159. AddCubeFace
  160. ================
  161. */
  162. static void AddCubeFace( srfTriangles_t *tri, idVec3 v1, idVec3 v2, idVec3 v3, idVec3 v4 ) {
  163. tri->verts[tri->numVerts+0].Clear();
  164. tri->verts[tri->numVerts+0].xyz = v1 * 8;
  165. tri->verts[tri->numVerts+0].st[0] = 0;
  166. tri->verts[tri->numVerts+0].st[1] = 0;
  167. tri->verts[tri->numVerts+1].Clear();
  168. tri->verts[tri->numVerts+1].xyz = v2 * 8;
  169. tri->verts[tri->numVerts+1].st[0] = 1;
  170. tri->verts[tri->numVerts+1].st[1] = 0;
  171. tri->verts[tri->numVerts+2].Clear();
  172. tri->verts[tri->numVerts+2].xyz = v3 * 8;
  173. tri->verts[tri->numVerts+2].st[0] = 1;
  174. tri->verts[tri->numVerts+2].st[1] = 1;
  175. tri->verts[tri->numVerts+3].Clear();
  176. tri->verts[tri->numVerts+3].xyz = v4 * 8;
  177. tri->verts[tri->numVerts+3].st[0] = 0;
  178. tri->verts[tri->numVerts+3].st[1] = 1;
  179. tri->indexes[tri->numIndexes+0] = tri->numVerts + 0;
  180. tri->indexes[tri->numIndexes+1] = tri->numVerts + 1;
  181. tri->indexes[tri->numIndexes+2] = tri->numVerts + 2;
  182. tri->indexes[tri->numIndexes+3] = tri->numVerts + 0;
  183. tri->indexes[tri->numIndexes+4] = tri->numVerts + 2;
  184. tri->indexes[tri->numIndexes+5] = tri->numVerts + 3;
  185. tri->numVerts += 4;
  186. tri->numIndexes += 6;
  187. }
  188. /*
  189. ================
  190. idRenderModelStatic::MakeDefaultModel
  191. ================
  192. */
  193. void idRenderModelStatic::MakeDefaultModel() {
  194. defaulted = true;
  195. // throw out any surfaces we already have
  196. PurgeModel();
  197. // create one new surface
  198. modelSurface_t surf;
  199. srfTriangles_t *tri = R_AllocStaticTriSurf();
  200. surf.shader = tr.defaultMaterial;
  201. surf.geometry = tri;
  202. R_AllocStaticTriSurfVerts( tri, 24 );
  203. R_AllocStaticTriSurfIndexes( tri, 36 );
  204. AddCubeFace( tri, idVec3(-1, 1, 1), idVec3(1, 1, 1), idVec3(1, -1, 1), idVec3(-1, -1, 1) );
  205. AddCubeFace( tri, idVec3(-1, 1, -1), idVec3(-1, -1, -1), idVec3(1, -1, -1), idVec3(1, 1, -1) );
  206. AddCubeFace( tri, idVec3(1, -1, 1), idVec3(1, 1, 1), idVec3(1, 1, -1), idVec3(1, -1, -1) );
  207. AddCubeFace( tri, idVec3(-1, -1, 1), idVec3(-1, -1, -1), idVec3(-1, 1, -1), idVec3(-1, 1, 1) );
  208. AddCubeFace( tri, idVec3(-1, -1, 1), idVec3(1, -1, 1), idVec3(1, -1, -1), idVec3(-1, -1, -1) );
  209. AddCubeFace( tri, idVec3(-1, 1, 1), idVec3(-1, 1, -1), idVec3(1, 1, -1), idVec3(1, 1, 1) );
  210. tri->generateNormals = true;
  211. AddSurface( surf );
  212. FinishSurfaces();
  213. }
  214. /*
  215. ================
  216. idRenderModelStatic::PartialInitFromFile
  217. ================
  218. */
  219. void idRenderModelStatic::PartialInitFromFile( const char *fileName ) {
  220. fastLoad = true;
  221. InitFromFile( fileName );
  222. }
  223. /*
  224. ================
  225. idRenderModelStatic::InitFromFile
  226. ================
  227. */
  228. void idRenderModelStatic::InitFromFile( const char *fileName ) {
  229. bool loaded;
  230. idStr extension;
  231. InitEmpty( fileName );
  232. // FIXME: load new .proc map format
  233. name.ExtractFileExtension( extension );
  234. if ( extension.Icmp( "ase" ) == 0 ) {
  235. loaded = LoadASE( name );
  236. reloadable = true;
  237. } else if ( extension.Icmp( "lwo" ) == 0 ) {
  238. loaded = LoadLWO( name );
  239. reloadable = true;
  240. } else if ( extension.Icmp( "flt" ) == 0 ) {
  241. loaded = LoadFLT( name );
  242. reloadable = true;
  243. } else if ( extension.Icmp( "ma" ) == 0 ) {
  244. loaded = LoadMA( name );
  245. reloadable = true;
  246. } else {
  247. common->Warning( "idRenderModelStatic::InitFromFile: unknown type for model: \'%s\'", name.c_str() );
  248. loaded = false;
  249. }
  250. if ( !loaded ) {
  251. common->Warning( "Couldn't load model: '%s'", name.c_str() );
  252. MakeDefaultModel();
  253. return;
  254. }
  255. // it is now available for use
  256. purged = false;
  257. // create the bounds for culling and dynamic surface creation
  258. FinishSurfaces();
  259. }
  260. /*
  261. ================
  262. idRenderModelStatic::LoadModel
  263. ================
  264. */
  265. void idRenderModelStatic::LoadModel() {
  266. PurgeModel();
  267. InitFromFile( name );
  268. }
  269. /*
  270. ================
  271. idRenderModelStatic::InitEmpty
  272. ================
  273. */
  274. void idRenderModelStatic::InitEmpty( const char *fileName ) {
  275. // model names of the form _area* are static parts of the
  276. // world, and have already been considered for optimized shadows
  277. // other model names are inline entity models, and need to be
  278. // shadowed normally
  279. if ( !idStr::Cmpn( fileName, "_area", 5 ) ) {
  280. isStaticWorldModel = true;
  281. } else {
  282. isStaticWorldModel = false;
  283. }
  284. name = fileName;
  285. reloadable = false; // if it didn't come from a file, we can't reload it
  286. PurgeModel();
  287. purged = false;
  288. bounds.Zero();
  289. }
  290. /*
  291. ================
  292. idRenderModelStatic::AddSurface
  293. ================
  294. */
  295. void idRenderModelStatic::AddSurface( modelSurface_t surface ) {
  296. surfaces.Append( surface );
  297. if ( surface.geometry ) {
  298. bounds += surface.geometry->bounds;
  299. }
  300. }
  301. /*
  302. ================
  303. idRenderModelStatic::Name
  304. ================
  305. */
  306. const char *idRenderModelStatic::Name() const {
  307. return name;
  308. }
  309. /*
  310. ================
  311. idRenderModelStatic::Timestamp
  312. ================
  313. */
  314. ID_TIME_T idRenderModelStatic::Timestamp() const {
  315. return timeStamp;
  316. }
  317. /*
  318. ================
  319. idRenderModelStatic::NumSurfaces
  320. ================
  321. */
  322. int idRenderModelStatic::NumSurfaces() const {
  323. return surfaces.Num();
  324. }
  325. /*
  326. ================
  327. idRenderModelStatic::NumBaseSurfaces
  328. ================
  329. */
  330. int idRenderModelStatic::NumBaseSurfaces() const {
  331. return surfaces.Num() - overlaysAdded;
  332. }
  333. /*
  334. ================
  335. idRenderModelStatic::Surface
  336. ================
  337. */
  338. const modelSurface_t *idRenderModelStatic::Surface( int surfaceNum ) const {
  339. return &surfaces[surfaceNum];
  340. }
  341. /*
  342. ================
  343. idRenderModelStatic::AllocSurfaceTriangles
  344. ================
  345. */
  346. srfTriangles_t *idRenderModelStatic::AllocSurfaceTriangles( int numVerts, int numIndexes ) const {
  347. srfTriangles_t *tri = R_AllocStaticTriSurf();
  348. R_AllocStaticTriSurfVerts( tri, numVerts );
  349. R_AllocStaticTriSurfIndexes( tri, numIndexes );
  350. return tri;
  351. }
  352. /*
  353. ================
  354. idRenderModelStatic::FreeSurfaceTriangles
  355. ================
  356. */
  357. void idRenderModelStatic::FreeSurfaceTriangles( srfTriangles_t *tris ) const {
  358. R_FreeStaticTriSurf( tris );
  359. }
  360. /*
  361. ================
  362. idRenderModelStatic::ShadowHull
  363. ================
  364. */
  365. srfTriangles_t *idRenderModelStatic::ShadowHull() const {
  366. return shadowHull;
  367. }
  368. /*
  369. ================
  370. idRenderModelStatic::IsStaticWorldModel
  371. ================
  372. */
  373. bool idRenderModelStatic::IsStaticWorldModel() const {
  374. return isStaticWorldModel;
  375. }
  376. /*
  377. ================
  378. idRenderModelStatic::IsDynamicModel
  379. ================
  380. */
  381. dynamicModel_t idRenderModelStatic::IsDynamicModel() const {
  382. // dynamic subclasses will override this
  383. return DM_STATIC;
  384. }
  385. /*
  386. ================
  387. idRenderModelStatic::IsReloadable
  388. ================
  389. */
  390. bool idRenderModelStatic::IsReloadable() const {
  391. return reloadable;
  392. }
  393. /*
  394. ================
  395. idRenderModelStatic::Bounds
  396. ================
  397. */
  398. idBounds idRenderModelStatic::Bounds( const struct renderEntity_s *mdef ) const {
  399. return bounds;
  400. }
  401. /*
  402. ================
  403. idRenderModelStatic::DepthHack
  404. ================
  405. */
  406. float idRenderModelStatic::DepthHack() const {
  407. return 0.0f;
  408. }
  409. /*
  410. ================
  411. idRenderModelStatic::InstantiateDynamicModel
  412. ================
  413. */
  414. idRenderModel *idRenderModelStatic::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) {
  415. if ( cachedModel ) {
  416. delete cachedModel;
  417. cachedModel = NULL;
  418. }
  419. common->Error( "InstantiateDynamicModel called on static model '%s'", name.c_str() );
  420. return NULL;
  421. }
  422. /*
  423. ================
  424. idRenderModelStatic::NumJoints
  425. ================
  426. */
  427. int idRenderModelStatic::NumJoints( void ) const {
  428. return 0;
  429. }
  430. /*
  431. ================
  432. idRenderModelStatic::GetJoints
  433. ================
  434. */
  435. const idMD5Joint *idRenderModelStatic::GetJoints( void ) const {
  436. return NULL;
  437. }
  438. /*
  439. ================
  440. idRenderModelStatic::GetJointHandle
  441. ================
  442. */
  443. jointHandle_t idRenderModelStatic::GetJointHandle( const char *name ) const {
  444. return INVALID_JOINT;
  445. }
  446. /*
  447. ================
  448. idRenderModelStatic::GetJointName
  449. ================
  450. */
  451. const char * idRenderModelStatic::GetJointName( jointHandle_t handle ) const {
  452. return "";
  453. }
  454. /*
  455. ================
  456. idRenderModelStatic::GetDefaultPose
  457. ================
  458. */
  459. const idJointQuat *idRenderModelStatic::GetDefaultPose( void ) const {
  460. return NULL;
  461. }
  462. /*
  463. ================
  464. idRenderModelStatic::NearestJoint
  465. ================
  466. */
  467. int idRenderModelStatic::NearestJoint( int surfaceNum, int a, int b, int c ) const {
  468. return INVALID_JOINT;
  469. }
  470. //=====================================================================
  471. /*
  472. ================
  473. idRenderModelStatic::FinishSurfaces
  474. The mergeShadows option allows surfaces with different textures to share
  475. silhouette edges for shadow calculation, instead of leaving shared edges
  476. hanging.
  477. If any of the original shaders have the noSelfShadow flag set, the surfaces
  478. can't be merged, because they will need to be drawn in different order.
  479. If there is only one surface, a separate merged surface won't be generated.
  480. A model with multiple surfaces can't later have a skinned shader change the
  481. state of the noSelfShadow flag.
  482. -----------------
  483. Creates mirrored copies of two sided surfaces with normal maps, which would
  484. otherwise light funny.
  485. Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges.
  486. ================
  487. */
  488. void idRenderModelStatic::FinishSurfaces() {
  489. int i;
  490. int totalVerts, totalIndexes;
  491. purged = false;
  492. // make sure we don't have a huge bounds even if we don't finish everything
  493. bounds.Zero();
  494. if ( surfaces.Num() == 0 ) {
  495. return;
  496. }
  497. // renderBump doesn't care about most of this
  498. if ( fastLoad ) {
  499. bounds.Zero();
  500. for ( i = 0 ; i < surfaces.Num() ; i++ ) {
  501. const modelSurface_t *surf = &surfaces[i];
  502. R_BoundTriSurf( surf->geometry );
  503. bounds.AddBounds( surf->geometry->bounds );
  504. }
  505. return;
  506. }
  507. // cleanup all the final surfaces, but don't create sil edges
  508. totalVerts = 0;
  509. totalIndexes = 0;
  510. // decide if we are going to merge all the surfaces into one shadower
  511. int numOriginalSurfaces = surfaces.Num();
  512. // make sure there aren't any NULL shaders or geometry
  513. for ( i = 0 ; i < numOriginalSurfaces ; i++ ) {
  514. const modelSurface_t *surf = &surfaces[i];
  515. if ( surf->geometry == NULL || surf->shader == NULL ) {
  516. MakeDefaultModel();
  517. common->Error( "Model %s, surface %i had NULL geometry", name.c_str(), i );
  518. }
  519. if ( surf->shader == NULL ) {
  520. MakeDefaultModel();
  521. common->Error( "Model %s, surface %i had NULL shader", name.c_str(), i );
  522. }
  523. }
  524. // duplicate and reverse triangles for two sided bump mapped surfaces
  525. // note that this won't catch surfaces that have their shaders dynamically
  526. // changed, and won't work with animated models.
  527. // It is better to create completely separate surfaces, rather than
  528. // add vertexes and indexes to the existing surface, because the
  529. // tangent generation wouldn't like the acute shared edges
  530. for ( i = 0 ; i < numOriginalSurfaces ; i++ ) {
  531. const modelSurface_t *surf = &surfaces[i];
  532. if ( surf->shader->ShouldCreateBackSides() ) {
  533. srfTriangles_t *newTri;
  534. newTri = R_CopyStaticTriSurf( surf->geometry );
  535. R_ReverseTriangles( newTri );
  536. modelSurface_t newSurf;
  537. newSurf.shader = surf->shader;
  538. newSurf.geometry = newTri;
  539. AddSurface( newSurf );
  540. }
  541. }
  542. // clean the surfaces
  543. for ( i = 0 ; i < surfaces.Num() ; i++ ) {
  544. const modelSurface_t *surf = &surfaces[i];
  545. R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() );
  546. if ( surf->shader->SurfaceCastsShadow() ) {
  547. totalVerts += surf->geometry->numVerts;
  548. totalIndexes += surf->geometry->numIndexes;
  549. }
  550. }
  551. // add up the total surface area for development information
  552. for ( i = 0 ; i < surfaces.Num() ; i++ ) {
  553. const modelSurface_t *surf = &surfaces[i];
  554. srfTriangles_t *tri = surf->geometry;
  555. for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) {
  556. float area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz,
  557. tri->verts[tri->indexes[j+1]].xyz, tri->verts[tri->indexes[j+2]].xyz );
  558. const_cast<idMaterial *>(surf->shader)->AddToSurfaceArea( area );
  559. }
  560. }
  561. // calculate the bounds
  562. if ( surfaces.Num() == 0 ) {
  563. bounds.Zero();
  564. } else {
  565. bounds.Clear();
  566. for ( i = 0 ; i < surfaces.Num() ; i++ ) {
  567. modelSurface_t *surf = &surfaces[i];
  568. // if the surface has a deformation, increase the bounds
  569. // the amount here is somewhat arbitrary, designed to handle
  570. // autosprites and flares, but could be done better with exact
  571. // deformation information.
  572. // Note that this doesn't handle deformations that are skinned in
  573. // at run time...
  574. if ( surf->shader->Deform() != DFRM_NONE ) {
  575. srfTriangles_t *tri = surf->geometry;
  576. idVec3 mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f;
  577. float radius = ( tri->bounds[0] - mid ).Length();
  578. radius += 20.0f;
  579. tri->bounds[0][0] = mid[0] - radius;
  580. tri->bounds[0][1] = mid[1] - radius;
  581. tri->bounds[0][2] = mid[2] - radius;
  582. tri->bounds[1][0] = mid[0] + radius;
  583. tri->bounds[1][1] = mid[1] + radius;
  584. tri->bounds[1][2] = mid[2] + radius;
  585. }
  586. // add to the model bounds
  587. bounds.AddBounds( surf->geometry->bounds );
  588. }
  589. }
  590. }
  591. /*
  592. =================
  593. idRenderModelStatic::ConvertASEToModelSurfaces
  594. =================
  595. */
  596. typedef struct matchVert_s {
  597. struct matchVert_s *next;
  598. int v, tv;
  599. byte color[4];
  600. idVec3 normal;
  601. } matchVert_t;
  602. bool idRenderModelStatic::ConvertASEToModelSurfaces( const struct aseModel_s *ase ) {
  603. aseObject_t * object;
  604. aseMesh_t * mesh;
  605. aseMaterial_t * material;
  606. const idMaterial *im1, *im2;
  607. srfTriangles_t *tri;
  608. int objectNum;
  609. int i, j, k;
  610. int v, tv;
  611. int * vRemap;
  612. int * tvRemap;
  613. matchVert_t * mvTable; // all of the match verts
  614. matchVert_t ** mvHash; // points inside mvTable for each xyz index
  615. matchVert_t * lastmv;
  616. matchVert_t * mv;
  617. idVec3 normal;
  618. float uOffset, vOffset, textureSin, textureCos;
  619. float uTiling, vTiling;
  620. int * mergeTo;
  621. byte * color;
  622. static byte identityColor[4] = { 255, 255, 255, 255 };
  623. modelSurface_t surf, *modelSurf;
  624. if ( !ase ) {
  625. return false;
  626. }
  627. if ( ase->objects.Num() < 1 ) {
  628. return false;
  629. }
  630. timeStamp = ase->timeStamp;
  631. // the modeling programs can save out multiple surfaces with a common
  632. // material, but we would like to mege them together where possible
  633. // meaning that this->NumSurfaces() <= ase->objects.currentElements
  634. mergeTo = (int *)_alloca( ase->objects.Num() * sizeof( *mergeTo ) );
  635. surf.geometry = NULL;
  636. if ( ase->materials.Num() == 0 ) {
  637. // if we don't have any materials, dump everything into a single surface
  638. surf.shader = tr.defaultMaterial;
  639. surf.id = 0;
  640. this->AddSurface( surf );
  641. for ( i = 0 ; i < ase->objects.Num() ; i++ ) {
  642. mergeTo[i] = 0;
  643. }
  644. } else if ( !r_mergeModelSurfaces.GetBool() ) {
  645. // don't merge any
  646. for ( i = 0 ; i < ase->objects.Num() ; i++ ) {
  647. mergeTo[i] = i;
  648. object = ase->objects[i];
  649. material = ase->materials[object->materialRef];
  650. surf.shader = declManager->FindMaterial( material->name );
  651. surf.id = this->NumSurfaces();
  652. this->AddSurface( surf );
  653. }
  654. } else {
  655. // search for material matches
  656. for ( i = 0 ; i < ase->objects.Num() ; i++ ) {
  657. object = ase->objects[i];
  658. material = ase->materials[object->materialRef];
  659. im1 = declManager->FindMaterial( material->name );
  660. if ( im1->IsDiscrete() ) {
  661. // flares, autosprites, etc
  662. j = this->NumSurfaces();
  663. } else {
  664. for ( j = 0 ; j < this->NumSurfaces() ; j++ ) {
  665. modelSurf = &this->surfaces[j];
  666. im2 = modelSurf->shader;
  667. if ( im1 == im2 ) {
  668. // merge this
  669. mergeTo[i] = j;
  670. break;
  671. }
  672. }
  673. }
  674. if ( j == this->NumSurfaces() ) {
  675. // didn't merge
  676. mergeTo[i] = j;
  677. surf.shader = im1;
  678. surf.id = this->NumSurfaces();
  679. this->AddSurface( surf );
  680. }
  681. }
  682. }
  683. idVectorSubset<idVec3, 3> vertexSubset;
  684. idVectorSubset<idVec2, 2> texCoordSubset;
  685. // build the surfaces
  686. for ( objectNum = 0 ; objectNum < ase->objects.Num() ; objectNum++ ) {
  687. object = ase->objects[objectNum];
  688. mesh = &object->mesh;
  689. material = ase->materials[object->materialRef];
  690. im1 = declManager->FindMaterial( material->name );
  691. bool normalsParsed = mesh->normalsParsed;
  692. // completely ignore any explict normals on surfaces with a renderbump command
  693. // which will guarantee the best contours and least vertexes.
  694. const char *rb = im1->GetRenderBump();
  695. if ( rb && rb[0] ) {
  696. normalsParsed = false;
  697. }
  698. // It seems like the tools our artists are using often generate
  699. // verts and texcoords slightly separated that should be merged
  700. // note that we really should combine the surfaces with common materials
  701. // before doing this operation, because we can miss a slop combination
  702. // if they are in different surfaces
  703. vRemap = (int *)R_StaticAlloc( mesh->numVertexes * sizeof( vRemap[0] ) );
  704. if ( fastLoad ) {
  705. // renderbump doesn't care about vertex count
  706. for ( j = 0; j < mesh->numVertexes; j++ ) {
  707. vRemap[j] = j;
  708. }
  709. } else {
  710. float vertexEpsilon = r_slopVertex.GetFloat();
  711. float expand = 2 * 32 * vertexEpsilon;
  712. idVec3 mins, maxs;
  713. SIMDProcessor->MinMax( mins, maxs, mesh->vertexes, mesh->numVertexes );
  714. mins -= idVec3( expand, expand, expand );
  715. maxs += idVec3( expand, expand, expand );
  716. vertexSubset.Init( mins, maxs, 32, 1024 );
  717. for ( j = 0; j < mesh->numVertexes; j++ ) {
  718. vRemap[j] = vertexSubset.FindVector( mesh->vertexes, j, vertexEpsilon );
  719. }
  720. }
  721. tvRemap = (int *)R_StaticAlloc( mesh->numTVertexes * sizeof( tvRemap[0] ) );
  722. if ( fastLoad ) {
  723. // renderbump doesn't care about vertex count
  724. for ( j = 0; j < mesh->numTVertexes; j++ ) {
  725. tvRemap[j] = j;
  726. }
  727. } else {
  728. float texCoordEpsilon = r_slopTexCoord.GetFloat();
  729. float expand = 2 * 32 * texCoordEpsilon;
  730. idVec2 mins, maxs;
  731. SIMDProcessor->MinMax( mins, maxs, mesh->tvertexes, mesh->numTVertexes );
  732. mins -= idVec2( expand, expand );
  733. maxs += idVec2( expand, expand );
  734. texCoordSubset.Init( mins, maxs, 32, 1024 );
  735. for ( j = 0; j < mesh->numTVertexes; j++ ) {
  736. tvRemap[j] = texCoordSubset.FindVector( mesh->tvertexes, j, texCoordEpsilon );
  737. }
  738. }
  739. // we need to find out how many unique vertex / texcoord combinations
  740. // there are, because ASE tracks them separately but we need them unified
  741. // the maximum possible number of combined vertexes is the number of indexes
  742. mvTable = (matchVert_t *)R_ClearedStaticAlloc( mesh->numFaces * 3 * sizeof( mvTable[0] ) );
  743. // we will have a hash chain based on the xyz values
  744. mvHash = (matchVert_t **)R_ClearedStaticAlloc( mesh->numVertexes * sizeof( mvHash[0] ) );
  745. // allocate triangle surface
  746. tri = R_AllocStaticTriSurf();
  747. tri->numVerts = 0;
  748. tri->numIndexes = 0;
  749. R_AllocStaticTriSurfIndexes( tri, mesh->numFaces * 3 );
  750. tri->generateNormals = !normalsParsed;
  751. // init default normal, color and tex coord index
  752. normal.Zero();
  753. color = identityColor;
  754. tv = 0;
  755. // find all the unique combinations
  756. float normalEpsilon = 1.0f - r_slopNormal.GetFloat();
  757. for ( j = 0; j < mesh->numFaces; j++ ) {
  758. for ( k = 0; k < 3; k++ ) {
  759. v = mesh->faces[j].vertexNum[k];
  760. if ( v < 0 || v >= mesh->numVertexes ) {
  761. common->Error( "ConvertASEToModelSurfaces: bad vertex index in ASE file %s", name.c_str() );
  762. }
  763. // collapse the position if it was slightly offset
  764. v = vRemap[v];
  765. // we may or may not have texcoords to compare
  766. if ( mesh->numTVFaces == mesh->numFaces && mesh->numTVertexes != 0 ) {
  767. tv = mesh->faces[j].tVertexNum[k];
  768. if ( tv < 0 || tv >= mesh->numTVertexes ) {
  769. common->Error( "ConvertASEToModelSurfaces: bad tex coord index in ASE file %s", name.c_str() );
  770. }
  771. // collapse the tex coord if it was slightly offset
  772. tv = tvRemap[tv];
  773. }
  774. // we may or may not have normals to compare
  775. if ( normalsParsed ) {
  776. normal = mesh->faces[j].vertexNormals[k];
  777. }
  778. // we may or may not have colors to compare
  779. if ( mesh->colorsParsed ) {
  780. color = mesh->faces[j].vertexColors[k];
  781. }
  782. // find a matching vert
  783. for ( lastmv = NULL, mv = mvHash[v]; mv != NULL; lastmv = mv, mv = mv->next ) {
  784. if ( mv->tv != tv ) {
  785. continue;
  786. }
  787. if ( *(unsigned *)mv->color != *(unsigned *)color ) {
  788. continue;
  789. }
  790. if ( !normalsParsed ) {
  791. // if we are going to create the normals, just
  792. // matching texcoords is enough
  793. break;
  794. }
  795. if ( mv->normal * normal > normalEpsilon ) {
  796. break; // we already have this one
  797. }
  798. }
  799. if ( !mv ) {
  800. // allocate a new match vert and link to hash chain
  801. mv = &mvTable[ tri->numVerts ];
  802. mv->v = v;
  803. mv->tv = tv;
  804. mv->normal = normal;
  805. *(unsigned *)mv->color = *(unsigned *)color;
  806. mv->next = NULL;
  807. if ( lastmv ) {
  808. lastmv->next = mv;
  809. } else {
  810. mvHash[v] = mv;
  811. }
  812. tri->numVerts++;
  813. }
  814. tri->indexes[tri->numIndexes] = mv - mvTable;
  815. tri->numIndexes++;
  816. }
  817. }
  818. // allocate space for the indexes and copy them
  819. if ( tri->numIndexes > mesh->numFaces * 3 ) {
  820. common->FatalError( "ConvertASEToModelSurfaces: index miscount in ASE file %s", name.c_str() );
  821. }
  822. if ( tri->numVerts > mesh->numFaces * 3 ) {
  823. common->FatalError( "ConvertASEToModelSurfaces: vertex miscount in ASE file %s", name.c_str() );
  824. }
  825. // an ASE allows the texture coordinates to be scaled, translated, and rotated
  826. if ( ase->materials.Num() == 0 ) {
  827. uOffset = vOffset = 0.0f;
  828. uTiling = vTiling = 1.0f;
  829. textureSin = 0.0f;
  830. textureCos = 1.0f;
  831. } else {
  832. material = ase->materials[object->materialRef];
  833. uOffset = -material->uOffset;
  834. vOffset = material->vOffset;
  835. uTiling = material->uTiling;
  836. vTiling = material->vTiling;
  837. textureSin = idMath::Sin( material->angle );
  838. textureCos = idMath::Cos( material->angle );
  839. }
  840. // now allocate and generate the combined vertexes
  841. R_AllocStaticTriSurfVerts( tri, tri->numVerts );
  842. for ( j = 0; j < tri->numVerts; j++ ) {
  843. mv = &mvTable[j];
  844. tri->verts[ j ].Clear();
  845. tri->verts[ j ].xyz = mesh->vertexes[ mv->v ];
  846. tri->verts[ j ].normal = mv->normal;
  847. *(unsigned *)tri->verts[j].color = *(unsigned *)mv->color;
  848. if ( mesh->numTVFaces == mesh->numFaces && mesh->numTVertexes != 0 ) {
  849. const idVec2 &tv = mesh->tvertexes[ mv->tv ];
  850. float u = tv.x * uTiling + uOffset;
  851. float v = tv.y * vTiling + vOffset;
  852. tri->verts[ j ].st[0] = u * textureCos + v * textureSin;
  853. tri->verts[ j ].st[1] = u * -textureSin + v * textureCos;
  854. }
  855. }
  856. R_StaticFree( mvTable );
  857. R_StaticFree( mvHash );
  858. R_StaticFree( tvRemap );
  859. R_StaticFree( vRemap );
  860. // see if we need to merge with a previous surface of the same material
  861. modelSurf = &this->surfaces[mergeTo[ objectNum ]];
  862. srfTriangles_t *mergeTri = modelSurf->geometry;
  863. if ( !mergeTri ) {
  864. modelSurf->geometry = tri;
  865. } else {
  866. modelSurf->geometry = R_MergeTriangles( mergeTri, tri );
  867. R_FreeStaticTriSurf( tri );
  868. R_FreeStaticTriSurf( mergeTri );
  869. }
  870. }
  871. return true;
  872. }
  873. /*
  874. =================
  875. idRenderModelStatic::ConvertLWOToModelSurfaces
  876. =================
  877. */
  878. bool idRenderModelStatic::ConvertLWOToModelSurfaces( const struct st_lwObject *lwo ) {
  879. const idMaterial *im1, *im2;
  880. srfTriangles_t *tri;
  881. lwSurface * lwoSurf;
  882. int numTVertexes;
  883. int i, j, k;
  884. int v, tv;
  885. idVec3 * vList;
  886. int * vRemap;
  887. idVec2 * tvList;
  888. int * tvRemap;
  889. matchVert_t * mvTable; // all of the match verts
  890. matchVert_t ** mvHash; // points inside mvTable for each xyz index
  891. matchVert_t * lastmv;
  892. matchVert_t * mv;
  893. idVec3 normal;
  894. int * mergeTo;
  895. byte color[4];
  896. modelSurface_t surf, *modelSurf;
  897. if ( !lwo ) {
  898. return false;
  899. }
  900. if ( lwo->surf == NULL ) {
  901. return false;
  902. }
  903. timeStamp = lwo->timeStamp;
  904. // count the number of surfaces
  905. i = 0;
  906. for ( lwoSurf = lwo->surf; lwoSurf; lwoSurf = lwoSurf->next ) {
  907. i++;
  908. }
  909. // the modeling programs can save out multiple surfaces with a common
  910. // material, but we would like to merge them together where possible
  911. mergeTo = (int *)_alloca( i * sizeof( mergeTo[0] ) );
  912. memset( &surf, 0, sizeof( surf ) );
  913. if ( !r_mergeModelSurfaces.GetBool() ) {
  914. // don't merge any
  915. for ( lwoSurf = lwo->surf, i = 0; lwoSurf; lwoSurf = lwoSurf->next, i++ ) {
  916. mergeTo[i] = i;
  917. surf.shader = declManager->FindMaterial( lwoSurf->name );
  918. surf.id = this->NumSurfaces();
  919. this->AddSurface( surf );
  920. }
  921. } else {
  922. // search for material matches
  923. for ( lwoSurf = lwo->surf, i = 0; lwoSurf; lwoSurf = lwoSurf->next, i++ ) {
  924. im1 = declManager->FindMaterial( lwoSurf->name );
  925. if ( im1->IsDiscrete() ) {
  926. // flares, autosprites, etc
  927. j = this->NumSurfaces();
  928. } else {
  929. for ( j = 0 ; j < this->NumSurfaces() ; j++ ) {
  930. modelSurf = &this->surfaces[j];
  931. im2 = modelSurf->shader;
  932. if ( im1 == im2 ) {
  933. // merge this
  934. mergeTo[i] = j;
  935. break;
  936. }
  937. }
  938. }
  939. if ( j == this->NumSurfaces() ) {
  940. // didn't merge
  941. mergeTo[i] = j;
  942. surf.shader = im1;
  943. surf.id = this->NumSurfaces();
  944. this->AddSurface( surf );
  945. }
  946. }
  947. }
  948. idVectorSubset<idVec3, 3> vertexSubset;
  949. idVectorSubset<idVec2, 2> texCoordSubset;
  950. // we only ever use the first layer
  951. lwLayer *layer = lwo->layer;
  952. // vertex positions
  953. if ( layer->point.count <= 0 ) {
  954. common->Warning( "ConvertLWOToModelSurfaces: model \'%s\' has bad or missing vertex data", name.c_str() );
  955. return false;
  956. }
  957. vList = (idVec3 *)R_StaticAlloc( layer->point.count * sizeof( vList[0] ) );
  958. for ( j = 0; j < layer->point.count; j++ ) {
  959. vList[j].x = layer->point.pt[j].pos[0];
  960. vList[j].y = layer->point.pt[j].pos[2];
  961. vList[j].z = layer->point.pt[j].pos[1];
  962. }
  963. // vertex texture coords
  964. numTVertexes = 0;
  965. if ( layer->nvmaps ) {
  966. for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) {
  967. if ( vm->type == LWID_('T','X','U','V') ) {
  968. numTVertexes += vm->nverts;
  969. }
  970. }
  971. }
  972. if ( numTVertexes ) {
  973. tvList = (idVec2 *)Mem_Alloc( numTVertexes * sizeof( tvList[0] ) );
  974. int offset = 0;
  975. for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) {
  976. if ( vm->type == LWID_('T','X','U','V') ) {
  977. vm->offset = offset;
  978. for ( k = 0; k < vm->nverts; k++ ) {
  979. tvList[k + offset].x = vm->val[k][0];
  980. tvList[k + offset].y = 1.0f - vm->val[k][1]; // invert the t
  981. }
  982. offset += vm->nverts;
  983. }
  984. }
  985. } else {
  986. common->Warning( "ConvertLWOToModelSurfaces: model \'%s\' has bad or missing uv data", name.c_str() );
  987. numTVertexes = 1;
  988. tvList = (idVec2 *)Mem_ClearedAlloc( numTVertexes * sizeof( tvList[0] ) );
  989. }
  990. // It seems like the tools our artists are using often generate
  991. // verts and texcoords slightly separated that should be merged
  992. // note that we really should combine the surfaces with common materials
  993. // before doing this operation, because we can miss a slop combination
  994. // if they are in different surfaces
  995. vRemap = (int *)R_StaticAlloc( layer->point.count * sizeof( vRemap[0] ) );
  996. if ( fastLoad ) {
  997. // renderbump doesn't care about vertex count
  998. for ( j = 0; j < layer->point.count; j++ ) {
  999. vRemap[j] = j;
  1000. }
  1001. } else {
  1002. float vertexEpsilon = r_slopVertex.GetFloat();
  1003. float expand = 2 * 32 * vertexEpsilon;
  1004. idVec3 mins, maxs;
  1005. SIMDProcessor->MinMax( mins, maxs, vList, layer->point.count );
  1006. mins -= idVec3( expand, expand, expand );
  1007. maxs += idVec3( expand, expand, expand );
  1008. vertexSubset.Init( mins, maxs, 32, 1024 );
  1009. for ( j = 0; j < layer->point.count; j++ ) {
  1010. vRemap[j] = vertexSubset.FindVector( vList, j, vertexEpsilon );
  1011. }
  1012. }
  1013. tvRemap = (int *)R_StaticAlloc( numTVertexes * sizeof( tvRemap[0] ) );
  1014. if ( fastLoad ) {
  1015. // renderbump doesn't care about vertex count
  1016. for ( j = 0; j < numTVertexes; j++ ) {
  1017. tvRemap[j] = j;
  1018. }
  1019. } else {
  1020. float texCoordEpsilon = r_slopTexCoord.GetFloat();
  1021. float expand = 2 * 32 * texCoordEpsilon;
  1022. idVec2 mins, maxs;
  1023. SIMDProcessor->MinMax( mins, maxs, tvList, numTVertexes );
  1024. mins -= idVec2( expand, expand );
  1025. maxs += idVec2( expand, expand );
  1026. texCoordSubset.Init( mins, maxs, 32, 1024 );
  1027. for ( j = 0; j < numTVertexes; j++ ) {
  1028. tvRemap[j] = texCoordSubset.FindVector( tvList, j, texCoordEpsilon );
  1029. }
  1030. }
  1031. // build the surfaces
  1032. for ( lwoSurf = lwo->surf, i = 0; lwoSurf; lwoSurf = lwoSurf->next, i++ ) {
  1033. im1 = declManager->FindMaterial( lwoSurf->name );
  1034. bool normalsParsed = true;
  1035. // completely ignore any explict normals on surfaces with a renderbump command
  1036. // which will guarantee the best contours and least vertexes.
  1037. const char *rb = im1->GetRenderBump();
  1038. if ( rb && rb[0] ) {
  1039. normalsParsed = false;
  1040. }
  1041. // we need to find out how many unique vertex / texcoord combinations there are
  1042. // the maximum possible number of combined vertexes is the number of indexes
  1043. mvTable = (matchVert_t *)R_ClearedStaticAlloc( layer->polygon.count * 3 * sizeof( mvTable[0] ) );
  1044. // we will have a hash chain based on the xyz values
  1045. mvHash = (matchVert_t **)R_ClearedStaticAlloc( layer->point.count * sizeof( mvHash[0] ) );
  1046. // allocate triangle surface
  1047. tri = R_AllocStaticTriSurf();
  1048. tri->numVerts = 0;
  1049. tri->numIndexes = 0;
  1050. R_AllocStaticTriSurfIndexes( tri, layer->polygon.count * 3 );
  1051. tri->generateNormals = !normalsParsed;
  1052. // find all the unique combinations
  1053. float normalEpsilon;
  1054. if ( fastLoad ) {
  1055. normalEpsilon = 1.0f; // don't merge unless completely exact
  1056. } else {
  1057. normalEpsilon = 1.0f - r_slopNormal.GetFloat();
  1058. }
  1059. for ( j = 0; j < layer->polygon.count; j++ ) {
  1060. lwPolygon *poly = &layer->polygon.pol[j];
  1061. if ( poly->surf != lwoSurf ) {
  1062. continue;
  1063. }
  1064. if ( poly->nverts != 3 ) {
  1065. common->Warning( "ConvertLWOToModelSurfaces: model %s has too many verts for a poly! Make sure you triplet it down", name.c_str() );
  1066. continue;
  1067. }
  1068. for ( k = 0; k < 3; k++ ) {
  1069. v = vRemap[poly->v[k].index];
  1070. normal.x = poly->v[k].norm[0];
  1071. normal.y = poly->v[k].norm[2];
  1072. normal.z = poly->v[k].norm[1];
  1073. // LWO models aren't all that pretty when it comes down to the floating point values they store
  1074. normal.FixDegenerateNormal();
  1075. tv = 0;
  1076. color[0] = lwoSurf->color.rgb[0] * 255;
  1077. color[1] = lwoSurf->color.rgb[1] * 255;
  1078. color[2] = lwoSurf->color.rgb[2] * 255;
  1079. color[3] = 255;
  1080. // first set attributes from the vertex
  1081. lwPoint *pt = &layer->point.pt[poly->v[k].index];
  1082. int nvm;
  1083. for ( nvm = 0; nvm < pt->nvmaps; nvm++ ) {
  1084. lwVMapPt *vm = &pt->vm[nvm];
  1085. if ( vm->vmap->type == LWID_('T','X','U','V') ) {
  1086. tv = tvRemap[vm->index + vm->vmap->offset];
  1087. }
  1088. if ( vm->vmap->type == LWID_('R','G','B','A') ) {
  1089. for ( int chan = 0; chan < 4; chan++ ) {
  1090. color[chan] = 255 * vm->vmap->val[vm->index][chan];
  1091. }
  1092. }
  1093. }
  1094. // then override with polygon attributes
  1095. for ( nvm = 0; nvm < poly->v[k].nvmaps; nvm++ ) {
  1096. lwVMapPt *vm = &poly->v[k].vm[nvm];
  1097. if ( vm->vmap->type == LWID_('T','X','U','V') ) {
  1098. tv = tvRemap[vm->index + vm->vmap->offset];
  1099. }
  1100. if ( vm->vmap->type == LWID_('R','G','B','A') ) {
  1101. for ( int chan = 0; chan < 4; chan++ ) {
  1102. color[chan] = 255 * vm->vmap->val[vm->index][chan];
  1103. }
  1104. }
  1105. }
  1106. // find a matching vert
  1107. for ( lastmv = NULL, mv = mvHash[v]; mv != NULL; lastmv = mv, mv = mv->next ) {
  1108. if ( mv->tv != tv ) {
  1109. continue;
  1110. }
  1111. if ( *(unsigned *)mv->color != *(unsigned *)color ) {
  1112. continue;
  1113. }
  1114. if ( !normalsParsed ) {
  1115. // if we are going to create the normals, just
  1116. // matching texcoords is enough
  1117. break;
  1118. }
  1119. if ( mv->normal * normal > normalEpsilon ) {
  1120. break; // we already have this one
  1121. }
  1122. }
  1123. if ( !mv ) {
  1124. // allocate a new match vert and link to hash chain
  1125. mv = &mvTable[ tri->numVerts ];
  1126. mv->v = v;
  1127. mv->tv = tv;
  1128. mv->normal = normal;
  1129. *(unsigned *)mv->color = *(unsigned *)color;
  1130. mv->next = NULL;
  1131. if ( lastmv ) {
  1132. lastmv->next = mv;
  1133. } else {
  1134. mvHash[v] = mv;
  1135. }
  1136. tri->numVerts++;
  1137. }
  1138. tri->indexes[tri->numIndexes] = mv - mvTable;
  1139. tri->numIndexes++;
  1140. }
  1141. }
  1142. // allocate space for the indexes and copy them
  1143. if ( tri->numIndexes > layer->polygon.count * 3 ) {
  1144. common->FatalError( "ConvertLWOToModelSurfaces: index miscount in LWO file %s", name.c_str() );
  1145. }
  1146. if ( tri->numVerts > layer->polygon.count * 3 ) {
  1147. common->FatalError( "ConvertLWOToModelSurfaces: vertex miscount in LWO file %s", name.c_str() );
  1148. }
  1149. // now allocate and generate the combined vertexes
  1150. R_AllocStaticTriSurfVerts( tri, tri->numVerts );
  1151. for ( j = 0; j < tri->numVerts; j++ ) {
  1152. mv = &mvTable[j];
  1153. tri->verts[ j ].Clear();
  1154. tri->verts[ j ].xyz = vList[ mv->v ];
  1155. tri->verts[ j ].st = tvList[ mv->tv ];
  1156. tri->verts[ j ].normal = mv->normal;
  1157. *(unsigned *)tri->verts[j].color = *(unsigned *)mv->color;
  1158. }
  1159. R_StaticFree( mvTable );
  1160. R_StaticFree( mvHash );
  1161. // see if we need to merge with a previous surface of the same material
  1162. modelSurf = &this->surfaces[mergeTo[ i ]];
  1163. srfTriangles_t *mergeTri = modelSurf->geometry;
  1164. if ( !mergeTri ) {
  1165. modelSurf->geometry = tri;
  1166. } else {
  1167. modelSurf->geometry = R_MergeTriangles( mergeTri, tri );
  1168. R_FreeStaticTriSurf( tri );
  1169. R_FreeStaticTriSurf( mergeTri );
  1170. }
  1171. }
  1172. R_StaticFree( tvRemap );
  1173. R_StaticFree( vRemap );
  1174. R_StaticFree( tvList );
  1175. R_StaticFree( vList );
  1176. return true;
  1177. }
  1178. /*
  1179. =================
  1180. idRenderModelStatic::ConvertLWOToASE
  1181. =================
  1182. */
  1183. struct aseModel_s *idRenderModelStatic::ConvertLWOToASE( const struct st_lwObject *obj, const char *fileName ) {
  1184. int j, k;
  1185. aseModel_t *ase;
  1186. if ( !obj ) {
  1187. return NULL;
  1188. }
  1189. // NOTE: using new operator because aseModel_t contains idList class objects
  1190. ase = new aseModel_t;
  1191. ase->timeStamp = obj->timeStamp;
  1192. ase->objects.Resize( obj->nlayers, obj->nlayers );
  1193. int materialRef = 0;
  1194. for ( lwSurface *surf = obj->surf; surf; surf = surf->next ) {
  1195. aseMaterial_t *mat = (aseMaterial_t *)Mem_ClearedAlloc( sizeof( *mat ) );
  1196. strcpy( mat->name, surf->name );
  1197. mat->uTiling = mat->vTiling = 1;
  1198. mat->angle = mat->uOffset = mat->vOffset = 0;
  1199. ase->materials.Append( mat );
  1200. lwLayer *layer = obj->layer;
  1201. aseObject_t *object = (aseObject_t *)Mem_ClearedAlloc( sizeof( *object ) );
  1202. object->materialRef = materialRef++;
  1203. aseMesh_t *mesh = &object->mesh;
  1204. ase->objects.Append( object );
  1205. mesh->numFaces = layer->polygon.count;
  1206. mesh->numTVFaces = mesh->numFaces;
  1207. mesh->faces = (aseFace_t *)Mem_Alloc( mesh->numFaces * sizeof( mesh->faces[0] ) );
  1208. mesh->numVertexes = layer->point.count;
  1209. mesh->vertexes = (idVec3 *)Mem_Alloc( mesh->numVertexes * sizeof( mesh->vertexes[0] ) );
  1210. // vertex positions
  1211. if ( layer->point.count <= 0 ) {
  1212. common->Warning( "ConvertLWOToASE: model \'%s\' has bad or missing vertex data", name.c_str() );
  1213. }
  1214. for ( j = 0; j < layer->point.count; j++ ) {
  1215. mesh->vertexes[j].x = layer->point.pt[j].pos[0];
  1216. mesh->vertexes[j].y = layer->point.pt[j].pos[2];
  1217. mesh->vertexes[j].z = layer->point.pt[j].pos[1];
  1218. }
  1219. // vertex texture coords
  1220. mesh->numTVertexes = 0;
  1221. if ( layer->nvmaps ) {
  1222. for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) {
  1223. if ( vm->type == LWID_('T','X','U','V') ) {
  1224. mesh->numTVertexes += vm->nverts;
  1225. }
  1226. }
  1227. }
  1228. if ( mesh->numTVertexes ) {
  1229. mesh->tvertexes = (idVec2 *)Mem_Alloc( mesh->numTVertexes * sizeof( mesh->tvertexes[0] ) );
  1230. int offset = 0;
  1231. for( lwVMap *vm = layer->vmap; vm; vm = vm->next ) {
  1232. if ( vm->type == LWID_('T','X','U','V') ) {
  1233. vm->offset = offset;
  1234. for ( k = 0; k < vm->nverts; k++ ) {
  1235. mesh->tvertexes[k + offset].x = vm->val[k][0];
  1236. mesh->tvertexes[k + offset].y = 1.0f - vm->val[k][1]; // invert the t
  1237. }
  1238. offset += vm->nverts;
  1239. }
  1240. }
  1241. } else {
  1242. common->Warning( "ConvertLWOToASE: model \'%s\' has bad or missing uv data", fileName );
  1243. mesh->numTVertexes = 1;
  1244. mesh->tvertexes = (idVec2 *)Mem_ClearedAlloc( mesh->numTVertexes * sizeof( mesh->tvertexes[0] ) );
  1245. }
  1246. mesh->normalsParsed = true;
  1247. mesh->colorsParsed = true; // because we are falling back to the surface color
  1248. // triangles
  1249. int faceIndex = 0;
  1250. for ( j = 0; j < layer->polygon.count; j++ ) {
  1251. lwPolygon *poly = &layer->polygon.pol[j];
  1252. if ( poly->surf != surf ) {
  1253. continue;
  1254. }
  1255. if ( poly->nverts != 3 ) {
  1256. common->Warning( "ConvertLWOToASE: model %s has too many verts for a poly! Make sure you triplet it down", fileName );
  1257. continue;
  1258. }
  1259. mesh->faces[faceIndex].faceNormal.x = poly->norm[0];
  1260. mesh->faces[faceIndex].faceNormal.y = poly->norm[2];
  1261. mesh->faces[faceIndex].faceNormal.z = poly->norm[1];
  1262. for ( k = 0; k < 3; k++ ) {
  1263. mesh->faces[faceIndex].vertexNum[k] = poly->v[k].index;
  1264. mesh->faces[faceIndex].vertexNormals[k].x = poly->v[k].norm[0];
  1265. mesh->faces[faceIndex].vertexNormals[k].y = poly->v[k].norm[2];
  1266. mesh->faces[faceIndex].vertexNormals[k].z = poly->v[k].norm[1];
  1267. // complete fallbacks
  1268. mesh->faces[faceIndex].tVertexNum[k] = 0;
  1269. mesh->faces[faceIndex].vertexColors[k][0] = surf->color.rgb[0] * 255;
  1270. mesh->faces[faceIndex].vertexColors[k][1] = surf->color.rgb[1] * 255;
  1271. mesh->faces[faceIndex].vertexColors[k][2] = surf->color.rgb[2] * 255;
  1272. mesh->faces[faceIndex].vertexColors[k][3] = 255;
  1273. // first set attributes from the vertex
  1274. lwPoint *pt = &layer->point.pt[poly->v[k].index];
  1275. int nvm;
  1276. for ( nvm = 0; nvm < pt->nvmaps; nvm++ ) {
  1277. lwVMapPt *vm = &pt->vm[nvm];
  1278. if ( vm->vmap->type == LWID_('T','X','U','V') ) {
  1279. mesh->faces[faceIndex].tVertexNum[k] = vm->index + vm->vmap->offset;
  1280. }
  1281. if ( vm->vmap->type == LWID_('R','G','B','A') ) {
  1282. for ( int chan = 0; chan < 4; chan++ ) {
  1283. mesh->faces[faceIndex].vertexColors[k][chan] = 255 * vm->vmap->val[vm->index][chan];
  1284. }
  1285. }
  1286. }
  1287. // then override with polygon attributes
  1288. for ( nvm = 0; nvm < poly->v[k].nvmaps; nvm++ ) {
  1289. lwVMapPt *vm = &poly->v[k].vm[nvm];
  1290. if ( vm->vmap->type == LWID_('T','X','U','V') ) {
  1291. mesh->faces[faceIndex].tVertexNum[k] = vm->index + vm->vmap->offset;
  1292. }
  1293. if ( vm->vmap->type == LWID_('R','G','B','A') ) {
  1294. for ( int chan = 0; chan < 4; chan++ ) {
  1295. mesh->faces[faceIndex].vertexColors[k][chan] = 255 * vm->vmap->val[vm->index][chan];
  1296. }
  1297. }
  1298. }
  1299. }
  1300. faceIndex++;
  1301. }
  1302. mesh->numFaces = faceIndex;
  1303. mesh->numTVFaces = faceIndex;
  1304. aseFace_t *newFaces = ( aseFace_t* )Mem_Alloc( mesh->numFaces * sizeof ( mesh->faces[0] ) );
  1305. memcpy( newFaces, mesh->faces, sizeof( mesh->faces[0] ) * mesh->numFaces );
  1306. Mem_Free( mesh->faces );
  1307. mesh->faces = newFaces;
  1308. }
  1309. return ase;
  1310. }
  1311. /*
  1312. =================
  1313. idRenderModelStatic::ConvertMAToModelSurfaces
  1314. =================
  1315. */
  1316. bool idRenderModelStatic::ConvertMAToModelSurfaces (const struct maModel_s *ma ) {
  1317. maObject_t * object;
  1318. maMesh_t * mesh;
  1319. maMaterial_t * material;
  1320. const idMaterial *im1, *im2;
  1321. srfTriangles_t *tri;
  1322. int objectNum;
  1323. int i, j, k;
  1324. int v, tv;
  1325. int * vRemap;
  1326. int * tvRemap;
  1327. matchVert_t * mvTable; // all of the match verts
  1328. matchVert_t ** mvHash; // points inside mvTable for each xyz index
  1329. matchVert_t * lastmv;
  1330. matchVert_t * mv;
  1331. idVec3 normal;
  1332. float uOffset, vOffset, textureSin, textureCos;
  1333. float uTiling, vTiling;
  1334. int * mergeTo;
  1335. byte * color;
  1336. static byte identityColor[4] = { 255, 255, 255, 255 };
  1337. modelSurface_t surf, *modelSurf;
  1338. if ( !ma ) {
  1339. return false;
  1340. }
  1341. if ( ma->objects.Num() < 1 ) {
  1342. return false;
  1343. }
  1344. timeStamp = ma->timeStamp;
  1345. // the modeling programs can save out multiple surfaces with a common
  1346. // material, but we would like to mege them together where possible
  1347. // meaning that this->NumSurfaces() <= ma->objects.currentElements
  1348. mergeTo = (int *)_alloca( ma->objects.Num() * sizeof( *mergeTo ) );
  1349. surf.geometry = NULL;
  1350. if ( ma->materials.Num() == 0 ) {
  1351. // if we don't have any materials, dump everything into a single surface
  1352. surf.shader = tr.defaultMaterial;
  1353. surf.id = 0;
  1354. this->AddSurface( surf );
  1355. for ( i = 0 ; i < ma->objects.Num() ; i++ ) {
  1356. mergeTo[i] = 0;
  1357. }
  1358. } else if ( !r_mergeModelSurfaces.GetBool() ) {
  1359. // don't merge any
  1360. for ( i = 0 ; i < ma->objects.Num() ; i++ ) {
  1361. mergeTo[i] = i;
  1362. object = ma->objects[i];
  1363. if(object->materialRef >= 0) {
  1364. material = ma->materials[object->materialRef];
  1365. surf.shader = declManager->FindMaterial( material->name );
  1366. } else {
  1367. surf.shader = tr.defaultMaterial;
  1368. }
  1369. surf.id = this->NumSurfaces();
  1370. this->AddSurface( surf );
  1371. }
  1372. } else {
  1373. // search for material matches
  1374. for ( i = 0 ; i < ma->objects.Num() ; i++ ) {
  1375. object = ma->objects[i];
  1376. if(object->materialRef >= 0) {
  1377. material = ma->materials[object->materialRef];
  1378. im1 = declManager->FindMaterial( material->name );
  1379. } else {
  1380. im1 = tr.defaultMaterial;
  1381. }
  1382. if ( im1->IsDiscrete() ) {
  1383. // flares, autosprites, etc
  1384. j = this->NumSurfaces();
  1385. } else {
  1386. for ( j = 0 ; j < this->NumSurfaces() ; j++ ) {
  1387. modelSurf = &this->surfaces[j];
  1388. im2 = modelSurf->shader;
  1389. if ( im1 == im2 ) {
  1390. // merge this
  1391. mergeTo[i] = j;
  1392. break;
  1393. }
  1394. }
  1395. }
  1396. if ( j == this->NumSurfaces() ) {
  1397. // didn't merge
  1398. mergeTo[i] = j;
  1399. surf.shader = im1;
  1400. surf.id = this->NumSurfaces();
  1401. this->AddSurface( surf );
  1402. }
  1403. }
  1404. }
  1405. idVectorSubset<idVec3, 3> vertexSubset;
  1406. idVectorSubset<idVec2, 2> texCoordSubset;
  1407. // build the surfaces
  1408. for ( objectNum = 0 ; objectNum < ma->objects.Num() ; objectNum++ ) {
  1409. object = ma->objects[objectNum];
  1410. mesh = &object->mesh;
  1411. if(object->materialRef >= 0) {
  1412. material = ma->materials[object->materialRef];
  1413. im1 = declManager->FindMaterial( material->name );
  1414. } else {
  1415. im1 = tr.defaultMaterial;
  1416. }
  1417. bool normalsParsed = mesh->normalsParsed;
  1418. // completely ignore any explict normals on surfaces with a renderbump command
  1419. // which will guarantee the best contours and least vertexes.
  1420. const char *rb = im1->GetRenderBump();
  1421. if ( rb && rb[0] ) {
  1422. normalsParsed = false;
  1423. }
  1424. // It seems like the tools our artists are using often generate
  1425. // verts and texcoords slightly separated that should be merged
  1426. // note that we really should combine the surfaces with common materials
  1427. // before doing this operation, because we can miss a slop combination
  1428. // if they are in different surfaces
  1429. vRemap = (int *)R_StaticAlloc( mesh->numVertexes * sizeof( vRemap[0] ) );
  1430. if ( fastLoad ) {
  1431. // renderbump doesn't care about vertex count
  1432. for ( j = 0; j < mesh->numVertexes; j++ ) {
  1433. vRemap[j] = j;
  1434. }
  1435. } else {
  1436. float vertexEpsilon = r_slopVertex.GetFloat();
  1437. float expand = 2 * 32 * vertexEpsilon;
  1438. idVec3 mins, maxs;
  1439. SIMDProcessor->MinMax( mins, maxs, mesh->vertexes, mesh->numVertexes );
  1440. mins -= idVec3( expand, expand, expand );
  1441. maxs += idVec3( expand, expand, expand );
  1442. vertexSubset.Init( mins, maxs, 32, 1024 );
  1443. for ( j = 0; j < mesh->numVertexes; j++ ) {
  1444. vRemap[j] = vertexSubset.FindVector( mesh->vertexes, j, vertexEpsilon );
  1445. }
  1446. }
  1447. tvRemap = (int *)R_StaticAlloc( mesh->numTVertexes * sizeof( tvRemap[0] ) );
  1448. if ( fastLoad ) {
  1449. // renderbump doesn't care about vertex count
  1450. for ( j = 0; j < mesh->numTVertexes; j++ ) {
  1451. tvRemap[j] = j;
  1452. }
  1453. } else {
  1454. float texCoordEpsilon = r_slopTexCoord.GetFloat();
  1455. float expand = 2 * 32 * texCoordEpsilon;
  1456. idVec2 mins, maxs;
  1457. SIMDProcessor->MinMax( mins, maxs, mesh->tvertexes, mesh->numTVertexes );
  1458. mins -= idVec2( expand, expand );
  1459. maxs += idVec2( expand, expand );
  1460. texCoordSubset.Init( mins, maxs, 32, 1024 );
  1461. for ( j = 0; j < mesh->numTVertexes; j++ ) {
  1462. tvRemap[j] = texCoordSubset.FindVector( mesh->tvertexes, j, texCoordEpsilon );
  1463. }
  1464. }
  1465. // we need to find out how many unique vertex / texcoord / color combinations
  1466. // there are, because MA tracks them separately but we need them unified
  1467. // the maximum possible number of combined vertexes is the number of indexes
  1468. mvTable = (matchVert_t *)R_ClearedStaticAlloc( mesh->numFaces * 3 * sizeof( mvTable[0] ) );
  1469. // we will have a hash chain based on the xyz values
  1470. mvHash = (matchVert_t **)R_ClearedStaticAlloc( mesh->numVertexes * sizeof( mvHash[0] ) );
  1471. // allocate triangle surface
  1472. tri = R_AllocStaticTriSurf();
  1473. tri->numVerts = 0;
  1474. tri->numIndexes = 0;
  1475. R_AllocStaticTriSurfIndexes( tri, mesh->numFaces * 3 );
  1476. tri->generateNormals = !normalsParsed;
  1477. // init default normal, color and tex coord index
  1478. normal.Zero();
  1479. color = identityColor;
  1480. tv = 0;
  1481. // find all the unique combinations
  1482. float normalEpsilon = 1.0f - r_slopNormal.GetFloat();
  1483. for ( j = 0; j < mesh->numFaces; j++ ) {
  1484. for ( k = 0; k < 3; k++ ) {
  1485. v = mesh->faces[j].vertexNum[k];
  1486. if ( v < 0 || v >= mesh->numVertexes ) {
  1487. common->Error( "ConvertMAToModelSurfaces: bad vertex index in MA file %s", name.c_str() );
  1488. }
  1489. // collapse the position if it was slightly offset
  1490. v = vRemap[v];
  1491. // we may or may not have texcoords to compare
  1492. if ( mesh->numTVertexes != 0 ) {
  1493. tv = mesh->faces[j].tVertexNum[k];
  1494. if ( tv < 0 || tv >= mesh->numTVertexes ) {
  1495. common->Error( "ConvertMAToModelSurfaces: bad tex coord index in MA file %s", name.c_str() );
  1496. }
  1497. // collapse the tex coord if it was slightly offset
  1498. tv = tvRemap[tv];
  1499. }
  1500. // we may or may not have normals to compare
  1501. if ( normalsParsed ) {
  1502. normal = mesh->faces[j].vertexNormals[k];
  1503. }
  1504. //BSM: Todo: Fix the vertex colors
  1505. // we may or may not have colors to compare
  1506. if ( mesh->faces[j].vertexColors[k] != -1 && mesh->faces[j].vertexColors[k] != -999 ) {
  1507. color = &mesh->colors[mesh->faces[j].vertexColors[k]*4];
  1508. }
  1509. // find a matching vert
  1510. for ( lastmv = NULL, mv = mvHash[v]; mv != NULL; lastmv = mv, mv = mv->next ) {
  1511. if ( mv->tv != tv ) {
  1512. continue;
  1513. }
  1514. if ( *(unsigned *)mv->color != *(unsigned *)color ) {
  1515. continue;
  1516. }
  1517. if ( !normalsParsed ) {
  1518. // if we are going to create the normals, just
  1519. // matching texcoords is enough
  1520. break;
  1521. }
  1522. if ( mv->normal * normal > normalEpsilon ) {
  1523. break; // we already have this one
  1524. }
  1525. }
  1526. if ( !mv ) {
  1527. // allocate a new match vert and link to hash chain
  1528. mv = &mvTable[ tri->numVerts ];
  1529. mv->v = v;
  1530. mv->tv = tv;
  1531. mv->normal = normal;
  1532. *(unsigned *)mv->color = *(unsigned *)color;
  1533. mv->next = NULL;
  1534. if ( lastmv ) {
  1535. lastmv->next = mv;
  1536. } else {
  1537. mvHash[v] = mv;
  1538. }
  1539. tri->numVerts++;
  1540. }
  1541. tri->indexes[tri->numIndexes] = mv - mvTable;
  1542. tri->numIndexes++;
  1543. }
  1544. }
  1545. // allocate space for the indexes and copy them
  1546. if ( tri->numIndexes > mesh->numFaces * 3 ) {
  1547. common->FatalError( "ConvertMAToModelSurfaces: index miscount in MA file %s", name.c_str() );
  1548. }
  1549. if ( tri->numVerts > mesh->numFaces * 3 ) {
  1550. common->FatalError( "ConvertMAToModelSurfaces: vertex miscount in MA file %s", name.c_str() );
  1551. }
  1552. // an MA allows the texture coordinates to be scaled, translated, and rotated
  1553. //BSM: Todo: Does Maya support this and if so how
  1554. //if ( ase->materials.Num() == 0 ) {
  1555. uOffset = vOffset = 0.0f;
  1556. uTiling = vTiling = 1.0f;
  1557. textureSin = 0.0f;
  1558. textureCos = 1.0f;
  1559. //} else {
  1560. // material = ase->materials[object->materialRef];
  1561. // uOffset = -material->uOffset;
  1562. // vOffset = material->vOffset;
  1563. // uTiling = material->uTiling;
  1564. // vTiling = material->vTiling;
  1565. // textureSin = idMath::Sin( material->angle );
  1566. // textureCos = idMath::Cos( material->angle );
  1567. //}
  1568. // now allocate and generate the combined vertexes
  1569. R_AllocStaticTriSurfVerts( tri, tri->numVerts );
  1570. for ( j = 0; j < tri->numVerts; j++ ) {
  1571. mv = &mvTable[j];
  1572. tri->verts[ j ].Clear();
  1573. tri->verts[ j ].xyz = mesh->vertexes[ mv->v ];
  1574. tri->verts[ j ].normal = mv->normal;
  1575. *(unsigned *)tri->verts[j].color = *(unsigned *)mv->color;
  1576. if ( mesh->numTVertexes != 0 ) {
  1577. const idVec2 &tv = mesh->tvertexes[ mv->tv ];
  1578. float u = tv.x * uTiling + uOffset;
  1579. float v = tv.y * vTiling + vOffset;
  1580. tri->verts[ j ].st[0] = u * textureCos + v * textureSin;
  1581. tri->verts[ j ].st[1] = u * -textureSin + v * textureCos;
  1582. }
  1583. }
  1584. R_StaticFree( mvTable );
  1585. R_StaticFree( mvHash );
  1586. R_StaticFree( tvRemap );
  1587. R_StaticFree( vRemap );
  1588. // see if we need to merge with a previous surface of the same material
  1589. modelSurf = &this->surfaces[mergeTo[ objectNum ]];
  1590. srfTriangles_t *mergeTri = modelSurf->geometry;
  1591. if ( !mergeTri ) {
  1592. modelSurf->geometry = tri;
  1593. } else {
  1594. modelSurf->geometry = R_MergeTriangles( mergeTri, tri );
  1595. R_FreeStaticTriSurf( tri );
  1596. R_FreeStaticTriSurf( mergeTri );
  1597. }
  1598. }
  1599. return true;
  1600. }
  1601. /*
  1602. =================
  1603. idRenderModelStatic::LoadASE
  1604. =================
  1605. */
  1606. bool idRenderModelStatic::LoadASE( const char *fileName ) {
  1607. aseModel_t *ase;
  1608. ase = ASE_Load( fileName );
  1609. if ( ase == NULL ) {
  1610. return false;
  1611. }
  1612. ConvertASEToModelSurfaces( ase );
  1613. ASE_Free( ase );
  1614. return true;
  1615. }
  1616. /*
  1617. =================
  1618. idRenderModelStatic::LoadLWO
  1619. =================
  1620. */
  1621. bool idRenderModelStatic::LoadLWO( const char *fileName ) {
  1622. unsigned int failID;
  1623. int failPos;
  1624. lwObject *lwo;
  1625. lwo = lwGetObject( fileName, &failID, &failPos );
  1626. if ( lwo == NULL ) {
  1627. return false;
  1628. }
  1629. ConvertLWOToModelSurfaces( lwo );
  1630. lwFreeObject( lwo );
  1631. return true;
  1632. }
  1633. /*
  1634. =================
  1635. idRenderModelStatic::LoadMA
  1636. =================
  1637. */
  1638. bool idRenderModelStatic::LoadMA( const char *fileName ) {
  1639. maModel_t *ma;
  1640. ma = MA_Load( fileName );
  1641. if ( ma == NULL ) {
  1642. return false;
  1643. }
  1644. ConvertMAToModelSurfaces( ma );
  1645. MA_Free( ma );
  1646. return true;
  1647. }
  1648. /*
  1649. =================
  1650. idRenderModelStatic::LoadFLT
  1651. USGS height map data for megaTexture experiments
  1652. =================
  1653. */
  1654. bool idRenderModelStatic::LoadFLT( const char *fileName ) {
  1655. float *data;
  1656. int len;
  1657. len = fileSystem->ReadFile( fileName, (void **)&data );
  1658. if ( len <= 0 ) {
  1659. return false;
  1660. }
  1661. int size = sqrt( len / 4.0f );
  1662. // bound the altitudes
  1663. float min = 9999999;
  1664. float max = -9999999;
  1665. for ( int i = 0 ; i < len/4 ; i++ ) {
  1666. data[i] = BigFloat( data[i] );
  1667. if ( data[i] == -9999 ) {
  1668. data[i] = 0; // unscanned areas
  1669. }
  1670. if ( data[i] < min ) {
  1671. min = data[i];
  1672. }
  1673. if ( data[i] > max ) {
  1674. max = data[i];
  1675. }
  1676. }
  1677. #if 1
  1678. // write out a gray scale height map
  1679. byte *image = (byte *)R_StaticAlloc( len );
  1680. byte *image_p = image;
  1681. for ( int i = 0 ; i < len/4 ; i++ ) {
  1682. float v = ( data[i] - min ) / ( max - min );
  1683. image_p[0] =
  1684. image_p[1] =
  1685. image_p[2] = v * 255;
  1686. image_p[3] = 255;
  1687. image_p += 4;
  1688. }
  1689. idStr tgaName = fileName;
  1690. tgaName.StripFileExtension();
  1691. tgaName += ".tga";
  1692. R_WriteTGA( tgaName.c_str(), image, size, size, false );
  1693. R_StaticFree( image );
  1694. //return false;
  1695. #endif
  1696. // find the island above sea level
  1697. int minX, maxX, minY, maxY;
  1698. {
  1699. int i;
  1700. for ( minX = 0 ; minX < size ; minX++ ) {
  1701. for ( i = 0 ; i < size ; i++ ) {
  1702. if ( data[i*size + minX] > 1.0 ) {
  1703. break;
  1704. }
  1705. }
  1706. if ( i != size ) {
  1707. break;
  1708. }
  1709. }
  1710. for ( maxX = size-1 ; maxX > 0 ; maxX-- ) {
  1711. for ( i = 0 ; i < size ; i++ ) {
  1712. if ( data[i*size + maxX] > 1.0 ) {
  1713. break;
  1714. }
  1715. }
  1716. if ( i != size ) {
  1717. break;
  1718. }
  1719. }
  1720. for ( minY = 0 ; minY < size ; minY++ ) {
  1721. for ( i = 0 ; i < size ; i++ ) {
  1722. if ( data[minY*size + i] > 1.0 ) {
  1723. break;
  1724. }
  1725. }
  1726. if ( i != size ) {
  1727. break;
  1728. }
  1729. }
  1730. for ( maxY = size-1 ; maxY < size ; maxY-- ) {
  1731. for ( i = 0 ; i < size ; i++ ) {
  1732. if ( data[maxY*size + i] > 1.0 ) {
  1733. break;
  1734. }
  1735. }
  1736. if ( i != size ) {
  1737. break;
  1738. }
  1739. }
  1740. }
  1741. int width = maxX - minX + 1;
  1742. int height = maxY - minY + 1;
  1743. //width /= 2;
  1744. // allocate triangle surface
  1745. srfTriangles_t *tri = R_AllocStaticTriSurf();
  1746. tri->numVerts = width * height;
  1747. tri->numIndexes = (width-1) * (height-1) * 6;
  1748. fastLoad = true; // don't do all the sil processing
  1749. R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
  1750. R_AllocStaticTriSurfVerts( tri, tri->numVerts );
  1751. for ( int i = 0 ; i < height ; i++ ) {
  1752. for ( int j = 0; j < width ; j++ ) {
  1753. int v = i * width + j;
  1754. tri->verts[ v ].Clear();
  1755. tri->verts[ v ].xyz[0] = j * 10; // each sample is 10 meters
  1756. tri->verts[ v ].xyz[1] = -i * 10;
  1757. tri->verts[ v ].xyz[2] = data[(minY+i)*size+minX+j]; // height is in meters
  1758. tri->verts[ v ].st[0] = (float) j / (width-1);
  1759. tri->verts[ v ].st[1] = 1.0 - ( (float) i / (height-1) );
  1760. }
  1761. }
  1762. for ( int i = 0 ; i < height-1 ; i++ ) {
  1763. for ( int j = 0; j < width-1 ; j++ ) {
  1764. int v = ( i * (width-1) + j ) * 6;
  1765. #if 0
  1766. tri->indexes[ v + 0 ] = i * width + j;
  1767. tri->indexes[ v + 1 ] = (i+1) * width + j;
  1768. tri->indexes[ v + 2 ] = (i+1) * width + j + 1;
  1769. tri->indexes[ v + 3 ] = i * width + j;
  1770. tri->indexes[ v + 4 ] = (i+1) * width + j + 1;
  1771. tri->indexes[ v + 5 ] = i * width + j + 1;
  1772. #else
  1773. tri->indexes[ v + 0 ] = i * width + j;
  1774. tri->indexes[ v + 1 ] = i * width + j + 1;
  1775. tri->indexes[ v + 2 ] = (i+1) * width + j + 1;
  1776. tri->indexes[ v + 3 ] = i * width + j;
  1777. tri->indexes[ v + 4 ] = (i+1) * width + j + 1;
  1778. tri->indexes[ v + 5 ] = (i+1) * width + j;
  1779. #endif
  1780. }
  1781. }
  1782. fileSystem->FreeFile( data );
  1783. modelSurface_t surface;
  1784. surface.geometry = tri;
  1785. surface.id = 0;
  1786. surface.shader = tr.defaultMaterial; // declManager->FindMaterial( "shaderDemos/megaTexture" );
  1787. this->AddSurface( surface );
  1788. return true;
  1789. }
  1790. //=============================================================================
  1791. /*
  1792. ================
  1793. idRenderModelStatic::PurgeModel
  1794. ================
  1795. */
  1796. void idRenderModelStatic::PurgeModel() {
  1797. int i;
  1798. modelSurface_t *surf;
  1799. for ( i = 0 ; i < surfaces.Num() ; i++ ) {
  1800. surf = &surfaces[i];
  1801. if ( surf->geometry ) {
  1802. R_FreeStaticTriSurf( surf->geometry );
  1803. }
  1804. }
  1805. surfaces.Clear();
  1806. purged = true;
  1807. }
  1808. /*
  1809. ==============
  1810. idRenderModelStatic::FreeVertexCache
  1811. We are about to restart the vertex cache, so dump everything
  1812. ==============
  1813. */
  1814. void idRenderModelStatic::FreeVertexCache( void ) {
  1815. for ( int j = 0 ; j < surfaces.Num() ; j++ ) {
  1816. srfTriangles_t *tri = surfaces[j].geometry;
  1817. if ( !tri ) {
  1818. continue;
  1819. }
  1820. if ( tri->ambientCache ) {
  1821. vertexCache.Free( tri->ambientCache );
  1822. tri->ambientCache = NULL;
  1823. }
  1824. // static shadows may be present
  1825. if ( tri->shadowCache ) {
  1826. vertexCache.Free( tri->shadowCache );
  1827. tri->shadowCache = NULL;
  1828. }
  1829. }
  1830. }
  1831. /*
  1832. ================
  1833. idRenderModelStatic::ReadFromDemoFile
  1834. ================
  1835. */
  1836. void idRenderModelStatic::ReadFromDemoFile( class idDemoFile *f ) {
  1837. PurgeModel();
  1838. InitEmpty( f->ReadHashString() );
  1839. int i, j, numSurfaces;
  1840. f->ReadInt( numSurfaces );
  1841. for ( i = 0 ; i < numSurfaces ; i++ ) {
  1842. modelSurface_t surf;
  1843. surf.shader = declManager->FindMaterial( f->ReadHashString() );
  1844. srfTriangles_t *tri = R_AllocStaticTriSurf();
  1845. f->ReadInt( tri->numIndexes );
  1846. R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
  1847. for ( j = 0; j < tri->numIndexes; ++j )
  1848. f->ReadInt( (int&)tri->indexes[j] );
  1849. f->ReadInt( tri->numVerts );
  1850. R_AllocStaticTriSurfVerts( tri, tri->numVerts );
  1851. for ( j = 0; j < tri->numVerts; ++j ) {
  1852. f->ReadVec3( tri->verts[j].xyz );
  1853. f->ReadVec2( tri->verts[j].st );
  1854. f->ReadVec3( tri->verts[j].normal );
  1855. f->ReadVec3( tri->verts[j].tangents[0] );
  1856. f->ReadVec3( tri->verts[j].tangents[1] );
  1857. f->ReadUnsignedChar( tri->verts[j].color[0] );
  1858. f->ReadUnsignedChar( tri->verts[j].color[1] );
  1859. f->ReadUnsignedChar( tri->verts[j].color[2] );
  1860. f->ReadUnsignedChar( tri->verts[j].color[3] );
  1861. }
  1862. surf.geometry = tri;
  1863. this->AddSurface( surf );
  1864. }
  1865. this->FinishSurfaces();
  1866. }
  1867. /*
  1868. ================
  1869. idRenderModelStatic::WriteToDemoFile
  1870. ================
  1871. */
  1872. void idRenderModelStatic::WriteToDemoFile( class idDemoFile *f ) {
  1873. int data[1];
  1874. // note that it has been updated
  1875. lastArchivedFrame = tr.frameCount;
  1876. data[0] = DC_DEFINE_MODEL;
  1877. f->WriteInt( data[0] );
  1878. f->WriteHashString( this->Name() );
  1879. int i, j, iData = surfaces.Num();
  1880. f->WriteInt( iData );
  1881. for ( i = 0 ; i < surfaces.Num() ; i++ ) {
  1882. const modelSurface_t *surf = &surfaces[i];
  1883. f->WriteHashString( surf->shader->GetName() );
  1884. srfTriangles_t *tri = surf->geometry;
  1885. f->WriteInt( tri->numIndexes );
  1886. for ( j = 0; j < tri->numIndexes; ++j )
  1887. f->WriteInt( (int&)tri->indexes[j] );
  1888. f->WriteInt( tri->numVerts );
  1889. for ( j = 0; j < tri->numVerts; ++j ) {
  1890. f->WriteVec3( tri->verts[j].xyz );
  1891. f->WriteVec2( tri->verts[j].st );
  1892. f->WriteVec3( tri->verts[j].normal );
  1893. f->WriteVec3( tri->verts[j].tangents[0] );
  1894. f->WriteVec3( tri->verts[j].tangents[1] );
  1895. f->WriteUnsignedChar( tri->verts[j].color[0] );
  1896. f->WriteUnsignedChar( tri->verts[j].color[1] );
  1897. f->WriteUnsignedChar( tri->verts[j].color[2] );
  1898. f->WriteUnsignedChar( tri->verts[j].color[3] );
  1899. }
  1900. }
  1901. }
  1902. /*
  1903. ================
  1904. idRenderModelStatic::IsLoaded
  1905. ================
  1906. */
  1907. bool idRenderModelStatic::IsLoaded( void ) {
  1908. return !purged;
  1909. }
  1910. /*
  1911. ================
  1912. idRenderModelStatic::SetLevelLoadReferenced
  1913. ================
  1914. */
  1915. void idRenderModelStatic::SetLevelLoadReferenced( bool referenced ) {
  1916. levelLoadReferenced = referenced;
  1917. }
  1918. /*
  1919. ================
  1920. idRenderModelStatic::IsLevelLoadReferenced
  1921. ================
  1922. */
  1923. bool idRenderModelStatic::IsLevelLoadReferenced( void ) {
  1924. return levelLoadReferenced;
  1925. }
  1926. /*
  1927. =================
  1928. idRenderModelStatic::TouchData
  1929. =================
  1930. */
  1931. void idRenderModelStatic::TouchData( void ) {
  1932. for ( int i = 0 ; i < surfaces.Num() ; i++ ) {
  1933. const modelSurface_t *surf = &surfaces[i];
  1934. // re-find the material to make sure it gets added to the
  1935. // level keep list
  1936. declManager->FindMaterial( surf->shader->GetName() );
  1937. }
  1938. }
  1939. /*
  1940. =================
  1941. idRenderModelStatic::DeleteSurfaceWithId
  1942. =================
  1943. */
  1944. bool idRenderModelStatic::DeleteSurfaceWithId( int id ) {
  1945. int i;
  1946. for ( i = 0; i < surfaces.Num(); i++ ) {
  1947. if ( surfaces[i].id == id ) {
  1948. R_FreeStaticTriSurf( surfaces[i].geometry );
  1949. surfaces.RemoveIndex( i );
  1950. return true;
  1951. }
  1952. }
  1953. return false;
  1954. }
  1955. /*
  1956. =================
  1957. idRenderModelStatic::DeleteSurfacesWithNegativeId
  1958. =================
  1959. */
  1960. void idRenderModelStatic::DeleteSurfacesWithNegativeId( void ) {
  1961. int i;
  1962. for ( i = 0; i < surfaces.Num(); i++ ) {
  1963. if ( surfaces[i].id < 0 ) {
  1964. R_FreeStaticTriSurf( surfaces[i].geometry );
  1965. surfaces.RemoveIndex( i );
  1966. i--;
  1967. }
  1968. }
  1969. }
  1970. /*
  1971. =================
  1972. idRenderModelStatic::FindSurfaceWithId
  1973. =================
  1974. */
  1975. bool idRenderModelStatic::FindSurfaceWithId( int id, int &surfaceNum ) {
  1976. int i;
  1977. for ( i = 0; i < surfaces.Num(); i++ ) {
  1978. if ( surfaces[i].id == id ) {
  1979. surfaceNum = i;
  1980. return true;
  1981. }
  1982. }
  1983. return false;
  1984. }