diff options
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 | ||