appMesh.cpp

Engine/source/ts/loader/appMesh.cpp

More...

Detailed Description

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