2
0

appMesh.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "ts/loader/appMesh.h"
  23. #include "ts/loader/tsShapeLoader.h"
  24. Vector<AppMaterial*> AppMesh::appMaterials;
  25. AppMesh::AppMesh()
  26. : flags(0), vertsPerFrame(0),numFrames(0), numMatFrames(0), detailSize(1)
  27. {
  28. }
  29. AppMesh::~AppMesh()
  30. {
  31. }
  32. void AppMesh::computeBounds(Box3F& bounds)
  33. {
  34. bounds = Box3F::Invalid;
  35. if ( isSkin() )
  36. {
  37. // Need to skin the mesh before we can compute the bounds
  38. // Setup bone transforms
  39. Vector<MatrixF> boneTransforms;
  40. boneTransforms.setSize( nodeIndex.size() );
  41. for (S32 iBone = 0; iBone < boneTransforms.size(); iBone++)
  42. {
  43. MatrixF nodeMat = bones[iBone]->getNodeTransform( TSShapeLoader::DefaultTime );
  44. TSShapeLoader::zapScale(nodeMat);
  45. boneTransforms[iBone].mul( nodeMat, initialTransforms[iBone] );
  46. }
  47. // Multiply verts by weighted bone transforms
  48. for (S32 iVert = 0; iVert < initialVerts.size(); iVert++)
  49. points[iVert].set( Point3F::Zero );
  50. for (S32 iWeight = 0; iWeight < vertexIndex.size(); iWeight++)
  51. {
  52. const S32& vertIndex = vertexIndex[iWeight];
  53. const MatrixF& deltaTransform = boneTransforms[ boneIndex[iWeight] ];
  54. Point3F v;
  55. deltaTransform.mulP( initialVerts[vertIndex], &v );
  56. v *= weight[iWeight];
  57. points[vertIndex] += v;
  58. }
  59. // compute bounds for the skinned mesh
  60. for (S32 iVert = 0; iVert < initialVerts.size(); iVert++)
  61. bounds.extend( points[iVert] );
  62. }
  63. else
  64. {
  65. MatrixF transform = getMeshTransform(TSShapeLoader::DefaultTime);
  66. TSShapeLoader::zapScale(transform);
  67. for (S32 iVert = 0; iVert < points.size(); iVert++)
  68. {
  69. Point3F p;
  70. transform.mulP(points[iVert], &p);
  71. bounds.extend(p);
  72. }
  73. }
  74. }
  75. void AppMesh::computeNormals()
  76. {
  77. // Clear normals
  78. normals.setSize( points.size() );
  79. for (S32 iNorm = 0; iNorm < normals.size(); iNorm++)
  80. normals[iNorm] = Point3F::Zero;
  81. // Sum triangle normals for each vertex
  82. for (S32 iPrim = 0; iPrim < primitives.size(); iPrim++)
  83. {
  84. const TSDrawPrimitive& prim = primitives[iPrim];
  85. for (S32 iInd = 0; iInd < prim.numElements; iInd += 3)
  86. {
  87. // Compute the normal for this triangle
  88. S32 idx0 = indices[prim.start + iInd + 0];
  89. S32 idx1 = indices[prim.start + iInd + 1];
  90. S32 idx2 = indices[prim.start + iInd + 2];
  91. const Point3F& v0 = points[idx0];
  92. const Point3F& v1 = points[idx1];
  93. const Point3F& v2 = points[idx2];
  94. Point3F n;
  95. mCross(v2 - v0, v1 - v0, &n);
  96. n.normalize(); // remove this to use 'weighted' normals (large triangles will have more effect)
  97. normals[idx0] += n;
  98. normals[idx1] += n;
  99. normals[idx2] += n;
  100. }
  101. }
  102. // Normalize the vertex normals (this takes care of averaging the triangle normals)
  103. for (S32 iNorm = 0; iNorm < normals.size(); iNorm++)
  104. normals[iNorm].normalize();
  105. }
  106. TSMesh* AppMesh::constructTSMesh()
  107. {
  108. TSMesh* tsmesh;
  109. if (isSkin())
  110. {
  111. TSSkinMesh* tsskin = new TSSkinMesh();
  112. tsmesh = tsskin;
  113. // Copy skin elements
  114. tsskin->weight = weight;
  115. tsskin->boneIndex = boneIndex;
  116. tsskin->vertexIndex = vertexIndex;
  117. tsskin->batchData.nodeIndex = nodeIndex;
  118. tsskin->batchData.initialTransforms = initialTransforms;
  119. tsskin->batchData.initialVerts = initialVerts;
  120. tsskin->batchData.initialNorms = initialNorms;
  121. }
  122. else
  123. {
  124. tsmesh = new TSMesh();
  125. }
  126. // Copy mesh elements
  127. tsmesh->mVerts = points;
  128. tsmesh->mNorms = normals;
  129. tsmesh->mTverts = uvs;
  130. tsmesh->mPrimitives = primitives;
  131. tsmesh->mIndices = indices;
  132. tsmesh->mColors = colors;
  133. tsmesh->mTverts2 = uv2s;
  134. // Finish initializing the shape
  135. tsmesh->setFlags(flags);
  136. tsmesh->updateMeshFlags();
  137. tsmesh->computeBounds();
  138. tsmesh->numFrames = numFrames;
  139. tsmesh->numMatFrames = numMatFrames;
  140. tsmesh->vertsPerFrame = vertsPerFrame;
  141. tsmesh->createTangents(tsmesh->mVerts, tsmesh->mNorms);
  142. tsmesh->mEncodedNorms.set(NULL,0);
  143. return tsmesh;
  144. }
  145. bool AppMesh::isBillboard()
  146. {
  147. return !dStrnicmp(getName(),"BB::",4) || !dStrnicmp(getName(),"BB_",3) || isBillboardZAxis();
  148. }
  149. bool AppMesh::isBillboardZAxis()
  150. {
  151. return !dStrnicmp(getName(),"BBZ::",5) || !dStrnicmp(getName(),"BBZ_",4);
  152. }