diff options
author | Robert Adams | 2013-04-23 18:31:12 -0700 |
---|---|---|
committer | Robert Adams | 2013-04-23 18:31:12 -0700 |
commit | 522ab85045066cb58bb76881032adab7cc6a2d68 (patch) | |
tree | ed9343f819b4c4e08adafdc44c2fbbfdd33e41fe /OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs | |
parent | revert CSJ2K.dll to version in use prior to commit d4fa2c69ed2895dcab76e0df1b... (diff) | |
download | opensim-SC_OLD-522ab85045066cb58bb76881032adab7cc6a2d68.zip opensim-SC_OLD-522ab85045066cb58bb76881032adab7cc6a2d68.tar.gz opensim-SC_OLD-522ab85045066cb58bb76881032adab7cc6a2d68.tar.bz2 opensim-SC_OLD-522ab85045066cb58bb76881032adab7cc6a2d68.tar.xz |
BulletSim: improve avatar stair walking up. Add more parameters to control force
of both position change and up force that move avatars over barrier.
Default parameters are for steps up to 0.5m in height.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs | 103 |
1 files changed, 85 insertions, 18 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs index 8416740..bd5ee0b1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs | |||
@@ -40,10 +40,16 @@ public class BSActorAvatarMove : BSActor | |||
40 | { | 40 | { |
41 | BSVMotor m_velocityMotor; | 41 | BSVMotor m_velocityMotor; |
42 | 42 | ||
43 | // Set to true if we think we're going up stairs. | ||
44 | // This state is remembered because collisions will turn on and off as we go up stairs. | ||
45 | int m_walkingUpStairs; | ||
46 | float m_lastStepUp; | ||
47 | |||
43 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) | 48 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) |
44 | : base(physicsScene, pObj, actorName) | 49 | : base(physicsScene, pObj, actorName) |
45 | { | 50 | { |
46 | m_velocityMotor = null; | 51 | m_velocityMotor = null; |
52 | m_walkingUpStairs = 0; | ||
47 | m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID); | 53 | m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID); |
48 | } | 54 | } |
49 | 55 | ||
@@ -119,6 +125,8 @@ public class BSActorAvatarMove : BSActor | |||
119 | SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); | 125 | SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); |
120 | 126 | ||
121 | m_physicsScene.BeforeStep += Mover; | 127 | m_physicsScene.BeforeStep += Mover; |
128 | |||
129 | m_walkingUpStairs = 0; | ||
122 | } | 130 | } |
123 | } | 131 | } |
124 | 132 | ||
@@ -216,8 +224,6 @@ public class BSActorAvatarMove : BSActor | |||
216 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. | 224 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. |
217 | OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass; | 225 | OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass; |
218 | 226 | ||
219 | // Should we check for move force being small and forcing velocity to zero? | ||
220 | |||
221 | // Add special movement force to allow avatars to walk up stepped surfaces. | 227 | // Add special movement force to allow avatars to walk up stepped surfaces. |
222 | moveForce += WalkUpStairs(); | 228 | moveForce += WalkUpStairs(); |
223 | 229 | ||
@@ -233,24 +239,33 @@ public class BSActorAvatarMove : BSActor | |||
233 | { | 239 | { |
234 | OMV.Vector3 ret = OMV.Vector3.Zero; | 240 | OMV.Vector3 ret = OMV.Vector3.Zero; |
235 | 241 | ||
242 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4},avHeight={5}", | ||
243 | m_controllingPrim.LocalID, m_controllingPrim.IsColliding, m_controllingPrim.Flying, | ||
244 | m_controllingPrim.TargetVelocitySpeed, m_controllingPrim.CollisionsLastTick.Count, m_controllingPrim.Size.Z); | ||
236 | // This test is done if moving forward, not flying and is colliding with something. | 245 | // This test is done if moving forward, not flying and is colliding with something. |
237 | // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", | 246 | // Check for stairs climbing if colliding, not flying and moving forward |
238 | // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); | 247 | if ( m_controllingPrim.IsColliding |
239 | if (m_controllingPrim.IsColliding && !m_controllingPrim.Flying && m_controllingPrim.TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */) | 248 | && !m_controllingPrim.Flying |
249 | && m_controllingPrim.TargetVelocitySpeed > 0.1f ) | ||
240 | { | 250 | { |
241 | // The range near the character's feet where we will consider stairs | 251 | // The range near the character's feet where we will consider stairs |
242 | float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f; | 252 | // float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f; |
253 | // Note: there is a problem with the computation of the capsule height. Thus RawPosition is off | ||
254 | // from the height. Revisit size and this computation when height is scaled properly. | ||
255 | float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) - 0.05f; | ||
243 | float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; | 256 | float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; |
244 | 257 | ||
245 | // Look for a collision point that is near the character's feet and is oriented the same as the charactor is | 258 | // Look for a collision point that is near the character's feet and is oriented the same as the charactor is. |
259 | // Find the highest 'good' collision. | ||
260 | OMV.Vector3 highestTouchPosition = OMV.Vector3.Zero; | ||
246 | foreach (KeyValuePair<uint, ContactPoint> kvp in m_controllingPrim.CollisionsLastTick.m_objCollisionList) | 261 | foreach (KeyValuePair<uint, ContactPoint> kvp in m_controllingPrim.CollisionsLastTick.m_objCollisionList) |
247 | { | 262 | { |
248 | // Don't care about collisions with the terrain | 263 | // Don't care about collisions with the terrain |
249 | if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID) | 264 | if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID) |
250 | { | 265 | { |
251 | OMV.Vector3 touchPosition = kvp.Value.Position; | 266 | OMV.Vector3 touchPosition = kvp.Value.Position; |
252 | // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}", | 267 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}", |
253 | // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition); | 268 | m_controllingPrim.LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition); |
254 | if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) | 269 | if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) |
255 | { | 270 | { |
256 | // This contact is within the 'near the feet' range. | 271 | // This contact is within the 'near the feet' range. |
@@ -261,24 +276,76 @@ public class BSActorAvatarMove : BSActor | |||
261 | float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); | 276 | float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); |
262 | if (diff < BSParam.AvatarStepApproachFactor) | 277 | if (diff < BSParam.AvatarStepApproachFactor) |
263 | { | 278 | { |
264 | // Found the stairs contact point. Push up a little to raise the character. | 279 | if (highestTouchPosition.Z < touchPosition.Z) |
265 | float upForce = (touchPosition.Z - nearFeetHeightMin) * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor; | 280 | highestTouchPosition = touchPosition; |
266 | ret = new OMV.Vector3(0f, 0f, upForce); | ||
267 | |||
268 | // Also move the avatar up for the new height | ||
269 | OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f); | ||
270 | m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement; | ||
271 | } | 281 | } |
272 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}", | ||
273 | m_controllingPrim.LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret); | ||
274 | } | 282 | } |
275 | } | 283 | } |
276 | } | 284 | } |
285 | m_walkingUpStairs = 0; | ||
286 | // If there is a good step sensing, move the avatar over the step. | ||
287 | if (highestTouchPosition != OMV.Vector3.Zero) | ||
288 | { | ||
289 | // Remember that we are going up stairs. This is needed because collisions | ||
290 | // will stop when we move up so this smoothes out that effect. | ||
291 | m_walkingUpStairs = BSParam.AvatarStepSmoothingSteps; | ||
292 | |||
293 | m_lastStepUp = highestTouchPosition.Z - nearFeetHeightMin; | ||
294 | ret = ComputeStairCorrection(m_lastStepUp); | ||
295 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},ret={3}", | ||
296 | m_controllingPrim.LocalID, highestTouchPosition, nearFeetHeightMin, ret); | ||
297 | } | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | // If we used to be going up stairs but are not now, smooth the case where collision goes away while | ||
302 | // we are bouncing up the stairs. | ||
303 | if (m_walkingUpStairs > 0) | ||
304 | { | ||
305 | m_walkingUpStairs--; | ||
306 | ret = ComputeStairCorrection(m_lastStepUp); | ||
307 | } | ||
277 | } | 308 | } |
278 | 309 | ||
279 | return ret; | 310 | return ret; |
280 | } | 311 | } |
281 | 312 | ||
313 | private OMV.Vector3 ComputeStairCorrection(float stepUp) | ||
314 | { | ||
315 | OMV.Vector3 ret = OMV.Vector3.Zero; | ||
316 | OMV.Vector3 displacement = OMV.Vector3.Zero; | ||
317 | |||
318 | if (stepUp > 0f) | ||
319 | { | ||
320 | // Found the stairs contact point. Push up a little to raise the character. | ||
321 | if (BSParam.AvatarStepForceFactor > 0f) | ||
322 | { | ||
323 | float upForce = stepUp * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor; | ||
324 | ret = new OMV.Vector3(0f, 0f, upForce); | ||
325 | } | ||
326 | |||
327 | // Also move the avatar up for the new height | ||
328 | if (BSParam.AvatarStepUpCorrectionFactor > 0f) | ||
329 | { | ||
330 | // Move the avatar up related to the height of the collision | ||
331 | displacement = new OMV.Vector3(0f, 0f, stepUp * BSParam.AvatarStepUpCorrectionFactor); | ||
332 | m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement; | ||
333 | } | ||
334 | else | ||
335 | { | ||
336 | if (BSParam.AvatarStepUpCorrectionFactor < 0f) | ||
337 | { | ||
338 | // Move the avatar up about the specified step height | ||
339 | displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight); | ||
340 | m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement; | ||
341 | } | ||
342 | } | ||
343 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs.ComputeStairCorrection,disp={1},force={2}", | ||
344 | m_controllingPrim.LocalID, displacement, ret); | ||
345 | |||
346 | } | ||
347 | return ret; | ||
348 | } | ||
282 | } | 349 | } |
283 | } | 350 | } |
284 | 351 | ||