animationComponent.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  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. #include "T3D/components/animation/animationComponent.h"
  23. #include "T3D/components/animation/animationComponent_ScriptBinding.h"
  24. #include "T3D/components/render/meshComponent.h"
  25. #include "platform/platform.h"
  26. #include "console/consoleTypes.h"
  27. #include "core/util/safeDelete.h"
  28. #include "core/resourceManager.h"
  29. #include "core/stream/fileStream.h"
  30. #include "console/consoleTypes.h"
  31. #include "console/consoleObject.h"
  32. #include "ts/tsShapeInstance.h"
  33. #include "core/stream/bitStream.h"
  34. #include "sim/netConnection.h"
  35. #include "gfx/gfxTransformSaver.h"
  36. #include "console/engineAPI.h"
  37. #include "lighting/lightQuery.h"
  38. #include "gfx/sim/debugDraw.h"
  39. extern bool gEditingMission;
  40. //////////////////////////////////////////////////////////////////////////
  41. // Callbacks
  42. //////////////////////////////////////////////////////////////////////////
  43. IMPLEMENT_CALLBACK( AnimationComponent, onAnimationStart, void, ( Component* obj, const String& animName ), ( obj, animName ),
  44. "@brief Called when we collide with another object.\n\n"
  45. "@param obj The ShapeBase object\n"
  46. "@param collObj The object we collided with\n"
  47. "@param vec Collision impact vector\n"
  48. "@param len Length of the impact vector\n" );
  49. IMPLEMENT_CALLBACK(AnimationComponent, onAnimationEnd, void, (Component* obj, const char* animName), (obj, animName),
  50. "@brief Called when we collide with another object.\n\n"
  51. "@param obj The ShapeBase object\n"
  52. "@param collObj The object we collided with\n"
  53. "@param vec Collision impact vector\n"
  54. "@param len Length of the impact vector\n" );
  55. IMPLEMENT_CALLBACK(AnimationComponent, onAnimationTrigger, void, (Component* obj, const String& animName, S32 triggerID), (obj, animName, triggerID),
  56. "@brief Called when we collide with another object.\n\n"
  57. "@param obj The ShapeBase object\n"
  58. "@param collObj The object we collided with\n"
  59. "@param vec Collision impact vector\n"
  60. "@param len Length of the impact vector\n" );
  61. //////////////////////////////////////////////////////////////////////////
  62. // Constructor/Destructor
  63. //////////////////////////////////////////////////////////////////////////
  64. AnimationComponent::AnimationComponent() : Component()
  65. {
  66. mNetworked = true;
  67. mFriendlyName = "Animation(Component)";
  68. mComponentType = "Render";
  69. mDescription = getDescriptionText("Allows a rendered mesh to be animated");
  70. mOwnerRenderInst = NULL;
  71. mOwnerShapeInstance = NULL;
  72. for (U32 i = 0; i < MaxScriptThreads; i++)
  73. {
  74. mAnimationThreads[i].sequence = -1;
  75. mAnimationThreads[i].thread = 0;
  76. mAnimationThreads[i].sound = 0;
  77. mAnimationThreads[i].state = Thread::Stop;
  78. mAnimationThreads[i].atEnd = false;
  79. mAnimationThreads[i].timescale = 1.f;
  80. mAnimationThreads[i].position = -1.f;
  81. mAnimationThreads[i].transition = true;
  82. }
  83. }
  84. AnimationComponent::~AnimationComponent()
  85. {
  86. for(S32 i = 0;i < mFields.size();++i)
  87. {
  88. ComponentField &field = mFields[i];
  89. SAFE_DELETE_ARRAY(field.mFieldDescription);
  90. }
  91. SAFE_DELETE_ARRAY(mDescription);
  92. }
  93. IMPLEMENT_CO_NETOBJECT_V1(AnimationComponent);
  94. bool AnimationComponent::onAdd()
  95. {
  96. if (!Parent::onAdd())
  97. return false;
  98. //we need at least one layer
  99. for (U32 i = 0; i < MaxScriptThreads; i++)
  100. {
  101. Thread& st = mAnimationThreads[i];
  102. if (st.sequence != -1)
  103. {
  104. // TG: Need to see about suppressing non-cyclic sounds
  105. // if the sequences were activated before the object was
  106. // ghosted.
  107. // TG: Cyclic animations need to have a random pos if
  108. // they were started before the object was ghosted.
  109. // If there was something running on the old shape, the thread
  110. // needs to be reset. Otherwise we assume that it's been
  111. // initialized either by the constructor or from the server.
  112. bool reset = st.thread != 0;
  113. st.thread = 0;
  114. if (st.sequence != -1)
  115. {
  116. setThreadSequence(i, st.sequence, reset);
  117. }
  118. }
  119. if (st.thread)
  120. updateThread(st);
  121. }
  122. return true;
  123. }
  124. void AnimationComponent::onRemove()
  125. {
  126. Parent::onRemove();
  127. mOwnerRenderInst = NULL;
  128. }
  129. void AnimationComponent::onComponentAdd()
  130. {
  131. //test if this is a shape component!
  132. RenderComponentInterface *shapeInstanceInterface = mOwner->getComponent<RenderComponentInterface>();
  133. if (shapeInstanceInterface)
  134. {
  135. shapeInstanceInterface->onShapeInstanceChanged.notify(this, &AnimationComponent::targetShapeChanged);
  136. targetShapeChanged(shapeInstanceInterface);
  137. }
  138. }
  139. void AnimationComponent::componentAddedToOwner(Component *comp)
  140. {
  141. if (comp->getId() == getId())
  142. return;
  143. //test if this is a shape component!
  144. RenderComponentInterface *shapeInstanceInterface = dynamic_cast<RenderComponentInterface*>(comp);
  145. if (shapeInstanceInterface)
  146. {
  147. shapeInstanceInterface->onShapeInstanceChanged.notify(this, &AnimationComponent::targetShapeChanged);
  148. targetShapeChanged(shapeInstanceInterface);
  149. }
  150. }
  151. void AnimationComponent::componentRemovedFromOwner(Component *comp)
  152. {
  153. if (comp->getId() == getId()) //?????????
  154. return;
  155. //test if this is a shape component!
  156. RenderComponentInterface *shapeInstanceInterface = dynamic_cast<RenderComponentInterface*>(comp);
  157. if (shapeInstanceInterface)
  158. {
  159. shapeInstanceInterface->onShapeInstanceChanged.remove(this, &AnimationComponent::targetShapeChanged);
  160. mOwnerRenderInst = NULL;
  161. }
  162. }
  163. void AnimationComponent::targetShapeChanged(RenderComponentInterface* instanceInterface)
  164. {
  165. mOwnerRenderInst = instanceInterface;
  166. if (!mOwnerRenderInst || !getShape())
  167. return;
  168. MeshComponent* meshComp = dynamic_cast<MeshComponent*>(mOwnerRenderInst);
  169. mOwnerShapeInstance = meshComp->getShapeInstance();
  170. if (!mOwnerShapeInstance)
  171. return;
  172. for (U32 i = 0; i < MaxScriptThreads; i++)
  173. {
  174. Thread& st = mAnimationThreads[i];
  175. st.thread = mOwnerShapeInstance->addThread();
  176. }
  177. }
  178. void AnimationComponent::initPersistFields()
  179. {
  180. Parent::initPersistFields();
  181. }
  182. U32 AnimationComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
  183. {
  184. U32 retMask = Parent::packUpdate(con, mask, stream);
  185. for (int i = 0; i < MaxScriptThreads; i++)
  186. {
  187. Thread& st = mAnimationThreads[i];
  188. if (stream->writeFlag((st.sequence != -1 || st.state == Thread::Destroy) && (mask & (ThreadMaskN << i))))
  189. {
  190. stream->writeInt(st.sequence, ThreadSequenceBits);
  191. stream->writeInt(st.state, 2);
  192. stream->write(st.timescale);
  193. stream->write(st.position);
  194. stream->writeFlag(st.atEnd);
  195. stream->writeFlag(st.transition);
  196. }
  197. }
  198. return retMask;
  199. }
  200. void AnimationComponent::unpackUpdate(NetConnection *con, BitStream *stream)
  201. {
  202. Parent::unpackUpdate(con, stream);
  203. for (S32 i = 0; i < MaxScriptThreads; i++)
  204. {
  205. if (stream->readFlag())
  206. {
  207. Thread& st = mAnimationThreads[i];
  208. U32 seq = stream->readInt(ThreadSequenceBits);
  209. st.state = stream->readInt(2);
  210. stream->read( &st.timescale );
  211. stream->read( &st.position );
  212. st.atEnd = stream->readFlag();
  213. bool transition = stream->readFlag();
  214. if (!st.thread || st.sequence != seq && st.state != Thread::Destroy)
  215. setThreadSequence(i, seq, false, transition);
  216. else
  217. updateThread(st);
  218. }
  219. }
  220. }
  221. void AnimationComponent::processTick()
  222. {
  223. Parent::processTick();
  224. if (!isActive())
  225. return;
  226. if (isServerObject())
  227. {
  228. // Server only...
  229. advanceThreads(TickSec);
  230. }
  231. }
  232. void AnimationComponent::advanceTime(F32 dt)
  233. {
  234. Parent::advanceTime(dt);
  235. // On the client, the shape threads and images are
  236. // advanced at framerate.
  237. advanceThreads(dt);
  238. }
  239. //
  240. const char *AnimationComponent::getThreadSequenceName(U32 slot)
  241. {
  242. Thread& st = mAnimationThreads[slot];
  243. if (st.sequence == -1)
  244. {
  245. // Invalid Animation.
  246. return "";
  247. }
  248. // Name Index
  249. TSShape* shape = getShape();
  250. if (shape)
  251. {
  252. const U32 nameIndex = shape->sequences[st.sequence].nameIndex;
  253. // Return Name.
  254. return shape->getName(nameIndex);
  255. }
  256. return "";
  257. }
  258. bool AnimationComponent::setThreadSequence(U32 slot, S32 seq, bool reset, bool transition, F32 transTime)
  259. {
  260. Thread& st = mAnimationThreads[slot];
  261. if (st.thread && st.sequence == seq && st.state == Thread::Play && !reset)
  262. return true;
  263. // Handle a -1 sequence, as this may be set when a thread has been destroyed.
  264. if (seq == -1)
  265. return true;
  266. if (seq < MaxSequenceIndex)
  267. {
  268. setMaskBits(ThreadMaskN << slot);
  269. st.sequence = seq;
  270. st.transition = transition;
  271. if (reset)
  272. {
  273. st.state = Thread::Play;
  274. st.atEnd = false;
  275. st.timescale = 1.f;
  276. st.position = 0.f;
  277. }
  278. if (mOwnerShapeInstance)
  279. {
  280. if (!st.thread)
  281. st.thread = mOwnerShapeInstance->addThread();
  282. if (transition)
  283. {
  284. mOwnerShapeInstance->transitionToSequence(st.thread, seq, st.position, transTime, true);
  285. }
  286. else
  287. {
  288. mOwnerShapeInstance->setSequence(st.thread, seq, 0);
  289. stopThreadSound(st);
  290. }
  291. updateThread(st);
  292. }
  293. return true;
  294. }
  295. return false;
  296. }
  297. S32 AnimationComponent::getThreadSequenceID(S32 slot)
  298. {
  299. if (slot >= 0 && slot < AnimationComponent::MaxScriptThreads)
  300. {
  301. return mAnimationThreads[slot].sequence;
  302. }
  303. else
  304. {
  305. return -1;
  306. }
  307. }
  308. void AnimationComponent::updateThread(Thread& st)
  309. {
  310. if (!mOwnerRenderInst)
  311. return;
  312. switch (st.state)
  313. {
  314. case Thread::Stop:
  315. {
  316. mOwnerShapeInstance->setTimeScale(st.thread, 1.f);
  317. mOwnerShapeInstance->setPos(st.thread, (st.timescale > 0.f) ? 0.0f : 1.0f);
  318. } // Drop through to pause state
  319. case Thread::Pause:
  320. {
  321. if (st.position != -1.f)
  322. {
  323. mOwnerShapeInstance->setTimeScale(st.thread, 1.f);
  324. mOwnerShapeInstance->setPos(st.thread, st.position);
  325. }
  326. mOwnerShapeInstance->setTimeScale(st.thread, 0.f);
  327. stopThreadSound(st);
  328. } break;
  329. case Thread::Play:
  330. {
  331. if (st.atEnd)
  332. {
  333. mOwnerShapeInstance->setTimeScale(st.thread, 1);
  334. mOwnerShapeInstance->setPos(st.thread, (st.timescale > 0.f) ? 1.0f : 0.0f);
  335. mOwnerShapeInstance->setTimeScale(st.thread, 0);
  336. stopThreadSound(st);
  337. st.state = Thread::Stop;
  338. }
  339. else
  340. {
  341. if (st.position != -1.f)
  342. {
  343. mOwnerShapeInstance->setTimeScale(st.thread, 1.f);
  344. mOwnerShapeInstance->setPos(st.thread, st.position);
  345. }
  346. mOwnerShapeInstance->setTimeScale(st.thread, st.timescale);
  347. if (!st.sound)
  348. {
  349. startSequenceSound(st);
  350. }
  351. }
  352. } break;
  353. case Thread::Destroy:
  354. {
  355. stopThreadSound(st);
  356. st.atEnd = true;
  357. st.sequence = -1;
  358. if (st.thread)
  359. {
  360. mOwnerShapeInstance->destroyThread(st.thread);
  361. st.thread = 0;
  362. }
  363. } break;
  364. }
  365. }
  366. bool AnimationComponent::stopThread(U32 slot)
  367. {
  368. Thread& st = mAnimationThreads[slot];
  369. if (st.sequence != -1 && st.state != Thread::Stop)
  370. {
  371. setMaskBits(ThreadMaskN << slot);
  372. st.state = Thread::Stop;
  373. updateThread(st);
  374. return true;
  375. }
  376. return false;
  377. }
  378. bool AnimationComponent::destroyThread(U32 slot)
  379. {
  380. Thread& st = mAnimationThreads[slot];
  381. if (st.sequence != -1 && st.state != Thread::Destroy)
  382. {
  383. setMaskBits(ThreadMaskN << slot);
  384. st.state = Thread::Destroy;
  385. updateThread(st);
  386. return true;
  387. }
  388. return false;
  389. }
  390. bool AnimationComponent::pauseThread(U32 slot)
  391. {
  392. Thread& st = mAnimationThreads[slot];
  393. if (st.sequence != -1 && st.state != Thread::Pause)
  394. {
  395. setMaskBits(ThreadMaskN << slot);
  396. st.state = Thread::Pause;
  397. updateThread(st);
  398. return true;
  399. }
  400. return false;
  401. }
  402. bool AnimationComponent::playThread(U32 slot)
  403. {
  404. Thread& st = mAnimationThreads[slot];
  405. if (st.sequence != -1 && st.state != Thread::Play)
  406. {
  407. setMaskBits(ThreadMaskN << slot);
  408. st.state = Thread::Play;
  409. updateThread(st);
  410. return true;
  411. }
  412. return false;
  413. }
  414. bool AnimationComponent::playThread(U32 slot, const char* name, bool transition, F32 transitionTime)
  415. {
  416. if (slot < AnimationComponent::MaxScriptThreads)
  417. {
  418. if (!dStrEqual(name, ""))
  419. {
  420. if (TSShape* shape = getShape())
  421. {
  422. S32 seq = shape->findSequence(name);
  423. if (seq != -1 && setThreadSequence(slot, seq, true, transition, transitionTime))
  424. {
  425. return true;
  426. }
  427. else if (seq == -1)
  428. {
  429. //We tried to play a non-existaint sequence, so stop the thread just in case
  430. destroyThread(slot);
  431. return false;
  432. }
  433. }
  434. }
  435. else
  436. {
  437. if (playThread(slot))
  438. return true;
  439. }
  440. }
  441. return false;
  442. }
  443. bool AnimationComponent::setThreadAnimation(U32 slot, const char* name)
  444. {
  445. if (slot < AnimationComponent::MaxScriptThreads)
  446. {
  447. if (!dStrEqual(name, ""))
  448. {
  449. if (TSShape* shape = getShape())
  450. {
  451. S32 seq = shape->findSequence(name);
  452. if (seq != -1 && setThreadSequence(slot, seq, false, false))
  453. {
  454. Thread& st = mAnimationThreads[slot];
  455. if (st.position == -1)
  456. st.position = 0;
  457. //st.state = Thread::Pause;
  458. return true;
  459. }
  460. else if (seq == -1)
  461. {
  462. //We tried to play a non-existaint sequence, so stop the thread just in case
  463. destroyThread(slot);
  464. return false;
  465. }
  466. }
  467. }
  468. else
  469. {
  470. if (playThread(slot))
  471. return true;
  472. }
  473. }
  474. return false;
  475. }
  476. bool AnimationComponent::setThreadPosition(U32 slot, F32 pos)
  477. {
  478. Thread& st = mAnimationThreads[slot];
  479. if (st.sequence != -1)
  480. {
  481. setMaskBits(ThreadMaskN << slot);
  482. st.position = pos;
  483. st.atEnd = false;
  484. updateThread(st);
  485. return true;
  486. }
  487. return false;
  488. }
  489. bool AnimationComponent::setThreadDir(U32 slot, bool forward)
  490. {
  491. Thread& st = mAnimationThreads[slot];
  492. if (st.sequence != -1)
  493. {
  494. if ((st.timescale >= 0.f) != forward)
  495. {
  496. setMaskBits(ThreadMaskN << slot);
  497. st.timescale *= -1.f;
  498. st.atEnd = false;
  499. updateThread(st);
  500. }
  501. return true;
  502. }
  503. return false;
  504. }
  505. bool AnimationComponent::setThreadTimeScale(U32 slot, F32 timeScale)
  506. {
  507. Thread& st = mAnimationThreads[slot];
  508. if (st.sequence != -1)
  509. {
  510. if (st.timescale != timeScale)
  511. {
  512. setMaskBits(ThreadMaskN << slot);
  513. st.timescale = timeScale;
  514. updateThread(st);
  515. }
  516. return true;
  517. }
  518. return false;
  519. }
  520. void AnimationComponent::stopThreadSound(Thread& thread)
  521. {
  522. return;
  523. }
  524. void AnimationComponent::startSequenceSound(Thread& thread)
  525. {
  526. return;
  527. }
  528. void AnimationComponent::advanceThreads(F32 dt)
  529. {
  530. if (!mOwnerRenderInst)
  531. return;
  532. if (mOwnerShapeInstance == nullptr || !getShape())
  533. return;
  534. for (U32 i = 0; i < MaxScriptThreads; i++)
  535. {
  536. Thread& st = mAnimationThreads[i];
  537. if (st.thread && st.sequence != -1)
  538. {
  539. bool cyclic = getShape()->sequences[st.sequence].isCyclic();
  540. if (!getShape()->sequences[st.sequence].isCyclic() &&
  541. !st.atEnd &&
  542. ((st.timescale > 0.f) ? mOwnerShapeInstance->getPos(st.thread) >= 1.0 : mOwnerShapeInstance->getPos(st.thread) <= 0))
  543. {
  544. st.atEnd = true;
  545. updateThread(st);
  546. if (!isClientObject())
  547. {
  548. Con::executef(this, "onAnimationEnd", st.thread->getSequenceName());
  549. }
  550. }
  551. // Make sure the thread is still valid after the call to onEndSequence_callback().
  552. // Someone could have called destroyThread() while in there.
  553. if (st.thread)
  554. {
  555. mOwnerShapeInstance->advanceTime(dt, st.thread);
  556. }
  557. if (mOwnerShapeInstance && !isClientObject())
  558. {
  559. for (U32 stateIDx = 1; stateIDx < 32; stateIDx++)
  560. {
  561. if (mOwnerShapeInstance->getTriggerState(stateIDx))
  562. {
  563. const char* animName = st.thread->getSequenceName().c_str();
  564. onAnimationTrigger_callback(this, animName, stateIDx);
  565. }
  566. }
  567. }
  568. if (isClientObject())
  569. {
  570. mOwnerShapeInstance->animate();
  571. /*mOwnerShapeInstance->animateGround();
  572. MatrixF groundTransform = mOwnerShapeInstance->getGroundTransform();
  573. if (groundTransform != MatrixF::Identity)
  574. {
  575. mOwner->setPosition(groundTransform.getPosition());
  576. }*/
  577. }
  578. }
  579. }
  580. }
  581. TSShape* AnimationComponent::getShape()
  582. {
  583. if (mOwner == NULL)
  584. return NULL;
  585. if (mOwnerRenderInst == NULL)
  586. return NULL;
  587. return mOwnerRenderInst->getShape();
  588. }
  589. S32 AnimationComponent::getAnimationCount()
  590. {
  591. if (getShape())
  592. return getShape()->sequences.size();
  593. else
  594. return 0;
  595. }
  596. S32 AnimationComponent::getAnimationIndex(const char* name)
  597. {
  598. if (getShape())
  599. return getShape()->findSequence(name);
  600. else
  601. return -1;
  602. }
  603. const char* AnimationComponent::getAnimationName(S32 index)
  604. {
  605. if (getShape())
  606. {
  607. if (index >= 0 && index < getShape()->sequences.size())
  608. return getShape()->getName(getShape()->sequences[index].nameIndex);
  609. }
  610. return "";
  611. }