aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs563
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs14
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs51
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
31using System; 31using System;
32using System.Collections.Generic; 32using 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)