tsShapeLoader.cpp 45 KB

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