2
0

DAESceneEncoder.cpp 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921
  1. #include <algorithm>
  2. #include "DAESceneEncoder.h"
  3. #include "DAEOptimizer.h"
  4. //#define ENCODER_PRINT_TIME 1
  5. using namespace gameplay;
  6. DAESceneEncoder::DAESceneEncoder()
  7. : _collada(NULL), _dom(NULL), file(NULL), _vertexBlendWeights(NULL), _vertexBlendIndices(NULL)
  8. {
  9. }
  10. DAESceneEncoder::~DAESceneEncoder()
  11. {
  12. }
  13. unsigned int getMaxOffset(domInputLocalOffset_Array& inputArray)
  14. {
  15. unsigned int maxOffset = 0;
  16. for (unsigned int i = 0; i < (int)inputArray.getCount(); ++i)
  17. {
  18. if ( inputArray[i]->getOffset() > maxOffset )
  19. {
  20. maxOffset = (unsigned int)inputArray[i]->getOffset();
  21. }
  22. }
  23. return maxOffset;
  24. }
  25. void DAESceneEncoder::optimizeCOLLADA(const EncoderArguments& arguments, domCOLLADA* dom)
  26. {
  27. DAEOptimizer optimizer(dom);
  28. const std::vector<std::string>& groupAnimatioNodeIds = arguments.getGroupAnimationNodeId();
  29. const std::vector<std::string>& groupAnimatioIds = arguments.getGroupAnimationAnimationId();
  30. assert(groupAnimatioNodeIds.size() == groupAnimatioIds.size());
  31. size_t size = groupAnimatioNodeIds.size();
  32. if (size > 0)
  33. {
  34. begin();
  35. for (size_t i = 0; i < size; ++i)
  36. {
  37. optimizer.combineAnimations(groupAnimatioNodeIds[i], groupAnimatioIds[i]);
  38. }
  39. end("groupAnimation");
  40. }
  41. if (arguments.DAEOutputEnabled())
  42. {
  43. if (!_collada->writeTo(arguments.getFilePath(), arguments.getDAEOutputPath()))
  44. {
  45. fprintf(stderr,"Error: COLLADA failed to write the dom for file:%s\n", arguments.getDAEOutputPath().c_str());
  46. }
  47. }
  48. }
  49. void DAESceneEncoder::triangulate(DAE* dae)
  50. {
  51. daeDatabase* dataBase = dae->getDatabase();
  52. int geometryCount = (int)(dataBase->getElementCount(0, "geometry"));
  53. for (int i = 0; i < geometryCount; ++i)
  54. {
  55. // Find the next geometry element.
  56. domGeometry* domGeometry;
  57. dataBase->getElement((daeElement**)&domGeometry, i, 0, "geometry");
  58. // Get the mesh out of the geometry.
  59. const domMeshRef domMesh = domGeometry->getMesh();
  60. if (!domMesh)
  61. {
  62. continue;
  63. }
  64. // Loop over all the polygons elements.
  65. int polygonsCount = (int)(domMesh->getPolygons_array().getCount());
  66. for (int j = 0; j < polygonsCount; ++j)
  67. {
  68. // Get the polygons out of the mesh.
  69. domPolygons* domPolygons = domMesh->getPolygons_array()[j];
  70. // Create the triangles from the polygons
  71. createTrianglesFromPolygons(domMesh, domPolygons);
  72. }
  73. while (domMesh->getPolygons_array().getCount() > 0)
  74. {
  75. domPolygons* domPolygons = domMesh->getPolygons_array().get(0);
  76. // Remove the polygons from the mesh.
  77. domMesh->removeChildElement(domPolygons);
  78. }
  79. // Loop over all the polylist elements.
  80. int polylistCount = (int)(domMesh->getPolylist_array().getCount());
  81. for (int j = 0; j < polylistCount; ++j)
  82. {
  83. // Get the polylist out of the mesh.
  84. domPolylist* domPolylist = domMesh->getPolylist_array()[j];
  85. // Create the triangles from the polygon list
  86. createTrianglesFromPolylist(domMesh, domPolylist);
  87. }
  88. while (domMesh->getPolylist_array().getCount() > 0)
  89. {
  90. domPolylist* domPolylist = domMesh->getPolylist_array().get(0);
  91. // Remove the polylist from the mesh.
  92. domMesh->removeChildElement(domPolylist);
  93. }
  94. }
  95. }
  96. void DAESceneEncoder::createTrianglesFromPolygons(domMesh* domMesh, domPolygons* domPolygons)
  97. {
  98. // Create a new <triangles> inside the mesh that has the same material as the <polygons>.
  99. domTriangles* triangles = (domTriangles*)domMesh->createAndPlace("triangles");
  100. triangles->setCount(0);
  101. triangles->setMaterial(domPolygons->getMaterial());
  102. domP* domTrianglesP = (domP*)triangles->createAndPlace("p");
  103. // Give the new <triangles> the same <_dae> and <parameters> as the old <polygons>.
  104. for (unsigned int i = 0; i < domPolygons->getInput_array().getCount(); ++i)
  105. {
  106. triangles->placeElement(domPolygons->getInput_array()[i]->clone());
  107. }
  108. // Get the number of inputs and primitives for the polygons array.
  109. unsigned int inputCount = getMaxOffset(domPolygons->getInput_array()) + 1;
  110. unsigned int primitiveCount = domPolygons->getP_array().getCount();
  111. // Triangulate all the primitives, this generates all the triangles in a single <p> element.
  112. for (unsigned int j = 0; j < primitiveCount; ++j)
  113. {
  114. // Check the polygons for consistancy (some exported files have had the wrong number of indices).
  115. domP* domCurrentP = domPolygons->getP_array()[j];
  116. int elementCount = (int)(domCurrentP->getValue().getCount());
  117. if ( (elementCount % inputCount) != 0 )
  118. {
  119. // Skip this case.
  120. }
  121. else
  122. {
  123. unsigned int triangleCount = (elementCount / inputCount) - 2;
  124. // Write out the primitives as triangles, just fan using the first element as the base.
  125. unsigned int index = inputCount;
  126. for (unsigned int k = 0; k < triangleCount; ++k)
  127. {
  128. // First vertex.
  129. for (unsigned int l = 0; l < inputCount; ++l)
  130. {
  131. domTrianglesP->getValue().append(domCurrentP->getValue()[l]);
  132. }
  133. // Second vertex.
  134. for (unsigned int l = 0; l < inputCount; ++l)
  135. {
  136. domTrianglesP->getValue().append(domCurrentP->getValue()[index + l]);
  137. }
  138. // Third vertex.
  139. index += inputCount;
  140. for (unsigned int l = 0; l < inputCount; ++l)
  141. {
  142. domTrianglesP->getValue().append(domCurrentP->getValue()[index + l]);
  143. }
  144. triangles->setCount(triangles->getCount() + 1);
  145. }
  146. }
  147. }
  148. }
  149. void DAESceneEncoder::createTrianglesFromPolylist(domMesh* domMesh, domPolylist* domPolylist)
  150. {
  151. // Create a new <triangles> inside the mesh that has the same material as the <polylist>.
  152. domTriangles* triangles = (domTriangles*)domMesh->createAndPlace("triangles");
  153. triangles->setMaterial(domPolylist->getMaterial());
  154. domP* domTrianglesP = (domP*)triangles->createAndPlace("p");
  155. // Give the new <triangles> the same <_dae> and <parameters> as the old <polylist>.
  156. for (int i = 0; i < (int)(domPolylist->getInput_array().getCount()); ++i)
  157. {
  158. triangles->placeElement(domPolylist->getInput_array()[i]->clone());
  159. }
  160. // Get the number of inputs and primitives for the polygons array.
  161. unsigned int inputCount = getMaxOffset(domPolylist->getInput_array()) + 1;
  162. unsigned int primitiveCount = domPolylist->getVcount()->getValue().getCount();
  163. unsigned int offset = 0;
  164. unsigned int trianglesProcessed = 0;
  165. // Triangulate all the primitives, this generates all the triangles in a single <p> element.
  166. for (unsigned int j = 0; j < primitiveCount; ++j)
  167. {
  168. unsigned int triangleCount = (unsigned int)domPolylist->getVcount()->getValue()[j] - 2;
  169. // Write out the primitives as triangles, just fan using the first element as the base.
  170. int index = inputCount;
  171. for (unsigned int k = 0; k < triangleCount; ++k)
  172. {
  173. // First vertex.
  174. for (unsigned int l = 0; l < inputCount; ++l)
  175. {
  176. domTrianglesP->getValue().append(domPolylist->getP()->getValue()[offset + l]);
  177. }
  178. // Second vertex.
  179. for (unsigned int l = 0; l < inputCount; ++l)
  180. {
  181. domTrianglesP->getValue().append(domPolylist->getP()->getValue()[offset + index + l]);
  182. }
  183. // Third vertex.
  184. index += inputCount;
  185. for (unsigned int l = 0; l < inputCount; ++l)
  186. {
  187. domTrianglesP->getValue().append(domPolylist->getP()->getValue()[offset + index + l]);
  188. }
  189. trianglesProcessed++;
  190. }
  191. offset += (unsigned int)domPolylist->getVcount()->getValue()[j] * inputCount;
  192. }
  193. triangles->setCount(trianglesProcessed);
  194. }
  195. void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments& arguments)
  196. {
  197. _begin = std::clock();
  198. const char* nodeId = arguments.getNodeId();
  199. bool text = arguments.textOutputEnabled();
  200. std::string filenameOnly = getFilenameFromFilePath(filepath);
  201. std::string dstPath = filepath.substr(0, filepath.find_last_of('/'));
  202. // Load the collada document
  203. _collada = new DAE();
  204. begin();
  205. _dom = _collada->open(filepath);
  206. end("Open file");
  207. if (!_dom)
  208. {
  209. fprintf(stderr,"Error: COLLADA failed to open file:%s\n", filepath.c_str());
  210. if (_collada)
  211. {
  212. delete _collada;
  213. _collada = NULL;
  214. }
  215. return;
  216. }
  217. // Run collada conditioners
  218. begin();
  219. triangulate(_collada);
  220. end("triangulate");
  221. // Optimize the dom before encoding
  222. optimizeCOLLADA(arguments, _dom);
  223. // Find the <visual_scene> element within the <scene>
  224. const domCOLLADA::domSceneRef& domScene = _dom->getScene();
  225. daeElement* scene = NULL;
  226. if (domScene && domScene->getInstance_visual_scene())
  227. {
  228. scene = domScene->getInstance_visual_scene()->getUrl().getElement();
  229. if (scene->getElementType() != COLLADA_TYPE::VISUAL_SCENE)
  230. {
  231. // This occured once where Maya exported a Node and Scene element with the same ID.
  232. fprintf(stderr,"Error: instance_visual_scene does not reference visual_scene for file:%s\n", filepath.c_str());
  233. return;
  234. }
  235. if (scene)
  236. {
  237. if (nodeId == NULL)
  238. {
  239. // If the -n <node_id> parameter was not passed then write out the entire scene.
  240. begin();
  241. loadScene((domVisual_scene*)scene);
  242. end("load scene");
  243. }
  244. else
  245. {
  246. // Resolve/Search for the node the user specified with the -n <node_id> parameter.
  247. daeSIDResolver resolver(scene, nodeId);
  248. const domNode* node = daeSafeCast<domNode>(resolver.getElement());
  249. if (node)
  250. {
  251. //createNode(node, NULL);
  252. }
  253. else
  254. {
  255. fprintf(stderr,"COLLADA File loaded to the dom, but node was not found with -n%s.\n", nodeId);
  256. }
  257. }
  258. }
  259. else
  260. {
  261. fprintf(stderr,"COLLADA File loaded to the dom, but query for the dom assets failed.\n");
  262. }
  263. }
  264. else
  265. {
  266. fprintf(stderr, "COLLADA File loaded to the dom, but missing <visual_scene>.\n");
  267. }
  268. // The animations should be loaded last
  269. begin();
  270. loadAnimations(_dom);
  271. end("loadAnimations");
  272. std::string dstFilename = dstPath;
  273. dstFilename.append(1, '/');
  274. dstFilename.append(getFilenameNoExt(filenameOnly));
  275. _gamePlayFile.adjust();
  276. if (text)
  277. {
  278. std::string outFile = dstFilename + ".xml";
  279. fprintf(stderr, "Saving debug file: %s\n", outFile.c_str());
  280. _gamePlayFile.saveText(outFile);
  281. }
  282. else
  283. {
  284. std::string outFile = dstFilename + ".gpb";
  285. fprintf(stderr, "Saving binary file: %s\n", outFile.c_str());
  286. begin();
  287. _gamePlayFile.saveBinary(outFile);
  288. end("save binary");
  289. }
  290. // Cleanup
  291. if (file)
  292. {
  293. fclose(file);
  294. }
  295. if (_collada)
  296. {
  297. delete _collada;
  298. _collada = NULL;
  299. }
  300. }
  301. void DAESceneEncoder::loadAnimations(const domCOLLADA* dom)
  302. {
  303. // Call loadAnimation on all <animation> elements in all <library_animations>
  304. const domLibrary_animations_Array& animationLibrarys = dom->getLibrary_animations_array();
  305. size_t animationLibrarysCount = animationLibrarys.getCount();
  306. for (size_t i = 0; i < animationLibrarysCount; ++i)
  307. {
  308. const domLibrary_animationsRef& libraryAnimation = animationLibrarys.get(i);
  309. const domAnimation_Array& animationArray = libraryAnimation->getAnimation_array();
  310. size_t animationCount = animationArray.getCount();
  311. for (size_t j = 0; j < animationCount; ++j)
  312. {
  313. const domAnimationRef& animationRef = animationArray.get(j);
  314. loadAnimation(animationRef);
  315. }
  316. }
  317. }
  318. void DAESceneEncoder::loadAnimation(const domAnimationRef animationRef)
  319. {
  320. // <channel> points to one <sampler>
  321. // <sampler> points to multiple <input> elements
  322. Animation* animation = new Animation();
  323. const char* str = animationRef->getId();
  324. if (str)
  325. {
  326. animation->setId(str);
  327. }
  328. // <channel>
  329. const domChannel_Array& channelArray = animationRef->getChannel_array();
  330. size_t channelArrayCount = channelArray.getCount();
  331. for (size_t i = 0; i < channelArrayCount; ++i)
  332. {
  333. AnimationChannel* animationChannel = new AnimationChannel();
  334. const domChannelRef& channelRef = channelArray.get(i);
  335. // <sampler>
  336. const domSamplerRef sampler = getSampler(channelRef);
  337. assert(sampler);
  338. // <input>
  339. const domInputLocal_Array& inputArray = sampler->getInput_array();
  340. size_t inputArrayCount = inputArray.getCount();
  341. for (size_t j = 0; j < inputArrayCount; ++j)
  342. {
  343. const domInputLocalRef& inputLocal = inputArray.get(j);
  344. // <source>
  345. const domSourceRef source = getSource(inputLocal, animationRef);
  346. std::string semantic = inputLocal->getSemantic();
  347. if (equals(semantic, "INTERPOLATION"))
  348. {
  349. // Interpolation source is a list of strings
  350. loadInterpolation(source, animationChannel);
  351. }
  352. else
  353. {
  354. // The other sources are lists of floats.
  355. std::vector<float> floats;
  356. copyFloats(source->getFloat_array(), &floats);
  357. if (equals(semantic, "INPUT"))
  358. {
  359. // TODO: Ensure param name is TIME?
  360. for (std::vector<float>::iterator k = floats.begin(); k != floats.end(); ++k)
  361. {
  362. // Convert seconds to milliseconds
  363. *k = *k * 1000.0f;
  364. }
  365. animationChannel->setKeyTimes(floats);
  366. }
  367. else if (equals(semantic, "OUTPUT"))
  368. {
  369. animationChannel->setKeyValues(floats);
  370. }
  371. else if (equals(semantic, "IN_TANGENT"))
  372. {
  373. animationChannel->setTangentsIn(floats);
  374. }
  375. else if (equals(semantic, "OUT_TANGENT"))
  376. {
  377. animationChannel->setTangentsOut(floats);
  378. }
  379. }
  380. }
  381. // get target attribute enum value
  382. if (loadTarget(channelRef, animationChannel))
  383. {
  384. animation->add(animationChannel);
  385. }
  386. }
  387. if (animation->getAnimationChannelCount() > 0)
  388. {
  389. _gamePlayFile.addAnimation(animation);
  390. }
  391. else
  392. {
  393. delete animation;
  394. }
  395. }
  396. void DAESceneEncoder::loadInterpolation(const domSourceRef source, AnimationChannel* animationChannel)
  397. {
  398. // COLLADA stores the interpolations as a list of strings while GBP uses unsigned int
  399. std::vector<unsigned int> values;
  400. const domName_arrayRef nameArray = getSourceNameArray(source);
  401. assert(nameArray);
  402. const domListOfNames& names = nameArray->getValue();
  403. size_t count = (size_t)names.getCount();
  404. values.resize(count);
  405. if (count > 0)
  406. {
  407. for (size_t i = 0; i < count; ++i)
  408. {
  409. values[i] = AnimationChannel::getInterpolationType(names.get(i));
  410. }
  411. // If all of the interpolation types are the same then only store the interpolation once
  412. // instead of storing the same type for each key frame.
  413. unsigned int firstType = values[0];
  414. bool allEqual = true;
  415. for (size_t i = 1; i < count; ++i)
  416. {
  417. if (firstType != values[i])
  418. {
  419. allEqual = false;
  420. break;
  421. }
  422. }
  423. if (allEqual)
  424. {
  425. values.resize(1);
  426. }
  427. }
  428. animationChannel->setInterpolations(values);
  429. }
  430. bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChannel* animationChannel)
  431. {
  432. // GamePlay requires that animations are baked. Use "Bake Transforms" in your 3D modeling tool.
  433. // If the target of an animation is not a matrix then an error will be printed.
  434. const static char* TRANSFORM_WARNING_FORMAT = "Warning: Node \"%s\":\n %s %s\n";
  435. const static char* TRANSFORM_MESSAGE = "transform found but not supported.\n Use \"Bake Transforms\" option when exporting.";
  436. unsigned int targetProperty = 0;
  437. DAEChannelTarget channelTarget(channelRef);
  438. const char* targetId = channelTarget.getTargetId().c_str();
  439. // TODO: Do we want to support more than one? If yes then this needs to be fixed.
  440. for (size_t i = 0; i < channelTarget.getTargetAttributeCount(); ++i)
  441. {
  442. std::string prop;
  443. channelTarget.getPropertyName(i, &prop);
  444. daeElement* attributeElement = channelTarget.getTargetAttribute(i);
  445. if (attributeElement)
  446. {
  447. daeInt type = attributeElement->typeID();
  448. if (type == domRotate::ID())
  449. {
  450. printf(TRANSFORM_WARNING_FORMAT, targetId, "Rotate", TRANSFORM_MESSAGE);
  451. return false;
  452. /*
  453. // <rotate>
  454. const domRotate* rotate = daeSafeCast<domRotate>(attributeElement);
  455. if (prop.size() > 0)
  456. {
  457. if (equalsIgnoreCase(prop, "ANGLE"))
  458. {
  459. targetProperty = Transform::ANIMATE_ROTATE;
  460. // get the rotation axis
  461. const domFloat4& f = rotate->getValue();
  462. float x = (float)f.get(0);
  463. float y = (float)f.get(1);
  464. float z = (float)f.get(2);
  465. // Get the angle values that were already read
  466. const std::vector<float>& keyValues = animationChannel->getKeyValues();
  467. size_t size = keyValues.size();
  468. assert(size > 0);
  469. // COLLADA only targeted a single prop but GBP requires all 4 rotate values.
  470. // Convert (ANGLE ANGLE ANGLE) to (X Y Z ANGLE X Y Z ANGLE X Y Z ANGLE)
  471. std::vector<float> floats(size * 4);
  472. // Duplicate rotation axis. We will replace only the angle that COLLADA is targeting.
  473. for (size_t j = 0; j < size; ++j)
  474. {
  475. size_t k = j * 4;
  476. floats[k+0] = x;
  477. floats[k+1] = y;
  478. floats[k+2] = z;
  479. floats[k+3] = keyValues[j]; // angle
  480. }
  481. animationChannel->setKeyValues(floats);
  482. }
  483. }
  484. */
  485. }
  486. else if (type == domScale::ID())
  487. {
  488. printf(TRANSFORM_WARNING_FORMAT, targetId, "Scale", TRANSFORM_MESSAGE);
  489. return false;
  490. /*
  491. // <scale>
  492. //const domScale* scale = daeSafeCast<domScale>(attributeElement);
  493. if (equalsIgnoreCase(prop, "X"))
  494. {
  495. targetProperty = Transform::ANIMATE_SCALE_X;
  496. }
  497. else if (equalsIgnoreCase(prop, "Y"))
  498. {
  499. targetProperty = Transform::ANIMATE_SCALE_Y;
  500. }
  501. else if (equalsIgnoreCase(prop, "Z"))
  502. {
  503. targetProperty = Transform::ANIMATE_SCALE_Z;
  504. }
  505. else
  506. {
  507. targetProperty = Transform::ANIMATE_SCALE;
  508. }
  509. */
  510. }
  511. else if (type == domTranslate::ID())
  512. {
  513. printf(TRANSFORM_WARNING_FORMAT, targetId, "Translate", TRANSFORM_MESSAGE);
  514. return false;
  515. /*
  516. // <translate>
  517. //const domTranslate* translate = daeSafeCast<domTranslate>(attributeElement);
  518. if (equalsIgnoreCase(prop, "X"))
  519. {
  520. targetProperty = Transform::ANIMATE_TRANSLATE_X;
  521. }
  522. else if (equalsIgnoreCase(prop, "Y"))
  523. {
  524. targetProperty = Transform::ANIMATE_TRANSLATE_Y;
  525. }
  526. else if (equalsIgnoreCase(prop, "Z"))
  527. {
  528. targetProperty = Transform::ANIMATE_TRANSLATE_Z;
  529. }
  530. else
  531. {
  532. targetProperty = Transform::ANIMATE_TRANSLATE;
  533. }
  534. */
  535. }
  536. else if (type == domMatrix::ID())
  537. {
  538. // If the animation is targetting a matrix then convert it into
  539. // a scale, rotate, translate animation by decomposing the matrix.
  540. targetProperty = Transform::ANIMATE_SCALE_ROTATE_TRANSLATE;
  541. const std::vector<float>& keyValues = animationChannel->getKeyValues();
  542. assert(keyValues.size() % 16 == 0);
  543. // The matrix was 16 floats and the new values will be 10 floats
  544. size_t newSize = keyValues.size() / 16 * 10;
  545. std::vector<float> floats(newSize);
  546. size_t matrixCount = keyValues.size() / 16;
  547. for (size_t i = 0; i < matrixCount; ++i)
  548. {
  549. size_t j = i * 16;
  550. // COLLADA used row-major but the Matrix class uses column-major
  551. Matrix matrix(
  552. keyValues[j+0], keyValues[j+4], keyValues[j+8], keyValues[j+12],
  553. keyValues[j+1], keyValues[j+5], keyValues[j+9], keyValues[j+13],
  554. keyValues[j+2], keyValues[j+6], keyValues[j+10], keyValues[j+14],
  555. keyValues[j+3], keyValues[j+7], keyValues[j+11], keyValues[j+15]);
  556. Vector3 scale;
  557. Quaternion rotation;
  558. Vector3 translation;
  559. matrix.decompose(&scale, &rotation, &translation);
  560. size_t k = i * 10;
  561. floats[k+0] = scale.x;
  562. floats[k+1] = scale.y;
  563. floats[k+2] = scale.z;
  564. floats[k+3] = rotation.x;
  565. floats[k+4] = rotation.y;
  566. floats[k+5] = rotation.z;
  567. floats[k+6] = rotation.w;
  568. floats[k+7] = translation.x;
  569. floats[k+8] = translation.y;
  570. floats[k+9] = translation.z;
  571. }
  572. animationChannel->setKeyValues(floats);
  573. }
  574. }
  575. }
  576. animationChannel->setTargetAttribute(targetProperty);
  577. animationChannel->setTargetId(channelTarget.getTargetId());
  578. //animationChannel->removeDuplicates();
  579. return true;
  580. }
  581. void DAESceneEncoder::begin()
  582. {
  583. #ifdef ENCODER_PRINT_TIME
  584. _begin = std::clock();
  585. #endif
  586. }
  587. void DAESceneEncoder::end(const char* str)
  588. {
  589. #ifdef ENCODER_PRINT_TIME
  590. clock_t time = std::clock() - _begin;
  591. fprintf(stderr,"%5d %s\n", time, str);
  592. #endif
  593. }
  594. void DAESceneEncoder::copyFloats(const domFloat_array* source, std::vector<float>* target)
  595. {
  596. std::vector<float>& t = *target;
  597. size_t count = (size_t)source->getCount();
  598. t.resize(count);
  599. const domListOfFloats& listOfFloats = source->getValue();
  600. for (size_t i = 0; i < count; ++i)
  601. {
  602. t[i] = (float)listOfFloats.get(i);
  603. }
  604. }
  605. void DAESceneEncoder::loadScene(const domVisual_scene* visualScene)
  606. {
  607. Scene* scene = new Scene();
  608. const domNode_Array& nodes = visualScene->getNode_array();
  609. scene->setId(visualScene->getId());
  610. size_t childCount = nodes.getCount();
  611. for (size_t i = 0; i < childCount; ++i)
  612. {
  613. scene->add(loadNode(nodes[i], NULL));
  614. }
  615. Node* activeCameraNode = findSceneActiveCameraNode(visualScene, scene);
  616. if (activeCameraNode)
  617. {
  618. scene->setActiveCameraNode(activeCameraNode);
  619. }
  620. _gamePlayFile.addScene(scene);
  621. }
  622. Node* DAESceneEncoder::findSceneActiveCameraNode(const domVisual_scene* visualScene, Scene* scene)
  623. {
  624. // Loops through each evaluate_scene's render until an active camera node is found.
  625. // Returns the first one found.
  626. // Find the active camera
  627. const domVisual_scene::domEvaluate_scene_Array& evaluateScenes = visualScene->getEvaluate_scene_array();
  628. size_t evaluateSceneCount = evaluateScenes.getCount();
  629. for (size_t i = 0; i < evaluateSceneCount; ++i)
  630. {
  631. const domVisual_scene::domEvaluate_scene::domRender_Array& renders = evaluateScenes[i]->getRender_array();
  632. size_t renderCount = renders.getCount();
  633. for (size_t j = 0; j < renderCount; ++j)
  634. {
  635. xsAnyURI cameraNodeURI = renders[i]->getCamera_node();
  636. domNode* nodeRef = daeSafeCast<domNode>(cameraNodeURI.getElement());
  637. if (nodeRef)
  638. {
  639. std::string id = nodeRef->getId();
  640. Node* node = _gamePlayFile.getNode(id.c_str());
  641. if (node)
  642. {
  643. return node;
  644. }
  645. }
  646. }
  647. }
  648. // Find the first node in the scene that contains a camera.
  649. return scene->getFirstCameraNode();
  650. }
  651. Node* DAESceneEncoder::loadNode(domNode* n, Node* parent)
  652. {
  653. Node* node = NULL;
  654. // Check if this node has already been loaded
  655. const char* id = n->getID();
  656. if (id && strlen(id) > 0)
  657. {
  658. node = _gamePlayFile.getNode(n->getID());
  659. if (node)
  660. {
  661. return node;
  662. }
  663. }
  664. // Load the node
  665. node = new Node();
  666. if (parent)
  667. {
  668. parent->addChild(node);
  669. }
  670. if (n->getType() == NODETYPE_JOINT)
  671. {
  672. node->setIsJoint(true);
  673. }
  674. // Set node id
  675. node->setId(n->getId());
  676. // If this node has an id then add it to the ref table
  677. _gamePlayFile.addNode(node);
  678. transformNode(n, node);
  679. loadControllerInstance(n, node);
  680. loadCameraInstance(n, node);
  681. loadLightInstance(n, node);
  682. loadGeometryInstance(n, node);
  683. // Load child nodes
  684. const domNode_Array& childNodes = n->getNode_array();
  685. size_t childCount = childNodes.getCount();
  686. for (size_t i = 0; i < childCount; ++i)
  687. {
  688. loadNode(childNodes.get(i), node);
  689. }
  690. return node;
  691. }
  692. void DAESceneEncoder::transformNode(domNode* domNode, Node* node)
  693. {
  694. // Apply the transform.
  695. // Note that we only honor the first matrix transform specified for the DOM node.
  696. const domMatrix_Array& matrixArray = domNode->getMatrix_array();
  697. if (matrixArray.getCount() > 0)
  698. {
  699. const domMatrixRef& matrix = matrixArray.get(0);
  700. if (!matrix)
  701. {
  702. return;
  703. }
  704. const domFloat4x4& tx = matrix->getValue();
  705. float transform[] = {(float)tx.get(0), (float)tx.get(4), (float)tx.get(8), (float)tx.get(12),
  706. (float)tx.get(1), (float)tx.get(5), (float)tx.get(9), (float)tx.get(13),
  707. (float)tx.get(2), (float)tx.get(6), (float)tx.get(10), (float)tx.get(14),
  708. (float)tx.get(3), (float)tx.get(7), (float)tx.get(11), (float)tx.get(15)};
  709. node->setTransformMatrix(transform);
  710. }
  711. else
  712. {
  713. Matrix transform;
  714. calcTransform(domNode, transform);
  715. node->setTransformMatrix(transform.m);
  716. }
  717. // TODO: Handle transforming by other types (SRT, etc) (see "Node" child elements spec)
  718. /*Vector3 scale;
  719. Quaternion rotation;
  720. Vector3 translation;
  721. localTransform.Decompose(&scale, &rotation, &translation);
  722. node->SetScale(scale);
  723. node->SetRotation(rotation);
  724. node->SetTranslation(translation);*/
  725. }
  726. void DAESceneEncoder::calcTransform(domNode* domNode, Matrix& dstTransform)
  727. {
  728. daeTArray<daeSmartRef<daeElement> > children;
  729. domNode->getChildren(children);
  730. size_t childCount = children.getCount();
  731. for (size_t i = 0; i < childCount; ++i)
  732. {
  733. daeElementRef childElement = children[i];
  734. switch (childElement->getElementType())
  735. {
  736. case COLLADA_TYPE::TRANSLATE:
  737. {
  738. domTranslateRef translateNode = daeSafeCast<domTranslate>(childElement);
  739. float x = (float)translateNode->getValue().get(0);
  740. float y = (float)translateNode->getValue().get(1);
  741. float z = (float)translateNode->getValue().get(2);
  742. dstTransform.translate(x, y, z);
  743. break;
  744. }
  745. case COLLADA_TYPE::ROTATE:
  746. {
  747. domRotateRef rotateNode = daeSafeCast<domRotate>(childElement);
  748. float x = (float)rotateNode->getValue().get(0);
  749. float y = (float)rotateNode->getValue().get(1);
  750. float z = (float)rotateNode->getValue().get(2);
  751. float angle = MATH_DEG_TO_RAD((float)rotateNode->getValue().get(3)); // COLLADA uses degrees, gameplay uses radians
  752. if (x == 1.0f && y == 0.0f && z == 0.0f)
  753. {
  754. dstTransform.rotateX(angle);
  755. }
  756. else if (x == 0.0f && y == 1.0f && z == 0.0f)
  757. {
  758. dstTransform.rotateY(angle);
  759. }
  760. else if (x == 0.0f && y == 0.0f && z == 1.0f)
  761. {
  762. dstTransform.rotateZ(angle);
  763. }
  764. else
  765. {
  766. dstTransform.rotate(x, y, z, angle);
  767. }
  768. break;
  769. }
  770. case COLLADA_TYPE::SCALE:
  771. {
  772. domScaleRef scaleNode = daeSafeCast<domScale>(childElement);
  773. float x = (float)scaleNode->getValue().get(0);
  774. float y = (float)scaleNode->getValue().get(1);
  775. float z = (float)scaleNode->getValue().get(2);
  776. dstTransform.scale(x, y, z);
  777. break;
  778. }
  779. case COLLADA_TYPE::SKEW:
  780. warning("Skew transform found but not supported.");
  781. break;
  782. case COLLADA_TYPE::LOOKAT:
  783. warning("Lookat transform found but not supported.");
  784. break;
  785. default:
  786. break;
  787. }
  788. }
  789. }
  790. void DAESceneEncoder::loadCameraInstance(const domNode* n, Node* node)
  791. {
  792. // Does this node have any camera instances?
  793. const domInstance_camera_Array& instanceCameras = n->getInstance_camera_array();
  794. size_t instanceCameraCount = instanceCameras.getCount();
  795. for (size_t i = 0; i < instanceCameraCount; ++i)
  796. {
  797. // Get the camrea object
  798. const domInstance_camera* cameraInstanceRef = instanceCameras.get(i);
  799. xsAnyURI cameraURI = cameraInstanceRef->getUrl();
  800. domCamera* cameraRef = daeSafeCast<domCamera>(cameraURI.getElement());
  801. if (cameraRef)
  802. {
  803. CameraInstance* cameraInstance = loadCamera(cameraRef);
  804. if (cameraInstance)
  805. {
  806. node->setCameraInstance(cameraInstance);
  807. }
  808. }
  809. else
  810. {
  811. // warning
  812. }
  813. }
  814. }
  815. void DAESceneEncoder::loadLightInstance(const domNode* n, Node* node)
  816. {
  817. // Does this node have any light instances?
  818. const domInstance_light_Array& instanceLights = n->getInstance_light_array();
  819. size_t instanceLightCount = instanceLights.getCount();
  820. for (size_t i = 0; i < instanceLightCount; ++i)
  821. {
  822. // Get the camrea object
  823. const domInstance_light* lightInstanceRef = instanceLights.get(i);
  824. xsAnyURI lightURI = lightInstanceRef->getUrl();
  825. domLight* lightRef = daeSafeCast<domLight>(lightURI.getElement());
  826. if (lightRef)
  827. {
  828. LightInstance* lightInstance = loadLight(lightRef);
  829. if (lightInstance)
  830. {
  831. node->setLightInstance(lightInstance);
  832. }
  833. }
  834. else
  835. {
  836. // warning
  837. }
  838. }
  839. }
  840. void DAESceneEncoder::loadGeometryInstance(const domNode* n, Node* node)
  841. {
  842. // Does this node have any geometry instances?
  843. const domInstance_geometry_Array& instanceGeometries = n->getInstance_geometry_array();
  844. size_t instanceGeometryCount = instanceGeometries.getCount();
  845. for (size_t i = 0; i < instanceGeometryCount; ++i)
  846. {
  847. // Get the geometry object
  848. const domInstance_geometryRef geometryInstanceRef = instanceGeometries.get(i);
  849. xsAnyURI geometryURI = geometryInstanceRef->getUrl();
  850. domGeometry* geometry = daeSafeCast<domGeometry>(geometryURI.getElement());
  851. // Load the model from this geometry
  852. if (geometry)
  853. {
  854. Model* model = loadGeometry(geometry, geometryInstanceRef->getBind_material());
  855. if (model)
  856. {
  857. node->setModel(model);
  858. }
  859. }
  860. else
  861. {
  862. warning(std::string("Failed to resolve geometry url: ") + geometryURI.getURI());
  863. }
  864. }
  865. }
  866. void DAESceneEncoder::loadControllerInstance(const domNode* n, Node* node)
  867. {
  868. // Does this node have any controller instances?
  869. const domInstance_controller_Array& instanceControllers = n->getInstance_controller_array();
  870. size_t instanceControllerCount = instanceControllers.getCount();
  871. for (size_t i = 0; i < instanceControllerCount; ++i)
  872. {
  873. const domInstance_controllerRef instanceControllerRef = instanceControllers.get(i);
  874. xsAnyURI controllerURI = instanceControllerRef->getUrl();
  875. domController* controllerRef = daeSafeCast<domController>(controllerURI.getElement());
  876. if (controllerRef)
  877. {
  878. const domSkin* skinElement = controllerRef->getSkin();
  879. if (skinElement)
  880. {
  881. Model* model = loadSkin(skinElement);
  882. if (model)
  883. {
  884. domInstance_controller::domSkeleton_Array& skeletons = instanceControllerRef->getSkeleton_array();
  885. if (skeletons.getCount() == 0)
  886. {
  887. warning("No skeletons found for instance controller: ");
  888. delete model;
  889. continue;
  890. }
  891. // Load the skeleton for this skin
  892. domInstance_controller::domSkeletonRef skeleton = getSkeleton(instanceControllerRef);
  893. assert(skeleton);
  894. loadSkeleton(skeleton, model->getSkin());
  895. node->setModel(model);
  896. }
  897. }
  898. }
  899. else
  900. {
  901. // warning
  902. }
  903. _jointLookupTable.clear();
  904. _jointInverseBindPoseMatrices.clear();
  905. }
  906. }
  907. CameraInstance* DAESceneEncoder::loadCamera(const domCamera* cameraRef)
  908. {
  909. ///////////////////////////// CAMERA
  910. // check if camera is already added to gamePlayFile
  911. const char* id = cameraRef->getId();
  912. Camera* camera = _gamePlayFile.getCamera(id);
  913. if (camera == NULL)
  914. {
  915. camera = new Camera();
  916. camera->setId(id);
  917. // Optics
  918. const domCamera::domOpticsRef opticsRef = cameraRef->getOptics();
  919. if (opticsRef.cast())
  920. {
  921. const domCamera::domOptics::domTechnique_commonRef techRef = opticsRef->getTechnique_common();
  922. // Orthographics
  923. const domCamera::domOptics::domTechnique_common::domOrthographicRef orthographicRef = techRef->getOrthographic();
  924. if (orthographicRef.cast())
  925. {
  926. camera->setOrthographic();
  927. camera->setAspectRatio((float)orthographicRef->getAspect_ratio()->getValue());
  928. camera->setNearPlane((float)orthographicRef->getZnear()->getValue());
  929. camera->setFarPlane((float)orthographicRef->getZfar()->getValue());
  930. const domTargetableFloatRef xmag = orthographicRef->getXmag();
  931. const domTargetableFloatRef ymag = orthographicRef->getYmag();
  932. // Viewport width
  933. if (xmag.cast())
  934. {
  935. camera->setViewportWidth((float)xmag->getValue());
  936. }
  937. // Viewport height
  938. if (ymag.cast())
  939. {
  940. camera->setViewportHeight((float)ymag->getValue());
  941. }
  942. // TODO: Viewport x and y?
  943. }
  944. // Perspective
  945. const domCamera::domOptics::domTechnique_common::domPerspectiveRef perspectiveRef = techRef->getPerspective();
  946. if (perspectiveRef.cast())
  947. {
  948. camera->setPerspective();
  949. camera->setNearPlane((float)perspectiveRef->getZnear()->getValue());
  950. camera->setFarPlane((float)perspectiveRef->getZfar()->getValue());
  951. float aspectRatio = -1.0f;
  952. if (perspectiveRef->getAspect_ratio().cast())
  953. {
  954. aspectRatio = (float)perspectiveRef->getAspect_ratio()->getValue();
  955. camera->setAspectRatio(aspectRatio);
  956. }
  957. if (perspectiveRef->getYfov().cast())
  958. {
  959. camera->setFieldOfView((float)perspectiveRef->getYfov()->getValue());
  960. }
  961. else if (perspectiveRef->getXfov().cast() && aspectRatio > 0.0f)
  962. {
  963. // The gameplaybinary stores the yfov but collada might have specified
  964. // an xfov and an aspect ratio. So use those to calculate the yfov.
  965. float xfov = (float)perspectiveRef->getXfov()->getValue();
  966. float yfov = xfov / aspectRatio;
  967. camera->setFieldOfView(yfov);
  968. }
  969. }
  970. }
  971. _gamePlayFile.addCamera(camera);
  972. }
  973. CameraInstance* cameraInstance = new CameraInstance();
  974. cameraInstance->setCamera(camera);
  975. return cameraInstance;
  976. }
  977. LightInstance* DAESceneEncoder::loadLight(const domLight* lightRef)
  978. {
  979. ///////////////////////////// LIGHT
  980. // check if light is already added to gamePlayFile
  981. const char* id = lightRef->getId();
  982. Light* light = _gamePlayFile.getLight(id);
  983. if (light == NULL)
  984. {
  985. light = new Light();
  986. light->setId(lightRef->getId());
  987. const domLight::domTechnique_commonRef techRef = lightRef->getTechnique_common();
  988. // Ambient light
  989. {
  990. const domLight::domTechnique_common::domAmbientRef ambientRef = techRef->getAmbient();
  991. if (ambientRef.cast())
  992. {
  993. light->setAmbientLight();
  994. // color
  995. const domTargetableFloat3Ref float3Ref = ambientRef->getColor();
  996. const domFloat3& color3 = float3Ref->getValue();
  997. light->setColor((float)color3.get(0), (float)color3.get(1), (float)color3.get(2));
  998. }
  999. }
  1000. // Directional light
  1001. {
  1002. const domLight::domTechnique_common::domDirectionalRef direcitonalRef = techRef->getDirectional();
  1003. if (direcitonalRef.cast())
  1004. {
  1005. light->setDirectionalLight();
  1006. // color
  1007. const domTargetableFloat3Ref float3Ref = direcitonalRef->getColor();
  1008. const domFloat3& color3 = float3Ref->getValue();
  1009. light->setColor((float)color3.get(0), (float)color3.get(1), (float)color3.get(2));
  1010. }
  1011. }
  1012. // Spot light
  1013. {
  1014. const domLight::domTechnique_common::domSpotRef spotRef = techRef->getSpot();
  1015. if (spotRef.cast())
  1016. {
  1017. light->setSpotLight();
  1018. // color
  1019. const domTargetableFloat3Ref float3Ref = spotRef->getColor();
  1020. const domFloat3& color3 = float3Ref->getValue();
  1021. light->setColor((float)color3.get(0), (float)color3.get(1), (float)color3.get(2));
  1022. const domTargetableFloatRef& constAtt = spotRef->getConstant_attenuation();
  1023. if (constAtt.cast())
  1024. {
  1025. light->setConstantAttenuation((float)constAtt->getValue());
  1026. }
  1027. const domTargetableFloatRef& linearAtt = spotRef->getLinear_attenuation();
  1028. if (linearAtt.cast())
  1029. {
  1030. light->setLinearAttenuation((float)linearAtt->getValue());
  1031. }
  1032. const domTargetableFloatRef& quadAtt = spotRef->getQuadratic_attenuation();
  1033. if (quadAtt.cast())
  1034. {
  1035. light->setQuadraticAttenuation((float)quadAtt->getValue());
  1036. }
  1037. const domTargetableFloatRef& falloffAngle = spotRef->getFalloff_angle();
  1038. if (falloffAngle.cast())
  1039. {
  1040. light->setFalloffAngle((float)falloffAngle->getValue());
  1041. }
  1042. const domTargetableFloatRef& falloffExp = spotRef->getFalloff_exponent();
  1043. if (falloffExp.cast())
  1044. {
  1045. light->setFalloffExponent((float)falloffExp->getValue());
  1046. }
  1047. }
  1048. }
  1049. // Point light
  1050. {
  1051. const domLight::domTechnique_common::domPointRef pointRef = techRef->getPoint();
  1052. if (pointRef.cast())
  1053. {
  1054. light->setPointLight();
  1055. // color
  1056. const domTargetableFloat3Ref float3Ref = pointRef->getColor();
  1057. const domFloat3& color3 = float3Ref->getValue();
  1058. light->setColor((float)color3.get(0), (float)color3.get(1), (float)color3.get(2));
  1059. const domTargetableFloatRef& constAtt = pointRef->getConstant_attenuation();
  1060. if (constAtt.cast())
  1061. {
  1062. light->setConstantAttenuation((float)constAtt->getValue());
  1063. }
  1064. const domTargetableFloatRef& linearAtt = pointRef->getLinear_attenuation();
  1065. if (linearAtt.cast())
  1066. {
  1067. light->setLinearAttenuation((float)linearAtt->getValue());
  1068. }
  1069. const domTargetableFloatRef& quadAtt = pointRef->getQuadratic_attenuation();
  1070. if (quadAtt.cast())
  1071. {
  1072. light->setQuadraticAttenuation((float)quadAtt->getValue());
  1073. }
  1074. }
  1075. }
  1076. _gamePlayFile.addLight(light);
  1077. }
  1078. LightInstance* lightInstance = new LightInstance();
  1079. lightInstance->setLight(light);
  1080. return lightInstance;
  1081. }
  1082. void DAESceneEncoder::loadSkeleton(domInstance_controller::domSkeleton* skeletonElement, MeshSkin* skin)
  1083. {
  1084. xsAnyURI skeletonUri = skeletonElement->getValue();
  1085. daeString skeletonId = skeletonUri.getID();
  1086. daeSIDResolver resolver(skeletonUri.getElement(), skeletonId);
  1087. domNode* rootNode = daeSafeCast<domNode>(resolver.getElement());
  1088. // Get the lookup scene id (sid) and joint index.
  1089. std::string id = std::string(skeletonId);
  1090. // Has the skeleton (root joint) been loaded yet?
  1091. Node* skeleton = (Node*)_gamePlayFile.getFromRefTable(id);
  1092. // The skeleton node is not loaded yet, so let's load it now
  1093. if (skeleton == NULL)
  1094. {
  1095. // Find the top most parent of rootNode that has not yet been loaded
  1096. domNode* topLevelParent = rootNode;
  1097. while (
  1098. topLevelParent->getParent() &&
  1099. topLevelParent->getParent()->getElementType() == COLLADA_TYPE::NODE &&
  1100. _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) == NULL)
  1101. {
  1102. topLevelParent = (domNode*)topLevelParent->getParent();
  1103. }
  1104. // Is the parent of this node loaded yet?
  1105. Node* parentNode = NULL;
  1106. if (topLevelParent->getParent() &&
  1107. topLevelParent->getParent()->getElementType() == COLLADA_TYPE::NODE &&
  1108. _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) != NULL)
  1109. {
  1110. parentNode = (Node*)_gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID());
  1111. }
  1112. // Finally, load the node hierarchy that includes the skeleton
  1113. skeleton = loadNode(topLevelParent, parentNode);
  1114. }
  1115. if (skeleton == NULL)
  1116. {
  1117. // This shouldn't really happen..
  1118. skeleton = new Node();
  1119. skeleton->setId(id);
  1120. _gamePlayFile.addNode(skeleton);
  1121. }
  1122. // Resolve and set joints array for skin
  1123. std::list<Node*> _joints;
  1124. const std::list<std::string>& jointNames = skin->getJointNames();
  1125. for (std::list<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); ++i)
  1126. {
  1127. Object* obj = _gamePlayFile.getFromRefTable(*i);
  1128. if (obj)
  1129. {
  1130. Node* node = (Node*)obj;
  1131. _joints.push_back(node);
  1132. }
  1133. }
  1134. skin->setJoints(_joints);
  1135. }
  1136. Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
  1137. {
  1138. ///////////////////////////// SKIN
  1139. Model* model = new Model();
  1140. MeshSkin* skin = new MeshSkin();
  1141. // Bind Shape Matrix
  1142. const domSkin::domBind_shape_matrix* bindShapeMatrix = skinElement->getBind_shape_matrix();
  1143. if (bindShapeMatrix)
  1144. {
  1145. const domFloat4x4& m = bindShapeMatrix->getValue();
  1146. float transform[] = {(float)m.get(0), (float)m.get(4), (float)m.get(8), (float)m.get(12),
  1147. (float)m.get(1), (float)m.get(5), (float)m.get(9), (float)m.get(13),
  1148. (float)m.get(2), (float)m.get(6), (float)m.get(10), (float)m.get(14),
  1149. (float)m.get(3), (float)m.get(7), (float)m.get(11), (float)m.get(15)};
  1150. skin->setBindShape(transform);
  1151. }
  1152. // Read and set our joints
  1153. domSkin::domJointsRef _joints = skinElement->getJoints();
  1154. domInputLocal_Array& jointInputs = _joints->getInput_array();
  1155. // Process "JOINT" input semantic first (we need to do this to set the joint count)
  1156. unsigned int jointCount = 0;
  1157. for (unsigned int i = 0; i < jointInputs.getCount(); ++i)
  1158. {
  1159. domInputLocalRef input = jointInputs.get(i);
  1160. std::string inputSemantic = std::string(input->getSemantic());
  1161. domURIFragmentType* sourceURI = &input->getSource();
  1162. sourceURI->resolveElement();
  1163. const domSourceRef source = (domSource*)(daeElement*)sourceURI->getElement();
  1164. if (equals(inputSemantic, "JOINT"))
  1165. {
  1166. // Get the joint Ids's
  1167. std::list<std::string> list;
  1168. getJointNames(source, list);
  1169. // Go through the joint list and conver them from sid to id because the sid information is
  1170. // lost when converting to the gameplay binary format.
  1171. for (std::list<std::string>::iterator i = list.begin(); i != list.end(); ++i)
  1172. {
  1173. daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
  1174. daeElement* element = resolver.getElement();
  1175. if (element && element->getElementType() == COLLADA_TYPE::NODE)
  1176. {
  1177. domNodeRef node = daeSafeCast<domNode>(element);
  1178. const char* nodeId = node->getId();
  1179. if (nodeId && !equals(*i, nodeId))
  1180. {
  1181. *i = nodeId;
  1182. }
  1183. }
  1184. }
  1185. // Get the joint count and set the capacities for both the
  1186. jointCount = list.size();
  1187. _jointInverseBindPoseMatrices.reserve(jointCount);
  1188. unsigned int j = 0;
  1189. for (std::list<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
  1190. {
  1191. _jointLookupTable[*i] = j++;
  1192. }
  1193. skin->setJointNames(list);
  1194. }
  1195. }
  1196. // Make sure we have some joints
  1197. if (jointCount == 0)
  1198. {
  1199. warning("No joints found for skin: ");
  1200. return NULL;
  1201. }
  1202. // Process "INV_BIND_MATRIX" next
  1203. for (unsigned int i = 0; i < jointInputs.getCount(); ++i)
  1204. {
  1205. domInputLocalRef input = jointInputs.get(i);
  1206. std::string inputSemantic = std::string(input->getSemantic());
  1207. domURIFragmentType* sourceURI = &input->getSource();
  1208. sourceURI->resolveElement();
  1209. domSource* source = (domSource*)(daeElement*)sourceURI->getElement();
  1210. if (equals(inputSemantic, "INV_BIND_MATRIX"))
  1211. {
  1212. domListOfFloats& matrixFloats = source->getFloat_array()->getValue();
  1213. //unsigned int matrixFloatsCount = (unsigned int)source->getFloat_array()->getCount();
  1214. unsigned int jointIndex = 0;
  1215. for (unsigned int j = 0; j < jointCount; ++j)
  1216. {
  1217. Matrix matrix((float)matrixFloats.get(jointIndex + 0), (float)matrixFloats.get(jointIndex + 4), (float)matrixFloats.get(jointIndex + 8), (float)matrixFloats.get(jointIndex + 12),
  1218. (float)matrixFloats.get(jointIndex + 1), (float)matrixFloats.get(jointIndex + 5), (float)matrixFloats.get(jointIndex + 9), (float)matrixFloats.get(jointIndex + 13),
  1219. (float)matrixFloats.get(jointIndex + 2), (float)matrixFloats.get(jointIndex + 6), (float)matrixFloats.get(jointIndex + 10), (float)matrixFloats.get(jointIndex + 14),
  1220. (float)matrixFloats.get(jointIndex + 3), (float)matrixFloats.get(jointIndex + 7), (float)matrixFloats.get(jointIndex + 11), (float)matrixFloats.get(jointIndex + 15));
  1221. _jointInverseBindPoseMatrices.push_back(matrix);
  1222. jointIndex += 16;
  1223. }
  1224. }
  1225. }
  1226. skin->setBindPoses(_jointInverseBindPoseMatrices);
  1227. // Get the vertex weights inputs
  1228. domSkin::domVertex_weights* vertexWeights = skinElement->getVertex_weights();
  1229. domInputLocalOffset_Array& vertexWeightsInputs = vertexWeights->getInput_array();
  1230. unsigned int vertexWeightsCount = (unsigned int)vertexWeights->getCount();
  1231. domListOfFloats jointWeights;
  1232. for (unsigned int i = 0; i < jointInputs.getCount(); ++i)
  1233. {
  1234. domInputLocalOffsetRef input = vertexWeightsInputs.get(i);
  1235. std::string inputSemantic = std::string(input->getSemantic());
  1236. domURIFragmentType* sourceURI = &input->getSource();
  1237. sourceURI->resolveElement();
  1238. domSource* source = (domSource*)(daeElement*)sourceURI->getElement();
  1239. if (equals(inputSemantic, "WEIGHT"))
  1240. {
  1241. domFloat_array* weights = source->getFloat_array();
  1242. if (weights)
  1243. {
  1244. jointWeights = weights->getValue();
  1245. }
  1246. }
  1247. }
  1248. // Get the number of joint influences per vertex
  1249. domSkin::domVertex_weights::domVcount* vCountElement = vertexWeights->getVcount();
  1250. domListOfUInts skinVertexInfluenceCounts = vCountElement->getValue();
  1251. // Get the joint/weight pair data.
  1252. domSkin::domVertex_weights::domV* vElement = vertexWeights->getV();
  1253. domListOfInts skinVertexJointWeightPairIndices = vElement->getValue();
  1254. // Get the vertex influence count for any given vertex (up to max of 4)
  1255. unsigned int maxVertexInfluencesCount = SCENE_SKIN_VERTEXINFLUENCES_MAX;
  1256. skin->setVertexInfluenceCount(maxVertexInfluencesCount);
  1257. // Get the vertex blend weights and joint indices and
  1258. // allocate our vertex blend weights and blend indices arrays.
  1259. // These will be used and cleaned up later in LoadMesh
  1260. int skinVertexInfluenceCountTotal = skinVertexInfluenceCounts.getCount();
  1261. int totalVertexInfluencesCount = vertexWeightsCount * maxVertexInfluencesCount;
  1262. _vertexBlendWeights = new float[totalVertexInfluencesCount];
  1263. _vertexBlendIndices = new unsigned int[totalVertexInfluencesCount];
  1264. // Preset the default blend weights to 0.0f (no effect) and blend indices to 0 (uses the first which when multiplied
  1265. // will have no effect anyhow.
  1266. memset(_vertexBlendWeights, 0, totalVertexInfluencesCount * sizeof(float));
  1267. memset(_vertexBlendIndices , 0, totalVertexInfluencesCount * sizeof(unsigned int));
  1268. int vOffset = 0;
  1269. int weightOffset = 0;
  1270. // Go through all the skin vertex influence weights from the indexed data.
  1271. for (int i = 0; i < skinVertexInfluenceCountTotal; ++i)
  1272. {
  1273. // Get the influence count and directly get the vertext blend weights and indices.
  1274. unsigned int vertexInfluenceCount = (unsigned int)skinVertexInfluenceCounts.get(i);
  1275. float vertexInfluencesTotalWeights = 0.0f;
  1276. std::vector<SkinnedVertexWeightPair> vertexInfluences;
  1277. //vertexInfluences.SetCapacity(vertexInfluenceCount);
  1278. // Get the index/weight pairs and some the weight totals while at it.
  1279. for (unsigned int j = 0; j < vertexInfluenceCount; ++j)
  1280. {
  1281. float weight = (float)jointWeights.get((unsigned int)skinVertexJointWeightPairIndices[vOffset + 1]);
  1282. int index = (int)skinVertexJointWeightPairIndices[vOffset];
  1283. // Set invalid index corresponding weights to zero
  1284. if (index < 0 || index > (int)vertexWeightsCount)
  1285. {
  1286. weight = 0.0f;
  1287. index = 0;
  1288. }
  1289. SkinnedVertexWeightPair pair(weight, index);
  1290. vertexInfluences.push_back(pair);
  1291. vertexInfluencesTotalWeights += weight;
  1292. vOffset+=2;
  1293. }
  1294. // Get up the the maximum vertex weight influence count.
  1295. for (unsigned int j = 0; j < maxVertexInfluencesCount; ++j)
  1296. {
  1297. if (j < vertexInfluenceCount)
  1298. {
  1299. SkinnedVertexWeightPair pair = vertexInfluences[j];
  1300. _vertexBlendIndices[weightOffset] = pair.BlendIndex;
  1301. if (vertexInfluencesTotalWeights > 0.0f)
  1302. {
  1303. _vertexBlendWeights[weightOffset] = pair.BlendWeight;
  1304. }
  1305. else
  1306. {
  1307. if (j == 0)
  1308. {
  1309. _vertexBlendWeights[weightOffset] = 1.0f;
  1310. }
  1311. else
  1312. {
  1313. _vertexBlendWeights[weightOffset] = 0.0f;
  1314. }
  1315. }
  1316. }
  1317. weightOffset++;
  1318. }
  1319. }
  1320. model->setSkin(skin);
  1321. ///////////////////////////////////////////////////////////
  1322. // get geometry
  1323. xsAnyURI geometryURI = skinElement->getSource();
  1324. domGeometry* geometry = daeSafeCast<domGeometry>(geometryURI.getElement());
  1325. if (geometry)
  1326. {
  1327. const domMesh* meshElement = geometry->getMesh();
  1328. if (meshElement)
  1329. {
  1330. Mesh* mesh = loadMesh(meshElement, geometry->getId());
  1331. if (mesh)
  1332. {
  1333. model->setMesh(mesh);
  1334. }
  1335. }
  1336. }
  1337. ///////////////////////////////////////////////////////////
  1338. return model;
  1339. }
  1340. Model* DAESceneEncoder::loadGeometry(const domGeometry* geometry, const domBind_materialRef bindMaterial)
  1341. {
  1342. // Does this geometry have a valid mesh?
  1343. // Get the mesh for the geometry (if it has one)
  1344. const domMesh* meshElement = geometry->getMesh();
  1345. if (meshElement == NULL)
  1346. {
  1347. warning(std::string("No mesh found for geometry: ") + geometry->getId());
  1348. return NULL;
  1349. }
  1350. ///////////////////////////// GEOMETRY
  1351. // Load the mesh for this model
  1352. Mesh* mesh = loadMesh(meshElement, geometry->getId());
  1353. if (mesh == NULL)
  1354. {
  1355. return NULL;
  1356. }
  1357. // Mesh instance
  1358. Model* model = new Model();
  1359. model->setMesh(mesh);
  1360. return model;
  1361. }
  1362. Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& geometryId)
  1363. {
  1364. const domTriangles_Array& trianglesArray = meshElement->getTriangles_array();
  1365. unsigned int trianglesArrayCount = (unsigned int)trianglesArray.getCount();
  1366. // Ensure the data is exported as triangles.
  1367. if (trianglesArrayCount == 0)
  1368. {
  1369. warning(std::string("Geometry mesh has no triangles: ") + geometryId);
  1370. return NULL;
  1371. }
  1372. // Check if this mesh already exists
  1373. Mesh* mesh = _gamePlayFile.getMesh(geometryId.c_str());
  1374. if (mesh)
  1375. {
  1376. return mesh;
  1377. }
  1378. mesh = new Mesh();
  1379. mesh->setId(geometryId.c_str());
  1380. std::vector<DAEPolygonInput*> polygonInputs;
  1381. // Quickly just go through each triangles array and make sure they have the same number of inputs
  1382. // with the same layout.
  1383. // const domSource_Array& sourceArray = meshElement->getSource_array();
  1384. const domInputLocal_Array& vertexArray = meshElement->getVertices()->getInput_array();
  1385. unsigned int inputCount = (unsigned int)-1;
  1386. // Loop through our set of triangle lists (each list of triangles corresponds to a single MeshPart)
  1387. for (unsigned int i = 0; i < trianglesArrayCount; ++i)
  1388. {
  1389. const domTrianglesRef& triangles = trianglesArray.get(i);
  1390. const domInputLocalOffset_Array& inputArray = triangles->getInput_array();
  1391. // If not set then determine the number of input for all the triangles.
  1392. if (inputCount == -1)
  1393. {
  1394. inputCount = (unsigned int)inputArray.getCount();
  1395. int texCoordCount = 0;
  1396. for (unsigned int j = 0; j < inputCount; ++j)
  1397. {
  1398. const domInputLocalOffsetRef& input = inputArray.get(j);
  1399. std::string inputSemantic = input->getSemantic();
  1400. // If its a vertex first do an extra lookup for the inclusive inputs
  1401. if (equals(inputSemantic, "VERTEX"))
  1402. {
  1403. unsigned int vertexArrayCount = (unsigned int)vertexArray.getCount();
  1404. for (unsigned int k = 0; k < vertexArrayCount; ++k)
  1405. {
  1406. const domInputLocalRef& vertexInput = vertexArray.get(k);
  1407. std::string semantic = std::string(vertexInput->getSemantic());
  1408. int type = getVertexUsageType(semantic);
  1409. if (type == -1)
  1410. {
  1411. warning(std::string("Vertex semantic (") + semantic + ") is invalid/unsupported for geometry mesh: " + geometryId);
  1412. }
  1413. DAEPolygonInput* polygonInput = new DAEPolygonInput();
  1414. domURIFragmentType& sourceURI = vertexInput->getSource();
  1415. sourceURI.resolveElement();
  1416. domSource* source = (domSource*)(daeElement*)sourceURI.getElement();
  1417. polygonInput->offset = 0;
  1418. polygonInput->sourceValues = source->getFloat_array()->getValue();
  1419. polygonInput->type = type;
  1420. polygonInputs.push_back(polygonInput);
  1421. }
  1422. }
  1423. else
  1424. {
  1425. std::string semantic = input->getSemantic();
  1426. int type = getVertexUsageType(semantic);
  1427. if (type == -1)
  1428. {
  1429. warning(std::string("Semantic (") + semantic + ") is invalid/unsupported for geometry mesh: " + geometryId);
  1430. break;
  1431. }
  1432. if (type == TEXCOORD0)
  1433. {
  1434. // Some meshes have multiple texture coordinates
  1435. assert(texCoordCount <= 7);
  1436. type += texCoordCount;
  1437. ++texCoordCount;
  1438. }
  1439. DAEPolygonInput* polygonInput = new DAEPolygonInput();
  1440. domURIFragmentType& sourceURI = input->getSource();
  1441. sourceURI.resolveElement();
  1442. domSource* source = (domSource*)(daeElement*)sourceURI.getElement();
  1443. polygonInput->offset = (unsigned int)input->getOffset();
  1444. polygonInput->sourceValues = source->getFloat_array()->getValue();
  1445. polygonInput->type = type;
  1446. // Get the accessor info
  1447. const domSource::domTechnique_commonRef& technique = source->getTechnique_common();
  1448. if (technique.cast())
  1449. {
  1450. const domAccessorRef& accessor = technique->getAccessor();
  1451. polygonInput->accessor = accessor;
  1452. }
  1453. polygonInputs.push_back(polygonInput);
  1454. }
  1455. }
  1456. }
  1457. else
  1458. {
  1459. // If there is a triangle array with a different number of inputs, this is not supported.
  1460. if (inputCount != (unsigned int)inputArray.getCount())
  1461. {
  1462. for (size_t j = 0; j < polygonInputs.size(); ++j)
  1463. {
  1464. delete polygonInputs[j];
  1465. }
  1466. warning(std::string("Triangles do not all have the same number of input sources for geometry mesh: ") + geometryId);
  1467. return NULL;
  1468. }
  1469. else
  1470. {
  1471. // TODO: Check if they are in the same order...
  1472. }
  1473. }
  1474. }
  1475. // Now we have validated that all input in all triangles are the same and in the same input layout.
  1476. // Lets start to read them and build our subsets.
  1477. for (unsigned int i = 0; i < trianglesArrayCount; ++i)
  1478. {
  1479. // Subset to be built.
  1480. MeshPart* subset = new MeshPart();
  1481. // All of the information about the triangles and the sources to access the data from.
  1482. domTriangles* triangles = daeSafeCast<domTriangles>(trianglesArray.get(i));
  1483. // Parse the material for this subset
  1484. //std::string materialName = triangles->getMaterial() == NULL ? _T("") : triangles->getMaterial();
  1485. //if (materialName.size() > 0)
  1486. /// subset->material = ParseMaterial(bindMaterial, materialName);
  1487. //const domInputLocalOffset_Array& inputArray = triangles->getInput_array();
  1488. const domListOfUInts& polyInts = triangles->getP()->getValue();
  1489. unsigned int polyIntsCount = (unsigned int)polyInts.getCount();
  1490. unsigned int poly = 0;
  1491. unsigned int inputSourceCount = (unsigned int)polygonInputs.size();
  1492. unsigned int maxOffset = 0;
  1493. // Go through the polygon indices for each input source retrieve the values
  1494. // and iterate by its offset.
  1495. Vertex vertex;
  1496. for (unsigned int k = 0; k < inputSourceCount && poly < polyIntsCount;)
  1497. {
  1498. const domListOfFloats& source = polygonInputs[k]->sourceValues;
  1499. unsigned int offset = polygonInputs[k]->offset;
  1500. if (offset > maxOffset)
  1501. {
  1502. maxOffset = offset;
  1503. }
  1504. int type = polygonInputs[k]->type;
  1505. unsigned int polyIndex = (unsigned int) polyInts.get(poly + offset);
  1506. switch (type)
  1507. {
  1508. case POSITION:
  1509. vertex = Vertex(); // TODO
  1510. if (_vertexBlendWeights && _vertexBlendIndices)
  1511. {
  1512. vertex.hasWeights = true;
  1513. vertex.blendWeights.x = _vertexBlendWeights[polyIndex * 4];
  1514. vertex.blendWeights.y = _vertexBlendWeights[polyIndex * 4 + 1];
  1515. vertex.blendWeights.z = _vertexBlendWeights[polyIndex * 4 + 2];
  1516. vertex.blendWeights.w = _vertexBlendWeights[polyIndex * 4 + 3];
  1517. vertex.blendIndices.x = (float)_vertexBlendIndices[polyIndex * 4];
  1518. vertex.blendIndices.y = (float)_vertexBlendIndices[polyIndex * 4 + 1];
  1519. vertex.blendIndices.z = (float)_vertexBlendIndices[polyIndex * 4 + 2];
  1520. vertex.blendIndices.w = (float)_vertexBlendIndices[polyIndex * 4 + 3];
  1521. }
  1522. vertex.position.x = (float)source.get(polyIndex * 3);
  1523. vertex.position.y = (float)source.get(polyIndex * 3 + 1);
  1524. vertex.position.z = (float)source.get(polyIndex * 3 + 2);
  1525. break;
  1526. case NORMAL:
  1527. vertex.hasNormal = true;
  1528. vertex.normal.x = (float)source.get(polyIndex * 3);
  1529. vertex.normal.y = (float)source.get(polyIndex * 3 + 1);
  1530. vertex.normal.z = (float)source.get(polyIndex * 3 + 2);
  1531. break;
  1532. // TODO: Handle reading of per-vertex colors.
  1533. // HOW do we know how many color components to read?
  1534. // We must examine the Collada input accessor and read the stride/count to verify this - not ONLY for Color, but we should be doing this for ALL components (i.e. Position, Normal, etc).
  1535. // case Color:
  1536. // vertex.hasColor = true;
  1537. // vertex.Diffuse.R = (float)source.get(polyIndex * 3);
  1538. // vertex.Diffuse.G = (float)source.get(polyIndex * 3 + 1);
  1539. // vertex.Diffuse.B = (float)source.get(polyIndex * 3 + 2);
  1540. // vertex.Diffuse.A = (float)source.get(polyIndex * 3 + 3);
  1541. // break;
  1542. case TANGENT:
  1543. vertex.hasTangent = true;
  1544. vertex.tangent.x = (float)source.get(polyIndex * 3);
  1545. vertex.tangent.y = (float)source.get(polyIndex * 3 + 1);
  1546. vertex.tangent.z = (float)source.get(polyIndex * 3 + 2);
  1547. break;
  1548. case BINORMAL:
  1549. vertex.hasBinormal = true;
  1550. vertex.binormal.x = (float)source.get(polyIndex * 3);
  1551. vertex.binormal.y = (float)source.get(polyIndex * 3 + 1);
  1552. vertex.binormal.z = (float)source.get(polyIndex * 3 + 2);
  1553. break;
  1554. case TEXCOORD0:
  1555. vertex.hasTexCoord = true;
  1556. if (polygonInputs[k]->accessor)
  1557. {
  1558. // TODO: This assumes (s, t) are first
  1559. unsigned int stride = (unsigned int)polygonInputs[k]->accessor->getStride();
  1560. vertex.texCoord.x = (float)source.get(polyIndex * stride);
  1561. vertex.texCoord.y = (float)source.get(polyIndex * stride + 1);
  1562. }
  1563. else
  1564. {
  1565. vertex.texCoord.x = (float)source.get(polyIndex * 2);
  1566. vertex.texCoord.y = (float)source.get(polyIndex * 2 + 1);
  1567. }
  1568. break;
  1569. case TEXCOORD1:
  1570. // TODO
  1571. break;
  1572. default:
  1573. break;
  1574. }
  1575. // On the last input source attempt to add the vertex or index an existing one.
  1576. if (k == (inputSourceCount - 1))
  1577. {
  1578. // Only add unique vertices, use a hashtable and compare the hash functions of the
  1579. // vertices. If they exist simply lookup the index of the existing ones.
  1580. // otherwise add and new one and index it.
  1581. unsigned int index;
  1582. if (mesh->contains(vertex))
  1583. {
  1584. index = mesh->getVertexIndex(vertex);
  1585. }
  1586. else
  1587. {
  1588. index = mesh->addVertex(vertex);
  1589. }
  1590. subset->addIndex(index);
  1591. poly += (maxOffset+1);
  1592. k = 0;
  1593. }
  1594. else
  1595. {
  1596. k++;
  1597. }
  1598. }
  1599. // Add our new subset for the mesh.
  1600. mesh->addMeshPart(subset);
  1601. }
  1602. bool hasNormals = mesh->vertices[0].hasNormal;
  1603. bool hasColors = mesh->vertices[0].hasColor;
  1604. bool hasTangents = mesh->vertices[0].hasTangent;
  1605. bool hasBinormals = mesh->vertices[0].hasBinormal;
  1606. bool hasTexCoords = mesh->vertices[0].hasTexCoord;
  1607. bool hasWeights = mesh->vertices[0].hasWeights;
  1608. // The order that the vertex elements are add to the list matters.
  1609. // It should be the same order as how the Vertex data is written.
  1610. // Position
  1611. mesh->addVetexAttribute(POSITION, 3);
  1612. // Normals
  1613. if (hasNormals)
  1614. {
  1615. mesh->addVetexAttribute(NORMAL, 3);
  1616. }
  1617. // Tangents
  1618. if (hasTangents)
  1619. {
  1620. mesh->addVetexAttribute(TANGENT, 3);
  1621. }
  1622. // Binormals
  1623. if (hasBinormals)
  1624. {
  1625. mesh->addVetexAttribute(BINORMAL, 3);
  1626. }
  1627. // Texture Coordinates
  1628. if (hasTexCoords)
  1629. {
  1630. mesh->addVetexAttribute(TEXCOORD0, 2);
  1631. }
  1632. // Diffuse Color
  1633. if (hasColors)
  1634. {
  1635. mesh->addVetexAttribute(COLOR, 3);
  1636. }
  1637. // Skinning BlendWeights BlendIndices
  1638. if (hasWeights /*_vertexBlendWeights && _vertexBlendIndices*/)
  1639. {
  1640. mesh->addVetexAttribute(BLENDWEIGHTS, 4);
  1641. mesh->addVetexAttribute(BLENDINDICES, 4);
  1642. }
  1643. _gamePlayFile.addMesh(mesh);
  1644. return mesh;
  1645. }
  1646. void DAESceneEncoder::warning(const std::string& message)
  1647. {
  1648. printf("Warning: %s\n", message.c_str());
  1649. }
  1650. void DAESceneEncoder::warning(const char* message)
  1651. {
  1652. printf("Warning: %s\n", message);
  1653. }
  1654. int DAESceneEncoder::getVertexUsageType(const std::string& semantic)
  1655. {
  1656. int type = -1;
  1657. if (semantic.length() > 0)
  1658. {
  1659. switch (semantic[0])
  1660. {
  1661. case 'P':
  1662. if (equals(semantic, "POSITION"))
  1663. {
  1664. type = POSITION;
  1665. }
  1666. break;
  1667. case 'N':
  1668. if (equals(semantic, "NORMAL"))
  1669. {
  1670. type = NORMAL;
  1671. }
  1672. case 'C':
  1673. if (equals(semantic, "COLOR"))
  1674. {
  1675. type = COLOR;
  1676. }
  1677. case 'T':
  1678. if (equals(semantic, "TANGENT"))
  1679. {
  1680. type = TANGENT;
  1681. }
  1682. else if (equals(semantic, "TEXCOORD"))
  1683. {
  1684. type = TEXCOORD0;
  1685. }
  1686. else if (equals(semantic, "TEXTANGENT"))
  1687. {
  1688. // Treat TEXTANGENT as TANGENT
  1689. type = TANGENT;
  1690. }
  1691. else if (equals(semantic, "TEXBINORMAL"))
  1692. {
  1693. // Treat TEXBINORMAL as BINORMAL
  1694. type = BINORMAL;
  1695. }
  1696. case 'B':
  1697. if (equals(semantic, "BINORMAL"))
  1698. {
  1699. type = BINORMAL;
  1700. }
  1701. default:
  1702. break;
  1703. }
  1704. }
  1705. return type;
  1706. }
  1707. DAESceneEncoder::DAEPolygonInput::DAEPolygonInput(void) :
  1708. offset(0),
  1709. type(0),
  1710. accessor(NULL)
  1711. {
  1712. }
  1713. DAESceneEncoder::DAEPolygonInput::~DAEPolygonInput(void)
  1714. {
  1715. }