tsShape.h 26 KB

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