aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs103
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