PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llbreastmotion.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 396 lines | 234 code | 76 blank | 86 comment | 27 complexity | b25708502bc935ba370d6e6b5e24b367 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llbreastmotion.cpp
  3. * @brief Implementation of LLBreastMotion class.
  4. *
  5. * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2011, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. //-----------------------------------------------------------------------------
  27. // Header Files
  28. //-----------------------------------------------------------------------------
  29. #include "llviewerprecompiledheaders.h"
  30. #include "linden_common.h"
  31. #include "m3math.h"
  32. #include "v3dmath.h"
  33. #include "llbreastmotion.h"
  34. #include "llcharacter.h"
  35. #include "llviewercontrol.h"
  36. #include "llviewervisualparam.h"
  37. #include "llvoavatarself.h"
  38. #define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 0.f;
  39. #define N_PARAMS 2
  40. // User-set params
  41. static const std::string breast_param_names_user[N_PARAMS] =
  42. {
  43. "Breast_Female_Cleavage_Driver",
  44. "Breast_Gravity_Driver"
  45. };
  46. // Params driven by this algorithm
  47. static const std::string breast_param_names_driven[N_PARAMS] =
  48. {
  49. "Breast_Female_Cleavage",
  50. "Breast_Gravity"
  51. };
  52. LLBreastMotion::LLBreastMotion(const LLUUID &id) :
  53. LLMotion(id),
  54. mCharacter(NULL)
  55. {
  56. mName = "breast_motion";
  57. mChestState = new LLJointState;
  58. mBreastMassParam = (F32)1.0;
  59. mBreastDragParam = LLVector3((F32)0.1, (F32)0.1, (F32)0.1);
  60. mBreastSmoothingParam = (U32)2;
  61. mBreastGravityParam = (F32)0.0;
  62. mBreastSpringParam = LLVector3((F32)3.0, (F32)0.0, (F32)3.0);
  63. mBreastGainParam = LLVector3((F32)50.0, (F32)0.0, (F32)50.0);
  64. mBreastDampingParam = LLVector3((F32)0.3, (F32)0.0, (F32)0.3);
  65. mBreastMaxVelocityParam = LLVector3((F32)10.0, (F32)0.0, (F32)10.0);
  66. mBreastParamsUser[0] = mBreastParamsUser[1] = mBreastParamsUser[2] = NULL;
  67. mBreastParamsDriven[0] = mBreastParamsDriven[1] = mBreastParamsDriven[2] = NULL;
  68. mCharLastPosition_world_pt = LLVector3(0,0,0);
  69. mCharLastVelocity_local_vec = LLVector3(0,0,0);
  70. mCharLastAcceleration_local_vec = LLVector3(0,0,0);
  71. mBreastLastPosition_local_pt = LLVector3(0,0,0);
  72. mBreastLastUpdatePosition_local_pt = LLVector3(0,0,0);
  73. mBreastVelocity_local_vec = LLVector3(0,0,0);
  74. }
  75. LLBreastMotion::~LLBreastMotion()
  76. {
  77. }
  78. BOOL LLBreastMotion::onActivate()
  79. {
  80. return TRUE;
  81. }
  82. void LLBreastMotion::onDeactivate()
  83. {
  84. }
  85. LLMotion::LLMotionInitStatus LLBreastMotion::onInitialize(LLCharacter *character)
  86. {
  87. mCharacter = character;
  88. if (!mChestState->setJoint(character->getJoint("mChest")))
  89. {
  90. return STATUS_FAILURE;
  91. }
  92. mChestState->setUsage(LLJointState::ROT);
  93. addJointState( mChestState );
  94. for (U32 i=0; i < N_PARAMS; i++)
  95. {
  96. mBreastParamsUser[i] = NULL;
  97. mBreastParamsDriven[i] = NULL;
  98. mBreastParamsMin[i] = 0;
  99. mBreastParamsMax[i] = 0;
  100. if (breast_param_names_user[i] != "" && breast_param_names_driven[i] != "")
  101. {
  102. mBreastParamsUser[i] = (LLViewerVisualParam*)mCharacter->getVisualParam(breast_param_names_user[i].c_str());
  103. mBreastParamsDriven[i] = (LLViewerVisualParam*)mCharacter->getVisualParam(breast_param_names_driven[i].c_str());
  104. if (mBreastParamsDriven[i])
  105. {
  106. mBreastParamsMin[i] = mBreastParamsDriven[i]->getMinWeight();
  107. mBreastParamsMax[i] = mBreastParamsDriven[i]->getMaxWeight();
  108. }
  109. }
  110. }
  111. mTimer.reset();
  112. return STATUS_SUCCESS;
  113. }
  114. F32 LLBreastMotion::getMinPixelArea()
  115. {
  116. return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION;
  117. }
  118. F32 LLBreastMotion::calculateTimeDelta()
  119. {
  120. const F32 time = mTimer.getElapsedTimeF32();
  121. const F32 time_delta = time - mLastTime;
  122. mLastTime = time;
  123. return time_delta;
  124. }
  125. // Local space means "parameter space".
  126. LLVector3 LLBreastMotion::toLocal(const LLVector3 &world_vector)
  127. {
  128. LLVector3 local_vec(0,0,0);
  129. LLJoint *chest_joint = mChestState->getJoint();
  130. const LLQuaternion world_rot = chest_joint->getWorldRotation();
  131. // Cleavage
  132. LLVector3 breast_dir_world_vec = LLVector3(-1,0,0) * world_rot; // -1 b/c cleavage param changes opposite to direction
  133. breast_dir_world_vec.normalize();
  134. local_vec[0] = world_vector * breast_dir_world_vec;
  135. // Up-Down Bounce
  136. LLVector3 breast_up_dir_world_vec = LLVector3(0,0,1) * world_rot;
  137. breast_up_dir_world_vec.normalize();
  138. local_vec[1] = world_vector * breast_up_dir_world_vec;
  139. return local_vec;
  140. }
  141. LLVector3 LLBreastMotion::calculateVelocity_local(const F32 time_delta)
  142. {
  143. LLJoint *chest_joint = mChestState->getJoint();
  144. const LLVector3 world_pos_pt = chest_joint->getWorldPosition();
  145. const LLQuaternion world_rot = chest_joint->getWorldRotation();
  146. const LLVector3 last_world_pos_pt = mCharLastPosition_world_pt;
  147. const LLVector3 char_velocity_world_vec = (world_pos_pt-last_world_pos_pt) / time_delta;
  148. const LLVector3 char_velocity_local_vec = toLocal(char_velocity_world_vec);
  149. return char_velocity_local_vec;
  150. }
  151. LLVector3 LLBreastMotion::calculateAcceleration_local(const LLVector3 &new_char_velocity_local_vec,
  152. const F32 time_delta)
  153. {
  154. LLVector3 char_acceleration_local_vec = new_char_velocity_local_vec - mCharLastVelocity_local_vec;
  155. char_acceleration_local_vec =
  156. char_acceleration_local_vec * 1.0/mBreastSmoothingParam +
  157. mCharLastAcceleration_local_vec * (mBreastSmoothingParam-1.0)/mBreastSmoothingParam;
  158. mCharLastAcceleration_local_vec = char_acceleration_local_vec;
  159. return char_acceleration_local_vec;
  160. }
  161. BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask)
  162. {
  163. // Skip if disabled globally.
  164. if (!gSavedSettings.getBOOL("AvatarPhysics"))
  165. {
  166. return TRUE;
  167. }
  168. // Higher LOD is better. This controls the granularity
  169. // and frequency of updates for the motions.
  170. const F32 lod_factor = LLVOAvatar::sPhysicsLODFactor;
  171. if (lod_factor == 0)
  172. {
  173. return TRUE;
  174. }
  175. if (mCharacter->getSex() != SEX_FEMALE) return TRUE;
  176. const F32 time_delta = calculateTimeDelta();
  177. if (time_delta < .01 || time_delta > 10.0) return TRUE;
  178. ////////////////////////////////////////////////////////////////////////////////
  179. // Get all parameters and settings
  180. //
  181. mBreastMassParam = mCharacter->getVisualParamWeight("Breast_Physics_Mass");
  182. mBreastSmoothingParam = (U32)(mCharacter->getVisualParamWeight("Breast_Physics_Smoothing"));
  183. mBreastGravityParam = mCharacter->getVisualParamWeight("Breast_Physics_Gravity");
  184. mBreastSpringParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Spring");
  185. mBreastGainParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Gain");
  186. mBreastDampingParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Damping");
  187. mBreastMaxVelocityParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Max_Velocity");
  188. mBreastDragParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Drag");
  189. mBreastSpringParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Spring");
  190. mBreastGainParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Gain");
  191. mBreastDampingParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Damping");
  192. mBreastMaxVelocityParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Max_Velocity");
  193. mBreastDragParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Drag");
  194. // Get the current morph parameters.
  195. LLVector3 breast_user_local_pt(0,0,0);
  196. for (U32 i=0; i < N_PARAMS; i++)
  197. {
  198. if (mBreastParamsUser[i] != NULL)
  199. {
  200. breast_user_local_pt[i] = mBreastParamsUser[i]->getWeight();
  201. }
  202. }
  203. LLVector3 breast_current_local_pt = mBreastLastPosition_local_pt;
  204. //
  205. // End parameters and settings
  206. ////////////////////////////////////////////////////////////////////////////////
  207. ////////////////////////////////////////////////////////////////////////////////
  208. // Calculate velocity and acceleration in parameter space.
  209. //
  210. const LLVector3 char_velocity_local_vec = calculateVelocity_local(time_delta);
  211. const LLVector3 char_acceleration_local_vec = calculateAcceleration_local(char_velocity_local_vec, time_delta);
  212. mCharLastVelocity_local_vec = char_velocity_local_vec;
  213. LLJoint *chest_joint = mChestState->getJoint();
  214. mCharLastPosition_world_pt = chest_joint->getWorldPosition();
  215. //
  216. // End velocity and acceleration
  217. ////////////////////////////////////////////////////////////////////////////////
  218. ////////////////////////////////////////////////////////////////////////////////
  219. // Calculate the total force
  220. //
  221. // Spring force is a restoring force towards the original user-set breast position.
  222. // F = kx
  223. const LLVector3 spring_length_local = breast_current_local_pt-breast_user_local_pt;
  224. LLVector3 force_spring_local_vec = -spring_length_local; force_spring_local_vec *= mBreastSpringParam;
  225. // Acceleration is the force that comes from the change in velocity of the torso.
  226. // F = ma + mg
  227. LLVector3 force_accel_local_vec = char_acceleration_local_vec * mBreastMassParam;
  228. const LLVector3 force_gravity_local_vec = toLocal(LLVector3(0,0,1))* mBreastGravityParam * mBreastMassParam;
  229. force_accel_local_vec += force_gravity_local_vec;
  230. force_accel_local_vec *= mBreastGainParam;
  231. // Damping is a restoring force that opposes the current velocity.
  232. // F = -kv
  233. LLVector3 force_damping_local_vec = -mBreastDampingParam;
  234. force_damping_local_vec *= mBreastVelocity_local_vec;
  235. // Drag is a force imparted by velocity, intuitively it is similar to wind resistance.
  236. // F = .5v*v
  237. LLVector3 force_drag_local_vec = .5*char_velocity_local_vec;
  238. force_drag_local_vec *= char_velocity_local_vec;
  239. force_drag_local_vec *= mBreastDragParam[0];
  240. LLVector3 force_net_local_vec =
  241. force_accel_local_vec +
  242. force_gravity_local_vec +
  243. force_spring_local_vec +
  244. force_damping_local_vec +
  245. force_drag_local_vec;
  246. //
  247. // End total force
  248. ////////////////////////////////////////////////////////////////////////////////
  249. ////////////////////////////////////////////////////////////////////////////////
  250. // Calculate new params
  251. //
  252. // Calculate the new acceleration based on the net force.
  253. // a = F/m
  254. LLVector3 acceleration_local_vec = force_net_local_vec / mBreastMassParam;
  255. mBreastVelocity_local_vec += acceleration_local_vec;
  256. mBreastVelocity_local_vec.clamp(-mBreastMaxVelocityParam*100.0, mBreastMaxVelocityParam*100.0);
  257. // Temporary debugging setting to cause all avatars to move, for profiling purposes.
  258. if (gSavedSettings.getBOOL("AvatarPhysicsTest"))
  259. {
  260. mBreastVelocity_local_vec[0] = sin(mTimer.getElapsedTimeF32()*4.0)*5.0;
  261. mBreastVelocity_local_vec[1] = sin(mTimer.getElapsedTimeF32()*3.0)*5.0;
  262. }
  263. // Calculate the new parameters and clamp them to the min/max ranges.
  264. LLVector3 new_local_pt = breast_current_local_pt + mBreastVelocity_local_vec*time_delta;
  265. new_local_pt.clamp(mBreastParamsMin,mBreastParamsMax);
  266. // Set the new parameters.
  267. for (U32 i=0; i < 3; i++)
  268. {
  269. // If the param is disabled, just set the param to the user value.
  270. if (mBreastMaxVelocityParam[i] == 0)
  271. {
  272. new_local_pt[i] = breast_user_local_pt[i];
  273. }
  274. if (mBreastParamsDriven[i])
  275. {
  276. mCharacter->setVisualParamWeight(mBreastParamsDriven[i],
  277. new_local_pt[i],
  278. FALSE);
  279. }
  280. }
  281. mBreastLastPosition_local_pt = new_local_pt;
  282. //
  283. // End calculate new params
  284. ////////////////////////////////////////////////////////////////////////////////
  285. ////////////////////////////////////////////////////////////////////////////////
  286. // Conditionally update the visual params
  287. //
  288. // Updating the visual params (i.e. what the user sees) is fairly expensive.
  289. // So only update if the params have changed enough, and also take into account
  290. // the graphics LOD settings.
  291. // For non-self, if the avatar is small enough visually, then don't update.
  292. const BOOL is_self = (dynamic_cast<LLVOAvatarSelf *>(this) != NULL);
  293. if (!is_self)
  294. {
  295. const F32 area_for_max_settings = 0.0;
  296. const F32 area_for_min_settings = 1400.0;
  297. const F32 area_for_this_setting = area_for_max_settings + (area_for_min_settings-area_for_max_settings)*(1.0-lod_factor);
  298. const F32 pixel_area = fsqrtf(mCharacter->getPixelArea());
  299. if (pixel_area < area_for_this_setting)
  300. {
  301. return TRUE;
  302. }
  303. }
  304. // If the parameter hasn't changed enough, then don't update.
  305. LLVector3 position_diff = mBreastLastUpdatePosition_local_pt-new_local_pt;
  306. for (U32 i=0; i < 3; i++)
  307. {
  308. const F32 min_delta = (1.0-lod_factor)*(mBreastParamsMax[i]-mBreastParamsMin[i])/2.0;
  309. if (llabs(position_diff[i]) > min_delta)
  310. {
  311. mCharacter->updateVisualParams();
  312. mBreastLastUpdatePosition_local_pt = new_local_pt;
  313. return TRUE;
  314. }
  315. }
  316. //
  317. // End update visual params
  318. ////////////////////////////////////////////////////////////////////////////////
  319. return TRUE;
  320. }