tsShape.h

Engine/source/ts/tsShape.h

More...

Classes:

class

TSShape stores generic data for a 3space model.

class

Details are used for render detail selection.

class

Nodes hold the transforms in the shape's tree. They are the bones of the skeleton.

class

Objects hold renderable items (in particular meshes).

class

Describes state of an individual object.

class

A Sequence holds all the information necessary to perform a particular animation (sequence).

class

When time on a sequence advances past a certain point, a trigger takes effect and changes one of the state variables to on or off.

class

Data storage helper for main shape buffer.

Public Defines

define
define
define
define

Detailed Description

Public Defines

DTS_EXPORTER_CURRENT_VERSION() 124
TSDetail() 
TSNode() 
TSObject() 
TSSequence() 
  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 _TSSHAPE_H_
 25#define _TSSHAPE_H_
 26
 27#ifndef _TSMESH_H_
 28#include "ts/tsMesh.h"
 29#endif
 30#ifndef _TSINTEGERSET_H_
 31#include "ts/tsIntegerSet.h"
 32#endif
 33#ifndef _TSTRANSFORM_H_
 34#include "ts/tsTransform.h"
 35#endif
 36#ifndef _TSSHAPEALLOC_H_
 37#include "ts/tsShapeAlloc.h"
 38#endif
 39
 40
 41#define DTS_EXPORTER_CURRENT_VERSION 124
 42
 43class TSMaterialList;
 44class TSLastDetail;
 45class PhysicsCollision;
 46
 47//
 48struct CollisionShapeInfo
 49{
 50   S32 colNode;
 51   PhysicsCollision *colShape;
 52};
 53
 54/// Data storage helper for main shape buffer
 55struct TSShapeVertexArray
 56{
 57   U8 *base;
 58   U32 size;
 59   bool vertexDataReady;
 60
 61   TSShapeVertexArray() : base(NULL), size(0), vertexDataReady(false) {}
 62   virtual ~TSShapeVertexArray() { set(NULL, 0); }
 63
 64   virtual void set(void *b, U32 s, bool autoFree = true)
 65   {
 66      if (base && autoFree)
 67         dFree_aligned(base);
 68      base = reinterpret_cast<U8 *>(b);
 69      size = s;
 70   }
 71};
 72
 73/// TSShape stores generic data for a 3space model.
 74///
 75/// TSShape and TSShapeInstance act in conjunction to allow the rendering and
 76/// manipulation of a three dimensional model.
 77///
 78/// @note The material lists are the only thing that is not loaded in TSShape.
 79/// instead, they are loaded in TSShapeInstance because of a former restriction
 80/// on the resource manager where only one file could be opened at a time.
 81/// The resource manager restriction has been resolved, but the material
 82/// lists are still loaded in TSShapeInstance.
 83///
 84/// @see TSShapeInstance for a further discussion of the 3space system.
 85class TSShape
 86{
 87  public:
 88      enum
 89      {
 90         UniformScale   = BIT(0),
 91         AlignedScale   = BIT(1),
 92         ArbitraryScale = BIT(2),
 93         Blend          = BIT(3),
 94         Cyclic         = BIT(4),
 95         MakePath       = BIT(5),
 96         HasTranslucency= BIT(6),
 97         AnyScale       = UniformScale | AlignedScale | ArbitraryScale
 98      };
 99
100   /// Nodes hold the transforms in the shape's tree.  They are the bones of the skeleton.
101   struct Node
102   {
103      S32 nameIndex;
104      S32 parentIndex;
105
106      // computed at runtime
107      S32 firstObject;
108      S32 firstChild;
109      S32 nextSibling;
110   };
111
112   /// Objects hold renderable items (in particular meshes).
113   ///
114   /// Each object has a number of meshes associated with it.
115   /// Each mesh corresponds to a different detail level.
116   ///
117   /// meshIndicesIndex points to numMeshes consecutive indices
118   /// into the meshList and meshType vectors.  It indexes the
119   /// meshIndexList vector (meshIndexList is merely a clearinghouse
120   /// for the object's mesh lists).  Some indices may correspond to
121   /// no mesh -- which means no mesh will be drawn for the part for
122   /// the given detail level.  See comments on the meshIndexList
123   /// for how null meshes are coded.
124   ///
125   /// @note Things are stored this way so that there are no pointers.
126   ///       This makes serialization to disk dramatically simpler.
127   struct Object
128   {
129      S32 nameIndex;
130      S32 numMeshes;
131      S32 startMeshIndex; ///< Index into meshes array.
132      S32 nodeIndex;
133
134      // computed at load
135      S32 nextSibling;
136      S32 firstDecal; // DEPRECATED
137   };
138
139   /// A Sequence holds all the information necessary to perform a particular animation (sequence).
140   ///
141   /// Sequences index a range of keyframes. Keyframes are assumed to be equally spaced in time.
142   ///
143   /// Each node and object is either a member of the sequence or not.  If not, they are set to
144   /// default values when we switch to the sequence unless they are members of some other active sequence.
145   /// Blended sequences "add" a transform to the current transform of a node.  Any object animation of
146   /// a blended sequence over-rides any existing object state.  Blended sequences are always
147   /// applied after non-blended sequences.
148   struct Sequence
149   {
150      S32 nameIndex;
151      S32 numKeyframes;
152      F32 duration;
153      S32 baseRotation;
154      S32 baseTranslation;
155      S32 baseScale;
156      S32 baseObjectState;
157      S32 baseDecalState; // DEPRECATED
158      S32 firstGroundFrame;
159      S32 numGroundFrames;
160      S32 firstTrigger;
161      S32 numTriggers;
162      F32 toolBegin;
163
164      /// @name Bitsets
165      /// These bitsets code whether this sequence cares about certain aspects of animation
166      /// e.g., the rotation, translation, or scale of node transforms,
167      /// or the visibility, frame or material frame of objects.
168      /// @{
169
170      TSIntegerSet rotationMatters;     ///< Set of nodes
171      TSIntegerSet translationMatters;  ///< Set of nodes
172      TSIntegerSet scaleMatters;        ///< Set of nodes
173      TSIntegerSet visMatters;          ///< Set of objects
174      TSIntegerSet frameMatters;        ///< Set of objects
175      TSIntegerSet matFrameMatters;     ///< Set of objects
176      /// @}
177
178      S32 priority;
179      U32 flags;
180      U32 dirtyFlags; ///< determined at load time
181
182      /// @name Source Data
183      /// Store some information about where the sequence data came from (used by
184      /// TSShapeConstructor and the Shape Editor)
185      /// @{
186      struct SeqSourceData
187      {
188         String from;         // The source sequence (ie. a DSQ file)
189         S32 start;           // The first frame in the source sequence
190         S32 end;             // The last frame in the source sequence
191         S32 total;           // The total number of frames in the source sequence
192         String blendSeq;     // The blend reference sequence
193         S32 blendFrame;      // The blend reference frame
194         SeqSourceData() : from("\t"), start(0), end(0), total(0), blendSeq(""), blendFrame(0) { }
195      } sourceData;
196
197      /// @name Flag Tests
198      /// Each of these tests a different flag against the object's flag list
199      /// to determine the attributes of the given object.
200      /// @{
201
202      bool testFlags(U32 comp) const      { return (flags&comp)!=0; }
203      bool animatesScale() const          { return testFlags(AnyScale); }
204      bool animatesUniformScale() const   { return testFlags(UniformScale); }
205      bool animatesAlignedScale() const   { return testFlags(AlignedScale); }
206      bool animatesArbitraryScale() const { return testFlags(ArbitraryScale); }
207      bool isBlend() const                { return testFlags(Blend); }
208      bool isCyclic() const               { return testFlags(Cyclic); }
209      bool makePath() const               { return testFlags(MakePath); }
210      /// @}
211
212      /// @name IO
213      /// @{
214
215      void read(Stream *, bool readNameIndex = true);
216      void write(Stream *, bool writeNameIndex = true) const;
217      /// @}
218   };
219
220   /// Describes state of an individual object.  Includes everything in an object that can be
221   /// controlled by animation.
222   struct ObjectState
223   {
224      F32 vis;
225      S32 frameIndex;
226      S32 matFrameIndex;
227   };
228
229   /// When time on a sequence advances past a certain point, a trigger takes effect and changes
230   /// one of the state variables to on or off. (State variables found in TSShapeInstance::mTriggerStates)
231   struct Trigger
232   {
233      enum TriggerStates
234      {
235         StateOn = BIT(31),
236         InvertOnReverse = BIT(30),
237         StateMask = BIT(30)-1
238      };
239
240      U32 state; ///< One of TriggerStates
241      F32 pos;
242   };
243
244   /// Details are used for render detail selection.
245   ///
246   /// As the projected size of the shape changes,
247   /// a different node structure can be used (subShape) and a different objectDetail can be selected
248   /// for each object drawn.   Either of these two parameters can also stay constant, but presumably
249   /// not both.  If size is negative then the detail level will never be selected by the standard
250   /// detail selection process.  It will have to be selected by name.  Such details are "utility
251   /// details" because they exist to hold data (node positions or collision information) but not
252   /// normally to be drawn.  By default there will always be a "Ground" utility detail.
253   ///
254   /// Note that this struct should always be 32bit aligned
255   /// as its required by assembleShape/disassembleShape.
256   struct Detail
257   {
258      S32 nameIndex;
259      S32 subShapeNum;
260      S32 objectDetailNum;
261      F32 size;
262      F32 averageError;
263      F32 maxError;
264      S32 polyCount;
265
266      /// These values are new autobillboard settings stored
267      /// as part of the Detail struct in version 26 and above.
268      /// @{
269
270      S32 bbDimension;     ///< The size of the autobillboard image.
271      S32 bbDetailLevel;   ///< The detail to render as the autobillboard.
272      U32 bbEquatorSteps;  ///< The number of autobillboard images to capture around the equator.
273      U32 bbPolarSteps;    ///< The number of autobillboard images to capture along the pole.
274      F32 bbPolarAngle;    ///< The angle in radians at which the top/bottom autobillboard images should be displayed.
275      U32 bbIncludePoles;  ///< If non-zero then top and bottom images are generated for the autobillboard.
276
277      /// @}
278   };
279
280   /// @name Collision Accelerators
281   ///
282   /// For speeding up buildpolylist and support calls.
283   /// @{
284   struct ConvexHullAccelerator {
285      S32      numVerts;
286      Point3F* vertexList;
287      Point3F* normalList;
288      U8**     emitStrings;
289   };
290   ConvexHullAccelerator* getAccelerator(S32 dl);
291   /// @}
292
293
294   /// @name Shape Vector Data
295   /// @{
296
297   Vector<Node> nodes;
298   Vector<Object> objects;
299   Vector<ObjectState> objectStates;
300   Vector<S32> subShapeFirstNode;
301   Vector<S32> subShapeFirstObject;
302   Vector<S32> detailFirstSkin;
303   Vector<S32> subShapeNumNodes;
304   Vector<S32> subShapeNumObjects;
305   Vector<Detail> details;
306   Vector<Quat16> defaultRotations;
307   Vector<Point3F> defaultTranslations;
308
309   /// @}
310
311   /// These are set up at load time, but memory is allocated along with loaded data
312   /// @{
313
314   Vector<S32> subShapeFirstTranslucentObject;
315   Vector<TSMesh*> meshes;
316
317   /// @}
318
319   /// @name Alpha Vectors
320   /// these vectors describe how to transition between detail
321   /// levels using alpha. "alpha-in" next detail as intraDL goes
322   /// from alphaIn+alphaOut to alphaOut. "alpha-out" current
323   /// detail level as intraDL goes from alphaOut to 0.
324   /// @note
325   ///   - intraDL is at 1 when if shape were any closer to us we'd be at dl-1
326   ///   - intraDL is at 0 when if shape were any farther away we'd be at dl+1
327   /// @{
328
329   Vector<F32> alphaIn;
330   Vector<F32> alphaOut
331      ;
332   /// @}
333
334   /// @name Resizeable vectors
335   /// @{
336
337   Vector<Sequence>                 sequences;
338   Vector<Quat16>                   nodeRotations;
339   Vector<Point3F>                  nodeTranslations;
340   Vector<F32>                      nodeUniformScales;
341   Vector<Point3F>                  nodeAlignedScales;
342   Vector<Quat16>                   nodeArbitraryScaleRots;
343   Vector<Point3F>                  nodeArbitraryScaleFactors;
344   Vector<Quat16>                   groundRotations;
345   Vector<Point3F>                  groundTranslations;
346   Vector<Trigger>                  triggers;
347   Vector<TSLastDetail*>            billboardDetails;
348   Vector<ConvexHullAccelerator*>   detailCollisionAccelerators;
349   Vector<String>                   names;
350
351   /// @}
352
353   TSMaterialList * materialList;
354
355   /// @name Bounding
356   /// @{
357
358   F32 mRadius;
359   F32 tubeRadius;
360   Point3F center;
361   Box3F mBounds;
362
363   /// @}
364
365   // various...
366   U32 mExporterVersion;
367   F32 mSmallestVisibleSize;  ///< Computed at load time from details vector.
368   S32 mSmallestVisibleDL;    ///< @see mSmallestVisibleSize
369   S32 mReadVersion;          ///< File version that this shape was read from.
370   U32 mFlags;                ///< hasTranslucancy
371   U32 data;                  ///< User-defined data storage.
372
373   /// If enabled detail selection will use the
374   /// legacy screen error method for lod.
375   /// @see setDetailFromScreenError
376   bool mUseDetailFromScreenError;
377
378   // TODO: This would be nice as Tuple<>
379   struct LodPair
380   {
381      S8 level; // -1 to 128
382      U8 intra; // encoded 0 to 1
383
384      inline void set( S32 dl, F32 intraDL )
385      {
386         level = (S8)dl;
387         intra = (S8)( intraDL * 255.0f );
388      }
389
390      inline void get( S32 &dl, F32 &intraDL )
391      {
392         dl = level;
393         intraDL = (F32)intra / 255.0f;
394      }
395   };
396
397   /// The lod lookup table where we mark down the detail
398   /// level and intra-detail level for each pixel size.
399   Vector<LodPair> mDetailLevelLookup;
400
401   /// The GFX vertex format for all detail meshes in the shape.
402   /// @see initVertexFeatures()
403   GFXVertexFormat mVertexFormat;
404   TSBasicVertexFormat mBasicVertexFormat;
405   U32 mVertexSize;
406
407   S8* mShapeData;
408   U32 mShapeDataSize;
409
410
411   // Processed vertex data
412   TSShapeVertexArray mShapeVertexData;
413   TSVertexBufferHandle mShapeVertexBuffer;
414   GFXPrimitiveBufferHandle mShapeVertexIndices;
415
416   bool mSequencesConstructed;
417   bool mNeedReinit;
418
419
420   // shape class has few methods --
421   // just constructor/destructor, io, and lookup methods
422
423   // constructor/destructor
424   TSShape();
425   ~TSShape();
426   void init();
427   void initMaterialList();    ///< you can swap in a new material list, but call this if you do
428   void finalizeEditable();
429   bool preloadMaterialList(const Torque::Path &path); ///< called to preload and validate the materials in the mat list
430
431   void setupBillboardDetails( const String &cachePath );
432
433   /// Inits object list (no geometry buffers)
434   void initObjects();
435
436   /// Initializes the main vertex buffer
437   void initVertexBuffers();
438
439   /// Loads shape vertex data into specified buffer
440   void getVertexBuffer(TSVertexBufferHandle &vb, GFXBufferType bufferType);
441
442   /// Called from init() to calcuate the GFX vertex features for
443   /// all detail meshes in the shape.
444   void initVertexFeatures();
445
446   /// Inits basic buffer pointers on load
447   void initVertexBufferPointers();
448
449   bool getSequencesConstructed() const { return mSequencesConstructed; }
450   void setSequencesConstructed(const bool c) { mSequencesConstructed = c; }
451
452   /// @name Lookup Animation Info
453   /// indexed by keyframe number and offset (which object/node/decal
454   /// of the animated objects/nodes/decals you want information for).
455   /// @{
456
457   QuatF & getRotation(const Sequence & seq, S32 keyframeNum, S32 rotNum, QuatF *) const;
458   const Point3F & getTranslation(const Sequence & seq, S32 keyframeNum, S32 tranNum) const;
459   F32 getUniformScale(const Sequence & seq, S32 keyframeNum, S32 scaleNum) const;
460   const Point3F & getAlignedScale(const Sequence & seq, S32 keyframeNum, S32 scaleNum) const;
461   TSScale & getArbitraryScale(const Sequence & seq, S32 keyframeNum, S32 scaleNum, TSScale *) const;
462   const ObjectState & getObjectState(const Sequence & seq, S32 keyframeNum, S32 objectNum) const;
463   /// @}
464
465   /// build LOS collision detail
466   void computeAccelerator(S32 dl);
467   bool buildConvexHull(S32 dl) const;
468   void computeBounds(S32 dl, Box3F & bounds) const; // uses default transforms to compute bounding box around a detail level
469                                                     // see like named method on shapeInstance if you want to use animated transforms
470
471   /// Used to find collision detail meshes in the DTS.
472   ///
473   /// @param useVisibleMesh If true return the highest visible detail level.
474   /// @param outDetails The output detail index vector.
475   /// @param outLOSDetails The optional output LOS detail vector.
476   ///
477   void findColDetails( bool useVisibleMesh, Vector<S32> *outDetails, Vector<S32> *outLOSDetails ) const;
478
479   /// Builds a physics collision shape at the requested scale.
480   ///
481   /// If using the visible mesh one or more triangle meshes are created
482   /// from the first visible detail level.
483   ///
484   /// If using collision meshes we look for mesh names prefixed with the
485   /// following hints:
486   //
487   ///  "colbox"
488   ///  "colsphere"
489   ///  "colcapsule"
490   ///  "colmesh"
491   ///
492   /// In the case of the primitives the mesh bounding box is used to generate
493   /// a box, sphere, or capsule collision shape.  The "colmesh" will create a
494   /// concave triangle mesh for collision.
495   ///
496   /// Any other named collision shape is interpreted as a regular convex hull.
497   ///
498   /// @return The collision object or NULL if no collision data could be generated.
499   ///
500   PhysicsCollision* buildColShape( bool useVisibleMesh, const Point3F &scale );
501   
502   /// Like buildColShape except we build one PhysicsCollision object per 
503   /// collision node.
504   ///
505   /// Results are returned by filling in the CollisionShapeInfo Vector, which also
506   /// specifies the collision node index for each PhysicsCollision built.
507   ///
508   void buildColShapes( bool useVisibleMesh, const Point3F &scale, Vector< CollisionShapeInfo> *list );
509
510   /// For internal use.
511   PhysicsCollision* _buildColShapes( bool useVisibleMesh, const Point3F &scale, Vector< CollisionShapeInfo> *list, bool perMesh );
512
513   /// @name Lookup Methods
514   /// @{
515
516   /// Returns index into the name vector that equals the passed name.
517   S32 findName( const String &name ) const;
518   
519   /// Returns name string at the passed name vector index.
520   const String& getName( S32 nameIndex ) const;
521   
522   /// Returns name string for mesh at the passed index.
523   const String& getMeshName( S32 meshIndex ) const;
524   
525   /// Returns name string for node at the passed index.
526   const String& getNodeName( S32 nodeIndex ) const;
527   
528   /// Returns name string for sequence at the passed index.
529   const String& getSequenceName( S32 seqIndex ) const;
530
531   S32 getTargetCount() const;
532   const String& getTargetName( S32 mapToNameIndex ) const;
533
534   S32 findNode(S32 nameIndex) const;
535   S32 findNode(const String &name) const { return findNode(findName(name)); }
536
537   S32 findObject(S32 nameIndex) const;
538   S32 findObject(const String &name) const { return findObject(findName(name)); }
539
540   S32 findDetail(S32 nameIndex) const;
541   S32 findDetail(const String &name) const { return findDetail(findName(name)); }
542   S32 findDetailBySize(S32 size) const;
543
544   S32 findSequence(S32 nameIndex) const;
545   S32 findSequence(const String &name) const { return findSequence(findName(name)); }
546
547   S32 getSubShapeForNode(S32 nodeIndex);
548   S32 getSubShapeForObject(S32 objIndex);
549   void getSubShapeDetails(S32 subShapeIndex, Vector<S32>& validDetails);
550
551   void getNodeWorldTransform(S32 nodeIndex, MatrixF* mat) const;
552   void getNodeKeyframe(S32 nodeIndex, const TSShape::Sequence& seq, S32 keyframe, MatrixF* mat) const;
553   void getNodeObjects(S32 nodeIndex, Vector<S32>& nodeObjects);
554   void getNodeChildren(S32 nodeIndex, Vector<S32>& nodeChildren);
555
556   void getObjectDetails(S32 objIndex, Vector<S32>& objDetails);
557
558   bool findMeshIndex(const String &meshName, S32& objIndex, S32& meshIndex);
559   TSMesh* findMesh(const String &meshName);
560
561   bool hasTranslucency() const { return (mFlags & HasTranslucency)!=0; }
562
563   const GFXVertexFormat* getVertexFormat() const { return &mVertexFormat; }
564
565   /// @}
566
567   /// @name Alpha Transitions
568   /// These control default values for alpha transitions between detail levels
569   /// @{
570
571   static F32 smAlphaOutLastDetail;
572   static F32 smAlphaInBillboard;
573   static F32 smAlphaOutBillboard;
574   static F32 smAlphaInDefault;
575   static F32 smAlphaOutDefault;
576   /// @}
577
578   /// don't load this many of the highest detail levels (although we always
579   /// load one renderable detail if there is one)
580   static S32 smNumSkipLoadDetails;
581
582   /// by default we initialize shape when we read...
583   static bool smInitOnRead;
584
585   /// Enables hardware skinning features
586   static bool smUseHardwareSkinning;
587
588   /// Determines maximum number of bones to use in hardware skinning shaders
589   static U32 smMaxSkinBones;
590
591   /// @name Version Info
592   /// @{
593
594   /// Most recent version...the one we write
595   static S32 smVersion;
596   /// Version currently being read, only valid during read
597   static S32 smReadVersion;
598   static const U32 smMostRecentExporterVersion;
599   ///@}
600
601   /// @name Persist Methods
602   /// Methods for saving/loading shapes to/from streams
603   /// @{
604
605   bool canWriteOldFormat() const;
606   void write(Stream *, bool saveOldFormat=false);
607   bool read(Stream *);
608   void readOldShape(Stream * s, S32 * &, S16 * &, S8 * &, S32 &, S32 &, S32 &);
609   void writeName(Stream *, S32 nameIndex);
610   S32  readName(Stream *, bool addName);
611
612   /// Initializes our TSShape to be ready to receive put mesh data
613   void createEmptyShape();
614
615   void exportSequences(Stream *);
616   void exportSequence(Stream * s, const TSShape::Sequence& seq, bool saveOldFormat);
617   bool importSequences(Stream *, const String& sequencePath);
618
619   /// @}
620
621   /// @name Persist Helper Functions
622   /// @{
623
624   static TSShapeAlloc smTSAlloc;
625
626   void fixEndian(S32 *, S16 *, S8 *, S32, S32, S32);
627   /// @}
628
629   /// @name Memory Buffer Transfer Methods
630   /// uses TSShape::Alloc structure
631   /// @{
632
633   void assembleShape();
634   void disassembleShape();
635   ///@}
636
637   /// mem buffer transfer helper (indicate when we don't want to include a particular mesh/decal)
638   bool checkSkip(S32 meshNum, S32 & curObject, S32 skipDL);
639
640   void fixupOldSkins(S32 numMeshes, S32 numSkins, S32 numDetails, S32 * detFirstSkin, S32 * detailNumSkins);
641
642   /// @name Shape Editing
643   /// @{
644   S32 addName(const String& name);
645   bool removeName(const String& name);
646   void updateSmallestVisibleDL();
647   S32 addDetail(const String& dname, S32 size, S32 subShapeNum);
648
649   S32 addImposter(  const String& cachePath,
650                     S32 size,
651                     S32 numEquatorSteps,
652                     S32 numPolarSteps,
653                     S32 dl,
654                     S32 dim,
655                     bool includePoles,
656                     F32 polarAngle );
657   bool removeImposter();
658
659   bool renameNode(const String& oldName, const String& newName);
660   bool renameObject(const String& oldName, const String& newName);
661   bool renameDetail(const String& oldName, const String& newName);
662   bool renameSequence(const String& oldName, const String& newName);
663
664   bool setNodeTransform(const String& name, const Point3F& pos, const QuatF& rot);
665   bool addNode(const String& name, const String& parentName, const Point3F& pos, const QuatF& rot);
666   bool removeNode(const String& name);
667
668   S32 addObject(const String& objName, S32 subShapeIndex);
669   void addMeshToObject(S32 objIndex, S32 meshIndex, TSMesh* mesh);
670   void removeMeshFromObject(S32 objIndex, S32 meshIndex);
671   bool setObjectNode(const String& objName, const String& nodeName);
672   bool removeObject(const String& objName);
673
674   TSMesh* copyMesh( const TSMesh* srcMesh ) const;
675   bool addMesh(TSShape* srcShape, const String& srcMeshName, const String& meshName);
676   bool addMesh(TSMesh* mesh, const String& meshName);
677   bool setMeshSize(const String& meshName, S32 size);
678   bool removeMesh(const String& meshName);
679
680   S32 setDetailSize(S32 oldSize, S32 newSize);
681   bool removeDetail(S32 size);
682
683   bool addSequence(const Torque::Path& path, const String& fromSeq, const String& name, S32 startFrame, S32 endFrame, bool padRotKeys, bool padTransKeys);
684   bool removeSequence(const String& name);
685
686   bool addTrigger(const String& seqName, S32 keyframe, S32 state);
687   bool removeTrigger(const String& seqName, S32 keyframe, S32 state);
688
689   bool setSequenceBlend(const String& seqName, bool blend, const String& blendRefSeqName, S32 blendRefFrame);
690   bool setSequenceGroundSpeed(const String& seqName, const Point3F& trans, const Point3F& rot);
691
692   void makeEditable();
693   bool needsReinit();
694   bool needsBufferUpdate();
695   /// @}
696};
697
698
699#define TSNode TSShape::Node
700#define TSObject TSShape::Object
701#define TSSequence TSShape::Sequence
702#define TSDetail TSShape::Detail
703
704inline QuatF & TSShape::getRotation(const Sequence & seq, S32 keyframeNum, S32 rotNum, QuatF * quat) const
705{
706   return nodeRotations[seq.baseRotation + rotNum*seq.numKeyframes + keyframeNum].getQuatF(quat);
707}
708
709inline const Point3F & TSShape::getTranslation(const Sequence & seq, S32 keyframeNum, S32 tranNum) const
710{
711   return nodeTranslations[seq.baseTranslation + tranNum*seq.numKeyframes + keyframeNum];
712}
713
714inline F32 TSShape::getUniformScale(const Sequence & seq, S32 keyframeNum, S32 scaleNum) const
715{
716   return nodeUniformScales[seq.baseScale + scaleNum*seq.numKeyframes + keyframeNum];
717}
718
719inline const Point3F & TSShape::getAlignedScale(const Sequence & seq, S32 keyframeNum, S32 scaleNum) const
720{
721   return nodeAlignedScales[seq.baseScale + scaleNum*seq.numKeyframes + keyframeNum];
722}
723
724inline TSScale & TSShape::getArbitraryScale(const Sequence & seq, S32 keyframeNum, S32 scaleNum, TSScale * scale) const
725{
726   nodeArbitraryScaleRots[seq.baseScale + scaleNum*seq.numKeyframes + keyframeNum].getQuatF(&scale->mRotate);
727   scale->mScale = nodeArbitraryScaleFactors[seq.baseScale + scaleNum*seq.numKeyframes + keyframeNum];
728   return *scale;
729}
730
731inline const TSShape::ObjectState & TSShape::getObjectState(const Sequence & seq, S32 keyframeNum, S32 objectNum) const
732{
733   return objectStates[seq.baseObjectState + objectNum*seq.numKeyframes + keyframeNum];
734}
735
736#endif
737