diff options
author | Teravus Ovares | 2008-01-13 07:14:54 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-01-13 07:14:54 +0000 |
commit | d9e45332022b18b50f00353588afd4bbe3392870 (patch) | |
tree | dcc39ec2e123052bc25f6b529dfd0821c47e4908 /OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |
parent | Thank you very much, Kinoc for implementing llGetSubString and llDeleteSubStr... (diff) | |
download | opensim-SC_OLD-d9e45332022b18b50f00353588afd4bbe3392870.zip opensim-SC_OLD-d9e45332022b18b50f00353588afd4bbe3392870.tar.gz opensim-SC_OLD-d9e45332022b18b50f00353588afd4bbe3392870.tar.bz2 opensim-SC_OLD-d9e45332022b18b50f00353588afd4bbe3392870.tar.xz |
* Fixed an overflow in the land manager
* Did some goofy math undoing in the Sim Stats Reporter
* More reduction to the amount of calls per second to UnManaged ODE code
* Added a significant amount of comments to ODE
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODECharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 247 |
1 files changed, 181 insertions, 66 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 8e92171..b824cbe 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |||
@@ -34,6 +34,26 @@ using OpenSim.Region.Physics.Manager; | |||
34 | 34 | ||
35 | namespace OpenSim.Region.Physics.OdePlugin | 35 | namespace OpenSim.Region.Physics.OdePlugin |
36 | { | 36 | { |
37 | /// <summary> | ||
38 | /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves. | ||
39 | /// </summary> | ||
40 | |||
41 | public enum dParam : int | ||
42 | { | ||
43 | LowStop = 0, | ||
44 | HiStop = 1, | ||
45 | Vel = 2, | ||
46 | FMax = 3, | ||
47 | FudgeFactor = 4, | ||
48 | Bounce = 5, | ||
49 | CFM = 6, | ||
50 | ERP = 7, | ||
51 | StopCFM = 8, | ||
52 | LoStop2 = 256, | ||
53 | HiStop2 = 257, | ||
54 | LoStop3 = 512, | ||
55 | HiStop3 = 513 | ||
56 | } | ||
37 | public class OdeCharacter : PhysicsActor | 57 | public class OdeCharacter : PhysicsActor |
38 | { | 58 | { |
39 | private PhysicsVector _position; | 59 | private PhysicsVector _position; |
@@ -45,7 +65,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
45 | private PhysicsVector _target_velocity; | 65 | private PhysicsVector _target_velocity; |
46 | private PhysicsVector _acceleration; | 66 | private PhysicsVector _acceleration; |
47 | private PhysicsVector m_rotationalVelocity; | 67 | private PhysicsVector m_rotationalVelocity; |
48 | private float m_density = 50f; | 68 | private float m_mass = 80f; |
69 | private float m_density = 60f; | ||
49 | private bool m_pidControllerActive = true; | 70 | private bool m_pidControllerActive = true; |
50 | private static float PID_D = 3020.0f; | 71 | private static float PID_D = 3020.0f; |
51 | private static float PID_P = 7000.0f; | 72 | private static float PID_P = 7000.0f; |
@@ -96,34 +117,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
96 | 117 | ||
97 | lock (OdeScene.OdeLock) | 118 | lock (OdeScene.OdeLock) |
98 | { | 119 | { |
99 | int dAMotorEuler = 1; | 120 | AvatarGeomAndBodyCreation(pos.X, pos.Y, pos.Z); |
100 | Shell = d.CreateCapsule(parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
101 | d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
102 | Body = d.BodyCreate(parent_scene.world); | ||
103 | d.BodySetMass(Body, ref ShellMass); | ||
104 | d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); | ||
105 | d.GeomSetBody(Shell, Body); | ||
106 | |||
107 | |||
108 | d.BodySetRotation(Body, ref m_StandUpRotation); | ||
109 | |||
110 | |||
111 | //Amotor = d.JointCreateAMotor(parent_scene.world, IntPtr.Zero); | ||
112 | //d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
113 | //d.JointSetAMotorMode(Amotor, dAMotorEuler); | ||
114 | //d.JointSetAMotorNumAxes(Amotor, 3); | ||
115 | //d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); | ||
116 | //d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); | ||
117 | ///d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); | ||
118 | //d.JointSetAMotorAngle(Amotor, 0, 0); | ||
119 | //d.JointSetAMotorAngle(Amotor, 1, 0); | ||
120 | //d.JointSetAMotorAngle(Amotor, 2, 0); | ||
121 | //d.JointSetAMotorParam(Amotor, 0, -0); | ||
122 | //d.JointSetAMotorParam(Amotor, 0x200, -0); | ||
123 | //d.JointSetAMotorParam(Amotor, 0x100, -0); | ||
124 | // d.JointSetAMotorParam(Amotor, 0, 0); | ||
125 | // d.JointSetAMotorParam(Amotor, 3, 0); | ||
126 | // d.JointSetAMotorParam(Amotor, 2, 0); | ||
127 | } | 121 | } |
128 | m_name = avName; | 122 | m_name = avName; |
129 | parent_scene.geom_name_map[Shell] = avName; | 123 | parent_scene.geom_name_map[Shell] = avName; |
@@ -136,6 +130,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
136 | set { return; } | 130 | set { return; } |
137 | } | 131 | } |
138 | 132 | ||
133 | /// <summary> | ||
134 | /// If this is set, the avatar will move faster | ||
135 | /// </summary> | ||
139 | public override bool SetAlwaysRun | 136 | public override bool SetAlwaysRun |
140 | { | 137 | { |
141 | get { return m_alwaysRun; } | 138 | get { return m_alwaysRun; } |
@@ -160,6 +157,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
160 | set { flying = value; } | 157 | set { flying = value; } |
161 | } | 158 | } |
162 | 159 | ||
160 | /// <summary> | ||
161 | /// Returns if the avatar is colliding in general. | ||
162 | /// This includes the ground and objects and avatar. | ||
163 | /// </summary> | ||
163 | public override bool IsColliding | 164 | public override bool IsColliding |
164 | { | 165 | { |
165 | get { return m_iscolliding; } | 166 | get { return m_iscolliding; } |
@@ -208,11 +209,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
208 | } | 209 | } |
209 | } | 210 | } |
210 | 211 | ||
212 | /// <summary> | ||
213 | /// Returns if an avatar is colliding with the ground | ||
214 | /// </summary> | ||
211 | public override bool CollidingGround | 215 | public override bool CollidingGround |
212 | { | 216 | { |
213 | get { return m_iscollidingGround; } | 217 | get { return m_iscollidingGround; } |
214 | set | 218 | set |
215 | { | 219 | { |
220 | // Collisions against the ground are not really reliable | ||
221 | // So, to get a consistant value we have to average the current result over time | ||
222 | // Currently we use 1 second = 10 calls to this. | ||
216 | int i; | 223 | int i; |
217 | int truecount = 0; | 224 | int truecount = 0; |
218 | int falsecount = 0; | 225 | int falsecount = 0; |
@@ -256,6 +263,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
256 | } | 263 | } |
257 | } | 264 | } |
258 | 265 | ||
266 | /// <summary> | ||
267 | /// Returns if the avatar is colliding with an object | ||
268 | /// </summary> | ||
259 | public override bool CollidingObj | 269 | public override bool CollidingObj |
260 | { | 270 | { |
261 | get { return m_iscollidingObj; } | 271 | get { return m_iscollidingObj; } |
@@ -269,11 +279,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
269 | } | 279 | } |
270 | } | 280 | } |
271 | 281 | ||
282 | /// <summary> | ||
283 | /// turn the PID controller on or off. | ||
284 | /// The PID Controller will turn on all by itself in many situations | ||
285 | /// </summary> | ||
286 | /// <param name="status"></param> | ||
272 | public void SetPidStatus(bool status) | 287 | public void SetPidStatus(bool status) |
273 | { | 288 | { |
274 | m_pidControllerActive = status; | 289 | m_pidControllerActive = status; |
275 | } | 290 | } |
276 | 291 | ||
292 | /// <summary> | ||
293 | /// This 'puts' an avatar somewhere in the physics space. | ||
294 | /// Not really a good choice unless you 'know' it's a good | ||
295 | /// spot otherwise you're likely to orbit the avatar. | ||
296 | /// </summary> | ||
277 | public override PhysicsVector Position | 297 | public override PhysicsVector Position |
278 | { | 298 | { |
279 | get { return _position; } | 299 | get { return _position; } |
@@ -293,6 +313,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
293 | set { m_rotationalVelocity = value; } | 313 | set { m_rotationalVelocity = value; } |
294 | } | 314 | } |
295 | 315 | ||
316 | /// <summary> | ||
317 | /// This property sets the height of the avatar only. We use the height to make sure the avatar stands up straight | ||
318 | /// and use it to offset landings properly | ||
319 | /// </summary> | ||
296 | public override PhysicsVector Size | 320 | public override PhysicsVector Size |
297 | { | 321 | { |
298 | get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); } | 322 | get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); } |
@@ -301,6 +325,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
301 | m_pidControllerActive = true; | 325 | m_pidControllerActive = true; |
302 | lock (OdeScene.OdeLock) | 326 | lock (OdeScene.OdeLock) |
303 | { | 327 | { |
328 | d.JointDestroy(Amotor); | ||
304 | PhysicsVector SetSize = value; | 329 | PhysicsVector SetSize = value; |
305 | float prevCapsule = CAPSULE_LENGTH; | 330 | float prevCapsule = CAPSULE_LENGTH; |
306 | float capsuleradius = CAPSULE_RADIUS; | 331 | float capsuleradius = CAPSULE_RADIUS; |
@@ -309,20 +334,91 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
309 | CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z*0.43f))); // subtract 43% of the size | 334 | CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z*0.43f))); // subtract 43% of the size |
310 | d.BodyDestroy(Body); | 335 | d.BodyDestroy(Body); |
311 | d.GeomDestroy(Shell); | 336 | d.GeomDestroy(Shell); |
312 | //MainLog.Instance.Verbose("PHYSICS", "Set Avatar Height To: " + (CAPSULE_RADIUS + CAPSULE_LENGTH)); | 337 | AvatarGeomAndBodyCreation(_position.X, _position.Y, |
313 | Shell = d.CreateCapsule(_parent_scene.space, capsuleradius, CAPSULE_LENGTH); | 338 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule)*2)); |
314 | d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); | 339 | Velocity = new PhysicsVector(0f, 0f, 0f); |
315 | Body = d.BodyCreate(_parent_scene.world); | 340 | |
316 | d.BodySetMass(Body, ref ShellMass); | ||
317 | d.BodySetPosition(Body, _position.X, _position.Y, | ||
318 | _position.Z + Math.Abs(CAPSULE_LENGTH - prevCapsule)); | ||
319 | d.GeomSetBody(Shell, Body); | ||
320 | } | 341 | } |
321 | _parent_scene.geom_name_map[Shell] = m_name; | 342 | _parent_scene.geom_name_map[Shell] = m_name; |
322 | _parent_scene.actor_name_map[Shell] = (PhysicsActor) this; | 343 | _parent_scene.actor_name_map[Shell] = (PhysicsActor) this; |
323 | } | 344 | } |
324 | } | 345 | } |
346 | /// <summary> | ||
347 | /// This creates the Avatar's physical Surrogate at the position supplied | ||
348 | /// </summary> | ||
349 | /// <param name="npositionX"></param> | ||
350 | /// <param name="npositionY"></param> | ||
351 | /// <param name="npositionZ"></param> | ||
352 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) | ||
353 | { | ||
354 | int dAMotorEuler = 1; | ||
355 | Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
356 | d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
357 | Body = d.BodyCreate(_parent_scene.world); | ||
358 | d.BodySetPosition(Body, npositionX, npositionY, npositionZ); | ||
359 | |||
360 | d.BodySetMass(Body, ref ShellMass); | ||
361 | |||
362 | // 90 Stand up on the cap of the capped cyllinder | ||
363 | d.RFromAxisAndAngle(out m_StandUpRotation, 1, 0, 0, (float)(Math.PI / 2)); | ||
364 | |||
365 | |||
366 | d.GeomSetRotation(Shell, ref m_StandUpRotation); | ||
367 | d.BodySetRotation(Body, ref m_StandUpRotation); | ||
368 | |||
369 | d.GeomSetBody(Shell, Body); | ||
370 | |||
371 | |||
372 | // The purpose of the AMotor here is to keep the avatar's physical | ||
373 | // surrogate from rotating while moving | ||
374 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | ||
375 | d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
376 | d.JointSetAMotorMode(Amotor, dAMotorEuler); | ||
377 | d.JointSetAMotorNumAxes(Amotor, 3); | ||
378 | d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); | ||
379 | d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); | ||
380 | d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); | ||
381 | d.JointSetAMotorAngle(Amotor, 0, 0); | ||
382 | d.JointSetAMotorAngle(Amotor, 1, 0); | ||
383 | d.JointSetAMotorAngle(Amotor, 2, 0); | ||
384 | |||
385 | // These lowstops and high stops are effectively (no wiggle room) | ||
386 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); | ||
387 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); | ||
388 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); | ||
389 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); | ||
390 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); | ||
391 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); | ||
392 | |||
393 | // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the | ||
394 | // capped cyllinder will fall over | ||
395 | d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); | ||
396 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 3800000f); | ||
397 | |||
398 | |||
399 | // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air. | ||
400 | // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you | ||
401 | // change appearance and when you enter the simulator | ||
402 | // After this routine is done, the amotor stabilizes much quicker | ||
403 | d.Vector3 feet; | ||
404 | d.Vector3 head; | ||
405 | d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet); | ||
406 | d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head); | ||
407 | float posture = head.Z - feet.Z; | ||
408 | |||
409 | // restoring force proportional to lack of posture: | ||
410 | float servo = (2.5f - posture) * POSTURE_SERVO; | ||
411 | d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); | ||
412 | d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); | ||
413 | |||
414 | |||
415 | } | ||
325 | 416 | ||
417 | // | ||
418 | /// <summary> | ||
419 | /// Uses the capped cyllinder volume formula to calculate the avatar's mass. | ||
420 | /// This may be used in calculations in the scene/scenepresence | ||
421 | /// </summary> | ||
326 | public override float Mass | 422 | public override float Mass |
327 | { | 423 | { |
328 | get | 424 | get |
@@ -385,6 +481,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
385 | _acceleration = accel; | 481 | _acceleration = accel; |
386 | } | 482 | } |
387 | 483 | ||
484 | /// <summary> | ||
485 | /// Adds the force supplied to the Target Velocity | ||
486 | /// The PID controller takes this target velocity and tries to make it a reality | ||
487 | /// </summary> | ||
488 | /// <param name="force"></param> | ||
388 | public override void AddForce(PhysicsVector force) | 489 | public override void AddForce(PhysicsVector force) |
389 | { | 490 | { |
390 | m_pidControllerActive = true; | 491 | m_pidControllerActive = true; |
@@ -395,29 +496,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
395 | //m_lastUpdateSent = false; | 496 | //m_lastUpdateSent = false; |
396 | } | 497 | } |
397 | 498 | ||
499 | /// <summary> | ||
500 | /// After all of the forces add up with 'add force' we apply them with doForce | ||
501 | /// </summary> | ||
502 | /// <param name="force"></param> | ||
398 | public void doForce(PhysicsVector force) | 503 | public void doForce(PhysicsVector force) |
399 | { | 504 | { |
400 | if (!collidelock) | 505 | if (!collidelock) |
401 | { | 506 | { |
402 | d.BodyAddForce(Body, force.X, force.Y, force.Z); | 507 | d.BodyAddForce(Body, force.X, force.Y, force.Z); |
403 | |||
404 | // ok -- let's stand up straight! | ||
405 | //d.Matrix3 StandUpRotationalMatrix = new d.Matrix3(0.8184158f, -0.5744568f, -0.0139677f, 0.5744615f, 0.8185215f, -0.004074608f, 0.01377355f, -0.004689182f, 0.9998941f); | ||
406 | //d.BodySetRotation(Body, ref StandUpRotationalMatrix); | ||
407 | //d.BodySetRotation(Body, ref m_StandUpRotation); | ||
408 | // The above matrix was generated with the amazing standup routine below by danX0r *cheer* | ||
409 | d.Vector3 feet; | ||
410 | d.Vector3 head; | ||
411 | d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet); | ||
412 | d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head); | ||
413 | float posture = head.Z - feet.Z; | ||
414 | |||
415 | // restoring force proportional to lack of posture: | ||
416 | float servo = (2.5f - posture) * POSTURE_SERVO; | ||
417 | d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); | ||
418 | d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); | ||
419 | |||
420 | //m_lastUpdateSent = false; | ||
421 | } | 508 | } |
422 | } | 509 | } |
423 | 510 | ||
@@ -425,9 +512,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
425 | { | 512 | { |
426 | } | 513 | } |
427 | 514 | ||
515 | |||
516 | /// <summary> | ||
517 | /// Called from Simulate | ||
518 | /// This is the avatar's movement control + PID Controller | ||
519 | /// </summary> | ||
520 | /// <param name="timeStep"></param> | ||
428 | public void Move(float timeStep) | 521 | public void Move(float timeStep) |
429 | { | 522 | { |
430 | // no lock; for now it's only called from within Simulate() | 523 | // no lock; for now it's only called from within Simulate() |
524 | |||
525 | // If the PID Controller isn't active then we set our force | ||
526 | // calculating base velocity to the current position | ||
527 | |||
431 | if (m_pidControllerActive == false) | 528 | if (m_pidControllerActive == false) |
432 | { | 529 | { |
433 | _zeroPosition = d.BodyGetPosition(Body); | 530 | _zeroPosition = d.BodyGetPosition(Body); |
@@ -458,6 +555,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
458 | } | 555 | } |
459 | if (m_pidControllerActive) | 556 | if (m_pidControllerActive) |
460 | { | 557 | { |
558 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | ||
559 | // react to the physics scene by moving it's position. | ||
560 | // Avatar to Avatar collisions | ||
561 | // Prim to avatar collisions | ||
562 | |||
461 | d.Vector3 pos = d.BodyGetPosition(Body); | 563 | d.Vector3 pos = d.BodyGetPosition(Body); |
462 | vec.X = (_target_velocity.X - vel.X)*PID_D + (_zeroPosition.X - pos.X)*PID_P; | 564 | vec.X = (_target_velocity.X - vel.X)*PID_D + (_zeroPosition.X - pos.X)*PID_P; |
463 | vec.Y = (_target_velocity.Y - vel.Y)*PID_D + (_zeroPosition.Y - pos.Y)*PID_P; | 565 | vec.Y = (_target_velocity.Y - vel.Y)*PID_D + (_zeroPosition.Y - pos.Y)*PID_P; |
@@ -474,11 +576,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
474 | _zeroFlag = false; | 576 | _zeroFlag = false; |
475 | if (m_iscolliding || flying) | 577 | if (m_iscolliding || flying) |
476 | { | 578 | { |
579 | // We're flying and colliding with something | ||
477 | vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*PID_D; | 580 | vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*PID_D; |
478 | vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*PID_D; | 581 | vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*PID_D; |
479 | } | 582 | } |
480 | if (m_iscolliding && !flying && _target_velocity.Z > 0.0f) | 583 | if (m_iscolliding && !flying && _target_velocity.Z > 0.0f) |
481 | { | 584 | { |
585 | // We're colliding with something and we're not flying but we're moving | ||
586 | // This means we're walking or running. | ||
482 | d.Vector3 pos = d.BodyGetPosition(Body); | 587 | d.Vector3 pos = d.BodyGetPosition(Body); |
483 | vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P; | 588 | vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P; |
484 | if (_target_velocity.X > 0) | 589 | if (_target_velocity.X > 0) |
@@ -492,6 +597,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
492 | } | 597 | } |
493 | else if (!m_iscolliding && !flying) | 598 | else if (!m_iscolliding && !flying) |
494 | { | 599 | { |
600 | // we're not colliding and we're not flying so that means we're falling! | ||
601 | // m_iscolliding includes collisions with the ground. | ||
495 | d.Vector3 pos = d.BodyGetPosition(Body); | 602 | d.Vector3 pos = d.BodyGetPosition(Body); |
496 | if (_target_velocity.X > 0) | 603 | if (_target_velocity.X > 0) |
497 | { | 604 | { |
@@ -518,6 +625,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
518 | doForce(vec); | 625 | doForce(vec); |
519 | } | 626 | } |
520 | 627 | ||
628 | /// <summary> | ||
629 | /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. | ||
630 | /// </summary> | ||
521 | public void UpdatePositionAndVelocity() | 631 | public void UpdatePositionAndVelocity() |
522 | { | 632 | { |
523 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 633 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
@@ -533,25 +643,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
533 | _position.Y = vec.Y; | 643 | _position.Y = vec.Y; |
534 | _position.Z = vec.Z; | 644 | _position.Z = vec.Z; |
535 | 645 | ||
646 | // Did we move last? = zeroflag | ||
647 | // This helps keep us from sliding all over | ||
648 | |||
536 | if (_zeroFlag) | 649 | if (_zeroFlag) |
537 | { | 650 | { |
538 | _velocity.X = 0.0f; | 651 | _velocity.X = 0.0f; |
539 | _velocity.Y = 0.0f; | 652 | _velocity.Y = 0.0f; |
540 | _velocity.Z = 0.0f; | 653 | _velocity.Z = 0.0f; |
654 | |||
655 | // Did we send out the 'stopped' message? | ||
541 | if (!m_lastUpdateSent) | 656 | if (!m_lastUpdateSent) |
542 | { | 657 | { |
543 | m_lastUpdateSent = true; | 658 | m_lastUpdateSent = true; |
544 | base.RequestPhysicsterseUpdate(); | 659 | base.RequestPhysicsterseUpdate(); |
545 | //string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); | 660 | |
546 | //int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); | ||
547 | //if (primScenAvatarIn == "0") | ||
548 | //{ | ||
549 | //MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); | ||
550 | //} | ||
551 | //else | ||
552 | //{ | ||
553 | // MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); | ||
554 | //} | ||
555 | } | 661 | } |
556 | } | 662 | } |
557 | else | 663 | else |
@@ -564,6 +670,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
564 | _velocity.Z = (vec.Z); | 670 | _velocity.Z = (vec.Z); |
565 | if (_velocity.Z < -6 && !m_hackSentFall) | 671 | if (_velocity.Z < -6 && !m_hackSentFall) |
566 | { | 672 | { |
673 | // Collisionupdates will be used in the future, right now the're not being used. | ||
567 | m_hackSentFall = true; | 674 | m_hackSentFall = true; |
568 | //base.SendCollisionUpdate(new CollisionEventUpdate()); | 675 | //base.SendCollisionUpdate(new CollisionEventUpdate()); |
569 | m_pidControllerActive = false; | 676 | m_pidControllerActive = false; |
@@ -581,13 +688,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
581 | } | 688 | } |
582 | } | 689 | } |
583 | 690 | ||
691 | /// <summary> | ||
692 | /// Cleanup the things we use in the scene. | ||
693 | /// </summary> | ||
584 | public void Destroy() | 694 | public void Destroy() |
585 | { | 695 | { |
586 | lock (OdeScene.OdeLock) | 696 | lock (OdeScene.OdeLock) |
587 | { | 697 | { |
588 | // d.JointDestroy(Amotor); | 698 | // Kill the Amotor |
699 | d.JointDestroy(Amotor); | ||
700 | |||
701 | //kill the Geometry | ||
589 | d.GeomDestroy(Shell); | 702 | d.GeomDestroy(Shell); |
590 | _parent_scene.geom_name_map.Remove(Shell); | 703 | _parent_scene.geom_name_map.Remove(Shell); |
704 | |||
705 | //kill the body | ||
591 | d.BodyDestroy(Body); | 706 | d.BodyDestroy(Body); |
592 | } | 707 | } |
593 | } | 708 | } |