aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2012-12-29 08:03:57 -0800
committerRobert Adams2012-12-29 08:03:57 -0800
commitdb6c0363f05db8b2a180eff04db9138a378d227f (patch)
treef5bb7eb9bb396c3d8c05066aa9da5b7bbf026b1b
parentBulletSim: update values in OpenSimDefaults.ini to reflect the values really ... (diff)
downloadopensim-SC-db6c0363f05db8b2a180eff04db9138a378d227f.zip
opensim-SC-db6c0363f05db8b2a180eff04db9138a378d227f.tar.gz
opensim-SC-db6c0363f05db8b2a180eff04db9138a378d227f.tar.bz2
opensim-SC-db6c0363f05db8b2a180eff04db9138a378d227f.tar.xz
BulletSim: tweeking avatar capsule code in an attempt to have
asymmetrical avatar capsule work now that rotation is being passed from the simulator. Turns out the Bullet capsule is just not very functional: it doesn't scale properly, the implementation only half does asymmetry and, in general, is hard to work with. Avatar shape is about what it was before these changes. Added initial data structures for avatar shape mesh.
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs104
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs4
4 files changed, 81 insertions, 46 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 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 65ebcaa..0cc51b0 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -420,8 +420,7 @@ public sealed class BSShapeCollection : IDisposable
420 if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) 420 if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
421 { 421 {
422 // an avatar capsule is close to a native shape (it is not shared) 422 // an avatar capsule is close to a native shape (it is not shared)
423 GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, 423 GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback);
424 FixedShapeKey.KEY_CAPSULE, shapeCallback);
425 if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); 424 if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
426 ret = true; 425 ret = true;
427 haveShape = true; 426 haveShape = true;
@@ -573,6 +572,9 @@ public sealed class BSShapeCollection : IDisposable
573 { 572 {
574 // The proper scale has been calculated in the prim. 573 // The proper scale has been calculated in the prim.
575 newShape = new BulletShape( 574 newShape = new BulletShape(
575 // Bullet's capsule total height is the passed "height + (radius * 2)" so, the base
576 // capsule is radius of 0.5f (1 diameter) and height of two (1.0f + 0.5f * 2)".
577 // This must be taken into account when computing the scaling of the capsule.
576 BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) 578 BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
577 , shapeType); 579 , shapeType);
578 if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); 580 if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index 96cd55e..c7885c6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -205,4 +205,17 @@ public class BSShapeCompound : BSShape
205 } 205 }
206 public override void Dereference(BSScene physicsScene) { } 206 public override void Dereference(BSScene physicsScene) { }
207} 207}
208
209public class BSShapeAvatar : BSShape
210{
211 private static string LogHeader = "[BULLETSIM SHAPE AVATAR]";
212 public BSShapeAvatar() : base()
213 {
214 }
215 public static BSShape GetReference(BSPhysObject prim)
216 {
217 return new BSShapeNull();
218 }
219 public override void Dereference(BSScene physicsScene) { }
220}
208} 221}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index eb4d039..b909b38 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -69,6 +69,7 @@ public enum BSPhysicsShapeType
69 SHAPE_TERRAIN = 21, 69 SHAPE_TERRAIN = 21,
70 SHAPE_COMPOUND = 22, 70 SHAPE_COMPOUND = 22,
71 SHAPE_HEIGHTMAP = 23, 71 SHAPE_HEIGHTMAP = 23,
72 SHAPE_AVATAR = 24,
72}; 73};
73 74
74// The native shapes have predefined shape hash keys 75// The native shapes have predefined shape hash keys
@@ -79,7 +80,8 @@ public enum FixedShapeKey : ulong
79 KEY_SPHERE = 2, 80 KEY_SPHERE = 2,
80 KEY_CONE = 3, 81 KEY_CONE = 3,
81 KEY_CYLINDER = 4, 82 KEY_CYLINDER = 4,
82 KEY_CAPSULE = 5, 83 KEY_CAPSULE = 5,
84 KEY_AVATAR = 6,
83} 85}
84 86
85[StructLayout(LayoutKind.Sequential)] 87[StructLayout(LayoutKind.Sequential)]