llhandmotion.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**
  2. * @file llhandmotion.cpp
  3. * @brief Implementation of LLHandMotion 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 "llhandmotion.h"
  34. #include "llcharacter.h"
  35. // Constants
  36. const char* gHandPoseNames[LLHandMotion::NUM_HAND_POSES] =
  37. {
  38. "",
  39. "Hands_Relaxed",
  40. "Hands_Point",
  41. "Hands_Fist",
  42. "Hands_Relaxed_L",
  43. "Hands_Point_L",
  44. "Hands_Fist_L",
  45. "Hands_Relaxed_R",
  46. "Hands_Point_R",
  47. "Hands_Fist_R",
  48. "Hands_Salute_R",
  49. "Hands_Typing",
  50. "Hands_Peace_R",
  51. "Hands_Spread_R"
  52. };
  53. constexpr F32 HAND_MORPH_BLEND_TIME = 0.2f;
  54. LLHandMotion::LLHandMotion(const LLUUID& id)
  55. : LLMotion(id),
  56. mCharacter(NULL),
  57. mLastTime(0.f),
  58. mCurrentPose(HAND_POSE_RELAXED),
  59. mNewPose(HAND_POSE_RELAXED)
  60. {
  61. mName = "hand_motion";
  62. // RN: flag hand joint as highest priority for now, until we implement a
  63. // proper animation track
  64. mJointSignature[0][LL_HAND_JOINT_NUM] = 0xff;
  65. mJointSignature[1][LL_HAND_JOINT_NUM] = 0xff;
  66. mJointSignature[2][LL_HAND_JOINT_NUM] = 0xff;
  67. }
  68. //virtual
  69. bool LLHandMotion::onActivate()
  70. {
  71. LLPolyMesh* upperBodyMesh = mCharacter->getUpperBodyMesh();
  72. if (upperBodyMesh)
  73. {
  74. // Note: 0 is the default
  75. for (S32 i = 1; i < LLHandMotion::NUM_HAND_POSES; ++i)
  76. {
  77. mCharacter->setVisualParamWeight(gHandPoseNames[i], 0.f);
  78. }
  79. mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
  80. mCharacter->updateVisualParams();
  81. }
  82. return true;
  83. }
  84. //virtual
  85. bool LLHandMotion::onUpdate(F32 time, U8* joint_mask)
  86. {
  87. F32 time_delta = time - mLastTime;
  88. if (time_delta < 0.f)
  89. {
  90. time_delta = 0.f;
  91. llwarns_sparse << "Negative time passed; zeroed." << llendl;
  92. }
  93. mLastTime = time;
  94. eHandPose* req_hand_pose =
  95. (eHandPose*)mCharacter->getAnimationData("Hand Pose");
  96. // check to see if requested pose has changed
  97. if (!req_hand_pose)
  98. {
  99. if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose)
  100. {
  101. // Only set param weight for poses other than the default
  102. // (HAND_POSE_SPREAD); HAND_POSE_SPREAD is not an animatable
  103. // morph !
  104. if (mNewPose != HAND_POSE_SPREAD)
  105. {
  106. mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose],
  107. 0.f);
  108. }
  109. // Reset morph weight for current pose back to its full extend or
  110. // it might be stuck somewhere in the middle if a pose is requested
  111. // and the old pose is requested again shortly after while still
  112. // blending to the other pose !
  113. if (mCurrentPose != HAND_POSE_SPREAD)
  114. {
  115. mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose],
  116. 1.f);
  117. }
  118. // Update visual params now if we won't blend
  119. if (mCurrentPose == HAND_POSE_RELAXED)
  120. {
  121. mCharacter->updateVisualParams();
  122. }
  123. }
  124. mNewPose = HAND_POSE_RELAXED;
  125. }
  126. else
  127. {
  128. // Sometimes we seem to get garbage here, with poses that are out of
  129. // bounds. So check for a valid pose first.
  130. if (*req_hand_pose >= 0 && *req_hand_pose < NUM_HAND_POSES)
  131. {
  132. // This is a new morph we didn't know about before: reset morph
  133. // weight for both current and new pose back their starting values
  134. // while still blending.
  135. if (*req_hand_pose != mNewPose && mNewPose != mCurrentPose)
  136. {
  137. if (mNewPose != HAND_POSE_SPREAD)
  138. {
  139. mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose],
  140. 0.f);
  141. }
  142. // Reset morph weight for current pose back to its full extend
  143. // or it might be stuck somewhere in the middle if a pose is
  144. // requested and the old pose is requested again shortly after
  145. // while still blending to the other pose !
  146. if (mCurrentPose != HAND_POSE_SPREAD)
  147. {
  148. mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose],
  149. 1.f);
  150. }
  151. // Update visual params now if we won't blend
  152. if (mCurrentPose == *req_hand_pose)
  153. {
  154. mCharacter->updateVisualParams();
  155. }
  156. }
  157. mNewPose = *req_hand_pose;
  158. }
  159. else
  160. {
  161. llwarns << "Invalid requested hand pose index; ignoring new hand pose."
  162. << llendl;
  163. mNewPose = mCurrentPose;
  164. }
  165. }
  166. mCharacter->removeAnimationData("Hand Pose");
  167. mCharacter->removeAnimationData("Hand Pose Priority");
  168. // If we are still blending...
  169. if (mCurrentPose != mNewPose)
  170. {
  171. LL_DEBUGS("Animation") << "New Hand Pose: " << gHandPoseNames[mNewPose]
  172. << LL_ENDL;
  173. F32 incoming_wght = 1.f;
  174. F32 outgoing_wght = 0.f;
  175. if (mNewPose != HAND_POSE_SPREAD)
  176. {
  177. incoming_wght =
  178. mCharacter->getVisualParamWeight(gHandPoseNames[mNewPose]);
  179. incoming_wght += (time_delta / HAND_MORPH_BLEND_TIME);
  180. incoming_wght = llclamp(incoming_wght, 0.f, 1.f);
  181. mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose],
  182. incoming_wght);
  183. }
  184. if (mCurrentPose != HAND_POSE_SPREAD)
  185. {
  186. outgoing_wght =
  187. mCharacter->getVisualParamWeight(gHandPoseNames[mCurrentPose]);
  188. outgoing_wght -= (time_delta / HAND_MORPH_BLEND_TIME);
  189. outgoing_wght = llclamp(outgoing_wght, 0.f, 1.f);
  190. mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose],
  191. outgoing_wght);
  192. }
  193. mCharacter->updateVisualParams();
  194. if (incoming_wght == 1.f && outgoing_wght == 0.f)
  195. {
  196. mCurrentPose = mNewPose;
  197. }
  198. }
  199. return true;
  200. }
  201. std::string LLHandMotion::getHandPoseName(eHandPose pose)
  202. {
  203. if ((S32)pose < LLHandMotion::NUM_HAND_POSES && (S32)pose >= 0)
  204. {
  205. return std::string(gHandPoseNames[pose]);
  206. }
  207. return LLStringUtil::null;
  208. }
  209. LLHandMotion::eHandPose LLHandMotion::getHandPose(const std::string& posename)
  210. {
  211. for (S32 pose = 0; pose < LLHandMotion::NUM_HAND_POSES; ++pose)
  212. {
  213. if (gHandPoseNames[pose] == posename)
  214. {
  215. return (eHandPose)pose;
  216. }
  217. }
  218. return (eHandPose)0;
  219. }