aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs')
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs213
1 files changed, 124 insertions, 89 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
index 6d5589f..5ad2136 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
@@ -40,7 +40,6 @@ public sealed class BSCharacter : BSPhysObject
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 // private bool _stopped; 42 // private bool _stopped;
43 private OMV.Vector3 _size;
44 private bool _grabbed; 43 private bool _grabbed;
45 private bool _selected; 44 private bool _selected;
46 private float _mass; 45 private float _mass;
@@ -57,6 +56,9 @@ public sealed class BSCharacter : BSPhysObject
57 private bool _kinematic; 56 private bool _kinematic;
58 private float _buoyancy; 57 private float _buoyancy;
59 58
59 private OMV.Vector3 _size;
60 private float _footOffset;
61
60 private BSActorAvatarMove m_moveActor; 62 private BSActorAvatarMove m_moveActor;
61 private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; 63 private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
62 64
@@ -76,7 +78,7 @@ public sealed class BSCharacter : BSPhysObject
76 public override bool IsIncomplete { get { return false; } } 78 public override bool IsIncomplete { get { return false; } }
77 79
78 public BSCharacter( 80 public BSCharacter(
79 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying) 81 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, float footOffset, bool isFlying)
80 82
81 : base(parent_scene, localID, avName, "BSCharacter") 83 : base(parent_scene, localID, avName, "BSCharacter")
82 { 84 {
@@ -91,21 +93,13 @@ public sealed class BSCharacter : BSPhysObject
91 Density = BSParam.AvatarDensity; 93 Density = BSParam.AvatarDensity;
92 _isPhysical = true; 94 _isPhysical = true;
93 95
94 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 96 // Adjustments for zero X and Y made in Size()
95 // replace with the default values. 97 // This also computes avatar scale, volume, and mass
96 _size = size; 98 SetAvatarSize(size, footOffset, true /* initializing */);
97 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
98 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
99
100 // The dimensions of the physical capsule are kept in the scale.
101 // Physics creates a unit capsule which is scaled by the physics engine.
102 Scale = ComputeAvatarScale(_size);
103 // set _avatarVolume and _mass based on capsule size, _density and Scale
104 ComputeAvatarVolumeAndMass();
105 99
106 DetailLog( 100 DetailLog(
107 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}", 101 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}",
108 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel); 102 LocalID, Size, Scale, Density, _avatarVolume, RawMass, pos, vel);
109 103
110 // do actual creation in taint time 104 // do actual creation in taint time
111 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() 105 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
@@ -209,45 +203,68 @@ public sealed class BSCharacter : BSPhysObject
209 public override OMV.Vector3 Size { 203 public override OMV.Vector3 Size {
210 get 204 get
211 { 205 {
212 // Avatar capsule size is kept in the scale parameter.
213 return _size; 206 return _size;
214 } 207 }
215 208
216 set { 209 set {
217 // This is how much the avatar size is changing. Positive means getting bigger. 210 setAvatarSize(value, _footOffset);
218 // The avatar altitude must be adjusted for this change. 211 }
219 float heightChange = value.Z - _size.Z; 212 }
220 213
221 _size = value; 214 // OpenSim 0.9 introduces a common avatar size computation
215 public override void setAvatarSize(OMV.Vector3 size, float feetOffset)
216 {
217 SetAvatarSize(size, feetOffset, false /* initializing */);
218 }
219
220 // Internal version that, if initializing, doesn't do all the updating of the physics engine
221 public void SetAvatarSize(OMV.Vector3 size, float feetOffset, bool initializing)
222 {
223 OMV.Vector3 newSize = size;
224 if (newSize.IsFinite())
225 {
222 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 226 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
223 // replace with the default values. 227 // replace with the default values.
224 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; 228 if (newSize.X == 0f) newSize.X = BSParam.AvatarCapsuleDepth;
225 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; 229 if (newSize.Y == 0f) newSize.Y = BSParam.AvatarCapsuleWidth;
226 230
227 Scale = ComputeAvatarScale(_size); 231 if (newSize.X < 0.01f) newSize.X = 0.01f;
228 ComputeAvatarVolumeAndMass(); 232 if (newSize.Y < 0.01f) newSize.Y = 0.01f;
229 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 233 if (newSize.Z < 0.01f) newSize.Z = BSParam.AvatarCapsuleHeight;
230 LocalID, _size, Scale, Density, _avatarVolume, RawMass); 234 }
235 else
236 {
237 newSize = new OMV.Vector3(BSParam.AvatarCapsuleDepth, BSParam.AvatarCapsuleWidth, BSParam.AvatarCapsuleHeight);
238 }
231 239
232 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate() 240 // This is how much the avatar size is changing. Positive means getting bigger.
233 { 241 // The avatar altitude must be adjusted for this change.
234 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) 242 float heightChange = newSize.Z - Size.Z;
235 {
236 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
237 UpdatePhysicalMassProperties(RawMass, true);
238 243
239 // Adjust the avatar's position to account for the increase/decrease in size 244 _size = newSize;
240 ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
241 245
242 // Make sure this change appears as a property update event 246 Scale = ComputeAvatarScale(Size);
243 PhysScene.PE.PushUpdate(PhysBody); 247 ComputeAvatarVolumeAndMass();
244 } 248 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
245 }); 249 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
246 250
247 } 251 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
252 {
253 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
254 {
255 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
256 UpdatePhysicalMassProperties(RawMass, true);
257
258 // Adjust the avatar's position to account for the increase/decrease in size
259 ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
260
261 // Make sure this change appears as a property update event
262 PhysScene.PE.PushUpdate(PhysBody);
263 }
264 });
248 } 265 }
249 266
250 public override PrimitiveBaseShape Shape 267 public override PrimitiveBaseShape Shape
251 { 268 {
252 set { BaseShape = value; } 269 set { BaseShape = value; }
253 } 270 }
@@ -702,60 +719,71 @@ public sealed class BSCharacter : BSPhysObject
702 public override void SetMomentum(OMV.Vector3 momentum) { 719 public override void SetMomentum(OMV.Vector3 momentum) {
703 } 720 }
704 721
722 // The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets
723 // the scale of that unit shape to create the avatars full size.
705 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) 724 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
706 { 725 {
707 OMV.Vector3 newScale = size; 726 OMV.Vector3 newScale = size;
708 727
709 // Bullet's capsule total height is the "passed height + radius * 2"; 728 if (BSParam.AvatarUseBefore09SizeComputation)
710 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1) 729 {
711 // The number we pass in for 'scaling' is the multiplier to get that base
712 // shape to be the size desired.
713 // So, when creating the scale for the avatar height, we take the passed height
714 // (size.Z) and remove the caps.
715 // An oddity of the Bullet capsule implementation is that it presumes the Y
716 // dimension is the radius of the capsule. Even though some of the code allows
717 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
718 730
719 // Scale is multiplier of radius with one of "0.5" 731 // Bullet's capsule total height is the "passed height + radius * 2";
732 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
733 // The number we pass in for 'scaling' is the multiplier to get that base
734 // shape to be the size desired.
735 // So, when creating the scale for the avatar height, we take the passed height
736 // (size.Z) and remove the caps.
737 // An oddity of the Bullet capsule implementation is that it presumes the Y
738 // dimension is the radius of the capsule. Even though some of the code allows
739 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
720 740
721 float heightAdjust = BSParam.AvatarHeightMidFudge; 741 // Scale is multiplier of radius with one of "0.5"
722 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) 742
723 { 743 float heightAdjust = BSParam.AvatarHeightMidFudge;
724 const float AVATAR_LOW = 1.1f; 744 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
725 const float AVATAR_MID = 1.775f; // 1.87f
726 const float AVATAR_HI = 2.45f;
727 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
728 float midHeightOffset = size.Z - AVATAR_MID;
729 if (midHeightOffset < 0f)
730 { 745 {
731 // Small avatar. Add the adjustment based on the distance from midheight 746 const float AVATAR_LOW = 1.1f;
732 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge; 747 const float AVATAR_MID = 1.775f; // 1.87f
748 const float AVATAR_HI = 2.45f;
749 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
750 float midHeightOffset = size.Z - AVATAR_MID;
751 if (midHeightOffset < 0f)
752 {
753 // Small avatar. Add the adjustment based on the distance from midheight
754 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
755 }
756 else
757 {
758 // Large avatar. Add the adjustment based on the distance from midheight
759 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
760 }
761 }
762 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
763 {
764 newScale.X = size.X / 2f;
765 newScale.Y = size.Y / 2f;
766 // The total scale height is the central cylindar plus the caps on the two ends.
767 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f;
733 } 768 }
734 else 769 else
735 { 770 {
736 // Large avatar. Add the adjustment based on the distance from midheight 771 newScale.Z = size.Z + heightAdjust;
737 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
738 } 772 }
739 } 773 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
740 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule) 774
741 { 775 // If smaller than the endcaps, just fake like we're almost that small
742 newScale.X = size.X / 2f; 776 if (newScale.Z < 0)
743 newScale.Y = size.Y / 2f; 777 newScale.Z = 0.1f;
744 // The total scale height is the central cylindar plus the caps on the two ends. 778
745 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f; 779 DetailLog("{0},BSCharacter.ComputeAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
780 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
746 } 781 }
747 else 782 else
748 { 783 {
749 newScale.Z = size.Z + heightAdjust; 784 newScale.Z = size.Z + _footOffset;
785 DetailLog("{0},BSCharacter.ComputeAvatarScale,using newScale={1}, footOffset={2}", LocalID, newScale, _footOffset);
750 } 786 }
751 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
752
753 // If smaller than the endcaps, just fake like we're almost that small
754 if (newScale.Z < 0)
755 newScale.Z = 0.1f;
756
757 DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
758 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
759 787
760 return newScale; 788 return newScale;
761 } 789 }
@@ -763,17 +791,24 @@ public sealed class BSCharacter : BSPhysObject
763 // set _avatarVolume and _mass based on capsule size, _density and Scale 791 // set _avatarVolume and _mass based on capsule size, _density and Scale
764 private void ComputeAvatarVolumeAndMass() 792 private void ComputeAvatarVolumeAndMass()
765 { 793 {
766 _avatarVolume = (float)( 794 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
767 Math.PI 795 {
768 * Size.X / 2f 796 _avatarVolume = (float)(
769 * Size.Y / 2f // the area of capsule cylinder 797 Math.PI
770 * Size.Z // times height of capsule cylinder 798 * Size.X / 2f
771 + 1.33333333f 799 * Size.Y / 2f // the area of capsule cylinder
772 * Math.PI 800 * Size.Z // times height of capsule cylinder
773 * Size.X / 2f 801 + 1.33333333f
774 * Math.Min(Size.X, Size.Y) / 2 802 * Math.PI
775 * Size.Y / 2f // plus the volume of the capsule end caps 803 * Size.X / 2f
776 ); 804 * Math.Min(Size.X, Size.Y) / 2
805 * Size.Y / 2f // plus the volume of the capsule end caps
806 );
807 }
808 else
809 {
810 _avatarVolume = Size.X * Size.Y * Size.Z;
811 }
777 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume; 812 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume;
778 } 813 }
779 814