aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs213
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/BSParam.cs3
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSScene.cs4
3 files changed, 129 insertions, 91 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
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
index e34e3a9..28df2d9 100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
@@ -142,6 +142,7 @@ public static class BSParam
142 public static float AvatarCapsuleWidth { get; private set; } 142 public static float AvatarCapsuleWidth { get; private set; }
143 public static float AvatarCapsuleDepth { get; private set; } 143 public static float AvatarCapsuleDepth { get; private set; }
144 public static float AvatarCapsuleHeight { get; private set; } 144 public static float AvatarCapsuleHeight { get; private set; }
145 public static bool AvatarUseBefore09SizeComputation { get; private set; }
145 public static float AvatarHeightLowFudge { get; private set; } 146 public static float AvatarHeightLowFudge { get; private set; }
146 public static float AvatarHeightMidFudge { get; private set; } 147 public static float AvatarHeightMidFudge { get; private set; }
147 public static float AvatarHeightHighFudge { get; private set; } 148 public static float AvatarHeightHighFudge { get; private set; }
@@ -616,6 +617,8 @@ public static class BSParam
616 0.45f ), 617 0.45f ),
617 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar", 618 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar",
618 1.5f ), 619 1.5f ),
620 new ParameterDefn<bool>("AvatarUseBefore09SizeComputation", "Use the old fudge method of computing avatar capsule size",
621 true ),
619 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 622 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
620 0f ), 623 0f ),
621 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", 624 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
index 747bad5..bd9f325 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
@@ -523,13 +523,13 @@ namespace OpenSim.Region.PhysicsModule.BulletS
523 return null; 523 return null;
524 } 524 }
525 525
526 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) 526 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float footOffset, bool isFlying)
527 { 527 {
528 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); 528 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
529 529
530 if (!m_initialized) return null; 530 if (!m_initialized) return null;
531 531
532 BSCharacter actor = new BSCharacter(localID, avName, this, position, velocity, size, isFlying); 532 BSCharacter actor = new BSCharacter(localID, avName, this, position, Vector3.Zero, size, footOffset, isFlying);
533 lock (PhysObjects) 533 lock (PhysObjects)
534 PhysObjects.Add(localID, actor); 534 PhysObjects.Add(localID, actor);
535 535