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