summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llbreastmotion.cpp227
-rw-r--r--indra/newview/llbreastmotion.h1
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;
};