aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs104
1 files changed, 61 insertions, 43 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 901f976..9659542 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -66,7 +66,6 @@ public sealed class BSCharacter : BSPhysObject
66 private float _buoyancy; 66 private float _buoyancy;
67 67
68 // The friction and velocity of the avatar is modified depending on whether walking or not. 68 // The friction and velocity of the avatar is modified depending on whether walking or not.
69 private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar
70 private float _currentFriction; // the friction currently being used (changed by setVelocity). 69 private float _currentFriction; // the friction currently being used (changed by setVelocity).
71 70
72 private BSVMotor _velocityMotor; 71 private BSVMotor _velocityMotor;
@@ -85,27 +84,27 @@ public sealed class BSCharacter : BSPhysObject
85 _physicsActorType = (int)ActorTypes.Agent; 84 _physicsActorType = (int)ActorTypes.Agent;
86 _position = pos; 85 _position = pos;
87 86
88 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
89 // replace with the default values.
90 _size = size;
91 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
92 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
93
94 SetupMovementMotor();
95
96 _flying = isFlying; 87 _flying = isFlying;
97 _orientation = OMV.Quaternion.Identity; 88 _orientation = OMV.Quaternion.Identity;
98 _velocity = OMV.Vector3.Zero; 89 _velocity = OMV.Vector3.Zero;
99 _appliedVelocity = OMV.Vector3.Zero;
100 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 90 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
101 _currentFriction = BSParam.AvatarStandingFriction; 91 _currentFriction = BSParam.AvatarStandingFriction;
102 _avatarDensity = BSParam.AvatarDensity; 92 _avatarDensity = BSParam.AvatarDensity;
103 93
104 // The dimensions of the avatar capsule are kept in the scale. 94 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
95 // replace with the default values.
96 _size = size;
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.
105 // Physics creates a unit capsule which is scaled by the physics engine. 101 // Physics creates a unit capsule which is scaled by the physics engine.
106 ComputeAvatarScale(_size); 102 Scale = ComputeAvatarScale(_size);
107 // set _avatarVolume and _mass based on capsule size, _density and Scale 103 // set _avatarVolume and _mass based on capsule size, _density and Scale
108 ComputeAvatarVolumeAndMass(); 104 ComputeAvatarVolumeAndMass();
105
106 SetupMovementMotor();
107
109 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", 108 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
110 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); 109 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
111 110
@@ -217,9 +216,21 @@ public sealed class BSCharacter : BSPhysObject
217 216
218 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. 217 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
219 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; 218 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep;
220 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", 219
221 LocalID, stepVelocity, _velocity, Mass, moveForce); 220 // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user
222 AddForce(moveForce, false, true); 221 float moveForceMagnitudeSquared = moveForce.LengthSquared();
222 if (moveForceMagnitudeSquared < 0.0001)
223 {
224 DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}",
225 LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce);
226 ForceVelocity = OMV.Vector3.Zero;
227 }
228 else
229 {
230 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
231 LocalID, stepVelocity, _velocity, Mass, moveForce);
232 AddForce(moveForce, false, true);
233 }
223 }); 234 });
224 } 235 }
225 236
@@ -238,14 +249,13 @@ public sealed class BSCharacter : BSPhysObject
238 } 249 }
239 250
240 set { 251 set {
241 // When an avatar's size is set, only the height is changed.
242 _size = value; 252 _size = value;
243 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 253 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
244 // replace with the default values. 254 // replace with the default values.
245 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; 255 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
246 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; 256 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
247 257
248 ComputeAvatarScale(_size); 258 Scale = ComputeAvatarScale(_size);
249 ComputeAvatarVolumeAndMass(); 259 ComputeAvatarVolumeAndMass();
250 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 260 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
251 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); 261 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
@@ -521,8 +531,6 @@ public sealed class BSCharacter : BSPhysObject
521 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); 531 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
522 } 532 }
523 } 533 }
524 // Remember the set velocity so we can suppress the reduction by friction, ...
525 _appliedVelocity = value;
526 534
527 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); 535 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
528 BulletSimAPI.Activate2(PhysBody.ptr, true); 536 BulletSimAPI.Activate2(PhysBody.ptr, true);
@@ -554,11 +562,7 @@ public sealed class BSCharacter : BSPhysObject
554 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 562 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
555 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() 563 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
556 { 564 {
557 if (PhysBody.HasPhysicalBody) 565 ForceOrientation = _orientation;
558 {
559 // _position = BulletSimAPI.GetPosition2(BSBody.ptr);
560 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
561 }
562 }); 566 });
563 } 567 }
564 } 568 }
@@ -573,7 +577,11 @@ public sealed class BSCharacter : BSPhysObject
573 set 577 set
574 { 578 {
575 _orientation = value; 579 _orientation = value;
576 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 580 if (PhysBody.HasPhysicalBody)
581 {
582 // _position = BulletSimAPI.GetPosition2(BSBody.ptr);
583 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
584 }
577 } 585 }
578 } 586 }
579 public override int PhysicsActorType { 587 public override int PhysicsActorType {
@@ -716,7 +724,7 @@ public sealed class BSCharacter : BSPhysObject
716 } 724 }
717 725
718 OMV.Vector3 addForce = force; 726 OMV.Vector3 addForce = force;
719 DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 727 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
720 728
721 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() 729 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
722 { 730 {
@@ -740,21 +748,31 @@ public sealed class BSCharacter : BSPhysObject
740 public override void SetMomentum(OMV.Vector3 momentum) { 748 public override void SetMomentum(OMV.Vector3 momentum) {
741 } 749 }
742 750
743 private void ComputeAvatarScale(OMV.Vector3 size) 751 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
744 { 752 {
745 OMV.Vector3 newScale = size; 753 OMV.Vector3 newScale;
746 // newScale.X = PhysicsScene.Params.avatarCapsuleWidth; 754
747 // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth; 755 // Bullet's capsule total height is the "passed height + radius * 2";
748 756 // The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1)
749 // From the total height, remove the capsule half spheres that are at each end 757 // The number we pass in for 'scaling' is the multiplier to get that base
750 // The 1.15f came from ODE. Not sure what this factors in. 758 // shape to be the size desired.
751 // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); 759 // So, when creating the scale for the avatar height, we take the passed height
760 // (size.Z) and remove the caps.
761 // Another oddity of the Bullet capsule implementation is that it presumes the Y
762 // dimension is the radius of the capsule. Even though some of the code allows
763 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
764
765 // Scale is multiplier of radius with one of "0.5"
766 newScale.X = size.X / 2f;
767 newScale.Y = size.Y / 2f;
752 768
753 // The total scale height is the central cylindar plus the caps on the two ends. 769 // The total scale height is the central cylindar plus the caps on the two ends.
754 newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f); 770 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2)) / 2f;
771 // If smaller than the endcaps, just fake like we're almost that small
772 if (newScale.Z < 0)
773 newScale.Z = 0.1f;
755 774
756 // Convert diameters to radii and height to half height -- the way Bullet expects it. 775 return newScale;
757 Scale = newScale / 2f;
758 } 776 }
759 777
760 // set _avatarVolume and _mass based on capsule size, _density and Scale 778 // set _avatarVolume and _mass based on capsule size, _density and Scale
@@ -762,14 +780,14 @@ public sealed class BSCharacter : BSPhysObject
762 { 780 {
763 _avatarVolume = (float)( 781 _avatarVolume = (float)(
764 Math.PI 782 Math.PI
765 * Scale.X 783 * Size.X / 2f
766 * Scale.Y // the area of capsule cylinder 784 * Size.Y / 2f // the area of capsule cylinder
767 * Scale.Z // times height of capsule cylinder 785 * Size.Z // times height of capsule cylinder
768 + 1.33333333f 786 + 1.33333333f
769 * Math.PI 787 * Math.PI
770 * Scale.X 788 * Size.X / 2f
771 * Math.Min(Scale.X, Scale.Y) 789 * Math.Min(Size.X, Size.Y) / 2
772 * Scale.Y // plus the volume of the capsule end caps 790 * Size.Y / 2f // plus the volume of the capsule end caps
773 ); 791 );
774 _mass = _avatarDensity * _avatarVolume; 792 _mass = _avatarDensity * _avatarVolume;
775 } 793 }