diff options
author | Robert Adams | 2012-12-28 11:56:07 -0800 |
---|---|---|
committer | Robert Adams | 2012-12-28 11:56:07 -0800 |
commit | 70e0a86601ed33113a87189ee53a40e12790c609 (patch) | |
tree | a4223212c91da14fe1b0dda42211c7000bf7ecbc | |
parent | BulletSim: correct collision mask definition for linkset children. (diff) | |
download | opensim-SC-70e0a86601ed33113a87189ee53a40e12790c609.zip opensim-SC-70e0a86601ed33113a87189ee53a40e12790c609.tar.gz opensim-SC-70e0a86601ed33113a87189ee53a40e12790c609.tar.bz2 opensim-SC-70e0a86601ed33113a87189ee53a40e12790c609.tar.xz |
BulletSim: fix problem of avatars appearing to walk through walls
by moving the movement motor to a pre-step action and out of its
questionable previous home in UpdateProperties.
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 106 |
1 files changed, 55 insertions, 51 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 3f7b5e1..90936d0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -91,17 +91,7 @@ public sealed class BSCharacter : BSPhysObject | |||
91 | if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; | 91 | if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; |
92 | if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; | 92 | if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; |
93 | 93 | ||
94 | // A motor to control the acceleration and deceleration of the avatar movement. | 94 | SetupMovementMotor(); |
95 | // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
96 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
97 | // Infinite decay and timescale values so motor only changes current to target values. | ||
98 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | ||
99 | 0.2f, // time scale | ||
100 | BSMotor.Infinite, // decay time scale | ||
101 | BSMotor.InfiniteVector, // friction timescale | ||
102 | 1f // efficiency | ||
103 | ); | ||
104 | _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. | ||
105 | 95 | ||
106 | _flying = isFlying; | 96 | _flying = isFlying; |
107 | _orientation = OMV.Quaternion.Identity; | 97 | _orientation = OMV.Quaternion.Identity; |
@@ -152,13 +142,12 @@ public sealed class BSCharacter : BSPhysObject | |||
152 | 142 | ||
153 | ZeroMotion(true); | 143 | ZeroMotion(true); |
154 | ForcePosition = _position; | 144 | ForcePosition = _position; |
145 | |||
155 | // Set the velocity and compute the proper friction | 146 | // Set the velocity and compute the proper friction |
156 | ForceVelocity = _velocity; | ||
157 | // Setting the current and target in the motor will cause it to start computing any deceleration. | ||
158 | _velocityMotor.Reset(); | 147 | _velocityMotor.Reset(); |
159 | _velocityMotor.SetCurrent(_velocity); | ||
160 | _velocityMotor.SetTarget(_velocity); | 148 | _velocityMotor.SetTarget(_velocity); |
161 | _velocityMotor.Enabled = false; | 149 | _velocityMotor.SetCurrent(_velocity); |
150 | ForceVelocity = _velocity; | ||
162 | 151 | ||
163 | // This will enable or disable the flying buoyancy of the avatar. | 152 | // This will enable or disable the flying buoyancy of the avatar. |
164 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. | 153 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. |
@@ -192,6 +181,48 @@ public sealed class BSCharacter : BSPhysObject | |||
192 | PhysBody.ApplyCollisionMask(); | 181 | PhysBody.ApplyCollisionMask(); |
193 | } | 182 | } |
194 | 183 | ||
184 | // The avatar's movement is controlled by this motor that speeds up and slows down | ||
185 | // the avatar seeking to reach the motor's target speed. | ||
186 | // This motor runs as a prestep action for the avatar so it will keep the avatar | ||
187 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. | ||
188 | private void SetupMovementMotor() | ||
189 | { | ||
190 | |||
191 | // Someday, use a PID motor for asymmetric speed up and slow down | ||
192 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
193 | |||
194 | // Infinite decay and timescale values so motor only changes current to target values. | ||
195 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | ||
196 | 0.2f, // time scale | ||
197 | BSMotor.Infinite, // decay time scale | ||
198 | BSMotor.InfiniteVector, // friction timescale | ||
199 | 1f // efficiency | ||
200 | ); | ||
201 | // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. | ||
202 | |||
203 | RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep) | ||
204 | { | ||
205 | // TODO: Decide if the step parameters should be changed depending on the avatar's | ||
206 | // state (flying, colliding, ...). There is code in ODE to do this. | ||
207 | |||
208 | OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); | ||
209 | |||
210 | // If falling, we keep the world's downward vector no matter what the other axis specify. | ||
211 | if (!Flying && !IsColliding) | ||
212 | { | ||
213 | stepVelocity.Z = _velocity.Z; | ||
214 | DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", | ||
215 | LocalID, stepVelocity); | ||
216 | } | ||
217 | |||
218 | // '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; | ||
220 | DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", | ||
221 | LocalID, stepVelocity, _velocity, Mass, moveForce); | ||
222 | AddForce(moveForce, false, true); | ||
223 | }); | ||
224 | } | ||
225 | |||
195 | public override void RequestPhysicsterseUpdate() | 226 | public override void RequestPhysicsterseUpdate() |
196 | { | 227 | { |
197 | base.RequestPhysicsterseUpdate(); | 228 | base.RequestPhysicsterseUpdate(); |
@@ -668,7 +699,13 @@ public sealed class BSCharacter : BSPhysObject | |||
668 | public override float APIDStrength { set { return; } } | 699 | public override float APIDStrength { set { return; } } |
669 | public override float APIDDamping { set { return; } } | 700 | public override float APIDDamping { set { return; } } |
670 | 701 | ||
671 | public override void AddForce(OMV.Vector3 force, bool pushforce) { | 702 | public override void AddForce(OMV.Vector3 force, bool pushforce) |
703 | { | ||
704 | // Since this force is being applied in only one step, make this a force per second. | ||
705 | OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; | ||
706 | AddForce(addForce, pushforce, false); | ||
707 | } | ||
708 | private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { | ||
672 | if (force.IsFinite()) | 709 | if (force.IsFinite()) |
673 | { | 710 | { |
674 | float magnitude = force.Length(); | 711 | float magnitude = force.Length(); |
@@ -678,10 +715,10 @@ public sealed class BSCharacter : BSPhysObject | |||
678 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | 715 | force = force / magnitude * BSParam.MaxAddForceMagnitude; |
679 | } | 716 | } |
680 | 717 | ||
681 | OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; | 718 | OMV.Vector3 addForce = force; |
682 | DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); | 719 | DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); |
683 | 720 | ||
684 | PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() | 721 | PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() |
685 | { | 722 | { |
686 | // Bullet adds this central force to the total force for this tick | 723 | // Bullet adds this central force to the total force for this tick |
687 | DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); | 724 | DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); |
@@ -750,39 +787,6 @@ public sealed class BSCharacter : BSPhysObject | |||
750 | // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. | 787 | // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. |
751 | PositionSanityCheck(true); | 788 | PositionSanityCheck(true); |
752 | 789 | ||
753 | if (_velocityMotor.Enabled) | ||
754 | { | ||
755 | // TODO: Decide if the step parameters should be changed depending on the avatar's | ||
756 | // state (flying, colliding, ...). | ||
757 | |||
758 | OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); | ||
759 | |||
760 | // Check for cases to turn off the motor. | ||
761 | if ( | ||
762 | // If the walking motor is all done, turn it off | ||
763 | (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) ) | ||
764 | { | ||
765 | ZeroMotion(true); | ||
766 | stepVelocity = OMV.Vector3.Zero; | ||
767 | _velocityMotor.Enabled = false; | ||
768 | DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); | ||
769 | } | ||
770 | else | ||
771 | { | ||
772 | // If the motor is not being turned off... | ||
773 | // If falling, we keep the world's downward vector no matter what the other axis specify. | ||
774 | if (!Flying && !IsColliding) | ||
775 | { | ||
776 | stepVelocity.Z = entprop.Velocity.Z; | ||
777 | DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); | ||
778 | } | ||
779 | } | ||
780 | |||
781 | _velocity = stepVelocity; | ||
782 | entprop.Velocity = _velocity; | ||
783 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); | ||
784 | } | ||
785 | |||
786 | // remember the current and last set values | 790 | // remember the current and last set values |
787 | LastEntityProperties = CurrentEntityProperties; | 791 | LastEntityProperties = CurrentEntityProperties; |
788 | CurrentEntityProperties = entprop; | 792 | CurrentEntityProperties = entprop; |