diff options
author | Robert Adams | 2016-01-18 10:48:10 -0800 |
---|---|---|
committer | Robert Adams | 2016-01-18 10:48:10 -0800 |
commit | 5ed90b39216cfa2777f390fb8f23a34e07153d56 (patch) | |
tree | 74b9e8c414e1f7a4d51d8d8f8ac82448bff57a83 /OpenSim/Region/PhysicsModules | |
parent | BulletSim: change method signatures for internal AddForce methods to remove (diff) | |
download | opensim-SC-5ed90b39216cfa2777f390fb8f23a34e07153d56.zip opensim-SC-5ed90b39216cfa2777f390fb8f23a34e07153d56.tar.gz opensim-SC-5ed90b39216cfa2777f390fb8f23a34e07153d56.tar.bz2 opensim-SC-5ed90b39216cfa2777f390fb8f23a34e07153d56.tar.xz |
BulletSim: fix problem of not zeroing motion when stationary (drift problem from
Mantis 7813). Redo Z computations for movement. Clean up code to simplify
tests. Add function to suppress stationary tests unless velocity drops.
Diffstat (limited to 'OpenSim/Region/PhysicsModules')
-rwxr-xr-x | OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs | 106 |
1 files changed, 40 insertions, 66 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs index 71cd879..35823ae 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs | |||
@@ -47,10 +47,9 @@ public class BSActorAvatarMove : BSActor | |||
47 | // The amount the step up is applying. Used to smooth stair walking. | 47 | // The amount the step up is applying. Used to smooth stair walking. |
48 | float m_lastStepUp; | 48 | float m_lastStepUp; |
49 | 49 | ||
50 | // Jumping happens over several frames. If use applies up force while colliding, start the | 50 | // There are times the velocity is set but we don't want to inforce stationary until the |
51 | // jump and allow the jump to continue for this number of frames. | 51 | // real velocity drops. |
52 | int m_jumpFrames = 0; | 52 | bool m_waitingForLowVelocityForStationary = false; |
53 | float m_jumpVelocity = 0f; | ||
54 | 53 | ||
55 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) | 54 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) |
56 | : base(physicsScene, pObj, actorName) | 55 | : base(physicsScene, pObj, actorName) |
@@ -117,12 +116,18 @@ public class BSActorAvatarMove : BSActor | |||
117 | m_velocityMotor.SetTarget(targ); | 116 | m_velocityMotor.SetTarget(targ); |
118 | m_velocityMotor.SetCurrent(vel); | 117 | m_velocityMotor.SetCurrent(vel); |
119 | m_velocityMotor.Enabled = true; | 118 | m_velocityMotor.Enabled = true; |
120 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}, inTaintTime={3}", | 119 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}", |
121 | m_controllingPrim.LocalID, vel, targ, inTaintTime); | 120 | m_controllingPrim.LocalID, vel, targ); |
121 | m_waitingForLowVelocityForStationary = false; | ||
122 | } | 122 | } |
123 | }); | 123 | }); |
124 | } | 124 | } |
125 | 125 | ||
126 | public void SuppressStationayCheckUntilLowVelocity() | ||
127 | { | ||
128 | m_waitingForLowVelocityForStationary = true; | ||
129 | } | ||
130 | |||
126 | // If a movement motor has not been created, create one and start the hovering. | 131 | // If a movement motor has not been created, create one and start the hovering. |
127 | private void ActivateAvatarMove() | 132 | private void ActivateAvatarMove() |
128 | { | 133 | { |
@@ -135,13 +140,14 @@ public class BSActorAvatarMove : BSActor | |||
135 | 1f // efficiency | 140 | 1f // efficiency |
136 | ); | 141 | ); |
137 | m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold; | 142 | m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold; |
138 | // m_velocityMotor.PhysicsScene = m_controllingPrim.PhysScene; // DEBUG DEBUG so motor will output detail log messages. | 143 | m_velocityMotor.PhysicsScene = m_controllingPrim.PhysScene; // DEBUG DEBUG so motor will output detail log messages. |
139 | SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); | 144 | SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); |
140 | 145 | ||
141 | m_physicsScene.BeforeStep += Mover; | 146 | m_physicsScene.BeforeStep += Mover; |
142 | m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; | 147 | m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; |
143 | 148 | ||
144 | m_walkingUpStairs = 0; | 149 | m_walkingUpStairs = 0; |
150 | m_waitingForLowVelocityForStationary = false; | ||
145 | } | 151 | } |
146 | } | 152 | } |
147 | 153 | ||
@@ -192,29 +198,25 @@ public class BSActorAvatarMove : BSActor | |||
192 | // if colliding with something stationary and we're not doing volume detect . | 198 | // if colliding with something stationary and we're not doing volume detect . |
193 | if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) | 199 | if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) |
194 | { | 200 | { |
195 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); | 201 | if (m_waitingForLowVelocityForStationary) |
196 | m_controllingPrim.IsStationary = true; | 202 | { |
197 | m_controllingPrim.ZeroMotion(true /* inTaintTime */); | 203 | // if waiting for velocity to drop and it has finally dropped, we can be stationary |
198 | 204 | if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) | |
199 | /* 20160118 Attempt to not be stationary if some velocity applied. Caused drifting since still can't tell who applied velocity. | 205 | { |
200 | * Solution is to make clearer what is causing the added velocity (push or environment) when deciding if stationary. | 206 | m_waitingForLowVelocityForStationary = false; |
201 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,totalForce={1}, vel={2}", | 207 | } |
202 | m_controllingPrim.LocalID, m_physicsScene.PE.GetTotalForce(m_controllingPrim.PhysBody), m_controllingPrim.Velocity); | 208 | } |
203 | // If velocity is very small, assume it is movement creep and suppress it. | 209 | if (!m_waitingForLowVelocityForStationary) |
204 | // Applying push forces (Character.AddForce) should move the avatar and that is only seen here as velocity. | ||
205 | if ( (m_controllingPrim.Velocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) | ||
206 | && (m_physicsScene.PE.GetTotalForce(m_controllingPrim.PhysBody).LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) ) | ||
207 | { | 210 | { |
208 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); | 211 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); |
209 | m_controllingPrim.IsStationary = true; | 212 | m_controllingPrim.IsStationary = true; |
210 | m_controllingPrim.ZeroMotion(true); | 213 | m_controllingPrim.ZeroMotion(true /* inTaintTime */); |
211 | } | 214 | } |
212 | else | 215 | else |
213 | { | 216 | { |
214 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,not zeroing because velocity={1}", | 217 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVel,rawvel={1}", |
215 | m_controllingPrim.LocalID, m_controllingPrim.Velocity); | 218 | m_controllingPrim.LocalID, m_controllingPrim.RawVelocity.Length()); |
216 | } | 219 | } |
217 | */ | ||
218 | } | 220 | } |
219 | 221 | ||
220 | // Standing has more friction on the ground | 222 | // Standing has more friction on the ground |
@@ -259,50 +261,24 @@ public class BSActorAvatarMove : BSActor | |||
259 | m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction); | 261 | m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction); |
260 | } | 262 | } |
261 | 263 | ||
262 | // If not flying and not colliding, assume falling and keep the downward motion component. | 264 | // 'm_velocityMotor is used for walking, flying, and jumping and will thus have the correct values |
263 | // This check is done here for the next jump test. | 265 | // for Z. But in come cases it must be over-ridden. Like when falling or jumping. |
264 | if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) | ||
265 | { | ||
266 | stepVelocity.Z = m_controllingPrim.RawVelocity.Z; | ||
267 | } | ||
268 | 266 | ||
269 | // Colliding and not flying with an upward force. The avatar must be trying to jump. | 267 | float realVelocityZ = m_controllingPrim.RawVelocity.Z; |
270 | if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0) | ||
271 | { | ||
272 | // We allow the upward force to happen for this many frames. | ||
273 | m_jumpFrames = BSParam.AvatarJumpFrames; | ||
274 | m_jumpVelocity = stepVelocity.Z; | ||
275 | } | ||
276 | 268 | ||
277 | // The case where the avatar is not colliding and is not flying is special. | 269 | // If not flying and falling, we over-ride the stepping motor so we can fall to the ground |
278 | // The avatar is either falling or jumping and the user can be applying force to the avatar | 270 | if (!m_controllingPrim.Flying && realVelocityZ < 0) |
279 | // (force in some direction or force up or down). | ||
280 | // If the avatar has negative Z velocity and is not colliding, presume we're falling and keep the velocity. | ||
281 | // If the user is trying to apply upward force but we're not colliding, assume the avatar | ||
282 | // is trying to jump and don't apply the upward force if not touching the ground any more. | ||
283 | if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) | ||
284 | { | 271 | { |
285 | // If upward velocity is being applied, this must be a jump and only allow that to go on so long | 272 | // Can't fall faster than this |
286 | if (m_jumpFrames > 0) | 273 | if (realVelocityZ < BSParam.AvatarTerminalVelocity) |
287 | { | ||
288 | // Since not touching the ground, only apply upward force for so long. | ||
289 | m_jumpFrames--; | ||
290 | stepVelocity.Z = m_jumpVelocity; | ||
291 | } | ||
292 | else | ||
293 | { | 274 | { |
294 | // Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast. | 275 | realVelocityZ = BSParam.AvatarTerminalVelocity; |
295 | if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity) | ||
296 | { | ||
297 | stepVelocity.Z = BSParam.AvatarTerminalVelocity; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | stepVelocity.Z = m_controllingPrim.RawVelocity.Z; | ||
302 | } | ||
303 | } | 276 | } |
304 | // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); | 277 | |
278 | stepVelocity.Z = realVelocityZ; | ||
305 | } | 279 | } |
280 | // m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,DEBUG,motorCurrent={1},realZ={2},flying={3},collid={4},jFrames={5}", | ||
281 | // m_controllingPrim.LocalID, m_velocityMotor.CurrentValue, realVelocityZ, m_controllingPrim.Flying, m_controllingPrim.IsColliding, m_jumpFrames); | ||
306 | 282 | ||
307 | //Alicia: Maintain minimum height when flying. | 283 | //Alicia: Maintain minimum height when flying. |
308 | // SL has a flying effect that keeps the avatar flying above the ground by some margin | 284 | // SL has a flying effect that keeps the avatar flying above the ground by some margin |
@@ -313,6 +289,8 @@ public class BSActorAvatarMove : BSActor | |||
313 | 289 | ||
314 | if( m_controllingPrim.Position.Z < hover_height) | 290 | if( m_controllingPrim.Position.Z < hover_height) |
315 | { | 291 | { |
292 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,addingUpforceForGroundMargin,height={1},hoverHeight={2}", | ||
293 | m_controllingPrim.LocalID, m_controllingPrim.Position.Z, hover_height); | ||
316 | stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce; | 294 | stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce; |
317 | } | 295 | } |
318 | } | 296 | } |
@@ -337,11 +315,7 @@ public class BSActorAvatarMove : BSActor | |||
337 | if (m_controllingPrim.IsStationary) | 315 | if (m_controllingPrim.IsStationary) |
338 | { | 316 | { |
339 | entprop.Position = m_controllingPrim.RawPosition; | 317 | entprop.Position = m_controllingPrim.RawPosition; |
340 | // Suppress small movement velocity | 318 | entprop.Velocity = OMV.Vector3.Zero; |
341 | if (entprop.Velocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) { | ||
342 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,OnPreUpdate,zeroing velocity={1}", m_controllingPrim.LocalID, entprop.Velocity); | ||
343 | entprop.Velocity = OMV.Vector3.Zero; | ||
344 | } | ||
345 | m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); | 319 | m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); |
346 | } | 320 | } |
347 | 321 | ||