tsShapeLoader.cpp 43 KB

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