From 3825ee503ddab29cf408ae35f5a43bcc154353f2 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Thu, 17 Mar 2011 17:36:01 -0400 Subject: Work in progress. Big code cleanup ported from TheShining/avatar-physics (defunct branch). Added butt and belly. --- indra/newview/llphysicsmotion.cpp | 559 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 559 insertions(+) create mode 100644 indra/newview/llphysicsmotion.cpp (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp new file mode 100644 index 0000000000..9043894009 --- /dev/null +++ b/indra/newview/llphysicsmotion.cpp @@ -0,0 +1,559 @@ +/** + * @file llphysicsmotion.cpp + * @brief Implementation of LLPhysicsMotion class. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "llviewerprecompiledheaders.h" +#include "linden_common.h" + +#include "m3math.h" +#include "v3dmath.h" + +#include "llphysicsmotion.h" +#include "llcharacter.h" +#include "llviewercontrol.h" +#include "llviewervisualparam.h" +#include "llvoavatarself.h" + +typedef std::map controller_map_t; + +#define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 0.f; + +inline F64 llsgn(const F64 a) +{ + if (a >= 0) + return 1; + return -1; +} + +class LLPhysicsMotion +{ +public: + LLPhysicsMotion(const std::string ¶m_user_name, + const std::string ¶m_driven_name, + const std::string &joint_name, + LLCharacter *character, + const LLVector3 &motion_direction_vec, + const controller_map_t &controllers) : + mParamUserName(param_user_name), + mParamDrivenName(param_driven_name), + mJointName(joint_name), + mMotionDirectionVec(motion_direction_vec), + mParamUser(NULL), + mParamDriven(NULL), + + mParamControllers(controllers), + mCharacter(character), + mLastTime(0), + mPosition_local(0), + mVelocityJoint_local(0), + mPositionLastUpdate_local(0), + mPositionMin_local(0), + mPositionMax_local(0) + { + mJointState = new LLJointState; + } + + BOOL initialize(); + + ~LLPhysicsMotion() {} + + BOOL onUpdate(F32 time); + + LLPointer getJointState() + { + return mJointState; + } +protected: + F32 getParamValue(const std::string& controller_key) + { + const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); + if (entry == mParamControllers.end()) + { + return 1.0; + } + const std::string& param_name = (*entry).second.c_str(); + return mCharacter->getVisualParamWeight(param_name.c_str()); + } + + F32 toLocal(const LLVector3 &world); + F32 calculateVelocity_local(const F32 time_delta); + F32 calculateAcceleration_local(F32 velocity_local, + const F32 time_delta); + +private: + const std::string mParamDrivenName; + const std::string mParamUserName; + const LLVector3 mMotionDirectionVec; + const std::string mJointName; + + F32 mPosition_local; + F32 mVelocityJoint_local; // How fast the joint is moving + F32 mAccelerationJoint_local; // Acceleration on the joint + + F32 mVelocity_local; // How fast the param is moving + F32 mPositionLastUpdate_local; + F32 mPositionMin_local; + F32 mPositionMax_local; + LLVector3 mPosition_world; + + LLViewerVisualParam *mParamUser; + LLViewerVisualParam *mParamDriven; + const controller_map_t mParamControllers; + + LLPointer mJointState; + LLCharacter *mCharacter; + + F32 mLastTime; + +}; + + + +BOOL LLPhysicsMotion::initialize() +{ + if (!mJointState->setJoint(mCharacter->getJoint(mJointName.c_str()))) + return FALSE; + mJointState->setUsage(LLJointState::ROT); + + mParamUser = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamUserName.c_str()); + mParamDriven = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDrivenName.c_str()); + if ((mParamUser == NULL) || + (mParamDriven == NULL)) + { + llinfos << "Failure reading in either of both of [ " << mParamUserName << " : " << mParamDrivenName << " ]" << llendl; + return FALSE; + } + mPositionMin_local = mParamDriven->getMinWeight(); + mPositionMax_local = mParamDriven->getMaxWeight(); + + return TRUE; +} + +LLPhysicsMotionController::LLPhysicsMotionController(const LLUUID &id) : + LLMotion(id), + mCharacter(NULL) +{ + mName = "breast_motion"; +} + +LLPhysicsMotionController::~LLPhysicsMotionController() +{ + for (motion_vec_t::iterator iter = mMotions.begin(); + iter != mMotions.end(); + ++iter) + { + delete (*iter); + } +} + +BOOL LLPhysicsMotionController::onActivate() +{ + return TRUE; +} + +void LLPhysicsMotionController::onDeactivate() +{ +} + +LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter *character) +{ + mCharacter = character; + + mMotions.clear(); + + controller_map_t controllers_cleavage; + controllers_cleavage["Mass"] = "Breast_Physics_Mass"; + controllers_cleavage["Smoothing"] = "Breast_Physics_Smoothing"; + controllers_cleavage["Gravity"] = "Breast_Physics_Gravity"; + controllers_cleavage["Damping"] = "Breast_Physics_Side_Damping"; + controllers_cleavage["Drag"] = "Breast_Physics_Side_Drag"; + controllers_cleavage["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; + controllers_cleavage["Spring"] = "Breast_Physics_Side_Spring"; + controllers_cleavage["Gain"] = "Breast_Physics_Side_Gain"; + + LLPhysicsMotion *cleavage_motion = new LLPhysicsMotion("Breast_Female_Cleavage_Driver", + "Breast_Female_Cleavage", + "mChest", + character, + LLVector3(-1,0,0), + controllers_cleavage); + if (!cleavage_motion->initialize()) + return STATUS_FAILURE; + addMotion(cleavage_motion); + + controller_map_t controllers_bounce; + controllers_bounce["Mass"] = "Breast_Physics_Mass"; + controllers_bounce["Smoothing"] = "Breast_Physics_Smoothing"; + controllers_bounce["Gravity"] = "Breast_Physics_Gravity"; + controllers_bounce["Damping"] = "Breast_Physics_UpDown_Damping"; + controllers_bounce["Drag"] = "Breast_Physics_UpDown_Drag"; + controllers_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controllers_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; + controllers_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; + + LLPhysicsMotion *bounce_motion = new LLPhysicsMotion("Breast_Gravity_Driver", + "Breast_Gravity", + "mChest", + character, + LLVector3(0,0,1), + controllers_bounce); + if (!bounce_motion->initialize()) + return STATUS_FAILURE; + addMotion(bounce_motion); + + controller_map_t controllers_butt_bounce; + controllers_butt_bounce["Mass"] = "Breast_Physics_Mass"; + controllers_butt_bounce["Smoothing"] = "Breast_Physics_Smoothing"; + controllers_butt_bounce["Gravity"] = "Breast_Physics_Gravity"; + controllers_butt_bounce["Damping"] = "Breast_Physics_Side_Damping"; + controllers_butt_bounce["Drag"] = "Breast_Physics_Side_Drag"; + controllers_butt_bounce["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; + controllers_butt_bounce["Spring"] = "Breast_Physics_Side_Spring"; + controllers_butt_bounce["Gain"] = "Breast_Physics_Side_Gain"; + + LLPhysicsMotion *butt_bounce_motion = new LLPhysicsMotion("Butt_Gravity_Driver", + "Butt_Gravity", + "mPelvis", + character, + LLVector3(0,0,-1), + controllers_butt_bounce); + if (!butt_bounce_motion->initialize()) + return STATUS_FAILURE; + addMotion(butt_bounce_motion); + + controller_map_t controllers_belly_bounce; + controllers_belly_bounce["Mass"] = "Breast_Physics_Mass"; + controllers_belly_bounce["Smoothing"] = "Breast_Physics_Smoothing"; + controllers_belly_bounce["Gravity"] = "Breast_Physics_Gravity"; + controllers_belly_bounce["Damping"] = "Breast_Physics_UpDown_Damping"; + controllers_belly_bounce["Drag"] = "Breast_Physics_UpDown_Drag"; + controllers_belly_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controllers_belly_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; + controllers_belly_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; + + LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Big_Belly_Torso", + "Belly Size", + "mChest", + character, + LLVector3(-0.005f,0,0), + controllers_belly_bounce); + if (!belly_bounce_motion->initialize()) + return STATUS_FAILURE; + addMotion(belly_bounce_motion); + + return STATUS_SUCCESS; +} + +void LLPhysicsMotionController::addMotion(LLPhysicsMotion *motion) +{ + addJointState(motion->getJointState()); + mMotions.push_back(motion); +} + +F32 LLPhysicsMotionController::getMinPixelArea() +{ + return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION; +} + +// Local space means "parameter space". +F32 LLPhysicsMotion::toLocal(const LLVector3 &world) +{ + LLJoint *joint = mJointState->getJoint(); + const LLQuaternion rotation_world = joint->getWorldRotation(); + + LLVector3 dir_world = mMotionDirectionVec * rotation_world; + dir_world.normalize(); + return world * dir_world * mMotionDirectionVec.length(); // dot product +} + +F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) +{ + 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 F32 velocity_local = toLocal(velocity_world); + return velocity_local; +} + +F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, + const F32 time_delta) +{ + const F32 smoothing = getParamValue("Smoothing"); + const F32 acceleration_local = velocity_local - mVelocityJoint_local; + + const F32 smoothed_acceleration_local = + acceleration_local * 1.0/smoothing + + mAccelerationJoint_local * (smoothing-1.0)/smoothing; + + return smoothed_acceleration_local; +} + +BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) +{ + // Skip if disabled globally. + if (!gSavedSettings.getBOOL("AvatarPhysics")) + { + return TRUE; + } + + if (mCharacter->getSex() != SEX_FEMALE) return TRUE; + + BOOL update_visuals = FALSE; + for (motion_vec_t::iterator iter = mMotions.begin(); + iter != mMotions.end(); + ++iter) + { + LLPhysicsMotion *motion = (*iter); + update_visuals |= motion->onUpdate(time); + } + + if (update_visuals) + mCharacter->updateVisualParams(); + + return TRUE; +} + + +// Return TRUE if character has to update visual params. +BOOL LLPhysicsMotion::onUpdate(F32 time) +{ + // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); + + if (!mParamUser || !mParamDriven) + return FALSE; + + if (!mLastTime) + { + mLastTime = time; + return FALSE; + } + + //////////////////////////////////////////////////////////////////////////////// + // Get all parameters and settings + // + + const F32 time_delta = time - mLastTime; + if (time_delta > 3.0 || time_delta <= 0.01) + { + mLastTime = time; + return FALSE; + } + + // 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; + } + + F32 behavior_mass = getParamValue("Mass"); + F32 behavior_gravity = getParamValue("Gravity"); + F32 behavior_spring = getParamValue("Spring"); + F32 behavior_gain = getParamValue("Gain"); + F32 behavior_damping = getParamValue("Damping"); + F32 behavior_maxspeed = getParamValue("MaxSpeed"); + F32 behavior_drag = getParamValue("Drag"); + + F32 position_user_local = mParamUser->getWeight(); + F32 position_current_local = mPosition_local; + + // + // End parameters and settings + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate velocity and acceleration in parameter space. + // + + const F32 velocity_joint_local = calculateVelocity_local(time_delta); + const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); + + LLJoint *joint = mJointState->getJoint(); + + // + // End velocity and acceleration + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate the total force + // + + // Spring force is a restoring force towards the original user-set breast position. + // F = kx + const F32 spring_length = position_current_local - position_user_local; + const F32 force_spring = -spring_length * behavior_spring; + + // Acceleration is the force that comes from the change in velocity of the torso. + // F = ma + const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); + + // 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); + + // Damping is a restoring force that opposes the current velocity. + // F = -kv + const F32 force_damping = -behavior_damping * mVelocity_local; + + // Drag is a force imparted by velocity (intuitively it is similar to wind resistance) + // F = .5kv^2 + const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); + + const F32 force_net = (force_accel + + force_gravity + + force_spring + + force_damping + + force_drag); + + // + // End total force + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate new params + // + + // Calculate the new acceleration based on the net force. + // a = F/m + const F32 acceleration_new_local = force_net / behavior_mass; + F32 velocity_new_local = mVelocity_local + acceleration_new_local; + velocity_new_local = llclamp(velocity_new_local, + -behavior_maxspeed*100.0f, behavior_maxspeed*100.0f); + + // Temporary debugging setting to cause all avatars to move, for profiling purposes. + if (gSavedSettings.getBOOL("AvatarPhysicsTest")) + { + velocity_new_local = sin(time*4.0)*5.0; + } + // Calculate the new parameters and clamp them to the min/max ranges. + F32 position_new_local = position_current_local + velocity_new_local*time_delta; + position_new_local = llclamp(position_new_local, + mPositionMin_local, mPositionMax_local); + + // Set the new parameters. + // If the param is disabled, just set the param to the user value. + if (behavior_maxspeed == 0) + { + position_new_local = position_user_local; + } + mCharacter->setVisualParamWeight(mParamDriven, + position_new_local, + FALSE); + + // + // 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. + + BOOL update_visuals = FALSE; + + // For non-self, if the avatar is small enough visually, then don't update. + const F32 area_for_max_settings = 0.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); + const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); + + const BOOL is_self = (dynamic_cast(mCharacter) != NULL); + if ((pixel_area > area_for_this_setting) || is_self) + { + // If the parameter hasn't changed enough, then don't update. + const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local); + const F32 min_delta = (1.0-lod_factor)*(mPositionMax_local-mPositionMin_local)/2.0; + if (llabs(position_diff_local) > min_delta) + { + update_visuals = TRUE; + mPositionLastUpdate_local = position_new_local; + } + } + + update_visuals = TRUE; + mPositionLastUpdate_local = position_new_local; + + // + // 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; + + /* + if (mFileWrite != NULL && is_self) + { + fprintf(mFileWrite,"%f\t%f\t%f \t\t%f \t\t%f\t%f\t%f\t \t\t%f\t%f\t%f\t%f\t%f \t\t%f\t%f\t%f\n", + position_new_local, + velocity_new_local, + acceleration_new_local, + + time_delta, + + mPosition_world[0], + mPosition_world[1], + mPosition_world[2], + + force_net, + force_spring, + force_accel, + force_damping, + force_drag, + + spring_length, + velocity_joint_local, + acceleration_joint_local + ); + } + */ + + return update_visuals; +} + -- cgit v1.2.3 From c754a7c0000d6f1defd58d7e8b4587d46ee1defe Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Fri, 18 Mar 2011 10:16:03 -0400 Subject: Enabling for belly vertical motion. --- indra/newview/llphysicsmotion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 9043894009..5de1f7e145 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -263,10 +263,10 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_belly_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Big_Belly_Torso", - "Belly Size", + "Belly_Gravity", "mChest", character, - LLVector3(-0.005f,0,0), + LLVector3(0,0,.25f), controllers_belly_bounce); if (!belly_bounce_motion->initialize()) return STATUS_FAILURE; -- cgit v1.2.3 From 9560faa1496790334becbe819b6ced6f5b17cf97 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Fri, 18 Mar 2011 10:31:38 -0400 Subject: Comments. --- indra/newview/llphysicsmotion.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 5de1f7e145..01b3ebe1f0 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -59,7 +59,30 @@ inline F64 llsgn(const F64 a) class LLPhysicsMotion { public: - LLPhysicsMotion(const std::string ¶m_user_name, + /* + param_user_name: The param (if any) that the user sees and controls. This is what + the particular body part would look like without physics. For example, it may be + the breast gravity. This param's value should will not be altered, and is only + used as a reference point for the rest position of the body party. This is usually + a driver param and the param that physics is altering is the driven param. + If this is left blank, that means that the physics is affecting a param that is + not exposed to the user. + + param_driven_name: The param whose value is actually set by the physics. + + joint_name: The joint that the body part is attached to. The joint is + used to determine the orientation (rotation) of the body part. + + character: The avatar that this physics affects. + + motion_direction_vec: The direction (in world coordinates) that determines the + motion. For example, (0,0,1) is up-down, and means that up-down motion is what + determines how this joint moves. + + controllers: The various settings (e.g. spring force, mass) that determine how + the body part behaves. + */ + LLPhysicsMotion(const std::string ¶m_user_name, const std::string ¶m_driven_name, const std::string &joint_name, LLCharacter *character, -- cgit v1.2.3 From d55f816fb15eab67abb72997b2eb589fff16f4ee Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Fri, 18 Mar 2011 14:54:30 -0400 Subject: Some code cleanup. Changed equations to occur in normalized (0,1) space instead of parameter space. --- indra/newview/llphysicsmotion.cpp | 199 +++++++++++++++++++++++++------------- 1 file changed, 130 insertions(+), 69 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 01b3ebe1f0..eb128e043c 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -46,6 +46,7 @@ #include "llvoavatarself.h" typedef std::map controller_map_t; +typedef std::map default_controller_map_t; #define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 0.f; @@ -56,19 +57,30 @@ inline F64 llsgn(const F64 a) return -1; } +/* + At a high level, this works by setting temporary parameters that are not stored + in the avatar's list of params, and are not conveyed to other users. We accomplish + this by creating some new temporary driven params inside avatar_lad that are then driven + by the actual params that the user sees and sets. For example, in the old system, + the user sets a param called breast bouyancy, which controls the Z value of the breasts. + In our new system, the user still sets the breast bouyancy, but that param is redefined + as a driver param so that it affects ... +*/ + class LLPhysicsMotion { public: /* param_user_name: The param (if any) that the user sees and controls. This is what - the particular body part would look like without physics. For example, it may be + the particular property would look like without physics. For example, it may be the breast gravity. This param's value should will not be altered, and is only used as a reference point for the rest position of the body party. This is usually - a driver param and the param that physics is altering is the driven param. - If this is left blank, that means that the physics is affecting a param that is - not exposed to the user. + a driver param and the param(s) that physics is altering are the driven params. - param_driven_name: The param whose value is actually set by the physics. + param_driven_name: The param whose value is actually set by the physics. If you + leave this blank (which should suffice normally), the physics will assume that + param_user_name is a driver param and will set the params that the driver is + in charge of (i.e. the "driven" params). joint_name: The joint that the body part is attached to. The joint is used to determine the orientation (rotation) of the body part. @@ -100,9 +112,7 @@ public: mLastTime(0), mPosition_local(0), mVelocityJoint_local(0), - mPositionLastUpdate_local(0), - mPositionMin_local(0), - mPositionMax_local(0) + mPositionLastUpdate_local(0) { mJointState = new LLJointState; } @@ -123,17 +133,18 @@ protected: const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); if (entry == mParamControllers.end()) { - return 1.0; + return sDefaultController[controller_key]; } const std::string& param_name = (*entry).second.c_str(); return mCharacter->getVisualParamWeight(param_name.c_str()); } + void setParamValue(LLViewerVisualParam *param, + const F32 new_value_local); F32 toLocal(const LLVector3 &world); F32 calculateVelocity_local(const F32 time_delta); F32 calculateAcceleration_local(F32 velocity_local, const F32 time_delta); - private: const std::string mParamDrivenName; const std::string mParamUserName; @@ -146,8 +157,6 @@ private: F32 mVelocity_local; // How fast the param is moving F32 mPositionLastUpdate_local; - F32 mPositionMin_local; - F32 mPositionMax_local; LLVector3 mPosition_world; LLViewerVisualParam *mParamUser; @@ -158,10 +167,25 @@ private: LLCharacter *mCharacter; F32 mLastTime; - + + static default_controller_map_t sDefaultController; }; +default_controller_map_t initDefaultController() +{ + default_controller_map_t controller; + controller["Mass"] = 2.0f; + controller["Smoothing"] = 2.0f; + controller["Gravity"] = 0.0f; + controller["Damping"] = .5f; + controller["Drag"] = 0.1f; + controller["MaxSpeed"] = 10.0f; + controller["Spring"] = 1.0f; + controller["Gain"] = 10.0f; + return controller; +} +default_controller_map_t LLPhysicsMotion::sDefaultController = initDefaultController(); BOOL LLPhysicsMotion::initialize() { @@ -170,15 +194,13 @@ BOOL LLPhysicsMotion::initialize() mJointState->setUsage(LLJointState::ROT); mParamUser = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamUserName.c_str()); - mParamDriven = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDrivenName.c_str()); - if ((mParamUser == NULL) || - (mParamDriven == NULL)) + if (mParamDrivenName != "") + mParamDriven = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDrivenName.c_str()); + if (mParamUser == NULL) { - llinfos << "Failure reading in either of both of [ " << mParamUserName << " : " << mParamDrivenName << " ]" << llendl; + llinfos << "Failure reading in [ " << mParamUserName << " ]" << llendl; return FALSE; } - mPositionMin_local = mParamDriven->getMinWeight(); - mPositionMax_local = mParamDriven->getMaxWeight(); return TRUE; } @@ -226,7 +248,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_cleavage["Gain"] = "Breast_Physics_Side_Gain"; LLPhysicsMotion *cleavage_motion = new LLPhysicsMotion("Breast_Female_Cleavage_Driver", - "Breast_Female_Cleavage", + "", "mChest", character, LLVector3(-1,0,0), @@ -246,7 +268,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; LLPhysicsMotion *bounce_motion = new LLPhysicsMotion("Breast_Gravity_Driver", - "Breast_Gravity", + "", "mChest", character, LLVector3(0,0,1), @@ -259,14 +281,13 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_butt_bounce["Mass"] = "Breast_Physics_Mass"; controllers_butt_bounce["Smoothing"] = "Breast_Physics_Smoothing"; controllers_butt_bounce["Gravity"] = "Breast_Physics_Gravity"; - controllers_butt_bounce["Damping"] = "Breast_Physics_Side_Damping"; - controllers_butt_bounce["Drag"] = "Breast_Physics_Side_Drag"; - controllers_butt_bounce["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; - controllers_butt_bounce["Spring"] = "Breast_Physics_Side_Spring"; - controllers_butt_bounce["Gain"] = "Breast_Physics_Side_Gain"; - + controllers_butt_bounce["Damping"] = "Breast_Physics_UpDown_Damping"; + controllers_butt_bounce["Drag"] = "Breast_Physics_UpDown_Drag"; + controllers_butt_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controllers_butt_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; + controllers_butt_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; LLPhysicsMotion *butt_bounce_motion = new LLPhysicsMotion("Butt_Gravity_Driver", - "Butt_Gravity", + "", "mPelvis", character, LLVector3(0,0,-1), @@ -284,13 +305,12 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_belly_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; controllers_belly_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; controllers_belly_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; - - LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Big_Belly_Torso", - "Belly_Gravity", - "mChest", - character, - LLVector3(0,0,.25f), - controllers_belly_bounce); + LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Belly_Gravity", + "", + "mChest", + character, + LLVector3(0,0,1), + controllers_belly_bounce); if (!belly_bounce_motion->initialize()) return STATUS_FAILURE; addMotion(belly_bounce_motion); @@ -375,7 +395,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) { // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); - if (!mParamUser || !mParamDriven) + if (!mParamUser) return FALSE; if (!mLastTime) @@ -403,16 +423,24 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) return TRUE; } - F32 behavior_mass = getParamValue("Mass"); - F32 behavior_gravity = getParamValue("Gravity"); - F32 behavior_spring = getParamValue("Spring"); - F32 behavior_gain = getParamValue("Gain"); - F32 behavior_damping = getParamValue("Damping"); - F32 behavior_maxspeed = getParamValue("MaxSpeed"); - F32 behavior_drag = getParamValue("Drag"); + LLJoint *joint = mJointState->getJoint(); + + const F32 behavior_mass = getParamValue("Mass"); + const F32 behavior_gravity = getParamValue("Gravity"); + const F32 behavior_spring = getParamValue("Spring"); + const F32 behavior_gain = getParamValue("Gain"); + const F32 behavior_damping = getParamValue("Damping"); + const F32 behavior_maxspeed = getParamValue("MaxSpeed"); + const F32 behavior_drag = getParamValue("Drag"); + + F32 position_current_local = mPosition_local; // Normalized [0,1] range + // 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 = mParamUser->getWeight(); - F32 position_current_local = mPosition_local; + position_user_local = (position_user_local - mParamUser->getMinWeight()) / (mParamUser->getMaxWeight() - mParamUser->getMinWeight()); // // End parameters and settings @@ -426,8 +454,6 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) const F32 velocity_joint_local = calculateVelocity_local(time_delta); const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); - LLJoint *joint = mJointState->getJoint(); - // // End velocity and acceleration //////////////////////////////////////////////////////////////////////////////// @@ -486,21 +512,46 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) { velocity_new_local = sin(time*4.0)*5.0; } - // Calculate the new parameters and clamp them to the min/max ranges. - F32 position_new_local = position_current_local + velocity_new_local*time_delta; - position_new_local = llclamp(position_new_local, - mPositionMin_local, mPositionMax_local); - - // Set the new parameters. - // If the param is disabled, just set the param to the user value. - if (behavior_maxspeed == 0) + // Calculate the new parameters, or remain unchanged if max speed is 0. + const F32 position_new_local = (behavior_maxspeed != 0) ? + (position_current_local + velocity_new_local*time_delta) : + position_user_local; + + const F32 position_new_local_clamped = llclamp(position_new_local, + 0.0f, + 1.0f); + + // Set the new param. + // 1. If the user has specified a param target, use that. + // 2. If the param is a driver param, set the param(s) that it drives. + // 3. Otherwise, set the param directly (don't do this if the param is a user-editable param!) + // If a specific param has been declared, then set that one. + // Otherwise, assume that the param is a driver param, and + // set the params that it drives. + if (mParamDriven) { - position_new_local = position_user_local; + setParamValue(mParamDriven,position_new_local_clamped); } - mCharacter->setVisualParamWeight(mParamDriven, - position_new_local, - FALSE); - + else + { + LLDriverParam *driver_param = dynamic_cast(mParamUser); + if (driver_param) + { + for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); + iter != driver_param->mDriven.end(); + ++iter) + { + LLDrivenEntry &entry = (*iter); + LLViewerVisualParam *driven_param = entry.mParam; + setParamValue(driven_param,position_new_local_clamped); + } + } + else + { + setParamValue(mParamUser,position_new_local_clamped); + } + } + // // End calculate new params //////////////////////////////////////////////////////////////////////////////// @@ -508,7 +559,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) //////////////////////////////////////////////////////////////////////////////// // 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. @@ -520,13 +571,12 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) 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); const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); - + const BOOL is_self = (dynamic_cast(mCharacter) != NULL); if ((pixel_area > area_for_this_setting) || is_self) { - // If the parameter hasn't changed enough, then don't update. - const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local); - const F32 min_delta = (1.0-lod_factor)*(mPositionMax_local-mPositionMin_local)/2.0; + const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); + const F32 min_delta = (1.0f-lod_factor)*4.0f; // Magic number 2.0f, can change this if experimentally something works better. if (llabs(position_diff_local) > min_delta) { update_visuals = TRUE; @@ -534,9 +584,6 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) } } - update_visuals = TRUE; - mPositionLastUpdate_local = position_new_local; - // // End update visual params //////////////////////////////////////////////////////////////////////////////// @@ -551,6 +598,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) mLastTime = time; /* + // Write out debugging info into a spreadsheet. if (mFileWrite != NULL && is_self) { fprintf(mFileWrite,"%f\t%f\t%f \t\t%f \t\t%f\t%f\t%f\t \t\t%f\t%f\t%f\t%f\t%f \t\t%f\t%f\t%f\n", @@ -577,6 +625,19 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) } */ - return update_visuals; + return TRUE; +} + +// Range of new_value_local is assumed to be [0 , 1] normalized. +void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param, + F32 new_value_normalized) +{ + const F32 value_min_local = param->getMinWeight(); + const F32 value_max_local = param->getMaxWeight(); + + const F32 new_value_local = value_min_local + (value_max_local-value_min_local) * new_value_normalized; + + mCharacter->setVisualParamWeight(param, + new_value_local, + FALSE); } - -- cgit v1.2.3 From 86613fd388d7985abc814ee8ee52da54fd74779e Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Fri, 18 Mar 2011 16:04:28 -0400 Subject: Variety of fixes for param ranges. Turned off normal/binormal effects for morphing. Fixed issue where updates were always being sent even if below the change threshold. --- indra/newview/llphysicsmotion.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index eb128e043c..c9a75784e1 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -309,7 +309,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter "", "mChest", character, - LLVector3(0,0,1), + LLVector3(0,0,-1), controllers_belly_bounce); if (!belly_bounce_motion->initialize()) return STATUS_FAILURE; @@ -337,7 +337,7 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world) LLVector3 dir_world = mMotionDirectionVec * rotation_world; dir_world.normalize(); - return world * dir_world * mMotionDirectionVec.length(); // dot product + return world * dir_world; } F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) @@ -625,7 +625,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) } */ - return TRUE; + return update_visuals; } // Range of new_value_local is assumed to be [0 , 1] normalized. -- cgit v1.2.3 From 53a944f2859d07eceed2a01a6b4f7339c0c591d9 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Fri, 18 Mar 2011 18:02:27 -0400 Subject: Set default parameters. Renamed various parameters. --- indra/newview/llphysicsmotion.cpp | 53 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index c9a75784e1..094faf4d97 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -174,13 +174,13 @@ private: default_controller_map_t initDefaultController() { default_controller_map_t controller; - controller["Mass"] = 2.0f; + controller["Mass"] = 0.2f; controller["Smoothing"] = 2.0f; controller["Gravity"] = 0.0f; - controller["Damping"] = .5f; - controller["Drag"] = 0.1f; - controller["MaxSpeed"] = 10.0f; - controller["Spring"] = 1.0f; + controller["Damping"] = .05f; + controller["Drag"] = 0.15f; + controller["MaxSpeed"] = 0.1f; + controller["Spring"] = 0.1f; controller["Gain"] = 10.0f; return controller; } @@ -247,7 +247,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_cleavage["Spring"] = "Breast_Physics_Side_Spring"; controllers_cleavage["Gain"] = "Breast_Physics_Side_Gain"; - LLPhysicsMotion *cleavage_motion = new LLPhysicsMotion("Breast_Female_Cleavage_Driver", + LLPhysicsMotion *cleavage_motion = new LLPhysicsMotion("Breast_Physics_Side_Controller", "", "mChest", character, @@ -267,52 +267,53 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controllers_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; controllers_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; - LLPhysicsMotion *bounce_motion = new LLPhysicsMotion("Breast_Gravity_Driver", + LLPhysicsMotion *bounce_motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", "", "mChest", character, LLVector3(0,0,1), controllers_bounce); if (!bounce_motion->initialize()) + { + llassert_always(FALSE); return STATUS_FAILURE; + } addMotion(bounce_motion); controller_map_t controllers_butt_bounce; - controllers_butt_bounce["Mass"] = "Breast_Physics_Mass"; - controllers_butt_bounce["Smoothing"] = "Breast_Physics_Smoothing"; - controllers_butt_bounce["Gravity"] = "Breast_Physics_Gravity"; - controllers_butt_bounce["Damping"] = "Breast_Physics_UpDown_Damping"; - controllers_butt_bounce["Drag"] = "Breast_Physics_UpDown_Drag"; - controllers_butt_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; - controllers_butt_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; - controllers_butt_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; - LLPhysicsMotion *butt_bounce_motion = new LLPhysicsMotion("Butt_Gravity_Driver", + controllers_butt_bounce["Damping"] = "Butt_Physics_Updown_Damping"; + controllers_butt_bounce["MaxSpeed"] = "Butt_Physics_Updown_Max_Velocity"; + controllers_butt_bounce["Spring"] = "Butt_Physics_Updown_Spring"; + controllers_butt_bounce["Gain"] = "Butt_Physics_Updown_Gain"; + LLPhysicsMotion *butt_bounce_motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", "", "mPelvis", character, LLVector3(0,0,-1), controllers_butt_bounce); if (!butt_bounce_motion->initialize()) + { + llassert_always(FALSE); return STATUS_FAILURE; + } addMotion(butt_bounce_motion); controller_map_t controllers_belly_bounce; - controllers_belly_bounce["Mass"] = "Breast_Physics_Mass"; - controllers_belly_bounce["Smoothing"] = "Breast_Physics_Smoothing"; - controllers_belly_bounce["Gravity"] = "Breast_Physics_Gravity"; - controllers_belly_bounce["Damping"] = "Breast_Physics_UpDown_Damping"; - controllers_belly_bounce["Drag"] = "Breast_Physics_UpDown_Drag"; - controllers_belly_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; - controllers_belly_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; - controllers_belly_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; - LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Belly_Gravity", + controllers_belly_bounce["Damping"] = "Belly_Physics_Updown_Damping"; + controllers_belly_bounce["MaxSpeed"] = "Belly_Physics_Updown_Max_Velocity"; + controllers_belly_bounce["Spring"] = "Belly_Physics_Updown_Spring"; + controllers_belly_bounce["Gain"] = "Belly_Physics_Updown_Gain"; + LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", "", "mChest", character, LLVector3(0,0,-1), controllers_belly_bounce); if (!belly_bounce_motion->initialize()) + { + llassert_always(FALSE); return STATUS_FAILURE; + } addMotion(belly_bounce_motion); return STATUS_SUCCESS; @@ -372,8 +373,6 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) return TRUE; } - if (mCharacter->getSex() != SEX_FEMALE) return TRUE; - BOOL update_visuals = FALSE; for (motion_vec_t::iterator iter = mMotions.begin(); iter != mMotions.end(); -- cgit v1.2.3 From 49e449e3a6ea08a969a214ffb7c66ac9607e2732 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Fri, 18 Mar 2011 18:59:59 -0400 Subject: Added more belly bounce. Added butt driver param back in. --- indra/newview/llphysicsmotion.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 094faf4d97..393120be40 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -64,7 +64,8 @@ inline F64 llsgn(const F64 a) by the actual params that the user sees and sets. For example, in the old system, the user sets a param called breast bouyancy, which controls the Z value of the breasts. In our new system, the user still sets the breast bouyancy, but that param is redefined - as a driver param so that it affects ... + as a driver param so that affects a new temporary driven param that the bounce is applied + to. */ class LLPhysicsMotion @@ -521,9 +522,6 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) 1.0f); // Set the new param. - // 1. If the user has specified a param target, use that. - // 2. If the param is a driver param, set the param(s) that it drives. - // 3. Otherwise, set the param directly (don't do this if the param is a user-editable param!) // If a specific param has been declared, then set that one. // Otherwise, assume that the param is a driver param, and // set the params that it drives. @@ -534,6 +532,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) else { LLDriverParam *driver_param = dynamic_cast(mParamUser); + llassert_always(driver_param); if (driver_param) { for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); @@ -545,10 +544,6 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) setParamValue(driven_param,position_new_local_clamped); } } - else - { - setParamValue(mParamUser,position_new_local_clamped); - } } // -- cgit v1.2.3 From 717d81daa7f42d18ca37eb738ceacfe2b9c1a09a Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Mon, 21 Mar 2011 12:04:31 -0400 Subject: Added left-right butt control. Did a bunch of code cleanup. --- indra/newview/llphysicsmotion.cpp | 136 +++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 59 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 393120be40..87e062a881 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -238,85 +238,103 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter mMotions.clear(); - controller_map_t controllers_cleavage; - controllers_cleavage["Mass"] = "Breast_Physics_Mass"; - controllers_cleavage["Smoothing"] = "Breast_Physics_Smoothing"; - controllers_cleavage["Gravity"] = "Breast_Physics_Gravity"; - controllers_cleavage["Damping"] = "Breast_Physics_Side_Damping"; - controllers_cleavage["Drag"] = "Breast_Physics_Side_Drag"; - controllers_cleavage["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; - controllers_cleavage["Spring"] = "Breast_Physics_Side_Spring"; - controllers_cleavage["Gain"] = "Breast_Physics_Side_Gain"; - - LLPhysicsMotion *cleavage_motion = new LLPhysicsMotion("Breast_Physics_Side_Controller", - "", - "mChest", - character, - LLVector3(-1,0,0), - controllers_cleavage); - if (!cleavage_motion->initialize()) + controller_map_t controller_breast_inout; + controller_breast_inout["Mass"] = "Breast_Physics_Mass"; + controller_breast_inout["Smoothing"] = "Breast_Physics_Smoothing"; + controller_breast_inout["Gravity"] = "Breast_Physics_Gravity"; + controller_breast_inout["Damping"] = "Breast_Physics_Side_Damping"; + controller_breast_inout["Drag"] = "Breast_Physics_Side_Drag"; + controller_breast_inout["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; + controller_breast_inout["Spring"] = "Breast_Physics_Side_Spring"; + controller_breast_inout["Gain"] = "Breast_Physics_Side_Gain"; + + LLPhysicsMotion *motion_breast_inout = new LLPhysicsMotion("Breast_Physics_Side_Controller", + "", + "mChest", + character, + LLVector3(-1,0,0), + controller_breast_inout); + if (!motion_breast_inout->initialize()) return STATUS_FAILURE; - addMotion(cleavage_motion); - - controller_map_t controllers_bounce; - controllers_bounce["Mass"] = "Breast_Physics_Mass"; - controllers_bounce["Smoothing"] = "Breast_Physics_Smoothing"; - controllers_bounce["Gravity"] = "Breast_Physics_Gravity"; - controllers_bounce["Damping"] = "Breast_Physics_UpDown_Damping"; - controllers_bounce["Drag"] = "Breast_Physics_UpDown_Drag"; - controllers_bounce["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; - controllers_bounce["Spring"] = "Breast_Physics_UpDown_Spring"; - controllers_bounce["Gain"] = "Breast_Physics_UpDown_Gain"; - - LLPhysicsMotion *bounce_motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", - "", - "mChest", - character, - LLVector3(0,0,1), - controllers_bounce); - if (!bounce_motion->initialize()) + addMotion(motion_breast_inout); + + controller_map_t controller_breast_updown; + controller_breast_updown["Mass"] = "Breast_Physics_Mass"; + controller_breast_updown["Smoothing"] = "Breast_Physics_Smoothing"; + controller_breast_updown["Gravity"] = "Breast_Physics_Gravity"; + controller_breast_updown["Damping"] = "Breast_Physics_UpDown_Damping"; + controller_breast_updown["Drag"] = "Breast_Physics_UpDown_Drag"; + controller_breast_updown["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controller_breast_updown["Spring"] = "Breast_Physics_UpDown_Spring"; + controller_breast_updown["Gain"] = "Breast_Physics_UpDown_Gain"; + + LLPhysicsMotion *motion_breast_updown = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", + "", + "mChest", + character, + LLVector3(0,0,1), + controller_breast_updown); + if (!motion_breast_updown->initialize()) { llassert_always(FALSE); return STATUS_FAILURE; } - addMotion(bounce_motion); - - controller_map_t controllers_butt_bounce; - controllers_butt_bounce["Damping"] = "Butt_Physics_Updown_Damping"; - controllers_butt_bounce["MaxSpeed"] = "Butt_Physics_Updown_Max_Velocity"; - controllers_butt_bounce["Spring"] = "Butt_Physics_Updown_Spring"; - controllers_butt_bounce["Gain"] = "Butt_Physics_Updown_Gain"; - LLPhysicsMotion *butt_bounce_motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", + addMotion(motion_breast_updown); + + controller_map_t controller_butt_updown; + controller_butt_updown["Damping"] = "Butt_Physics_Updown_Damping"; + controller_butt_updown["MaxSpeed"] = "Butt_Physics_Updown_Max_Velocity"; + controller_butt_updown["Spring"] = "Butt_Physics_Updown_Spring"; + controller_butt_updown["Gain"] = "Butt_Physics_Updown_Gain"; + LLPhysicsMotion *motion_butt_updown = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", "", "mPelvis", character, - LLVector3(0,0,-1), - controllers_butt_bounce); - if (!butt_bounce_motion->initialize()) + LLVector3(0,0,1), + controller_butt_updown); + if (!motion_butt_updown->initialize()) { llassert_always(FALSE); return STATUS_FAILURE; } - addMotion(butt_bounce_motion); - - controller_map_t controllers_belly_bounce; - controllers_belly_bounce["Damping"] = "Belly_Physics_Updown_Damping"; - controllers_belly_bounce["MaxSpeed"] = "Belly_Physics_Updown_Max_Velocity"; - controllers_belly_bounce["Spring"] = "Belly_Physics_Updown_Spring"; - controllers_belly_bounce["Gain"] = "Belly_Physics_Updown_Gain"; - LLPhysicsMotion *belly_bounce_motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", + addMotion(motion_butt_updown); + + controller_map_t controller_butt_leftright; + controller_butt_leftright["Damping"] = "Butt_Physics_Updown_Damping"; + controller_butt_leftright["MaxSpeed"] = "Butt_Physics_Updown_Max_Velocity"; + controller_butt_leftright["Spring"] = "Butt_Physics_Updown_Spring"; + controller_butt_leftright["Gain"] = "Butt_Physics_Updown_Gain"; + LLPhysicsMotion *motion_butt_leftright = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", + "", + "mPelvis", + character, + LLVector3(0,1,0), + controller_butt_leftright); + if (!motion_butt_leftright->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion_butt_leftright); + + controller_map_t controller_belly_updown; + controller_belly_updown["Damping"] = "Belly_Physics_Updown_Damping"; + controller_belly_updown["MaxSpeed"] = "Belly_Physics_Updown_Max_Velocity"; + controller_belly_updown["Spring"] = "Belly_Physics_Updown_Spring"; + controller_belly_updown["Gain"] = "Belly_Physics_Updown_Gain"; + LLPhysicsMotion *motion_belly_updown = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", "", "mChest", character, LLVector3(0,0,-1), - controllers_belly_bounce); - if (!belly_bounce_motion->initialize()) + controller_belly_updown); + if (!motion_belly_updown->initialize()) { llassert_always(FALSE); return STATUS_FAILURE; } - addMotion(belly_bounce_motion); - + addMotion(motion_belly_updown); + return STATUS_SUCCESS; } -- cgit v1.2.3 From 77ad0269aca9169dc41bee08ff860373d7715b8c Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Mon, 21 Mar 2011 14:15:41 -0400 Subject: Fixes for physics update thresholds. --- indra/newview/llphysicsmotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 87e062a881..2a88a4a2b5 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -588,7 +588,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) if ((pixel_area > area_for_this_setting) || is_self) { const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); - const F32 min_delta = (1.0f-lod_factor)*4.0f; // Magic number 2.0f, can change this if experimentally something works better. + const F32 min_delta = (1.01f-lod_factor)*0.75f; // 75% is just an experimental magic number. if (llabs(position_diff_local) > min_delta) { update_visuals = TRUE; -- cgit v1.2.3 From 209110d1aa7ee369ccdf68641c3d7f9e558427de Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Mon, 21 Mar 2011 15:39:42 -0400 Subject: Velocity now gets zeroed out if the param is pushed beyond limits. Rescaled the max speed param. --- indra/newview/llphysicsmotion.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 2a88a4a2b5..48e632280e 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -523,7 +523,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) const F32 acceleration_new_local = force_net / behavior_mass; F32 velocity_new_local = mVelocity_local + acceleration_new_local; velocity_new_local = llclamp(velocity_new_local, - -behavior_maxspeed*100.0f, behavior_maxspeed*100.0f); + -behavior_maxspeed, behavior_maxspeed); // Temporary debugging setting to cause all avatars to move, for profiling purposes. if (gSavedSettings.getBOOL("AvatarPhysicsTest")) @@ -535,6 +535,12 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) (position_current_local + velocity_new_local*time_delta) : position_user_local; + // Zero out the velocity if the param is being pushed beyond its limits. + if (position_new_local < 0 || position_new_local > 1) + { + velocity_new_local = 0; + } + const F32 position_new_local_clamped = llclamp(position_new_local, 0.0f, 1.0f); -- cgit v1.2.3 From 3208104e2e51124fb6ee90133fee328f59e1fddc Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 29 Mar 2011 20:57:17 -0400 Subject: A bit of rearchitecture so that we can have edit wearables that don't have associated snapshots. Needed to support physics wearables, which don't use a snapshot. --- indra/newview/llphysicsmotion.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 48e632280e..4048c66262 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -448,8 +448,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) const F32 behavior_spring = getParamValue("Spring"); const F32 behavior_gain = getParamValue("Gain"); const F32 behavior_damping = getParamValue("Damping"); - const F32 behavior_maxspeed = getParamValue("MaxSpeed"); const F32 behavior_drag = getParamValue("Drag"); + const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); + + F32 behavior_maxspeed = getParamValue("MaxSpeed"); + if (physics_test) + behavior_maxspeed = 100.0f; + /* + if (behavior_maxspeed == 0) + return FALSE; + */ F32 position_current_local = mPosition_local; // Normalized [0,1] range @@ -526,9 +534,9 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) -behavior_maxspeed, behavior_maxspeed); // Temporary debugging setting to cause all avatars to move, for profiling purposes. - if (gSavedSettings.getBOOL("AvatarPhysicsTest")) + if (physics_test) { - velocity_new_local = sin(time*4.0)*5.0; + velocity_new_local = sin(time*4.0); } // Calculate the new parameters, or remain unchanged if max speed is 0. const F32 position_new_local = (behavior_maxspeed != 0) ? -- cgit v1.2.3 From 993ad22f9ffeae6d20f75dc409cf0128ca167a0e Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Wed, 30 Mar 2011 19:28:03 -0400 Subject: Cleanup to logically group physics params in avatar_lad.xml. Added more controls for belly & butt. Cleaned up code around physics parameter initialization. --- indra/newview/llphysicsmotion.cpp | 204 ++++++++++++++++++++++---------------- 1 file changed, 116 insertions(+), 88 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 4048c66262..fd83f4d482 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -238,102 +238,130 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter mMotions.clear(); - controller_map_t controller_breast_inout; - controller_breast_inout["Mass"] = "Breast_Physics_Mass"; - controller_breast_inout["Smoothing"] = "Breast_Physics_Smoothing"; - controller_breast_inout["Gravity"] = "Breast_Physics_Gravity"; - controller_breast_inout["Damping"] = "Breast_Physics_Side_Damping"; - controller_breast_inout["Drag"] = "Breast_Physics_Side_Drag"; - controller_breast_inout["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; - controller_breast_inout["Spring"] = "Breast_Physics_Side_Spring"; - controller_breast_inout["Gain"] = "Breast_Physics_Side_Gain"; - - LLPhysicsMotion *motion_breast_inout = new LLPhysicsMotion("Breast_Physics_Side_Controller", - "", - "mChest", - character, - LLVector3(-1,0,0), - controller_breast_inout); - if (!motion_breast_inout->initialize()) - return STATUS_FAILURE; - addMotion(motion_breast_inout); - - controller_map_t controller_breast_updown; - controller_breast_updown["Mass"] = "Breast_Physics_Mass"; - controller_breast_updown["Smoothing"] = "Breast_Physics_Smoothing"; - controller_breast_updown["Gravity"] = "Breast_Physics_Gravity"; - controller_breast_updown["Damping"] = "Breast_Physics_UpDown_Damping"; - controller_breast_updown["Drag"] = "Breast_Physics_UpDown_Drag"; - controller_breast_updown["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; - controller_breast_updown["Spring"] = "Breast_Physics_UpDown_Spring"; - controller_breast_updown["Gain"] = "Breast_Physics_UpDown_Gain"; - - LLPhysicsMotion *motion_breast_updown = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", - "", - "mChest", - character, - LLVector3(0,0,1), - controller_breast_updown); - if (!motion_breast_updown->initialize()) + // Breast Cleavage { - llassert_always(FALSE); - return STATUS_FAILURE; + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Smoothing"] = "Breast_Physics_Smoothing"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Damping"] = "Breast_Physics_Side_Damping"; + controller["Drag"] = "Breast_Physics_Side_Drag"; + controller["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; + controller["Spring"] = "Breast_Physics_Side_Spring"; + controller["Gain"] = "Breast_Physics_Side_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_Side_Controller", + "", + "mChest", + character, + LLVector3(-1,0,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Breast Bounce + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Smoothing"] = "Breast_Physics_Smoothing"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Damping"] = "Breast_Physics_UpDown_Damping"; + controller["Drag"] = "Breast_Physics_UpDown_Drag"; + controller["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controller["Spring"] = "Breast_Physics_UpDown_Spring"; + controller["Gain"] = "Breast_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", + "", + "mChest", + character, + LLVector3(0,0,1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); } - addMotion(motion_breast_updown); - - controller_map_t controller_butt_updown; - controller_butt_updown["Damping"] = "Butt_Physics_Updown_Damping"; - controller_butt_updown["MaxSpeed"] = "Butt_Physics_Updown_Max_Velocity"; - controller_butt_updown["Spring"] = "Butt_Physics_Updown_Spring"; - controller_butt_updown["Gain"] = "Butt_Physics_Updown_Gain"; - LLPhysicsMotion *motion_butt_updown = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", - "", - "mPelvis", - character, - LLVector3(0,0,1), - controller_butt_updown); - if (!motion_butt_updown->initialize()) + + // Butt Bounce { - llassert_always(FALSE); - return STATUS_FAILURE; + controller_map_t controller; + controller["Mass"] = "Butt_Physics_Mass"; + controller["Smoothing"] = "Butt_Physics_Smoothing"; + controller["Gravity"] = "Butt_Physics_Gravity"; + controller["Damping"] = "Butt_Physics_UpDown_Damping"; + controller["Drag"] = "Butt_Physics_UpDown_Drag"; + controller["MaxSpeed"] = "Butt_Physics_UpDown_Max_Velocity"; + controller["Spring"] = "Butt_Physics_UpDown_Spring"; + controller["Gain"] = "Butt_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", + "", + "mPelvis", + character, + LLVector3(0,0,1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); } - addMotion(motion_butt_updown); - - controller_map_t controller_butt_leftright; - controller_butt_leftright["Damping"] = "Butt_Physics_Updown_Damping"; - controller_butt_leftright["MaxSpeed"] = "Butt_Physics_Updown_Max_Velocity"; - controller_butt_leftright["Spring"] = "Butt_Physics_Updown_Spring"; - controller_butt_leftright["Gain"] = "Butt_Physics_Updown_Gain"; - LLPhysicsMotion *motion_butt_leftright = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", - "", - "mPelvis", - character, - LLVector3(0,1,0), - controller_butt_leftright); - if (!motion_butt_leftright->initialize()) + + // Butt LeftRight { - llassert_always(FALSE); - return STATUS_FAILURE; + controller_map_t controller; + controller["Mass"] = "Butt_Physics_Mass"; + controller["Smoothing"] = "Butt_Physics_Smoothing"; + controller["Gravity"] = "Butt_Physics_Gravity"; + controller["Damping"] = "Butt_Physics_LeftRight_Damping"; + controller["Drag"] = "Butt_Physics_LeftRight_Drag"; + controller["MaxSpeed"] = "Butt_Physics_LeftRight_Max_Velocity"; + controller["Spring"] = "Butt_Physics_LeftRight_Spring"; + controller["Gain"] = "Butt_Physics_LeftRight_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", + "", + "mPelvis", + character, + LLVector3(0,1,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); } - addMotion(motion_butt_leftright); - - controller_map_t controller_belly_updown; - controller_belly_updown["Damping"] = "Belly_Physics_Updown_Damping"; - controller_belly_updown["MaxSpeed"] = "Belly_Physics_Updown_Max_Velocity"; - controller_belly_updown["Spring"] = "Belly_Physics_Updown_Spring"; - controller_belly_updown["Gain"] = "Belly_Physics_Updown_Gain"; - LLPhysicsMotion *motion_belly_updown = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", - "", - "mChest", - character, - LLVector3(0,0,-1), - controller_belly_updown); - if (!motion_belly_updown->initialize()) + + // Belly Bounce { - llassert_always(FALSE); - return STATUS_FAILURE; + controller_map_t controller; + controller["Mass"] = "Belly_Physics_Mass"; + controller["Smoothing"] = "Belly_Physics_Smoothing"; + controller["Gravity"] = "Belly_Physics_Gravity"; + controller["Damping"] = "Belly_Physics_UpDown_Damping"; + controller["Drag"] = "Belly_Physics_UpDown_Drag"; + controller["MaxSpeed"] = "Belly_Physics_UpDown_Max_Velocity"; + controller["Spring"] = "Belly_Physics_UpDown_Spring"; + controller["Gain"] = "Belly_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", + "", + "mPelvis", + character, + LLVector3(0,0,-1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); } - addMotion(motion_belly_updown); return STATUS_SUCCESS; } -- cgit v1.2.3 From 1ceb29bdacb309ed374128feae879953c2e13820 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Wed, 30 Mar 2011 23:17:58 -0400 Subject: Change in physics parameter names. Split some physics parameters into separate accordions based on updown/leftright. Fixed a minor issue with physics edit tab height. --- indra/newview/llphysicsmotion.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index fd83f4d482..e6fe6fe924 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -244,12 +244,12 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Mass"] = "Breast_Physics_Mass"; controller["Smoothing"] = "Breast_Physics_Smoothing"; controller["Gravity"] = "Breast_Physics_Gravity"; - controller["Damping"] = "Breast_Physics_Side_Damping"; - controller["Drag"] = "Breast_Physics_Side_Drag"; - controller["MaxSpeed"] = "Breast_Physics_Side_Max_Velocity"; - controller["Spring"] = "Breast_Physics_Side_Spring"; - controller["Gain"] = "Breast_Physics_Side_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_Side_Controller", + controller["Damping"] = "Breast_Physics_InOut_Damping"; + controller["Drag"] = "Breast_Physics_InOut_Drag"; + controller["MaxSpeed"] = "Breast_Physics_InOut_Max_Velocity"; + controller["Spring"] = "Breast_Physics_InOut_Spring"; + controller["Gain"] = "Breast_Physics_InOut_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", "", "mChest", character, @@ -630,7 +630,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) if ((pixel_area > area_for_this_setting) || is_self) { const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); - const F32 min_delta = (1.01f-lod_factor)*0.75f; // 75% is just an experimental magic number. + const F32 min_delta = (1.01f-lod_factor)*0.5f; // 75% is just an experimental magic number. if (llabs(position_diff_local) > min_delta) { update_visuals = TRUE; -- cgit v1.2.3 From 107ca5d7c8f7a511e6606a91930b893edbfe884e Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Thu, 31 Mar 2011 15:41:01 -0400 Subject: Simple fix for out-of-bounds parameter issues. --- indra/newview/llphysicsmotion.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index e6fe6fe924..157d13e1a4 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -482,12 +482,13 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) F32 behavior_maxspeed = getParamValue("MaxSpeed"); if (physics_test) behavior_maxspeed = 100.0f; - /* + if (behavior_maxspeed == 0) return FALSE; - */ - F32 position_current_local = mPosition_local; // Normalized [0,1] range + F32 position_current_local = llclamp(mPosition_local, + 0.0f, + 1.0f); // Normalized [0,1] range // Normalize the param position to be from [0,1]. // We have to use normalized values because there may be more than one driven param, -- cgit v1.2.3 From ba0c369aa20cdbfd7940a2435dd3c6630f0d54ae Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Thu, 31 Mar 2011 15:56:33 -0400 Subject: Tweaking of avatar physics detail slider. --- indra/newview/llphysicsmotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 157d13e1a4..73de1cef3f 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -631,7 +631,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) if ((pixel_area > area_for_this_setting) || is_self) { const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); - const F32 min_delta = (1.01f-lod_factor)*0.5f; // 75% is just an experimental magic number. + const F32 min_delta = (1.01f-lod_factor)*0.4f; if (llabs(position_diff_local) > min_delta) { update_visuals = TRUE; -- cgit v1.2.3 From cc2a813ce40a09bab230a62809f5ff21083a81f2 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sat, 2 Apr 2011 18:36:49 -0400 Subject: Moved Drag to be a general shape physics param, to save on number of transmitted params. --- indra/newview/llphysicsmotion.cpp | 1114 ++++++++++++++++++------------------- 1 file changed, 557 insertions(+), 557 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 73de1cef3f..53809b4d19 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -52,9 +52,9 @@ typedef std::map default_controller_map_t; inline F64 llsgn(const F64 a) { - if (a >= 0) - return 1; - return -1; + if (a >= 0) + return 1; + return -1; } /* @@ -71,161 +71,161 @@ inline F64 llsgn(const F64 a) class LLPhysicsMotion { public: - /* - param_user_name: The param (if any) that the user sees and controls. This is what - the particular property would look like without physics. For example, it may be - the breast gravity. This param's value should will not be altered, and is only - used as a reference point for the rest position of the body party. This is usually - a driver param and the param(s) that physics is altering are the driven params. - - param_driven_name: The param whose value is actually set by the physics. If you - leave this blank (which should suffice normally), the physics will assume that - param_user_name is a driver param and will set the params that the driver is - in charge of (i.e. the "driven" params). - - joint_name: The joint that the body part is attached to. The joint is - used to determine the orientation (rotation) of the body part. - - character: The avatar that this physics affects. - - motion_direction_vec: The direction (in world coordinates) that determines the - motion. For example, (0,0,1) is up-down, and means that up-down motion is what - determines how this joint moves. - - controllers: The various settings (e.g. spring force, mass) that determine how - the body part behaves. - */ - LLPhysicsMotion(const std::string ¶m_user_name, - const std::string ¶m_driven_name, - const std::string &joint_name, - LLCharacter *character, - const LLVector3 &motion_direction_vec, - const controller_map_t &controllers) : - mParamUserName(param_user_name), - mParamDrivenName(param_driven_name), - mJointName(joint_name), - mMotionDirectionVec(motion_direction_vec), - mParamUser(NULL), - mParamDriven(NULL), - - mParamControllers(controllers), - mCharacter(character), - mLastTime(0), - mPosition_local(0), - mVelocityJoint_local(0), - mPositionLastUpdate_local(0) - { - mJointState = new LLJointState; - } - - BOOL initialize(); - - ~LLPhysicsMotion() {} - - BOOL onUpdate(F32 time); - - LLPointer getJointState() - { - return mJointState; - } + /* + param_user_name: The param (if any) that the user sees and controls. This is what + the particular property would look like without physics. For example, it may be + the breast gravity. This param's value should will not be altered, and is only + used as a reference point for the rest position of the body party. This is usually + a driver param and the param(s) that physics is altering are the driven params. + + param_driven_name: The param whose value is actually set by the physics. If you + leave this blank (which should suffice normally), the physics will assume that + param_user_name is a driver param and will set the params that the driver is + in charge of (i.e. the "driven" params). + + joint_name: The joint that the body part is attached to. The joint is + used to determine the orientation (rotation) of the body part. + + character: The avatar that this physics affects. + + motion_direction_vec: The direction (in world coordinates) that determines the + motion. For example, (0,0,1) is up-down, and means that up-down motion is what + determines how this joint moves. + + controllers: The various settings (e.g. spring force, mass) that determine how + the body part behaves. + */ + LLPhysicsMotion(const std::string ¶m_user_name, + const std::string ¶m_driven_name, + const std::string &joint_name, + LLCharacter *character, + const LLVector3 &motion_direction_vec, + const controller_map_t &controllers) : + mParamUserName(param_user_name), + mParamDrivenName(param_driven_name), + mJointName(joint_name), + mMotionDirectionVec(motion_direction_vec), + mParamUser(NULL), + mParamDriven(NULL), + + mParamControllers(controllers), + mCharacter(character), + mLastTime(0), + mPosition_local(0), + mVelocityJoint_local(0), + mPositionLastUpdate_local(0) + { + mJointState = new LLJointState; + } + + BOOL initialize(); + + ~LLPhysicsMotion() {} + + BOOL onUpdate(F32 time); + + LLPointer getJointState() + { + return mJointState; + } protected: - F32 getParamValue(const std::string& controller_key) - { - const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); - if (entry == mParamControllers.end()) - { - return sDefaultController[controller_key]; - } - const std::string& param_name = (*entry).second.c_str(); - return mCharacter->getVisualParamWeight(param_name.c_str()); - } - void setParamValue(LLViewerVisualParam *param, - const F32 new_value_local); - - F32 toLocal(const LLVector3 &world); - F32 calculateVelocity_local(const F32 time_delta); - F32 calculateAcceleration_local(F32 velocity_local, - const F32 time_delta); + F32 getParamValue(const std::string& controller_key) + { + const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); + if (entry == mParamControllers.end()) + { + return sDefaultController[controller_key]; + } + const std::string& param_name = (*entry).second.c_str(); + return mCharacter->getVisualParamWeight(param_name.c_str()); + } + void setParamValue(LLViewerVisualParam *param, + const F32 new_value_local); + + F32 toLocal(const LLVector3 &world); + F32 calculateVelocity_local(const F32 time_delta); + F32 calculateAcceleration_local(F32 velocity_local, + const F32 time_delta); private: - const std::string mParamDrivenName; - const std::string mParamUserName; - const LLVector3 mMotionDirectionVec; - const std::string mJointName; - - F32 mPosition_local; - F32 mVelocityJoint_local; // How fast the joint is moving - F32 mAccelerationJoint_local; // Acceleration on the joint - - F32 mVelocity_local; // How fast the param is moving - F32 mPositionLastUpdate_local; - LLVector3 mPosition_world; - - LLViewerVisualParam *mParamUser; - LLViewerVisualParam *mParamDriven; - const controller_map_t mParamControllers; - - LLPointer mJointState; - LLCharacter *mCharacter; - - F32 mLastTime; - - static default_controller_map_t sDefaultController; + const std::string mParamDrivenName; + const std::string mParamUserName; + const LLVector3 mMotionDirectionVec; + const std::string mJointName; + + F32 mPosition_local; + F32 mVelocityJoint_local; // How fast the joint is moving + F32 mAccelerationJoint_local; // Acceleration on the joint + + F32 mVelocity_local; // How fast the param is moving + F32 mPositionLastUpdate_local; + LLVector3 mPosition_world; + + LLViewerVisualParam *mParamUser; + LLViewerVisualParam *mParamDriven; + const controller_map_t mParamControllers; + + LLPointer mJointState; + LLCharacter *mCharacter; + + F32 mLastTime; + + static default_controller_map_t sDefaultController; }; default_controller_map_t initDefaultController() { - default_controller_map_t controller; - controller["Mass"] = 0.2f; - controller["Smoothing"] = 2.0f; - controller["Gravity"] = 0.0f; - controller["Damping"] = .05f; - controller["Drag"] = 0.15f; - controller["MaxSpeed"] = 0.1f; - controller["Spring"] = 0.1f; - controller["Gain"] = 10.0f; - return controller; + default_controller_map_t controller; + controller["Mass"] = 0.2f; + controller["Smoothing"] = 2.0f; + controller["Gravity"] = 0.0f; + controller["Damping"] = .05f; + controller["Drag"] = 0.15f; + controller["MaxSpeed"] = 0.1f; + controller["Spring"] = 0.1f; + controller["Gain"] = 10.0f; + return controller; } default_controller_map_t LLPhysicsMotion::sDefaultController = initDefaultController(); BOOL LLPhysicsMotion::initialize() { - if (!mJointState->setJoint(mCharacter->getJoint(mJointName.c_str()))) - return FALSE; - mJointState->setUsage(LLJointState::ROT); - - mParamUser = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamUserName.c_str()); - if (mParamDrivenName != "") - mParamDriven = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDrivenName.c_str()); - if (mParamUser == NULL) - { - llinfos << "Failure reading in [ " << mParamUserName << " ]" << llendl; - return FALSE; - } - - return TRUE; + if (!mJointState->setJoint(mCharacter->getJoint(mJointName.c_str()))) + return FALSE; + mJointState->setUsage(LLJointState::ROT); + + mParamUser = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamUserName.c_str()); + if (mParamDrivenName != "") + mParamDriven = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDrivenName.c_str()); + if (mParamUser == NULL) + { + llinfos << "Failure reading in [ " << mParamUserName << " ]" << llendl; + return FALSE; + } + + return TRUE; } LLPhysicsMotionController::LLPhysicsMotionController(const LLUUID &id) : - LLMotion(id), - mCharacter(NULL) + LLMotion(id), + mCharacter(NULL) { - mName = "breast_motion"; + mName = "breast_motion"; } LLPhysicsMotionController::~LLPhysicsMotionController() { - for (motion_vec_t::iterator iter = mMotions.begin(); - iter != mMotions.end(); - ++iter) - { - delete (*iter); - } + for (motion_vec_t::iterator iter = mMotions.begin(); + iter != mMotions.end(); + ++iter) + { + delete (*iter); + } } BOOL LLPhysicsMotionController::onActivate() { - return TRUE; + return TRUE; } void LLPhysicsMotionController::onDeactivate() @@ -234,465 +234,465 @@ void LLPhysicsMotionController::onDeactivate() LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter *character) { - mCharacter = character; - - mMotions.clear(); - - // Breast Cleavage - { - controller_map_t controller; - controller["Mass"] = "Breast_Physics_Mass"; - controller["Smoothing"] = "Breast_Physics_Smoothing"; - controller["Gravity"] = "Breast_Physics_Gravity"; - controller["Damping"] = "Breast_Physics_InOut_Damping"; - controller["Drag"] = "Breast_Physics_InOut_Drag"; - controller["MaxSpeed"] = "Breast_Physics_InOut_Max_Velocity"; - controller["Spring"] = "Breast_Physics_InOut_Spring"; - controller["Gain"] = "Breast_Physics_InOut_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", - "", - "mChest", - character, - LLVector3(-1,0,0), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Breast Bounce - { - controller_map_t controller; - controller["Mass"] = "Breast_Physics_Mass"; - controller["Smoothing"] = "Breast_Physics_Smoothing"; - controller["Gravity"] = "Breast_Physics_Gravity"; - controller["Damping"] = "Breast_Physics_UpDown_Damping"; - controller["Drag"] = "Breast_Physics_UpDown_Drag"; - controller["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; - controller["Spring"] = "Breast_Physics_UpDown_Spring"; - controller["Gain"] = "Breast_Physics_UpDown_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", - "", - "mChest", - character, - LLVector3(0,0,1), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Butt Bounce - { - controller_map_t controller; - controller["Mass"] = "Butt_Physics_Mass"; - controller["Smoothing"] = "Butt_Physics_Smoothing"; - controller["Gravity"] = "Butt_Physics_Gravity"; - controller["Damping"] = "Butt_Physics_UpDown_Damping"; - controller["Drag"] = "Butt_Physics_UpDown_Drag"; - controller["MaxSpeed"] = "Butt_Physics_UpDown_Max_Velocity"; - controller["Spring"] = "Butt_Physics_UpDown_Spring"; - controller["Gain"] = "Butt_Physics_UpDown_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", - "", - "mPelvis", - character, - LLVector3(0,0,1), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Butt LeftRight - { - controller_map_t controller; - controller["Mass"] = "Butt_Physics_Mass"; - controller["Smoothing"] = "Butt_Physics_Smoothing"; - controller["Gravity"] = "Butt_Physics_Gravity"; - controller["Damping"] = "Butt_Physics_LeftRight_Damping"; - controller["Drag"] = "Butt_Physics_LeftRight_Drag"; - controller["MaxSpeed"] = "Butt_Physics_LeftRight_Max_Velocity"; - controller["Spring"] = "Butt_Physics_LeftRight_Spring"; - controller["Gain"] = "Butt_Physics_LeftRight_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", - "", - "mPelvis", - character, - LLVector3(0,1,0), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Belly Bounce - { - controller_map_t controller; - controller["Mass"] = "Belly_Physics_Mass"; - controller["Smoothing"] = "Belly_Physics_Smoothing"; - controller["Gravity"] = "Belly_Physics_Gravity"; - controller["Damping"] = "Belly_Physics_UpDown_Damping"; - controller["Drag"] = "Belly_Physics_UpDown_Drag"; - controller["MaxSpeed"] = "Belly_Physics_UpDown_Max_Velocity"; - controller["Spring"] = "Belly_Physics_UpDown_Spring"; - controller["Gain"] = "Belly_Physics_UpDown_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", - "", - "mPelvis", - character, - LLVector3(0,0,-1), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - return STATUS_SUCCESS; + mCharacter = character; + + mMotions.clear(); + + // Breast Cleavage + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Smoothing"] = "Breast_Physics_Smoothing"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Drag"] = "Breast_Physics_Drag"; + controller["Damping"] = "Breast_Physics_InOut_Damping"; + controller["MaxSpeed"] = "Breast_Physics_InOut_Max_Velocity"; + controller["Spring"] = "Breast_Physics_InOut_Spring"; + controller["Gain"] = "Breast_Physics_InOut_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", + "", + "mChest", + character, + LLVector3(-1,0,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Breast Bounce + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Smoothing"] = "Breast_Physics_Smoothing"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Drag"] = "Breast_Physics_Drag"; + controller["Damping"] = "Breast_Physics_UpDown_Damping"; + controller["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controller["Spring"] = "Breast_Physics_UpDown_Spring"; + controller["Gain"] = "Breast_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", + "", + "mChest", + character, + LLVector3(0,0,1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Butt Bounce + { + controller_map_t controller; + controller["Mass"] = "Butt_Physics_Mass"; + controller["Smoothing"] = "Butt_Physics_Smoothing"; + controller["Gravity"] = "Butt_Physics_Gravity"; + controller["Drag"] = "Butt_Physics_Drag"; + controller["Damping"] = "Butt_Physics_UpDown_Damping"; + controller["MaxSpeed"] = "Butt_Physics_UpDown_Max_Velocity"; + controller["Spring"] = "Butt_Physics_UpDown_Spring"; + controller["Gain"] = "Butt_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", + "", + "mPelvis", + character, + LLVector3(0,0,1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Butt LeftRight + { + controller_map_t controller; + controller["Mass"] = "Butt_Physics_Mass"; + controller["Smoothing"] = "Butt_Physics_Smoothing"; + controller["Gravity"] = "Butt_Physics_Gravity"; + controller["Drag"] = "Butt_Physics_Drag"; + controller["Damping"] = "Butt_Physics_LeftRight_Damping"; + controller["MaxSpeed"] = "Butt_Physics_LeftRight_Max_Velocity"; + controller["Spring"] = "Butt_Physics_LeftRight_Spring"; + controller["Gain"] = "Butt_Physics_LeftRight_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", + "", + "mPelvis", + character, + LLVector3(0,1,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Belly Bounce + { + controller_map_t controller; + controller["Mass"] = "Belly_Physics_Mass"; + controller["Smoothing"] = "Belly_Physics_Smoothing"; + controller["Gravity"] = "Belly_Physics_Gravity"; + controller["Drag"] = "Belly_Physics_Drag"; + controller["Damping"] = "Belly_Physics_UpDown_Damping"; + controller["MaxSpeed"] = "Belly_Physics_UpDown_Max_Velocity"; + controller["Spring"] = "Belly_Physics_UpDown_Spring"; + controller["Gain"] = "Belly_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", + "", + "mPelvis", + character, + LLVector3(0,0,-1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + return STATUS_SUCCESS; } void LLPhysicsMotionController::addMotion(LLPhysicsMotion *motion) { - addJointState(motion->getJointState()); - mMotions.push_back(motion); + addJointState(motion->getJointState()); + mMotions.push_back(motion); } F32 LLPhysicsMotionController::getMinPixelArea() { - return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION; + return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION; } // Local space means "parameter space". F32 LLPhysicsMotion::toLocal(const LLVector3 &world) { - LLJoint *joint = mJointState->getJoint(); - const LLQuaternion rotation_world = joint->getWorldRotation(); - - LLVector3 dir_world = mMotionDirectionVec * rotation_world; - dir_world.normalize(); - return world * dir_world; + LLJoint *joint = mJointState->getJoint(); + const LLQuaternion rotation_world = joint->getWorldRotation(); + + LLVector3 dir_world = mMotionDirectionVec * rotation_world; + dir_world.normalize(); + return world * dir_world; } F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) { - 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 F32 velocity_local = toLocal(velocity_world); - return velocity_local; + 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 F32 velocity_local = toLocal(velocity_world); + return velocity_local; } F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, - const F32 time_delta) + const F32 time_delta) { - const F32 smoothing = getParamValue("Smoothing"); - const F32 acceleration_local = velocity_local - mVelocityJoint_local; - - const F32 smoothed_acceleration_local = - acceleration_local * 1.0/smoothing + - mAccelerationJoint_local * (smoothing-1.0)/smoothing; - - return smoothed_acceleration_local; + const F32 smoothing = getParamValue("Smoothing"); + const F32 acceleration_local = velocity_local - mVelocityJoint_local; + + const F32 smoothed_acceleration_local = + acceleration_local * 1.0/smoothing + + mAccelerationJoint_local * (smoothing-1.0)/smoothing; + + return smoothed_acceleration_local; } BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) { - // Skip if disabled globally. - if (!gSavedSettings.getBOOL("AvatarPhysics")) - { - return TRUE; - } - - BOOL update_visuals = FALSE; - for (motion_vec_t::iterator iter = mMotions.begin(); - iter != mMotions.end(); - ++iter) - { - LLPhysicsMotion *motion = (*iter); - update_visuals |= motion->onUpdate(time); - } - - if (update_visuals) - mCharacter->updateVisualParams(); - - return TRUE; + // Skip if disabled globally. + if (!gSavedSettings.getBOOL("AvatarPhysics")) + { + return TRUE; + } + + BOOL update_visuals = FALSE; + for (motion_vec_t::iterator iter = mMotions.begin(); + iter != mMotions.end(); + ++iter) + { + LLPhysicsMotion *motion = (*iter); + update_visuals |= motion->onUpdate(time); + } + + if (update_visuals) + mCharacter->updateVisualParams(); + + return TRUE; } // Return TRUE if character has to update visual params. BOOL LLPhysicsMotion::onUpdate(F32 time) { - // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); - - if (!mParamUser) - return FALSE; - - if (!mLastTime) - { - mLastTime = time; - return FALSE; - } - - //////////////////////////////////////////////////////////////////////////////// - // Get all parameters and settings - // - - const F32 time_delta = time - mLastTime; - if (time_delta > 3.0 || time_delta <= 0.01) - { - mLastTime = time; - return FALSE; - } - - // 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; - } - - LLJoint *joint = mJointState->getJoint(); - - const F32 behavior_mass = getParamValue("Mass"); - const F32 behavior_gravity = getParamValue("Gravity"); - const F32 behavior_spring = getParamValue("Spring"); - const F32 behavior_gain = getParamValue("Gain"); - const F32 behavior_damping = getParamValue("Damping"); - const F32 behavior_drag = getParamValue("Drag"); - const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); - - F32 behavior_maxspeed = getParamValue("MaxSpeed"); - if (physics_test) - behavior_maxspeed = 100.0f; - - if (behavior_maxspeed == 0) - return FALSE; - - F32 position_current_local = llclamp(mPosition_local, - 0.0f, - 1.0f); // Normalized [0,1] range - - // 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 = mParamUser->getWeight(); - position_user_local = (position_user_local - mParamUser->getMinWeight()) / (mParamUser->getMaxWeight() - mParamUser->getMinWeight()); - - // - // End parameters and settings - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate velocity and acceleration in parameter space. - // - - const F32 velocity_joint_local = calculateVelocity_local(time_delta); - const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); - - // - // End velocity and acceleration - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate the total force - // - - // Spring force is a restoring force towards the original user-set breast position. - // F = kx - const F32 spring_length = position_current_local - position_user_local; - const F32 force_spring = -spring_length * behavior_spring; - - // Acceleration is the force that comes from the change in velocity of the torso. - // F = ma - const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); - - // 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); - - // Damping is a restoring force that opposes the current velocity. - // F = -kv - const F32 force_damping = -behavior_damping * mVelocity_local; - - // Drag is a force imparted by velocity (intuitively it is similar to wind resistance) - // F = .5kv^2 - const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); - - const F32 force_net = (force_accel + - force_gravity + - force_spring + - force_damping + - force_drag); - - // - // End total force - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate new params - // - - // Calculate the new acceleration based on the net force. - // a = F/m - const F32 acceleration_new_local = force_net / behavior_mass; - F32 velocity_new_local = mVelocity_local + acceleration_new_local; - velocity_new_local = llclamp(velocity_new_local, - -behavior_maxspeed, behavior_maxspeed); - - // Temporary debugging setting to cause all avatars to move, for profiling purposes. - if (physics_test) - { - velocity_new_local = sin(time*4.0); - } - // Calculate the new parameters, or remain unchanged if max speed is 0. - const F32 position_new_local = (behavior_maxspeed != 0) ? - (position_current_local + velocity_new_local*time_delta) : - position_user_local; - - // Zero out the velocity if the param is being pushed beyond its limits. - if (position_new_local < 0 || position_new_local > 1) - { - velocity_new_local = 0; - } - - const F32 position_new_local_clamped = llclamp(position_new_local, - 0.0f, - 1.0f); - - // Set the new param. - // If a specific param has been declared, then set that one. - // Otherwise, assume that the param is a driver param, and - // set the params that it drives. - if (mParamDriven) - { - setParamValue(mParamDriven,position_new_local_clamped); - } - else - { - LLDriverParam *driver_param = dynamic_cast(mParamUser); - llassert_always(driver_param); - if (driver_param) - { - for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); - iter != driver_param->mDriven.end(); - ++iter) - { - LLDrivenEntry &entry = (*iter); - LLViewerVisualParam *driven_param = entry.mParam; - setParamValue(driven_param,position_new_local_clamped); - } - } - } - - // - // 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. - - BOOL update_visuals = FALSE; - - // For non-self, if the avatar is small enough visually, then don't update. - const F32 area_for_max_settings = 0.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); - const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); - - const BOOL is_self = (dynamic_cast(mCharacter) != NULL); - if ((pixel_area > area_for_this_setting) || is_self) - { - const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); - const F32 min_delta = (1.01f-lod_factor)*0.4f; - if (llabs(position_diff_local) > min_delta) - { - update_visuals = TRUE; - mPositionLastUpdate_local = position_new_local; - } - } - - // - // 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; - - /* - // Write out debugging info into a spreadsheet. - if (mFileWrite != NULL && is_self) - { - fprintf(mFileWrite,"%f\t%f\t%f \t\t%f \t\t%f\t%f\t%f\t \t\t%f\t%f\t%f\t%f\t%f \t\t%f\t%f\t%f\n", - position_new_local, - velocity_new_local, - acceleration_new_local, - - time_delta, - - mPosition_world[0], - mPosition_world[1], - mPosition_world[2], - - force_net, - force_spring, - force_accel, - force_damping, - force_drag, - - spring_length, - velocity_joint_local, - acceleration_joint_local - ); - } - */ - - return update_visuals; + // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); + + if (!mParamUser) + return FALSE; + + if (!mLastTime) + { + mLastTime = time; + return FALSE; + } + + //////////////////////////////////////////////////////////////////////////////// + // Get all parameters and settings + // + + const F32 time_delta = time - mLastTime; + if (time_delta > 3.0 || time_delta <= 0.01) + { + mLastTime = time; + return FALSE; + } + + // 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; + } + + LLJoint *joint = mJointState->getJoint(); + + const F32 behavior_mass = getParamValue("Mass"); + const F32 behavior_gravity = getParamValue("Gravity"); + const F32 behavior_spring = getParamValue("Spring"); + const F32 behavior_gain = getParamValue("Gain"); + const F32 behavior_damping = getParamValue("Damping"); + const F32 behavior_drag = getParamValue("Drag"); + const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); + + F32 behavior_maxspeed = getParamValue("MaxSpeed"); + if (physics_test) + behavior_maxspeed = 100.0f; + + if (behavior_maxspeed == 0) + return FALSE; + + F32 position_current_local = llclamp(mPosition_local, + 0.0f, + 1.0f); // Normalized [0,1] range + + // 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 = mParamUser->getWeight(); + position_user_local = (position_user_local - mParamUser->getMinWeight()) / (mParamUser->getMaxWeight() - mParamUser->getMinWeight()); + + // + // End parameters and settings + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate velocity and acceleration in parameter space. + // + + const F32 velocity_joint_local = calculateVelocity_local(time_delta); + const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); + + // + // End velocity and acceleration + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate the total force + // + + // Spring force is a restoring force towards the original user-set breast position. + // F = kx + const F32 spring_length = position_current_local - position_user_local; + const F32 force_spring = -spring_length * behavior_spring; + + // Acceleration is the force that comes from the change in velocity of the torso. + // F = ma + const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); + + // 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); + + // Damping is a restoring force that opposes the current velocity. + // F = -kv + const F32 force_damping = -behavior_damping * mVelocity_local; + + // Drag is a force imparted by velocity (intuitively it is similar to wind resistance) + // F = .5kv^2 + const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); + + const F32 force_net = (force_accel + + force_gravity + + force_spring + + force_damping + + force_drag); + + // + // End total force + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate new params + // + + // Calculate the new acceleration based on the net force. + // a = F/m + const F32 acceleration_new_local = force_net / behavior_mass; + F32 velocity_new_local = mVelocity_local + acceleration_new_local; + velocity_new_local = llclamp(velocity_new_local, + -behavior_maxspeed, behavior_maxspeed); + + // Temporary debugging setting to cause all avatars to move, for profiling purposes. + if (physics_test) + { + velocity_new_local = sin(time*4.0); + } + // Calculate the new parameters, or remain unchanged if max speed is 0. + const F32 position_new_local = (behavior_maxspeed != 0) ? + (position_current_local + velocity_new_local*time_delta) : + position_user_local; + + // Zero out the velocity if the param is being pushed beyond its limits. + if (position_new_local < 0 || position_new_local > 1) + { + velocity_new_local = 0; + } + + const F32 position_new_local_clamped = llclamp(position_new_local, + 0.0f, + 1.0f); + + // Set the new param. + // If a specific param has been declared, then set that one. + // Otherwise, assume that the param is a driver param, and + // set the params that it drives. + if (mParamDriven) + { + setParamValue(mParamDriven,position_new_local_clamped); + } + else + { + LLDriverParam *driver_param = dynamic_cast(mParamUser); + llassert_always(driver_param); + if (driver_param) + { + for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); + iter != driver_param->mDriven.end(); + ++iter) + { + LLDrivenEntry &entry = (*iter); + LLViewerVisualParam *driven_param = entry.mParam; + setParamValue(driven_param,position_new_local_clamped); + } + } + } + + // + // 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. + + BOOL update_visuals = FALSE; + + // For non-self, if the avatar is small enough visually, then don't update. + const F32 area_for_max_settings = 0.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); + const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); + + const BOOL is_self = (dynamic_cast(mCharacter) != NULL); + if ((pixel_area > area_for_this_setting) || is_self) + { + const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); + const F32 min_delta = (1.01f-lod_factor)*0.4f; + if (llabs(position_diff_local) > min_delta) + { + update_visuals = TRUE; + mPositionLastUpdate_local = position_new_local; + } + } + + // + // 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; + + /* + // Write out debugging info into a spreadsheet. + if (mFileWrite != NULL && is_self) + { + fprintf(mFileWrite,"%f\t%f\t%f \t\t%f \t\t%f\t%f\t%f\t \t\t%f\t%f\t%f\t%f\t%f \t\t%f\t%f\t%f\n", + position_new_local, + velocity_new_local, + acceleration_new_local, + + time_delta, + + mPosition_world[0], + mPosition_world[1], + mPosition_world[2], + + force_net, + force_spring, + force_accel, + force_damping, + force_drag, + + spring_length, + velocity_joint_local, + acceleration_joint_local + ); + } + */ + + return update_visuals; } // Range of new_value_local is assumed to be [0 , 1] normalized. void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param, - F32 new_value_normalized) + F32 new_value_normalized) { - const F32 value_min_local = param->getMinWeight(); - const F32 value_max_local = param->getMaxWeight(); + const F32 value_min_local = param->getMinWeight(); + const F32 value_max_local = param->getMaxWeight(); - const F32 new_value_local = value_min_local + (value_max_local-value_min_local) * new_value_normalized; + const F32 new_value_local = value_min_local + (value_max_local-value_min_local) * new_value_normalized; - mCharacter->setVisualParamWeight(param, - new_value_local, - FALSE); + mCharacter->setVisualParamWeight(param, + new_value_local, + FALSE); } -- cgit v1.2.3 From a47ea6c619d1b689478f9e41c87cb89c010273de Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 13:56:55 -0400 Subject: Added breast sway (left-right). --- indra/newview/llphysicsmotion.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 53809b4d19..43044e20ea 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -287,6 +287,31 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter } addMotion(motion); } + + // Breast Sway + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Smoothing"] = "Breast_Physics_Smoothing"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Drag"] = "Breast_Physics_Drag"; + controller["Damping"] = "Breast_Physics_LeftRight_Damping"; + controller["MaxSpeed"] = "Breast_Physics_LeftRight_Max_Velocity"; + controller["Spring"] = "Breast_Physics_LeftRight_Spring"; + controller["Gain"] = "Breast_Physics_LeftRight_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_LeftRight_Controller", + "", + "mChest", + character, + LLVector3(0,-1,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } // Butt Bounce { -- cgit v1.2.3 From e8f2380489b9ce58f7a7bb047231256ae7833309 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 13:59:19 -0400 Subject: Changed Max Velocity param name to Max Effect --- indra/newview/llphysicsmotion.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 43044e20ea..7b5ae0199a 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -246,7 +246,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Gravity"] = "Breast_Physics_Gravity"; controller["Drag"] = "Breast_Physics_Drag"; controller["Damping"] = "Breast_Physics_InOut_Damping"; - controller["MaxSpeed"] = "Breast_Physics_InOut_Max_Velocity"; + controller["MaxSpeed"] = "Breast_Physics_InOut_Max_Effect"; controller["Spring"] = "Breast_Physics_InOut_Spring"; controller["Gain"] = "Breast_Physics_InOut_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", @@ -271,7 +271,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Gravity"] = "Breast_Physics_Gravity"; controller["Drag"] = "Breast_Physics_Drag"; controller["Damping"] = "Breast_Physics_UpDown_Damping"; - controller["MaxSpeed"] = "Breast_Physics_UpDown_Max_Velocity"; + controller["MaxSpeed"] = "Breast_Physics_UpDown_Max_Effect"; controller["Spring"] = "Breast_Physics_UpDown_Spring"; controller["Gain"] = "Breast_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", @@ -296,7 +296,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Gravity"] = "Breast_Physics_Gravity"; controller["Drag"] = "Breast_Physics_Drag"; controller["Damping"] = "Breast_Physics_LeftRight_Damping"; - controller["MaxSpeed"] = "Breast_Physics_LeftRight_Max_Velocity"; + controller["MaxSpeed"] = "Breast_Physics_LeftRight_Max_Effect"; controller["Spring"] = "Breast_Physics_LeftRight_Spring"; controller["Gain"] = "Breast_Physics_LeftRight_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_LeftRight_Controller", @@ -321,7 +321,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Gravity"] = "Butt_Physics_Gravity"; controller["Drag"] = "Butt_Physics_Drag"; controller["Damping"] = "Butt_Physics_UpDown_Damping"; - controller["MaxSpeed"] = "Butt_Physics_UpDown_Max_Velocity"; + controller["MaxSpeed"] = "Butt_Physics_UpDown_Max_Effect"; controller["Spring"] = "Butt_Physics_UpDown_Spring"; controller["Gain"] = "Butt_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", @@ -346,7 +346,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Gravity"] = "Butt_Physics_Gravity"; controller["Drag"] = "Butt_Physics_Drag"; controller["Damping"] = "Butt_Physics_LeftRight_Damping"; - controller["MaxSpeed"] = "Butt_Physics_LeftRight_Max_Velocity"; + controller["MaxSpeed"] = "Butt_Physics_LeftRight_Max_Effect"; controller["Spring"] = "Butt_Physics_LeftRight_Spring"; controller["Gain"] = "Butt_Physics_LeftRight_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", @@ -371,7 +371,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Gravity"] = "Belly_Physics_Gravity"; controller["Drag"] = "Belly_Physics_Drag"; controller["Damping"] = "Belly_Physics_UpDown_Damping"; - controller["MaxSpeed"] = "Belly_Physics_UpDown_Max_Velocity"; + controller["MaxSpeed"] = "Belly_Physics_UpDown_Max_Effect"; controller["Spring"] = "Belly_Physics_UpDown_Spring"; controller["Gain"] = "Belly_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", -- cgit v1.2.3 From f433ad353131cc1df581be11a9ff6184767a0ed6 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 17:25:17 -0400 Subject: Changed _driven params to cross wearables; major fix so they wouldn't keep getting reset to default values from wearable. Took out smoothing param. Redefined maxeffect param to affect range of motion. --- indra/newview/llphysicsmotion.cpp | 73 +++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 30 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 7b5ae0199a..57ba76cf6d 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -176,11 +176,10 @@ default_controller_map_t initDefaultController() { default_controller_map_t controller; controller["Mass"] = 0.2f; - controller["Smoothing"] = 2.0f; controller["Gravity"] = 0.0f; controller["Damping"] = .05f; controller["Drag"] = 0.15f; - controller["MaxSpeed"] = 0.1f; + controller["MaxEffect"] = 0.1f; controller["Spring"] = 0.1f; controller["Gain"] = 10.0f; return controller; @@ -242,11 +241,10 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter { controller_map_t controller; controller["Mass"] = "Breast_Physics_Mass"; - controller["Smoothing"] = "Breast_Physics_Smoothing"; controller["Gravity"] = "Breast_Physics_Gravity"; controller["Drag"] = "Breast_Physics_Drag"; controller["Damping"] = "Breast_Physics_InOut_Damping"; - controller["MaxSpeed"] = "Breast_Physics_InOut_Max_Effect"; + controller["MaxEffect"] = "Breast_Physics_InOut_Max_Effect"; controller["Spring"] = "Breast_Physics_InOut_Spring"; controller["Gain"] = "Breast_Physics_InOut_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", @@ -267,11 +265,10 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter { controller_map_t controller; controller["Mass"] = "Breast_Physics_Mass"; - controller["Smoothing"] = "Breast_Physics_Smoothing"; controller["Gravity"] = "Breast_Physics_Gravity"; controller["Drag"] = "Breast_Physics_Drag"; controller["Damping"] = "Breast_Physics_UpDown_Damping"; - controller["MaxSpeed"] = "Breast_Physics_UpDown_Max_Effect"; + controller["MaxEffect"] = "Breast_Physics_UpDown_Max_Effect"; controller["Spring"] = "Breast_Physics_UpDown_Spring"; controller["Gain"] = "Breast_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", @@ -292,11 +289,10 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter { controller_map_t controller; controller["Mass"] = "Breast_Physics_Mass"; - controller["Smoothing"] = "Breast_Physics_Smoothing"; controller["Gravity"] = "Breast_Physics_Gravity"; controller["Drag"] = "Breast_Physics_Drag"; controller["Damping"] = "Breast_Physics_LeftRight_Damping"; - controller["MaxSpeed"] = "Breast_Physics_LeftRight_Max_Effect"; + controller["MaxEffect"] = "Breast_Physics_LeftRight_Max_Effect"; controller["Spring"] = "Breast_Physics_LeftRight_Spring"; controller["Gain"] = "Breast_Physics_LeftRight_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_LeftRight_Controller", @@ -312,23 +308,21 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter } addMotion(motion); } - // Butt Bounce { controller_map_t controller; controller["Mass"] = "Butt_Physics_Mass"; - controller["Smoothing"] = "Butt_Physics_Smoothing"; controller["Gravity"] = "Butt_Physics_Gravity"; controller["Drag"] = "Butt_Physics_Drag"; controller["Damping"] = "Butt_Physics_UpDown_Damping"; - controller["MaxSpeed"] = "Butt_Physics_UpDown_Max_Effect"; + controller["MaxEffect"] = "Butt_Physics_UpDown_Max_Effect"; controller["Spring"] = "Butt_Physics_UpDown_Spring"; controller["Gain"] = "Butt_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", "", "mPelvis", character, - LLVector3(0,0,1), + LLVector3(0,0,-1), controller); if (!motion->initialize()) { @@ -342,11 +336,10 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter { controller_map_t controller; controller["Mass"] = "Butt_Physics_Mass"; - controller["Smoothing"] = "Butt_Physics_Smoothing"; controller["Gravity"] = "Butt_Physics_Gravity"; controller["Drag"] = "Butt_Physics_Drag"; controller["Damping"] = "Butt_Physics_LeftRight_Damping"; - controller["MaxSpeed"] = "Butt_Physics_LeftRight_Max_Effect"; + controller["MaxEffect"] = "Butt_Physics_LeftRight_Max_Effect"; controller["Spring"] = "Butt_Physics_LeftRight_Spring"; controller["Gain"] = "Butt_Physics_LeftRight_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", @@ -367,11 +360,10 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter { controller_map_t controller; controller["Mass"] = "Belly_Physics_Mass"; - controller["Smoothing"] = "Belly_Physics_Smoothing"; controller["Gravity"] = "Belly_Physics_Gravity"; controller["Drag"] = "Belly_Physics_Drag"; controller["Damping"] = "Belly_Physics_UpDown_Damping"; - controller["MaxSpeed"] = "Belly_Physics_UpDown_Max_Effect"; + controller["MaxEffect"] = "Belly_Physics_UpDown_Max_Effect"; controller["Spring"] = "Belly_Physics_UpDown_Spring"; controller["Gain"] = "Belly_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", @@ -427,7 +419,8 @@ F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, const F32 time_delta) { - const F32 smoothing = getParamValue("Smoothing"); +// const F32 smoothing = getParamValue("Smoothing"); + static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary const F32 acceleration_local = velocity_local - mVelocityJoint_local; const F32 smoothed_acceleration_local = @@ -504,16 +497,17 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) const F32 behavior_drag = getParamValue("Drag"); const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); - F32 behavior_maxspeed = getParamValue("MaxSpeed"); + F32 behavior_maxeffect = getParamValue("MaxEffect"); if (physics_test) - behavior_maxspeed = 100.0f; - - if (behavior_maxspeed == 0) - return FALSE; + behavior_maxeffect = 1.0f; + // Maximum effect is [0,1] range. + const F32 min_val = 0.5f-behavior_maxeffect/2.0; + const F32 max_val = 0.5f+behavior_maxeffect/2.0; + // mPositon_local should be in normalized 0,1 range already. Just making sure... F32 position_current_local = llclamp(mPosition_local, 0.0f, - 1.0f); // Normalized [0,1] range + 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, @@ -522,6 +516,13 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) F32 position_user_local = mParamUser->getWeight(); position_user_local = (position_user_local - mParamUser->getMinWeight()) / (mParamUser->getMaxWeight() - mParamUser->getMinWeight()); + // 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; + } + // // End parameters and settings //////////////////////////////////////////////////////////////////////////////// @@ -583,9 +584,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; + const F32 max_acceleration = 10.0f; // magic number, used to be customizable. F32 velocity_new_local = mVelocity_local + acceleration_new_local; velocity_new_local = llclamp(velocity_new_local, - -behavior_maxspeed, behavior_maxspeed); + -max_acceleration, max_acceleration); // Temporary debugging setting to cause all avatars to move, for profiling purposes. if (physics_test) @@ -593,19 +595,20 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) velocity_new_local = sin(time*4.0); } // Calculate the new parameters, or remain unchanged if max speed is 0. - const F32 position_new_local = (behavior_maxspeed != 0) ? - (position_current_local + velocity_new_local*time_delta) : - position_user_local; + F32 position_new_local = position_current_local + velocity_new_local*time_delta; + if (behavior_maxeffect == 0) + position_new_local = position_user_local; // Zero out the velocity if the param is being pushed beyond its limits. - if (position_new_local < 0 || position_new_local > 1) + if ((position_new_local < min_val && velocity_new_local < 0) || + (position_new_local > max_val && velocity_new_local > 0)) { velocity_new_local = 0; } const F32 position_new_local_clamped = llclamp(position_new_local, - 0.0f, - 1.0f); + min_val, + max_val); // Set the new param. // If a specific param has been declared, then set that one. @@ -621,6 +624,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) llassert_always(driver_param); if (driver_param) { + // If this is one of our "hidden" driver params, then make sure it's + // the default value. + if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && + (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT) && + (driver_param->getVisualParamWeight() != 0)) + { + mCharacter->setVisualParamWeight(driver_param, + 0, + FALSE); + } for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); iter != driver_param->mDriven.end(); ++iter) -- cgit v1.2.3 From 9c3b0ddeaf39bfbfe1bdfbbb614c8abe0b7c03a9 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 17:27:11 -0400 Subject: Fix for compile error. --- indra/newview/llphysicsmotion.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 57ba76cf6d..15797e5ab7 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -627,8 +627,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) // If this is one of our "hidden" driver params, then make sure it's // the default value. if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && - (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT) && - (driver_param->getVisualParamWeight() != 0)) + (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) { mCharacter->setVisualParamWeight(driver_param, 0, -- cgit v1.2.3 From 05e23c39f731ed50663d3dd3f8fa442d95161241 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 17:46:56 -0400 Subject: Minor fixes. --- indra/newview/llphysicsmotion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 15797e5ab7..8f747af824 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -420,7 +420,7 @@ F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, const F32 time_delta) { // const F32 smoothing = getParamValue("Smoothing"); - static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary + static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary const F32 acceleration_local = velocity_local - mVelocityJoint_local; const F32 smoothed_acceleration_local = @@ -584,7 +584,7 @@ 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; - const F32 max_acceleration = 10.0f; // magic number, used to be customizable. + static const F32 max_acceleration = 10.0f; // magic number, used to be customizable. F32 velocity_new_local = mVelocity_local + acceleration_new_local; velocity_new_local = llclamp(velocity_new_local, -max_acceleration, max_acceleration); -- cgit v1.2.3 From 01c236df47c2bc48af26e96d2a7bde8d32cf3514 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 18:09:38 -0400 Subject: Fix for butt gravity direction. Added more displacement range for butt leftright. --- indra/newview/llphysicsmotion.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 8f747af824..eab66749d0 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -346,7 +346,7 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter "", "mPelvis", character, - LLVector3(0,1,0), + LLVector3(0,-1,0), controller); if (!motion->initialize()) { @@ -420,7 +420,7 @@ F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, const F32 time_delta) { // const F32 smoothing = getParamValue("Smoothing"); - static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary + static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary const F32 acceleration_local = velocity_local - mVelocityJoint_local; const F32 smoothed_acceleration_local = @@ -624,15 +624,15 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) llassert_always(driver_param); if (driver_param) { - // If this is one of our "hidden" driver params, then make sure it's - // the default value. - if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && - (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) - { - mCharacter->setVisualParamWeight(driver_param, - 0, - FALSE); - } + // If this is one of our "hidden" driver params, then make sure it's + // the default value. + if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && + (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) + { + mCharacter->setVisualParamWeight(driver_param, + 0, + FALSE); + } for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); iter != driver_param->mDriven.end(); ++iter) -- cgit v1.2.3 From 62ebe50a561694d2072dcf4db27119303c686bb8 Mon Sep 17 00:00:00 2001 From: Seraph Linden Date: Sun, 3 Apr 2011 21:16:34 -0400 Subject: Added duplicate morph to handle breast bounce/clap. Took out unused params in llphysicsmotion.cpp. --- indra/newview/llphysicsmotion.cpp | 96 +++++++++++++-------------------------- 1 file changed, 31 insertions(+), 65 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index eab66749d0..acf8973f03 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -72,17 +72,7 @@ class LLPhysicsMotion { public: /* - param_user_name: The param (if any) that the user sees and controls. This is what - the particular property would look like without physics. For example, it may be - the breast gravity. This param's value should will not be altered, and is only - used as a reference point for the rest position of the body party. This is usually - a driver param and the param(s) that physics is altering are the driven params. - - param_driven_name: The param whose value is actually set by the physics. If you - leave this blank (which should suffice normally), the physics will assume that - param_user_name is a driver param and will set the params that the driver is - in charge of (i.e. the "driven" params). - + param_driver_name: The param that controls the params that are being affected by the physics. joint_name: The joint that the body part is attached to. The joint is used to determine the orientation (rotation) of the body part. @@ -95,19 +85,15 @@ public: controllers: The various settings (e.g. spring force, mass) that determine how the body part behaves. */ - LLPhysicsMotion(const std::string ¶m_user_name, - const std::string ¶m_driven_name, + LLPhysicsMotion(const std::string ¶m_driver_name, const std::string &joint_name, LLCharacter *character, const LLVector3 &motion_direction_vec, const controller_map_t &controllers) : - mParamUserName(param_user_name), - mParamDrivenName(param_driven_name), + mParamDriverName(param_driver_name), mJointName(joint_name), mMotionDirectionVec(motion_direction_vec), - mParamUser(NULL), - mParamDriven(NULL), - + mParamDriver(NULL), mParamControllers(controllers), mCharacter(character), mLastTime(0), @@ -147,8 +133,8 @@ protected: F32 calculateAcceleration_local(F32 velocity_local, const F32 time_delta); private: - const std::string mParamDrivenName; - const std::string mParamUserName; + const std::string mParamDriverName; + const std::string mParamControllerName; const LLVector3 mMotionDirectionVec; const std::string mJointName; @@ -160,8 +146,7 @@ private: F32 mPositionLastUpdate_local; LLVector3 mPosition_world; - LLViewerVisualParam *mParamUser; - LLViewerVisualParam *mParamDriven; + LLViewerVisualParam *mParamDriver; const controller_map_t mParamControllers; LLPointer mJointState; @@ -193,12 +178,10 @@ BOOL LLPhysicsMotion::initialize() return FALSE; mJointState->setUsage(LLJointState::ROT); - mParamUser = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamUserName.c_str()); - if (mParamDrivenName != "") - mParamDriven = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDrivenName.c_str()); - if (mParamUser == NULL) + mParamDriver = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDriverName.c_str()); + if (mParamDriver == NULL) { - llinfos << "Failure reading in [ " << mParamUserName << " ]" << llendl; + llinfos << "Failure reading in [ " << mParamDriverName << " ]" << llendl; return FALSE; } @@ -248,7 +231,6 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Spring"] = "Breast_Physics_InOut_Spring"; controller["Gain"] = "Breast_Physics_InOut_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", - "", "mChest", character, LLVector3(-1,0,0), @@ -272,7 +254,6 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Spring"] = "Breast_Physics_UpDown_Spring"; controller["Gain"] = "Breast_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", - "", "mChest", character, LLVector3(0,0,1), @@ -296,7 +277,6 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Spring"] = "Breast_Physics_LeftRight_Spring"; controller["Gain"] = "Breast_Physics_LeftRight_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_LeftRight_Controller", - "", "mChest", character, LLVector3(0,-1,0), @@ -319,7 +299,6 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Spring"] = "Butt_Physics_UpDown_Spring"; controller["Gain"] = "Butt_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", - "", "mPelvis", character, LLVector3(0,0,-1), @@ -343,7 +322,6 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Spring"] = "Butt_Physics_LeftRight_Spring"; controller["Gain"] = "Butt_Physics_LeftRight_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", - "", "mPelvis", character, LLVector3(0,-1,0), @@ -367,7 +345,6 @@ LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter controller["Spring"] = "Belly_Physics_UpDown_Spring"; controller["Gain"] = "Belly_Physics_UpDown_Gain"; LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", - "", "mPelvis", character, LLVector3(0,0,-1), @@ -459,7 +436,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) { // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); - if (!mParamUser) + if (!mParamDriver) return FALSE; if (!mLastTime) @@ -513,8 +490,8 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) // 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 = mParamUser->getWeight(); - position_user_local = (position_user_local - mParamUser->getMinWeight()) / (mParamUser->getMaxWeight() - mParamUser->getMinWeight()); + F32 position_user_local = mParamDriver->getWeight(); + position_user_local = (position_user_local - mParamDriver->getMinWeight()) / (mParamDriver->getMaxWeight() - mParamDriver->getMinWeight()); // 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. @@ -610,37 +587,26 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) min_val, max_val); - // Set the new param. - // If a specific param has been declared, then set that one. - // Otherwise, assume that the param is a driver param, and - // set the params that it drives. - if (mParamDriven) + LLDriverParam *driver_param = dynamic_cast(mParamDriver); + llassert_always(driver_param); + if (driver_param) { - setParamValue(mParamDriven,position_new_local_clamped); - } - else - { - LLDriverParam *driver_param = dynamic_cast(mParamUser); - llassert_always(driver_param); - if (driver_param) + // If this is one of our "hidden" driver params, then make sure it's + // the default value. + if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && + (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) + { + mCharacter->setVisualParamWeight(driver_param, + 0, + FALSE); + } + for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); + iter != driver_param->mDriven.end(); + ++iter) { - // If this is one of our "hidden" driver params, then make sure it's - // the default value. - if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && - (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) - { - mCharacter->setVisualParamWeight(driver_param, - 0, - FALSE); - } - for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); - iter != driver_param->mDriven.end(); - ++iter) - { - LLDrivenEntry &entry = (*iter); - LLViewerVisualParam *driven_param = entry.mParam; - setParamValue(driven_param,position_new_local_clamped); - } + LLDrivenEntry &entry = (*iter); + LLViewerVisualParam *driven_param = entry.mParam; + setParamValue(driven_param,position_new_local_clamped); } } -- cgit v1.2.3 From a1a5a793a70f62c977e97b7433840fcb70f47c03 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 6 Apr 2011 08:13:44 -0400 Subject: fix line endings (one missing, two files of DOS) --- indra/newview/llphysicsmotion.cpp | 1402 ++++++++++++++++++------------------- 1 file changed, 701 insertions(+), 701 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index acf8973f03..cb7a55320a 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -1,701 +1,701 @@ -/** - * @file llphysicsmotion.cpp - * @brief Implementation of LLPhysicsMotion class. - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" - -#include "m3math.h" -#include "v3dmath.h" - -#include "llphysicsmotion.h" -#include "llcharacter.h" -#include "llviewercontrol.h" -#include "llviewervisualparam.h" -#include "llvoavatarself.h" - -typedef std::map controller_map_t; -typedef std::map default_controller_map_t; - -#define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 0.f; - -inline F64 llsgn(const F64 a) -{ - if (a >= 0) - return 1; - return -1; -} - -/* - At a high level, this works by setting temporary parameters that are not stored - in the avatar's list of params, and are not conveyed to other users. We accomplish - this by creating some new temporary driven params inside avatar_lad that are then driven - by the actual params that the user sees and sets. For example, in the old system, - the user sets a param called breast bouyancy, which controls the Z value of the breasts. - In our new system, the user still sets the breast bouyancy, but that param is redefined - as a driver param so that affects a new temporary driven param that the bounce is applied - to. -*/ - -class LLPhysicsMotion -{ -public: - /* - param_driver_name: The param that controls the params that are being affected by the physics. - joint_name: The joint that the body part is attached to. The joint is - used to determine the orientation (rotation) of the body part. - - character: The avatar that this physics affects. - - motion_direction_vec: The direction (in world coordinates) that determines the - motion. For example, (0,0,1) is up-down, and means that up-down motion is what - determines how this joint moves. - - controllers: The various settings (e.g. spring force, mass) that determine how - the body part behaves. - */ - LLPhysicsMotion(const std::string ¶m_driver_name, - const std::string &joint_name, - LLCharacter *character, - const LLVector3 &motion_direction_vec, - const controller_map_t &controllers) : - mParamDriverName(param_driver_name), - mJointName(joint_name), - mMotionDirectionVec(motion_direction_vec), - mParamDriver(NULL), - mParamControllers(controllers), - mCharacter(character), - mLastTime(0), - mPosition_local(0), - mVelocityJoint_local(0), - mPositionLastUpdate_local(0) - { - mJointState = new LLJointState; - } - - BOOL initialize(); - - ~LLPhysicsMotion() {} - - BOOL onUpdate(F32 time); - - LLPointer getJointState() - { - return mJointState; - } -protected: - F32 getParamValue(const std::string& controller_key) - { - const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); - if (entry == mParamControllers.end()) - { - return sDefaultController[controller_key]; - } - const std::string& param_name = (*entry).second.c_str(); - return mCharacter->getVisualParamWeight(param_name.c_str()); - } - void setParamValue(LLViewerVisualParam *param, - const F32 new_value_local); - - F32 toLocal(const LLVector3 &world); - F32 calculateVelocity_local(const F32 time_delta); - F32 calculateAcceleration_local(F32 velocity_local, - const F32 time_delta); -private: - const std::string mParamDriverName; - const std::string mParamControllerName; - const LLVector3 mMotionDirectionVec; - const std::string mJointName; - - F32 mPosition_local; - F32 mVelocityJoint_local; // How fast the joint is moving - F32 mAccelerationJoint_local; // Acceleration on the joint - - F32 mVelocity_local; // How fast the param is moving - F32 mPositionLastUpdate_local; - LLVector3 mPosition_world; - - LLViewerVisualParam *mParamDriver; - const controller_map_t mParamControllers; - - LLPointer mJointState; - LLCharacter *mCharacter; - - F32 mLastTime; - - static default_controller_map_t sDefaultController; -}; - -default_controller_map_t initDefaultController() -{ - default_controller_map_t controller; - controller["Mass"] = 0.2f; - controller["Gravity"] = 0.0f; - controller["Damping"] = .05f; - controller["Drag"] = 0.15f; - controller["MaxEffect"] = 0.1f; - controller["Spring"] = 0.1f; - controller["Gain"] = 10.0f; - return controller; -} - -default_controller_map_t LLPhysicsMotion::sDefaultController = initDefaultController(); - -BOOL LLPhysicsMotion::initialize() -{ - if (!mJointState->setJoint(mCharacter->getJoint(mJointName.c_str()))) - return FALSE; - mJointState->setUsage(LLJointState::ROT); - - mParamDriver = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDriverName.c_str()); - if (mParamDriver == NULL) - { - llinfos << "Failure reading in [ " << mParamDriverName << " ]" << llendl; - return FALSE; - } - - return TRUE; -} - -LLPhysicsMotionController::LLPhysicsMotionController(const LLUUID &id) : - LLMotion(id), - mCharacter(NULL) -{ - mName = "breast_motion"; -} - -LLPhysicsMotionController::~LLPhysicsMotionController() -{ - for (motion_vec_t::iterator iter = mMotions.begin(); - iter != mMotions.end(); - ++iter) - { - delete (*iter); - } -} - -BOOL LLPhysicsMotionController::onActivate() -{ - return TRUE; -} - -void LLPhysicsMotionController::onDeactivate() -{ -} - -LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter *character) -{ - mCharacter = character; - - mMotions.clear(); - - // Breast Cleavage - { - controller_map_t controller; - controller["Mass"] = "Breast_Physics_Mass"; - controller["Gravity"] = "Breast_Physics_Gravity"; - controller["Drag"] = "Breast_Physics_Drag"; - controller["Damping"] = "Breast_Physics_InOut_Damping"; - controller["MaxEffect"] = "Breast_Physics_InOut_Max_Effect"; - controller["Spring"] = "Breast_Physics_InOut_Spring"; - controller["Gain"] = "Breast_Physics_InOut_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", - "mChest", - character, - LLVector3(-1,0,0), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Breast Bounce - { - controller_map_t controller; - controller["Mass"] = "Breast_Physics_Mass"; - controller["Gravity"] = "Breast_Physics_Gravity"; - controller["Drag"] = "Breast_Physics_Drag"; - controller["Damping"] = "Breast_Physics_UpDown_Damping"; - controller["MaxEffect"] = "Breast_Physics_UpDown_Max_Effect"; - controller["Spring"] = "Breast_Physics_UpDown_Spring"; - controller["Gain"] = "Breast_Physics_UpDown_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", - "mChest", - character, - LLVector3(0,0,1), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Breast Sway - { - controller_map_t controller; - controller["Mass"] = "Breast_Physics_Mass"; - controller["Gravity"] = "Breast_Physics_Gravity"; - controller["Drag"] = "Breast_Physics_Drag"; - controller["Damping"] = "Breast_Physics_LeftRight_Damping"; - controller["MaxEffect"] = "Breast_Physics_LeftRight_Max_Effect"; - controller["Spring"] = "Breast_Physics_LeftRight_Spring"; - controller["Gain"] = "Breast_Physics_LeftRight_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_LeftRight_Controller", - "mChest", - character, - LLVector3(0,-1,0), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - // Butt Bounce - { - controller_map_t controller; - controller["Mass"] = "Butt_Physics_Mass"; - controller["Gravity"] = "Butt_Physics_Gravity"; - controller["Drag"] = "Butt_Physics_Drag"; - controller["Damping"] = "Butt_Physics_UpDown_Damping"; - controller["MaxEffect"] = "Butt_Physics_UpDown_Max_Effect"; - controller["Spring"] = "Butt_Physics_UpDown_Spring"; - controller["Gain"] = "Butt_Physics_UpDown_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", - "mPelvis", - character, - LLVector3(0,0,-1), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Butt LeftRight - { - controller_map_t controller; - controller["Mass"] = "Butt_Physics_Mass"; - controller["Gravity"] = "Butt_Physics_Gravity"; - controller["Drag"] = "Butt_Physics_Drag"; - controller["Damping"] = "Butt_Physics_LeftRight_Damping"; - controller["MaxEffect"] = "Butt_Physics_LeftRight_Max_Effect"; - controller["Spring"] = "Butt_Physics_LeftRight_Spring"; - controller["Gain"] = "Butt_Physics_LeftRight_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", - "mPelvis", - character, - LLVector3(0,-1,0), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - // Belly Bounce - { - controller_map_t controller; - controller["Mass"] = "Belly_Physics_Mass"; - controller["Gravity"] = "Belly_Physics_Gravity"; - controller["Drag"] = "Belly_Physics_Drag"; - controller["Damping"] = "Belly_Physics_UpDown_Damping"; - controller["MaxEffect"] = "Belly_Physics_UpDown_Max_Effect"; - controller["Spring"] = "Belly_Physics_UpDown_Spring"; - controller["Gain"] = "Belly_Physics_UpDown_Gain"; - LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", - "mPelvis", - character, - LLVector3(0,0,-1), - controller); - if (!motion->initialize()) - { - llassert_always(FALSE); - return STATUS_FAILURE; - } - addMotion(motion); - } - - return STATUS_SUCCESS; -} - -void LLPhysicsMotionController::addMotion(LLPhysicsMotion *motion) -{ - addJointState(motion->getJointState()); - mMotions.push_back(motion); -} - -F32 LLPhysicsMotionController::getMinPixelArea() -{ - return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION; -} - -// Local space means "parameter space". -F32 LLPhysicsMotion::toLocal(const LLVector3 &world) -{ - LLJoint *joint = mJointState->getJoint(); - const LLQuaternion rotation_world = joint->getWorldRotation(); - - LLVector3 dir_world = mMotionDirectionVec * rotation_world; - dir_world.normalize(); - return world * dir_world; -} - -F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) -{ - 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 F32 velocity_local = toLocal(velocity_world); - return velocity_local; -} - -F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, - const F32 time_delta) -{ -// const F32 smoothing = getParamValue("Smoothing"); - static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary - const F32 acceleration_local = velocity_local - mVelocityJoint_local; - - const F32 smoothed_acceleration_local = - acceleration_local * 1.0/smoothing + - mAccelerationJoint_local * (smoothing-1.0)/smoothing; - - return smoothed_acceleration_local; -} - -BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) -{ - // Skip if disabled globally. - if (!gSavedSettings.getBOOL("AvatarPhysics")) - { - return TRUE; - } - - BOOL update_visuals = FALSE; - for (motion_vec_t::iterator iter = mMotions.begin(); - iter != mMotions.end(); - ++iter) - { - LLPhysicsMotion *motion = (*iter); - update_visuals |= motion->onUpdate(time); - } - - if (update_visuals) - mCharacter->updateVisualParams(); - - return TRUE; -} - - -// Return TRUE if character has to update visual params. -BOOL LLPhysicsMotion::onUpdate(F32 time) -{ - // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); - - if (!mParamDriver) - return FALSE; - - if (!mLastTime) - { - mLastTime = time; - return FALSE; - } - - //////////////////////////////////////////////////////////////////////////////// - // Get all parameters and settings - // - - const F32 time_delta = time - mLastTime; - if (time_delta > 3.0 || time_delta <= 0.01) - { - mLastTime = time; - return FALSE; - } - - // 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; - } - - LLJoint *joint = mJointState->getJoint(); - - const F32 behavior_mass = getParamValue("Mass"); - const F32 behavior_gravity = getParamValue("Gravity"); - const F32 behavior_spring = getParamValue("Spring"); - const F32 behavior_gain = getParamValue("Gain"); - const F32 behavior_damping = getParamValue("Damping"); - const F32 behavior_drag = getParamValue("Drag"); - const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); - - F32 behavior_maxeffect = getParamValue("MaxEffect"); - if (physics_test) - behavior_maxeffect = 1.0f; - // Maximum effect is [0,1] range. - const F32 min_val = 0.5f-behavior_maxeffect/2.0; - const F32 max_val = 0.5f+behavior_maxeffect/2.0; - - // 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()); - - // 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; - } - - // - // End parameters and settings - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate velocity and acceleration in parameter space. - // - - const F32 velocity_joint_local = calculateVelocity_local(time_delta); - const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); - - // - // End velocity and acceleration - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate the total force - // - - // Spring force is a restoring force towards the original user-set breast position. - // F = kx - const F32 spring_length = position_current_local - position_user_local; - const F32 force_spring = -spring_length * behavior_spring; - - // Acceleration is the force that comes from the change in velocity of the torso. - // F = ma - const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); - - // 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); - - // Damping is a restoring force that opposes the current velocity. - // F = -kv - const F32 force_damping = -behavior_damping * mVelocity_local; - - // Drag is a force imparted by velocity (intuitively it is similar to wind resistance) - // F = .5kv^2 - const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); - - const F32 force_net = (force_accel + - force_gravity + - force_spring + - force_damping + - force_drag); - - // - // End total force - //////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Calculate new params - // - - // 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; - velocity_new_local = llclamp(velocity_new_local, - -max_acceleration, max_acceleration); - - // Temporary debugging setting to cause all avatars to move, for profiling purposes. - if (physics_test) - { - velocity_new_local = sin(time*4.0); - } - // Calculate the new parameters, or remain unchanged if max speed is 0. - F32 position_new_local = position_current_local + velocity_new_local*time_delta; - if (behavior_maxeffect == 0) - position_new_local = position_user_local; - - // Zero out the velocity if the param is being pushed beyond its limits. - if ((position_new_local < min_val && velocity_new_local < 0) || - (position_new_local > max_val && velocity_new_local > 0)) - { - velocity_new_local = 0; - } - - const F32 position_new_local_clamped = llclamp(position_new_local, - min_val, - max_val); - - LLDriverParam *driver_param = dynamic_cast(mParamDriver); - llassert_always(driver_param); - if (driver_param) - { - // If this is one of our "hidden" driver params, then make sure it's - // the default value. - if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && - (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) - { - mCharacter->setVisualParamWeight(driver_param, - 0, - FALSE); - } - for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); - iter != driver_param->mDriven.end(); - ++iter) - { - LLDrivenEntry &entry = (*iter); - LLViewerVisualParam *driven_param = entry.mParam; - setParamValue(driven_param,position_new_local_clamped); - } - } - - // - // 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. - - BOOL update_visuals = FALSE; - - // For non-self, if the avatar is small enough visually, then don't update. - const F32 area_for_max_settings = 0.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); - const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); - - const BOOL is_self = (dynamic_cast(mCharacter) != NULL); - if ((pixel_area > area_for_this_setting) || is_self) - { - const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); - const F32 min_delta = (1.01f-lod_factor)*0.4f; - if (llabs(position_diff_local) > min_delta) - { - update_visuals = TRUE; - mPositionLastUpdate_local = position_new_local; - } - } - - // - // 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; - - /* - // Write out debugging info into a spreadsheet. - if (mFileWrite != NULL && is_self) - { - fprintf(mFileWrite,"%f\t%f\t%f \t\t%f \t\t%f\t%f\t%f\t \t\t%f\t%f\t%f\t%f\t%f \t\t%f\t%f\t%f\n", - position_new_local, - velocity_new_local, - acceleration_new_local, - - time_delta, - - mPosition_world[0], - mPosition_world[1], - mPosition_world[2], - - force_net, - force_spring, - force_accel, - force_damping, - force_drag, - - spring_length, - velocity_joint_local, - acceleration_joint_local - ); - } - */ - - return update_visuals; -} - -// Range of new_value_local is assumed to be [0 , 1] normalized. -void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param, - F32 new_value_normalized) -{ - const F32 value_min_local = param->getMinWeight(); - const F32 value_max_local = param->getMaxWeight(); - - const F32 new_value_local = value_min_local + (value_max_local-value_min_local) * new_value_normalized; - - mCharacter->setVisualParamWeight(param, - new_value_local, - FALSE); -} +/** + * @file llphysicsmotion.cpp + * @brief Implementation of LLPhysicsMotion class. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "llviewerprecompiledheaders.h" +#include "linden_common.h" + +#include "m3math.h" +#include "v3dmath.h" + +#include "llphysicsmotion.h" +#include "llcharacter.h" +#include "llviewercontrol.h" +#include "llviewervisualparam.h" +#include "llvoavatarself.h" + +typedef std::map controller_map_t; +typedef std::map default_controller_map_t; + +#define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 0.f; + +inline F64 llsgn(const F64 a) +{ + if (a >= 0) + return 1; + return -1; +} + +/* + At a high level, this works by setting temporary parameters that are not stored + in the avatar's list of params, and are not conveyed to other users. We accomplish + this by creating some new temporary driven params inside avatar_lad that are then driven + by the actual params that the user sees and sets. For example, in the old system, + the user sets a param called breast bouyancy, which controls the Z value of the breasts. + In our new system, the user still sets the breast bouyancy, but that param is redefined + as a driver param so that affects a new temporary driven param that the bounce is applied + to. +*/ + +class LLPhysicsMotion +{ +public: + /* + param_driver_name: The param that controls the params that are being affected by the physics. + joint_name: The joint that the body part is attached to. The joint is + used to determine the orientation (rotation) of the body part. + + character: The avatar that this physics affects. + + motion_direction_vec: The direction (in world coordinates) that determines the + motion. For example, (0,0,1) is up-down, and means that up-down motion is what + determines how this joint moves. + + controllers: The various settings (e.g. spring force, mass) that determine how + the body part behaves. + */ + LLPhysicsMotion(const std::string ¶m_driver_name, + const std::string &joint_name, + LLCharacter *character, + const LLVector3 &motion_direction_vec, + const controller_map_t &controllers) : + mParamDriverName(param_driver_name), + mJointName(joint_name), + mMotionDirectionVec(motion_direction_vec), + mParamDriver(NULL), + mParamControllers(controllers), + mCharacter(character), + mLastTime(0), + mPosition_local(0), + mVelocityJoint_local(0), + mPositionLastUpdate_local(0) + { + mJointState = new LLJointState; + } + + BOOL initialize(); + + ~LLPhysicsMotion() {} + + BOOL onUpdate(F32 time); + + LLPointer getJointState() + { + return mJointState; + } +protected: + F32 getParamValue(const std::string& controller_key) + { + const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); + if (entry == mParamControllers.end()) + { + return sDefaultController[controller_key]; + } + const std::string& param_name = (*entry).second.c_str(); + return mCharacter->getVisualParamWeight(param_name.c_str()); + } + void setParamValue(LLViewerVisualParam *param, + const F32 new_value_local); + + F32 toLocal(const LLVector3 &world); + F32 calculateVelocity_local(const F32 time_delta); + F32 calculateAcceleration_local(F32 velocity_local, + const F32 time_delta); +private: + const std::string mParamDriverName; + const std::string mParamControllerName; + const LLVector3 mMotionDirectionVec; + const std::string mJointName; + + F32 mPosition_local; + F32 mVelocityJoint_local; // How fast the joint is moving + F32 mAccelerationJoint_local; // Acceleration on the joint + + F32 mVelocity_local; // How fast the param is moving + F32 mPositionLastUpdate_local; + LLVector3 mPosition_world; + + LLViewerVisualParam *mParamDriver; + const controller_map_t mParamControllers; + + LLPointer mJointState; + LLCharacter *mCharacter; + + F32 mLastTime; + + static default_controller_map_t sDefaultController; +}; + +default_controller_map_t initDefaultController() +{ + default_controller_map_t controller; + controller["Mass"] = 0.2f; + controller["Gravity"] = 0.0f; + controller["Damping"] = .05f; + controller["Drag"] = 0.15f; + controller["MaxEffect"] = 0.1f; + controller["Spring"] = 0.1f; + controller["Gain"] = 10.0f; + return controller; +} + +default_controller_map_t LLPhysicsMotion::sDefaultController = initDefaultController(); + +BOOL LLPhysicsMotion::initialize() +{ + if (!mJointState->setJoint(mCharacter->getJoint(mJointName.c_str()))) + return FALSE; + mJointState->setUsage(LLJointState::ROT); + + mParamDriver = (LLViewerVisualParam*)mCharacter->getVisualParam(mParamDriverName.c_str()); + if (mParamDriver == NULL) + { + llinfos << "Failure reading in [ " << mParamDriverName << " ]" << llendl; + return FALSE; + } + + return TRUE; +} + +LLPhysicsMotionController::LLPhysicsMotionController(const LLUUID &id) : + LLMotion(id), + mCharacter(NULL) +{ + mName = "breast_motion"; +} + +LLPhysicsMotionController::~LLPhysicsMotionController() +{ + for (motion_vec_t::iterator iter = mMotions.begin(); + iter != mMotions.end(); + ++iter) + { + delete (*iter); + } +} + +BOOL LLPhysicsMotionController::onActivate() +{ + return TRUE; +} + +void LLPhysicsMotionController::onDeactivate() +{ +} + +LLMotion::LLMotionInitStatus LLPhysicsMotionController::onInitialize(LLCharacter *character) +{ + mCharacter = character; + + mMotions.clear(); + + // Breast Cleavage + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Drag"] = "Breast_Physics_Drag"; + controller["Damping"] = "Breast_Physics_InOut_Damping"; + controller["MaxEffect"] = "Breast_Physics_InOut_Max_Effect"; + controller["Spring"] = "Breast_Physics_InOut_Spring"; + controller["Gain"] = "Breast_Physics_InOut_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_InOut_Controller", + "mChest", + character, + LLVector3(-1,0,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Breast Bounce + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Drag"] = "Breast_Physics_Drag"; + controller["Damping"] = "Breast_Physics_UpDown_Damping"; + controller["MaxEffect"] = "Breast_Physics_UpDown_Max_Effect"; + controller["Spring"] = "Breast_Physics_UpDown_Spring"; + controller["Gain"] = "Breast_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_UpDown_Controller", + "mChest", + character, + LLVector3(0,0,1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Breast Sway + { + controller_map_t controller; + controller["Mass"] = "Breast_Physics_Mass"; + controller["Gravity"] = "Breast_Physics_Gravity"; + controller["Drag"] = "Breast_Physics_Drag"; + controller["Damping"] = "Breast_Physics_LeftRight_Damping"; + controller["MaxEffect"] = "Breast_Physics_LeftRight_Max_Effect"; + controller["Spring"] = "Breast_Physics_LeftRight_Spring"; + controller["Gain"] = "Breast_Physics_LeftRight_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Breast_Physics_LeftRight_Controller", + "mChest", + character, + LLVector3(0,-1,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + // Butt Bounce + { + controller_map_t controller; + controller["Mass"] = "Butt_Physics_Mass"; + controller["Gravity"] = "Butt_Physics_Gravity"; + controller["Drag"] = "Butt_Physics_Drag"; + controller["Damping"] = "Butt_Physics_UpDown_Damping"; + controller["MaxEffect"] = "Butt_Physics_UpDown_Max_Effect"; + controller["Spring"] = "Butt_Physics_UpDown_Spring"; + controller["Gain"] = "Butt_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_UpDown_Controller", + "mPelvis", + character, + LLVector3(0,0,-1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Butt LeftRight + { + controller_map_t controller; + controller["Mass"] = "Butt_Physics_Mass"; + controller["Gravity"] = "Butt_Physics_Gravity"; + controller["Drag"] = "Butt_Physics_Drag"; + controller["Damping"] = "Butt_Physics_LeftRight_Damping"; + controller["MaxEffect"] = "Butt_Physics_LeftRight_Max_Effect"; + controller["Spring"] = "Butt_Physics_LeftRight_Spring"; + controller["Gain"] = "Butt_Physics_LeftRight_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Butt_Physics_LeftRight_Controller", + "mPelvis", + character, + LLVector3(0,-1,0), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + // Belly Bounce + { + controller_map_t controller; + controller["Mass"] = "Belly_Physics_Mass"; + controller["Gravity"] = "Belly_Physics_Gravity"; + controller["Drag"] = "Belly_Physics_Drag"; + controller["Damping"] = "Belly_Physics_UpDown_Damping"; + controller["MaxEffect"] = "Belly_Physics_UpDown_Max_Effect"; + controller["Spring"] = "Belly_Physics_UpDown_Spring"; + controller["Gain"] = "Belly_Physics_UpDown_Gain"; + LLPhysicsMotion *motion = new LLPhysicsMotion("Belly_Physics_UpDown_Controller", + "mPelvis", + character, + LLVector3(0,0,-1), + controller); + if (!motion->initialize()) + { + llassert_always(FALSE); + return STATUS_FAILURE; + } + addMotion(motion); + } + + return STATUS_SUCCESS; +} + +void LLPhysicsMotionController::addMotion(LLPhysicsMotion *motion) +{ + addJointState(motion->getJointState()); + mMotions.push_back(motion); +} + +F32 LLPhysicsMotionController::getMinPixelArea() +{ + return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION; +} + +// Local space means "parameter space". +F32 LLPhysicsMotion::toLocal(const LLVector3 &world) +{ + LLJoint *joint = mJointState->getJoint(); + const LLQuaternion rotation_world = joint->getWorldRotation(); + + LLVector3 dir_world = mMotionDirectionVec * rotation_world; + dir_world.normalize(); + return world * dir_world; +} + +F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) +{ + 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 F32 velocity_local = toLocal(velocity_world); + return velocity_local; +} + +F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, + const F32 time_delta) +{ +// const F32 smoothing = getParamValue("Smoothing"); + static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary + const F32 acceleration_local = velocity_local - mVelocityJoint_local; + + const F32 smoothed_acceleration_local = + acceleration_local * 1.0/smoothing + + mAccelerationJoint_local * (smoothing-1.0)/smoothing; + + return smoothed_acceleration_local; +} + +BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) +{ + // Skip if disabled globally. + if (!gSavedSettings.getBOOL("AvatarPhysics")) + { + return TRUE; + } + + BOOL update_visuals = FALSE; + for (motion_vec_t::iterator iter = mMotions.begin(); + iter != mMotions.end(); + ++iter) + { + LLPhysicsMotion *motion = (*iter); + update_visuals |= motion->onUpdate(time); + } + + if (update_visuals) + mCharacter->updateVisualParams(); + + return TRUE; +} + + +// Return TRUE if character has to update visual params. +BOOL LLPhysicsMotion::onUpdate(F32 time) +{ + // static FILE *mFileWrite = fopen("c:\\temp\\avatar_data.txt","w"); + + if (!mParamDriver) + return FALSE; + + if (!mLastTime) + { + mLastTime = time; + return FALSE; + } + + //////////////////////////////////////////////////////////////////////////////// + // Get all parameters and settings + // + + const F32 time_delta = time - mLastTime; + if (time_delta > 3.0 || time_delta <= 0.01) + { + mLastTime = time; + return FALSE; + } + + // 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; + } + + LLJoint *joint = mJointState->getJoint(); + + const F32 behavior_mass = getParamValue("Mass"); + const F32 behavior_gravity = getParamValue("Gravity"); + const F32 behavior_spring = getParamValue("Spring"); + const F32 behavior_gain = getParamValue("Gain"); + const F32 behavior_damping = getParamValue("Damping"); + const F32 behavior_drag = getParamValue("Drag"); + const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); + + F32 behavior_maxeffect = getParamValue("MaxEffect"); + if (physics_test) + behavior_maxeffect = 1.0f; + // Maximum effect is [0,1] range. + const F32 min_val = 0.5f-behavior_maxeffect/2.0; + const F32 max_val = 0.5f+behavior_maxeffect/2.0; + + // 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()); + + // 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; + } + + // + // End parameters and settings + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate velocity and acceleration in parameter space. + // + + const F32 velocity_joint_local = calculateVelocity_local(time_delta); + const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); + + // + // End velocity and acceleration + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate the total force + // + + // Spring force is a restoring force towards the original user-set breast position. + // F = kx + const F32 spring_length = position_current_local - position_user_local; + const F32 force_spring = -spring_length * behavior_spring; + + // Acceleration is the force that comes from the change in velocity of the torso. + // F = ma + const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); + + // 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); + + // Damping is a restoring force that opposes the current velocity. + // F = -kv + const F32 force_damping = -behavior_damping * mVelocity_local; + + // Drag is a force imparted by velocity (intuitively it is similar to wind resistance) + // F = .5kv^2 + const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); + + const F32 force_net = (force_accel + + force_gravity + + force_spring + + force_damping + + force_drag); + + // + // End total force + //////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Calculate new params + // + + // 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; + velocity_new_local = llclamp(velocity_new_local, + -max_acceleration, max_acceleration); + + // Temporary debugging setting to cause all avatars to move, for profiling purposes. + if (physics_test) + { + velocity_new_local = sin(time*4.0); + } + // Calculate the new parameters, or remain unchanged if max speed is 0. + F32 position_new_local = position_current_local + velocity_new_local*time_delta; + if (behavior_maxeffect == 0) + position_new_local = position_user_local; + + // Zero out the velocity if the param is being pushed beyond its limits. + if ((position_new_local < min_val && velocity_new_local < 0) || + (position_new_local > max_val && velocity_new_local > 0)) + { + velocity_new_local = 0; + } + + const F32 position_new_local_clamped = llclamp(position_new_local, + min_val, + max_val); + + LLDriverParam *driver_param = dynamic_cast(mParamDriver); + llassert_always(driver_param); + if (driver_param) + { + // If this is one of our "hidden" driver params, then make sure it's + // the default value. + if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && + (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) + { + mCharacter->setVisualParamWeight(driver_param, + 0, + FALSE); + } + for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); + iter != driver_param->mDriven.end(); + ++iter) + { + LLDrivenEntry &entry = (*iter); + LLViewerVisualParam *driven_param = entry.mParam; + setParamValue(driven_param,position_new_local_clamped); + } + } + + // + // 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. + + BOOL update_visuals = FALSE; + + // For non-self, if the avatar is small enough visually, then don't update. + const F32 area_for_max_settings = 0.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); + const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); + + const BOOL is_self = (dynamic_cast(mCharacter) != NULL); + if ((pixel_area > area_for_this_setting) || is_self) + { + const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); + const F32 min_delta = (1.01f-lod_factor)*0.4f; + if (llabs(position_diff_local) > min_delta) + { + update_visuals = TRUE; + mPositionLastUpdate_local = position_new_local; + } + } + + // + // 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; + + /* + // Write out debugging info into a spreadsheet. + if (mFileWrite != NULL && is_self) + { + fprintf(mFileWrite,"%f\t%f\t%f \t\t%f \t\t%f\t%f\t%f\t \t\t%f\t%f\t%f\t%f\t%f \t\t%f\t%f\t%f\n", + position_new_local, + velocity_new_local, + acceleration_new_local, + + time_delta, + + mPosition_world[0], + mPosition_world[1], + mPosition_world[2], + + force_net, + force_spring, + force_accel, + force_damping, + force_drag, + + spring_length, + velocity_joint_local, + acceleration_joint_local + ); + } + */ + + return update_visuals; +} + +// Range of new_value_local is assumed to be [0 , 1] normalized. +void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param, + F32 new_value_normalized) +{ + const F32 value_min_local = param->getMinWeight(); + const F32 value_max_local = param->getMaxWeight(); + + const F32 new_value_local = value_min_local + (value_max_local-value_min_local) * new_value_normalized; + + mCharacter->setVisualParamWeight(param, + new_value_local, + FALSE); +} -- cgit v1.2.3 From ef8ce5bf5eb3325dec8a51d27ca01ddab47f183c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 7 Apr 2011 12:55:12 -0400 Subject: SH-1319: Fix for disappearing torso sections on avatars --- indra/newview/llphysicsmotion.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index acf8973f03..254fa5c33f 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -472,7 +472,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) const F32 behavior_gain = getParamValue("Gain"); const F32 behavior_damping = getParamValue("Damping"); const F32 behavior_drag = getParamValue("Drag"); - const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest"); + const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest") && gAgent.isGodlike(); F32 behavior_maxeffect = getParamValue("MaxEffect"); if (physics_test) @@ -583,9 +583,25 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) velocity_new_local = 0; } + // Check for NaN values. A NaN value is detected if the variables doesn't equal itself. + // If NaN, then reset everything. + if ((mPosition_local != mPosition_local) || + (mVelocity_local != mVelocity_local) || + (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; + mPosition_local = 0; + mPosition_world = LLVector3(0,0,0); + } + const F32 position_new_local_clamped = llclamp(position_new_local, - min_val, - max_val); + min_val, + max_val); LLDriverParam *driver_param = dynamic_cast(mParamDriver); llassert_always(driver_param); @@ -613,7 +629,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) // // End calculate new params //////////////////////////////////////////////////////////////////////////////// - + //////////////////////////////////////////////////////////////////////////////// // Conditionally update the visual params // -- cgit v1.2.3 From 4895b24e3861021c26a9df3ba9ba04400c63f5c8 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Thu, 7 Apr 2011 13:23:01 -0400 Subject: SH-1319 fix missing include --- indra/newview/llphysicsmotion.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 254fa5c33f..67bb139a5e 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -40,6 +40,7 @@ #include "v3dmath.h" #include "llphysicsmotion.h" +#include "llagent.h" #include "llcharacter.h" #include "llviewercontrol.h" #include "llviewervisualparam.h" -- cgit v1.2.3 From 60ffa83c325ede978f2de1dce2a0d49c1c137fe3 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Sat, 9 Apr 2011 21:57:01 -0400 Subject: fix incorrect license headers --- indra/newview/llphysicsmotion.cpp | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'indra/newview/llphysicsmotion.cpp') diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 7799ef04e6..968e62a8c3 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -2,31 +2,25 @@ * @file llphysicsmotion.cpp * @brief Implementation of LLPhysicsMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -- cgit v1.2.3