llgltfasset.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. /**
  2. * @file llgltfasset.cpp
  3. * @brief LL GLTF Implementation
  4. *
  5. * $LicenseInfo:firstyear=2024&license=viewergpl$
  6. *
  7. * Copyright (c) 2024, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include "tinygltf/tiny_gltf.h"
  34. #include "llgltfasset.h"
  35. #include "llgltfaccessor.h"
  36. #include "llshadermgr.h"
  37. #include "llvolumeoctree.h"
  38. // Global variable defined in newview (llappviewer.h)
  39. extern F32 gFrameTimeSeconds;
  40. // External functions from LLFetchedGLTFMaterial. HB
  41. extern LLGLTFMaterial* create_fetch_material();
  42. extern void bind_fetched_material(LLGLTFMaterial* matp);
  43. // External function from LLTinyGLTFHelper. HB
  44. extern void get_material_from_model(const std::string& filename,
  45. const tinygltf::Model& model, S32 mat_idx,
  46. LLGLTFMaterial* matp,
  47. std::string& mat_name, bool flip);
  48. using namespace LLGLTF;
  49. ///////////////////////////////////////////////////////////////////////////////
  50. // LLGLTF::Node class
  51. ///////////////////////////////////////////////////////////////////////////////
  52. Node::Node()
  53. : mParent(INVALID_INDEX),
  54. mMesh(INVALID_INDEX),
  55. mSkin(INVALID_INDEX),
  56. mMatrixValid(false),
  57. mTRSValid(false),
  58. mNeedsApplyMatrix(false)
  59. {
  60. }
  61. void Node::updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview)
  62. {
  63. mRenderMatrix.matMul(mMatrix, modelview);
  64. for (auto& idx : mChildren)
  65. {
  66. Node& child = asset.mNodes[idx];
  67. child.updateRenderTransforms(asset, mRenderMatrix);
  68. }
  69. }
  70. void Node::updateTransforms(Asset& asset, const LLMatrix4a& parent_mat)
  71. {
  72. makeMatrixValid();
  73. mAssetMatrix.matMul(mMatrix, parent_mat);
  74. mAssetMatrixInv = mAssetMatrix;
  75. mAssetMatrixInv.invert();
  76. S32 my_index = this - &asset.mNodes[0];
  77. for (auto& idx : mChildren)
  78. {
  79. Node& child = asset.mNodes[idx];
  80. child.mParent = my_index;
  81. child.updateTransforms(asset, mAssetMatrix);
  82. }
  83. }
  84. void Node::makeMatrixValid()
  85. {
  86. if (!mMatrixValid && mTRSValid)
  87. {
  88. // t = sc * rot * trans;
  89. // t = trans * rot * sc; // Best so far, still wrong on negative scale
  90. // t = sc * trans * rot;
  91. glh::matrix4f rot, trans, sc;
  92. mRotation.get_value(rot);
  93. trans.set_translate(mTranslation);
  94. sc.set_scale(mScale);
  95. glh::matrix4f t = trans * sc * rot;
  96. mMatrix.loadu(t.m);
  97. mMatrixValid = true;
  98. }
  99. }
  100. void Node::makeTRSValid()
  101. {
  102. if (!mTRSValid && mMatrixValid)
  103. {
  104. glh::matrix4f t(mMatrix.getF32ptr());
  105. glh::vec4f p = t.get_column(3);
  106. mTranslation.set_value(p.v[0], p.v[1], p.v[2]);
  107. mScale.set_value(t.get_column(0).length(), t.get_column(1).length(),
  108. t.get_column(2).length());
  109. mRotation.set_value(t);
  110. mTRSValid = true;
  111. }
  112. }
  113. void Node::setRotation(const glh::quaternionf& q)
  114. {
  115. makeTRSValid();
  116. mRotation = q;
  117. mMatrixValid = false;
  118. }
  119. void Node::setTranslation(const glh::vec3f& t)
  120. {
  121. makeTRSValid();
  122. mTranslation = t;
  123. mMatrixValid = false;
  124. }
  125. void Node::setScale(const glh::vec3f& s)
  126. {
  127. makeTRSValid();
  128. mScale = s;
  129. mMatrixValid = false;
  130. }
  131. const Node& Node::operator=(const tinygltf::Node& src)
  132. {
  133. F32* dst_mat = mMatrix.getF32ptr();
  134. if (src.matrix.size() == 16)
  135. {
  136. // Node has a transformation matrix, just copy it
  137. for (U32 i = 0; i < 16; ++i)
  138. {
  139. dst_mat[i] = (F32)src.matrix[i];
  140. }
  141. mMatrixValid = true;
  142. }
  143. else if (!src.rotation.empty() || !src.translation.empty() ||
  144. !src.scale.empty())
  145. {
  146. // Node has rotation/translation/scale, convert to matrix
  147. if (src.rotation.size() == 4)
  148. {
  149. mRotation = glh::quaternionf((F32)src.rotation[0],
  150. (F32)src.rotation[1],
  151. (F32)src.rotation[2],
  152. (F32)src.rotation[3]);
  153. }
  154. if (src.translation.size() == 3)
  155. {
  156. mTranslation = glh::vec3f((F32)src.translation[0],
  157. (F32)src.translation[1],
  158. (F32)src.translation[2]);
  159. }
  160. glh::vec3f scale;
  161. if (src.scale.size() == 3)
  162. {
  163. mScale = glh::vec3f((F32)src.scale[0], (F32)src.scale[1],
  164. (F32)src.scale[2]);
  165. }
  166. else
  167. {
  168. mScale.set_value(1.f, 1.f, 1.f);
  169. }
  170. mTRSValid = true;
  171. }
  172. else
  173. {
  174. // Node specifies no transformation, set to identity
  175. mMatrix.setIdentity();
  176. }
  177. mChildren = src.children;
  178. mMesh = src.mesh;
  179. mSkin = src.skin;
  180. mName = src.name;
  181. return *this;
  182. }
  183. ///////////////////////////////////////////////////////////////////////////////
  184. // LLGLTF::Asset class
  185. ///////////////////////////////////////////////////////////////////////////////
  186. Asset::Asset()
  187. {
  188. mLastUpdateTime = gFrameTimeSeconds;
  189. }
  190. void Asset::updateTransforms()
  191. {
  192. for (auto& scene : mScenes)
  193. {
  194. scene.updateTransforms(*this);
  195. }
  196. }
  197. void Asset::updateRenderTransforms(const LLMatrix4a& modelview)
  198. {
  199. #if 0
  200. // Traverse hierarchy and update render transforms from scratch
  201. for (auto& scene : mScenes)
  202. {
  203. scene.updateRenderTransforms(*this, modelview);
  204. }
  205. #else
  206. // Use mAssetMatrix to update render transforms from node list
  207. for (auto& node : mNodes)
  208. {
  209. //if (node.mMesh != INVALID_INDEX)
  210. {
  211. node.mRenderMatrix.matMul(node.mAssetMatrix, modelview);
  212. }
  213. }
  214. #endif
  215. }
  216. S32 Asset::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
  217. LLVector4a* intersectp, LLVector2* tcoordp,
  218. LLVector4a* normalp, LLVector4a* tangentp,
  219. S32* prim_hitp)
  220. {
  221. S32 node_hit = -1;
  222. S32 primitive_hit = -1;
  223. LLVector4a p, local_start, local_end;
  224. LLVector4a asset_end = end;
  225. for (auto& node : mNodes)
  226. {
  227. if (node.mMesh != INVALID_INDEX)
  228. {
  229. bool new_hit = false;
  230. // Transform start and end to this node's local space
  231. node.mAssetMatrixInv.affineTransform(start, local_start);
  232. node.mAssetMatrixInv.affineTransform(asset_end, local_end);
  233. Mesh& mesh = mMeshes[node.mMesh];
  234. for (auto& primitive : mesh.mPrimitives)
  235. {
  236. const LLVolumeTriangle* tri =
  237. primitive.lineSegmentIntersect(local_start, local_end, &p,
  238. tcoordp, normalp, tangentp);
  239. if (tri)
  240. {
  241. new_hit = true;
  242. local_end = p;
  243. // Pointer math to get the node index
  244. node_hit = &node - &mNodes[0];
  245. llassert(&mNodes[node_hit] == &node);
  246. // Pointer math to get the primitive index
  247. primitive_hit = &primitive - &mesh.mPrimitives[0];
  248. llassert(&mesh.mPrimitives[primitive_hit] == &primitive);
  249. }
  250. }
  251. if (new_hit)
  252. {
  253. // Shorten line segment on hit
  254. node.mAssetMatrix.affineTransform(p, asset_end);
  255. // Transform results back to asset space
  256. if (intersectp)
  257. {
  258. *intersectp = asset_end;
  259. }
  260. if (normalp || tangentp)
  261. {
  262. LLMatrix4 normal_mat4(node.mAssetMatrixInv.getF32ptr());
  263. normal_mat4.transpose();
  264. LLMatrix4a norm_mat;
  265. norm_mat.loadu(normal_mat4.getF32ptr());
  266. if (normalp)
  267. {
  268. LLVector4a n = *normalp;
  269. F32 w = n.getF32ptr()[3];
  270. n.getF32ptr()[3] = 0.0f;
  271. norm_mat.affineTransform(n, *normalp);
  272. normalp->getF32ptr()[3] = w;
  273. }
  274. if (tangentp)
  275. {
  276. LLVector4a t = *tangentp;
  277. F32 w = t.getF32ptr()[3];
  278. t.getF32ptr()[3] = 0.0f;
  279. norm_mat.affineTransform(t, *tangentp);
  280. tangentp->getF32ptr()[3] = w;
  281. }
  282. }
  283. }
  284. }
  285. }
  286. if (node_hit != -1)
  287. {
  288. if (prim_hitp)
  289. {
  290. *prim_hitp = primitive_hit;
  291. }
  292. }
  293. return node_hit;
  294. }
  295. void Asset::render(bool opaque, bool rigged)
  296. {
  297. if (rigged)
  298. {
  299. gGL.loadIdentity();
  300. }
  301. for (auto& node : mNodes)
  302. {
  303. if (node.mSkin != INVALID_INDEX)
  304. {
  305. if (rigged)
  306. {
  307. Skin& skin = mSkins[node.mSkin];
  308. skin.uploadMatrixPalette(*this, node);
  309. }
  310. else
  311. {
  312. // Skip static nodes if we are rendering rigged
  313. continue;
  314. }
  315. }
  316. else if (rigged)
  317. {
  318. // Skip rigged nodes if we are not rendering rigged
  319. continue;
  320. }
  321. if (node.mMesh != INVALID_INDEX)
  322. {
  323. Mesh& mesh = mMeshes[node.mMesh];
  324. for (auto& primitive : mesh.mPrimitives)
  325. {
  326. if (!rigged)
  327. {
  328. gGL.loadMatrix((F32*)node.mRenderMatrix.mMatrix);
  329. }
  330. bool cull = true;
  331. if (primitive.mMaterial != INVALID_INDEX)
  332. {
  333. Material& material = mMaterials[primitive.mMaterial];
  334. if ((material.mMaterial->mAlphaMode ==
  335. LLGLTFMaterial::ALPHA_MODE_BLEND) == opaque)
  336. {
  337. continue;
  338. }
  339. bind_fetched_material(material.mMaterial);
  340. cull = !material.mMaterial->mDoubleSided;
  341. }
  342. else
  343. {
  344. if (!opaque)
  345. {
  346. continue;
  347. }
  348. bind_fetched_material(NULL);
  349. }
  350. LLVertexBuffer* buffp = primitive.mVertexBuffer;
  351. if (!buffp) continue;
  352. LLGLDisable cull_face(!cull ? GL_CULL_FACE : 0);
  353. buffp->setBuffer();
  354. U32 num_indices = buffp->getNumIndices();
  355. if (num_indices > 0)
  356. {
  357. buffp->draw(primitive.mGLMode, num_indices, 0);
  358. }
  359. else
  360. {
  361. buffp->drawArrays(primitive.mGLMode, 0,
  362. buffp->getNumVerts());
  363. }
  364. }
  365. }
  366. }
  367. }
  368. void Asset::renderOpaque()
  369. {
  370. render(true);
  371. }
  372. void Asset::renderTransparent()
  373. {
  374. render(false);
  375. }
  376. void Asset::update()
  377. {
  378. F32 dt = gFrameTimeSeconds - mLastUpdateTime;
  379. if (dt <= 0.f)
  380. {
  381. return;
  382. }
  383. mLastUpdateTime = gFrameTimeSeconds;
  384. if (mAnimations.size() > 0)
  385. {
  386. #if 0 // For now, these settings are not even listed in LL's viewer
  387. // app_settings/settings.xml, so they default to 0 and 1.f
  388. // respectively. If configuration is ever to be provided, just use
  389. // static variables in the LLGLTF::Asset class and setter methods to
  390. // set them on viewer launch from llappviewer.cpp, and on change from
  391. // llviewercontrol.cpp... HB
  392. static LLCachedControl<U32> anim_idx(gSavedSettings,
  393. "GLTFAnimationIndex", 0);
  394. static LLCachedControl<F32> anim_speed(gSavedSettings,
  395. "GLTFAnimationSpeed", 1.f);
  396. U32 idx = llclamp(anim_idx(), 0U, mAnimations.size() - 1);
  397. #else
  398. constexpr U32 idx = 0;
  399. constexpr F32 anim_speed = 1.f;
  400. #endif
  401. mAnimations[idx].update(*this, dt * anim_speed);
  402. }
  403. updateTransforms();
  404. }
  405. bool Asset::allocateGLResources(const std::string& filename,
  406. const tinygltf::Model& model)
  407. {
  408. // Do images first as materials may depend on images
  409. for (auto& image : mImages)
  410. {
  411. image.allocateGLResources();
  412. }
  413. // Do materials before meshes as meshes may depend on materials
  414. for (size_t i = 0, count = mMaterials.size(); i < count; ++i)
  415. {
  416. mMaterials[i].allocateGLResources(*this);
  417. get_material_from_model(filename, model, i, mMaterials[i].mMaterial,
  418. mMaterials[i].mName, true);
  419. }
  420. for (auto& mesh : mMeshes)
  421. {
  422. if (!mesh.allocateGLResources(*this))
  423. {
  424. // Too many vertice: aborted ! HB
  425. return false;
  426. }
  427. }
  428. for (auto& animation : mAnimations)
  429. {
  430. animation.allocateGLResources(*this);
  431. }
  432. for (auto& skin : mSkins)
  433. {
  434. skin.allocateGLResources(*this);
  435. }
  436. return true;
  437. }
  438. const Asset& Asset::operator=(const tinygltf::Model& src)
  439. {
  440. size_t count = src.scenes.size();
  441. mScenes.resize(count);
  442. for (size_t i = 0; i < count; ++i)
  443. {
  444. mScenes[i] = src.scenes[i];
  445. }
  446. count = src.nodes.size();
  447. mNodes.resize(count);
  448. for (size_t i = 0; i < count; ++i)
  449. {
  450. mNodes[i] = src.nodes[i];
  451. }
  452. count = src.meshes.size();
  453. mMeshes.resize(count);
  454. for (size_t i = 0; i < count; ++i)
  455. {
  456. mMeshes[i] = src.meshes[i];
  457. }
  458. count = src.materials.size();
  459. mMaterials.resize(count);
  460. for (size_t i = 0; i < count; ++i)
  461. {
  462. mMaterials[i] = src.materials[i];
  463. }
  464. count = src.buffers.size();
  465. mBuffers.resize(count);
  466. for (size_t i = 0; i < count; ++i)
  467. {
  468. mBuffers[i] = src.buffers[i];
  469. }
  470. count = src.bufferViews.size();
  471. mBufferViews.resize(count);
  472. for (size_t i = 0; i < count; ++i)
  473. {
  474. mBufferViews[i] = src.bufferViews[i];
  475. }
  476. count = src.textures.size();
  477. mTextures.resize(count);
  478. for (size_t i = 0; i < count; ++i)
  479. {
  480. mTextures[i] = src.textures[i];
  481. }
  482. count = src.samplers.size();
  483. mSamplers.resize(count);
  484. for (size_t i = 0; i < count; ++i)
  485. {
  486. mSamplers[i] = src.samplers[i];
  487. }
  488. count = src.images.size();
  489. mImages.resize(count);
  490. for (size_t i = 0; i < count; ++i)
  491. {
  492. mImages[i] = src.images[i];
  493. }
  494. count = src.accessors.size();
  495. mAccessors.resize(count);
  496. for (size_t i = 0; i < count; ++i)
  497. {
  498. mAccessors[i] = src.accessors[i];
  499. }
  500. count = src.animations.size();
  501. mAnimations.resize(count);
  502. for (size_t i = 0; i < count; ++i)
  503. {
  504. mAnimations[i] = src.animations[i];
  505. }
  506. count = src.skins.size();
  507. mSkins.resize(count);
  508. for (size_t i = 0; i < count; ++i)
  509. {
  510. mSkins[i] = src.skins[i];
  511. }
  512. return *this;
  513. }
  514. ///////////////////////////////////////////////////////////////////////////////
  515. // LLGLTF::Material class
  516. ///////////////////////////////////////////////////////////////////////////////
  517. const Material& Material::operator=(const tinygltf::Material& src)
  518. {
  519. mName = src.name;
  520. return *this;
  521. }
  522. void Material::allocateGLResources(Asset& asset)
  523. {
  524. // Allocate material
  525. mMaterial = create_fetch_material();
  526. }
  527. ///////////////////////////////////////////////////////////////////////////////
  528. // LLGLTF::Mesh class
  529. ///////////////////////////////////////////////////////////////////////////////
  530. const Mesh& Mesh::operator=(const tinygltf::Mesh& src)
  531. {
  532. size_t count = src.primitives.size();
  533. mPrimitives.resize(count);
  534. for (size_t i = 0; i < count; ++i)
  535. {
  536. mPrimitives[i] = src.primitives[i];
  537. }
  538. mWeights = src.weights;
  539. mName = src.name;
  540. return *this;
  541. }
  542. bool Mesh::allocateGLResources(Asset& asset)
  543. {
  544. for (auto& primitive : mPrimitives)
  545. {
  546. if (!primitive.allocateGLResources(asset))
  547. {
  548. // Too many vertice: aborted ! HB
  549. return false;
  550. }
  551. }
  552. return true;
  553. }
  554. ///////////////////////////////////////////////////////////////////////////////
  555. // LLGLTF::Scene class
  556. ///////////////////////////////////////////////////////////////////////////////
  557. void Scene::updateTransforms(Asset& asset)
  558. {
  559. LLMatrix4a identity;
  560. identity.setIdentity();
  561. for (auto& idx : mNodes)
  562. {
  563. Node& node = asset.mNodes[idx];
  564. node.updateTransforms(asset, identity);
  565. }
  566. }
  567. void Scene::updateRenderTransforms(Asset& asset, const LLMatrix4a& modelview)
  568. {
  569. for (auto& idx : mNodes)
  570. {
  571. Node& node = asset.mNodes[idx];
  572. node.updateRenderTransforms(asset, modelview);
  573. }
  574. }
  575. const Scene& Scene::operator=(const tinygltf::Scene& src)
  576. {
  577. mNodes = src.nodes;
  578. mName = src.name;
  579. return *this;
  580. }
  581. ///////////////////////////////////////////////////////////////////////////////
  582. // LLGLTF::Texture class
  583. ///////////////////////////////////////////////////////////////////////////////
  584. Texture::Texture()
  585. : mSampler(INVALID_INDEX),
  586. mSource(INVALID_INDEX)
  587. {
  588. }
  589. const Texture& Texture::operator=(const tinygltf::Texture& src)
  590. {
  591. mSampler = src.sampler;
  592. mSource = src.source;
  593. mName = src.name;
  594. return *this;
  595. }
  596. ///////////////////////////////////////////////////////////////////////////////
  597. // LLGLTF::Image class
  598. ///////////////////////////////////////////////////////////////////////////////
  599. const Image& Image::operator=(const tinygltf::Image& src)
  600. {
  601. mName = src.name;
  602. mUri = src.uri;
  603. mMimeType = src.mimeType;
  604. mData = src.image;
  605. mWidth = src.width;
  606. mHeight = src.height;
  607. mComponent = src.component;
  608. mBits = src.bits;
  609. return *this;
  610. }
  611. ///////////////////////////////////////////////////////////////////////////////
  612. // LLGLTF::Sampler class
  613. ///////////////////////////////////////////////////////////////////////////////
  614. const Sampler& Sampler::operator=(const tinygltf::Sampler& src)
  615. {
  616. mMagFilter = src.magFilter;
  617. mMinFilter = src.minFilter;
  618. mWrapS = src.wrapS;
  619. mWrapT = src.wrapT;
  620. mName = src.name;
  621. return *this;
  622. }
  623. ///////////////////////////////////////////////////////////////////////////////
  624. // LLGLTF::Skin class
  625. ///////////////////////////////////////////////////////////////////////////////
  626. Skin::Skin()
  627. : mInverseBindMatrices(INVALID_INDEX),
  628. mSkeleton(INVALID_INDEX)
  629. {
  630. }
  631. const Skin& Skin::operator=(const tinygltf::Skin& src)
  632. {
  633. mName = src.name;
  634. mSkeleton = src.skeleton;
  635. mInverseBindMatrices = src.inverseBindMatrices;
  636. mJoints = src.joints;
  637. return *this;
  638. }
  639. void Skin::uploadMatrixPalette(Asset& asset, Node& node)
  640. {
  641. // Prepare matrix palette
  642. // Model view will be applied by the shader, so assume matrix palette is in
  643. // asset space
  644. std::vector<glh::matrix4f> t_mp;
  645. t_mp.resize(mJoints.size());
  646. for (U32 i = 0; i < mJoints.size(); ++i)
  647. {
  648. Node& joint = asset.mNodes[mJoints[i]];
  649. //t_mp[i].set_value(joint.mRenderMatrix.getF32ptr());
  650. //t_mp[i] = t_mp[i] * mInverseBindMatricesData[i];
  651. //t_mp[i].set_value(joint.mRenderMatrix.getF32ptr());
  652. //t_mp[i] = mInverseBindMatricesData[i] * t_mp[i];
  653. t_mp[i].set_value(joint.mRenderMatrix.getF32ptr());
  654. t_mp[i] = t_mp[i] * mInverseBindMatricesData[i];
  655. }
  656. std::vector<F32> glmp;
  657. glmp.resize(mJoints.size() * 12);
  658. F32* mp = glmp.data();
  659. for (U32 i = 0; i < mJoints.size(); ++i)
  660. {
  661. F32* m = (F32*)t_mp[i].m;
  662. U32 idx = i * 12;
  663. mp[idx + 0] = m[0];
  664. mp[idx + 1] = m[1];
  665. mp[idx + 2] = m[2];
  666. mp[idx + 3] = m[12];
  667. mp[idx + 4] = m[4];
  668. mp[idx + 5] = m[5];
  669. mp[idx + 6] = m[6];
  670. mp[idx + 7] = m[13];
  671. mp[idx + 8] = m[8];
  672. mp[idx + 9] = m[9];
  673. mp[idx + 10] = m[10];
  674. mp[idx + 11] = m[14];
  675. }
  676. LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLShaderMgr::AVATAR_MATRIX,
  677. mJoints.size(), GL_FALSE,
  678. (F32*)glmp.data());
  679. }