diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llbreastmotion.cpp | 227 | ||||
-rw-r--r-- | indra/newview/llbreastmotion.h | 1 |
2 files changed, 116 insertions, 112 deletions
diff --git a/indra/newview/llbreastmotion.cpp b/indra/newview/llbreastmotion.cpp index d4d0a78543..b38e818dbd 100644 --- a/indra/newview/llbreastmotion.cpp +++ b/indra/newview/llbreastmotion.cpp @@ -47,12 +47,27 @@ #define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 1000.f; -// #define OUTPUT_BREAST_DATA +#define N_PARAMS 2 + +// User-set params +static const std::string breast_param_names_user[N_PARAMS] = +{ + "Breast_Female_Cleavage_Driver", + "Breast_Gravity_Driver" +}; + +// Params driven by this algorithm +static const std::string breast_param_names_driven[N_PARAMS] = +{ + "Breast_Female_Cleavage", + "Breast_Gravity" +}; + + LLBreastMotion::LLBreastMotion(const LLUUID &id) : LLMotion(id), - mCharacter(NULL), - mFileWrite(NULL) + mCharacter(NULL) { mName = "breast_motion"; mChestState = new LLJointState; @@ -94,35 +109,16 @@ void LLBreastMotion::onDeactivate() LLMotion::LLMotionInitStatus LLBreastMotion::onInitialize(LLCharacter *character) { mCharacter = character; - BOOL success = true; - - if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) { success = false; } - if (!success) + if (!mChestState->setJoint(character->getJoint("mChest"))) { return STATUS_FAILURE; } - + mChestState->setUsage(LLJointState::ROT); addJointState( mChestState ); - - // User-set params - static const std::string breast_param_names_user[3] = - { - "Breast_Female_Cleavage_Driver", - "", - "Breast_Gravity_Driver" - }; - - // Params driven by this algorithm - static const std::string breast_param_names_driven[3] = - { - "Breast_Female_Cleavage", - "", - "Breast_Gravity" - }; - - for (U32 i=0; i < 3; i++) + + for (U32 i=0; i < N_PARAMS; i++) { mBreastParamsUser[i] = NULL; mBreastParamsDriven[i] = NULL; @@ -139,19 +135,7 @@ LLMotion::LLMotionInitStatus LLBreastMotion::onInitialize(LLCharacter *character } } } - -#ifdef OUTPUT_BREAST_DATA - //if (mCharacter->getSex() == SEX_FEMALE) - if (dynamic_cast<LLVOAvatarSelf *>(mCharacter)) - { - mFileWrite = fopen("c:\\temp\\data.txt","w"); - if (mFileWrite != NULL) - { - fprintf(mFileWrite,"Pos\tParam\tNet\tVel\t\tAccel\tSpring\tDamp\n"); - } - } -#endif - + mTimer.reset(); return STATUS_SUCCESS; } @@ -166,33 +150,27 @@ F32 LLBreastMotion::calculateTimeDelta() { const F32 time = mTimer.getElapsedTimeF32(); const F32 time_delta = time - mLastTime; - mLastTime = time; - return time_delta; } +// Local space means "parameter space". LLVector3 LLBreastMotion::toLocal(const LLVector3 &world_vector) { LLVector3 local_vec(0,0,0); LLJoint *chest_joint = mChestState->getJoint(); const LLQuaternion world_rot = chest_joint->getWorldRotation(); - - // -1 because cleavage param changes opposite to direction. - LLVector3 breast_dir_world_vec = LLVector3(-1,0,0) * world_rot; + + // Cleavage + LLVector3 breast_dir_world_vec = LLVector3(-1,0,0) * world_rot; // -1 b/c cleavage param changes opposite to direction breast_dir_world_vec.normalize(); local_vec[0] = world_vector * breast_dir_world_vec; - + + // Up-Down Bounce LLVector3 breast_up_dir_world_vec = LLVector3(0,0,1) * world_rot; breast_up_dir_world_vec.normalize(); - local_vec[2] = world_vector * breast_up_dir_world_vec; - - /* - { - llinfos << "Dir: " << breast_dir_world_vec << "V: " << world_vector << "DP: " << local_vec[0] << " time: " << llendl; - } - */ + local_vec[1] = world_vector * breast_up_dir_world_vec; return local_vec; } @@ -213,7 +191,7 @@ LLVector3 LLBreastMotion::calculateAcceleration_local(const LLVector3 &new_char_ const F32 time_delta) { LLVector3 char_acceleration_local_vec = new_char_velocity_local_vec - mCharLastVelocity_local_vec; - + char_acceleration_local_vec = char_acceleration_local_vec * 1.0/mBreastSmoothingParam + mCharLastAcceleration_local_vec * (mBreastSmoothingParam-1.0)/mBreastSmoothingParam; @@ -223,34 +201,31 @@ LLVector3 LLBreastMotion::calculateAcceleration_local(const LLVector3 &new_char_ return char_acceleration_local_vec; } -// called per time step -// must return TRUE while it is active, and -// must return FALSE when the motion is completed. BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask) { + // Skip if disabled globally. if (!gSavedSettings.getBOOL("AvatarPhysics")) { return TRUE; } + // Higher LOD is better. This controls the granularity + // and frequency of updates for the motions. const F32 lod_factor = LLVOAvatar::sPhysicsLODFactor; if (lod_factor == 0) { return TRUE; } - - if (!dynamic_cast<LLVOAvatarSelf *>(mCharacter)) - { - static int ticks=0; - ticks = (ticks + 1) % 10; - if (!ticks) - llinfos << "Pixel Area: " << mCharacter->getPixelArea() << " rt: " << fsqrtf(mCharacter->getPixelArea()) << llendl; - } - + if (mCharacter->getSex() != SEX_FEMALE) return TRUE; const F32 time_delta = calculateTimeDelta(); if (time_delta < .01 || time_delta > 10.0) return TRUE; + + //////////////////////////////////////////////////////////////////////////////// + // Get all parameters and settings + // + mBreastMassParam = mCharacter->getVisualParamWeight("Breast_Physics_Mass"); mBreastSmoothingParam = (U32)(mCharacter->getVisualParamWeight("Breast_Physics_Smoothing")); mBreastGravityParam = mCharacter->getVisualParamWeight("Breast_Physics_Gravity"); @@ -261,51 +236,72 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask) mBreastMaxVelocityParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Max_Velocity"); mBreastDragParam[0] = mCharacter->getVisualParamWeight("Breast_Physics_Side_Drag"); - mBreastSpringParam[2] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Spring"); - mBreastGainParam[2] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Gain"); - mBreastDampingParam[2] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Damping"); - mBreastMaxVelocityParam[2] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Max_Velocity"); - mBreastDragParam[2] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Drag"); + mBreastSpringParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Spring"); + mBreastGainParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Gain"); + mBreastDampingParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Damping"); + mBreastMaxVelocityParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Max_Velocity"); + mBreastDragParam[1] = mCharacter->getVisualParamWeight("Breast_Physics_UpDown_Drag"); - const BOOL is_self = (dynamic_cast<LLVOAvatarSelf *>(this) != NULL); - + // Get the current morph parameters. LLVector3 breast_user_local_pt(0,0,0); - - for (U32 i=0; i < 3; i++) + for (U32 i=0; i < N_PARAMS; i++) { if (mBreastParamsUser[i] != NULL) { breast_user_local_pt[i] = mBreastParamsUser[i]->getWeight(); } } - + LLVector3 breast_current_local_pt = mBreastLastPosition_local_pt; - + + // + // End parameters and settings + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate velocity and acceleration in parameter space. + // + const LLVector3 char_velocity_local_vec = calculateVelocity_local(time_delta); const LLVector3 char_acceleration_local_vec = calculateAcceleration_local(char_velocity_local_vec, time_delta); mCharLastVelocity_local_vec = char_velocity_local_vec; LLJoint *chest_joint = mChestState->getJoint(); mCharLastPosition_world_pt = chest_joint->getWorldPosition(); - + // + // End velocity and acceleration + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate the total force + // + + // Spring force is a restoring force towards the original user-set breast position. + // F = kx const LLVector3 spring_length_local = breast_current_local_pt-breast_user_local_pt; LLVector3 force_spring_local_vec = -spring_length_local; force_spring_local_vec *= mBreastSpringParam; + // Acceleration is the force that comes from the change in velocity of the torso. + // F = ma + mg LLVector3 force_accel_local_vec = char_acceleration_local_vec * mBreastMassParam; const LLVector3 force_gravity_local_vec = toLocal(LLVector3(0,0,1))* mBreastGravityParam * mBreastMassParam; force_accel_local_vec += force_gravity_local_vec; - force_accel_local_vec[0] *= mBreastGainParam[0]; - force_accel_local_vec[1] *= mBreastGainParam[1]; - force_accel_local_vec[2] *= mBreastGainParam[2]; - - LLVector3 force_damping_local_vec = -mBreastDampingParam; force_damping_local_vec *= mBreastVelocity_local_vec; + force_accel_local_vec *= mBreastGainParam; - LLVector3 force_drag_local_vec = .5*char_velocity_local_vec; // should square char_velocity_vec - force_drag_local_vec[0] *= mBreastDragParam[0]; - force_drag_local_vec[1] *= mBreastDragParam[1]; - force_drag_local_vec[2] *= mBreastDragParam[2]; + // Damping is a restoring force that opposes the current velocity. + // F = -kv + LLVector3 force_damping_local_vec = -mBreastDampingParam; + force_damping_local_vec *= mBreastVelocity_local_vec; + + // Drag is a force imparted by velocity, intuitively it is similar to wind resistance. + // F = .5v*v + LLVector3 force_drag_local_vec = .5*char_velocity_local_vec; + force_drag_local_vec *= char_velocity_local_vec; + force_drag_local_vec *= mBreastDragParam[0]; LLVector3 force_net_local_vec = force_accel_local_vec + @@ -314,17 +310,29 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask) force_damping_local_vec + force_drag_local_vec; + // + // End total force + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate new params + // + // Calculate the new acceleration based on the net force. + // a = F/m LLVector3 acceleration_local_vec = force_net_local_vec / mBreastMassParam; mBreastVelocity_local_vec += acceleration_local_vec; mBreastVelocity_local_vec.clamp(-mBreastMaxVelocityParam*100.0, mBreastMaxVelocityParam*100.0); + // Calculate the new parameters and clamp them to the min/max ranges. LLVector3 new_local_pt = breast_current_local_pt + mBreastVelocity_local_vec*time_delta; new_local_pt.clamp(mBreastParamsMin,mBreastParamsMax); - + // Set the new parameters. for (U32 i=0; i < 3; i++) { + // If the param is disabled, just set the param to the user value. if (mBreastMaxVelocityParam[i] == 0) { new_local_pt[i] = breast_user_local_pt[i]; @@ -337,32 +345,26 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask) } } - if (mFileWrite != NULL) - { - fprintf(mFileWrite,"%f\t%f\t%f\t%f\t\t%f\t%f\t%f\t \t%f\t%f\t%f\t%f\t%f\t%f\n", - mCharLastPosition_world_pt[2], - breast_current_local_pt[2], - acceleration_local_vec[2], - mBreastVelocity_local_vec[2], - - force_accel_local_vec[2], - force_spring_local_vec[2], - force_damping_local_vec[2], - - force_accel_local_vec[2], - force_damping_local_vec[2], - force_drag_local_vec[2], - force_net_local_vec[2], - time_delta, - mBreastMassParam - ); - } - mBreastLastPosition_local_pt = new_local_pt; + // + // End calculate new params + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Conditionally update the visual params + // + + // Updating the visual params (i.e. what the user sees) is fairly expensive. + // So only update if the params have changed enough, and also take into account + // the graphics LOD settings. + + // For non-self, if the avatar is small enough visually, then don't update. + const BOOL is_self = (dynamic_cast<LLVOAvatarSelf *>(this) != NULL); if (!is_self) { - const F32 area_for_max_settings = 300.0; + const F32 area_for_max_settings = 200.0; const F32 area_for_min_settings = 1400.0; const F32 area_for_this_setting = area_for_max_settings + (area_for_min_settings-area_for_max_settings)*(1.0-lod_factor); @@ -373,7 +375,7 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask) } } - + // If the parameter hasn't changed enough, then don't update. LLVector3 position_diff = mBreastLastUpdatePosition_local_pt-new_local_pt; for (U32 i=0; i < 3; i++) { @@ -385,7 +387,10 @@ BOOL LLBreastMotion::onUpdate(F32 time, U8* joint_mask) return TRUE; } } - + + // + // End update visual params + //////////////////////////////////////////////////////////////////////////////// return TRUE; } diff --git a/indra/newview/llbreastmotion.h b/indra/newview/llbreastmotion.h index da71962453..8578d4ad1a 100644 --- a/indra/newview/llbreastmotion.h +++ b/indra/newview/llbreastmotion.h @@ -153,7 +153,6 @@ private: LLFrameTimer mTimer; F32 mLastTime; - FILE *mFileWrite; U32 mFileTicks; }; |