From 7a330c0e3fd4a3e190e6327deb769b595bc91342 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Thu, 21 Apr 2011 19:49:03 -0400 Subject: SH-1381 Avatar Physics behavior is tightly tied to viewer framerate Changed physics algorithm to perform integration over several steps if framerate is slow. Fixed a fundamental issue in the algorithm where timestep wasn't being used to calculate velocity changes. Had to change around some parameter ranges since the physics are calculated slightly differently now. --- indra/newview/character/avatar_lad.xml | 72 +++++++++++++------------- indra/newview/llphysicsmotion.cpp | 94 ++++++++++++++++------------------ 2 files changed, 79 insertions(+), 87 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 6acaa75c32..5d6b10c047 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -4352,8 +4352,8 @@ wearable="shape" edit_group="driven" value_default="0" - value_min="-1.5" - value_max="1.5"> + value_min="-1.25" + value_max="1.25"> @@ -11875,7 +11875,7 @@ render_pass="bump"> edit_group="physics_advanced" value_default="0" value_min="0" - value_max=".1"> + value_max="30"> @@ -11887,9 +11887,9 @@ render_pass="bump"> label="Breast Physics Drag" wearable="physics" edit_group="physics_advanced" - value_default=".15" + value_default="1" value_min="0" - value_max=".5"> + value_max="10"> @@ -11914,9 +11914,9 @@ render_pass="bump"> label="Breast Physics UpDown Spring" wearable="physics" edit_group="physics_breasts_updown" - value_default=".1" + value_default="10" value_min="0" - value_max="3"> + value_max="100"> label="Breast Physics UpDown Damping" wearable="physics" edit_group="physics_breasts_updown" - value_default=".05" + value_default=".2" value_min="0" - value_max=".1" - camera_elevation=".3" - camera_distance=".8"> + value_max="1"> @@ -11969,9 +11967,9 @@ render_pass="bump"> label="Breast Physics InOut Spring" wearable="physics" edit_group="physics_breasts_inout" - value_default=".1" + value_default="10" value_min="0" - value_max="3"> + value_max="100"> label="Breast Physics InOut Damping" wearable="physics" edit_group="physics_breasts_inout" - value_default=".05" + value_default=".2" value_min="0" - value_max=".1"> + value_max="1"> @@ -12022,7 +12020,7 @@ render_pass="bump"> edit_group="physics_advanced" value_default="0" value_min="0" - value_max=".1"> + value_max="30"> label="Belly Physics Drag" wearable="physics" edit_group="physics_advanced" - value_default=".15" + value_default="1" value_min="0" - value_max=".5"> + value_max="10"> label="Belly Physics UpDown Spring" wearable="physics" edit_group="physics_belly_updown" - value_default=".1" + value_default="10" value_min="0" - value_max="3"> + value_max="100"> label="Belly Physics UpDown Damping" wearable="physics" edit_group="physics_belly_updown" - value_default=".05" + value_default=".2" value_min="0" - value_max=".1"> + value_max="1"> @@ -12107,7 +12105,7 @@ render_pass="bump"> edit_group="physics_advanced" value_default="0" value_min="0" - value_max=".1"> + value_max="30"> label="Butt Physics Drag" wearable="physics" edit_group="physics_advanced" - value_default=".15" + value_default="1" value_min="0" - value_max=".5"> + value_max="10"> @@ -12142,9 +12140,9 @@ render_pass="bump"> label="Butt Physics UpDown Spring" wearable="physics" edit_group="physics_butt_updown" - value_default=".1" + value_default="10" value_min="0" - value_max="3"> + value_max="100"> label="Butt Physics UpDown Damping" wearable="physics" edit_group="physics_butt_updown" - value_default=".05" + value_default=".2" value_min="0" - value_max=".1"> + value_max="1"> @@ -12191,9 +12189,9 @@ render_pass="bump"> label="Butt Physics LeftRight Spring" wearable="physics" edit_group="physics_butt_leftright" - value_default=".1" + value_default="10" value_min="0" - value_max="3"> + value_max="100"> label="Butt Physics LeftRight Damping" wearable="physics" edit_group="physics_butt_leftright" - value_default=".05" + value_default=".2" value_min="0" - value_max=".1"> + value_max="1"> @@ -12242,9 +12240,9 @@ render_pass="bump"> label="Breast Physics LeftRight Spring" wearable="physics" edit_group="physics_breasts_leftright" - value_default=".1" + value_default="10" value_min="0" - value_max="3"> + value_max="100"> label="Breast Physics LeftRight Damping" wearable="physics" edit_group="physics_breasts_leftright" - value_default=".05" + value_default=".2" value_min="0" - value_max=".1"> + value_max="1"> diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index c9d355b3b5..7d862848b5 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -132,9 +132,8 @@ protected: F32 behavior_maxeffect); F32 toLocal(const LLVector3 &world); - F32 calculateVelocity_local(const F32 time_delta); - F32 calculateAcceleration_local(F32 velocity_local, - const F32 time_delta); + F32 calculateVelocity_local(); + F32 calculateAcceleration_local(F32 velocity_local); private: const std::string mParamDriverName; const std::string mParamControllerName; @@ -385,19 +384,20 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world) return world * dir_world; } -F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) +F32 LLPhysicsMotion::calculateVelocity_local() { + const F32 world_to_model_scale = 10.0f; LLJoint *joint = mJointState->getJoint(); const LLVector3 position_world = joint->getWorldPosition(); const LLQuaternion rotation_world = joint->getWorldRotation(); const LLVector3 last_position_world = mPosition_world; - const LLVector3 velocity_world = (position_world-last_position_world) / time_delta; + const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale; + const LLVector3 velocity_world = positionchange_world; const F32 velocity_local = toLocal(velocity_world); return velocity_local; } -F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, - const F32 time_delta) +F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local) { // const F32 smoothing = getParamValue("Smoothing"); static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary @@ -489,7 +489,31 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) if (physics_test) behavior_maxeffect = 1.0f; - BOOL update_visuals = FALSE; + // Normalize the param position to be from [0,1]. + // We have to use normalized values because there may be more than one driven param, + // and each of these driven params may have its own range. + // This means we'll do all our calculations in normalized [0,1] local coordinates. + const F32 position_user_local = (mParamDriver->getWeight() - mParamDriver->getMinWeight()) / (mParamDriver->getMaxWeight() - mParamDriver->getMinWeight()); + + // + // End parameters and settings + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate velocity and acceleration in parameter space. + // + + //const F32 velocity_joint_local = calculateVelocity_local(time_iteration_step); + const F32 velocity_joint_local = calculateVelocity_local(); + const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local); + + // + // End velocity and acceleration + //////////////////////////////////////////////////////////////////////////////// + + BOOL update_visuals = FALSE; + // Break up the physics into a bunch of iterations so that differing framerates will show // roughly the same behavior. for (F32 time_iteration = 0; time_iteration <= time_delta; time_iteration += TIME_ITERATION_STEP) @@ -497,46 +521,20 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) F32 time_iteration_step = TIME_ITERATION_STEP; if (time_iteration + TIME_ITERATION_STEP > time_delta) { - time_iteration_step = time_delta; + time_iteration_step = time_delta-time_iteration; } - // mPositon_local should be in normalized 0,1 range already. Just making sure... - F32 position_current_local = llclamp(mPosition_local, - 0.0f, - 1.0f); - - // Normalize the param position to be from [0,1]. - // We have to use normalized values because there may be more than one driven param, - // and each of these driven params may have its own range. - // This means we'll do all our calculations in normalized [0,1] local coordinates. - F32 position_user_local = mParamDriver->getWeight(); - position_user_local = (position_user_local - mParamDriver->getMinWeight()) / (mParamDriver->getMaxWeight() - mParamDriver->getMinWeight()); - + const F32 position_current_local = llclamp(mPosition_local, + 0.0f, + 1.0f); // If the effect is turned off then don't process unless we need one more update // to set the position to the default (i.e. user) position. if ((behavior_maxeffect == 0) && (position_current_local == position_user_local)) { - return FALSE; + return update_visuals; } - // - // End parameters and settings - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate velocity and acceleration in parameter space. - // - - const F32 velocity_joint_local = calculateVelocity_local(time_iteration_step); - const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_iteration_step); - - // - // End velocity and acceleration - //////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////// // Calculate the total force // @@ -553,7 +551,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) // Gravity always points downward in world space. // F = mg const LLVector3 gravity_world(0,0,1); - const F32 force_gravity = behavior_gain * (toLocal(gravity_world) * behavior_gravity * behavior_mass); + const F32 force_gravity = (toLocal(gravity_world) * behavior_gravity * behavior_mass); // Damping is a restoring force that opposes the current velocity. // F = -kv @@ -581,10 +579,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) // Calculate the new acceleration based on the net force. // a = F/m const F32 acceleration_new_local = force_net / behavior_mass; - static const F32 max_acceleration = 10.0f; // magic number, used to be customizable. - F32 velocity_new_local = mVelocity_local + acceleration_new_local; + static const F32 max_velocity = 100.0f; // magic number, used to be customizable. + F32 velocity_new_local = mVelocity_local + acceleration_new_local*time_iteration_step; velocity_new_local = llclamp(velocity_new_local, - -max_acceleration, max_acceleration); + -max_velocity, max_velocity); // Temporary debugging setting to cause all avatars to move, for profiling purposes. if (physics_test) @@ -610,8 +608,6 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) (position_new_local != position_new_local)) { position_new_local = 0; - position_current_local = 0; - position_user_local = 0; mVelocity_local = 0; mVelocityJoint_local = 0; mAccelerationJoint_local = 0; @@ -680,16 +676,14 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) // End update visual params //////////////////////////////////////////////////////////////////////////////// - mVelocityJoint_local = velocity_joint_local; - mVelocity_local = velocity_new_local; mAccelerationJoint_local = acceleration_joint_local; mPosition_local = position_new_local; - - mPosition_world = joint->getWorldPosition(); - } mLastTime = time; + mPosition_world = joint->getWorldPosition(); + mVelocityJoint_local = velocity_joint_local; + /* // Write out debugging info into a spreadsheet. -- cgit v1.2.3