tsShapeInstance.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  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 _TSSHAPEINSTANCE_H_
  23. #define _TSSHAPEINSTANCE_H_
  24. #ifndef __RESOURCE_H__
  25. #include "core/resource.h"
  26. #endif
  27. #ifndef _TSSHAPE_H_
  28. #include "ts/tsShape.h"
  29. #endif
  30. #ifndef _TSINTEGERSET_H_
  31. #include "ts/tsIntegerSet.h"
  32. #endif
  33. #ifndef _CONSOLE_H_
  34. #include "console/console.h"
  35. #endif
  36. #ifndef _GBITMAP_H_
  37. #include "gfx/bitmap/gBitmap.h"
  38. #endif
  39. #ifndef _TSRENDERDATA_H_
  40. #include "ts/tsRenderState.h"
  41. #endif
  42. #ifndef _TSMATERIALLIST_H_
  43. #include "ts/tsMaterialList.h"
  44. #endif
  45. class RenderItem;
  46. class TSThread;
  47. class ConvexFeature;
  48. class SceneRenderState;
  49. class FeatureSet;
  50. //-------------------------------------------------------------------------------------
  51. // Instance versions of shape objects
  52. //-------------------------------------------------------------------------------------
  53. class TSCallback
  54. {
  55. public:
  56. virtual ~TSCallback() {}
  57. virtual void setNodeTransform(TSShapeInstance * si, S32 nodeIndex, MatrixF & localTransform) = 0;
  58. };
  59. /// An instance of a 3space shape.
  60. ///
  61. /// @section TSShapeInstance_intro Introduction
  62. ///
  63. /// A 3space model represents a significant amount of data. There are multiple meshes,
  64. /// skeleton information, as well as animation data. Some of this, like the skeletal
  65. /// transforms, are unique for each instance of the model (as different instances are
  66. /// likely to be in different states of animation), while most of it, like texturing
  67. /// information and vertex data, is the same amongst all instances of the shape.
  68. ///
  69. /// To keep this data from being replicated for every instance of a 3shape object, Torque
  70. /// uses the ResManager to instantiate and track TSShape objects. TSShape handles reading
  71. /// and writing 3space models, as well as keeping track of static model data, as discussed
  72. /// above. TSShapeInstance keeps track of all instance specific data, such as the currently
  73. /// playing sequences or the active node transforms.
  74. ///
  75. /// TSShapeInstance contains all the functionality for 3space models, while TSShape acts as
  76. /// a repository for common data.
  77. ///
  78. /// @section TSShapeInstance_functionality What Does TSShapeInstance Do?
  79. ///
  80. /// TSShapeInstance handles several areas of functionality:
  81. /// - Collision.
  82. /// - Rendering.
  83. /// - Animation.
  84. /// - Updating skeletal transforms.
  85. /// - Ballooning (see setShapeBalloon() and getShapeBalloon())
  86. ///
  87. /// For an excellent example of how to render a TSShape in game, see TSStatic. For examples
  88. /// of how to procedurally animate models, look at Player::updateLookAnimation().
  89. class TSShapeInstance
  90. {
  91. public:
  92. struct ObjectInstance;
  93. friend class TSThread;
  94. friend class TSLastDetail;
  95. friend class TSPartInstance;
  96. /// Base class for all renderable objects, including mesh objects and decal objects.
  97. ///
  98. /// An ObjectInstance points to the renderable items in the shape...
  99. struct ObjectInstance
  100. {
  101. virtual ~ObjectInstance() {}
  102. /// this needs to be set before using an objectInstance...tells us where to
  103. /// look for the transforms...gets set be shape instance 'setStatics' method
  104. const Vector<MatrixF> *mTransforms;
  105. S32 nodeIndex;
  106. /// Gets the transform of this object
  107. inline const MatrixF& getTransform() const
  108. {
  109. return nodeIndex < 0 ? MatrixF::Identity : (*mTransforms)[ nodeIndex ];
  110. }
  111. /// @name Render Functions
  112. /// @{
  113. /// Render! This draws the base-textured object.
  114. virtual void render( S32 objectDetail, TSVertexBufferHandle &vb, TSMaterialList *, TSRenderState &rdata, F32 alpha, const char *meshName );
  115. /// Updates the vertex buffer data for this mesh (used for software skinning)
  116. virtual void updateVertexBuffer( S32 objectDetail, U8 *buffer );
  117. virtual bool bufferNeedsUpdate( S32 objectDetail );
  118. /// @}
  119. /// @name Collision Routines
  120. /// @{
  121. virtual bool buildPolyList( S32 objectDetail, AbstractPolyList *polyList, U32 &surfaceKey, TSMaterialList *materials );
  122. virtual bool getFeatures( S32 objectDetail, const MatrixF &mat, const Point3F &n, ConvexFeature *feature, U32 &surfaceKey );
  123. virtual void support( S32 od, const Point3F &v, F32 *currMaxDP, Point3F *currSupport );
  124. virtual bool buildPolyListOpcode( S32 objectDetail, AbstractPolyList *polyList, U32 &surfaceKey, TSMaterialList *materials );
  125. virtual bool castRayOpcode( S32 objectDetail, const Point3F &start, const Point3F &end, RayInfo *info, TSMaterialList *materials );
  126. virtual bool buildConvexOpcode( const MatrixF &mat, S32 objectDetail, const Box3F &bounds, Convex *c, Convex *list );
  127. /// Ray cast for collision detection
  128. virtual bool castRay( S32 objectDetail, const Point3F &start, const Point3F &end, RayInfo *info, TSMaterialList* materials ) = 0;
  129. /// @}
  130. };
  131. /// These are set up by default based on shape data
  132. struct MeshObjectInstance : ObjectInstance
  133. {
  134. TSMesh * const * meshList; ///< one mesh per detail level... Null entries allowed.
  135. const TSObject * object;
  136. S32 frame;
  137. S32 matFrame;
  138. F32 visible;
  139. /// If true this mesh is forced to be hidden
  140. /// regardless of the animation state.
  141. bool forceHidden;
  142. /// The time at which this mesh
  143. /// was last rendered.
  144. U32 mLastTime;
  145. Vector<MatrixF> mActiveTransforms;
  146. MeshObjectInstance();
  147. virtual ~MeshObjectInstance() {}
  148. void render( S32 objectDetail, TSVertexBufferHandle &vb, TSMaterialList *, TSRenderState &rdata, F32 alpha, const char *meshName );
  149. void updateVertexBuffer( S32 objectDetail, U8 *buffer );
  150. bool bufferNeedsUpdate(S32 objectDetail);
  151. /// Gets the mesh with specified detail level
  152. TSMesh * getMesh(S32 num) const { return num<object->numMeshes ? *(meshList+num) : NULL; }
  153. /// @name Collision Routines
  154. /// @{
  155. bool buildPolyList( S32 objectDetail, AbstractPolyList *polyList, U32 &surfaceKey, TSMaterialList *materials );
  156. bool getFeatures( S32 objectDetail, const MatrixF &mat, const Point3F &n, ConvexFeature *feature, U32 &surfaceKey );
  157. void support( S32 od, const Point3F &v, F32 *currMaxDP, Point3F *currSupport );
  158. bool castRay( S32 objectDetail, const Point3F &start, const Point3F &end, RayInfo *info, TSMaterialList *materials );
  159. bool castRayRendered( S32 objectDetail, const Point3F &start, const Point3F &end, RayInfo *info, TSMaterialList *materials );
  160. bool buildPolyListOpcode( S32 objectDetail, AbstractPolyList *polyList, const Box3F &box, TSMaterialList* materials );
  161. bool castRayOpcode( S32 objectDetail, const Point3F &start, const Point3F &end, RayInfo *info, TSMaterialList *materials );
  162. bool buildConvexOpcode( const MatrixF &mat, S32 objectDetail, const Box3F &bounds, Convex *c, Convex *list );
  163. /// @}
  164. };
  165. protected:
  166. struct TSCallbackRecord
  167. {
  168. TSCallback * callback;
  169. S32 nodeIndex;
  170. };
  171. //-------------------------------------------------------------------------------------
  172. // Lists used for storage of transforms, nodes, objects, etc...
  173. //-------------------------------------------------------------------------------------
  174. public:
  175. Vector<MeshObjectInstance> mMeshObjects;
  176. /// storage space for node transforms
  177. Vector<MatrixF> mNodeTransforms;
  178. /// @name Reference Transform Vectors
  179. /// unused until first transition
  180. /// @{
  181. Vector<Quat16> mNodeReferenceRotations;
  182. Vector<Point3F> mNodeReferenceTranslations;
  183. Vector<F32> mNodeReferenceUniformScales;
  184. Vector<Point3F> mNodeReferenceScaleFactors;
  185. Vector<Quat16> mNodeReferenceArbitraryScaleRots;
  186. /// @}
  187. /// @name Workspace for Node Transforms
  188. /// @{
  189. static Vector<QuatF> smNodeCurrentRotations;
  190. static Vector<Point3F> smNodeCurrentTranslations;
  191. static Vector<F32> smNodeCurrentUniformScales;
  192. static Vector<Point3F> smNodeCurrentAlignedScales;
  193. static Vector<TSScale> smNodeCurrentArbitraryScales;
  194. static Vector<MatrixF> smNodeLocalTransforms;
  195. static TSIntegerSet smNodeLocalTransformDirty;
  196. /// @}
  197. /// @name Threads
  198. /// keep track of who controls what on currently animating shape
  199. /// @{
  200. static Vector<TSThread*> smRotationThreads;
  201. static Vector<TSThread*> smTranslationThreads;
  202. static Vector<TSThread*> smScaleThreads;
  203. /// @}
  204. TSMaterialList* mMaterialList; ///< by default, points to hShape material list
  205. //-------------------------------------------------------------------------------------
  206. // Misc.
  207. //-------------------------------------------------------------------------------------
  208. protected:
  209. /// @name Ground Transform Data
  210. /// @{
  211. MatrixF mGroundTransform;
  212. TSThread * mGroundThread;
  213. /// @}
  214. bool mScaleCurrentlyAnimated;
  215. S32 mCurrentDetailLevel;
  216. /// 0-1, how far along from current to next (higher) detail level...
  217. ///
  218. /// 0=at this dl, 1=at higher detail level, where higher means bigger size on screen
  219. /// for dl=0, we use twice detail level 0's size as the size of the "next" dl
  220. F32 mCurrentIntraDetailLevel;
  221. /// This is only valid when the instance was created from
  222. /// a resource. Else it is null.
  223. Resource<TSShape> mShapeResource;
  224. /// This should always point to a valid shape and should
  225. /// equal mShapeResource if it was created from a resource.
  226. TSShape *mShape;
  227. /// Vertex buffer used for software skinning this instance
  228. TSVertexBufferHandle mSoftwareVertexBuffer;
  229. bool mOwnMaterialList; ///< Does this own the material list pointer?
  230. bool mUseOwnBuffer; ///< Force using our own copy of the vertex buffer
  231. bool mAlphaAlways;
  232. F32 mAlphaAlwaysValue;
  233. bool mUseOverrideTexture;
  234. U32 debrisRefCount;
  235. // the threads...
  236. Vector<TSThread*> mThreadList;
  237. Vector<TSThread*> mTransitionThreads;
  238. /// @name Transition nodes
  239. /// keep track of nodes that are involved in a transition
  240. ///
  241. /// @note this only tracks nodes we're transitioning from...
  242. /// nodes we're transitioning to are implicitly handled
  243. /// (i.e., we don't need to keep track of them)
  244. /// @{
  245. TSIntegerSet mTransitionRotationNodes;
  246. TSIntegerSet mTransitionTranslationNodes;
  247. TSIntegerSet mTransitionScaleNodes;
  248. /// @}
  249. /// keep track of nodes with animation restrictions put on them
  250. TSIntegerSet mMaskRotationNodes;
  251. TSIntegerSet mMaskPosXNodes;
  252. TSIntegerSet mMaskPosYNodes;
  253. TSIntegerSet mMaskPosZNodes;
  254. TSIntegerSet mDisableBlendNodes;
  255. TSIntegerSet mHandsOffNodes; ///< Nodes that aren't animated through threads automatically
  256. TSIntegerSet mCallbackNodes;
  257. // node callbacks
  258. Vector<TSCallbackRecord> mNodeCallbacks;
  259. /// state variables
  260. U32 mTriggerStates;
  261. bool initGround();
  262. void addPath(TSThread * gt, F32 start, F32 end, MatrixF * mat = NULL);
  263. public:
  264. TSShape* getShape() const { return mShape; }
  265. TSMaterialList* getMaterialList() const { return mMaterialList; }
  266. /// Set the material list without taking ownership.
  267. /// @see cloneMaterialList
  268. void setMaterialList( TSMaterialList *matList );
  269. /// Call this to own the material list -- i.e., we'll make a copy of the
  270. /// currently set material list and be responsible for deleting it. You
  271. /// can pass an optional feature set for initializing the cloned materials.
  272. void cloneMaterialList( const FeatureSet *features = NULL );
  273. /// Initializes or re-initializes the material list with
  274. /// an optional feature set.
  275. void initMaterialList( const FeatureSet *features = NULL );
  276. void setUseOwnBuffer();
  277. bool ownMaterialList() const { return mOwnMaterialList; }
  278. /// Get the number of material targets in this shape instance
  279. S32 getTargetCount() const
  280. {
  281. if ( mOwnMaterialList )
  282. return getMaterialList()->size();
  283. else
  284. return getShape()->getTargetCount();
  285. }
  286. /// Get the indexed material target (may differ from the base TSShape material
  287. /// list if this instance has been reskinned).
  288. const String& getTargetName( S32 mapToNameIndex ) const
  289. {
  290. if ( mOwnMaterialList )
  291. {
  292. if ( mapToNameIndex < 0 || mapToNameIndex >= getMaterialList()->size() )
  293. return String::EmptyString;
  294. return getMaterialList()->getMaterialName( mapToNameIndex );
  295. }
  296. else
  297. {
  298. return getShape()->getTargetName( mapToNameIndex );
  299. }
  300. }
  301. void reSkin( String newBaseName, String oldBaseName = String::EmptyString );
  302. enum
  303. {
  304. MaskNodeRotation = 0x01,
  305. MaskNodePosX = 0x02,
  306. MaskNodePosY = 0x04,
  307. MaskNodePosZ = 0x08,
  308. MaskNodeBlend = 0x10,
  309. MaskNodeAll = MaskNodeRotation|MaskNodePosX|MaskNodePosY|MaskNodePosZ|MaskNodeBlend,
  310. MaskNodeAllButBlend = MaskNodeRotation|MaskNodePosX|MaskNodePosY|MaskNodePosZ,
  311. MaskNodeAllButRotation = MaskNodePosX|MaskNodePosY|MaskNodePosZ|MaskNodeBlend,
  312. MaskNodeAllButPosX = MaskNodeRotation|MaskNodePosY|MaskNodePosZ|MaskNodeBlend,
  313. MaskNodeAllButPosY = MaskNodeRotation|MaskNodePosX|MaskNodePosZ|MaskNodeBlend,
  314. MaskNodeAllButPosZ = MaskNodeRotation|MaskNodePosX|MaskNodePosY|MaskNodeBlend,
  315. MaskNodeHandsOff = 0x20, ///< meaning, don't even set to default, programmer controls it (blend still applies)
  316. MaskNodeCallback = 0x40 ///< meaning, get local transform via callback function (see setCallback)
  317. ///< callback data2 is node index, callback return value is pointer to local transform
  318. ///< Note: won't get this callback everytime you animate...application responsibility
  319. ///< to make sure matrix pointer continues to point to valid and updated local transform
  320. };
  321. /// @name Node Masking
  322. /// set node masking...
  323. /// @{
  324. void setNodeAnimationState(S32 nodeIndex, U32 animationState, TSCallback * callback = NULL);
  325. U32 getNodeAnimationState(S32 nodeIndex);
  326. /// @}
  327. /// @name Trigger states
  328. /// check trigger value
  329. /// @{
  330. bool getTriggerState(U32 stateNum, bool clearState = true);
  331. void setTriggerState(U32 stateNum, bool on);
  332. void setTriggerStateBit(U32 stateBit, bool on);
  333. /// @}
  334. /// @name Debris Management
  335. /// @{
  336. void incDebrisRefCount() { ++debrisRefCount; }
  337. void decDebrisRefCount() { debrisRefCount > 0 ? --debrisRefCount : 0; }
  338. U32 getDebrisRefCount() const { return debrisRefCount; }
  339. /// @}
  340. /// @name AlphaAlways
  341. /// AlphaAlways allows the entire model to become translucent at the same value
  342. /// @{
  343. void setAlphaAlways(F32 value) { mAlphaAlways = (value<0.99f); mAlphaAlwaysValue = value; }
  344. F32 getAlphaAlwaysValue() const { return mAlphaAlways ? mAlphaAlwaysValue : 1.0f; }
  345. bool getAlphaAlways() const { return mAlphaAlways; }
  346. /// @}
  347. //-------------------------------------------------------------------------------------
  348. // private methods for setting up and affecting animation
  349. //-------------------------------------------------------------------------------------
  350. private:
  351. /// @name Private animation methods
  352. /// These are private methods for setting up and affecting animation
  353. /// @{
  354. void sortThreads();
  355. void updateTransitions();
  356. void handleDefaultScale(S32 a, S32 b, TSIntegerSet & scaleBeenSet);
  357. void updateTransitionNodeTransforms(TSIntegerSet& transitionNodes);
  358. void handleTransitionNodes(S32 a, S32 b);
  359. void handleNodeScale(S32 a, S32 b);
  360. void handleAnimatedScale(TSThread *, S32 a, S32 b, TSIntegerSet &);
  361. void handleMaskedPositionNode(TSThread *, S32 nodeIndex, S32 offset);
  362. void handleBlendSequence(TSThread *, S32 a, S32 b);
  363. void checkScaleCurrentlyAnimated();
  364. /// @}
  365. //-------------------------------------------------------------------------------------
  366. // animate, render, & detail control
  367. //-------------------------------------------------------------------------------------
  368. public:
  369. struct RenderData
  370. {
  371. MeshObjectInstance* currentObjectInstance;
  372. S32 detailLevel;
  373. S32 materialIndex;
  374. const Point3F * objectScale;
  375. };
  376. /// Scale pixel size by this amount when selecting
  377. /// detail levels.
  378. static F32 smDetailAdjust;
  379. /// If this is set to a positive pixel value shapes
  380. /// with a smaller pixel size than this will skip
  381. /// rendering entirely.
  382. static F32 smSmallestVisiblePixelSize;
  383. /// never choose detail level number below this value (except if
  384. /// only way to get a visible detail)
  385. static S32 smNumSkipRenderDetails;
  386. /// For debugging / metrics.
  387. static F32 smLastScreenErrorTolerance;
  388. static F32 smLastScaledDistance;
  389. static F32 smLastPixelSize;
  390. /// Debugging
  391. /// @{
  392. /// Renders the vertex normals assuming the GFX state
  393. /// is setup for rendering in model space.
  394. void renderDebugNormals( F32 normalScalar, S32 dl );
  395. /// Render all node transforms as small axis gizmos. It is recommended
  396. /// that prior to calling this, shapeInstance::animate is called so that
  397. /// nodes are in object space and that the GFX state is setup for
  398. /// rendering in model space.
  399. void renderDebugNodes();
  400. /// Print mesh data to the console, valid String parameters
  401. /// are Visible, Hidden, or All.
  402. void listMeshes( const String &state ) const;
  403. /// @}
  404. void render( const TSRenderState &rdata );
  405. void render( const TSRenderState &rdata, S32 dl, F32 intraDL = 0.0f );
  406. bool bufferNeedsUpdate(S32 objectDetail, S32 start, S32 end);
  407. void animate() { animate( mCurrentDetailLevel ); }
  408. void animate(S32 dl);
  409. void animateNodes(S32 ss);
  410. void animateVisibility(S32 ss);
  411. void animateFrame(S32 ss);
  412. void animateMatFrame(S32 ss);
  413. void animateSubtrees(bool forceFull = true);
  414. void animateNodeSubtrees(bool forceFull = true);
  415. /// Sets the 'forceHidden' state on the named mesh.
  416. /// @see MeshObjectInstance::forceHidden
  417. void setMeshForceHidden( const char *meshName, bool hidden );
  418. /// Sets the 'forceHidden' state on a mesh.
  419. /// @see MeshObjectInstance::forceHidden
  420. void setMeshForceHidden( S32 meshIndex, bool hidden );
  421. /// @name Animation Scale
  422. /// Query about animated scale
  423. /// @{
  424. bool animatesScale() { return (mShape->mFlags & TSShape::AnyScale) != 0; }
  425. bool animatesUniformScale() { return (mShape->mFlags & TSShape::UniformScale) != 0; }
  426. bool animatesAlignedScale() { return (mShape->mFlags & TSShape::AlignedScale) != 0; }
  427. bool animatesArbitraryScale() { return (mShape->mFlags & TSShape::ArbitraryScale) != 0; }
  428. bool scaleCurrentlyAnimated() { return mScaleCurrentlyAnimated; }
  429. /// @}
  430. //
  431. bool inTransition() { return !mTransitionThreads.empty(); }
  432. /// @name Ground Transforms
  433. /// The animator of a model can make the bounding box
  434. /// animate along with the object. Doing so will move the object with the bounding box.
  435. /// The ground transform turns the world bounding box into the post-animation bounding box
  436. /// when such a technique is used. However, few models actually use this technique.
  437. /// @{
  438. void animateGround(); ///< clears previous ground transform
  439. MatrixF & getGroundTransform() { return mGroundTransform; }
  440. void deltaGround(TSThread *, F32 start, F32 end, MatrixF * mat = NULL);
  441. void deltaGround1(TSThread *, F32 start, F32 end, MatrixF& mat);
  442. /// @}
  443. U32 getNumDetails() const { return mShape ? mShape->details.size() : 0; }
  444. S32 getCurrentDetail() const { return mCurrentDetailLevel; }
  445. F32 getCurrentIntraDetail() const { return mCurrentIntraDetailLevel; }
  446. void setCurrentDetail( S32 dl, F32 intraDL = 1.0f );
  447. /// Helper function which internally calls setDetailFromDistance.
  448. S32 setDetailFromPosAndScale( const SceneRenderState *state,
  449. const Point3F &pos,
  450. const Point3F &scale );
  451. /// Selects the current detail level using the scaled
  452. /// distance between your object and the camera.
  453. ///
  454. /// @see TSShape::Detail.
  455. S32 setDetailFromDistance( const SceneRenderState *state, F32 scaledDist );
  456. /// Sets the current detail level using the legacy screen error metric.
  457. S32 setDetailFromScreenError( F32 errorTOL );
  458. enum
  459. {
  460. TransformDirty = BIT(0),
  461. VisDirty = BIT(1),
  462. FrameDirty = BIT(2),
  463. MatFrameDirty = BIT(3),
  464. ThreadDirty = BIT(4),
  465. AllDirtyMask = TransformDirty | VisDirty | FrameDirty | MatFrameDirty | ThreadDirty
  466. };
  467. U32 * mDirtyFlags;
  468. void setDirty(U32 dirty);
  469. void clearDirty(U32 dirty);
  470. //-------------------------------------------------------------------------------------
  471. // collision interface routines
  472. //-------------------------------------------------------------------------------------
  473. public:
  474. bool buildPolyList(AbstractPolyList *, S32 dl);
  475. bool getFeatures(const MatrixF& mat, const Point3F& n, ConvexFeature*, S32 dl);
  476. bool castRay(const Point3F & start, const Point3F & end, RayInfo *,S32 dl);
  477. bool castRayRendered(const Point3F & start, const Point3F & end, RayInfo *,S32 dl);
  478. bool quickLOS(const Point3F & start, const Point3F & end, S32 dl) { return castRay(start,end,NULL,dl); }
  479. Point3F support(const Point3F & v, S32 dl);
  480. void computeBounds(S32 dl, Box3F & bounds); ///< uses current transforms to compute bounding box around a detail level
  481. ///< see like named method on shape if you want to use default transforms
  482. bool buildPolyListOpcode( S32 dl, AbstractPolyList *polyList, const Box3F &box );
  483. bool castRayOpcode( S32 objectDetail, const Point3F & start, const Point3F & end, RayInfo *);
  484. bool buildConvexOpcode( const MatrixF &objMat, const Point3F &objScale, S32 objectDetail, const Box3F &bounds, Convex *c, Convex *list );
  485. //-------------------------------------------------------------------------------------
  486. // Thread Control
  487. //-------------------------------------------------------------------------------------
  488. /// @name Thread Control
  489. /// Threads! In order to animate an object, first you need to have an animation in the object.
  490. /// Then, you need to get the TSShape of the object:
  491. /// @code
  492. /// TSShape* shape = mShapeInstance->getShape());
  493. /// @endcode
  494. /// Next, get the sequence and store::
  495. /// @code
  496. /// S32 seq = shape->findSequence("foo"));
  497. /// @endcode
  498. /// Create a new thread (if needed):
  499. /// @code
  500. /// TSThread* thread = mShapeInstance->addThread();
  501. /// @endcode
  502. /// Finally, set the position in the sequence:
  503. /// @code
  504. /// mShapeInstance->setSequence(thread, seq, 0)
  505. /// @endcode
  506. /// @{
  507. public:
  508. TSThread * addThread(); ///< Create a new thread
  509. TSThread * getThread(S32 threadNumber); ///< @note threads can change order, best to hold
  510. ///< onto a thread from the start
  511. void destroyThread(TSThread * thread); ///< Destroy a thread!
  512. U32 threadCount(); ///< How many threads are there?
  513. void setSequence(TSThread *, S32 seq, F32 pos);///< Get the thread a sequence
  514. /// Transition to a sequence
  515. void transitionToSequence(TSThread *, S32 seq, F32 pos, F32 duration, bool continuePlay);
  516. void clearTransition(TSThread *); ///< Stop transitions
  517. U32 getSequence(TSThread *); ///< Get the sequence of the thread
  518. void setBlendEnabled(TSThread *, bool blendOn);///< Set whether or not the thread will blend
  519. bool getBlendEnabled(TSThread *); ///< Does this thread blend?
  520. void setPriority(TSThread *, F32 priority); ///< Set thread priority
  521. F32 getPriority(TSThread * thread); ///< Get thread priority
  522. F32 getTime(TSThread * thread); ///< Get how long the thread has been playing
  523. F32 getPos(TSThread * thread); ///< Get the position in the thread
  524. void setTime(TSThread * thread, F32 time); ///< Set how long into the thread to use
  525. void setPos(TSThread * thread, F32 pos); ///< Set the position of the thread
  526. bool isInTransition(TSThread * thread); ///< Is this thread in transition?
  527. F32 getTimeScale(TSThread * thread); ///< Get the time scale of the thread
  528. void setTimeScale(TSThread * thread, F32); ///< Set the time scale of the thread
  529. F32 getDuration(TSThread * thread); ///< Get the duration of the thread
  530. F32 getScaledDuration(TSThread * thread); ///< Get the duration of the thread with the scale factored in
  531. S32 getKeyframeCount(TSThread * thread); ///< Get the number of keyframes
  532. S32 getKeyframeNumber(TSThread * thread); ///< Get which keyframe the thread is on
  533. /// Set which keyframe the thread is on
  534. void setKeyframeNumber(TSThread * thread, S32 kf);
  535. void advanceTime(F32 delta, TSThread *); ///< advance time on a particular thread
  536. void advanceTime(F32 delta); ///< advance time on all threads
  537. void advancePos(F32 delta, TSThread *); ///< advance pos on a particular thread
  538. void advancePos(F32 delta); ///< advance pos on all threads
  539. /// @}
  540. //-------------------------------------------------------------------------------------
  541. // constructors, destructors, initialization, io
  542. //-------------------------------------------------------------------------------------
  543. TSShapeInstance( const Resource<TSShape> & shape, bool loadMaterials = true);
  544. TSShapeInstance( TSShape * pShape, bool loadMaterials = true);
  545. ~TSShapeInstance();
  546. void buildInstanceData(TSShape *, bool loadMaterials);
  547. void initNodeTransforms();
  548. void initMeshObjects();
  549. void dump(Stream &);
  550. void dumpNode(Stream &, S32 level, S32 nodeIndex, Vector<S32> & detailSizes);
  551. void *mData; ///< available for use by app...initialized to 0
  552. void prepCollision();
  553. //-------------------------------------------------------------------------------------
  554. // accumulation
  555. //-------------------------------------------------------------------------------------
  556. bool hasAccumulation();
  557. };
  558. //-------------------------------------------------------------------------------------
  559. // Thread class
  560. //-------------------------------------------------------------------------------------
  561. /// 3space animation thread.
  562. ///
  563. /// An animation thread: runtime data associated with a single sequence that is
  564. /// running (or two sequences if in transition between them).
  565. ///
  566. /// A shape instance can have multiple threads running. When multiple threads are running,
  567. /// which thread/sequence controls which node or object is determined based
  568. /// on priority of the sequence.
  569. ///
  570. /// @note all thread data and methods are private (but TSShapeInstance is a friend).
  571. /// Users should treat thread pointers like keys -- they are used to ID
  572. /// the thread when interfacing with the shape, but are not manipulated
  573. /// by anything but the TSShapeInstance. See "Thread control" methods
  574. /// for more info on controlling threads.
  575. class TSThread
  576. {
  577. friend class TSShapeInstance;
  578. S32 priority;
  579. TSShapeInstance * mShapeInstance; ///< Instance of the shape that this thread animates
  580. S32 sequence; ///< Sequence this thread will perform
  581. F32 pos;
  582. F32 timeScale; ///< How fast to play through the sequence
  583. S32 keyNum1; ///< Keyframe at or before current position
  584. S32 keyNum2; ///< Keyframe at or after current position
  585. F32 keyPos;
  586. bool blendDisabled; ///< Blend with other sequences?
  587. /// if in transition...
  588. struct TransitionData
  589. {
  590. bool inTransition;
  591. F32 duration;
  592. F32 pos;
  593. F32 direction;
  594. F32 targetScale; ///< time scale for sequence we are transitioning to (during transition only)
  595. ///< this is either 1 or 0 (if 1 target sequence plays as we transition, if 0 it doesn't)
  596. TSIntegerSet oldRotationNodes; ///< nodes controlled by this thread pre-transition
  597. TSIntegerSet oldTranslationNodes; ///< nodes controlled by this thread pre-transition
  598. TSIntegerSet oldScaleNodes; ///< nodes controlled by this thread pre-transition
  599. U32 oldSequence; ///< sequence that was set before transition began
  600. F32 oldPos; ///< position of sequence before transition began
  601. } transitionData;
  602. struct
  603. {
  604. F32 start;
  605. F32 end;
  606. S32 loop;
  607. } path;
  608. bool makePath;
  609. /// given a position on the thread, choose correct keyframes
  610. /// slight difference between one-shot and cyclic sequences -- see comments below for details
  611. void selectKeyframes(F32 pos, const TSSequence * seq, S32 * k1, S32 * k2, F32 * kpos);
  612. void getGround(F32 p, MatrixF * pMat);
  613. /// @name Triggers
  614. /// Triggers are used to do something once a certain animation point has been reached.
  615. ///
  616. /// For example, when the player's foot animation hits the ground, a foot puff and
  617. /// foot print are triggered from the thread.
  618. ///
  619. /// These are called by advancePos()
  620. /// @{
  621. void animateTriggers();
  622. void activateTriggers(F32 a, F32 b);
  623. /// @}
  624. TSThread(TSShapeInstance*);
  625. TSThread() {}
  626. void setSequence(S32 seq, F32 pos);
  627. void transitionToSequence(S32 seq, F32 pos, F32 duration, bool continuePlay);
  628. void advanceTime(F32 delta);
  629. void advancePos(F32 delta);
  630. F32 getTime();
  631. F32 getPos();
  632. void setTime(F32);
  633. void setPos(F32);
  634. bool isInTransition();
  635. F32 getTimeScale();
  636. void setTimeScale(F32);
  637. F32 getDuration();
  638. F32 getScaledDuration();
  639. S32 getKeyframeCount();
  640. S32 getKeyframeNumber();
  641. void setKeyframeNumber(S32 kf);
  642. public:
  643. TSShapeInstance * getShapeInstance() { return mShapeInstance; }
  644. bool hasSequence() const { return sequence >= 0; }
  645. U32 getSeqIndex() const { return sequence; }
  646. const TSSequence* getSequence() const { return &(mShapeInstance->mShape->sequences[sequence]); }
  647. const String& getSequenceName() const { return mShapeInstance->mShape->getSequenceName(sequence); }
  648. S32 operator<(const TSThread &) const;
  649. };
  650. typedef TSShapeInstance::ObjectInstance TSObjectInstance;
  651. #endif // _TSSHAPEINSTANCE_H_