diff options
Diffstat (limited to 'OpenSim/Region/Physics')
5 files changed, 119 insertions, 27 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index fe48166..939d38a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -184,10 +184,6 @@ public sealed class BSCharacter : BSPhysObject | |||
184 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. | 184 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. |
185 | private void SetupMovementMotor() | 185 | private void SetupMovementMotor() |
186 | { | 186 | { |
187 | |||
188 | // Someday, use a PID motor for asymmetric speed up and slow down | ||
189 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
190 | |||
191 | // Infinite decay and timescale values so motor only changes current to target values. | 187 | // Infinite decay and timescale values so motor only changes current to target values. |
192 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | 188 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", |
193 | 0.2f, // time scale | 189 | 0.2f, // time scale |
@@ -214,25 +210,68 @@ public sealed class BSCharacter : BSPhysObject | |||
214 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. | 210 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. |
215 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; | 211 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; |
216 | 212 | ||
217 | /* | 213 | // Should we check for move force being small and forcing velocity to zero? |
218 | // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user | 214 | |
219 | float moveForceMagnitudeSquared = moveForce.LengthSquared(); | 215 | // Add special movement force to allow avatars to walk up stepped surfaces. |
220 | if (moveForceMagnitudeSquared < 0.0001) | 216 | moveForce += WalkUpStairs(); |
221 | { | 217 | |
222 | DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}", | 218 | DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); |
223 | LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce); | ||
224 | ForceVelocity = OMV.Vector3.Zero; | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | AddForce(moveForce, false, true); | ||
229 | } | ||
230 | */ | ||
231 | // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); | ||
232 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); | 219 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); |
233 | }); | 220 | }); |
234 | } | 221 | } |
235 | 222 | ||
223 | // Decide of the character is colliding with a low object and compute a force to pop the | ||
224 | // avatar up so it has a chance of walking up and over the low object. | ||
225 | private OMV.Vector3 WalkUpStairs() | ||
226 | { | ||
227 | OMV.Vector3 ret = OMV.Vector3.Zero; | ||
228 | |||
229 | // This test is done if moving forward, not flying and is colliding with something. | ||
230 | // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", | ||
231 | // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); | ||
232 | if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */) | ||
233 | { | ||
234 | // The range near the character's feet where we will consider stairs | ||
235 | float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; | ||
236 | float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; | ||
237 | |||
238 | // Look for a collision point that is near the character's feet and is oriented the same as the charactor is | ||
239 | foreach (KeyValuePair<uint, ContactPoint> kvp in CollisionsLastTick.m_objCollisionList) | ||
240 | { | ||
241 | // Don't care about collisions with the terrain | ||
242 | if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID) | ||
243 | { | ||
244 | OMV.Vector3 touchPosition = kvp.Value.Position; | ||
245 | // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}", | ||
246 | // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition); | ||
247 | if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) | ||
248 | { | ||
249 | // This contact is within the 'near the feet' range. | ||
250 | // The normal should be our contact point to the object so it is pointing away | ||
251 | // thus the difference between our facing orientation and the normal should be small. | ||
252 | OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation; | ||
253 | OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal); | ||
254 | float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); | ||
255 | if (diff < BSParam.AvatarStepApproachFactor) | ||
256 | { | ||
257 | // Found the stairs contact point. Push up a little to raise the character. | ||
258 | float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor; | ||
259 | ret = new OMV.Vector3(0f, 0f, upForce); | ||
260 | |||
261 | // Also move the avatar up for the new height | ||
262 | OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f); | ||
263 | ForcePosition = RawPosition + displacement; | ||
264 | } | ||
265 | DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}", | ||
266 | LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
236 | public override void RequestPhysicsterseUpdate() | 275 | public override void RequestPhysicsterseUpdate() |
237 | { | 276 | { |
238 | base.RequestPhysicsterseUpdate(); | 277 | base.RequestPhysicsterseUpdate(); |
@@ -342,13 +381,11 @@ public sealed class BSCharacter : BSPhysObject | |||
342 | } | 381 | } |
343 | set { | 382 | set { |
344 | _position = value; | 383 | _position = value; |
345 | PositionSanityCheck(); | ||
346 | 384 | ||
347 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() | 385 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() |
348 | { | 386 | { |
349 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 387 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
350 | if (PhysBody.HasPhysicalBody) | 388 | ForcePosition = _position; |
351 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
352 | }); | 389 | }); |
353 | } | 390 | } |
354 | } | 391 | } |
@@ -359,8 +396,11 @@ public sealed class BSCharacter : BSPhysObject | |||
359 | } | 396 | } |
360 | set { | 397 | set { |
361 | _position = value; | 398 | _position = value; |
362 | PositionSanityCheck(); | 399 | if (PhysBody.HasPhysicalBody) |
363 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 400 | { |
401 | PositionSanityCheck(); | ||
402 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
403 | } | ||
364 | } | 404 | } |
365 | } | 405 | } |
366 | 406 | ||
@@ -373,7 +413,7 @@ public sealed class BSCharacter : BSPhysObject | |||
373 | bool ret = false; | 413 | bool ret = false; |
374 | 414 | ||
375 | // TODO: check for out of bounds | 415 | // TODO: check for out of bounds |
376 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 416 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
377 | { | 417 | { |
378 | // The character is out of the known/simulated area. | 418 | // The character is out of the known/simulated area. |
379 | // Upper levels of code will handle the transition to other areas so, for | 419 | // Upper levels of code will handle the transition to other areas so, for |
@@ -382,7 +422,7 @@ public sealed class BSCharacter : BSPhysObject | |||
382 | } | 422 | } |
383 | 423 | ||
384 | // If below the ground, move the avatar up | 424 | // If below the ground, move the avatar up |
385 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); | 425 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); |
386 | if (Position.Z < terrainHeight) | 426 | if (Position.Z < terrainHeight) |
387 | { | 427 | { |
388 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 428 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
@@ -485,6 +525,11 @@ public sealed class BSCharacter : BSPhysObject | |||
485 | }); | 525 | }); |
486 | } | 526 | } |
487 | } | 527 | } |
528 | public override OMV.Vector3 RawVelocity | ||
529 | { | ||
530 | get { return _velocity; } | ||
531 | set { _velocity = value; } | ||
532 | } | ||
488 | // Directly setting velocity means this is what the user really wants now. | 533 | // Directly setting velocity means this is what the user really wants now. |
489 | public override OMV.Vector3 Velocity { | 534 | public override OMV.Vector3 Velocity { |
490 | get { return _velocity; } | 535 | get { return _velocity; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index b9bd0bf..23d573f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -75,6 +75,9 @@ public static class BSParam | |||
75 | public static float AvatarCapsuleDepth { get; private set; } | 75 | public static float AvatarCapsuleDepth { get; private set; } |
76 | public static float AvatarCapsuleHeight { get; private set; } | 76 | public static float AvatarCapsuleHeight { get; private set; } |
77 | public static float AvatarContactProcessingThreshold { get; private set; } | 77 | public static float AvatarContactProcessingThreshold { get; private set; } |
78 | public static float AvatarStepHeight { get; private set; } | ||
79 | public static float AvatarStepApproachFactor { get; private set; } | ||
80 | public static float AvatarStepForceFactor { get; private set; } | ||
78 | 81 | ||
79 | public static float VehicleAngularDamping { get; private set; } | 82 | public static float VehicleAngularDamping { get; private set; } |
80 | 83 | ||
@@ -403,6 +406,21 @@ public static class BSParam | |||
403 | (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, | 406 | (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, |
404 | (s) => { return AvatarContactProcessingThreshold; }, | 407 | (s) => { return AvatarContactProcessingThreshold; }, |
405 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), | 408 | (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), |
409 | new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", | ||
410 | 0.3f, | ||
411 | (s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); }, | ||
412 | (s) => { return AvatarStepHeight; }, | ||
413 | (s,p,l,v) => { AvatarStepHeight = v; } ), | ||
414 | new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", | ||
415 | 0.6f, | ||
416 | (s,cf,p,v) => { AvatarStepApproachFactor = cf.GetFloat(p, v); }, | ||
417 | (s) => { return AvatarStepApproachFactor; }, | ||
418 | (s,p,l,v) => { AvatarStepApproachFactor = v; } ), | ||
419 | new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", | ||
420 | 2.0f, | ||
421 | (s,cf,p,v) => { AvatarStepForceFactor = cf.GetFloat(p, v); }, | ||
422 | (s) => { return AvatarStepForceFactor; }, | ||
423 | (s,p,l,v) => { AvatarStepForceFactor = v; } ), | ||
406 | 424 | ||
407 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", | 425 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", |
408 | 0.95f, | 426 | 0.95f, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 534f929..e8575f6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -79,6 +79,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
79 | Material = MaterialAttributes.Material.Wood; | 79 | Material = MaterialAttributes.Material.Wood; |
80 | 80 | ||
81 | CollisionCollection = new CollisionEventUpdate(); | 81 | CollisionCollection = new CollisionEventUpdate(); |
82 | CollisionsLastTick = CollisionCollection; | ||
82 | SubscribedEventsMs = 0; | 83 | SubscribedEventsMs = 0; |
83 | CollidingStep = 0; | 84 | CollidingStep = 0; |
84 | CollidingGroundStep = 0; | 85 | CollidingGroundStep = 0; |
@@ -159,6 +160,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
159 | public abstract OMV.Quaternion ForceOrientation { get; set; } | 160 | public abstract OMV.Quaternion ForceOrientation { get; set; } |
160 | 161 | ||
161 | // The system is telling us the velocity it wants to move at. | 162 | // The system is telling us the velocity it wants to move at. |
163 | // Velocity in world coordinates. | ||
162 | // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor | 164 | // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor |
163 | public override OMV.Vector3 TargetVelocity | 165 | public override OMV.Vector3 TargetVelocity |
164 | { | 166 | { |
@@ -169,6 +171,15 @@ public abstract class BSPhysObject : PhysicsActor | |||
169 | Velocity = value; | 171 | Velocity = value; |
170 | } | 172 | } |
171 | } | 173 | } |
174 | public virtual float TargetSpeed | ||
175 | { | ||
176 | get | ||
177 | { | ||
178 | OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); | ||
179 | return characterOrientedVelocity.X; | ||
180 | } | ||
181 | } | ||
182 | public abstract OMV.Vector3 RawVelocity { get; set; } | ||
172 | public abstract OMV.Vector3 ForceVelocity { get; set; } | 183 | public abstract OMV.Vector3 ForceVelocity { get; set; } |
173 | 184 | ||
174 | public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } | 185 | public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } |
@@ -177,6 +188,15 @@ public abstract class BSPhysObject : PhysicsActor | |||
177 | 188 | ||
178 | public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } | 189 | public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } |
179 | 190 | ||
191 | public virtual float ForwardSpeed | ||
192 | { | ||
193 | get | ||
194 | { | ||
195 | OMV.Vector3 characterOrientedVelocity = RawVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); | ||
196 | return characterOrientedVelocity.X; | ||
197 | } | ||
198 | } | ||
199 | |||
180 | #region Collisions | 200 | #region Collisions |
181 | 201 | ||
182 | // Requested number of milliseconds between collision events. Zero means disabled. | 202 | // Requested number of milliseconds between collision events. Zero means disabled. |
@@ -223,9 +243,13 @@ public abstract class BSPhysObject : PhysicsActor | |||
223 | 243 | ||
224 | // The collisions that have been collected this tick | 244 | // The collisions that have been collected this tick |
225 | protected CollisionEventUpdate CollisionCollection; | 245 | protected CollisionEventUpdate CollisionCollection; |
246 | // Remember collisions from last tick for fancy collision based actions | ||
247 | // (like a BSCharacter walking up stairs). | ||
248 | protected CollisionEventUpdate CollisionsLastTick; | ||
226 | 249 | ||
227 | // The simulation step is telling this object about a collision. | 250 | // The simulation step is telling this object about a collision. |
228 | // Return 'true' if a collision was processed and should be sent up. | 251 | // Return 'true' if a collision was processed and should be sent up. |
252 | // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. | ||
229 | // Called at taint time from within the Step() function | 253 | // Called at taint time from within the Step() function |
230 | public virtual bool Collide(uint collidingWith, BSPhysObject collidee, | 254 | public virtual bool Collide(uint collidingWith, BSPhysObject collidee, |
231 | OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) | 255 | OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) |
@@ -286,6 +310,9 @@ public abstract class BSPhysObject : PhysicsActor | |||
286 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); | 310 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); |
287 | base.SendCollisionUpdate(CollisionCollection); | 311 | base.SendCollisionUpdate(CollisionCollection); |
288 | 312 | ||
313 | // Remember the collisions from this tick for some collision specific processing. | ||
314 | CollisionsLastTick = CollisionCollection; | ||
315 | |||
289 | // The CollisionCollection instance is passed around in the simulator. | 316 | // The CollisionCollection instance is passed around in the simulator. |
290 | // Make sure we don't have a handle to that one and that a new one is used for next time. | 317 | // Make sure we don't have a handle to that one and that a new one is used for next time. |
291 | // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, | 318 | // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 94b63e5..400d5d6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -562,7 +562,7 @@ public sealed class BSPrim : BSPhysObject | |||
562 | } | 562 | } |
563 | return; | 563 | return; |
564 | } | 564 | } |
565 | public OMV.Vector3 RawVelocity | 565 | public override OMV.Vector3 RawVelocity |
566 | { | 566 | { |
567 | get { return _velocity; } | 567 | get { return _velocity; } |
568 | set { _velocity = value; } | 568 | set { _velocity = value; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7b59e60..794a6af 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -88,6 +88,8 @@ setForce should set a constant force. Different than AddImpulse. | |||
88 | Implement raycast. | 88 | Implement raycast. |
89 | Implement ShapeCollection.Dispose() | 89 | Implement ShapeCollection.Dispose() |
90 | Implement water as a plain so raycasting and collisions can happen with same. | 90 | Implement water as a plain so raycasting and collisions can happen with same. |
91 | Add collision penetration return | ||
92 | Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance() | ||
91 | Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE | 93 | Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE |
92 | Also osGetPhysicsEngineVerion() maybe. | 94 | Also osGetPhysicsEngineVerion() maybe. |
93 | Linkset.Position and Linkset.Orientation requre rewrite to properly return | 95 | Linkset.Position and Linkset.Orientation requre rewrite to properly return |