diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs | 213 | ||||
-rwxr-xr-x | OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | 4 |
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 | ||