diff options
author | Robert Adams | 2012-12-29 08:03:57 -0800 |
---|---|---|
committer | Robert Adams | 2012-12-29 08:03:57 -0800 |
commit | db6c0363f05db8b2a180eff04db9138a378d227f (patch) | |
tree | f5bb7eb9bb396c3d8c05066aa9da5b7bbf026b1b /OpenSim/Region/Physics | |
parent | BulletSim: update values in OpenSimDefaults.ini to reflect the values really ... (diff) | |
download | opensim-SC_OLD-db6c0363f05db8b2a180eff04db9138a378d227f.zip opensim-SC_OLD-db6c0363f05db8b2a180eff04db9138a378d227f.tar.gz opensim-SC_OLD-db6c0363f05db8b2a180eff04db9138a378d227f.tar.bz2 opensim-SC_OLD-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.
Diffstat (limited to 'OpenSim/Region/Physics')
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 | |||
209 | public 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)] |