llkeyframestandmotion.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /**
  2. * @file llkeyframestandmotion.cpp
  3. * @brief Implementation of LLKeyframeStandMotion class.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include "llkeyframestandmotion.h"
  34. #include "llcharacter.h"
  35. #define GO_TO_KEY_POSE 1
  36. #define MIN_TRACK_SPEED 0.01f
  37. constexpr F32 ROTATION_THRESHOLD = 0.6f;
  38. constexpr F32 POSITION_THRESHOLD = 0.1f;
  39. LLKeyframeStandMotion::LLKeyframeStandMotion(const LLUUID& id)
  40. : LLKeyframeMotion(id),
  41. mCharacter(NULL),
  42. mPelvisState(NULL),
  43. mHipLeftState(NULL),
  44. mKneeLeftState(NULL),
  45. mAnkleLeftState(NULL),
  46. mHipRightState(NULL),
  47. mKneeRightState(NULL),
  48. mAnkleRightState(NULL),
  49. mFrameNum(0),
  50. mFlipFeet(false),
  51. mTrackAnkles(true)
  52. {
  53. // Create kinematic hierarchy
  54. mPelvisJoint.addChild(&mHipLeftJoint);
  55. mHipLeftJoint.addChild(&mKneeLeftJoint);
  56. mKneeLeftJoint.addChild(&mAnkleLeftJoint);
  57. mPelvisJoint.addChild(&mHipRightJoint);
  58. mHipRightJoint.addChild(&mKneeRightJoint);
  59. mKneeRightJoint.addChild(&mAnkleRightJoint);
  60. }
  61. LLMotion::LLMotionInitStatus LLKeyframeStandMotion::onInitialize(LLCharacter* character)
  62. {
  63. // Save character pointer for later use
  64. mCharacter = character;
  65. mFlipFeet = false;
  66. // Load keyframe data, setup pose and joint states
  67. LLMotion::LLMotionInitStatus status =
  68. LLKeyframeMotion::onInitialize(character);
  69. if (status == STATUS_FAILURE)
  70. {
  71. return status;
  72. }
  73. // Find the necessary joint states
  74. LLPose* pose = getPose();
  75. mPelvisState = pose->findJointState(LL_JOINT_KEY_PELVIS);
  76. mHipLeftState = pose->findJointState(LL_JOINT_KEY_HIPLEFT);
  77. mKneeLeftState = pose->findJointState(LL_JOINT_KEY_KNEELEFT);
  78. mAnkleLeftState = pose->findJointState(LL_JOINT_KEY_ANKLELEFT);
  79. mHipRightState = pose->findJointState(LL_JOINT_KEY_HIPRIGHT);
  80. mKneeRightState = pose->findJointState(LL_JOINT_KEY_KNEERIGHT);
  81. mAnkleRightState = pose->findJointState(LL_JOINT_KEY_ANKLERIGHT);
  82. if (!mPelvisState || !mHipLeftState || !mKneeLeftState ||
  83. !mAnkleLeftState || !mHipRightState || !mKneeRightState ||
  84. !mAnkleRightState)
  85. {
  86. llinfos << getName() << ": cannot find necessary joint states."
  87. << llendl;
  88. return STATUS_FAILURE;
  89. }
  90. return STATUS_SUCCESS;
  91. }
  92. bool LLKeyframeStandMotion::onActivate()
  93. {
  94. // Setup the IK solvers
  95. mIKLeft.setPoleVector(LLVector3(1.f, 0.f, 0.f));
  96. mIKRight.setPoleVector(LLVector3(1.f, 0.f, 0.f));
  97. mIKLeft.setBAxis(LLVector3(0.05f, 1.f, 0.f));
  98. mIKRight.setBAxis(LLVector3(-0.05f, 1.f, 0.f));
  99. mLastGoodPelvisRotation.loadIdentity();
  100. mLastGoodPosition.clear();
  101. mFrameNum = 0;
  102. return LLKeyframeMotion::onActivate();
  103. }
  104. void LLKeyframeStandMotion::onDeactivate()
  105. {
  106. LLKeyframeMotion::onDeactivate();
  107. }
  108. bool LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask)
  109. {
  110. // Let the base class update the cycle
  111. bool status = LLKeyframeMotion::onUpdate(time, joint_mask);
  112. if (!status)
  113. {
  114. return false;
  115. }
  116. LLJoint* pelvisp = mPelvisState->getJoint();
  117. if (!pelvisp)
  118. {
  119. // Something is wrong. Pretend update is done and abort !
  120. return true;
  121. }
  122. LLJoint* parentp = pelvisp->getParent();
  123. if (!parentp)
  124. {
  125. // Something is wrong. Pretend update is done and abort !
  126. return true;
  127. }
  128. LLVector3 root_world_pos = parentp->getWorldPosition();
  129. // Have we received a valid world position for this avatar ?
  130. if (root_world_pos.isExactlyZero())
  131. {
  132. return true;
  133. }
  134. // Stop tracking (start locking) ankles once ease in is done.
  135. // Setting this here ensures we track until we get valid foot position.
  136. if (dot(pelvisp->getWorldRotation(),
  137. mLastGoodPelvisRotation) < ROTATION_THRESHOLD)
  138. {
  139. mLastGoodPelvisRotation = pelvisp->getWorldRotation();
  140. mLastGoodPelvisRotation.normalize();
  141. mTrackAnkles = true;
  142. }
  143. else if ((mCharacter->getCharacterPosition() -
  144. mLastGoodPosition).lengthSquared() > POSITION_THRESHOLD)
  145. {
  146. mLastGoodPosition = mCharacter->getCharacterPosition();
  147. mTrackAnkles = true;
  148. }
  149. else if (mPose.getWeight() < 1.f)
  150. {
  151. mTrackAnkles = true;
  152. }
  153. // Propagate joint positions to internal versions
  154. mPelvisJoint.setPosition(root_world_pos + mPelvisState->getPosition());
  155. mHipLeftJoint.setPosition(mHipLeftState->getJoint()->getPosition());
  156. mKneeLeftJoint.setPosition(mKneeLeftState->getJoint()->getPosition());
  157. mAnkleLeftJoint.setPosition(mAnkleLeftState->getJoint()->getPosition());
  158. mHipLeftJoint.setScale(mHipLeftState->getJoint()->getScale());
  159. mKneeLeftJoint.setScale(mKneeLeftState->getJoint()->getScale());
  160. mAnkleLeftJoint.setScale(mAnkleLeftState->getJoint()->getScale());
  161. mHipRightJoint.setPosition(mHipRightState->getJoint()->getPosition());
  162. mKneeRightJoint.setPosition(mKneeRightState->getJoint()->getPosition());
  163. mAnkleRightJoint.setPosition(mAnkleRightState->getJoint()->getPosition());
  164. mHipRightJoint.setScale(mHipRightState->getJoint()->getScale());
  165. mKneeRightJoint.setScale(mKneeRightState->getJoint()->getScale());
  166. mAnkleRightJoint.setScale(mAnkleRightState->getJoint()->getScale());
  167. // Propagate joint rotations to internal versions
  168. mPelvisJoint.setRotation(pelvisp->getWorldRotation());
  169. #if GO_TO_KEY_POSE
  170. mHipLeftJoint.setRotation(mHipLeftState->getRotation());
  171. mKneeLeftJoint.setRotation(mKneeLeftState->getRotation());
  172. mAnkleLeftJoint.setRotation(mAnkleLeftState->getRotation());
  173. mHipRightJoint.setRotation(mHipRightState->getRotation());
  174. mKneeRightJoint.setRotation(mKneeRightState->getRotation());
  175. mAnkleRightJoint.setRotation(mAnkleRightState->getRotation());
  176. #else
  177. mHipLeftJoint.setRotation(mHipLeftState->getJoint()->getRotation());
  178. mKneeLeftJoint.setRotation(mKneeLeftState->getJoint()->getRotation());
  179. mAnkleLeftJoint.setRotation(mAnkleLeftState->getJoint()->getRotation());
  180. mHipRightJoint.setRotation(mHipRightState->getJoint()->getRotation());
  181. mKneeRightJoint.setRotation(mKneeRightState->getJoint()->getRotation());
  182. mAnkleRightJoint.setRotation(mAnkleRightState->getJoint()->getRotation());
  183. #endif
  184. // Need to wait for underlying keyframe motion to affect the skeleton
  185. if (mFrameNum == 2)
  186. {
  187. mIKLeft.setupJoints(&mHipLeftJoint, &mKneeLeftJoint,
  188. &mAnkleLeftJoint, &mTargetLeft);
  189. mIKRight.setupJoints(&mHipRightJoint, &mKneeRightJoint,
  190. &mAnkleRightJoint, &mTargetRight);
  191. }
  192. else if (mFrameNum < 2)
  193. {
  194. ++mFrameNum;
  195. return true;
  196. }
  197. ++mFrameNum;
  198. // Compute target position by projecting ankles to the ground
  199. if (mTrackAnkles)
  200. {
  201. mCharacter->getGround(mAnkleLeftJoint.getWorldPosition(),
  202. mPositionLeft, mNormalLeft);
  203. mCharacter->getGround(mAnkleRightJoint.getWorldPosition(),
  204. mPositionRight, mNormalRight);
  205. mTargetLeft.setPosition(mPositionLeft);
  206. mTargetRight.setPosition(mPositionRight);
  207. }
  208. // Update solvers
  209. mIKLeft.solve();
  210. mIKRight.solve();
  211. // Make ankle rotation conform to the ground
  212. if (mTrackAnkles)
  213. {
  214. LLVector4 dir_left4 = mAnkleLeftJoint.getWorldMatrix().getFwdRow4();
  215. LLVector4 dir_right4 = mAnkleRightJoint.getWorldMatrix().getFwdRow4();
  216. LLVector3 dir_left = vec4to3(dir_left4);
  217. LLVector3 dir_right = vec4to3(dir_right4);
  218. LLVector3 up;
  219. LLVector3 dir;
  220. LLVector3 left;
  221. up = mNormalLeft;
  222. up.normalize();
  223. if (mFlipFeet)
  224. {
  225. up *= -1.f;
  226. }
  227. dir = dir_left;
  228. dir.normalize();
  229. left = up % dir;
  230. left.normalize();
  231. dir = left % up;
  232. mRotationLeft = LLQuaternion(dir, left, up);
  233. up = mNormalRight;
  234. up.normalize();
  235. if (mFlipFeet)
  236. {
  237. up *= -1.f;
  238. }
  239. dir = dir_right;
  240. dir.normalize();
  241. left = up % dir;
  242. left.normalize();
  243. dir = left % up;
  244. mRotationRight = LLQuaternion(dir, left, up);
  245. }
  246. mAnkleLeftJoint.setWorldRotation(mRotationLeft);
  247. mAnkleRightJoint.setWorldRotation(mRotationRight);
  248. // Propagate joint rotations to joint states
  249. mHipLeftState->setRotation(mHipLeftJoint.getRotation());
  250. mKneeLeftState->setRotation(mKneeLeftJoint.getRotation());
  251. mAnkleLeftState->setRotation(mAnkleLeftJoint.getRotation());
  252. mHipRightState->setRotation(mHipRightJoint.getRotation());
  253. mKneeRightState->setRotation(mKneeRightJoint.getRotation());
  254. mAnkleRightState->setRotation(mAnkleRightJoint.getRotation());
  255. return true;
  256. }