29 using System.Collections.Generic;
30 using System.Reflection;
32 using OpenSim.Framework;
33 using OpenSim.Region.PhysicsModules.SharedBase;
36 namespace OpenSim.
Region.PhysicsModule.ODE
68 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
70 private Vector3 _position;
72 private bool _zeroFlag =
false;
73 private bool m_lastUpdateSent =
false;
74 private Vector3 _velocity;
75 private Vector3 m_taintTargetVelocity;
76 private Vector3 _target_velocity;
77 private Vector3 _acceleration;
78 private Vector3 m_rotationalVelocity;
79 private float m_mass = 80f;
80 private float m_density = 60f;
81 private bool m_pidControllerActive =
true;
82 private float PID_D = 800.0f;
83 private float PID_P = 900.0f;
85 private float CAPSULE_RADIUS = 0.37f;
86 private float CAPSULE_LENGTH = 2.140599f;
87 private float m_tensor = 3800000f;
89 private float walkDivisor = 1.3f;
90 private float runDivisor = 0.8f;
91 private bool flying =
false;
92 private bool m_iscolliding =
false;
93 private bool m_iscollidingGround =
false;
94 private bool m_wascolliding =
false;
95 private bool m_wascollidingGround =
false;
96 private bool m_iscollidingObj =
false;
97 private bool m_alwaysRun =
false;
98 private bool m_hackSentFall =
false;
99 private bool m_hackSentFly =
false;
100 private int m_requestedUpdateFrequency = 0;
101 private Vector3 m_taintPosition;
102 internal bool m_avatarplanted =
false;
107 private Vector3 m_taintForce;
110 private bool m_isPhysical =
false;
111 private bool m_tainted_isPhysical =
false;
112 internal float MinimumGroundFlightOffset = 3f;
114 private float m_tainted_CAPSULE_LENGTH;
119 private float m_tiltBaseMovement = (float)Math.Sqrt(2);
124 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f;
126 private float m_buoyancy = 0f;
129 private bool[] m_colliderarr =
new bool[11];
130 private bool[] m_colliderGroundarr =
new bool[11];
137 | CollisionCategories.Space
138 | CollisionCategories.Body
139 | CollisionCategories.Character
140 | CollisionCategories.Land);
144 internal IntPtr
Body {
get;
private set; }
151 internal IntPtr Shell {
get;
private set; }
153 private IntPtr Amotor = IntPtr.Zero;
156 private int m_eventsubscription = 0;
160 internal UUID m_uuid {
get;
private set; }
161 internal bool bad =
false;
181 String avName,
OdeScene parent_scene, Vector3 pos, Vector3 vel, Vector3 size,
float pid_d,
float pid_p,
182 float capsule_radius,
float tensor,
float density,
183 float walk_divisor,
float rundivisor)
185 m_uuid = UUID.Random();
189 if (pos.Z > 9999999f)
191 pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
195 pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
199 m_taintPosition = pos;
205 (
float)_parent_scene.WorldExtents.X * 0.5f,
206 (
float)_parent_scene.WorldExtents.Y * 0.5f,
207 parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f);
208 m_taintPosition = _position;
210 m_log.WarnFormat(
"[ODE CHARACTER]: Got NaN Position on Character Create for {0}", avName);
214 m_taintTargetVelocity = vel;
216 _parent_scene = parent_scene;
220 CAPSULE_RADIUS = capsule_radius;
224 walkDivisor = walk_divisor;
225 runDivisor = rundivisor;
233 SetTaintedCapsuleLength(size);
234 CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
236 m_isPhysical =
false;
237 m_tainted_isPhysical =
true;
239 _parent_scene.AddPhysicsActorTaint(
this);
244 public override int PhysicsActorType
246 get {
return (
int) ActorTypes.Agent; }
255 get {
return m_alwaysRun; }
256 set { m_alwaysRun = value; }
259 public override bool Grabbed
269 public override float Buoyancy
271 get {
return m_buoyancy; }
272 set { m_buoyancy = value; }
275 public override bool FloatOnWater
280 public override bool IsPhysical
282 get {
return m_isPhysical; }
286 public override bool ThrottleUpdates
288 get {
return false; }
292 public override bool Flying
294 get {
return flying; }
306 public override bool IsColliding
308 get {
return m_iscolliding; }
315 if (m_colliderarr.Length >= 10)
317 for (i = 0; i < 10; i++)
319 m_colliderarr[i] = m_colliderarr[i + 1];
322 m_colliderarr[10] = value;
324 for (i = 0; i < 11; i++)
326 if (m_colliderarr[i])
338 if (falsecount > 1.2*truecount)
340 m_iscolliding =
false;
344 m_iscolliding =
true;
347 if (m_wascolliding != m_iscolliding)
352 m_wascolliding = m_iscolliding;
359 public override bool CollidingGround
361 get {
return m_iscollidingGround; }
371 if (m_colliderGroundarr.Length >= 10)
373 for (i = 0; i < 10; i++)
375 m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
378 m_colliderGroundarr[10] = value;
380 for (i = 0; i < 11; i++)
382 if (m_colliderGroundarr[i])
394 if (falsecount > 1.2*truecount)
396 m_iscollidingGround =
false;
400 m_iscollidingGround =
true;
402 if (m_wascollidingGround != m_iscollidingGround)
406 m_wascollidingGround = m_iscollidingGround;
413 public override bool CollidingObj
415 get {
return m_iscollidingObj; }
418 m_iscollidingObj = value;
419 if (value && !m_avatarplanted)
420 m_pidControllerActive =
false;
422 m_pidControllerActive =
true;
433 m_pidControllerActive = status;
436 public override bool Stopped
438 get {
return _zeroFlag; }
448 get {
return _position; }
451 if (
Body == IntPtr.Zero || Shell == IntPtr.Zero)
453 if (value.IsFinite())
455 if (value.Z > 9999999f)
457 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
459 if (value.Z < -90000f)
461 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
464 m_taintPosition = value;
465 _parent_scene.AddPhysicsActorTaint(
this);
469 m_log.WarnFormat(
"[ODE CHARACTER]: Got a NaN Position from Scene on character {0}", Name);
475 public override Vector3 RotationalVelocity
477 get {
return m_rotationalVelocity; }
478 set { m_rotationalVelocity = value; }
485 public override Vector3
Size
487 get {
return new Vector3(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); }
490 SetTaintedCapsuleLength(value);
496 _parent_scene.AddPhysicsActorTaint(
this);
500 private void SetTaintedCapsuleLength(Vector3 size)
504 m_pidControllerActive =
true;
506 m_tainted_CAPSULE_LENGTH = size.Z - CAPSULE_RADIUS * 2.0f;
513 m_log.WarnFormat(
"[ODE CHARACTER]: Got a NaN Size for {0} in {1}", Name, _parent_scene.PhysicsSceneName);
517 private void AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3 movementVector)
519 movementVector.Z = 0f;
520 float magnitude = (float)Math.Sqrt((
double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y));
521 if (magnitude < 0.1f)
return;
524 float invMagnitude = 1.0f / magnitude;
525 movementVector.X *= invMagnitude;
526 movementVector.Y *= invMagnitude;
531 if (movementVector.X > 0)
534 if (movementVector.Y > 0)
537 movementVector.X = m_tiltBaseMovement;
538 movementVector.Y = m_tiltBaseMovement;
543 movementVector.X = m_tiltBaseMovement;
544 movementVector.Y = -m_tiltBaseMovement;
550 if (movementVector.Y > 0)
553 movementVector.X = -m_tiltBaseMovement;
554 movementVector.Y = m_tiltBaseMovement;
559 movementVector.X = -m_tiltBaseMovement;
560 movementVector.Y = -m_tiltBaseMovement;
568 float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane;
569 float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane;
572 d.JointSetAMotorParam(Amotor, (int)
dParam.LowStop, xTiltComponent);
573 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop, xTiltComponent);
574 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop2, yTiltComponent);
575 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop2, yTiltComponent);
576 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop3, 0f);
577 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop3, 0f);
584 public override float Mass
588 float AVvolume = (float)(Math.PI * Math.Pow(CAPSULE_RADIUS, 2) * CAPSULE_LENGTH);
589 return m_density * AVvolume;
622 public override Vector3 Force
624 get {
return _target_velocity; }
628 public override int VehicleType
654 public override Vector3 CenterOfMass
656 get {
return Vector3.Zero; }
659 public override Vector3 GeometricCenter
661 get {
return Vector3.Zero; }
669 public override Vector3 TargetVelocity
673 return m_taintTargetVelocity;
690 m_lastUpdateSent =
false;
696 if (value.IsFinite())
698 m_pidControllerActive =
true;
699 m_taintTargetVelocity = value;
700 _parent_scene.AddPhysicsActorTaint(
this);
704 m_log.WarnFormat(
"[ODE CHARACTER]: Got a NaN velocity from Scene for {0}", Name);
711 public override Vector3 Torque
713 get {
return Vector3.Zero; }
717 public override float CollisionScore
723 public override bool Kinematic
725 get {
return false; }
729 public override Quaternion Orientation
731 get {
return Quaternion.Identity; }
741 get {
return _acceleration; }
742 set { _acceleration = value; }
750 public override void AddForce(Vector3 force,
bool pushforce)
752 if (force.IsFinite())
756 m_pidControllerActive =
false;
758 m_taintForce += force;
759 _parent_scene.AddPhysicsActorTaint(
this);
770 m_pidControllerActive =
true;
771 m_taintTargetVelocity += force;
776 m_log.WarnFormat(
"[ODE CHARACTER]: Got a NaN force applied to {0}", Name);
796 internal void Move(List<OdeCharacter> defects)
803 if (Body == IntPtr.Zero)
806 if (m_pidControllerActive ==
false)
808 _zeroPosition = d.BodyGetPosition(
Body);
812 d.Vector3 localpos = d.BodyGetPosition(Body);
813 Vector3 localPos =
new Vector3(localpos.X, localpos.Y, localpos.Z);
815 if (!localPos.IsFinite())
818 "[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.",
826 Vector3 vec = Vector3.Zero;
827 d.Vector3 vel = d.BodyGetLinearVel(Body);
833 float movementdivisor = 1f;
837 movementdivisor = walkDivisor;
841 movementdivisor = runDivisor;
845 if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
851 _zeroPosition = d.BodyGetPosition(Body);
854 if (m_pidControllerActive)
861 d.Vector3 pos = d.BodyGetPosition(
Body);
862 vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
863 vec.Y = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2);
866 vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
873 m_pidControllerActive =
true;
875 if (m_iscolliding && !flying)
878 vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D);
879 vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D);
881 else if (m_iscolliding && flying)
884 vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D / 16);
885 vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D / 16);
887 else if (!m_iscolliding && flying)
890 vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D / 6);
891 vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D / 6);
901 vec.Z = (_target_velocity.Z - vel.Z) * (PID_D);
905 if (m_iscolliding && _target_velocity.Z > 0.0f)
909 d.Vector3 pos = d.BodyGetPosition(
Body);
910 vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
911 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D;
912 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
914 else if (!m_iscolliding)
918 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D;
919 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
927 vec.Z += ((-1 * _parent_scene.gravityz) * m_mass);
931 float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset;
933 if (_position.Z < target_altitude)
935 vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f;
943 d.BodyAddForce(
Body, vec.X, vec.Y, vec.Z);
946 AlignAvatarTiltWithCurrentDirectionOfMovement(vec);
951 "[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.",
959 d.Vector3 newVel = d.BodyGetLinearVel(Body);
960 if (newVel.X >= 256 || newVel.X <= 256 || newVel.Y >= 256 || newVel.Y <= 256 || newVel.Z >= 256 || newVel.Z <= 256)
965 newVel.X = Util.Clamp<
float>(newVel.X, -255f, 255f);
966 newVel.Y = Util.Clamp<
float>(newVel.Y, -255f, 255f);
971 newVel.Z, -_parent_scene.AvatarTerminalVelocity, _parent_scene.AvatarTerminalVelocity);
973 newVel.Z = Util.Clamp<
float>(newVel.Z, -255f, 255f);
975 d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
985 internal void UpdatePositionAndVelocity(List<OdeCharacter> defects)
991 newPos = d.BodyGetPosition(Body);
993 catch (NullReferenceException)
997 newPos =
new d.Vector3(_position.X, _position.Y, _position.Z);
998 base.RaiseOutOfBounds(_position);
999 m_log.WarnFormat(
"[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid);
1005 if (newPos.X < 0.0f) newPos.X = 0.0f;
1006 if (newPos.Y < 0.0f) newPos.Y = 0.0f;
1007 if (newPos.X > (
int)_parent_scene.WorldExtents.X - 0.05f) newPos.X = (
int)_parent_scene.WorldExtents.X - 0.05f;
1008 if (newPos.Y > (
int)_parent_scene.WorldExtents.Y - 0.05f) newPos.Y = (
int)_parent_scene.WorldExtents.Y - 0.05f;
1010 _position.X = newPos.X;
1011 _position.Y = newPos.Y;
1012 _position.Z = newPos.Z;
1015 m_taintPosition = _position;
1022 _velocity = Vector3.Zero;
1025 if (!m_lastUpdateSent)
1027 m_lastUpdateSent =
true;
1033 m_lastUpdateSent =
false;
1034 d.Vector3 newVelocity;
1038 newVelocity = d.BodyGetLinearVel(Body);
1040 catch (NullReferenceException)
1042 newVelocity.X = _velocity.X;
1043 newVelocity.Y = _velocity.Y;
1044 newVelocity.Z = _velocity.Z;
1047 _velocity.X = newVelocity.X;
1048 _velocity.Y = newVelocity.Y;
1049 _velocity.Z = newVelocity.Z;
1051 if (_velocity.Z < -6 && !m_hackSentFall)
1053 m_hackSentFall =
true;
1054 m_pidControllerActive =
false;
1056 else if (flying && !m_hackSentFly)
1063 m_hackSentFly =
false;
1064 m_hackSentFall =
false;
1081 private void CreateOdeStructures(
float npositionX,
float npositionY,
float npositionZ,
float tensor)
1083 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
1086 "[ODE CHARACTER]: Creating ODE structures for {0} even though some already exist. Shell = {1}, Body = {2}, Amotor = {3}",
1087 Name, Shell, Body, Amotor);
1090 int dAMotorEuler = 1;
1092 if (CAPSULE_LENGTH <= 0)
1094 m_log.Warn(
"[ODE CHARACTER]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
1095 CAPSULE_LENGTH = 0.01f;
1098 if (CAPSULE_RADIUS <= 0)
1100 m_log.Warn(
"[ODE CHARACTER]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
1101 CAPSULE_RADIUS = 0.01f;
1105 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
1107 d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories);
1108 d.GeomSetCollideBits(Shell, (uint)m_collisionFlags);
1110 d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH);
1111 Body = d.BodyCreate(_parent_scene.world);
1112 d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
1114 _position.X = npositionX;
1115 _position.Y = npositionY;
1116 _position.Z = npositionZ;
1118 m_taintPosition = _position;
1120 d.BodySetMass(Body, ref ShellMass);
1123 if (_parent_scene.IsAvCapsuleTilted)
1125 d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2));
1129 d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2));
1132 d.GeomSetRotation(Shell, ref m_caprot);
1133 d.BodySetRotation(Body, ref m_caprot);
1135 d.GeomSetBody(Shell, Body);
1139 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
1140 d.JointAttach(Amotor, Body, IntPtr.Zero);
1141 d.JointSetAMotorMode(Amotor, dAMotorEuler);
1142 d.JointSetAMotorNumAxes(Amotor, 3);
1143 d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
1144 d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
1145 d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
1146 d.JointSetAMotorAngle(Amotor, 0, 0);
1147 d.JointSetAMotorAngle(Amotor, 1, 0);
1148 d.JointSetAMotorAngle(Amotor, 2, 0);
1151 if (_parent_scene.IsAvCapsuleTilted)
1153 d.JointSetAMotorParam(Amotor, (int)
dParam.LowStop, -0.000000000001f);
1154 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop3, -0.000000000001f);
1155 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop2, -0.000000000001f);
1156 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop, 0.000000000001f);
1157 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop3, 0.000000000001f);
1158 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop2, 0.000000000001f);
1162 #region Documentation of capsule motor LowStop and HighStop parameters
1169 AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero);
1170 d.JointSetAMotorParam(Amotor, (int)
dParam.LowStop, 0.08f);
1171 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop3, -0f);
1172 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop2, 0.08f);
1173 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop, 0.08f);
1174 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop3, 0f);
1175 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop2, 0.08f);
1180 d.JointSetAMotorParam(Amotor, (int)
dParam.FudgeFactor, 0f);
1181 d.JointSetAMotorParam(Amotor, (int)
dParam.FMax, tensor);
1190 _parent_scene.geom_name_map[Shell] = Name;
1191 _parent_scene.actor_name_map[Shell] =
this;
1197 internal void Destroy()
1199 m_tainted_isPhysical =
false;
1200 _parent_scene.AddPhysicsActorTaint(
this);
1206 internal void DestroyOdeStructures()
1209 if (Shell == IntPtr.Zero || Body == IntPtr.Zero || Amotor == IntPtr.Zero)
1212 "[ODE CHARACTER]: Destroying ODE structures for {0} even though some are already null. Shell = {1}, Body = {2}, Amotor = {3}",
1213 Name, Shell, Body, Amotor);
1217 if (Amotor != IntPtr.Zero)
1220 d.JointDestroy(Amotor);
1221 Amotor = IntPtr.Zero;
1227 if (Body != IntPtr.Zero)
1230 d.BodyDestroy(Body);
1234 if (Shell != IntPtr.Zero)
1237 d.GeomDestroy(Shell);
1239 _parent_scene.geom_name_map.Remove(Shell);
1240 _parent_scene.actor_name_map.Remove(Shell);
1242 Shell = IntPtr.Zero;
1250 public override Vector3 PIDTarget { set {
return; } }
1251 public override bool PIDActive
1253 get {
return false; }
1256 public override float PIDTau { set {
return; } }
1258 public override float PIDHoverHeight { set {
return; } }
1259 public override bool PIDHoverActive {
get {
return false;} set {
return; } }
1261 public override float PIDHoverTau { set {
return; } }
1263 public override Quaternion APIDTarget{ set {
return; } }
1265 public override bool APIDActive{ set {
return; } }
1267 public override float APIDStrength{ set {
return; } }
1269 public override float APIDDamping{ set {
return; } }
1273 m_requestedUpdateFrequency = ms;
1274 m_eventsubscription = ms;
1279 _parent_scene.AddCollisionEventReporting(
this);
1284 _parent_scene.RemoveCollisionEventReporting(
this);
1289 m_requestedUpdateFrequency = 0;
1290 m_eventsubscription = 0;
1295 if (m_eventsubscription > 0)
1300 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
1304 internal void SendCollisions()
1306 if (m_eventsubscription > m_requestedUpdateFrequency)
1308 base.SendCollisionUpdate(CollisionEventsThisFrame);
1310 CollisionEventsThisFrame.Clear();
1311 m_eventsubscription = 0;
1317 if (m_eventsubscription > 0)
1322 internal void ProcessTaints()
1324 if (m_taintPosition != _position)
1326 if (Body != IntPtr.Zero)
1328 d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
1329 _position = m_taintPosition;
1333 if (m_taintForce != Vector3.Zero)
1335 if (Body != IntPtr.Zero)
1340 d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z);
1343 m_taintForce = Vector3.Zero;
1346 if (m_taintTargetVelocity != _target_velocity)
1347 _target_velocity = m_taintTargetVelocity;
1349 if (m_tainted_isPhysical != m_isPhysical)
1351 if (m_tainted_isPhysical)
1353 CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor);
1354 _parent_scene.AddCharacter(
this);
1358 _parent_scene.RemoveCharacter(
this);
1359 DestroyOdeStructures();
1362 m_isPhysical = m_tainted_isPhysical;
1365 if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
1367 if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
1373 m_pidControllerActive =
true;
1376 DestroyOdeStructures();
1378 float prevCapsule = CAPSULE_LENGTH;
1379 CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
1381 CreateOdeStructures(
1384 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
1392 m_log.Warn(
"[ODE CHARACTER]: trying to change capsule size for " + Name +
", but the following ODE data is missing - "
1393 + (Shell==IntPtr.Zero ?
"Shell ":
"")
1394 + (Body==IntPtr.Zero ?
"Body ":
"")
1395 + (Amotor==IntPtr.Zero ?
"Amotor ":
""));
1400 internal void AddCollisionFrameTime(
int p)
1403 if (m_eventsubscription + p >=
int.MaxValue)
1404 m_eventsubscription = 0;
1405 m_eventsubscription += p;
override void VehicleFlags(int param, bool remove)
override void AddAngularForce(Vector3 force, bool pushforce)
override void SubscribeEvents(int ms)
dParam
Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ours...
delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun)
override void CrossingFailure()
void SetPidStatus(bool status)
turn the PID controller on or off. The PID Controller will turn on all by itself in many situations ...
override void AddForce(Vector3 force, bool pushforce)
Adds the force supplied to the Target Velocity The PID controller takes this target velocity and trie...
override void UnSubscribeEvents()
OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 vel, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float walk_divisor, float rundivisor)
ODE Avatar.
Used to pass collision information to OnCollisionUpdate listeners.
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
override void VehicleRotationParam(int param, Quaternion rotation)
dParam
Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ours...
override void VehicleFloatParam(int param, float value)
override void SetVolumeDetect(int param)
Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more ...
override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
override void VehicleVectorParam(int param, Vector3 value)
override void LockAngularMotion(byte axislocks)
override void SetMomentum(Vector3 momentum)
override void link(PhysicsActor obj)
override bool SubscribedEvents()