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;
}
BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask)
{
        // Skip if disabled globally.
		static const LLCachedControl<bool> avatar_physics("AvatarPhysics",false);
		bool supports_physics = !avatar_physics || (!((LLVOAvatar*)mCharacter)->isSelf() && !((LLVOAvatar*)mCharacter)->mSupportsPhysics);
		//Treat lod 0 as AvatarPhyiscs:FALSE. AvatarPhyiscs setting is superfluous unless we decide to hook it into param sending.
        if (supports_physics || !LLVOAvatar::sPhysicsLODFactor)
        {
			if(!mIsDefault)
			{
				mIsDefault = true;
				for (motion_vec_t::iterator iter = mMotions.begin();iter != mMotions.end();++iter)
				{
					(*iter)->reset();
				}
				mCharacter->updateVisualParams();
			}
			if(!supports_physics) //Only use emerald physics if avatarphysiscs is really off, or the client doesn't seem to support new physics.
			((LLVOAvatar*)mCharacter)->idleUpdateBoobEffect(); //Fall back to emerald physics	
			return TRUE;
		}
        
		mIsDefault = false;

        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;
}
BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask)
{
        // Skip if disabled globally.
		static LLCachedControl<bool> avatar_physics(gSavedSettings, "AvatarPhysics");
        if (!avatar_physics || (!((LLVOAvatar*)mCharacter)->isSelf() && !((LLVOAvatar*)mCharacter)->mSupportsPhysics))
        {
			if(!mIsDefault)
			{
				mIsDefault = true;
				for (motion_vec_t::iterator iter = mMotions.begin();iter != mMotions.end();++iter)
				{
					(*iter)->reset();
				}
				mCharacter->updateVisualParams();
			}
#ifdef OLD_BREAST_PHYSICS
			((LLVOAvatar*)mCharacter)->idleUpdateBoobEffect(); //Fall back to emerald physics	
#endif
			return TRUE;
		}
        
		mIsDefault = false;

        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;
}
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;
}