tsShapeLoader.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "console/engineAPI.h"
  24. #include "ts/loader/tsShapeLoader.h"
  25. #include "core/volume.h"
  26. #include "materials/materialList.h"
  27. #include "materials/matInstance.h"
  28. #include "materials/materialManager.h"
  29. #include "ts/tsShapeInstance.h"
  30. #include "ts/tsMaterialList.h"
  31. MODULE_BEGIN( ShapeLoader )
  32. MODULE_INIT_AFTER( GFX )
  33. MODULE_INIT
  34. {
  35. TSShapeLoader::addFormat("Torque DTS", "dts");
  36. TSShapeLoader::addFormat("Torque DSQ", "dsq");
  37. }
  38. MODULE_END;
  39. const F32 TSShapeLoader::DefaultTime = -1.0f;
  40. const F64 TSShapeLoader::MinFrameRate = 15.0f;
  41. const F64 TSShapeLoader::MaxFrameRate = 60.0f;
  42. const F64 TSShapeLoader::AppGroundFrameRate = 10.0f;
  43. Torque::Path TSShapeLoader::shapePath;
  44. Vector<TSShapeLoader::ShapeFormat> TSShapeLoader::smFormats;
  45. //------------------------------------------------------------------------------
  46. // Utility functions
  47. void TSShapeLoader::zapScale(MatrixF& mat)
  48. {
  49. Point3F invScale = mat.getScale();
  50. invScale.x = invScale.x ? (1.0f / invScale.x) : 0;
  51. invScale.y = invScale.y ? (1.0f / invScale.y) : 0;
  52. invScale.z = invScale.z ? (1.0f / invScale.z) : 0;
  53. mat.scale(invScale);
  54. }
  55. //------------------------------------------------------------------------------
  56. // Shape utility functions
  57. MatrixF TSShapeLoader::getLocalNodeMatrix(AppNode* node, F32 t)
  58. {
  59. MatrixF m1 = node->getNodeTransform(t);
  60. // multiply by inverse scale at t=0
  61. MatrixF m10 = node->getNodeTransform(DefaultTime);
  62. m1.scale(Point3F(1.0f/m10.getScale().x, 1.0f/m10.getScale().y, 1.0f/m10.getScale().z));
  63. if (node->mParentIndex >= 0)
  64. {
  65. AppNode *parent = appNodes[node->mParentIndex];
  66. MatrixF m2 = parent->getNodeTransform(t);
  67. // multiply by inverse scale at t=0
  68. MatrixF m20 = parent->getNodeTransform(DefaultTime);
  69. m2.scale(Point3F(1.0f/m20.getScale().x, 1.0f/m20.getScale().y, 1.0f/m20.getScale().z));
  70. // get local transform by pre-multiplying by inverted parent transform
  71. m1 = m2.inverse() * m1;
  72. }
  73. else if (boundsNode && node != boundsNode)
  74. {
  75. // make transform relative to bounds node transform at time=t
  76. MatrixF mb = boundsNode->getNodeTransform(t);
  77. zapScale(mb);
  78. m1 = mb.inverse() * m1;
  79. }
  80. return m1;
  81. }
  82. void TSShapeLoader::generateNodeTransform(AppNode* node, F32 t, bool blend, F32 referenceTime,
  83. QuatF& rot, Point3F& trans, QuatF& srot, Point3F& scale)
  84. {
  85. MatrixF m1 = getLocalNodeMatrix(node, t);
  86. if (blend)
  87. {
  88. MatrixF m0 = getLocalNodeMatrix(node, referenceTime);
  89. m1 = m0.inverse() * m1;
  90. }
  91. rot.set(m1);
  92. trans = m1.getPosition();
  93. srot.identity(); //@todo: srot not supported yet
  94. scale = m1.getScale();
  95. }
  96. //-----------------------------------------------------------------------------
  97. void TSShapeLoader::updateProgress(S32 major, const char* msg, S32 numMinor, S32 minor)
  98. {
  99. // Calculate progress value
  100. F32 progress = (F32)major / NumLoadPhases;
  101. const char *progressMsg = msg;
  102. if (numMinor)
  103. {
  104. progress += (minor * (1.0f / NumLoadPhases) / numMinor);
  105. progressMsg = avar("%s (%d of %d)", msg, minor + 1, numMinor);
  106. }
  107. if(Con::isFunction("updateTSShapeLoadProgress"))
  108. Con::executef("updateTSShapeLoadProgress", Con::getFloatArg(progress), progressMsg);
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Shape creation entry point
  112. TSShape* TSShapeLoader::generateShape(const Torque::Path& path)
  113. {
  114. shapePath = path;
  115. shape = new TSShape();
  116. shape->mExporterVersion = 124;
  117. shape->mSmallestVisibleSize = 999999;
  118. shape->mSmallestVisibleDL = 0;
  119. shape->mReadVersion = 24;
  120. shape->mFlags = 0;
  121. shape->mSequencesConstructed = 0;
  122. // Get all nodes, objects and sequences in the shape
  123. updateProgress(Load_EnumerateScene, "Enumerating scene...");
  124. enumerateScene();
  125. if (!subshapes.size())
  126. {
  127. delete shape;
  128. Con::errorf("Failed to load shape \"%s\", no subshapes found", path.getFullPath().c_str());
  129. return NULL;
  130. }
  131. // Create the TSShape::Node hierarchy
  132. generateSubshapes();
  133. // Create objects (meshes and details)
  134. generateObjects();
  135. // Generate initial object states and node transforms
  136. generateDefaultStates();
  137. // Generate skins
  138. generateSkins();
  139. // Generate material list
  140. generateMaterialList();
  141. // Generate animation sequences
  142. generateSequences();
  143. // Sort detail levels and meshes
  144. updateProgress(Load_InitShape, "Initialising shape...");
  145. sortDetails();
  146. // Install the TS memory helper into a TSShape object.
  147. install();
  148. return shape;
  149. }
  150. bool TSShapeLoader::processNode(AppNode* node)
  151. {
  152. // Detect bounds node
  153. if ( node->isBounds() )
  154. {
  155. if ( boundsNode )
  156. {
  157. Con::warnf( "More than one bounds node found" );
  158. return false;
  159. }
  160. boundsNode = node;
  161. // Process bounds geometry
  162. MatrixF boundsMat(boundsNode->getNodeTransform(DefaultTime));
  163. boundsMat.inverse();
  164. zapScale(boundsMat);
  165. for (S32 iMesh = 0; iMesh < boundsNode->getNumMesh(); iMesh++)
  166. {
  167. AppMesh* mesh = boundsNode->getMesh(iMesh);
  168. MatrixF transform = mesh->getMeshTransform(DefaultTime);
  169. transform.mulL(boundsMat);
  170. mesh->lockMesh(DefaultTime, transform);
  171. }
  172. return true;
  173. }
  174. // Detect sequence markers
  175. if ( node->isSequence() )
  176. {
  177. //appSequences.push_back(new AppSequence(node));
  178. return false;
  179. }
  180. // Add this node to the subshape (create one if needed)
  181. if ( subshapes.size() == 0 )
  182. subshapes.push_back( new TSShapeLoader::Subshape );
  183. subshapes.last()->branches.push_back( node );
  184. return true;
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Nodes, meshes and skins
  188. typedef bool (*NameCmpFunc)(const String&, const Vector<String>&, void*, void*);
  189. bool cmpShapeName(const String& key, const Vector<String>& names, void* arg1, void* arg2)
  190. {
  191. for (S32 i = 0; i < names.size(); i++)
  192. {
  193. if (names[i].compare(key, 0, String::NoCase) == 0)
  194. return false;
  195. }
  196. return true;
  197. }
  198. String getUniqueName(const char* name, NameCmpFunc isNameUnique, const Vector<String>& names, void* arg1=0, void* arg2=0)
  199. {
  200. const S32 MAX_ITERATIONS = 0x10000; // maximum of 4 characters (A-P) will be appended
  201. String suffix;
  202. for (S32 i = 0; i < MAX_ITERATIONS; i++)
  203. {
  204. // Generate a suffix using the first 16 characters of the alphabet
  205. suffix.clear();
  206. for (S32 value = i; value != 0; value >>= 4)
  207. suffix = suffix + (char)('A' + (value & 0xF));
  208. String uname = name + suffix;
  209. if (isNameUnique(uname, names, arg1, arg2))
  210. return uname;
  211. }
  212. return name;
  213. }
  214. void TSShapeLoader::recurseSubshape(AppNode* appNode, S32 parentIndex, bool recurseChildren)
  215. {
  216. // Ignore local bounds nodes
  217. if (appNode->isBounds())
  218. return;
  219. S32 subShapeNum = shape->subShapeFirstNode.size()-1;
  220. Subshape* subshape = subshapes[subShapeNum];
  221. // Check if we should collapse this node
  222. S32 myIndex;
  223. if (ignoreNode(appNode->getName()))
  224. {
  225. myIndex = parentIndex;
  226. }
  227. else
  228. {
  229. // Check that adding this node will not exceed the maximum node count
  230. if (shape->nodes.size() >= MAX_TS_SET_SIZE)
  231. return;
  232. myIndex = shape->nodes.size();
  233. String nodeName = getUniqueName(appNode->getName(), cmpShapeName, shape->names);
  234. // Create the 3space node
  235. shape->nodes.increment();
  236. TSShape::Node& lastNode = shape->nodes.last();
  237. lastNode.nameIndex = shape->addName(nodeName);
  238. lastNode.parentIndex = parentIndex;
  239. lastNode.firstObject = -1;
  240. lastNode.firstChild = -1;
  241. lastNode.nextSibling = -1;
  242. // Add the AppNode to a matching list (so AppNodes can be accessed using 3space
  243. // node indices)
  244. appNodes.push_back(appNode);
  245. appNodes.last()->mParentIndex = parentIndex;
  246. // Check for NULL detail or AutoBillboard nodes (no children or geometry)
  247. if ((appNode->getNumChildNodes() == 0) &&
  248. (appNode->getNumMesh() == 0))
  249. {
  250. S32 size = 0x7FFFFFFF;
  251. String dname(String::GetTrailingNumber(appNode->getName(), size));
  252. if (dStrEqual(dname, "nulldetail") && (size != 0x7FFFFFFF))
  253. {
  254. shape->addDetail("detail", size, subShapeNum);
  255. }
  256. else if (appNode->isBillboard() && (size != 0x7FFFFFFF))
  257. {
  258. // AutoBillboard detail
  259. S32 numEquatorSteps = 4;
  260. S32 numPolarSteps = 0;
  261. F32 polarAngle = 0.0f;
  262. S32 dl = 0;
  263. S32 dim = 64;
  264. bool includePoles = true;
  265. appNode->getInt("BB::EQUATOR_STEPS", numEquatorSteps);
  266. appNode->getInt("BB::POLAR_STEPS", numPolarSteps);
  267. appNode->getFloat("BB::POLAR_ANGLE", polarAngle);
  268. appNode->getInt("BB::DL", dl);
  269. appNode->getInt("BB::DIM", dim);
  270. appNode->getBool("BB::INCLUDE_POLES", includePoles);
  271. S32 detIndex = shape->addDetail( "bbDetail", size, -1 );
  272. TSShape::Detail& detIndexDetail = shape->details[detIndex];
  273. detIndexDetail.bbEquatorSteps = numEquatorSteps;
  274. detIndexDetail.bbPolarSteps = numPolarSteps;
  275. detIndexDetail.bbDetailLevel = dl;
  276. detIndexDetail.bbDimension = dim;
  277. detIndexDetail.bbIncludePoles = includePoles;
  278. detIndexDetail.bbPolarAngle = polarAngle;
  279. }
  280. }
  281. }
  282. // Collect geometry
  283. for (U32 iMesh = 0; iMesh < appNode->getNumMesh(); iMesh++)
  284. {
  285. AppMesh* mesh = appNode->getMesh(iMesh);
  286. if (!ignoreMesh(mesh->getName()))
  287. {
  288. subshape->objMeshes.push_back(mesh);
  289. subshape->objNodes.push_back(mesh->isSkin() ? -1 : myIndex);
  290. }
  291. }
  292. // Create children
  293. if (recurseChildren)
  294. {
  295. for (S32 iChild = 0; iChild < appNode->getNumChildNodes(); iChild++)
  296. recurseSubshape(appNode->getChildNode(iChild), myIndex, true);
  297. }
  298. }
  299. void TSShapeLoader::generateSubshapes()
  300. {
  301. for (U32 iSub = 0; iSub < subshapes.size(); iSub++)
  302. {
  303. updateProgress(Load_GenerateSubshapes, "Generating subshapes...", subshapes.size(), iSub);
  304. Subshape* subshape = subshapes[iSub];
  305. // Recurse through the node hierarchy, adding 3space nodes and
  306. // collecting geometry
  307. S32 firstNode = shape->nodes.size();
  308. shape->subShapeFirstNode.push_back(firstNode);
  309. for (U32 iBranch = 0; iBranch < subshape->branches.size(); iBranch++)
  310. recurseSubshape(subshape->branches[iBranch], -1, true);
  311. shape->subShapeNumNodes.push_back(shape->nodes.size() - firstNode);
  312. if (shape->nodes.size() >= MAX_TS_SET_SIZE)
  313. {
  314. Con::warnf("Shape exceeds the maximum node count (%d). Ignoring additional nodes.",
  315. MAX_TS_SET_SIZE);
  316. }
  317. }
  318. }
  319. // Custom name comparison function to compare mesh name and detail size
  320. bool cmpMeshNameAndSize(const String& key, const Vector<String>& names, void* arg1, void* arg2)
  321. {
  322. const Vector<AppMesh*>& meshes = *(Vector<AppMesh*>*)arg1;
  323. S32 meshSize = (intptr_t)arg2;
  324. for (S32 i = 0; i < names.size(); i++)
  325. {
  326. if (names[i].compare(key, 0, String::NoCase) == 0)
  327. {
  328. if (meshes[i]->detailSize == meshSize)
  329. return false;
  330. }
  331. }
  332. return true;
  333. }
  334. void TSShapeLoader::generateObjects()
  335. {
  336. for (S32 iSub = 0; iSub < subshapes.size(); iSub++)
  337. {
  338. Subshape* subshape = subshapes[iSub];
  339. shape->subShapeFirstObject.push_back(shape->objects.size());
  340. // Get the names and sizes of the meshes for this subshape
  341. Vector<String> meshNames;
  342. for (S32 iMesh = 0; iMesh < subshape->objMeshes.size(); iMesh++)
  343. {
  344. AppMesh* mesh = subshape->objMeshes[iMesh];
  345. mesh->detailSize = 2;
  346. String name = String::GetTrailingNumber( mesh->getName(), mesh->detailSize );
  347. name = getUniqueName( name, cmpMeshNameAndSize, meshNames, &(subshape->objMeshes), (void*)(uintptr_t)mesh->detailSize );
  348. meshNames.push_back( name );
  349. // Fix up any collision details that don't have a negative detail level.
  350. if ( dStrStartsWith(meshNames[iMesh], "Collision") ||
  351. dStrStartsWith(meshNames[iMesh], "LOSCol") )
  352. {
  353. if (mesh->detailSize > 0)
  354. mesh->detailSize = -mesh->detailSize;
  355. }
  356. }
  357. // An 'object' is a collection of meshes with the same base name and
  358. // different detail sizes. The object is attached to the node of the
  359. // highest detail mesh.
  360. // Sort the 3 arrays (objMeshes, objNodes, meshNames) by name and size
  361. for (S32 i = 0; i < subshape->objMeshes.size()-1; i++)
  362. {
  363. for (S32 j = i+1; j < subshape->objMeshes.size(); j++)
  364. {
  365. if ((meshNames[i].compare(meshNames[j]) < 0) ||
  366. ((meshNames[i].compare(meshNames[j]) == 0) &&
  367. (subshape->objMeshes[i]->detailSize < subshape->objMeshes[j]->detailSize)))
  368. {
  369. {
  370. AppMesh* tmp = subshape->objMeshes[i];
  371. subshape->objMeshes[i] = subshape->objMeshes[j];
  372. subshape->objMeshes[j] = tmp;
  373. }
  374. {
  375. S32 tmp = subshape->objNodes[i];
  376. subshape->objNodes[i] = subshape->objNodes[j];
  377. subshape->objNodes[j] = tmp;
  378. }
  379. {
  380. String tmp = meshNames[i];
  381. meshNames[i] = meshNames[j];
  382. meshNames[j] = tmp;
  383. }
  384. }
  385. }
  386. }
  387. // Now create objects
  388. const String* lastName = 0;
  389. for (S32 iMesh = 0; iMesh < subshape->objMeshes.size(); iMesh++)
  390. {
  391. AppMesh* mesh = subshape->objMeshes[iMesh];
  392. if (!lastName || (meshNames[iMesh] != *lastName))
  393. {
  394. shape->objects.increment();
  395. TSShape::Object& lastObject = shape->objects.last();
  396. lastObject.nameIndex = shape->addName(meshNames[iMesh]);
  397. lastObject.nodeIndex = subshape->objNodes[iMesh];
  398. lastObject.startMeshIndex = appMeshes.size();
  399. lastObject.numMeshes = 0;
  400. lastName = &meshNames[iMesh];
  401. }
  402. // Add this mesh to the object
  403. appMeshes.push_back(mesh);
  404. shape->objects.last().numMeshes++;
  405. // Set mesh flags
  406. mesh->flags = 0;
  407. if (mesh->isBillboard())
  408. {
  409. mesh->flags |= TSMesh::Billboard;
  410. if (mesh->isBillboardZAxis())
  411. mesh->flags |= TSMesh::BillboardZAxis;
  412. }
  413. // Set the detail name... do fixups for collision details.
  414. const char* detailName = "detail";
  415. if ( mesh->detailSize < 0 )
  416. {
  417. if ( dStrStartsWith(meshNames[iMesh], "Collision") ||
  418. dStrStartsWith(meshNames[iMesh], "Col") )
  419. detailName = "Collision";
  420. else if (dStrStartsWith(meshNames[iMesh], "LOSCol"))
  421. detailName = "LOS";
  422. }
  423. // Attempt to add the detail (will fail if it already exists)
  424. S32 oldNumDetails = shape->details.size();
  425. shape->addDetail(detailName, mesh->detailSize, iSub);
  426. if (shape->details.size() > oldNumDetails)
  427. {
  428. Con::warnf("Object mesh \"%s\" has no matching detail (\"%s%d\" has"
  429. " been added automatically)", mesh->getName(false), detailName, mesh->detailSize);
  430. }
  431. }
  432. // Get object count for this subshape
  433. shape->subShapeNumObjects.push_back(shape->objects.size() - shape->subShapeFirstObject.last());
  434. }
  435. }
  436. void TSShapeLoader::generateSkins()
  437. {
  438. Vector<AppMesh*> skins;
  439. for (S32 iObject = 0; iObject < shape->objects.size(); iObject++)
  440. {
  441. for (S32 iMesh = 0; iMesh < shape->objects[iObject].numMeshes; iMesh++)
  442. {
  443. AppMesh* mesh = appMeshes[shape->objects[iObject].startMeshIndex + iMesh];
  444. if (mesh->isSkin())
  445. skins.push_back(mesh);
  446. }
  447. }
  448. for (S32 iSkin = 0; iSkin < skins.size(); iSkin++)
  449. {
  450. updateProgress(Load_GenerateSkins, "Generating skins...", skins.size(), iSkin);
  451. // Get skin data (bones, vertex weights etc)
  452. AppMesh* skin = skins[iSkin];
  453. skin->lookupSkinData();
  454. // Just copy initial verts and norms for now
  455. skin->initialVerts.set(skin->points.address(), skin->vertsPerFrame);
  456. skin->initialNorms.set(skin->normals.address(), skin->vertsPerFrame);
  457. // Map bones to nodes
  458. skin->nodeIndex.setSize(skin->bones.size());
  459. for (S32 iBone = 0; iBone < skin->bones.size(); iBone++)
  460. {
  461. // Find the node that matches this bone
  462. skin->nodeIndex[iBone] = -1;
  463. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  464. {
  465. if (appNodes[iNode]->isEqual(skin->bones[iBone]))
  466. {
  467. delete skin->bones[iBone];
  468. skin->bones[iBone] = appNodes[iNode];
  469. skin->nodeIndex[iBone] = iNode;
  470. break;
  471. }
  472. }
  473. if (skin->nodeIndex[iBone] == -1)
  474. {
  475. Con::warnf("Could not find bone %d. Defaulting to first node", iBone);
  476. skin->nodeIndex[iBone] = 0;
  477. }
  478. }
  479. }
  480. }
  481. void TSShapeLoader::generateDefaultStates()
  482. {
  483. // Generate default object states (includes initial geometry)
  484. for (S32 iObject = 0; iObject < shape->objects.size(); iObject++)
  485. {
  486. updateProgress(Load_GenerateDefaultStates, "Generating initial mesh and node states...",
  487. shape->objects.size(), iObject);
  488. TSShape::Object& obj = shape->objects[iObject];
  489. // Calculate the objectOffset for each mesh at T=0
  490. for (S32 iMesh = 0; iMesh < obj.numMeshes; iMesh++)
  491. {
  492. AppMesh* appMesh = appMeshes[obj.startMeshIndex + iMesh];
  493. AppNode* appNode = obj.nodeIndex >= 0 ? appNodes[obj.nodeIndex] : boundsNode;
  494. MatrixF meshMat(appMesh->getMeshTransform(DefaultTime));
  495. MatrixF nodeMat(appMesh->isSkin() ? meshMat : appNode->getNodeTransform(DefaultTime));
  496. zapScale(nodeMat);
  497. appMesh->objectOffset = nodeMat.inverse() * meshMat;
  498. }
  499. generateObjectState(shape->objects[iObject], DefaultTime, true, true);
  500. }
  501. // Generate default node transforms
  502. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  503. {
  504. // Determine the default translation and rotation for the node
  505. QuatF rot, srot;
  506. Point3F trans, scale;
  507. generateNodeTransform(appNodes[iNode], DefaultTime, false, 0, rot, trans, srot, scale);
  508. // Add default node translation and rotation
  509. addNodeRotation(rot, true);
  510. addNodeTranslation(trans, true);
  511. }
  512. }
  513. void TSShapeLoader::generateObjectState(TSShape::Object& obj, F32 t, bool addFrame, bool addMatFrame)
  514. {
  515. shape->objectStates.increment();
  516. TSShape::ObjectState& state = shape->objectStates.last();
  517. state.frameIndex = 0;
  518. state.matFrameIndex = 0;
  519. state.vis = mClampF(appMeshes[obj.startMeshIndex]->getVisValue(t), 0.0f, 1.0f);
  520. if (addFrame || addMatFrame)
  521. {
  522. generateFrame(obj, t, addFrame, addMatFrame);
  523. // set the frame number for the object state
  524. state.frameIndex = appMeshes[obj.startMeshIndex]->numFrames - 1;
  525. state.matFrameIndex = appMeshes[obj.startMeshIndex]->numMatFrames - 1;
  526. }
  527. }
  528. void TSShapeLoader::generateFrame(TSShape::Object& obj, F32 t, bool addFrame, bool addMatFrame)
  529. {
  530. for (S32 iMesh = 0; iMesh < obj.numMeshes; iMesh++)
  531. {
  532. AppMesh* appMesh = appMeshes[obj.startMeshIndex + iMesh];
  533. U32 oldNumPoints = appMesh->points.size();
  534. U32 oldNumUvs = appMesh->uvs.size();
  535. // Get the mesh geometry at time, 't'
  536. // Geometry verts, normals and tverts can be animated (different set for
  537. // each frame), but the TSDrawPrimitives stay the same, so the way lockMesh
  538. // works is that it will only generate the primitives once, then after that
  539. // will just append verts, normals and tverts each time it is called.
  540. appMesh->lockMesh(t, appMesh->objectOffset);
  541. // Calculate vertex normals if required
  542. if (appMesh->normals.size() != appMesh->points.size())
  543. appMesh->computeNormals();
  544. // If this is the first call, set the number of points per frame
  545. if (appMesh->numFrames == 0)
  546. {
  547. appMesh->vertsPerFrame = appMesh->points.size();
  548. }
  549. else
  550. {
  551. // Check frame topology => ie. that the right number of points, normals
  552. // and tverts was added
  553. if ((appMesh->points.size() - oldNumPoints) != appMesh->vertsPerFrame)
  554. {
  555. Con::warnf("Wrong number of points (%d) added at time=%f (expected %d)",
  556. appMesh->points.size() - oldNumPoints, t, appMesh->vertsPerFrame);
  557. addFrame = false;
  558. }
  559. if ((appMesh->normals.size() - oldNumPoints) != appMesh->vertsPerFrame)
  560. {
  561. Con::warnf("Wrong number of normals (%d) added at time=%f (expected %d)",
  562. appMesh->normals.size() - oldNumPoints, t, appMesh->vertsPerFrame);
  563. addFrame = false;
  564. }
  565. if ((appMesh->uvs.size() - oldNumUvs) != appMesh->vertsPerFrame)
  566. {
  567. Con::warnf("Wrong number of tverts (%d) added at time=%f (expected %d)",
  568. appMesh->uvs.size() - oldNumUvs, t, appMesh->vertsPerFrame);
  569. addMatFrame = false;
  570. }
  571. }
  572. // Because lockMesh adds points, normals AND tverts each call, if we didn't
  573. // actually want another frame or matFrame, we need to remove them afterwards.
  574. // In the common case (we DO want the frame), we can do nothing => the
  575. // points/normals/tverts are already in place!
  576. if (addFrame)
  577. {
  578. appMesh->numFrames++;
  579. }
  580. else
  581. {
  582. appMesh->points.setSize(oldNumPoints);
  583. appMesh->normals.setSize(oldNumPoints);
  584. }
  585. if (addMatFrame)
  586. {
  587. appMesh->numMatFrames++;
  588. }
  589. else
  590. {
  591. appMesh->uvs.setSize(oldNumPoints);
  592. }
  593. }
  594. }
  595. //-----------------------------------------------------------------------------
  596. // Materials
  597. /// Convert all Collada materials into a single TSMaterialList
  598. void TSShapeLoader::generateMaterialList()
  599. {
  600. // Install the materials into the material list
  601. shape->materialList = new TSMaterialList;
  602. for (S32 iMat = 0; iMat < AppMesh::appMaterials.size(); iMat++)
  603. {
  604. updateProgress(Load_GenerateMaterials, "Generating materials...", AppMesh::appMaterials.size(), iMat);
  605. AppMaterial* appMat = AppMesh::appMaterials[iMat];
  606. shape->materialList->push_back(appMat->getName(), appMat->getFlags(), U32(-1), U32(-1), U32(-1), 1.0f, appMat->getReflectance());
  607. }
  608. }
  609. //-----------------------------------------------------------------------------
  610. // Animation Sequences
  611. void TSShapeLoader::generateSequences()
  612. {
  613. for (S32 iSeq = 0; iSeq < appSequences.size(); iSeq++)
  614. {
  615. updateProgress(Load_GenerateSequences, "Generating sequences...", appSequences.size(), iSeq);
  616. // Initialize the sequence
  617. appSequences[iSeq]->setActive(true);
  618. shape->sequences.increment();
  619. TSShape::Sequence& seq = shape->sequences.last();
  620. seq.nameIndex = shape->addName(appSequences[iSeq]->getName());
  621. seq.toolBegin = appSequences[iSeq]->getStart();
  622. seq.priority = appSequences[iSeq]->getPriority();
  623. seq.flags = appSequences[iSeq]->getFlags();
  624. // Compute duration and number of keyframes (then adjust time between frames to match)
  625. seq.duration = appSequences[iSeq]->getEnd() - appSequences[iSeq]->getStart();
  626. seq.numKeyframes = (S32)(seq.duration * appSequences[iSeq]->fps + 0.5f) + 1;
  627. seq.sourceData.start = 0;
  628. seq.sourceData.end = seq.numKeyframes-1;
  629. seq.sourceData.total = seq.numKeyframes;
  630. // Set membership arrays (ie. which nodes and objects are affected by this sequence)
  631. setNodeMembership(seq, appSequences[iSeq]);
  632. setObjectMembership(seq, appSequences[iSeq]);
  633. // Generate keyframes
  634. generateNodeAnimation(seq);
  635. generateObjectAnimation(seq, appSequences[iSeq]);
  636. generateGroundAnimation(seq, appSequences[iSeq]);
  637. generateFrameTriggers(seq, appSequences[iSeq]);
  638. // Set sequence flags
  639. seq.dirtyFlags = 0;
  640. if (seq.rotationMatters.testAll() || seq.translationMatters.testAll() || seq.scaleMatters.testAll())
  641. seq.dirtyFlags |= TSShapeInstance::TransformDirty;
  642. if (seq.visMatters.testAll())
  643. seq.dirtyFlags |= TSShapeInstance::VisDirty;
  644. if (seq.frameMatters.testAll())
  645. seq.dirtyFlags |= TSShapeInstance::FrameDirty;
  646. if (seq.matFrameMatters.testAll())
  647. seq.dirtyFlags |= TSShapeInstance::MatFrameDirty;
  648. // Set shape flags (only the most significant scale type)
  649. U32 curVal = shape->mFlags & TSShape::AnyScale;
  650. shape->mFlags &= ~(TSShape::AnyScale);
  651. shape->mFlags |= getMax(curVal, seq.flags & TSShape::AnyScale); // take the larger value (can only convert upwards)
  652. appSequences[iSeq]->setActive(false);
  653. }
  654. }
  655. void TSShapeLoader::setNodeMembership(TSShape::Sequence& seq, const AppSequence* appSeq)
  656. {
  657. seq.rotationMatters.clearAll(); // node rotation (size = nodes.size())
  658. seq.translationMatters.clearAll(); // node translation (size = nodes.size())
  659. seq.scaleMatters.clearAll(); // node scale (size = nodes.size())
  660. // This shouldn't be allowed, but check anyway...
  661. if (seq.numKeyframes < 2)
  662. return;
  663. // Note: this fills the cache with current sequence data. Methods that get
  664. // called later (e.g. generateNodeAnimation) use this info (and assume it's set).
  665. fillNodeTransformCache(seq, appSeq);
  666. // Test to see if the transform changes over the interval in order to decide
  667. // whether to animate the transform in 3space. We don't use app's mechanism
  668. // for doing this because it functions different in different apps and we do
  669. // some special stuff with scale.
  670. setRotationMembership(seq);
  671. setTranslationMembership(seq);
  672. setScaleMembership(seq);
  673. }
  674. void TSShapeLoader::setRotationMembership(TSShape::Sequence& seq)
  675. {
  676. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  677. {
  678. // Check if any of the node rotations are different to
  679. // the default rotation
  680. QuatF defaultRot;
  681. shape->defaultRotations[iNode].getQuatF(&defaultRot);
  682. for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
  683. {
  684. if (nodeRotCache[iNode][iFrame] != defaultRot)
  685. {
  686. seq.rotationMatters.set(iNode);
  687. break;
  688. }
  689. }
  690. }
  691. }
  692. void TSShapeLoader::setTranslationMembership(TSShape::Sequence& seq)
  693. {
  694. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  695. {
  696. // Check if any of the node translations are different to
  697. // the default translation
  698. Point3F& defaultTrans = shape->defaultTranslations[iNode];
  699. for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
  700. {
  701. if (!nodeTransCache[iNode][iFrame].equal(defaultTrans))
  702. {
  703. seq.translationMatters.set(iNode);
  704. break;
  705. }
  706. }
  707. }
  708. }
  709. void TSShapeLoader::setScaleMembership(TSShape::Sequence& seq)
  710. {
  711. Point3F unitScale(1,1,1);
  712. U32 arbitraryScaleCount = 0;
  713. U32 alignedScaleCount = 0;
  714. U32 uniformScaleCount = 0;
  715. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  716. {
  717. // Check if any of the node scales are not the unit scale
  718. for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
  719. {
  720. Point3F& scale = nodeScaleCache[iNode][iFrame];
  721. if (!unitScale.equal(scale))
  722. {
  723. // Determine what type of scale this is
  724. if (!nodeScaleRotCache[iNode][iFrame].isIdentity())
  725. arbitraryScaleCount++;
  726. else if (scale.x != scale.y || scale.y != scale.z)
  727. alignedScaleCount++;
  728. else
  729. uniformScaleCount++;
  730. seq.scaleMatters.set(iNode);
  731. break;
  732. }
  733. }
  734. }
  735. // Only one type of scale is animated
  736. if (arbitraryScaleCount)
  737. seq.flags |= TSShape::ArbitraryScale;
  738. else if (alignedScaleCount)
  739. seq.flags |= TSShape::AlignedScale;
  740. else if (uniformScaleCount)
  741. seq.flags |= TSShape::UniformScale;
  742. }
  743. void TSShapeLoader::setObjectMembership(TSShape::Sequence& seq, const AppSequence* appSeq)
  744. {
  745. seq.visMatters.clearAll(); // object visibility (size = objects.size())
  746. seq.frameMatters.clearAll(); // vert animation (morph) (size = objects.size())
  747. seq.matFrameMatters.clearAll(); // UV animation (size = objects.size())
  748. for (S32 iObject = 0; iObject < shape->objects.size(); iObject++)
  749. {
  750. if (!appMeshes[shape->objects[iObject].startMeshIndex])
  751. continue;
  752. if (appMeshes[shape->objects[iObject].startMeshIndex]->animatesVis(appSeq))
  753. seq.visMatters.set(iObject);
  754. // Morph and UV animation has been deprecated
  755. //if (appMeshes[shape->objects[iObject].startMeshIndex]->animatesFrame(appSeq))
  756. //seq.frameMatters.set(iObject);
  757. //if (appMeshes[shape->objects[iObject].startMeshIndex]->animatesMatFrame(appSeq))
  758. //seq.matFrameMatters.set(iObject);
  759. }
  760. }
  761. void TSShapeLoader::clearNodeTransformCache()
  762. {
  763. // clear out the transform caches
  764. for (S32 i = 0; i < nodeRotCache.size(); i++)
  765. delete [] nodeRotCache[i];
  766. nodeRotCache.clear();
  767. for (S32 i = 0; i < nodeTransCache.size(); i++)
  768. delete [] nodeTransCache[i];
  769. nodeTransCache.clear();
  770. for (S32 i = 0; i < nodeScaleRotCache.size(); i++)
  771. delete [] nodeScaleRotCache[i];
  772. nodeScaleRotCache.clear();
  773. for (S32 i = 0; i < nodeScaleCache.size(); i++)
  774. delete [] nodeScaleCache[i];
  775. nodeScaleCache.clear();
  776. }
  777. void TSShapeLoader::fillNodeTransformCache(TSShape::Sequence& seq, const AppSequence* appSeq)
  778. {
  779. // clear out the transform caches and set it up for this sequence
  780. clearNodeTransformCache();
  781. nodeRotCache.setSize(appNodes.size());
  782. for (S32 i = 0; i < nodeRotCache.size(); i++)
  783. nodeRotCache[i] = new QuatF[seq.numKeyframes];
  784. nodeTransCache.setSize(appNodes.size());
  785. for (S32 i = 0; i < nodeTransCache.size(); i++)
  786. nodeTransCache[i] = new Point3F[seq.numKeyframes];
  787. nodeScaleRotCache.setSize(appNodes.size());
  788. for (S32 i = 0; i < nodeScaleRotCache.size(); i++)
  789. nodeScaleRotCache[i] = new QuatF[seq.numKeyframes];
  790. nodeScaleCache.setSize(appNodes.size());
  791. for (S32 i = 0; i < nodeScaleCache.size(); i++)
  792. nodeScaleCache[i] = new Point3F[seq.numKeyframes];
  793. // get the node transforms for every frame
  794. for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
  795. {
  796. F32 time = appSeq->getStart() + seq.duration * iFrame / getMax(1, seq.numKeyframes - 1);
  797. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  798. {
  799. generateNodeTransform(appNodes[iNode], time, seq.isBlend(), appSeq->getBlendRefTime(),
  800. nodeRotCache[iNode][iFrame], nodeTransCache[iNode][iFrame],
  801. nodeScaleRotCache[iNode][iFrame], nodeScaleCache[iNode][iFrame]);
  802. }
  803. }
  804. }
  805. void TSShapeLoader::addNodeRotation(QuatF& rot, bool defaultVal)
  806. {
  807. Quat16 rot16;
  808. rot16.set(rot);
  809. if (!defaultVal)
  810. shape->nodeRotations.push_back(rot16);
  811. else
  812. shape->defaultRotations.push_back(rot16);
  813. }
  814. void TSShapeLoader::addNodeTranslation(Point3F& trans, bool defaultVal)
  815. {
  816. if (!defaultVal)
  817. shape->nodeTranslations.push_back(trans);
  818. else
  819. shape->defaultTranslations.push_back(trans);
  820. }
  821. void TSShapeLoader::addNodeUniformScale(F32 scale)
  822. {
  823. shape->nodeUniformScales.push_back(scale);
  824. }
  825. void TSShapeLoader::addNodeAlignedScale(Point3F& scale)
  826. {
  827. shape->nodeAlignedScales.push_back(scale);
  828. }
  829. void TSShapeLoader::addNodeArbitraryScale(QuatF& qrot, Point3F& scale)
  830. {
  831. Quat16 rot16;
  832. rot16.set(qrot);
  833. shape->nodeArbitraryScaleRots.push_back(rot16);
  834. shape->nodeArbitraryScaleFactors.push_back(scale);
  835. }
  836. void TSShapeLoader::generateNodeAnimation(TSShape::Sequence& seq)
  837. {
  838. seq.baseRotation = shape->nodeRotations.size();
  839. seq.baseTranslation = shape->nodeTranslations.size();
  840. seq.baseScale = (seq.flags & TSShape::ArbitraryScale) ? shape->nodeArbitraryScaleRots.size() :
  841. (seq.flags & TSShape::AlignedScale) ? shape->nodeAlignedScales.size() :
  842. shape->nodeUniformScales.size();
  843. for (S32 iNode = 0; iNode < appNodes.size(); iNode++)
  844. {
  845. for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
  846. {
  847. if (seq.rotationMatters.test(iNode))
  848. addNodeRotation(nodeRotCache[iNode][iFrame], false);
  849. if (seq.translationMatters.test(iNode))
  850. addNodeTranslation(nodeTransCache[iNode][iFrame], false);
  851. if (seq.scaleMatters.test(iNode))
  852. {
  853. QuatF& rot = nodeScaleRotCache[iNode][iFrame];
  854. Point3F scale = nodeScaleCache[iNode][iFrame];
  855. if (seq.flags & TSShape::ArbitraryScale)
  856. addNodeArbitraryScale(rot, scale);
  857. else if (seq.flags & TSShape::AlignedScale)
  858. addNodeAlignedScale(scale);
  859. else if (seq.flags & TSShape::UniformScale)
  860. addNodeUniformScale((scale.x+scale.y+scale.z)/3.0f);
  861. }
  862. }
  863. }
  864. }
  865. void TSShapeLoader::generateObjectAnimation(TSShape::Sequence& seq, const AppSequence* appSeq)
  866. {
  867. seq.baseObjectState = shape->objectStates.size();
  868. for (S32 iObject = 0; iObject < shape->objects.size(); iObject++)
  869. {
  870. bool visMatters = seq.visMatters.test(iObject);
  871. bool frameMatters = seq.frameMatters.test(iObject);
  872. bool matFrameMatters = seq.matFrameMatters.test(iObject);
  873. if (visMatters || frameMatters || matFrameMatters)
  874. {
  875. for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
  876. {
  877. F32 time = appSeq->getStart() + seq.duration * iFrame / getMax(1, seq.numKeyframes - 1);
  878. generateObjectState(shape->objects[iObject], time, frameMatters, matFrameMatters);
  879. }
  880. }
  881. }
  882. }
  883. void TSShapeLoader::generateGroundAnimation(TSShape::Sequence& seq, const AppSequence* appSeq)
  884. {
  885. seq.firstGroundFrame = shape->groundTranslations.size();
  886. seq.numGroundFrames = 0;
  887. if (!boundsNode)
  888. return;
  889. // Check if the bounds node is animated by this sequence
  890. seq.numGroundFrames = (S32)((seq.duration + 0.25f/AppGroundFrameRate) * AppGroundFrameRate);
  891. seq.flags |= TSShape::MakePath;
  892. // Get ground transform at the start of the sequence
  893. MatrixF invStartMat = boundsNode->getNodeTransform(appSeq->getStart());
  894. zapScale(invStartMat);
  895. invStartMat.inverse();
  896. for (S32 iFrame = 0; iFrame < seq.numGroundFrames; iFrame++)
  897. {
  898. F32 time = appSeq->getStart() + seq.duration * iFrame / getMax(1, seq.numGroundFrames - 1);
  899. // Determine delta bounds node transform at 't'
  900. MatrixF mat = boundsNode->getNodeTransform(time);
  901. zapScale(mat);
  902. mat = invStartMat * mat;
  903. // Add ground transform
  904. Quat16 rotation;
  905. rotation.set(QuatF(mat));
  906. shape->groundTranslations.push_back(mat.getPosition());
  907. shape->groundRotations.push_back(rotation);
  908. }
  909. }
  910. void TSShapeLoader::generateFrameTriggers(TSShape::Sequence& seq, const AppSequence* appSeq)
  911. {
  912. // Initialize triggers
  913. seq.firstTrigger = shape->triggers.size();
  914. seq.numTriggers = appSeq->getNumTriggers();
  915. if (!seq.numTriggers)
  916. return;
  917. seq.flags |= TSShape::MakePath;
  918. // Add triggers
  919. for (S32 iTrigger = 0; iTrigger < seq.numTriggers; iTrigger++)
  920. {
  921. shape->triggers.increment();
  922. appSeq->getTrigger(iTrigger, shape->triggers.last());
  923. }
  924. // Track the triggers that get turned off by this shape...normally, triggers
  925. // aren't turned on/off, just on...if we are a trigger that does both then we
  926. // need to mark ourselves as such so that on/off can become off/on when sequence
  927. // is played in reverse...
  928. U32 offTriggers = 0;
  929. for (S32 iTrigger = 0; iTrigger < seq.numTriggers; iTrigger++)
  930. {
  931. U32 state = shape->triggers[seq.firstTrigger+iTrigger].state;
  932. if ((state & TSShape::Trigger::StateOn) == 0)
  933. offTriggers |= (state & TSShape::Trigger::StateMask);
  934. }
  935. // We now know which states are turned off, set invert on all those (including when turned on)
  936. for (int iTrigger = 0; iTrigger < seq.numTriggers; iTrigger++)
  937. {
  938. if (shape->triggers[seq.firstTrigger + iTrigger].state & offTriggers)
  939. shape->triggers[seq.firstTrigger + iTrigger].state |= TSShape::Trigger::InvertOnReverse;
  940. }
  941. }
  942. //-----------------------------------------------------------------------------
  943. void TSShapeLoader::sortDetails()
  944. {
  945. // Sort objects by: transparency, material index and node index
  946. // Insert NULL meshes where required
  947. for (S32 iSub = 0; iSub < subshapes.size(); iSub++)
  948. {
  949. Vector<S32> validDetails;
  950. shape->getSubShapeDetails(iSub, validDetails);
  951. for (S32 iDet = 0; iDet < validDetails.size(); iDet++)
  952. {
  953. TSShape::Detail &detail = shape->details[validDetails[iDet]];
  954. if (detail.subShapeNum >= 0)
  955. detail.objectDetailNum = iDet;
  956. for (S32 iObj = shape->subShapeFirstObject[iSub];
  957. iObj < (shape->subShapeFirstObject[iSub] + shape->subShapeNumObjects[iSub]);
  958. iObj++)
  959. {
  960. TSShape::Object &object = shape->objects[iObj];
  961. // Insert a NULL mesh for this detail level if required (ie. if the
  962. // object does not already have a mesh with an equal or higher detail)
  963. S32 meshIndex = (iDet < object.numMeshes) ? iDet : object.numMeshes-1;
  964. if (appMeshes[object.startMeshIndex + meshIndex]->detailSize < shape->details[iDet].size)
  965. {
  966. // Add a NULL mesh
  967. appMeshes.insert(object.startMeshIndex + iDet, NULL);
  968. object.numMeshes++;
  969. // Fixup the start index for the other objects
  970. for (S32 k = iObj+1; k < shape->objects.size(); k++)
  971. shape->objects[k].startMeshIndex++;
  972. }
  973. }
  974. }
  975. }
  976. }
  977. // Install into the TSShape, the shape is expected to be empty.
  978. // Data is not copied, the TSShape is modified to point to memory
  979. // managed by this object. This object is also bound to the TSShape
  980. // object and will be deleted when it's deleted.
  981. void TSShapeLoader::install()
  982. {
  983. // Arrays that are filled in by ts shape init, but need
  984. // to be allocated beforehand.
  985. shape->subShapeFirstTranslucentObject.setSize(shape->subShapeFirstObject.size());
  986. // Construct TS sub-meshes
  987. shape->meshes.setSize(appMeshes.size());
  988. for (U32 m = 0; m < appMeshes.size(); m++)
  989. shape->meshes[m] = appMeshes[m] ? appMeshes[m]->constructTSMesh() : NULL;
  990. // Remove empty meshes and objects
  991. for (S32 iObj = shape->objects.size()-1; iObj >= 0; iObj--)
  992. {
  993. TSShape::Object& obj = shape->objects[iObj];
  994. for (S32 iMesh = obj.numMeshes-1; iMesh >= 0; iMesh--)
  995. {
  996. TSMesh *mesh = shape->meshes[obj.startMeshIndex + iMesh];
  997. if (mesh && !mesh->mPrimitives.size())
  998. {
  999. S32 oldMeshCount = obj.numMeshes;
  1000. destructInPlace(mesh);
  1001. shape->removeMeshFromObject(iObj, iMesh);
  1002. iMesh -= (oldMeshCount - obj.numMeshes - 1); // handle when more than one mesh is removed
  1003. }
  1004. }
  1005. if (!obj.numMeshes)
  1006. shape->removeObject(shape->getName(obj.nameIndex));
  1007. }
  1008. // Add a dummy object if needed so the shape loads and renders ok
  1009. if (!shape->details.size())
  1010. {
  1011. shape->addDetail("detail", 2, 0);
  1012. shape->subShapeNumObjects.last() = 1;
  1013. shape->meshes.push_back(NULL);
  1014. shape->objects.increment();
  1015. TSShape::Object& lastObject = shape->objects.last();
  1016. lastObject.nameIndex = shape->addName("dummy");
  1017. lastObject.nodeIndex = 0;
  1018. lastObject.startMeshIndex = 0;
  1019. lastObject.numMeshes = 1;
  1020. shape->objectStates.increment();
  1021. shape->objectStates.last().frameIndex = 0;
  1022. shape->objectStates.last().matFrameIndex = 0;
  1023. shape->objectStates.last().vis = 1.0f;
  1024. }
  1025. // Update smallest visible detail
  1026. shape->mSmallestVisibleDL = -1;
  1027. shape->mSmallestVisibleSize = 999999;
  1028. for (S32 i = 0; i < shape->details.size(); i++)
  1029. {
  1030. if ((shape->details[i].size >= 0) &&
  1031. (shape->details[i].size < shape->mSmallestVisibleSize))
  1032. {
  1033. shape->mSmallestVisibleDL = i;
  1034. shape->mSmallestVisibleSize = shape->details[i].size;
  1035. }
  1036. }
  1037. computeBounds(shape->mBounds);
  1038. if (!shape->mBounds.isValidBox())
  1039. shape->mBounds = Box3F(1.0f);
  1040. shape->mBounds.getCenter(&shape->center);
  1041. shape->mRadius = (shape->mBounds.maxExtents - shape->center).len();
  1042. shape->tubeRadius = shape->mRadius;
  1043. shape->init();
  1044. shape->finalizeEditable();
  1045. }
  1046. void TSShapeLoader::computeBounds(Box3F& bounds)
  1047. {
  1048. // Compute the box that encloses the model geometry
  1049. bounds = Box3F::Invalid;
  1050. // Use bounds node geometry if present
  1051. if ( boundsNode && boundsNode->getNumMesh() )
  1052. {
  1053. for (S32 iMesh = 0; iMesh < boundsNode->getNumMesh(); iMesh++)
  1054. {
  1055. AppMesh* mesh = boundsNode->getMesh( iMesh );
  1056. if ( !mesh )
  1057. continue;
  1058. Box3F meshBounds;
  1059. mesh->computeBounds( meshBounds );
  1060. if ( meshBounds.isValidBox() )
  1061. bounds.intersect( meshBounds );
  1062. }
  1063. }
  1064. else
  1065. {
  1066. // Compute bounds based on all geometry in the model
  1067. for (S32 iMesh = 0; iMesh < appMeshes.size(); iMesh++)
  1068. {
  1069. AppMesh* mesh = appMeshes[iMesh];
  1070. if ( !mesh )
  1071. continue;
  1072. Box3F meshBounds;
  1073. mesh->computeBounds( meshBounds );
  1074. if ( meshBounds.isValidBox() )
  1075. bounds.intersect( meshBounds );
  1076. }
  1077. }
  1078. }
  1079. TSShapeLoader::~TSShapeLoader()
  1080. {
  1081. clearNodeTransformCache();
  1082. // Clear shared AppMaterial list
  1083. for (S32 iMat = 0; iMat < AppMesh::appMaterials.size(); iMat++)
  1084. delete AppMesh::appMaterials[iMat];
  1085. AppMesh::appMaterials.clear();
  1086. // Delete Subshapes
  1087. delete boundsNode;
  1088. for (S32 iSub = 0; iSub < subshapes.size(); iSub++)
  1089. delete subshapes[iSub];
  1090. // Delete AppSequences
  1091. for (S32 iSeq = 0; iSeq < appSequences.size(); iSeq++)
  1092. delete appSequences[iSeq];
  1093. appSequences.clear();
  1094. }
  1095. // Static functions to handle supported formats for shape loader.
  1096. void TSShapeLoader::addFormat(String name, String extension)
  1097. {
  1098. ShapeFormat newFormat;
  1099. newFormat.mName = name;
  1100. newFormat.mExtension = extension;
  1101. smFormats.push_back(newFormat);
  1102. }
  1103. String TSShapeLoader::getFormatExtensions()
  1104. {
  1105. // "*.dsq TAB *.dae TAB
  1106. StringBuilder output;
  1107. for(U32 n = 0; n < smFormats.size(); ++n)
  1108. {
  1109. output.append("*.");
  1110. output.append(smFormats[n].mExtension);
  1111. output.append("\t");
  1112. }
  1113. return output.end();
  1114. }
  1115. String TSShapeLoader::getFormatFilters()
  1116. {
  1117. // "DSQ Files|*.dsq|COLLADA Files|*.dae|"
  1118. StringBuilder output;
  1119. for(U32 n = 0; n < smFormats.size(); ++n)
  1120. {
  1121. output.append(smFormats[n].mName);
  1122. output.append("|*.");
  1123. output.append(smFormats[n].mExtension);
  1124. output.append("|");
  1125. }
  1126. return output.end();
  1127. }
  1128. bool TSShapeLoader::isSupportedFormat(String extension)
  1129. {
  1130. String extLower = String::ToLower(extension);
  1131. for (U32 n = 0; n < smFormats.size(); ++n)
  1132. {
  1133. if (smFormats[n].mExtension.equal(extLower))
  1134. return true;
  1135. }
  1136. return false;
  1137. }
  1138. DefineEngineFunction( getFormatExtensions, const char*, ( ),,
  1139. "Returns a list of supported shape format extensions separated by tabs."
  1140. "Example output: *.dsq TAB *.dae TAB")
  1141. {
  1142. return Con::getReturnBuffer(TSShapeLoader::getFormatExtensions());
  1143. }
  1144. DefineEngineFunction( getFormatFilters, const char*, ( ),,
  1145. "Returns a list of supported shape formats in filter form.\n"
  1146. "Example output: DSQ Files|*.dsq|COLLADA Files|*.dae|")
  1147. {
  1148. return Con::getReturnBuffer(TSShapeLoader::getFormatFilters());
  1149. }
  1150. DefineEngineFunction(isSupportedFormat, bool, (const char* extension), , "")
  1151. {
  1152. return TSShapeLoader::isSupportedFormat(extension);
  1153. }