From d0936606412ccaf05a2e17894d2bc9a3c18506ab Mon Sep 17 00:00:00 2001 From: Armin Weatherwax Date: Mon, 22 Feb 2010 17:57:35 +0100 Subject: Ported breast physics from Emerald. --- linden/indra/llcharacter/llcharacter.cpp | 3 +- linden/indra/llcharacter/llcharacter.h | 7 + linden/indra/newview/CMakeLists.txt | 2 + linden/indra/newview/app_settings/settings.xml | 90 +++++++++++ linden/indra/newview/emeraldboobutils.cpp | 188 +++++++++++++++++++++++ linden/indra/newview/emeraldboobutils.h | 197 +++++++++++++++++++++++++ linden/indra/newview/llagent.cpp | 11 +- linden/indra/newview/llviewercontrol.cpp | 52 +++++++ linden/indra/newview/llvoavatar.cpp | 138 ++++++++++++++++- linden/indra/newview/llvoavatar.h | 56 +++++++ linden/indra/newview/llwearable.cpp | 122 ++++++++++++--- linden/indra/newview/llwearable.h | 6 +- 12 files changed, 846 insertions(+), 26 deletions(-) create mode 100644 linden/indra/newview/emeraldboobutils.cpp create mode 100644 linden/indra/newview/emeraldboobutils.h (limited to 'linden/indra') diff --git a/linden/indra/llcharacter/llcharacter.cpp b/linden/indra/llcharacter/llcharacter.cpp index 6633c65..dcdfe07 100644 --- a/linden/indra/llcharacter/llcharacter.cpp +++ b/linden/indra/llcharacter/llcharacter.cpp @@ -55,7 +55,8 @@ LLCharacter::LLCharacter() mPreferredPelvisHeight( 0.f ), mSex( SEX_FEMALE ), mAppearanceSerialNum( 0 ), - mSkeletonSerialNum( 0 ) + mSkeletonSerialNum( 0 ), + mInAppearance( false ) { mMotionController.setCharacter( this ); sInstances.push_back(this); diff --git a/linden/indra/llcharacter/llcharacter.h b/linden/indra/llcharacter/llcharacter.h index 0112788..d91124b 100644 --- a/linden/indra/llcharacter/llcharacter.h +++ b/linden/indra/llcharacter/llcharacter.h @@ -253,6 +253,11 @@ public: ESex getSex() { return mSex; } void setSex( ESex sex ) { mSex = sex; } + // set appearance flag + void setAppearanceFlag( bool flag ) { mInAppearance = flag; } + bool getAppearanceFlag() { return mInAppearance; } + + U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; } void setAppearanceSerialNum( U32 num ) { mAppearanceSerialNum = num; } @@ -273,6 +278,8 @@ protected: U32 mSkeletonSerialNum; LLAnimPauseRequest mPauseRequest; + BOOL mInAppearance; + private: // visual parameter stuff diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index f522f44..d4b618f 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -65,6 +65,7 @@ include_directories( ) set(viewer_SOURCE_FILES + emeraldboobutils.cpp floaterlogin.cpp hippoGridManager.cpp hippoLimits.cpp @@ -485,6 +486,7 @@ endif (LINUX) set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + emeraldboobutils.h floaterlogin.h hippoGridManager.h hippoLimits.h diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 1cf31d7..29b3bcc 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -3417,6 +3417,96 @@ + EmeraldBoobMass + + Comment + Mass of boobs. + Persist + 1 + Type + F32 + Value + 54.0 + + EmeraldBoobHardness + + Comment + Hardness (dampening) of boobs. + Persist + 1 + Type + F32 + Value + 51 + + EmeraldBreastPhysicsToggle + + Comment + Enables/Disables breast physics + Persist + 1 + Type + Boolean + Value + 1 + + EmeraldBreastSportsBra + + Comment + allows disabling the physics for 1 av, in case their outfit looks wrong with it on + Persist + 1 + Type + Boolean + Value + 0 + + EmeraldBoobVelMax + + Comment + Max amount of velocity boobs can have + Persist + 1 + Type + F32 + Value + 64 + + EmeraldBoobFriction + + Comment + Internal friction (brings boobs to rest). Shouldn't ever be above 1. + Persist + 1 + Type + F32 + Value + 80 + + EmeraldBoobVelMin + + Comment + Friction Fraction of FPS (used to keep friction uniform through FPS change). + Persist + 1 + Type + F32 + Value + 24 + + EmeraldBoobXYInfluence + + Comment + Amount of influence along the X and Y planes. + Persist + 1 + Type + F32 + Value + 0.1 + + + EmeraldTemporaryUpload Comment diff --git a/linden/indra/newview/emeraldboobutils.cpp b/linden/indra/newview/emeraldboobutils.cpp new file mode 100644 index 0000000..f68d6a7 --- /dev/null +++ b/linden/indra/newview/emeraldboobutils.cpp @@ -0,0 +1,188 @@ +#include "emeraldboobutils.h" + +std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v) +{ + os << "EmeraldBoobConfig" << std::endl; + os << "enabled: " << v.enabled << std::endl; + os << "mass: " << v.mass << std::endl; + os << "hardness: " << v.hardness << std::endl; + os << "zMax: " << v.zMax << std::endl; + os << "velMin: " << v.velMin << std::endl; + os << "velMax: " << v.velMax << std::endl; + os << "zInfluence: " << v.zInfluence << std::endl; + os << "friction: " << v.friction << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldAvatarLocalBoobConfig &v) +{ + os << "EmeraldAvatarLocalBoobConfig" << std::endl; + os << "actualBoobGrav: " << v.actualBoobGrav << std::endl; + os << "boobSize: " << v.boobSize << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobState &v) +{ + os << "EmeraldBoobState" << std::endl; + os << "boobGrav: " << v.boobGrav << std::endl; + os << "chestPosition: " << v.chestPosition << std::endl; + os << "chestRotation: " << v.chestRotation << std::endl; + os << "elapsedTime: " << v.elapsedTime << std::endl; + os << "frameDuration: " << v.frameDuration << std::endl; + os << "chestDisplacement: " << v.chestDisplacement << std::endl; + os << "localChestDisplacement: " << v.localChestDisplacement << std::endl; + os << "displacementForce: " << v.displacementForce << std::endl; + os << "mysteryValue: " << v.mysteryValue << std::endl; + os << "Number of bounceStates: " << v.bounceStates.size() << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobInputs &v) +{ + os << "EmeraldBoobInputs" << std::endl; + os << "chestPosition: " << v.chestPosition << std::endl; + os << "chestRotation: " << v.chestRotation << std::endl; + os << "elapsedTime: " << v.elapsedTime << std::endl; + os << "appearanceFlag: " << v.appearanceFlag << std::endl; + os << "appearanceAnimating: " << v.appearanceAnimating << std::endl; + return os; +} + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobBounceState &v) +{ + os << "EmeraldBoobBounceState" << std::endl; + os << "bounceStart: " << v.bounceStart << std::endl; + os << "bounceStartAmplitude: " << v.bounceStartAmplitude << std::endl; + os << "bounceStartFrameDuration: " << v.bounceStartFrameDuration << std::endl; + return os; +} + +F32 EmeraldBoobUtils::convertMass(F32 displayMass) +{ return displayMass/100.f*150.f; }; + +F32 EmeraldBoobUtils::convertHardness(F32 displayHardness) +{ return displayHardness/100.f*50; }; + +F32 EmeraldBoobUtils::convertVelMax(F32 displayVelMax) +{ return displayVelMax/100.f*0.01f; }; + +F32 EmeraldBoobUtils::convertFriction(F32 displayFriction) +{ return displayFriction/100.f*1.0f; }; + +F32 EmeraldBoobUtils::convertVelMin(F32 displayVelMin) +{ return displayVelMin/100.f; }; + +EmeraldBoobState EmeraldBoobUtils::idleUpdate(const EmeraldGlobalBoobConfig &config, const EmeraldAvatarLocalBoobConfig &localConfig, const EmeraldBoobState &oldState, const EmeraldBoobInputs &inputs) +{ + EmeraldBoobState newState; + F32 avatarLocalMass = 0.0f; + F32 partMod = 1.f; + + if(!config.enabled || inputs.appearanceFlag || inputs.appearanceAnimating) + return newState; + + if(inputs.type == 0) + { + newState.boobGrav = localConfig.actualBoobGrav; + avatarLocalMass = (llclamp(localConfig.boobSize, 0.0f, 0.5f) / 0.5f); + } + if(inputs.type == 1) + { + newState.boobGrav = localConfig.actualButtGrav; + partMod = 1.5f; + avatarLocalMass = llclamp(localConfig.actualButtGrav, 0.0f, 0.5f) / 0.5f; + } + if(inputs.type == 2) + { + newState.boobGrav = localConfig.actualFatGrav; + partMod = 1.3f; + avatarLocalMass = localConfig.actualFatGrav; + } + + + newState.elapsedTime = inputs.elapsedTime; + // seemed to create incorrect amounts of velocity when FPS varied + newState.frameDuration = inputs.elapsedTime - oldState.elapsedTime; + newState.chestPosition = inputs.chestPosition; + newState.chestRotation = inputs.chestRotation; + newState.chestDisplacement = inputs.chestPosition - oldState.chestPosition; + newState.localChestDisplacement = newState.chestDisplacement * ~inputs.chestRotation; + + + std::list bounceStates = oldState.bounceStates; + + if(fabs(newState.localChestDisplacement.length()) > 0.f) + { + F32 boobVel = 0.f; + boobVel = newState.localChestDisplacement.mV[VZ]; + boobVel += newState.localChestDisplacement[VX] * config.XYInfluence; + boobVel += newState.localChestDisplacement.mV[VY] * config.XYInfluence; + boobVel *= newState.frameDuration * 0.3f * 100.f; + boobVel = llclamp(boobVel, -config.velMax, config.velMax); + if(fabs(boobVel) <= config.velMax * config.velMin * newState.frameDuration * 100.f) + boobVel = 0.0f; + else + { + EmeraldBoobBounceState bounceState; + bounceState.bounceStart = inputs.elapsedTime; + bounceState.bounceStartFrameDuration = newState.frameDuration; + bounceState.bounceStartAmplitude = boobVel; + bounceState.bounceStartAmplitude *= avatarLocalMass; + bounceState.bounceStartAmplitude *= config.mass; + bounceStates.push_front(bounceState); + } + } + + /*if(fabs(newState.localChestDisplacement.length()) >= 0.f) { + LLVector3 displacementInfluence = newState.localChestDisplacement; + displacementInfluence *= LLVector3(0.3f, 0.3f, 1.0f); + F32 clampedDisplacementInfluenceLength = llclamp(displacementInfluence.length(), 0.0f, config.velMax); + if(displacementInfluence[VZ]<0.f) + clampedDisplacementInfluenceLength= -clampedDisplacementInfluenceLength; + EmeraldBoobBounceState bounceState; + bounceState.bounceStart = inputs.elapsedTime; + bounceState.bounceStartFrameDuration = newState.frameDuration; + bounceState.bounceStartAmplitude = clampedDisplacementInfluenceLength; + if(fabs(bounceState.bounceStartAmplitude) < config.velMin * config.velMax) + bounceState.bounceStartAmplitude = 0.0f; + else + { + bounceState.bounceStartAmplitude *= config.mass; + bounceStates.push_front(bounceState); + } + } + */ + + F32 totalNewAmplitude = 0.0f; + //std::cout << "Beginning bounce State processing at time " << inputs.elapsedTime << std::endl; + while(!bounceStates.empty()) { + EmeraldBoobBounceState bounceState = bounceStates.front(); + //std::cout << "Now processing " << bounceState; + bounceStates.pop_front(); + F32 bounceTime = newState.elapsedTime-bounceState.bounceStart; + F32 newAmplitude = bounceState.bounceStartAmplitude*pow(60.f*config.friction, -bounceTime)*cos(config.hardness*partMod*bounceTime); + if(fabs(newAmplitude) < 0.005f) { + newAmplitude = 0.0f; + } else { + newState.bounceStates.push_front(bounceState); + } + totalNewAmplitude+=newAmplitude; + } + //std::cout << "Total new amplitude: " << totalNewAmplitude << std::endl; + /* + if(inputs.type == 0) + newState.boobGrav = localConfig.actualBoobGrav + totalNewAmplitude; + if(inputs.type == 1) + newState.boobGrav = localConfig.actualButtGrav + totalNewAmplitude; + if(inputs.type == 2) + newState.boobGrav = localConfig.actualFatGrav + totalNewAmplitude; + */ + + newState.boobGrav = totalNewAmplitude; + + + newState.boobGrav = llclamp(newState.boobGrav, -1.5f, 2.0f); + + return newState; +} diff --git a/linden/indra/newview/emeraldboobutils.h b/linden/indra/newview/emeraldboobutils.h new file mode 100644 index 0000000..26008f9 --- /dev/null +++ b/linden/indra/newview/emeraldboobutils.h @@ -0,0 +1,197 @@ +#ifndef __emeraldboobutils_h +#define __emeraldboobutils_h + +#include +#include + +#include "stdtypes.h" +#include "v3math.h" +#include "llquaternion.h" + +struct EmeraldGlobalBoobConfig +{ + bool enabled; + F32 mass; + F32 hardness; + F32 zMax; + F32 velMin; + F32 velMax; + F32 zInfluence; + F32 friction; + F32 XYInfluence; + + EmeraldGlobalBoobConfig() + : enabled(false), + mass(6.4f), + hardness(0.67f), + zMax(1.29f), + velMin(0.0027f*0.017f), + velMax(0.0027f), + zInfluence(0.0f), + friction(0.35f), + XYInfluence(0.3f) + { + } + + bool operator==(const EmeraldGlobalBoobConfig &other) const + { + return + enabled == other.enabled && + mass == other.mass && + zMax == other.zMax && + velMax == other.velMax && + velMin == other.velMin && + zInfluence == other.zInfluence && + XYInfluence == other.XYInfluence && + friction == other.friction; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v); + +struct EmeraldAvatarLocalBoobConfig +{ + F32 actualBoobGrav; + F32 actualButtGrav; + F32 actualFatGrav; + F32 boobSize; + + EmeraldAvatarLocalBoobConfig() + : actualBoobGrav(0.0f), + actualButtGrav(0.0f), + actualFatGrav(0.0f), + boobSize(0.0f) + { + } + + bool operator==(const EmeraldAvatarLocalBoobConfig &other) const + { + return + actualBoobGrav == other.actualBoobGrav && + actualButtGrav == other.actualButtGrav && + actualFatGrav == other.actualFatGrav && + boobSize == other.boobSize; + } + +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldAvatarLocalBoobConfig &v); + +struct EmeraldBoobBounceState; + +struct EmeraldBoobState +{ + F32 boobGrav; + LLVector3 chestPosition; + LLQuaternion chestRotation; + F32 elapsedTime; + F32 frameDuration; + LLVector3 chestDisplacement; + LLVector3 localChestDisplacement; + LLVector3 displacementForce; + F32 mysteryValue; + std::list bounceStates; + + EmeraldBoobState() + : boobGrav(0.0f), + chestPosition(0.0f,0.0f,0.0f), + chestRotation(0.0f,0.0f,0.0f,1.0f), + elapsedTime(0.0f), + frameDuration(0.0f), + chestDisplacement(0.0f,0.0f,0.0f), + localChestDisplacement(0.0f,0.0f,0.0f), + displacementForce(0.0f,0.0f,0.0f), + mysteryValue(0.0f) + { + } + + bool operator==(const EmeraldBoobState &other) const + { + return + boobGrav == other.boobGrav && + chestPosition == other.chestPosition && + chestRotation == other.chestRotation && + elapsedTime == other.elapsedTime && + frameDuration == other.frameDuration && + chestDisplacement == other.chestDisplacement && + localChestDisplacement == other.localChestDisplacement && + displacementForce == other.displacementForce && + mysteryValue == other.mysteryValue && + bounceStates == other.bounceStates; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobState &v); + +struct EmeraldBoobInputs +{ + LLVector3 chestPosition; + LLQuaternion chestRotation; + F32 elapsedTime; + bool appearanceFlag; + bool appearanceAnimating; + S32 type; + + EmeraldBoobInputs() + : chestPosition(0.0f,0.0f,0.0f), + chestRotation(0.0f,0.0f,0.0f,1.0f), + elapsedTime(0.0f), + appearanceFlag(false), + appearanceAnimating(false), + type(0) + { + } + + bool operator==(const EmeraldBoobInputs &other) const + { + return + chestPosition == other.chestPosition && + chestRotation == other.chestRotation && + elapsedTime == other.elapsedTime && + appearanceFlag == other.appearanceFlag && + appearanceAnimating == other.appearanceAnimating && + type == other.type; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobInputs &v); + +struct EmeraldBoobBounceState +{ + F32 bounceStart; + F32 bounceStartAmplitude; + F32 bounceStartFrameDuration; + + EmeraldBoobBounceState() + : bounceStart(0.0f), + bounceStartAmplitude(0.0f), + bounceStartFrameDuration(0.0f) + { + }; + + bool operator==(const EmeraldBoobBounceState &other) const + { + return + bounceStart == other.bounceStart && + bounceStartAmplitude == other.bounceStartAmplitude && + bounceStartFrameDuration == other.bounceStartFrameDuration; + } +}; + +std::ostream &operator<<(std::ostream &os, const EmeraldBoobBounceState &v); + + +struct EmeraldBoobUtils +{ +public: + static EmeraldBoobState idleUpdate(const EmeraldGlobalBoobConfig &config, const EmeraldAvatarLocalBoobConfig &localConfig, const EmeraldBoobState &oldState, const EmeraldBoobInputs &inputs); + + static F32 convertMass(F32 displayMass); + static F32 convertHardness(F32 displayHardness); + static F32 convertVelMax(F32 displayVelMax); + static F32 convertFriction(F32 displayFriction); + static F32 convertVelMin(F32 displayVelMin); +}; + + +#endif diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 0b9f646..df3ab18 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -7411,7 +7411,16 @@ void LLAgent::sendAgentSetAppearance() msg->nextBlockFast(_PREHASH_VisualParam ); // We don't send the param ids. Instead, we assume that the receiver has the same params in the same sequence. - const F32 param_value = param->getWeight(); + F32 param_value; + if(param->getID() == 507) + param_value = mAvatarObject->getActualBoobGrav(); + else if(param->getID() == 795) + param_value = mAvatarObject->getActualButtGrav(); + else if(param->getID() == 157) + param_value = mAvatarObject->getActualFatGrav(); + else + param_value = param->getWeight(); + const U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight()); msg->addU8Fast(_PREHASH_ParamValue, new_weight ); transmitted_params++; diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 6d62db5..8bbef79 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -123,6 +123,50 @@ static bool handleSetShaderChanged(const LLSD& newvalue) return true; } +static bool handleAvatarBoobMassChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.mass = EmeraldBoobUtils::convertMass((F32) newvalue.asReal()); + return true; +} + +static bool handleAvatarBoobHardnessChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.hardness = EmeraldBoobUtils::convertHardness((F32) newvalue.asReal()); + return true; +} + +static bool handleAvatarBoobVelMaxChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.velMax = EmeraldBoobUtils::convertVelMax((F32) newvalue.asReal()); + LLVOAvatar::sBoobConfig.velMin = LLVOAvatar::sBoobConfig.velMin*LLVOAvatar::sBoobConfig.velMax; + return true; +} + +static bool handleAvatarBoobFrictionChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.friction = EmeraldBoobUtils::convertFriction((F32) newvalue.asReal()); + return true; +} + +static bool handleAvatarBoobVelMinChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.velMin = EmeraldBoobUtils::convertVelMin((F32) newvalue.asReal())*LLVOAvatar::sBoobConfig.velMax; + return true; +} + +static bool handleAvatarBoobToggleChanged(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.enabled = (BOOL) newvalue.asReal(); + return true; +} + +static bool handleAvatarBoobXYInfluence(const LLSD& newvalue) +{ + LLVOAvatar::sBoobConfig.XYInfluence = (F32) newvalue.asReal(); + return true; +} + + static bool handleSetSelfInvisible( const LLSD& newvalue) { LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() ); @@ -504,6 +548,14 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1)); gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _1)); gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _1)); + gSavedSettings.getControl("EmeraldBoobMass")->getSignal()->connect(boost::bind(&handleAvatarBoobMassChanged, _1)); + gSavedSettings.getControl("EmeraldBoobHardness")->getSignal()->connect(boost::bind(&handleAvatarBoobHardnessChanged, _1)); + gSavedSettings.getControl("EmeraldBoobVelMax")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMaxChanged, _1)); + gSavedSettings.getControl("EmeraldBoobFriction")->getSignal()->connect(boost::bind(&handleAvatarBoobFrictionChanged, _1)); + gSavedSettings.getControl("EmeraldBoobVelMin")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMinChanged, _1)); + gSavedSettings.getControl("EmeraldBreastPhysicsToggle")->getSignal()->connect(boost::bind(&handleAvatarBoobToggleChanged, _1)); + gSavedSettings.getControl("EmeraldBoobXYInfluence")->getSignal()->connect(boost::bind(&handleAvatarBoobXYInfluence, _1)); + gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _1)); gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _1)); gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _1)); diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 3692b1b..10e2ec7 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -706,6 +706,8 @@ F32 LLVOAvatar::sLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; BOOL LLVOAvatar::sJointDebug = FALSE; +EmeraldGlobalBoobConfig LLVOAvatar::sBoobConfig; + F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; @@ -764,7 +766,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mVisibleChat( FALSE ), mFullyLoadedInitialized(FALSE), mFullyLoaded(FALSE), - mHasBakedHair( FALSE ) + mHasBakedHair( FALSE ), + mFirstSetActualBoobGravRan( false ), + mFirstSetActualButtGravRan( false ), + mFirstSetActualFatGravRan( false ) { LLMemType mt(LLMemType::MTYPE_AVATAR); //VTResume(); // VTune @@ -985,6 +990,16 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, } + // grab the boob savedparams (prob a better place for this) + sBoobConfig.mass = EmeraldBoobUtils::convertMass(gSavedSettings.getF32("EmeraldBoobMass")); + sBoobConfig.hardness = EmeraldBoobUtils::convertHardness(gSavedSettings.getF32("EmeraldBoobHardness")); + sBoobConfig.velMax = EmeraldBoobUtils::convertVelMax(gSavedSettings.getF32("EmeraldBoobVelMax")); + sBoobConfig.velMin = EmeraldBoobUtils::convertVelMin(gSavedSettings.getF32("EmeraldBoobVelMin")); + sBoobConfig.friction = EmeraldBoobUtils::convertFriction(gSavedSettings.getF32("EmeraldBoobFriction")); + sBoobConfig.enabled = gSavedSettings.getBOOL("EmeraldBreastPhysicsToggle"); + sBoobConfig.XYInfluence = gSavedSettings.getF32("EmeraldBoobXYInfluence"); + + if (gNoRender) { return; @@ -2625,7 +2640,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateVoiceVisualizer( voice_enabled ); idleUpdateMisc( detailed_update ); idleUpdateAppearanceAnimation(); - + idleUpdateBoobEffect(); idleUpdateLipSync( voice_enabled ); idleUpdateLoadingEffect(); idleUpdateBelowWater(); // wind effect uses this @@ -2879,6 +2894,8 @@ void LLVOAvatar::idleUpdateAppearanceAnimation() { if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) { + // so boobs don't go spastic when a shape's changed, but still seems buggy + //if(param->getID() != 507) param->animate(morph_amt, mAppearanceAnimSetByUser); } } @@ -2897,6 +2914,107 @@ void LLVOAvatar::idleUpdateAppearanceAnimation() } } +// ------------------------------------------------------------ +// Danny: ZOMG Boob Phsyics go! +// ------------------------------------------------------------ +void LLVOAvatar::idleUpdateBoobEffect() +{ + if(mFirstSetActualBoobGravRan) + { + // should probably be moved somewhere where it is only called when boobsize changes + LLVisualParam *param; + + // BOOBS + param = getVisualParam(105); //boob size + mLocalBoobConfig.boobSize = param->getCurrentWeight(); + EmeraldBoobInputs boobInputs; + boobInputs.type = 0; + boobInputs.chestPosition = mChestp->getWorldPosition(); + boobInputs.chestRotation = mChestp->getWorldRotation(); + boobInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32(); + boobInputs.appearanceFlag = getAppearanceFlag(); + + + EmeraldBoobState newBoobState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mBoobState, boobInputs); + + if(mBoobState.boobGrav != newBoobState.boobGrav) + { + LLVisualParam *param; + param = getVisualParam(507); + + ESex avatar_sex = getSex(); + + param->stopAnimating(FALSE); + param->setWeight(llclamp(newBoobState.boobGrav+getActualBoobGrav(), -1.5f, 2.f), FALSE); + param->apply(avatar_sex); + updateVisualParams(); + } + + mBoobState = newBoobState; + } + /* + if(mFirstSetActualButtGravRan) + { + // BUTT + EmeraldBoobInputs buttInputs; + buttInputs.type = 1; + buttInputs.chestPosition = mPelvisp->getWorldPosition(); + buttInputs.chestRotation = mPelvisp->getWorldRotation(); + buttInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32(); + buttInputs.appearanceFlag = getAppearanceFlag(); + + + EmeraldBoobState newButtState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mButtState, buttInputs); + + if(mButtState.boobGrav != newButtState.boobGrav) + { + LLVisualParam *param; + param = getVisualParam(795); + + ESex avatar_sex = getSex(); + + param->stopAnimating(FALSE); + param->setWeight(newButtState.boobGrav*0.3f+getActualButtGrav(), FALSE); + param->apply(avatar_sex); + updateVisualParams(); + } + + mButtState = newButtState; + } + + if(mFirstSetActualFatGravRan) + { + // FAT + EmeraldBoobInputs fatInputs; + fatInputs.type = 2; + fatInputs.chestPosition = mPelvisp->getWorldPosition(); + fatInputs.chestRotation = mPelvisp->getWorldRotation(); + fatInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32(); + fatInputs.appearanceFlag = getAppearanceFlag(); + + + EmeraldBoobState newFatState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mFatState, fatInputs); + + if(mFatState.boobGrav != newFatState.boobGrav) + { + LLVisualParam *param; + param = getVisualParam(157); + + ESex avatar_sex = getSex(); + + param->stopAnimating(FALSE); + param->setWeight(newFatState.boobGrav*0.3f+getActualFatGrav(), FALSE); + param->apply(avatar_sex); + updateVisualParams(); + } + + mFatState = newFatState; + } + */ + +} + + void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) { // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync @@ -8342,6 +8460,22 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i); F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); + if(param->getID() == 507 && newWeight != getActualBoobGrav()) + { + llwarns << "Boob Grav SET to " << newWeight << " for " << getFullname() << llendl; + setActualBoobGrav(newWeight); + } + if(param->getID() == 795 && newWeight != getActualButtGrav()) + { + llwarns << "Butt Grav SET to " << newWeight << " for " << getFullname() << llendl; + setActualButtGrav(newWeight); + } + if(param->getID() == 157 && newWeight != getActualFatGrav()) + { + llwarns << "Fat Grav SET to " << newWeight << " for " << getFullname() << llendl; + setActualFatGrav(newWeight); + } + if (is_first_appearance_message || (param->getWeight() != newWeight)) { //llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl; diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index 33cec69..0bf648a 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -49,6 +49,8 @@ #include "llwearable.h" #include "llvoavatardefines.h" +#include "emeraldboobutils.h" + extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; extern const LLUUID ANIM_AGENT_EDITING; @@ -106,6 +108,7 @@ public: void idleUpdateLipSync(bool voice_enabled); void idleUpdateLoadingEffect(); void idleUpdateWindEffect(); + void idleUpdateBoobEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); void idleUpdateRenderCost(); void idleUpdateTractorBeam(); @@ -494,6 +497,59 @@ private: F32 mLastAppearanceBlendTime; //-------------------------------------------------------------------- + // boob bounce stuff + //-------------------------------------------------------------------- + +private: + bool mFirstSetActualBoobGravRan; + bool mFirstSetActualButtGravRan; + bool mFirstSetActualFatGravRan; + LLFrameTimer mBoobBounceTimer; + EmeraldAvatarLocalBoobConfig mLocalBoobConfig; + EmeraldBoobState mBoobState; + EmeraldBoobState mButtState; + EmeraldBoobState mFatState; + +public: + //boob + F32 getActualBoobGrav() { return mLocalBoobConfig.actualBoobGrav; } + void setActualBoobGrav(F32 grav) + { + mLocalBoobConfig.actualBoobGrav = grav; + if(!mFirstSetActualBoobGravRan) + { + mBoobState.boobGrav = grav; + mFirstSetActualBoobGravRan = true; + } + } + + //butt + F32 getActualButtGrav() { return mLocalBoobConfig.actualButtGrav; } + void setActualButtGrav(F32 grav) + { + mLocalBoobConfig.actualButtGrav = grav; + if(!mFirstSetActualButtGravRan) + { + mButtState.boobGrav = grav; + mFirstSetActualButtGravRan = true; + } + } + + //fat + F32 getActualFatGrav() { return mLocalBoobConfig.actualFatGrav; } + void setActualFatGrav(F32 grav) + { + mLocalBoobConfig.actualFatGrav = grav; + if(!mFirstSetActualFatGravRan) + { + mFatState.boobGrav = grav; + mFirstSetActualFatGravRan = true; + } + } + + static EmeraldGlobalBoobConfig sBoobConfig; + + //-------------------------------------------------------------------- // Attachments //-------------------------------------------------------------------- public: diff --git a/linden/indra/newview/llwearable.cpp b/linden/indra/newview/llwearable.cpp index bf5fd4a..087c74c 100644 --- a/linden/indra/newview/llwearable.cpp +++ b/linden/indra/newview/llwearable.cpp @@ -152,38 +152,34 @@ EWearableType LLWearable::typeNameToType( const std::string& type_name ) } return WT_INVALID; } - -const char* terse_F32_to_string( F32 f, char s[MAX_STRING] ) /* Flawfinder: ignore */ +std::string terse_F32_to_string( F32 f ) { - char* r = s; - S32 len = snprintf( s, MAX_STRING, "%.2f", f ); /* Flawfinder: ignore */ - + std::string r = llformat( "%.2f", f ); // "1.20" -> "1.2" // "24.00" -> "24." - while( '0' == r[len - 1] ) + S32 len = r.length(); + while( len > 0 && '0' == r[len - 1] ) { - len--; - r[len] = '\0'; + r.erase(len-1, 1); + len--; } if( '.' == r[len - 1] ) { // "24." -> "24" - len--; - r[len] = '\0'; + r.erase(len-1, 1); } else if( ('-' == r[0]) && ('0' == r[1]) ) { // "-0.59" -> "-.59" - r++; - r[0] = '-'; + r.erase(1, 1); } else if( '0' == r[0] ) { // "0.59" -> ".59" - r++; + r.erase(0, 1); } return r; @@ -200,13 +196,12 @@ BOOL LLWearable::FileExportParams( FILE* file ) S32 num_parameters = mVisualParamMap.size(); fprintf( file, "parameters %d\n", num_parameters ); - char s[ MAX_STRING ]; /* Flawfinder: ignore */ for (param_map_t::iterator iter = mVisualParamMap.begin(); iter != mVisualParamMap.end(); ++iter) { S32 param_id = iter->first; F32 param_weight = iter->second; - fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight, s ) ); + fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() ); } return TRUE; @@ -280,13 +275,12 @@ BOOL LLWearable::exportFile( LLFILE* file ) return FALSE; } - char s[ MAX_STRING ]; /* Flawfinder: ignore */ for (param_map_t::iterator iter = mVisualParamMap.begin(); iter != mVisualParamMap.end(); ++iter) { S32 param_id = iter->first; F32 param_weight = iter->second; - if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight, s ) ) < 0 ) + if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 ) { return FALSE; } @@ -597,9 +591,52 @@ BOOL LLWearable::isDirty() weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() ); - U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() ); + + if(avatar->getAppearanceFlag() == true) + { + //boob + if(param->getID() == 507) + { + weight = get_if_there(mVisualParamMap, param->getID(), avatar->getActualBoobGrav()); + weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); + } + //butt + if(param->getID() == 795) + { + weight = get_if_there(mVisualParamMap, param->getID(), avatar->getActualButtGrav()); + weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); + } + //fat + if(param->getID() == 157) + { + weight = get_if_there(mVisualParamMap, param->getID(), avatar->getActualFatGrav()); + weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); + } + } + else + { + //boob + if(param->getID() == 507) + { + a = F32_to_U8( avatar->getActualBoobGrav(), param->getMinWeight(), param->getMaxWeight() ); + } + //butt + if(param->getID() == 795) + { + a = F32_to_U8( avatar->getActualButtGrav(), param->getMinWeight(), param->getMaxWeight() ); + } + //fat + if(param->getID() == 157) + { + a = F32_to_U8( avatar->getActualFatGrav(), param->getMinWeight(), param->getMaxWeight() ); + } + } + + + U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() ); if( a != b ) { + llwarns << "param ID " << param->getID() << " was changed." << llendl; return TRUE; } } @@ -685,6 +722,16 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { S32 param_id = param->getID(); F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight()); + + //ZOMG: When switching shapes from inventory + if(param_id == 507) + avatar->setActualBoobGrav(weight); + if(param_id == 795) + avatar->setActualButtGrav(weight); + if(param_id == 157) + avatar->setActualFatGrav(weight); + + // only animate with user-originated changes if (set_by_user) { @@ -745,7 +792,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) // if( set_by_user ) // { -// gAgent.sendAgentSetAppearance(); + gAgent.sendAgentSetAppearance(); // } } @@ -822,6 +869,22 @@ void LLWearable::readFromAvatar() { if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { + + //pretty sure is right + if(param->getID() == 507) + avatar->setActualBoobGrav(param->getWeight()); + if(param->getID() == 151) + avatar->setActualButtGrav(param->getWeight()); + if(param->getID() == 157) + avatar->setActualFatGrav(param->getWeight()); + + //if(param->getID() == 507) + //{ + // llwarns << "current = " << avatar->getActualBoobGrav() << llendl; + // llwarns << "param weight = " << param->getWeight() << llendl; + //} + + mVisualParamMap[param->getID()] = param->getWeight(); } } @@ -873,6 +936,27 @@ void LLWearable::copyDataFrom( LLWearable* src ) { S32 id = param->getID(); F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() ); + //llwarns << "------------------------------" << llendl; + //llwarns << "copydatafrom" << llendl; + //llwarns << "------------------------------" << llendl; + + //if(id == 507) + //{ + // llwarns << "weight = " << weight << llendl; + // llwarns << "actual = " << avatar->getActualBoobGrav() << llendl; + // llwarns << "mVisualParamMap[id] = " << mVisualParamMap[id] << llendl; + //} + + //pretty sure right + if(id == 507) + avatar->setActualBoobGrav(weight); + if(id == 795) + avatar->setActualButtGrav(weight); + if(id == 157) + avatar->setActualFatGrav(weight); + + + mVisualParamMap[id] = weight; } } diff --git a/linden/indra/newview/llwearable.h b/linden/indra/newview/llwearable.h index 6e473c1..81aa61d 100644 --- a/linden/indra/newview/llwearable.h +++ b/linden/indra/newview/llwearable.h @@ -105,11 +105,11 @@ public: friend std::ostream& operator<<(std::ostream &s, const LLWearable &w); -private: - // Private constructor used by LLWearableList +public: + // -not anymore Private- constructor used by LLWearableList LLWearable(const LLTransactionID& transactionID); LLWearable(const LLAssetID& assetID); - +private: static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml. S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created. std::string mName; -- cgit v1.1