tsMesh.h

Engine/source/ts/tsMesh.h

More...

Classes:

Namespaces:

namespace
namespace

Public Typedefs

TSVertexBufferHandle 

Detailed Description

Public Typedefs

typedef GFXVertexBufferDataHandle TSVertexBufferHandle 
  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#ifndef _TSMESH_H_
 25#define _TSMESH_H_
 26
 27#ifndef _STREAM_H_
 28#include "core/stream/stream.h"
 29#endif
 30#ifndef _MMATH_H_
 31#include "math/mMath.h"
 32#endif
 33#ifndef _TVECTOR_H_
 34#include "core/util/tVector.h"
 35#endif
 36#ifndef _ABSTRACTPOLYLIST_H_
 37#include "collision/abstractPolyList.h"
 38#endif
 39#ifndef _GFXDEVICE_H_
 40#include "gfx/gfxDevice.h"
 41#endif
 42#ifndef _GFXPRIMITIVEBUFFER_H_
 43#include "gfx/gfxPrimitiveBuffer.h"
 44#endif
 45#ifndef _TSPARSEARRAY_H_
 46#include "core/tSparseArray.h"
 47#endif
 48
 49#include "core/util/safeDelete.h"
 50
 51namespace Opcode { class Model; class MeshInterface; }
 52namespace IceMaths { class IndexedTriangle; class Point; }
 53
 54class Convex;
 55
 56class SceneRenderState;
 57class SceneObject;
 58struct MeshRenderInst;
 59class TSRenderState;
 60class RenderPassManager;
 61class TSMaterialList;
 62class TSShapeInstance;
 63struct RayInfo;
 64class ConvexFeature;
 65class ShapeBase;
 66
 67struct TSDrawPrimitive
 68{
 69   enum
 70   {
 71      Triangles    = 0 << 30, ///< bits 30 and 31 index element type
 72      Strip        = 1 << 30, ///< bits 30 and 31 index element type
 73      Fan          = 2 << 30, ///< bits 30 and 31 index element type
 74      Indexed      = BIT(29), ///< use glDrawElements if indexed, glDrawArrays o.w.
 75      NoMaterial   = BIT(28), ///< set if no material (i.e., texture missing)
 76      MaterialMask = ~(Strip</a>|<a href="/coding/class/structtsdrawprimitive/#structtsdrawprimitive_1ac9813717d47f33a65a1a751a1713507dabea6d0438f7b5e0210a231246d3386e2">Fan</a>|<a href="/coding/class/structtsdrawprimitive/#structtsdrawprimitive_1ac9813717d47f33a65a1a751a1713507da383272fb09d3d8bf4fb3d2e2dad57d72">Triangles</a>|<a href="/coding/class/structtsdrawprimitive/#structtsdrawprimitive_1ac9813717d47f33a65a1a751a1713507da0d0a8ba44e59dbcf11c7f4ab1685a2ab">Indexed</a>|<a href="/coding/class/structtsdrawprimitive/#structtsdrawprimitive_1ac9813717d47f33a65a1a751a1713507dae83c71dfda906a3e94e66f8773717b24">NoMaterial),
 77      TypeMask     = Strip</a>|<a href="/coding/class/structtsdrawprimitive/#structtsdrawprimitive_1ac9813717d47f33a65a1a751a1713507dabea6d0438f7b5e0210a231246d3386e2">Fan</a>|<a href="/coding/class/structtsdrawprimitive/#structtsdrawprimitive_1ac9813717d47f33a65a1a751a1713507da383272fb09d3d8bf4fb3d2e2dad57d72">Triangles
 78   };
 79
 80   S32 start;
 81   S32 numElements;
 82   S32 matIndex;    ///< holds material index & element type (see above enum)
 83};
 84
 85typedef GFXVertexBufferDataHandle TSVertexBufferHandle;
 86
 87class TSMesh;
 88class TSShapeAlloc;
 89
 90/// @name Vertex format serialization
 91/// {
 92struct TSBasicVertexFormat
 93{
 94   S16 texCoordOffset;
 95   S16 boneOffset;
 96   S16 colorOffset;
 97   S16 numBones;
 98   S16 vertexSize;
 99
100   TSBasicVertexFormat();
101   TSBasicVertexFormat(TSMesh *mesh);
102   void getFormat(GFXVertexFormat &fmt);
103   void calculateSize();
104
105   void writeAlloc(TSShapeAlloc* alloc);
106   void readAlloc(TSShapeAlloc* alloc);
107
108   void addMeshRequirements(TSMesh *mesh);
109};
110/// }
111
112///
113class TSMesh
114{
115   friend class TSShape;
116public:
117
118   /// Helper class for a freeable vector
119   template<class T>
120   class FreeableVector : public Vector<T>
121   {
122   public:
123      bool free_memory() { return Vector<T>::resize(0); }
124
125      FreeableVector<T>& operator=(const Vector<T>& p) { Vector<T>::operator=(p); return *this; }
126      FreeableVector<T>& operator=(const FreeableVector<T>& p) { Vector<T>::operator=(p); return *this; }
127   };
128
129   /// @name Aligned Vertex Data 
130   /// {
131
132#pragma pack(1)
133
134   struct __TSMeshVertexBase
135   {
136      Point3F _vert;
137      F32 _tangentW;
138      Point3F _normal;
139      Point3F _tangent;
140      Point2F _tvert;
141
142      const Point3F &vert() const { return _vert; }
143      void vert(const Point3F &v) { _vert = v; }
144
145      const Point3F &normal() const { return _normal; }
146      void normal(const Point3F &n) { _normal = n; }
147
148      Point4F tangent() const { return Point4F(_tangent.x, _tangent.y, _tangent.z, _tangentW); }
149      void tangent(const Point4F &t) { _tangent = t.asPoint3F(); _tangentW = t.w; }
150
151      const Point2F &tvert() const { return _tvert; }
152      void tvert(const Point2F &tv) { _tvert = tv; }
153   };
154
155   struct __TSMeshVertex_3xUVColor
156   {
157      Point2F _tvert2;
158      GFXVertexColor _color;
159
160      const Point2F &tvert2() const { return _tvert2; }
161      void tvert2(const Point2F& c) { _tvert2 = c; }
162
163      const GFXVertexColor &color() const { return _color; }
164      void color(const GFXVertexColor &c) { _color = c; }
165   };
166
167   struct __TSMeshIndex_List {
168      U8 x;
169      U8 y;
170      U8 z;
171      U8 w;
172   };
173
174   struct __TSMeshVertex_BoneData
175   {
176      __TSMeshIndex_List _indexes;
177      Point4F _weights;
178
179      const __TSMeshIndex_List &index() const { return _indexes; }
180      void index(const __TSMeshIndex_List& c) { _indexes = c; }
181
182      const Point4F &weight() const { return _weights; }
183      void weight(const Point4F &w) { _weights = w; }
184   };
185
186#pragma pack()
187
188   struct TSMeshVertexArray
189   {
190   protected:
191      U8 *base;
192      dsize_t vertSz;
193      U32 numElements;
194
195      U32 colorOffset;
196      U32 boneOffset;
197
198      bool vertexDataReady;
199      bool ownsData;
200
201   public:
202      TSMeshVertexArray() : base(NULL), vertSz(0), numElements(0), colorOffset(0), boneOffset(0), vertexDataReady(false), ownsData(false) {}
203      virtual ~TSMeshVertexArray() { set(NULL, 0, 0, 0, 0); }
204
205      virtual void set(void *b, dsize_t s, U32 n, S32 inColorOffset, S32 inBoneOffset, bool nowOwnsData = true)
206      {
207         if (base && ownsData)
208            dFree_aligned(base);
209         base = reinterpret_cast<U8 *>(b);
210         vertSz = s;
211         numElements = n;
212         colorOffset = inColorOffset >= 0 ? inColorOffset : 0;
213         boneOffset = inBoneOffset >= 0 ? inBoneOffset : 0;
214         ownsData = nowOwnsData;
215      }
216
217      /// Gets pointer to __TSMeshVertexBase for vertex idx
218      __TSMeshVertexBase &getBase(int idx) const
219      {
220         AssertFatal(idx < numElements, "Out of bounds access!"); return *reinterpret_cast<__TSMeshVertexBase *>(base + (idx * vertSz));
221      }
222
223      /// Gets pointer to __TSMeshVertex_3xUVColor for vertex idx
224      __TSMeshVertex_3xUVColor &getColor(int idx) const
225      {
226         AssertFatal(idx < numElements, "Out of bounds access!"); return *reinterpret_cast<__TSMeshVertex_3xUVColor *>(base + (idx * vertSz) + colorOffset);
227      }
228
229      /// Gets pointer to __TSMeshVertex_BoneData for vertex idx, additionally offsetted by subBoneList 
230      __TSMeshVertex_BoneData &getBone(int idx, int subBoneList) const
231      {
232         AssertFatal(idx < numElements, "Out of bounds access!"); return *reinterpret_cast<__TSMeshVertex_BoneData *>(base + (idx * vertSz) + boneOffset + (sizeof(__TSMeshVertex_BoneData) * subBoneList));
233      }
234
235      /// Returns base address of vertex data
236      __TSMeshVertexBase *address() const
237      {
238         return reinterpret_cast<__TSMeshVertexBase *>(base);
239      }
240
241      U32 size() const { return numElements; }
242      dsize_t mem_size() const { return numElements * vertSz; }
243      dsize_t vertSize() const { return vertSz; }
244      bool isReady() const { return vertexDataReady; }
245      void setReady(bool r) { vertexDataReady = r; }
246
247      U8* getPtr() { return base; }
248
249      inline U32 getColorOffset() const { return colorOffset; }
250      inline U32 getBoneOffset() const { return boneOffset; }
251   };
252
253protected:
254
255   U32 mMeshType;
256   Box3F mBounds;
257   Point3F mCenter;
258   F32 mRadius;
259   F32 mVisibility;
260
261   const GFXVertexFormat *mVertexFormat;
262
263   TSMesh *mParentMeshObject; ///< Current parent object instance
264
265   U32 mPrimBufferOffset;
266
267   GFXVertexBufferDataHandle mVB;
268   GFXPrimitiveBufferHandle mPB;
269
270public:
271
272   S32 mParentMesh; ///< index into shapes mesh list
273   S32 numFrames;
274   S32 numMatFrames;
275   S32 vertsPerFrame;
276
277   U32 mVertOffset;
278   U32 mVertSize;
279
280protected:
281
282   void _convertToVertexData(TSMeshVertexArray &outArray, const Vector<Point3F> &_verts, const Vector<Point3F> &_norms);
283
284  public:
285
286   enum
287   {
288      /// types...
289      StandardMeshType = 0,
290      SkinMeshType     = 1,
291      DecalMeshType    = 2,
292      SortedMeshType   = 3,
293      NullMeshType     = 4,
294      TypeMask = StandardMeshType</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfa4e7301620099d7cf3438bea494da25e4">SkinMeshType</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfa20c73022bcf281f02273d7d6d770e482">DecalMeshType</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfad1c2c699595c9fb7cb8f957dfe5fb2a8">SortedMeshType</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfa23c57aaa3b865f2395f2223d6f492e52">NullMeshType,
295
296      /// flags (stored with meshType)...
297      Billboard = BIT(31), HasDetailTexture = BIT(30),
298      BillboardZAxis = BIT(29), UseEncodedNormals = BIT(28),
299      HasColor = BIT(27), HasTVert2 = BIT(26),
300      FlagMask = Billboard</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfa47ae38c7447a21d8db0ef3ceb1f1c983">BillboardZAxis</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfab4e88ff4d7b8e2721730433aca415015">HasDetailTexture</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfa59474c5c8adec52f2c2f347b09d90daa">UseEncodedNormals</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfae374b307e10f1c2952037a42574063e9">HasColor</a>|<a href="/coding/class/classtsmesh/#classtsmesh_1abecf9557a0f4b4a582f2cae15eff21bfa43355203daf746358e0c4225e69f9291">HasTVert2
301   };
302
303   U32 getMeshType() const { return mMeshType & TypeMask; }
304   U32 getHasColor() const { return mColors.size() > 0 || mMeshType & HasColor; }
305   U32 getHasTVert2() const { return mTverts2.size() > 0 || mMeshType & HasTVert2; }
306   void setFlags(U32 flag) { mMeshType |= flag; }
307   void clearFlags(U32 flag) { mMeshType &= ~flag; }
308   U32 getFlags( U32 flag = 0xFFFFFFFF ) const { return mMeshType & flag; }
309
310   const Point3F* getNormals( S32 firstVert );
311
312   TSMeshVertexArray mVertexData;
313   U32 mNumVerts; ///< Number of verts allocated in main vertex buffer
314
315   virtual void convertToVertexData();
316
317   virtual void copySourceVertexDataFrom(const TSMesh* srcMesh);
318   /// @}
319
320   /// @name Vertex data
321   /// @{
322
323   FreeableVector<Point3F> mVerts;
324   FreeableVector<Point3F> mNorms;
325   FreeableVector<Point2F> mTverts;
326   FreeableVector<Point4F> mTangents;
327   
328   // Optional second texture uvs.
329   FreeableVector<Point2F> mTverts2;
330
331   // Optional vertex colors data.
332   FreeableVector<ColorI> mColors;
333   /// @}
334
335   Vector<TSDrawPrimitive> mPrimitives;
336   Vector<U8> mEncodedNorms;
337   Vector<U32> mIndices;
338
339   /// billboard data
340   Point3F mBillboardAxis;
341
342   /// @name Convex Hull Data
343   /// Convex hulls are convex (no angles >= 180º) meshes used for collision
344   /// @{
345
346   Vector<Point3F> mPlaneNormals;
347   Vector<F32>     mPlaneConstants;
348   Vector<U32>     mPlaneMaterials;
349   S32 mPlanesPerFrame;
350   U32 mMergeBufferStart;
351   /// @}
352
353   /// @name Render Methods
354   /// @{
355
356   /// This is used by sgShadowProjector to render the 
357   /// mesh directly, skipping the render manager.
358   virtual void render( TSVertexBufferHandle &vb );
359   void innerRender( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb );
360   virtual void render( TSMaterialList *, 
361                        const TSRenderState &data,
362                        bool isSkinDirty,
363                        const Vector<MatrixF> &transforms, 
364                        TSVertexBufferHandle &vertexBuffer,
365                        const char *meshName);
366
367   void innerRender( TSMaterialList *, const TSRenderState &data, TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb, const char *meshName );
368
369   /// @}
370
371   /// @name Material Methods
372   /// @{
373   void setFade( F32 fade ) { mVisibility = fade; }
374   void clearFade() { setFade( 1.0f ); }
375   /// @}
376
377   /// @name Collision Methods
378   /// @{
379
380   virtual bool buildPolyList( S32 frame, AbstractPolyList * polyList, U32 & surfaceKey, TSMaterialList* materials );
381   virtual bool getFeatures( S32 frame, const MatrixF&, const VectorF&, ConvexFeature*, U32 &surfaceKey );
382   virtual void support( S32 frame, const Point3F &v, F32 *currMaxDP, Point3F *currSupport );
383   virtual bool castRay( S32 frame, const Point3F & start, const Point3F & end, RayInfo * rayInfo, TSMaterialList* materials );
384   virtual bool castRayRendered( S32 frame, const Point3F & start, const Point3F & end, RayInfo * rayInfo, TSMaterialList* materials );
385   virtual bool buildConvexHull(); ///< returns false if not convex (still builds planes)
386   bool addToHull( U32 idx0, U32 idx1, U32 idx2 );
387   /// @}
388
389   /// @name Bounding Methods
390   /// calculate and get bounding information
391   /// @{
392
393   void computeBounds();
394   virtual void computeBounds( const MatrixF &transform, Box3F &bounds, S32 frame = 0, Point3F *center = NULL, F32 *radius = NULL );
395   void computeBounds( const Point3F *, S32 numVerts, S32 stride, const MatrixF &transform, Box3F &bounds, Point3F *center, F32 *radius );
396   const Box3F& getBounds() const { return mBounds; }
397   const Point3F& getCenter() const { return mCenter; }
398   F32 getRadius() const { return mRadius; }
399   virtual S32 getNumPolys() const;
400
401   static U8 encodeNormal( const Point3F &normal );
402   static const Point3F& decodeNormal( U8 ncode ) { return smU8ToNormalTable[ncode]; }
403   /// @}
404
405   virtual U32 getMaxBonesPerVert() { return 0; }
406
407   /// persist methods...
408   virtual void assemble( bool skip );
409   static TSMesh* assembleMesh( U32 meshType, bool skip );
410   virtual void disassemble();
411
412   void createTangents(const Vector<Point3F> &_verts, const Vector<Point3F> &_norms);
413   void findTangent( U32 index1, 
414                     U32 index2, 
415                     U32 index3, 
416                     Point3F *tan0, 
417                     Point3F *tan1,
418                     const Vector<Point3F> &_verts);
419
420   /// on load...optionally convert primitives to other form
421   static bool smUseTriangles;
422   static bool smUseOneStrip;
423   static S32  smMinStripSize;
424   static bool smUseEncodedNormals;
425
426   /// Enables mesh instancing on non-skin meshes that
427   /// have less that this count of verts.
428   static S32 smMaxInstancingVerts;
429
430   /// Default node transform for standard meshes which have blend indices
431   static MatrixF smDummyNodeTransform;
432
433   /// convert primitives on load...
434   void convertToTris(const TSDrawPrimitive *primitivesIn, const S32 *indicesIn,
435                      S32 numPrimIn, S32 & numPrimOut, S32 & numIndicesOut,
436                      TSDrawPrimitive *primitivesOut, S32 *indicesOut) const;
437   void convertToSingleStrip(const TSDrawPrimitive *primitivesIn, const S32 *indicesIn,
438                             S32 numPrimIn, S32 &numPrimOut, S32 &numIndicesOut,
439                             TSDrawPrimitive *primitivesOut, S32 *indicesOut) const;
440   void leaveAsMultipleStrips(const TSDrawPrimitive *primitivesIn, const S32 *indicesIn,
441                              S32 numPrimIn, S32 &numPrimOut, S32 &numIndicesOut,
442                              TSDrawPrimitive *primitivesOut, S32 *indicesOut) const;
443
444   /// Moves vertices from the vertex buffer back into the split vert lists, unless verts already exist
445   virtual void makeEditable();
446
447   /// Clears split vertex lists
448   virtual void clearEditable();
449
450   void updateMeshFlags();
451
452   /// methods used during assembly to share vertexand other info
453   /// between meshes (and for skipping detail levels on load)
454   S32* getSharedData32( S32 parentMesh, S32 size, S32 **source, bool skip );
455   S8* getSharedData8( S32 parentMesh, S32 size, S8  **source, bool skip );
456
457   /// @name Assembly Variables
458   /// variables used during assembly (for skipping mesh detail levels
459   /// on load and for sharing verts between meshes)
460   /// @{
461
462   static Vector<Point3F*> smVertsList;
463   static Vector<Point3F*> smNormsList;
464   static Vector<U8*>      smEncodedNormsList;
465   
466   static Vector<Point2F*> smTVertsList;
467
468   // Optional second texture uvs.
469   static Vector<Point2F*> smTVerts2List;
470
471   // Optional vertex colors.
472   static Vector<ColorI*> smColorsList;
473
474   static Vector<bool>     smDataCopied;
475
476   static const Point3F smU8ToNormalTable[];
477   /// @}
478
479
480   TSMesh();
481   virtual ~TSMesh();
482   
483   Opcode::Model *mOptTree;
484   Opcode::MeshInterface* mOpMeshInterface;
485   IceMaths::IndexedTriangle* mOpTris;
486   IceMaths::Point* mOpPoints;
487
488   void prepOpcodeCollision();
489   bool buildConvexOpcode( const MatrixF &mat, const Box3F &bounds, Convex *c, Convex *list );
490   bool buildPolyListOpcode( const S32 od, AbstractPolyList *polyList, const Box3F &nodeBox, TSMaterialList *materials );
491   bool castRayOpcode( const Point3F &start, const Point3F &end, RayInfo *rayInfo, TSMaterialList *materials );
492
493   void dumpPrimitives(U32 startVertex, U32 startIndex, GFXPrimitive *piArray, U16* ibIndices);
494   virtual U32 getNumVerts();
495
496   static const F32 VISIBILITY_EPSILON; 
497};
498
499
500class TSSkinMesh : public TSMesh
501{
502public:
503   struct BatchData
504   {
505      enum Constants
506      {
507         maxBonePerVert = 16,  // Assumes a maximum of 4 blocks of bone indices for HW skinning
508      };
509
510      /// @name Batch by vertex
511      /// These are used for batches where each element is a vertex, built by
512      /// iterating over 0..maxBonePerVert bone transforms
513      /// @{
514      struct TransformOp
515      {
516         S32 transformIndex;
517         F32 weight;
518
519         TransformOp() : transformIndex( -1 ), weight( -1.0f ) {}
520         TransformOp( const S32 tIdx, const F32 w ) :  transformIndex( tIdx ), weight( w ) {};
521      };
522
523      struct BatchedVertex
524      {
525         S32 vertexIndex;
526         S32 transformCount;
527         TransformOp transform[maxBonePerVert];
528
529         BatchedVertex() : vertexIndex( -1 ), transformCount( -1 ) {}
530      };
531
532      Vector<BatchedVertex> vertexBatchOperations;
533      /// @}
534
535      // # = num bones
536      Vector<S32> nodeIndex;
537      Vector<MatrixF> initialTransforms;
538
539      // # = numverts
540      Vector<Point3F> initialVerts;
541      Vector<Point3F> initialNorms;
542
543      bool initialized;
544
545      BatchData() : initialized(false) { ; }
546   };
547
548   /// This method will build the batch operations and prepare the BatchData
549   /// for use.
550   void createSkinBatchData();
551
552   /// Inserts transform indices and weights into vertex data
553   void setupVertexTransforms();
554
555   /// Returns maximum bones used per vertex
556   virtual U32 getMaxBonesPerVert();
557
558   virtual void convertToVertexData();
559   virtual void copySourceVertexDataFrom(const TSMesh* srcMesh);
560
561   void printVerts();
562
563   void addWeightsFromVertexBuffer();
564
565   void makeEditable();
566   void clearEditable();
567
568public:
569   typedef TSMesh Parent;
570   
571   /// @name Vertex tuples
572   /// {
573   FreeableVector<F32> weight;      ///< blend weight
574   FreeableVector<S32> boneIndex;   ///< Maps from mesh node to bone in shape
575   FreeableVector<S32> vertexIndex; ///< index of affected vertex
576   /// }
577
578   /// Maximum number of bones referenced by this skin mesh
579   S32 maxBones;
580
581   /// Structure containing data needed to batch skinning
582   BatchData batchData;
583
584   /// set verts and normals...
585   void updateSkinBuffer( const Vector<MatrixF> &transforms, U8 *buffer );
586
587   /// update bone transforms for this mesh
588   void updateSkinBones( const Vector<MatrixF> &transforms, Vector<MatrixF>& destTransforms );
589
590   // render methods..
591   void render( TSVertexBufferHandle &instanceVB );
592   void render(   TSMaterialList *, 
593                  const TSRenderState &data,
594                  bool isSkinDirty,
595                  const Vector<MatrixF> &transforms, 
596                  TSVertexBufferHandle &vertexBuffer,
597                  const char *meshName );
598
599   // collision methods...
600   bool buildPolyList( S32 frame, AbstractPolyList *polyList, U32 &surfaceKey, TSMaterialList *materials );
601   bool castRay( S32 frame, const Point3F &start, const Point3F &end, RayInfo *rayInfo, TSMaterialList *materials );
602   bool buildConvexHull(); // does nothing, skins don't use this
603
604   void computeBounds( const MatrixF &transform, Box3F &bounds, S32 frame, Point3F *center, F32 *radius );
605
606   /// persist methods...
607   void assemble( bool skip );
608   void disassemble();
609
610   /// Helper method to add a blend tuple for a vertex
611   inline void addWeightForVert(U32 vi, U32 bi, F32 w)
612   {
613      weight.push_back(w);
614      boneIndex.push_back(bi);
615      vertexIndex.push_back(vi);
616   }
617
618   /// variables used during assembly (for skipping mesh detail levels
619   /// on load and for sharing verts between meshes)
620   static Vector<MatrixF*> smInitTransformList;
621   static Vector<S32*>     smVertexIndexList;
622   static Vector<S32*>     smBoneIndexList;
623   static Vector<F32*>     smWeightList;
624   static Vector<S32*>     smNodeIndexList;
625
626   static bool smDebugSkinVerts;
627
628   TSSkinMesh();
629};
630
631
632#endif // _TSMESH_H_
633