diff options
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 563 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 51 |
3 files changed, 378 insertions, 250 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index b0b91f6..cf7fdca 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | 28 | ||
29 | // Revision by Ubit 2011 | 29 | // Revision by Ubit 2011/12 |
30 | 30 | ||
31 | using System; | 31 | using System; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
@@ -95,21 +95,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
95 | private bool m_iscollidingObj = false; | 95 | private bool m_iscollidingObj = false; |
96 | private bool m_alwaysRun = false; | 96 | private bool m_alwaysRun = false; |
97 | private int m_requestedUpdateFrequency = 0; | 97 | private int m_requestedUpdateFrequency = 0; |
98 | private Vector3 m_taintPosition = Vector3.Zero; | ||
99 | private bool m_hasTaintPosition = false; | ||
100 | public uint m_localID = 0; | 98 | public uint m_localID = 0; |
101 | public bool m_returnCollisions = false; | 99 | public bool m_returnCollisions = false; |
102 | // taints and their non-tainted counterparts | 100 | // taints and their non-tainted counterparts |
103 | public bool m_isPhysical = false; // the current physical status | 101 | public bool m_isPhysical = false; // the current physical status |
104 | public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing) | ||
105 | public float MinimumGroundFlightOffset = 3f; | 102 | public float MinimumGroundFlightOffset = 3f; |
106 | 103 | ||
107 | |||
108 | private Vector3 m_taintForce; | ||
109 | private bool m_hasTaintForce; | ||
110 | private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. | ||
111 | |||
112 | |||
113 | private float m_buoyancy = 0f; | 104 | private float m_buoyancy = 0f; |
114 | 105 | ||
115 | // private CollisionLocker ode; | 106 | // private CollisionLocker ode; |
@@ -151,15 +142,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
151 | { | 142 | { |
152 | m_uuid = UUID.Random(); | 143 | m_uuid = UUID.Random(); |
153 | 144 | ||
154 | m_hasTaintPosition = false; | ||
155 | |||
156 | if (pos.IsFinite()) | 145 | if (pos.IsFinite()) |
157 | { | 146 | { |
158 | if (pos.Z > 9999999f) | 147 | if (pos.Z > 99999f) |
159 | { | 148 | { |
160 | pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; | 149 | pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; |
161 | } | 150 | } |
162 | if (pos.Z < -90000f) | 151 | if (pos.Z < -100f) // shouldn't this be 0 ? |
163 | { | 152 | { |
164 | pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; | 153 | pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; |
165 | } | 154 | } |
@@ -187,15 +176,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
187 | 176 | ||
188 | CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f; | 177 | CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f; |
189 | //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); | 178 | //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); |
190 | m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH; | ||
191 | 179 | ||
192 | m_isPhysical = false; // current status: no ODE information exists | 180 | m_isPhysical = false; // current status: no ODE information exists |
193 | m_tainted_isPhysical = true; // new tainted status: need to create ODE information | ||
194 | |||
195 | m_hasTaintForce = false; | ||
196 | _parent_scene.AddPhysicsActorTaint(this); | ||
197 | 181 | ||
198 | m_name = avName; | 182 | m_name = avName; |
183 | |||
184 | AddChange(changes.Add, null); | ||
199 | } | 185 | } |
200 | 186 | ||
201 | public override int PhysicsActorType | 187 | public override int PhysicsActorType |
@@ -402,16 +388,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
402 | { | 388 | { |
403 | value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; | 389 | value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; |
404 | } | 390 | } |
405 | if (value.Z < -90000f) | 391 | if (value.Z < -100f) |
406 | { | 392 | { |
407 | value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; | 393 | value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; |
408 | } | 394 | } |
409 | 395 | AddChange(changes.Position, value); | |
410 | m_taintPosition.X = value.X; | ||
411 | m_taintPosition.Y = value.Y; | ||
412 | m_taintPosition.Z = value.Z; | ||
413 | m_hasTaintPosition = true; | ||
414 | _parent_scene.AddPhysicsActorTaint(this); | ||
415 | } | 396 | } |
416 | else | 397 | else |
417 | { | 398 | { |
@@ -440,11 +421,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
440 | { | 421 | { |
441 | if (value.IsFinite()) | 422 | if (value.IsFinite()) |
442 | { | 423 | { |
443 | m_pidControllerActive = true; | 424 | AddChange(changes.Size, value); |
444 | |||
445 | Vector3 SetSize = value; | ||
446 | m_tainted_CAPSULE_LENGTH = SetSize.Z *1.15f - CAPSULE_RADIUS * 2.0f; | ||
447 | _parent_scene.AddPhysicsActorTaint(this); | ||
448 | } | 425 | } |
449 | else | 426 | else |
450 | { | 427 | { |
@@ -460,129 +437,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
460 | /// <param name="npositionY"></param> | 437 | /// <param name="npositionY"></param> |
461 | /// <param name="npositionZ"></param> | 438 | /// <param name="npositionZ"></param> |
462 | 439 | ||
463 | // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access | ||
464 | // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only | ||
465 | // place that is safe to call this routine AvatarGeomAndBodyCreation. | ||
466 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) | ||
467 | { | ||
468 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | ||
469 | if (CAPSULE_LENGTH <= 0) | ||
470 | { | ||
471 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
472 | CAPSULE_LENGTH = 0.01f; | ||
473 | |||
474 | } | ||
475 | |||
476 | if (CAPSULE_RADIUS <= 0) | ||
477 | { | ||
478 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
479 | CAPSULE_RADIUS = 0.01f; | ||
480 | |||
481 | } | ||
482 | Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
483 | |||
484 | d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); | ||
485 | d.GeomSetCollideBits(Shell, (int)m_collisionFlags); | ||
486 | |||
487 | d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
488 | |||
489 | m_mass = ShellMass.mass; // update mass | ||
490 | |||
491 | // rescale PID parameters | ||
492 | PID_D = _parent_scene.avPIDD; | ||
493 | PID_P = _parent_scene.avPIDP; | ||
494 | |||
495 | // rescale PID parameters so that this aren't affected by mass | ||
496 | // and so don't get unstable for some masses | ||
497 | // also scale by ode time step so you don't need to refix them | ||
498 | |||
499 | PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps | ||
500 | PID_D *= m_mass / _parent_scene.ODE_STEPSIZE; | ||
501 | PID_P /= 50 * 80; | ||
502 | PID_P *= m_mass / _parent_scene.ODE_STEPSIZE; | ||
503 | |||
504 | Body = d.BodyCreate(_parent_scene.world); | ||
505 | |||
506 | d.BodySetAutoDisableFlag(Body, false); | ||
507 | d.BodySetPosition(Body, npositionX, npositionY, npositionZ); | ||
508 | |||
509 | _position.X = npositionX; | ||
510 | _position.Y = npositionY; | ||
511 | _position.Z = npositionZ; | ||
512 | |||
513 | m_hasTaintPosition = false; | ||
514 | |||
515 | d.BodySetMass(Body, ref ShellMass); | ||
516 | d.GeomSetBody(Shell, Body); | ||
517 | |||
518 | // The purpose of the AMotor here is to keep the avatar's physical | ||
519 | // surrogate from rotating while moving | ||
520 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | ||
521 | d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
522 | |||
523 | d.JointSetAMotorMode(Amotor, 0); | ||
524 | d.JointSetAMotorNumAxes(Amotor, 3); | ||
525 | d.JointSetAMotorAxis(Amotor, 0, 0 , 1, 0, 0); | ||
526 | d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); | ||
527 | d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); | ||
528 | |||
529 | d.JointSetAMotorAngle(Amotor, 0, 0); | ||
530 | d.JointSetAMotorAngle(Amotor, 1, 0); | ||
531 | d.JointSetAMotorAngle(Amotor, 2, 0); | ||
532 | |||
533 | d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD | ||
534 | d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f); | ||
535 | d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f); | ||
536 | d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f); | ||
537 | d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f); | ||
538 | d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f); | ||
539 | |||
540 | // These lowstops and high stops are effectively (no wiggle room) | ||
541 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f); | ||
542 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f); | ||
543 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f); | ||
544 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f); | ||
545 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f); | ||
546 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f); | ||
547 | |||
548 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); | ||
549 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0); | ||
550 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0); | ||
551 | |||
552 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f); | ||
553 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f); | ||
554 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f); | ||
555 | } | ||
556 | |||
557 | /// <summary> | ||
558 | /// Destroys the avatar body and geom | ||
559 | |||
560 | private void AvatarGeomAndBodyDestroy() | ||
561 | { | ||
562 | // Kill the Amotor | ||
563 | if (Amotor != IntPtr.Zero) | ||
564 | { | ||
565 | d.JointDestroy(Amotor); | ||
566 | Amotor = IntPtr.Zero; | ||
567 | } | ||
568 | |||
569 | if (Body != IntPtr.Zero) | ||
570 | { | ||
571 | //kill the body | ||
572 | d.BodyDestroy(Body); | ||
573 | Body = IntPtr.Zero; | ||
574 | } | ||
575 | |||
576 | //kill the Geometry | ||
577 | if (Shell != IntPtr.Zero) | ||
578 | { | ||
579 | _parent_scene.geom_name_map.Remove(Shell); | ||
580 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | ||
581 | d.GeomDestroy(Shell); | ||
582 | _parent_scene.geom_name_map.Remove(Shell); | ||
583 | Shell = IntPtr.Zero; | ||
584 | } | ||
585 | } | ||
586 | // | 440 | // |
587 | /// <summary> | 441 | /// <summary> |
588 | /// Uses the capped cyllinder volume formula to calculate the avatar's mass. | 442 | /// Uses the capped cyllinder volume formula to calculate the avatar's mass. |
@@ -705,8 +559,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
705 | { | 559 | { |
706 | if (value.IsFinite()) | 560 | if (value.IsFinite()) |
707 | { | 561 | { |
708 | m_pidControllerActive = true; | 562 | AddChange(changes.Velocity, value); |
709 | _target_velocity = value; | ||
710 | } | 563 | } |
711 | else | 564 | else |
712 | { | 565 | { |
@@ -738,9 +591,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
738 | get { return Quaternion.Identity; } | 591 | get { return Quaternion.Identity; } |
739 | set | 592 | set |
740 | { | 593 | { |
741 | //Matrix3 or = Orientation.ToRotationMatrix(); | ||
742 | //d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22); | ||
743 | //d.BodySetRotation(Body, ref ord); | ||
744 | } | 594 | } |
745 | } | 595 | } |
746 | 596 | ||
@@ -767,18 +617,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
767 | { | 617 | { |
768 | if (pushforce) | 618 | if (pushforce) |
769 | { | 619 | { |
770 | m_pidControllerActive = false; | 620 | AddChange(changes.Force, force * m_density / _parent_scene.ODE_STEPSIZE / 28f); |
771 | // scale with odetime step and density | ||
772 | m_taintForce = force * m_density / _parent_scene.ODE_STEPSIZE / 28f; | ||
773 | m_hasTaintForce = true; | ||
774 | _parent_scene.AddPhysicsActorTaint(this); | ||
775 | } | 621 | } |
776 | else | 622 | else |
777 | { | 623 | { |
778 | m_pidControllerActive = true; | 624 | AddChange(changes.Velocity, force); |
779 | _target_velocity.X += force.X; | ||
780 | _target_velocity.Y += force.Y; | ||
781 | _target_velocity.Z += force.Z; | ||
782 | } | 625 | } |
783 | } | 626 | } |
784 | else | 627 | else |
@@ -798,6 +641,128 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
798 | } | 641 | } |
799 | 642 | ||
800 | 643 | ||
644 | // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access | ||
645 | // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only | ||
646 | // place that is safe to call this routine AvatarGeomAndBodyCreation. | ||
647 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) | ||
648 | { | ||
649 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | ||
650 | if (CAPSULE_LENGTH <= 0) | ||
651 | { | ||
652 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
653 | CAPSULE_LENGTH = 0.01f; | ||
654 | |||
655 | } | ||
656 | |||
657 | if (CAPSULE_RADIUS <= 0) | ||
658 | { | ||
659 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
660 | CAPSULE_RADIUS = 0.01f; | ||
661 | |||
662 | } | ||
663 | Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
664 | |||
665 | d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); | ||
666 | d.GeomSetCollideBits(Shell, (int)m_collisionFlags); | ||
667 | |||
668 | d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
669 | |||
670 | m_mass = ShellMass.mass; // update mass | ||
671 | |||
672 | // rescale PID parameters | ||
673 | PID_D = _parent_scene.avPIDD; | ||
674 | PID_P = _parent_scene.avPIDP; | ||
675 | |||
676 | // rescale PID parameters so that this aren't affected by mass | ||
677 | // and so don't get unstable for some masses | ||
678 | // also scale by ode time step so you don't need to refix them | ||
679 | |||
680 | PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps | ||
681 | PID_D *= m_mass / _parent_scene.ODE_STEPSIZE; | ||
682 | PID_P /= 50 * 80; | ||
683 | PID_P *= m_mass / _parent_scene.ODE_STEPSIZE; | ||
684 | |||
685 | Body = d.BodyCreate(_parent_scene.world); | ||
686 | |||
687 | d.BodySetAutoDisableFlag(Body, false); | ||
688 | d.BodySetPosition(Body, npositionX, npositionY, npositionZ); | ||
689 | |||
690 | _position.X = npositionX; | ||
691 | _position.Y = npositionY; | ||
692 | _position.Z = npositionZ; | ||
693 | |||
694 | d.BodySetMass(Body, ref ShellMass); | ||
695 | d.GeomSetBody(Shell, Body); | ||
696 | |||
697 | // The purpose of the AMotor here is to keep the avatar's physical | ||
698 | // surrogate from rotating while moving | ||
699 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | ||
700 | d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
701 | |||
702 | d.JointSetAMotorMode(Amotor, 0); | ||
703 | d.JointSetAMotorNumAxes(Amotor, 3); | ||
704 | d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); | ||
705 | d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); | ||
706 | d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); | ||
707 | |||
708 | d.JointSetAMotorAngle(Amotor, 0, 0); | ||
709 | d.JointSetAMotorAngle(Amotor, 1, 0); | ||
710 | d.JointSetAMotorAngle(Amotor, 2, 0); | ||
711 | |||
712 | d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD | ||
713 | d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f); | ||
714 | d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f); | ||
715 | d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f); | ||
716 | d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f); | ||
717 | d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f); | ||
718 | |||
719 | // These lowstops and high stops are effectively (no wiggle room) | ||
720 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f); | ||
721 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f); | ||
722 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f); | ||
723 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f); | ||
724 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f); | ||
725 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f); | ||
726 | |||
727 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); | ||
728 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0); | ||
729 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0); | ||
730 | |||
731 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f); | ||
732 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f); | ||
733 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f); | ||
734 | } | ||
735 | |||
736 | /// <summary> | ||
737 | /// Destroys the avatar body and geom | ||
738 | |||
739 | private void AvatarGeomAndBodyDestroy() | ||
740 | { | ||
741 | // Kill the Amotor | ||
742 | if (Amotor != IntPtr.Zero) | ||
743 | { | ||
744 | d.JointDestroy(Amotor); | ||
745 | Amotor = IntPtr.Zero; | ||
746 | } | ||
747 | |||
748 | if (Body != IntPtr.Zero) | ||
749 | { | ||
750 | //kill the body | ||
751 | d.BodyDestroy(Body); | ||
752 | Body = IntPtr.Zero; | ||
753 | } | ||
754 | |||
755 | //kill the Geometry | ||
756 | if (Shell != IntPtr.Zero) | ||
757 | { | ||
758 | _parent_scene.geom_name_map.Remove(Shell); | ||
759 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | ||
760 | d.GeomDestroy(Shell); | ||
761 | _parent_scene.geom_name_map.Remove(Shell); | ||
762 | Shell = IntPtr.Zero; | ||
763 | } | ||
764 | } | ||
765 | |||
801 | /// <summary> | 766 | /// <summary> |
802 | /// Called from Simulate | 767 | /// Called from Simulate |
803 | /// This is the avatar's movement control + PID Controller | 768 | /// This is the avatar's movement control + PID Controller |
@@ -1136,8 +1101,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1136 | /// </summary> | 1101 | /// </summary> |
1137 | public void Destroy() | 1102 | public void Destroy() |
1138 | { | 1103 | { |
1139 | m_tainted_isPhysical = false; | 1104 | AddChange(changes.Remove, null); |
1140 | _parent_scene.AddPhysicsActorTaint(this); | ||
1141 | } | 1105 | } |
1142 | 1106 | ||
1143 | public override void CrossingFailure() | 1107 | public override void CrossingFailure() |
@@ -1207,12 +1171,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1207 | return m_haseventsubscription; | 1171 | return m_haseventsubscription; |
1208 | } | 1172 | } |
1209 | 1173 | ||
1210 | public void ProcessTaints(float timestep) | 1174 | private void changePhysicsStatus(bool NewStatus) |
1211 | { | 1175 | { |
1212 | 1176 | if (NewStatus != m_isPhysical) | |
1213 | if (m_tainted_isPhysical != m_isPhysical) | ||
1214 | { | 1177 | { |
1215 | if (m_tainted_isPhysical) | 1178 | if (NewStatus) |
1216 | { | 1179 | { |
1217 | // Create avatar capsule and related ODE data | 1180 | // Create avatar capsule and related ODE data |
1218 | if ((Shell != IntPtr.Zero)) | 1181 | if ((Shell != IntPtr.Zero)) |
@@ -1237,60 +1200,246 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1237 | AvatarGeomAndBodyDestroy(); | 1200 | AvatarGeomAndBodyDestroy(); |
1238 | } | 1201 | } |
1239 | 1202 | ||
1240 | m_isPhysical = m_tainted_isPhysical; | 1203 | m_isPhysical = NewStatus; |
1241 | } | 1204 | } |
1205 | } | ||
1206 | |||
1207 | private void changeAdd() | ||
1208 | { | ||
1209 | changePhysicsStatus(true); | ||
1210 | } | ||
1242 | 1211 | ||
1243 | if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) | 1212 | private void changeRemove() |
1213 | { | ||
1214 | changePhysicsStatus(false); | ||
1215 | } | ||
1216 | |||
1217 | private void changeShape(PrimitiveBaseShape arg) | ||
1218 | { | ||
1219 | } | ||
1220 | |||
1221 | private void changeSize(Vector3 Size) | ||
1222 | { | ||
1223 | if (Size.IsFinite()) | ||
1244 | { | 1224 | { |
1245 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) | 1225 | float caplen = Size.Z; |
1226 | |||
1227 | caplen = caplen * 1.15f - CAPSULE_RADIUS * 2.0f; | ||
1228 | |||
1229 | if (caplen != CAPSULE_LENGTH) | ||
1246 | { | 1230 | { |
1247 | AvatarGeomAndBodyDestroy(); | 1231 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) |
1232 | { | ||
1233 | AvatarGeomAndBodyDestroy(); | ||
1248 | 1234 | ||
1249 | m_pidControllerActive = true; | 1235 | float prevCapsule = CAPSULE_LENGTH; |
1236 | CAPSULE_LENGTH = caplen; | ||
1250 | 1237 | ||
1251 | float prevCapsule = CAPSULE_LENGTH; | 1238 | AvatarGeomAndBodyCreation(_position.X, _position.Y, |
1252 | CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; | 1239 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2)); |
1253 | |||
1254 | AvatarGeomAndBodyCreation(_position.X, _position.Y, | ||
1255 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2)); | ||
1256 | 1240 | ||
1257 | Velocity = Vector3.Zero; | 1241 | Velocity = Vector3.Zero; |
1258 | 1242 | ||
1259 | _parent_scene.geom_name_map[Shell] = m_name; | 1243 | _parent_scene.geom_name_map[Shell] = m_name; |
1260 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; | 1244 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; |
1261 | } | 1245 | } |
1262 | else | 1246 | else |
1263 | { | 1247 | { |
1264 | m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " | 1248 | m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " |
1265 | + (Shell == IntPtr.Zero ? "Shell " : "") | 1249 | + (Shell == IntPtr.Zero ? "Shell " : "") |
1266 | + (Body == IntPtr.Zero ? "Body " : "") | 1250 | + (Body == IntPtr.Zero ? "Body " : "") |
1267 | + (Amotor == IntPtr.Zero ? "Amotor " : "")); | 1251 | + (Amotor == IntPtr.Zero ? "Amotor " : "")); |
1252 | } | ||
1268 | } | 1253 | } |
1254 | |||
1255 | m_pidControllerActive = true; | ||
1256 | } | ||
1257 | else | ||
1258 | { | ||
1259 | m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character"); | ||
1269 | } | 1260 | } |
1261 | } | ||
1270 | 1262 | ||
1271 | if (m_hasTaintPosition) | 1263 | private void changePosition( Vector3 newPos) |
1272 | { | 1264 | { |
1273 | if (Body != IntPtr.Zero) | 1265 | if (Body != IntPtr.Zero) |
1274 | d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); | 1266 | d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z); |
1267 | _position = newPos; | ||
1268 | } | ||
1269 | |||
1270 | private void changeOrientation(Quaternion newOri) | ||
1271 | { | ||
1272 | } | ||
1273 | |||
1274 | private void changeVelocity(Vector3 newVel) | ||
1275 | { | ||
1276 | m_pidControllerActive = true; | ||
1277 | _target_velocity = newVel; | ||
1278 | } | ||
1275 | 1279 | ||
1276 | _position.X = m_taintPosition.X; | 1280 | private void changeSetTorque(Vector3 newTorque) |
1277 | _position.Y = m_taintPosition.Y; | 1281 | { |
1278 | _position.Z = m_taintPosition.Z; | 1282 | } |
1279 | m_hasTaintPosition = false; | 1283 | |
1284 | private void changeAddForce(Vector3 newForce) | ||
1285 | { | ||
1286 | } | ||
1287 | |||
1288 | private void changeAddAngularForce(Vector3 arg) | ||
1289 | { | ||
1290 | } | ||
1291 | |||
1292 | private void changeAngularLock(Vector3 arg) | ||
1293 | { | ||
1294 | } | ||
1295 | |||
1296 | private void changeFloatOnWater(bool arg) | ||
1297 | { | ||
1298 | } | ||
1299 | |||
1300 | private void changeVolumedetetion(bool arg) | ||
1301 | { | ||
1302 | } | ||
1303 | |||
1304 | private void changeSelectedStatus(bool arg) | ||
1305 | { | ||
1306 | } | ||
1307 | |||
1308 | private void changeDisable(bool arg) | ||
1309 | { | ||
1310 | } | ||
1311 | |||
1312 | private void changeBuilding(bool arg) | ||
1313 | { | ||
1314 | } | ||
1315 | |||
1316 | private void changeForce(Vector3 newForce) | ||
1317 | { | ||
1318 | m_pidControllerActive = false; | ||
1319 | if (Body != IntPtr.Zero) | ||
1320 | { | ||
1321 | if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0) | ||
1322 | d.BodyAddForce(Body, newForce.X, newForce.Y, newForce.Z); | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | private void donullchange() | ||
1327 | { | ||
1328 | } | ||
1329 | |||
1330 | public bool DoAChange(changes what, object arg) | ||
1331 | { | ||
1332 | if (Shell == IntPtr.Zero && what != changes.Add && what != changes.Remove) | ||
1333 | { | ||
1334 | return false; | ||
1280 | } | 1335 | } |
1281 | 1336 | ||
1282 | if (m_hasTaintForce) | 1337 | // nasty switch |
1338 | switch (what) | ||
1283 | { | 1339 | { |
1284 | if (Body != IntPtr.Zero) | 1340 | case changes.Add: |
1285 | { | 1341 | changeAdd(); |
1286 | if(m_taintForce.X !=0f || m_taintForce.Y !=0f || m_taintForce.Z !=0) | 1342 | break; |
1287 | d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z); | 1343 | case changes.Remove: |
1288 | m_hasTaintForce = false; | 1344 | changeRemove(); |
1289 | } | 1345 | break; |
1346 | |||
1347 | case changes.Position: | ||
1348 | changePosition((Vector3)arg); | ||
1349 | break; | ||
1350 | |||
1351 | case changes.Orientation: | ||
1352 | changeOrientation((Quaternion)arg); | ||
1353 | break; | ||
1354 | |||
1355 | case changes.PosOffset: | ||
1356 | donullchange(); | ||
1357 | break; | ||
1358 | |||
1359 | case changes.OriOffset: | ||
1360 | donullchange(); | ||
1361 | break; | ||
1362 | |||
1363 | case changes.Velocity: | ||
1364 | changeVelocity((Vector3)arg); | ||
1365 | break; | ||
1366 | |||
1367 | // case changes.Acceleration: | ||
1368 | // changeacceleration((Vector3)arg); | ||
1369 | // break; | ||
1370 | // case changes.AngVelocity: | ||
1371 | // changeangvelocity((Vector3)arg); | ||
1372 | // break; | ||
1373 | |||
1374 | case changes.Force: | ||
1375 | changeForce((Vector3)arg); | ||
1376 | break; | ||
1377 | |||
1378 | case changes.Torque: | ||
1379 | changeSetTorque((Vector3)arg); | ||
1380 | break; | ||
1381 | |||
1382 | case changes.AddForce: | ||
1383 | changeAddForce((Vector3)arg); | ||
1384 | break; | ||
1385 | |||
1386 | case changes.AddAngForce: | ||
1387 | changeAddAngularForce((Vector3)arg); | ||
1388 | break; | ||
1389 | |||
1390 | case changes.AngLock: | ||
1391 | changeAngularLock((Vector3)arg); | ||
1392 | break; | ||
1393 | |||
1394 | case changes.Size: | ||
1395 | changeSize((Vector3)arg); | ||
1396 | break; | ||
1397 | /* not in use for now | ||
1398 | case changes.Shape: | ||
1399 | changeShape((PrimitiveBaseShape)arg); | ||
1400 | break; | ||
1401 | |||
1402 | case changes.CollidesWater: | ||
1403 | changeFloatOnWater((bool)arg); | ||
1404 | break; | ||
1405 | |||
1406 | case changes.VolumeDtc: | ||
1407 | changeVolumedetetion((bool)arg); | ||
1408 | break; | ||
1409 | |||
1410 | case changes.Physical: | ||
1411 | changePhysicsStatus((bool)arg); | ||
1412 | break; | ||
1413 | |||
1414 | case changes.Selected: | ||
1415 | changeSelectedStatus((bool)arg); | ||
1416 | break; | ||
1417 | |||
1418 | case changes.disabled: | ||
1419 | changeDisable((bool)arg); | ||
1420 | break; | ||
1421 | |||
1422 | case changes.building: | ||
1423 | changeBuilding((bool)arg); | ||
1424 | break; | ||
1425 | */ | ||
1426 | case changes.Null: | ||
1427 | donullchange(); | ||
1428 | break; | ||
1429 | |||
1430 | default: | ||
1431 | donullchange(); | ||
1432 | break; | ||
1290 | } | 1433 | } |
1434 | return false; | ||
1435 | } | ||
1291 | 1436 | ||
1437 | public void AddChange(changes what, object arg) | ||
1438 | { | ||
1439 | _parent_scene.AddChange((PhysicsActor)this, what, arg); | ||
1292 | } | 1440 | } |
1293 | 1441 | ||
1442 | |||
1294 | internal void AddCollisionFrameTime(int p) | 1443 | internal void AddCollisionFrameTime(int p) |
1295 | { | 1444 | { |
1296 | // protect it from overflow crashing | 1445 | // protect it from overflow crashing |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 53a39d7..078adeb 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -668,13 +668,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
668 | AddChange(changes.VehicleVectorParam, fp); | 668 | AddChange(changes.VehicleVectorParam, fp); |
669 | } | 669 | } |
670 | 670 | ||
671 | public override void VehicleFlags(int param, bool remove) | 671 | public override void VehicleFlags(int param, bool value) |
672 | { | 672 | { |
673 | if (m_vehicle == null) | 673 | if (m_vehicle == null) |
674 | return; | 674 | return; |
675 | m_vehicle.ProcessVehicleFlags(param, remove); | 675 | strVehicleBoolParam bp = new strVehicleBoolParam(); |
676 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | 676 | bp.param = param; |
677 | d.BodyEnable(Body); | 677 | bp.value = value; |
678 | AddChange(changes.VehicleFlags, bp); | ||
678 | } | 679 | } |
679 | 680 | ||
680 | public void SetAcceleration(Vector3 accel) | 681 | public void SetAcceleration(Vector3 accel) |
@@ -2374,8 +2375,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2374 | changeShape(_pbs); | 2375 | changeShape(_pbs); |
2375 | } | 2376 | } |
2376 | else | 2377 | else |
2377 | */ | 2378 | */ |
2378 | DestroyBody(); | 2379 | DestroyBody(); |
2380 | Stop(); | ||
2379 | } | 2381 | } |
2380 | } | 2382 | } |
2381 | } | 2383 | } |
@@ -3287,7 +3289,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3287 | 3289 | ||
3288 | public void AddChange(changes what, object arg) | 3290 | public void AddChange(changes what, object arg) |
3289 | { | 3291 | { |
3290 | _parent_scene.AddChange(this, what, arg); | 3292 | _parent_scene.AddChange((PhysicsActor) this, what, arg); |
3291 | } | 3293 | } |
3292 | 3294 | ||
3293 | 3295 | ||
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 86385bf..2dfcca6 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -147,7 +147,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
147 | 147 | ||
148 | public struct ODEchangeitem | 148 | public struct ODEchangeitem |
149 | { | 149 | { |
150 | public OdePrim prim; | 150 | public PhysicsActor actor; |
151 | public OdeCharacter character; | 151 | public OdeCharacter character; |
152 | public changes what; | 152 | public changes what; |
153 | public Object arg; | 153 | public Object arg; |
@@ -187,7 +187,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
187 | public float gravityy = 0f; | 187 | public float gravityy = 0f; |
188 | public float gravityz = -9.8f; | 188 | public float gravityz = -9.8f; |
189 | 189 | ||
190 | |||
191 | private float waterlevel = 0f; | 190 | private float waterlevel = 0f; |
192 | private int framecount = 0; | 191 | private int framecount = 0; |
193 | 192 | ||
@@ -1558,23 +1557,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1558 | return true; | 1557 | return true; |
1559 | } | 1558 | } |
1560 | 1559 | ||
1561 | public void AddChange(OdePrim prim, changes what, Object arg) | ||
1562 | { | ||
1563 | ODEchangeitem item = new ODEchangeitem(); | ||
1564 | item.prim = prim; | ||
1565 | item.what = what; | ||
1566 | item.arg = arg; | ||
1567 | ChangesQueue.Enqueue(item); | ||
1568 | } | ||
1569 | |||
1570 | /// <summary> | 1560 | /// <summary> |
1571 | /// Called to queue a change to a prim | 1561 | /// Called to queue a change to a actor |
1572 | /// to use in place of old taint mechanism so changes do have a time sequence | 1562 | /// to use in place of old taint mechanism so changes do have a time sequence |
1573 | /// </summary> | 1563 | /// </summary> |
1574 | public void AddChange(OdeCharacter character, changes what, Object arg) | 1564 | |
1565 | public void AddChange(PhysicsActor actor, changes what, Object arg) | ||
1575 | { | 1566 | { |
1576 | ODEchangeitem item = new ODEchangeitem(); | 1567 | ODEchangeitem item = new ODEchangeitem(); |
1577 | item.character = character; | 1568 | item.actor = actor; |
1578 | item.what = what; | 1569 | item.what = what; |
1579 | item.arg = arg; | 1570 | item.arg = arg; |
1580 | ChangesQueue.Enqueue(item); | 1571 | ChangesQueue.Enqueue(item); |
@@ -1687,25 +1678,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1687 | // clear pointer/counter to contacts to pass into joints | 1678 | // clear pointer/counter to contacts to pass into joints |
1688 | m_global_contactcount = 0; | 1679 | m_global_contactcount = 0; |
1689 | 1680 | ||
1690 | // do characters requested changes | ||
1691 | |||
1692 | OdeCharacter character; | ||
1693 | int numtaints; | ||
1694 | lock (_taintedCharacterLock) | ||
1695 | { | ||
1696 | numtaints = _taintedCharacterQ.Count; | ||
1697 | // if (numtaints > 50) | ||
1698 | // numtaints = 50; | ||
1699 | while (numtaints > 0) | ||
1700 | { | ||
1701 | character = _taintedCharacterQ.Dequeue(); | ||
1702 | character.ProcessTaints(ODE_STEPSIZE); | ||
1703 | _taintedCharacterH.Remove(character); | ||
1704 | numtaints--; | ||
1705 | } | ||
1706 | } | ||
1707 | // do other objects requested changes | ||
1708 | |||
1709 | ODEchangeitem item; | 1681 | ODEchangeitem item; |
1710 | 1682 | ||
1711 | if(ChangesQueue.Count >0) | 1683 | if(ChangesQueue.Count >0) |
@@ -1716,14 +1688,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1716 | 1688 | ||
1717 | while(ChangesQueue.Dequeue(out item)) | 1689 | while(ChangesQueue.Dequeue(out item)) |
1718 | { | 1690 | { |
1719 | if (item.prim != null) | 1691 | if (item.actor != null) |
1720 | { | 1692 | { |
1721 | try | 1693 | try |
1722 | { | 1694 | { |
1723 | if (item.prim.DoAChange(item.what, item.arg)) | 1695 | if (item.actor is OdeCharacter) |
1724 | RemovePrimThreadLocked(item.prim); | 1696 | ((OdeCharacter)item.actor).DoAChange(item.what, item.arg); |
1697 | else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) | ||
1698 | RemovePrimThreadLocked((OdePrim)item.actor); | ||
1725 | } | 1699 | } |
1726 | catch { }; | 1700 | catch |
1701 | { | ||
1702 | m_log.Warn("[PHYSICS]: doChange failed for a actor"); | ||
1703 | }; | ||
1727 | } | 1704 | } |
1728 | ttmp = Util.EnvironmentTickCountSubtract(ttmpstart); | 1705 | ttmp = Util.EnvironmentTickCountSubtract(ttmpstart); |
1729 | if (ttmp > 20) | 1706 | if (ttmp > 20) |