Merge branch 'V2AvatarPhysics'
This commit is contained in:
@@ -348,6 +348,7 @@ set(viewer_SOURCE_FILES
|
||||
llpanelweb.cpp
|
||||
llparcelselection.cpp
|
||||
llpatchvertexarray.cpp
|
||||
llphysicsmotion.cpp
|
||||
llpolymesh.cpp
|
||||
llpolymorph.cpp
|
||||
llprefschat.cpp
|
||||
@@ -822,6 +823,7 @@ set(viewer_HEADER_FILES
|
||||
llpanelweb.h
|
||||
llparcelselection.h
|
||||
llpatchvertexarray.h
|
||||
llphysicsmotion.h
|
||||
llpolymesh.h
|
||||
llpolymorph.h
|
||||
llprefschat.h
|
||||
|
||||
@@ -1784,6 +1784,17 @@
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>AvatarPhysics</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable avatar wearable physics.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AvatarSex</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -8887,6 +8898,17 @@
|
||||
<key>Value</key>
|
||||
<integer>35</integer>
|
||||
</map>
|
||||
<key>RenderAvatarPhysicsLODFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Controls level of detail of avatar physics (such as breast physics).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<integer>1.0</integer>
|
||||
</map>
|
||||
<key>RenderAvatarInvisible</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -2923,6 +2923,8 @@
|
||||
id="40"
|
||||
group="1"
|
||||
name="Male_Head"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
@@ -3508,6 +3510,8 @@
|
||||
id="104"
|
||||
group="1"
|
||||
name="Big_Belly_Torso"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_morph>
|
||||
@@ -3824,6 +3828,8 @@
|
||||
id="855"
|
||||
group="1"
|
||||
name="Love_Handles"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-1"
|
||||
value_max="2">
|
||||
@@ -3879,6 +3885,8 @@
|
||||
id="100"
|
||||
group="1"
|
||||
name="Male_Torso"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
label_min="Male_Torso"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
@@ -4047,9 +4055,66 @@
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<!--
|
||||
#end morph targets
|
||||
-->
|
||||
<!--
|
||||
#############
|
||||
# physics morphs (not user controlled)
|
||||
#############
|
||||
-->
|
||||
<param
|
||||
id="1200"
|
||||
group="1"
|
||||
sex="female"
|
||||
name="Breast_Physics_UpDown_Driven"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-3"
|
||||
value_max="3">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1201"
|
||||
group="1"
|
||||
sex="female"
|
||||
name="Breast_Physics_InOut_Driven"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-1.25"
|
||||
value_max="1.25">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1204"
|
||||
group="1"
|
||||
name="Belly_Physics_Torso_UpDown_Driven"
|
||||
wearable="physics"
|
||||
cross_wearable="true"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1207"
|
||||
group="1"
|
||||
name="Breast_Physics_LeftRight_Driven"
|
||||
wearable="physics"
|
||||
cross_wearable="true"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-2"
|
||||
value_max="2">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<!--
|
||||
#end morph targets
|
||||
-->
|
||||
</mesh>
|
||||
|
||||
<mesh
|
||||
@@ -4103,11 +4168,14 @@
|
||||
id="156"
|
||||
group="1"
|
||||
name="Big_Belly_Legs"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
|
||||
<param
|
||||
id="151"
|
||||
group="1"
|
||||
@@ -4499,6 +4567,8 @@
|
||||
id="854"
|
||||
group="1"
|
||||
name="Saddlebags"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_min="-.5"
|
||||
value_max="3">
|
||||
<param_morph>
|
||||
@@ -4537,15 +4607,62 @@
|
||||
id="153"
|
||||
group="1"
|
||||
name="Male_Legs"
|
||||
wearable="shape"
|
||||
edit_group="driven"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<!--
|
||||
#end morph targets
|
||||
-->
|
||||
</mesh>
|
||||
<!--
|
||||
#############
|
||||
# physics morphs (not user controlled)
|
||||
#############
|
||||
-->
|
||||
<param
|
||||
id="1202"
|
||||
group="1"
|
||||
name="Belly_Physics_Legs_UpDown_Driven"
|
||||
wearable="physics"
|
||||
cross_wearable="true"
|
||||
edit_group="driven"
|
||||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
|
||||
<param
|
||||
id="1205"
|
||||
group="1"
|
||||
name="Butt_Physics_UpDown_Driven"
|
||||
wearable="physics"
|
||||
cross_wearable="true"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1206"
|
||||
group="1"
|
||||
name="Butt_Physics_LeftRight_Driven"
|
||||
wearable="physics"
|
||||
cross_wearable="true"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<!--
|
||||
#end morph targets
|
||||
-->
|
||||
|
||||
</mesh>
|
||||
|
||||
<mesh
|
||||
type="lowerBodyMesh"
|
||||
@@ -4818,6 +4935,7 @@
|
||||
name="skirt_bowlegs"
|
||||
label="legs skirt"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
@@ -4828,6 +4946,8 @@
|
||||
id="852"
|
||||
group="1"
|
||||
name="skirt_bigbutt"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
label="bigbutt skirt"
|
||||
label_min="less"
|
||||
label_max="more"
|
||||
@@ -4840,6 +4960,8 @@
|
||||
id="849"
|
||||
group="1"
|
||||
name="skirt_belly"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
label="big belly skirt"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
@@ -4849,6 +4971,8 @@
|
||||
<param
|
||||
id="850"
|
||||
group="1"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
name="skirt_saddlebags"
|
||||
value_min="-.5"
|
||||
value_max="3">
|
||||
@@ -4859,6 +4983,8 @@
|
||||
id="851"
|
||||
group="1"
|
||||
name="skirt_chubby"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
label_min="less"
|
||||
label_max="more"
|
||||
value_min="0"
|
||||
@@ -4871,6 +4997,8 @@
|
||||
id="856"
|
||||
group="1"
|
||||
name="skirt_lovehandles"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
label_min="less"
|
||||
label_max="more"
|
||||
value_min="-1"
|
||||
@@ -4888,11 +5016,32 @@
|
||||
id="857"
|
||||
group="1"
|
||||
name="skirt_male"
|
||||
wearable="skirt"
|
||||
edit_group="driven"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
</mesh>
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
<!--
|
||||
#############
|
||||
# physics morphs (not user controlled)
|
||||
#############
|
||||
-->
|
||||
<param
|
||||
id="1203"
|
||||
group="1"
|
||||
name="Belly_Physics_Skirt_UpDown_Driven"
|
||||
wearable="physics"
|
||||
cross_wearable="true"
|
||||
edit_group="driven"
|
||||
value_default="0"
|
||||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_morph />
|
||||
</param>
|
||||
|
||||
</mesh>
|
||||
|
||||
<mesh
|
||||
type="skirtMesh"
|
||||
@@ -5564,6 +5713,7 @@
|
||||
<param
|
||||
id="1003"
|
||||
group="1"
|
||||
wearable="hair"
|
||||
edit_group="driven"
|
||||
name="Eyebrow Density"
|
||||
value_min="0"
|
||||
@@ -6212,6 +6362,7 @@
|
||||
id="1005"
|
||||
sex="male"
|
||||
group="1"
|
||||
wearable="hair"
|
||||
edit_group="driven"
|
||||
name="Sideburns"
|
||||
value_min="0"
|
||||
@@ -6226,6 +6377,7 @@
|
||||
id="1007"
|
||||
sex="male"
|
||||
group="1"
|
||||
wearable="hair"
|
||||
edit_group="driven"
|
||||
name="Moustache"
|
||||
value_min="0"
|
||||
@@ -6240,6 +6392,7 @@
|
||||
id="1009"
|
||||
sex="male"
|
||||
group="1"
|
||||
wearable="hair"
|
||||
edit_group="driven"
|
||||
name="Soulpatch"
|
||||
value_min="0"
|
||||
@@ -6254,6 +6407,7 @@
|
||||
id="1011"
|
||||
sex="male"
|
||||
group="1"
|
||||
wearable="hair"
|
||||
edit_group="driven"
|
||||
name="Chin Curtains"
|
||||
value_min="0"
|
||||
@@ -9050,7 +9204,7 @@
|
||||
wearable="skin"
|
||||
edit_group="skin_facedetail"
|
||||
edit_group_order="3"
|
||||
name="wrinkles"
|
||||
name="Wrinkles"
|
||||
label_min="Less"
|
||||
label_max="More"
|
||||
value_min="0"
|
||||
@@ -11150,6 +11304,523 @@
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<!-- ==PHYSICS PARAMETERS======================================= -->
|
||||
|
||||
<param
|
||||
id="1100"
|
||||
group="1"
|
||||
sex="female"
|
||||
wearable="physics"
|
||||
name="Breast_Physics_UpDown_Controller"
|
||||
label="Breast Physics UpDown Controller"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
<param_driver>
|
||||
<driven
|
||||
id="1200" />
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1101"
|
||||
group="1"
|
||||
sex="female"
|
||||
wearable="physics"
|
||||
name="Breast_Physics_InOut_Controller"
|
||||
label="Breast Physics InOut Controller"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
<param_driver>
|
||||
<driven
|
||||
id="1201" />
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1102"
|
||||
group="1"
|
||||
wearable="physics"
|
||||
name="Belly_Physics_UpDown_Controller"
|
||||
label="Belly Physics UpDown Controller"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
<param_driver>
|
||||
<driven
|
||||
id="1202" />
|
||||
<driven
|
||||
id="1203" />
|
||||
<driven
|
||||
id="1204" />
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1103"
|
||||
group="1"
|
||||
wearable="shape"
|
||||
name="Butt_Physics_UpDown_Controller"
|
||||
label="Butt Physics UpDown Controller"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
<param_driver>
|
||||
<driven
|
||||
id="1205" />
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1104"
|
||||
group="1"
|
||||
wearable="shape"
|
||||
name="Butt_Physics_LeftRight_Controller"
|
||||
label="Butt Physics LeftRight Controller"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
<param_driver>
|
||||
<driven
|
||||
id="1206" />
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="1105"
|
||||
group="1"
|
||||
wearable="shape"
|
||||
name="Breast_Physics_LeftRight_Controller"
|
||||
label="Breast Physics LeftRight Controller"
|
||||
value_min="-1"
|
||||
value_max="1"
|
||||
value_default="0">
|
||||
<param_driver>
|
||||
<driven
|
||||
id="1207" />
|
||||
</param_driver>
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10000"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_Mass"
|
||||
label="Breast Mass"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default=".1"
|
||||
value_min=".1"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10001"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_Gravity"
|
||||
label="Breast Gravity"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="30">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10002"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_Drag"
|
||||
label="Breast Drag"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default="1"
|
||||
value_min="0"
|
||||
value_max="10">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10003"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_UpDown_Max_Effect"
|
||||
label="Max Effect"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_updown"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="3">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10004"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_UpDown_Spring"
|
||||
label="Spring"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_updown"
|
||||
value_default="10"
|
||||
value_min="0"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10005"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_UpDown_Gain"
|
||||
label="Gain"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_updown"
|
||||
value_default="10"
|
||||
value_min="1"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10006"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_UpDown_Damping"
|
||||
label="Damping"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_updown"
|
||||
value_default=".2"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10007"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_InOut_Max_Effect"
|
||||
label="Max Effect"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_inout"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="3">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10008"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_InOut_Spring"
|
||||
label="Spring"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_inout"
|
||||
value_default="10"
|
||||
value_min="0"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10009"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_InOut_Gain"
|
||||
label="Gain"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_inout"
|
||||
value_default="10"
|
||||
value_min="1"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10010"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_InOut_Damping"
|
||||
label="Damping"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_inout"
|
||||
value_default=".2"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10011"
|
||||
group="0"
|
||||
name="Belly_Physics_Mass"
|
||||
label="Belly Mass"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default=".1"
|
||||
value_min=".1"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10012"
|
||||
group="0"
|
||||
name="Belly_Physics_Gravity"
|
||||
label="Belly Gravity"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="30">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10013"
|
||||
group="0"
|
||||
name="Belly_Physics_Drag"
|
||||
label="Belly Drag"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default="1"
|
||||
value_min="0"
|
||||
value_max="10">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10014"
|
||||
group="0"
|
||||
name="Belly_Physics_UpDown_Max_Effect"
|
||||
label="Max Effect"
|
||||
wearable="physics"
|
||||
edit_group="physics_belly_updown"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="3">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10015"
|
||||
group="0"
|
||||
name="Belly_Physics_UpDown_Spring"
|
||||
label="Spring"
|
||||
wearable="physics"
|
||||
edit_group="physics_belly_updown"
|
||||
value_default="10"
|
||||
value_min="0"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10016"
|
||||
group="0"
|
||||
name="Belly_Physics_UpDown_Gain"
|
||||
label="Gain"
|
||||
wearable="physics"
|
||||
edit_group="physics_belly_updown"
|
||||
value_default="10"
|
||||
value_min="1"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10017"
|
||||
group="0"
|
||||
name="Belly_Physics_UpDown_Damping"
|
||||
label="Damping"
|
||||
wearable="physics"
|
||||
edit_group="physics_belly_updown"
|
||||
value_default=".2"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10018"
|
||||
group="0"
|
||||
name="Butt_Physics_Mass"
|
||||
label="Butt Mass"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default=".1"
|
||||
value_min=".1"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10019"
|
||||
group="0"
|
||||
name="Butt_Physics_Gravity"
|
||||
label="Butt Gravity"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="30">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10020"
|
||||
group="0"
|
||||
name="Butt_Physics_Drag"
|
||||
label="Butt Drag"
|
||||
wearable="physics"
|
||||
edit_group="physics_advanced"
|
||||
value_default="1"
|
||||
value_min="0"
|
||||
value_max="10">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10021"
|
||||
group="0"
|
||||
name="Butt_Physics_UpDown_Max_Effect"
|
||||
label="Max Effect"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_updown"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="3">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10022"
|
||||
group="0"
|
||||
name="Butt_Physics_UpDown_Spring"
|
||||
label="Spring"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_updown"
|
||||
value_default="10"
|
||||
value_min="0"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10023"
|
||||
group="0"
|
||||
name="Butt_Physics_UpDown_Gain"
|
||||
label="Gain"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_updown"
|
||||
value_default="10"
|
||||
value_min="1"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10024"
|
||||
group="0"
|
||||
name="Butt_Physics_UpDown_Damping"
|
||||
label="Damping"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_updown"
|
||||
value_default=".2"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10025"
|
||||
group="0"
|
||||
name="Butt_Physics_LeftRight_Max_Effect"
|
||||
label="Max Effect"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_leftright"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="3">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10026"
|
||||
group="0"
|
||||
name="Butt_Physics_LeftRight_Spring"
|
||||
label="Spring"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_leftright"
|
||||
value_default="10"
|
||||
value_min="0"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10027"
|
||||
group="0"
|
||||
name="Butt_Physics_LeftRight_Gain"
|
||||
label="Gain"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_leftright"
|
||||
value_default="10"
|
||||
value_min="1"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10028"
|
||||
group="0"
|
||||
name="Butt_Physics_LeftRight_Damping"
|
||||
label="Damping"
|
||||
wearable="physics"
|
||||
edit_group="physics_butt_leftright"
|
||||
value_default=".2"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
|
||||
<param
|
||||
id="10029"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_LeftRight_Max_Effect"
|
||||
label="Max Effect"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_leftright"
|
||||
value_default="0"
|
||||
value_min="0"
|
||||
value_max="3">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10030"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_LeftRight_Spring"
|
||||
label="Spring"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_leftright"
|
||||
value_default="10"
|
||||
value_min="0"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10031"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_LeftRight_Gain"
|
||||
label="Gain"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_leftright"
|
||||
value_default="10"
|
||||
value_min="1"
|
||||
value_max="100">
|
||||
<param_driver />
|
||||
</param>
|
||||
<param
|
||||
id="10032"
|
||||
group="0"
|
||||
sex="female"
|
||||
name="Breast_Physics_LeftRight_Damping"
|
||||
label="Damping"
|
||||
wearable="physics"
|
||||
edit_group="physics_breasts_leftright"
|
||||
value_default=".2"
|
||||
value_min="0"
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
</driver_parameters>
|
||||
</linden_avatar>
|
||||
|
||||
|
||||
@@ -7306,7 +7306,8 @@ void LLAgent::createStandardWearables(BOOL female)
|
||||
TRUE, //WT_UNDERPANTS
|
||||
FALSE, //WT_SKIRT
|
||||
FALSE, //WT_ALPHA
|
||||
FALSE //WT_TATTOO
|
||||
FALSE, //WT_TATTOO
|
||||
FALSE, //WT_PHYSICS
|
||||
};
|
||||
|
||||
for( S32 i=0; i < WT_COUNT; i++ )
|
||||
@@ -7918,6 +7919,7 @@ void LLAgent::setWearableOutfit(
|
||||
wearables_to_remove[WT_SKIRT] = remove && gRlvWearableLocks.canRemove(WT_SKIRT);
|
||||
wearables_to_remove[WT_ALPHA] = remove && gRlvWearableLocks.canRemove(WT_ALPHA);
|
||||
wearables_to_remove[WT_TATTOO] = remove && gRlvWearableLocks.canRemove(WT_TATTOO);
|
||||
wearables_to_remove[WT_PHYSICS] = remove && gRlvWearableLocks.canRemove(WT_PHYSICS);
|
||||
// [/RLVa:KB]
|
||||
|
||||
S32 count = wearables.count();
|
||||
@@ -8199,6 +8201,7 @@ void LLAgent::userRemoveAllClothesStep2( BOOL proceed, void* userdata )
|
||||
gAgent.removeWearable( WT_SKIRT );
|
||||
gAgent.removeWearable( WT_ALPHA );
|
||||
gAgent.removeWearable( WT_TATTOO );
|
||||
gAgent.removeWearable( WT_PHYSICS );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -429,6 +429,7 @@ static void settings_to_globals()
|
||||
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
|
||||
LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
|
||||
LLVOAvatar::sLODFactor = gSavedSettings.getF32("RenderAvatarLODFactor");
|
||||
LLVOAvatar::sPhysicsLODFactor = gSavedSettings.getF32("RenderAvatarPhysicsLODFactor");
|
||||
LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible");
|
||||
LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
|
||||
// clamp auto-open time to some minimum usable value
|
||||
|
||||
@@ -144,7 +144,7 @@ LLAssetType::EType LLAssetConverter::convert(std::string src_filename, std::stri
|
||||
return LLAssetType::AT_NONE;
|
||||
}
|
||||
}
|
||||
else if(exten == "eyes" || exten == "gloves" || exten == "hair" || exten == "jacket" || exten == "pants" || exten == "shape" || exten == "shirt" || exten == "shoes" || exten == "skin" || exten == "skirt" || exten == "socks" || exten == "underpants" || exten == "undershirt" || exten == "bodypart" || exten == "clothing")
|
||||
else if(exten == "eyes" || exten == "gloves" || exten == "hair" || exten == "jacket" || exten == "pants" || exten == "shape" || exten == "shirt" || exten == "shoes" || exten == "skin" || exten == "skirt" || exten == "socks" || exten == "underpants" || exten == "undershirt" || exten == "bodypart" || exten == "clothing" || exten == "physics")
|
||||
{
|
||||
asset_type = LLAssetType::AT_CLOTHING;
|
||||
if(!copyFile(src_filename, filename))
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "llviewervisualparam.h"
|
||||
|
||||
class LLPhysicsMotion;
|
||||
class LLVOAvatar;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -78,6 +79,7 @@ protected:
|
||||
|
||||
class LLDriverParam : public LLViewerVisualParam
|
||||
{
|
||||
friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
|
||||
public:
|
||||
LLDriverParam(LLVOAvatar *avatarp);
|
||||
~LLDriverParam();
|
||||
|
||||
@@ -693,6 +693,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
|
||||
L"Asset Blacklists (*.blacklist)\0*.blacklist\0" \
|
||||
L"\0";
|
||||
break;
|
||||
case FFSAVE_PHYSICS:
|
||||
if(filename.empty())
|
||||
{
|
||||
wcsncpy( mFilesW,L"untitled.phy", FILENAME_BUFFER_SIZE);
|
||||
}
|
||||
mOFN.lpstrDefExt = L"phy";
|
||||
mOFN.lpstrFilter =
|
||||
L"Landmarks (*.phy)\0*.phy\0" \
|
||||
L"\0";
|
||||
break;
|
||||
// </edit>
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
@@ -139,6 +139,7 @@ public:
|
||||
FFSAVE_LANDMARK = 34,
|
||||
FFSAVE_AO = 35,
|
||||
FFSAVE_BLACKLIST = 36,
|
||||
FFSAVE_PHYSICS = 37,
|
||||
// </edit>
|
||||
};
|
||||
|
||||
|
||||
@@ -405,12 +405,19 @@ enum ESubpart {
|
||||
SUBPART_UNDERPANTS,
|
||||
SUBPART_SKIRT,
|
||||
SUBPART_ALPHA,
|
||||
SUBPART_TATTOO
|
||||
SUBPART_TATTOO,
|
||||
SUBPART_PHYSICS_BREASTS_UPDOWN,
|
||||
SUBPART_PHYSICS_BREASTS_INOUT,
|
||||
SUBPART_PHYSICS_BREASTS_LEFTRIGHT,
|
||||
SUBPART_PHYSICS_BELLY_UPDOWN,
|
||||
SUBPART_PHYSICS_BUTT_UPDOWN,
|
||||
SUBPART_PHYSICS_BUTT_LEFTRIGHT,
|
||||
SUBPART_PHYSICS_ADVANCED
|
||||
};
|
||||
|
||||
struct LLSubpart
|
||||
{
|
||||
LLSubpart() : mSex( SEX_BOTH ) {}
|
||||
LLSubpart() : mSex( SEX_BOTH ), mVisualHint(true) {}
|
||||
|
||||
std::string mButtonName;
|
||||
std::string mTargetJoint;
|
||||
@@ -418,6 +425,8 @@ struct LLSubpart
|
||||
LLVector3d mTargetOffset;
|
||||
LLVector3d mCameraOffset;
|
||||
ESex mSex;
|
||||
|
||||
bool mVisualHint;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -622,7 +631,7 @@ void LLPanelEditWearable::setSubpart( ESubpart subpart )
|
||||
llassert( sorted_params.find(-param->getDisplayOrder()) == sorted_params.end() ); // Check for duplicates
|
||||
sorted_params.insert(vt);
|
||||
}
|
||||
gFloaterCustomize->generateVisualParamHints(NULL, sorted_params);
|
||||
gFloaterCustomize->generateVisualParamHints(NULL, sorted_params, part->mVisualHint);
|
||||
gFloaterCustomize->updateScrollingPanelUI();
|
||||
gFloaterCustomize->childSetEnabled("Export", can_export);
|
||||
gFloaterCustomize->childSetEnabled("Import", can_import);
|
||||
@@ -926,6 +935,7 @@ ESubpart LLPanelEditWearable::getDefaultSubpart()
|
||||
case WT_SKIRT: return SUBPART_SKIRT;
|
||||
case WT_ALPHA: return SUBPART_ALPHA;
|
||||
case WT_TATTOO: return SUBPART_TATTOO;
|
||||
case WT_PHYSICS: return SUBPART_PHYSICS_BELLY_UPDOWN;
|
||||
|
||||
default: llassert(0); return SUBPART_SHAPE_WHOLE;
|
||||
}
|
||||
@@ -974,6 +984,7 @@ void LLPanelEditWearable::draw()
|
||||
for (std::map<ESubpart, LLSubpart*>::iterator iter = mSubpartList.begin();
|
||||
iter != mSubpartList.end(); ++iter)
|
||||
{
|
||||
childSetVisible(iter->second->mButtonName,has_wearable);
|
||||
if( has_wearable && is_complete && is_modifiable )
|
||||
{
|
||||
childSetEnabled(iter->second->mButtonName, iter->second->mSex & avatar->getSex() );
|
||||
@@ -993,6 +1004,8 @@ void LLPanelEditWearable::draw()
|
||||
|
||||
childSetVisible("path", FALSE);
|
||||
|
||||
LLTextBox *av_height = getChild<LLTextBox>("avheight",FALSE,FALSE);
|
||||
if(av_height) //Only display this if the element exists
|
||||
{
|
||||
// Display the shape's nominal height.
|
||||
//
|
||||
@@ -1006,8 +1019,8 @@ void LLPanelEditWearable::draw()
|
||||
std::ostringstream avheight(std::ostringstream::trunc);
|
||||
avheight << std::fixed << std::setprecision(2) << avsize << " m ("
|
||||
<< feet << "' " << inches << "\")";
|
||||
childSetVisible("avheight", TRUE);
|
||||
childSetTextArg("avheight", "[AVHEIGHT]", avheight.str());
|
||||
av_height->setVisible(TRUE);
|
||||
av_height->setTextArg("[AVHEIGHT]",avheight.str());
|
||||
}
|
||||
|
||||
if(has_wearable && !is_modifiable)
|
||||
@@ -1271,7 +1284,7 @@ void LLPanelEditWearable::setUIPermissions(U32 perm_mask, BOOL is_complete)
|
||||
class LLScrollingPanelParam : public LLScrollingPanel
|
||||
{
|
||||
public:
|
||||
LLScrollingPanelParam( const std::string& name, LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify );
|
||||
LLScrollingPanelParam( const std::string& name, LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, bool bVisualHint );
|
||||
virtual ~LLScrollingPanelParam();
|
||||
|
||||
virtual void draw();
|
||||
@@ -1299,6 +1312,9 @@ public:
|
||||
LLViewerVisualParam* mParam;
|
||||
LLPointer<LLVisualParamHint> mHintMin;
|
||||
LLPointer<LLVisualParamHint> mHintMax;
|
||||
LLButton* mLess;
|
||||
LLButton* mMore;
|
||||
|
||||
static S32 sUpdateDelayFrames;
|
||||
|
||||
protected:
|
||||
@@ -1319,51 +1335,68 @@ const S32 PARAM_PANEL_WIDTH = 2 * (3* BTN_BORDER + PARAM_HINT_WIDTH + LLPANEL_B
|
||||
const S32 PARAM_PANEL_HEIGHT = 2 * BTN_BORDER + PARAM_HINT_HEIGHT + PARAM_HINT_LABEL_HEIGHT + 4 * LLPANEL_BORDER_WIDTH;
|
||||
|
||||
LLScrollingPanelParam::LLScrollingPanelParam( const std::string& name,
|
||||
LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify )
|
||||
LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, bool bVisualHint )
|
||||
: LLScrollingPanel( name, LLRect( 0, PARAM_PANEL_HEIGHT, PARAM_PANEL_WIDTH, 0 ) ),
|
||||
mParam(param),
|
||||
mAllowModify(allow_modify)
|
||||
mAllowModify(allow_modify),
|
||||
mLess(NULL),
|
||||
mMore(NULL)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_scrolling_param.xml");
|
||||
|
||||
S32 pos_x = 2 * LLPANEL_BORDER_WIDTH;
|
||||
S32 pos_y = 3 * LLPANEL_BORDER_WIDTH + SLIDERCTRL_HEIGHT;
|
||||
F32 min_weight = param->getMinWeight();
|
||||
F32 max_weight = param->getMaxWeight();
|
||||
|
||||
mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, min_weight);
|
||||
pos_x += PARAM_HINT_WIDTH + 3 * BTN_BORDER;
|
||||
mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, max_weight );
|
||||
|
||||
mHintMin->setAllowsUpdates( FALSE );
|
||||
mHintMax->setAllowsUpdates( FALSE );
|
||||
childSetValue("param slider", weightToPercent(param->getWeight()));
|
||||
childSetLabelArg("param slider", "[DESC]", param->getDisplayName());
|
||||
childSetEnabled("param slider", mAllowModify);
|
||||
childSetCommitCallback("param slider", LLScrollingPanelParam::onSliderMoved, this);
|
||||
//Set up the slider
|
||||
LLSliderCtrl *slider = getChild<LLSliderCtrl>("param slider");
|
||||
slider->setValue(weightToPercent(param->getWeight()));
|
||||
slider->setLabelArg("[DESC]", param->getDisplayName());
|
||||
slider->setEnabled(mAllowModify);
|
||||
slider->setCommitCallback(LLScrollingPanelParam::onSliderMoved);
|
||||
slider->setCallbackUserData(this);
|
||||
|
||||
// *TODO::translate
|
||||
std::string min_name = param->getMinDisplayName();
|
||||
std::string max_name = param->getMaxDisplayName();
|
||||
childSetValue("min param text", min_name);
|
||||
childSetValue("max param text", max_name);
|
||||
|
||||
LLButton* less = getChild<LLButton>("less");
|
||||
if (less)
|
||||
if(bVisualHint)
|
||||
{
|
||||
less->setMouseDownCallback( LLScrollingPanelParam::onHintMinMouseDown );
|
||||
less->setMouseUpCallback( LLScrollingPanelParam::onHintMinMouseUp );
|
||||
less->setHeldDownCallback( LLScrollingPanelParam::onHintMinHeldDown );
|
||||
less->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
|
||||
S32 pos_x = 2 * LLPANEL_BORDER_WIDTH;
|
||||
S32 pos_y = 3 * LLPANEL_BORDER_WIDTH + SLIDERCTRL_HEIGHT;
|
||||
F32 min_weight = param->getMinWeight();
|
||||
F32 max_weight = param->getMaxWeight();
|
||||
|
||||
mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, min_weight);
|
||||
pos_x += PARAM_HINT_WIDTH + 3 * BTN_BORDER;
|
||||
mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, param, max_weight );
|
||||
|
||||
mHintMin->setAllowsUpdates( FALSE );
|
||||
mHintMax->setAllowsUpdates( FALSE );
|
||||
|
||||
// *TODO::translate
|
||||
std::string min_name = param->getMinDisplayName();
|
||||
std::string max_name = param->getMaxDisplayName();
|
||||
childSetValue("min param text", min_name);
|
||||
childSetValue("max param text", max_name);
|
||||
mLess = getChild<LLButton>("less");
|
||||
mLess->setMouseDownCallback( LLScrollingPanelParam::onHintMinMouseDown );
|
||||
mLess->setMouseUpCallback( LLScrollingPanelParam::onHintMinMouseUp );
|
||||
mLess->setHeldDownCallback( LLScrollingPanelParam::onHintMinHeldDown );
|
||||
mLess->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
|
||||
|
||||
mMore = getChild<LLButton>("more");
|
||||
mMore->setMouseDownCallback( LLScrollingPanelParam::onHintMaxMouseDown );
|
||||
mMore->setMouseUpCallback( LLScrollingPanelParam::onHintMaxMouseUp );
|
||||
mMore->setHeldDownCallback( LLScrollingPanelParam::onHintMaxHeldDown );
|
||||
mMore->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
|
||||
}
|
||||
|
||||
LLButton* more = getChild<LLButton>("more");
|
||||
if (more)
|
||||
else
|
||||
{
|
||||
more->setMouseDownCallback( LLScrollingPanelParam::onHintMaxMouseDown );
|
||||
more->setMouseUpCallback( LLScrollingPanelParam::onHintMaxMouseUp );
|
||||
more->setHeldDownCallback( LLScrollingPanelParam::onHintMaxHeldDown );
|
||||
more->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
|
||||
//Kill everything that isn't the slider...
|
||||
for(child_list_t::const_iterator it = getChildList()->begin();it!=getChildList()->end();)
|
||||
{
|
||||
if((*it)!=slider && (*it)->getName() != "panel border")
|
||||
{
|
||||
llinfos << "removing: " << (*it)->getName() << llendl;
|
||||
removeChild((*(it++)),TRUE);
|
||||
}
|
||||
else ++it;
|
||||
}
|
||||
slider->translate(0,PARAM_HINT_HEIGHT);
|
||||
reshape(getRect().getWidth(),getRect().getHeight()-PARAM_HINT_HEIGHT);
|
||||
}
|
||||
|
||||
setVisible(FALSE);
|
||||
@@ -1378,15 +1411,19 @@ LLScrollingPanelParam::~LLScrollingPanelParam()
|
||||
|
||||
void LLScrollingPanelParam::updatePanel(BOOL allow_modify)
|
||||
{
|
||||
LLViewerVisualParam* param = mHintMin->getVisualParam();
|
||||
childSetValue("param slider", weightToPercent( param->getWeight() ) );
|
||||
mHintMin->requestUpdate( sUpdateDelayFrames++ );
|
||||
mHintMax->requestUpdate( sUpdateDelayFrames++ );
|
||||
childSetValue("param slider", weightToPercent( mParam->getWeight() ) );
|
||||
if(mHintMin)
|
||||
mHintMin->requestUpdate( sUpdateDelayFrames++ );
|
||||
if(mHintMax)
|
||||
mHintMax->requestUpdate( sUpdateDelayFrames++ );
|
||||
|
||||
mAllowModify = allow_modify;
|
||||
childSetEnabled("param slider", mAllowModify);
|
||||
childSetEnabled("less", mAllowModify);
|
||||
childSetEnabled("more", mAllowModify);
|
||||
|
||||
if(mLess)
|
||||
mLess->setEnabled(mAllowModify);
|
||||
if(mMore)
|
||||
mMore->setEnabled(mAllowModify);
|
||||
}
|
||||
|
||||
void LLScrollingPanelParam::setVisible( BOOL visible )
|
||||
@@ -1394,13 +1431,17 @@ void LLScrollingPanelParam::setVisible( BOOL visible )
|
||||
if( getVisible() != visible )
|
||||
{
|
||||
LLPanel::setVisible( visible );
|
||||
mHintMin->setAllowsUpdates( visible );
|
||||
mHintMax->setAllowsUpdates( visible );
|
||||
if(mHintMin)
|
||||
mHintMin->setAllowsUpdates( visible );
|
||||
if(mHintMax)
|
||||
mHintMax->setAllowsUpdates( visible );
|
||||
|
||||
if( visible )
|
||||
{
|
||||
mHintMin->setUpdateDelayFrames( sUpdateDelayFrames++ );
|
||||
mHintMax->setUpdateDelayFrames( sUpdateDelayFrames++ );
|
||||
if(mHintMin)
|
||||
mHintMin->setUpdateDelayFrames( sUpdateDelayFrames++ );
|
||||
if(mHintMax)
|
||||
mHintMax->setUpdateDelayFrames( sUpdateDelayFrames++ );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1412,8 +1453,10 @@ void LLScrollingPanelParam::draw()
|
||||
return;
|
||||
}
|
||||
|
||||
childSetVisible("less", mHintMin->getVisible());
|
||||
childSetVisible("more", mHintMax->getVisible());
|
||||
if(mLess)
|
||||
mLess->setVisible(mHintMin ? mHintMin->getVisible() : false);
|
||||
if(mMore)
|
||||
mMore->setVisible(mHintMax ? mHintMax->getVisible() : false);
|
||||
|
||||
// Draw all the children except for the labels
|
||||
childSetVisible( "min param text", FALSE );
|
||||
@@ -1421,25 +1464,31 @@ void LLScrollingPanelParam::draw()
|
||||
LLPanel::draw();
|
||||
|
||||
// Draw the hints over the "less" and "more" buttons.
|
||||
glPushMatrix();
|
||||
if(mHintMin)
|
||||
{
|
||||
const LLRect& r = mHintMin->getRect();
|
||||
F32 left = (F32)(r.mLeft + BTN_BORDER);
|
||||
F32 bot = (F32)(r.mBottom + BTN_BORDER);
|
||||
glTranslatef(left, bot, 0.f);
|
||||
mHintMin->draw();
|
||||
glPushMatrix();
|
||||
{
|
||||
const LLRect& r = mHintMin->getRect();
|
||||
F32 left = (F32)(r.mLeft + BTN_BORDER);
|
||||
F32 bot = (F32)(r.mBottom + BTN_BORDER);
|
||||
glTranslatef(left, bot, 0.f);
|
||||
mHintMin->draw();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
if(mHintMax)
|
||||
{
|
||||
const LLRect& r = mHintMax->getRect();
|
||||
F32 left = (F32)(r.mLeft + BTN_BORDER);
|
||||
F32 bot = (F32)(r.mBottom + BTN_BORDER);
|
||||
glTranslatef(left, bot, 0.f);
|
||||
mHintMax->draw();
|
||||
glPushMatrix();
|
||||
{
|
||||
const LLRect& r = mHintMax->getRect();
|
||||
F32 left = (F32)(r.mLeft + BTN_BORDER);
|
||||
F32 bot = (F32)(r.mBottom + BTN_BORDER);
|
||||
glTranslatef(left, bot, 0.f);
|
||||
mHintMax->draw();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
// Draw labels on top of the buttons
|
||||
@@ -1684,6 +1733,8 @@ LLFloaterCustomize::LLFloaterCustomize()
|
||||
mNextStepAfterSaveCallback( NULL ),
|
||||
mNextStepAfterSaveUserdata( NULL )
|
||||
{
|
||||
memset(&mWearablePanelList[0],0,sizeof(char*)*WT_COUNT); //Initialize to 0
|
||||
|
||||
gSavedSettings.setU32("AvatarSex", (gAgent.getAvatarObject()->getSex() == SEX_MALE) );
|
||||
|
||||
mResetParams = new LLVisualParamReset();
|
||||
@@ -1708,6 +1759,7 @@ LLFloaterCustomize::LLFloaterCustomize()
|
||||
factory_map["Skirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_SKIRT) ) );
|
||||
factory_map["Alpha"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_ALPHA)));
|
||||
factory_map["Tattoo"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_TATTOO)));
|
||||
factory_map["Physics"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_PHYSICS)));
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map);
|
||||
}
|
||||
@@ -1741,6 +1793,7 @@ BOOL LLFloaterCustomize::postBuild()
|
||||
childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)WT_SKIRT, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Alpha", onTabChanged, (void*)WT_ALPHA, onTabPrecommit);
|
||||
childSetTabChangeCallback("customize tab container", "Tattoo", onTabChanged, (void*)WT_TATTOO, onTabPrecommit);
|
||||
childSetTabChangeCallback("customize tab container", "Physics", onTabChanged, (void*)WT_PHYSICS, onTabPrecommit);
|
||||
|
||||
// Remove underwear panels for teens
|
||||
if (gAgent.isTeen())
|
||||
@@ -2406,63 +2459,72 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Alpha
|
||||
panel = mWearablePanelList[WT_ALPHA];
|
||||
// Physics
|
||||
|
||||
if (panel)
|
||||
panel = mWearablePanelList[WT_PHYSICS];
|
||||
|
||||
if(panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "alpha";
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_breasts_updown";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_ALPHA, part);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Breast Bounce", SUBPART_PHYSICS_BREASTS_UPDOWN, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_ALPHA, "Lower Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_UPPER_ALPHA, "Upper Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HEAD_ALPHA, "Head Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_EYES_ALPHA, "Eye Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HAIR_ALPHA, "Hair Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_breasts_inout";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Breast Cleavage", SUBPART_PHYSICS_BREASTS_INOUT, part);
|
||||
|
||||
panel->addInvisibilityCheckbox(TEX_LOWER_ALPHA, "lower alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_UPPER_ALPHA, "upper alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_HEAD_ALPHA, "head alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_EYES_ALPHA, "eye alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_HAIR_ALPHA, "hair alpha texture invisible");
|
||||
}
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_breasts_leftright";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Breast Sway", SUBPART_PHYSICS_BREASTS_LEFTRIGHT, part);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Tattoo
|
||||
panel = mWearablePanelList[WT_TATTOO];
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_belly_updown";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -.05f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Belly Bounce", SUBPART_PHYSICS_BELLY_UPDOWN, part);
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "tattoo";
|
||||
part->mEditGroup = "physics_butt_updown";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.1f);
|
||||
part->mCameraOffset.setVec(0.3f, 0.8f, -0.1f);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Butt Bounce", SUBPART_PHYSICS_BUTT_UPDOWN, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "physics_butt_leftright";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.1f);
|
||||
part->mCameraOffset.setVec(0.3f, 0.8f, -0.1f);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Butt Sway", SUBPART_PHYSICS_BUTT_LEFTRIGHT, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_advanced";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_TATTOO, part);
|
||||
part->mVisualHint = false;
|
||||
panel->addSubpart("Advanced Parameters", SUBPART_PHYSICS_ADVANCED, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_TATTOO, "Lower Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_UPPER_TATTOO, "Upper Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HEAD_TATTOO, "Head Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2597,7 +2659,7 @@ void LLFloaterCustomize::clearScrollingPanelList()
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterCustomize::generateVisualParamHints(LLViewerJointMesh* joint_mesh, LLFloaterCustomize::param_map& params)
|
||||
void LLFloaterCustomize::generateVisualParamHints(LLViewerJointMesh* joint_mesh, LLFloaterCustomize::param_map& params, bool bVisualHint)
|
||||
{
|
||||
// sorted_params is sorted according to magnitude of effect from
|
||||
// least to greatest. Adding to the front of the child list
|
||||
@@ -2608,7 +2670,7 @@ void LLFloaterCustomize::generateVisualParamHints(LLViewerJointMesh* joint_mesh,
|
||||
param_map::iterator end = params.end();
|
||||
for(param_map::iterator it = params.begin(); it != end; ++it)
|
||||
{
|
||||
mScrollingPanelList->addPanel( new LLScrollingPanelParam( "LLScrollingPanelParam", joint_mesh, (*it).second.second, (*it).second.first) );
|
||||
mScrollingPanelList->addPanel( new LLScrollingPanelParam( "LLScrollingPanelParam", joint_mesh, (*it).second.second, (*it).second.first, bVisualHint) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
// New methods
|
||||
void clearScrollingPanelList();
|
||||
void generateVisualParamHints(LLViewerJointMesh* joint_mesh,
|
||||
param_map& params);
|
||||
param_map& params, bool bVisualHint);
|
||||
|
||||
const std::string& getEditGroup();
|
||||
void updateScrollingPanelList(BOOL allow_modify);
|
||||
|
||||
@@ -462,7 +462,11 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type,
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART);
|
||||
LLFolderBridge::createWearable(parent_id, WT_EYES);
|
||||
}
|
||||
|
||||
else if ("physics" == type)
|
||||
{
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
|
||||
LLFolderBridge::createWearable(parent_id, WT_PHYSICS);
|
||||
}
|
||||
ptr->getRootFolder()->setNeedsAutoRename(TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,8 @@ LLFilePicker::ESaveFilter LLInventoryBackup::getSaveFilter(LLInventoryItem* item
|
||||
return LLFilePicker::FFSAVE_UNDERPANTS;
|
||||
case WT_UNDERSHIRT:
|
||||
return LLFilePicker::FFSAVE_UNDERSHIRT;
|
||||
case WT_PHYSICS:
|
||||
return LLFilePicker::FFSAVE_PHYSICS;
|
||||
default:
|
||||
return LLFilePicker::FFSAVE_ALL;
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
|
||||
"inv_item_skirt.tga",
|
||||
"inv_item_alpha.tga",
|
||||
"inv_item_tattoo.tga",
|
||||
"inv_item_physics.png",
|
||||
|
||||
"inv_item_animation.tga",
|
||||
"inv_item_gesture.tga",
|
||||
@@ -2712,6 +2713,10 @@ void LLFolderBridge::createNewEyes(void* user_data)
|
||||
LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_EYES);
|
||||
}
|
||||
|
||||
void LLFolderBridge::createNewPhysics(void* user_data)
|
||||
{
|
||||
LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_PHYSICS);
|
||||
}
|
||||
// static
|
||||
void LLFolderBridge::createWearable(LLFolderBridge* bridge, EWearableType type)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,7 @@ enum EInventoryIcon
|
||||
CLOTHING_SKIRT_ICON_NAME,
|
||||
CLOTHING_ALPHA_ICON_NAME,
|
||||
CLOTHING_TATTOO_ICON_NAME,
|
||||
CLOTHING_PHYSICS_ICON_NAME,
|
||||
|
||||
ANIMATION_ICON_NAME,
|
||||
GESTURE_ICON_NAME,
|
||||
@@ -375,6 +376,7 @@ protected:
|
||||
static void createNewSkin(void* user_data);
|
||||
static void createNewHair(void* user_data);
|
||||
static void createNewEyes(void* user_data);
|
||||
static void createNewPhysics(void* user_data);
|
||||
|
||||
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
|
||||
|
||||
|
||||
@@ -1521,6 +1521,9 @@ std::string get_item_icon_name(LLAssetType::EType asset_type,
|
||||
case WT_TATTOO:
|
||||
idx = CLOTHING_TATTOO_ICON_NAME;
|
||||
break;
|
||||
case WT_PHYSICS:
|
||||
idx = CLOTHING_PHYSICS_ICON_NAME;
|
||||
break;
|
||||
default:
|
||||
// no-op, go with choice above
|
||||
break;
|
||||
|
||||
773
indra/newview/llphysicsmotion.cpp
Normal file
773
indra/newview/llphysicsmotion.cpp
Normal file
@@ -0,0 +1,773 @@
|
||||
/**
|
||||
* @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 "llagent.h"
|
||||
#include "llcharacter.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewervisualparam.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "lldriverparam.h"
|
||||
|
||||
typedef std::map<std::string, std::string> controller_map_t;
|
||||
typedef std::map<std::string, F32> default_controller_map_t;
|
||||
|
||||
#define MIN_REQUIRED_PIXEL_AREA_AVATAR_PHYSICS_MOTION 0.f
|
||||
#define TIME_ITERATION_STEP 0.1f
|
||||
|
||||
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<LLJointState> getJointState()
|
||||
{
|
||||
return mJointState;
|
||||
}
|
||||
|
||||
void reset();
|
||||
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 behavior_maxeffect);
|
||||
|
||||
F32 toLocal(const LLVector3 &world);
|
||||
F32 calculateVelocity_local();
|
||||
F32 calculateAcceleration_local(F32 velocity_local);
|
||||
|
||||
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<LLJointState> 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),
|
||||
mIsDefault(true)
|
||||
{
|
||||
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_AVATAR_PHYSICS_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 world_to_model_scale = 100.0f;
|
||||
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 positionchange_world = (position_world-last_position_world) * world_to_model_scale;
|
||||
const LLVector3 velocity_world = positionchange_world;
|
||||
const F32 velocity_local = toLocal(velocity_world);
|
||||
return velocity_local;
|
||||
}
|
||||
|
||||
F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local)
|
||||
{
|
||||
// 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.
|
||||
static const LLCachedControl<bool> avatar_physics("AvatarPhysics",false);
|
||||
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();
|
||||
}
|
||||
((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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// Don't update too frequently, to avoid precision errors from small time slices.
|
||||
if (time_delta <= .01)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If less than 1FPS, we don't want to be spending time updating physics at all.
|
||||
if (time_delta > 1.0)
|
||||
{
|
||||
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 = FALSE; // Enable this to simulate bouncing on all parts.
|
||||
|
||||
F32 behavior_maxeffect = getParamValue("MaxEffect");
|
||||
if (physics_test)
|
||||
behavior_maxeffect = 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.
|
||||
const F32 position_user_local = (mParamDriver->getWeight() - mParamDriver->getMinWeight()) / (mParamDriver->getMaxWeight() - mParamDriver->getMinWeight());
|
||||
|
||||
//
|
||||
// End parameters and settings
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Calculate velocity and acceleration in parameter space.
|
||||
//
|
||||
|
||||
//const F32 velocity_joint_local = calculateVelocity_local(time_iteration_step);
|
||||
const F32 velocity_joint_local = calculateVelocity_local();
|
||||
const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local);
|
||||
|
||||
//
|
||||
// End velocity and acceleration
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL update_visuals = FALSE;
|
||||
|
||||
// Break up the physics into a bunch of iterations so that differing framerates will show
|
||||
// roughly the same behavior.
|
||||
for (F32 time_iteration = 0; time_iteration <= time_delta; time_iteration += TIME_ITERATION_STEP)
|
||||
{
|
||||
F32 time_iteration_step = TIME_ITERATION_STEP;
|
||||
if (time_iteration + TIME_ITERATION_STEP > time_delta)
|
||||
{
|
||||
time_iteration_step = time_delta-time_iteration;
|
||||
}
|
||||
|
||||
// mPositon_local should be in normalized 0,1 range already. Just making sure...
|
||||
const F32 position_current_local = llclamp(mPosition_local,
|
||||
0.0f,
|
||||
1.0f);
|
||||
// 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 update_visuals;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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 = (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_velocity = 100.0f; // magic number, used to be customizable.
|
||||
F32 velocity_new_local = mVelocity_local + acceleration_new_local*time_iteration_step;
|
||||
velocity_new_local = llclamp(velocity_new_local,
|
||||
-max_velocity, max_velocity);
|
||||
|
||||
// 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_iteration_step;
|
||||
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 && velocity_new_local < 0) ||
|
||||
(position_new_local > 1 && velocity_new_local > 0))
|
||||
{
|
||||
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;
|
||||
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,
|
||||
0.0f,
|
||||
1.0f);
|
||||
|
||||
LLDriverParam *driver_param = dynamic_cast<LLDriverParam *>(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, behavior_maxeffect);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End calculate new params
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Conditionally update the visual params
|
||||
//
|
||||
|
||||
// Updating the visual params (i.e. what the user sees) is fairly expensive.
|
||||
// So only update if the params have changed enough, and also take into account
|
||||
// the graphics LOD settings.
|
||||
|
||||
// For non-self, if the avatar is small enough visually, then don't update.
|
||||
const 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<LLVOAvatar *>(mCharacter) != NULL && ((LLVOAvatar*)mCharacter)->isSelf());
|
||||
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.0001f-lod_factor)*0.4f;
|
||||
if (llabs(position_diff_local) > min_delta)
|
||||
{
|
||||
update_visuals = TRUE;
|
||||
mPositionLastUpdate_local = position_new_local;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End update visual params
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mVelocity_local = velocity_new_local;
|
||||
mAccelerationJoint_local = acceleration_joint_local;
|
||||
mPosition_local = position_new_local;
|
||||
}
|
||||
mLastTime = time;
|
||||
mPosition_world = joint->getWorldPosition();
|
||||
mVelocityJoint_local = velocity_joint_local;
|
||||
|
||||
|
||||
/*
|
||||
// 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 behavior_maxeffect)
|
||||
{
|
||||
const F32 value_min_local = param->getMinWeight();
|
||||
const F32 value_max_local = param->getMaxWeight();
|
||||
const F32 min_val = 0.5f-behavior_maxeffect/2.0;
|
||||
const F32 max_val = 0.5f+behavior_maxeffect/2.0;
|
||||
|
||||
// Scale from [0,1] to [min_val,max_val]
|
||||
const F32 new_value_rescaled = min_val + (max_val-min_val) * new_value_normalized;
|
||||
|
||||
// Scale from [0,1] to [value_min_local,value_max_local]
|
||||
const F32 new_value_local = value_min_local + (value_max_local-value_min_local) * new_value_rescaled;
|
||||
|
||||
mCharacter->setVisualParamWeight(param,
|
||||
new_value_local,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
void LLPhysicsMotion::reset()
|
||||
{
|
||||
LLDriverParam *driver_param = dynamic_cast<LLDriverParam *>(mParamDriver);
|
||||
if (driver_param)
|
||||
{
|
||||
if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) &&
|
||||
(driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT))
|
||||
{
|
||||
mCharacter->setVisualParamWeight(driver_param,driver_param->getDefaultWeight());
|
||||
}
|
||||
for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin();
|
||||
iter != driver_param->mDriven.end();++iter)
|
||||
{
|
||||
mCharacter->setVisualParamWeight((*iter).mParam,(*iter).mParam->getDefaultWeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
125
indra/newview/llphysicsmotion.h
Normal file
125
indra/newview/llphysicsmotion.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @file llphysicsmotion.h
|
||||
* @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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPHYSICSMOTIONCONTROLLER_H
|
||||
#define LL_LLPHYSICSMOTIONCONTROLLER_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Header files
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "llmotion.h"
|
||||
#include "llframetimer.h"
|
||||
|
||||
#define PHYSICS_MOTION_FADEIN_TIME 1.0f
|
||||
#define PHYSICS_MOTION_FADEOUT_TIME 1.0f
|
||||
|
||||
class LLPhysicsMotion;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class LLPhysicsMotion
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLPhysicsMotionController :
|
||||
public LLMotion
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
LLPhysicsMotionController(const LLUUID &id);
|
||||
|
||||
// Destructor
|
||||
virtual ~LLPhysicsMotionController();
|
||||
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
// functions to support MotionController and MotionRegistry
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// static constructor
|
||||
// all subclasses must implement such a function and register it
|
||||
static LLMotion *create(const LLUUID &id) { return new LLPhysicsMotionController(id); }
|
||||
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
// animation callbacks to be implemented by subclasses
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// motions must specify whether or not they loop
|
||||
virtual BOOL getLoop() { return TRUE; }
|
||||
|
||||
// motions must report their total duration
|
||||
virtual F32 getDuration() { return 0.0; }
|
||||
|
||||
// motions must report their "ease in" duration
|
||||
virtual F32 getEaseInDuration() { return PHYSICS_MOTION_FADEIN_TIME; }
|
||||
|
||||
// motions must report their "ease out" duration.
|
||||
virtual F32 getEaseOutDuration() { return PHYSICS_MOTION_FADEOUT_TIME; }
|
||||
|
||||
// called to determine when a motion should be activated/deactivated based on avatar pixel coverage
|
||||
virtual F32 getMinPixelArea();
|
||||
|
||||
// motions must report their priority
|
||||
virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; }
|
||||
|
||||
virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; }
|
||||
|
||||
// run-time (post constructor) initialization,
|
||||
// called after parameters have been set
|
||||
// must return true to indicate success and be available for activation
|
||||
virtual LLMotionInitStatus onInitialize(LLCharacter *character);
|
||||
|
||||
// called when a motion is activated
|
||||
// must return TRUE to indicate success, or else
|
||||
// it will be deactivated
|
||||
virtual BOOL onActivate();
|
||||
|
||||
// called per time step
|
||||
// must return TRUE while it is active, and
|
||||
// must return FALSE when the motion is completed.
|
||||
virtual BOOL onUpdate(F32 time, U8* joint_mask);
|
||||
|
||||
// called when a motion is deactivated
|
||||
virtual void onDeactivate();
|
||||
|
||||
LLCharacter* getCharacter() { return mCharacter; }
|
||||
protected:
|
||||
void addMotion(LLPhysicsMotion *motion);
|
||||
private:
|
||||
LLCharacter* mCharacter;
|
||||
|
||||
typedef std::vector<LLPhysicsMotion *> motion_vec_t;
|
||||
motion_vec_t mMotions;
|
||||
|
||||
bool mIsDefault;
|
||||
};
|
||||
|
||||
#endif // LL_LLPHYSICSMOTION_H
|
||||
|
||||
@@ -49,7 +49,16 @@
|
||||
#define HEADER_ASCII "Linden Mesh 1.0"
|
||||
#define HEADER_BINARY "Linden Binary Mesh 1.0"
|
||||
|
||||
extern LLControlGroup gSavedSettings; // read only
|
||||
extern LLControlGroup gSavedSettings; // read only
|
||||
|
||||
LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
|
||||
const std::string &name);
|
||||
LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
|
||||
const LLVector3 &direction,
|
||||
const std::string &name);
|
||||
LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
|
||||
F32 scale,
|
||||
const std::string &name);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Global table of loaded LLPolyMeshes
|
||||
@@ -606,8 +615,60 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
|
||||
continue;
|
||||
}
|
||||
|
||||
mMorphData.insert(morph_data);
|
||||
}
|
||||
mMorphData.insert(morph_data);
|
||||
|
||||
if (!strcmp(morphName, "Breast_Female_Cleavage"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_cleavage(morph_data,
|
||||
.75f,
|
||||
"Breast_Physics_LeftRight_Driven"));
|
||||
}
|
||||
|
||||
if (!strcmp(morphName, "Breast_Female_Cleavage"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_duplicate(morph_data,
|
||||
"Breast_Physics_InOut_Driven"));
|
||||
}
|
||||
if (!strcmp(morphName, "Breast_Gravity"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_duplicate(morph_data,
|
||||
"Breast_Physics_UpDown_Driven"));
|
||||
}
|
||||
|
||||
if (!strcmp(morphName, "Big_Belly_Torso"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_direction(morph_data,
|
||||
LLVector3(0,0,0.05f),
|
||||
"Belly_Physics_Torso_UpDown_Driven"));
|
||||
}
|
||||
|
||||
if (!strcmp(morphName, "Big_Belly_Legs"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_direction(morph_data,
|
||||
LLVector3(0,0,0.05f),
|
||||
"Belly_Physics_Legs_UpDown_Driven"));
|
||||
}
|
||||
|
||||
if (!strcmp(morphName, "skirt_belly"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_direction(morph_data,
|
||||
LLVector3(0,0,0.05f),
|
||||
"Belly_Physics_Skirt_UpDown_Driven"));
|
||||
}
|
||||
|
||||
if (!strcmp(morphName, "Small_Butt"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_direction(morph_data,
|
||||
LLVector3(0,0,0.05f),
|
||||
"Butt_Physics_UpDown_Driven"));
|
||||
}
|
||||
if (!strcmp(morphName, "Small_Butt"))
|
||||
{
|
||||
mMorphData.insert(clone_morph_param_direction(morph_data,
|
||||
LLVector3(0,0.03f,0),
|
||||
"Butt_Physics_LeftRight_Driven"));
|
||||
}
|
||||
}
|
||||
|
||||
S32 numRemaps;
|
||||
if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
|
||||
@@ -1156,4 +1217,55 @@ void LLPolySkeletalDistortion::apply( ESex avatar_sex )
|
||||
mLastWeight = mCurWeight;
|
||||
}
|
||||
|
||||
|
||||
LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
|
||||
const std::string &name)
|
||||
{
|
||||
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
|
||||
cloned_morph_data->mName = name;
|
||||
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
|
||||
{
|
||||
cloned_morph_data->mCoords[v] = src_data->mCoords[v];
|
||||
cloned_morph_data->mNormals[v] = src_data->mNormals[v];
|
||||
cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
|
||||
}
|
||||
return cloned_morph_data;
|
||||
}
|
||||
|
||||
LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
|
||||
const LLVector3 &direction,
|
||||
const std::string &name)
|
||||
{
|
||||
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
|
||||
cloned_morph_data->mName = name;
|
||||
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
|
||||
{
|
||||
cloned_morph_data->mCoords[v] = direction;
|
||||
cloned_morph_data->mNormals[v] = LLVector3(0,0,0);
|
||||
cloned_morph_data->mBinormals[v] = LLVector3(0,0,0);
|
||||
}
|
||||
return cloned_morph_data;
|
||||
}
|
||||
|
||||
LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
|
||||
F32 scale,
|
||||
const std::string &name)
|
||||
{
|
||||
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
|
||||
cloned_morph_data->mName = name;
|
||||
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
|
||||
{
|
||||
cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale;
|
||||
cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale;
|
||||
cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale;
|
||||
if (cloned_morph_data->mCoords[v][1] < 0)
|
||||
{
|
||||
cloned_morph_data->mCoords[v][1] *= -1;
|
||||
cloned_morph_data->mNormals[v][1] *= -1;
|
||||
cloned_morph_data->mBinormals[v][1] *= -1;
|
||||
}
|
||||
}
|
||||
return cloned_morph_data;
|
||||
}
|
||||
|
||||
// End
|
||||
|
||||
@@ -64,6 +64,36 @@ LLPolyMorphData::LLPolyMorphData(const std::string& morph_name)
|
||||
mMesh = NULL;
|
||||
}
|
||||
|
||||
LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
|
||||
mName(rhs.mName),
|
||||
mNumIndices(rhs.mNumIndices),
|
||||
mTotalDistortion(rhs.mTotalDistortion),
|
||||
mAvgDistortion(rhs.mAvgDistortion),
|
||||
mMaxDistortion(rhs.mMaxDistortion),
|
||||
mVertexIndices(NULL),
|
||||
mCoords(NULL),
|
||||
mNormals(NULL),
|
||||
mBinormals(NULL),
|
||||
mTexCoords(NULL)
|
||||
{
|
||||
const S32 numVertices = mNumIndices;
|
||||
|
||||
mCoords = new LLVector3[numVertices];
|
||||
mNormals = new LLVector3[numVertices];
|
||||
mBinormals = new LLVector3[numVertices];
|
||||
mTexCoords = new LLVector2[numVertices];
|
||||
mVertexIndices = new U32[numVertices];
|
||||
|
||||
for (S32 v=0; v < numVertices; v++)
|
||||
{
|
||||
mCoords[v] = rhs.mCoords[v];
|
||||
mNormals[v] = rhs.mNormals[v];
|
||||
mBinormals[v] = rhs.mBinormals[v];
|
||||
mTexCoords[v] = rhs.mTexCoords[v];
|
||||
mVertexIndices[v] = rhs.mVertexIndices[v];
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~LLPolyMorphData()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -292,10 +322,22 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
|
||||
}
|
||||
}
|
||||
|
||||
mMorphData = mMesh->getMorphData(getInfo()->mMorphName);
|
||||
std::string morph_param_name = getInfo()->mMorphName;
|
||||
|
||||
mMorphData = mMesh->getMorphData(morph_param_name);
|
||||
if (!mMorphData)
|
||||
{
|
||||
llwarns << "No morph target named " << getInfo()->mMorphName << " found in mesh." << llendl;
|
||||
const std::string driven_tag = "_Driven";
|
||||
U32 pos = morph_param_name.find(driven_tag);
|
||||
if (pos > 0)
|
||||
{
|
||||
morph_param_name = morph_param_name.substr(0,pos);
|
||||
mMorphData = mMesh->getMorphData(morph_param_name);
|
||||
}
|
||||
}
|
||||
if (!mMorphData)
|
||||
{
|
||||
llwarns << "No morph target named " << morph_param_name << " found in mesh." << llendl;
|
||||
return FALSE; // Continue, ignoring this tag
|
||||
}
|
||||
return TRUE;
|
||||
@@ -445,6 +487,16 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
||||
|
||||
mLastSex = avatar_sex;
|
||||
|
||||
// Check for NaN condition (NaN is detected if a variable doesn't equal itself.
|
||||
if (mCurWeight != mCurWeight)
|
||||
{
|
||||
mCurWeight = 0.0;
|
||||
}
|
||||
if (mLastWeight != mLastWeight)
|
||||
{
|
||||
mLastWeight = mCurWeight+.001;
|
||||
}
|
||||
|
||||
// perform differential update of morph
|
||||
F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight);
|
||||
// store last weight
|
||||
|
||||
@@ -51,6 +51,7 @@ class LLPolyMorphData
|
||||
public:
|
||||
LLPolyMorphData(const std::string& morph_name);
|
||||
~LLPolyMorphData();
|
||||
LLPolyMorphData(const LLPolyMorphData &rhs);
|
||||
|
||||
BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh);
|
||||
const std::string& getName() { return mName; }
|
||||
|
||||
@@ -915,10 +915,12 @@ void LLTextureCache::purgeCache(ELLPath location)
|
||||
if(LLFile::isdir(mTexturesDirName))
|
||||
{
|
||||
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
|
||||
LLAPRFile::remove(file_name);
|
||||
if(LLAPRFile::isExist(file_name))
|
||||
LLAPRFile::remove(file_name);
|
||||
|
||||
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
|
||||
LLAPRFile::remove(file_name);
|
||||
if(LLAPRFile::isExist(file_name))
|
||||
LLAPRFile::remove(file_name);
|
||||
|
||||
purgeAllTextures(true);
|
||||
}
|
||||
@@ -1711,7 +1713,8 @@ void LLTextureCache::purgeTextureFilesTimeSliced(bool force)
|
||||
if (mHeaderIDMap.find(curiter->first) == mHeaderIDMap.end())
|
||||
{
|
||||
filename = curiter->second;
|
||||
LLAPRFile::remove(filename);
|
||||
if(LLAPRFile::isExist(filename))
|
||||
LLAPRFile::remove(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1963,7 +1966,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename, b
|
||||
mFreeList.insert(idx);
|
||||
}
|
||||
|
||||
if (remove_file)
|
||||
if (remove_file && LLAPRFile::isExist(filename))
|
||||
{
|
||||
LLAPRFile::remove(filename);
|
||||
}
|
||||
|
||||
@@ -216,6 +216,12 @@ static bool handleAvatarLODChanged(const LLSD& newvalue)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue)
|
||||
{
|
||||
LLVOAvatar::sLODFactor = (F32) newvalue.asReal();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleAvatarMaxVisibleChanged(const LLSD& newvalue)
|
||||
{
|
||||
LLVOAvatar::sMaxVisible = (U32) newvalue.asInteger();
|
||||
@@ -583,6 +589,7 @@ void settings_setup_listeners()
|
||||
gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1));
|
||||
gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1));
|
||||
gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _1));
|
||||
gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _1));
|
||||
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));
|
||||
|
||||
@@ -3913,6 +3913,7 @@ class LLEditEnableCustomizeAvatar : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class LLEditEnableChangeDisplayname : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
@@ -8894,6 +8895,10 @@ class LLEditEnableTakeOff : public view_listener_t
|
||||
{
|
||||
new_value = LLAgent::selfHasWearable((void *)WT_TATTOO);
|
||||
}
|
||||
if (clothing == "physics")
|
||||
{
|
||||
new_value = LLAgent::selfHasWearable((void *)WT_PHYSICS);
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b | OK
|
||||
// Why aren't they using LLWearable::typeNameToType()? *confuzzled*
|
||||
@@ -8957,6 +8962,10 @@ class LLEditTakeOff : public view_listener_t
|
||||
{
|
||||
LLAgent::userRemoveWearable((void*)WT_TATTOO);
|
||||
}
|
||||
else if (clothing == "physics")
|
||||
{
|
||||
LLAgent::userRemoveWearable((void*)WT_PHYSICS);
|
||||
}
|
||||
else if (clothing == "all")
|
||||
{
|
||||
LLAgent::userRemoveAllClothes(NULL);
|
||||
|
||||
@@ -103,6 +103,8 @@
|
||||
#include "llavatarname.h"
|
||||
#include "llavatarnamecache.h"
|
||||
|
||||
#include "llphysicsmotion.h"
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c)
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
@@ -128,6 +130,7 @@ const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"
|
||||
const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix"
|
||||
const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target"
|
||||
const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust"
|
||||
const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -720,6 +723,7 @@ BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
|
||||
BOOL LLVOAvatar::sShowFootPlane = FALSE;
|
||||
BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
|
||||
F32 LLVOAvatar::sLODFactor = 1.f;
|
||||
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
|
||||
BOOL LLVOAvatar::sUseImpostors = FALSE;
|
||||
BOOL LLVOAvatar::sJointDebug = FALSE;
|
||||
|
||||
@@ -791,7 +795,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
||||
mFullyLoadedInitialized(FALSE),
|
||||
mHasBakedHair( FALSE ),
|
||||
mSupportsAlphaLayers(FALSE),
|
||||
mFirstSetActualBoobGravRan( false )
|
||||
mFirstSetActualBoobGravRan( false ),
|
||||
mSupportsPhysics( false )
|
||||
//mFirstSetActualButtGravRan( false ),
|
||||
//mFirstSetActualFatGravRan( false )
|
||||
// <edit>
|
||||
@@ -1016,6 +1021,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
||||
// motions without a start/stop bit
|
||||
registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create );
|
||||
registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create );
|
||||
registerMotion( ANIM_AGENT_PHYSICS_MOTION, LLPhysicsMotionController::create );
|
||||
registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create );
|
||||
registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create );
|
||||
registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create );
|
||||
@@ -1970,6 +1976,7 @@ void LLVOAvatar::startDefaultMotions()
|
||||
startMotion( ANIM_AGENT_EYE );
|
||||
startMotion( ANIM_AGENT_BODY_NOISE );
|
||||
startMotion( ANIM_AGENT_BREATHE_ROT );
|
||||
startMotion( ANIM_AGENT_PHYSICS_MOTION );
|
||||
startMotion( ANIM_AGENT_HAND_MOTION );
|
||||
startMotion( ANIM_AGENT_PELVIS_FIX );
|
||||
|
||||
@@ -2791,7 +2798,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
idleUpdateAppearanceAnimation();
|
||||
if (detailed_update)
|
||||
{
|
||||
idleUpdateBoobEffect();
|
||||
//idleUpdateBoobEffect();
|
||||
idleUpdateLipSync( voice_enabled );
|
||||
idleUpdateLoadingEffect();
|
||||
idleUpdateBelowWater(); // wind effect uses this
|
||||
@@ -9151,6 +9158,13 @@ void LLVOAvatar::wearableUpdated(EWearableType type, BOOL upload_result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Physics type has no associated baked textures, but change of params needs to be sent to
|
||||
// other avatars.
|
||||
if (isSelf() && type == WT_PHYSICS)
|
||||
{
|
||||
gAgent.sendAgentSetAppearance();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9355,6 +9369,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
|
||||
|
||||
updateMeshTextures(); // enables updates for laysets without baked textures.
|
||||
|
||||
mSupportsPhysics = false;
|
||||
|
||||
// parse visual params
|
||||
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
|
||||
if( num_blocks > 1 )
|
||||
@@ -9387,6 +9403,10 @@ 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() == 10000)
|
||||
{
|
||||
mSupportsPhysics = true;
|
||||
}
|
||||
if(param->getID() == 507 && newWeight != getActualBoobGrav())
|
||||
{
|
||||
llwarns << "Boob Grav SET to " << newWeight << " for " << getFullname() << llendl;
|
||||
@@ -9431,6 +9451,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
|
||||
{
|
||||
if (param->getName() == "tattoo_red")
|
||||
llinfos << getFullname() << " does not have tattoo tinting." << llendl;
|
||||
else if(param->getName() == "breast_physics_leftright_spring")
|
||||
llinfos << getFullname() << " does not have avatar physics." << llendl;
|
||||
else
|
||||
llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file for " << getFullname() << " (Prematurely reached end of list at " << param->getName() << ")." << llendl;
|
||||
//return; //ASC-TTRFE
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
extern const LLUUID ANIM_AGENT_BODY_NOISE;
|
||||
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
|
||||
extern const LLUUID ANIM_AGENT_PHYSICS_MOTION;
|
||||
extern const LLUUID ANIM_AGENT_EDITING;
|
||||
extern const LLUUID ANIM_AGENT_EYE;
|
||||
extern const LLUUID ANIM_AGENT_FLY_ADJUST;
|
||||
@@ -98,6 +99,9 @@ public:
|
||||
void getClientInfo(std::string& clientTag, LLColor4& tagColor, BOOL useComment=FALSE);
|
||||
std::string extraMetadata;
|
||||
// </edit>
|
||||
|
||||
// EmeraldBoobUtils
|
||||
bool mSupportsPhysics; //Client supports v2 wearable physics. Disable emerald physics.
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// LLViewerObject interface
|
||||
@@ -629,6 +633,7 @@ public:
|
||||
static BOOL sDebugInvisible;
|
||||
static BOOL sShowAttachmentPoints;
|
||||
static F32 sLODFactor; // user-settable LOD factor
|
||||
static F32 sPhysicsLODFactor; // user-settable physics LOD factor
|
||||
static BOOL sJointDebug; // output total number of joints being touched for each avatar
|
||||
static BOOL sDebugAvatarRotation;
|
||||
static F32 sAvMorphTime;
|
||||
|
||||
@@ -72,6 +72,7 @@ const std::string LLWearable::sTypeName[ WT_COUNT+1 ] =
|
||||
"skirt",
|
||||
"alpha",
|
||||
"tattoo",
|
||||
"physics",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
@@ -93,6 +94,7 @@ const std::string LLWearable::sTypeLabel[ WT_COUNT+1 ] =
|
||||
"Skirt",
|
||||
"Alpha",
|
||||
"Tattoo",
|
||||
"Physics",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
@@ -118,6 +120,7 @@ LLAssetType::EType LLWearable::typeToAssetType(EWearableType wearable_type)
|
||||
case WT_SKIRT:
|
||||
case WT_ALPHA:
|
||||
case WT_TATTOO:
|
||||
case WT_PHYSICS:
|
||||
return LLAssetType::AT_CLOTHING;
|
||||
default:
|
||||
return LLAssetType::AT_NONE;
|
||||
|
||||
@@ -58,7 +58,8 @@ enum EWearableType // If you change this, update LLWearable::getTypeName(), get
|
||||
WT_SKIRT = 12,
|
||||
WT_ALPHA = 13,
|
||||
WT_TATTOO = 14,
|
||||
WT_COUNT = 15,
|
||||
WT_PHYSICS = 15,
|
||||
WT_COUNT = 16,
|
||||
WT_INVALID = 255
|
||||
};
|
||||
|
||||
|
||||
@@ -1993,7 +1993,7 @@ ERlvCmdRet RlvHandler::onGetOutfit(const RlvCommand& rlvCmd, std::string& strRep
|
||||
const EWearableType wtRlvTypes[] =
|
||||
{
|
||||
WT_GLOVES, WT_JACKET, WT_PANTS, WT_SHIRT, WT_SHOES, WT_SKIRT, WT_SOCKS,
|
||||
WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE, WT_ALPHA, WT_TATTOO
|
||||
WT_UNDERPANTS, WT_UNDERSHIRT, WT_SKIN, WT_EYES, WT_HAIR, WT_SHAPE, WT_ALPHA, WT_TATTOO, WT_PHYSICS
|
||||
};
|
||||
|
||||
for (int idxType = 0, cntType = sizeof(wtRlvTypes) / sizeof(EWearableType); idxType < cntType; idxType++)
|
||||
|
||||
BIN
indra/newview/skins/default/textures/inv_item_physics.png
Normal file
BIN
indra/newview/skins/default/textures/inv_item_physics.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 539 B |
@@ -1298,11 +1298,103 @@ scratch and wear it.
|
||||
<button name="Revert" label="Revert" label_selected="Revert"
|
||||
follows="right|bottom" width="82" height="20" left="305" bottom="-478"/>
|
||||
</panel>
|
||||
<panel border="true" bottom="-482" follows="left|top|right|bottom" height="481"
|
||||
label="Physics" left="102" mouse_opaque="true" name="Physics" width="389">
|
||||
<icon bottom="-21" color="1 1 1 1" follows="top|right" height="16"
|
||||
image_name="icon_lock.tga" left="333" mouse_opaque="true" name="square"
|
||||
width="16" />
|
||||
<icon bottom="-24" color="1 1 1 1" follows="left|top" height="16" left="8"
|
||||
mouse_opaque="true" name="icon" width="16" />
|
||||
<button bottom="-81" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Belly Bounce" label_selected="Belly Bounce" left="8"
|
||||
mouse_opaque="true" name="Belly Bounce" scale_image="true" width="82" />
|
||||
<button bottom="-113" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Breast Bounce" label_selected="Breast Bounce" left="8"
|
||||
mouse_opaque="true" name="Breast Bounce" scale_image="true" width="82" />
|
||||
<button bottom="-145" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Breast Cleavage" label_selected="Breast Cleavage" left="8"
|
||||
mouse_opaque="true" name="Breast Cleavage" scale_image="true" width="82" />
|
||||
<button bottom="-177" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Breast Sway" label_selected="Breast Sway" left="8"
|
||||
mouse_opaque="true" name="Breast Sway" scale_image="true" width="82" />
|
||||
<button bottom="-209" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Butt Bounce" label_selected="Butt Bounce" left="8"
|
||||
mouse_opaque="true" name="Butt Bounce" scale_image="true" width="82" />
|
||||
<button bottom="-241" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Butt Sway" label_selected="Butt Sway" left="8"
|
||||
mouse_opaque="true" name="Butt Sway" scale_image="true" width="82" />
|
||||
<button bottom="-273" follows="left|top" font="SansSerifSmall" halign="center"
|
||||
height="16" label="Advanced Parameters" label_selected="Advanced Parameters" left="8"
|
||||
mouse_opaque="true" name="Advanced Parameters" scale_image="true" width="82" />
|
||||
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title" v_pad="0" width="355">
|
||||
[DESC]
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_no_modify" v_pad="0" width="355">
|
||||
[DESC]: cannot modify
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_loading" v_pad="0" width="355">
|
||||
[DESC]: loading...
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_not_worn" v_pad="0" width="355">
|
||||
[DESC]: not worn
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-38" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="14" left="8"
|
||||
mouse_opaque="true" name="path" v_pad="0" width="373">
|
||||
Located in [PATH]
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-74" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8"
|
||||
mouse_opaque="true" name="not worn instructions" v_pad="0" width="373">
|
||||
Put on a new physics wearable by dragging one from your inventory
|
||||
to your avatar. Alternately, you create a new one from
|
||||
scratch and wear it.
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-74" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8"
|
||||
mouse_opaque="true" name="no modify instructions" v_pad="0" width="373">
|
||||
You do not have permission to modify this wearable.
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-486" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="right" height="28" right="117"
|
||||
mouse_opaque="true" name="Item Action Label" v_pad="0" width="100">
|
||||
Physics:
|
||||
</text>
|
||||
<button bottom="-128" follows="left|top" halign="center" height="24"
|
||||
label="Create New Physics" label_selected="Create New Physics" left="8"
|
||||
mouse_opaque="true" name="Create New" scale_image="true" width="170" />
|
||||
<button bottom="-478" follows="right|bottom" font="SansSerif" halign="center"
|
||||
height="20" label="Save" label_selected="Save" left="123"
|
||||
mouse_opaque="true" name="Save" scale_image="true" width="82" />
|
||||
<button bottom="-478" follows="right|bottom" font="SansSerif" halign="center"
|
||||
height="20" label="Save As..." label_selected="Save As..." left="209"
|
||||
mouse_opaque="true" name="Save As" scale_image="true" width="92" />
|
||||
<button bottom="-478" follows="right|bottom" font="SansSerif" halign="center"
|
||||
height="20" label="Revert" label_selected="Revert" left="305"
|
||||
mouse_opaque="true" name="Revert" scale_image="true" width="82" />
|
||||
</panel>
|
||||
</tab_container>
|
||||
<scroll_container bottom="-476" follows="left|top|right|bottom" height="382" left="197"
|
||||
mouse_opaque="false" name="panel_container" opaque="false" width="292" />
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-400" drop_shadow_visible="true" follows="left|top"
|
||||
bottom="-410" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16"
|
||||
left="8" mouse_opaque="true" name="AvatarHeightText" v_pad="0" width="140">
|
||||
Avatar Height:
|
||||
|
||||
@@ -160,6 +160,10 @@
|
||||
mouse_opaque="true" name="New Alpha" width="125">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="alpha" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="New Physics" left="0"
|
||||
mouse_opaque="true" name="New Physics" width="125">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="physics" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu bottom_delta="-599" drop_shadow="true" height="85" left="0"
|
||||
mouse_opaque="false" name="New Body Parts" opaque="true" width="118">
|
||||
|
||||
@@ -96,6 +96,10 @@
|
||||
mouse_opaque="true" name="New Alpha" width="128">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="alpha" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="New Physics" left="0"
|
||||
mouse_opaque="true" name="New Physics" width="128">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="physics" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu bottom_delta="0" color="MenuDefaultBgColor" drop_shadow="true" height="175" left="0"
|
||||
mouse_opaque="false" name="New Body Parts" opaque="true" tear_off="false"
|
||||
|
||||
@@ -59,6 +59,11 @@
|
||||
<on_click function="Edit.TakeOff" userdata="underpants" />
|
||||
<on_enable function="Edit.EnableTakeOff" userdata="underpants" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom="-162" enabled="false" height="19" label="Physics" left="0"
|
||||
mouse_opaque="true" name="Self Physics" width="118">
|
||||
<on_click function="Edit.TakeOff" userdata="physics" />
|
||||
<on_enable function="Edit.EnableTakeOff" userdata="physics" />
|
||||
</menu_item_call>
|
||||
</pie_menu>
|
||||
<menu_item_call bottom="-181" enabled="false" height="19" label="Skirt" left="0"
|
||||
mouse_opaque="true" name="Skirt" width="118">
|
||||
|
||||
@@ -196,7 +196,12 @@
|
||||
<on_click function="Edit.TakeOff" userdata="skirt" />
|
||||
<on_enable function="Edit.EnableTakeOff" userdata="skirt" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom="-200" enabled="true" height="19" label="All Clothes" left="0"
|
||||
<menu_item_call bottom="-200" enabled="false" height="19" label="Physics" left="0"
|
||||
mouse_opaque="true" name="Physics" width="118">
|
||||
<on_click function="Edit.TakeOff" userdata="physics" />
|
||||
<on_enable function="Edit.EnableTakeOff" userdata="physics" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom="-119" enabled="true" height="19" label="All Clothes" left="0"
|
||||
mouse_opaque="true" name="All Clothes" width="118">
|
||||
<on_click function="Edit.TakeOff" userdata="all" />
|
||||
</menu_item_call>
|
||||
|
||||
Reference in New Issue
Block a user