45 using System.Collections.Generic;
46 using System.Reflection;
47 using System.Runtime.InteropServices;
48 using System.Threading;
51 using OpenSim.Framework;
52 using OpenSim.Region.PhysicsModules.SharedBase;
54 namespace OpenSim.
Region.PhysicsModule.ODE
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 private bool m_isphysical;
65 public int ExpectedCollisionContacts {
get {
return m_expectedCollisionContacts; } }
66 private int m_expectedCollisionContacts = 0;
71 private int BadMeshAssetCollideBits
79 public override bool IsPhysical
81 get {
return m_isphysical; }
88 m_lastVelocity = Vector3.Zero;
89 _acceleration = Vector3.Zero;
90 _velocity = Vector3.Zero;
91 m_taintVelocity = Vector3.Zero;
92 m_rotationalVelocity = Vector3.Zero;
97 private Vector3 _position;
98 private Vector3 _velocity;
99 private Vector3 _torque;
100 private Vector3 m_lastVelocity;
101 private Vector3 m_lastposition;
102 private Quaternion m_lastorientation =
new Quaternion();
103 private Vector3 m_rotationalVelocity;
104 private Vector3 _size;
105 private Vector3 _acceleration;
107 private Quaternion _orientation;
108 private Vector3 m_taintposition;
109 private Vector3 m_taintsize;
110 private Vector3 m_taintVelocity;
111 private Vector3 m_taintTorque;
112 private Quaternion m_taintrot;
114 private IntPtr Amotor = IntPtr.Zero;
116 private byte m_taintAngularLock = 0;
117 private byte m_angularlock = 0;
119 private bool m_assetFailed =
false;
121 private Vector3 m_PIDTarget;
122 private float m_PIDTau;
123 private float PID_D = 35f;
124 private float PID_G = 25f;
129 private float m_PIDHoverHeight;
130 private float m_PIDHoverTau;
131 private bool m_useHoverPID;
132 private PIDHoverType m_PIDHoverType = PIDHoverType.Ground;
133 private float m_targetHoverHeight;
134 private float m_groundHeight;
135 private float m_waterHeight;
136 private float m_buoyancy;
139 private int body_autodisable_frames = 20;
143 | CollisionCategories.Space
144 | CollisionCategories.Body
145 | CollisionCategories.Character
147 private bool m_taintshape;
148 private bool m_taintPhysics;
149 private bool m_collidesLand =
true;
150 private bool m_collidesWater;
158 public bool m_taintremove {
get;
private set; }
159 public bool m_taintdisable {
get;
private set; }
160 internal bool m_disabled;
161 public bool m_taintadd {
get;
private set; }
162 public bool m_taintselected {
get;
private set; }
163 public bool m_taintCollidesWater {
get;
private set; }
165 private bool m_taintforce =
false;
166 private bool m_taintaddangularforce =
false;
167 private Vector3 m_force;
168 private List<Vector3> m_forcelist =
new List<Vector3>();
169 private List<Vector3> m_angularforcelist =
new List<Vector3>();
177 public IntPtr m_targetSpace = IntPtr.Zero;
186 public IntPtr prim_geom {
get;
private set; }
188 public IntPtr _triMeshData {
get;
private set; }
190 private IntPtr _linkJointGroup = IntPtr.Zero;
194 private List<OdePrim> childrenPrim =
new List<OdePrim>();
196 private bool iscolliding;
197 private bool m_isSelected;
199 internal bool m_isVolumeDetect;
201 private bool m_throttleUpdates;
202 private int throttleCounter;
203 public int m_interpenetrationcount {
get;
private set; }
204 internal float m_collisionscore;
205 public int m_roundsUnderMotionThreshold {
get;
private set; }
207 public bool outofBounds {
get;
private set; }
208 private float m_density = 10.000006836f;
210 public bool _zeroFlag {
get;
private set; }
211 private bool m_lastUpdateSent;
213 public IntPtr
Body = IntPtr.Zero;
214 private Vector3 _target_velocity;
217 private int m_eventsubscription;
227 private bool m_collisionsOnPreviousFrame;
229 private IntPtr m_linkJoint = IntPtr.Zero;
231 internal volatile bool childPrim;
235 internal int m_material = (int)
Material.Wood;
238 String primName,
OdeScene parent_scene, Vector3 pos, Vector3 size,
249 m_log.WarnFormat(
"[PHYSICS]: Got nonFinite Object create Position for {0}", Name);
252 m_taintposition = pos;
253 PID_D = parent_scene.bodyPIDD;
254 PID_G = parent_scene.bodyPIDG;
255 m_density = parent_scene.geomDefaultDensity;
257 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
259 prim_geom = IntPtr.Zero;
263 size =
new Vector3(0.5f, 0.5f, 0.5f);
264 m_log.WarnFormat(
"[PHYSICS]: Got nonFinite Object create Size for {0}", Name);
267 if (size.X <= 0) size.X = 0.01f;
268 if (size.Y <= 0) size.Y = 0.01f;
269 if (size.Z <= 0) size.Z = 0.01f;
274 if (!QuaternionIsFinite(rotation))
276 rotation = Quaternion.Identity;
277 m_log.WarnFormat(
"[PHYSICS]: Got nonFinite Object create Rotation for {0}", Name);
281 m_taintrot = _orientation;
284 _parent_scene = parent_scene;
285 m_targetSpace = (IntPtr)0;
293 IsPhysical = pisPhysical;
297 m_targetSpace = _parent_scene.space;
301 m_assetFailed =
false;
302 _parent_scene.AddPhysicsActorTaint(
this);
305 public override int PhysicsActorType
307 get {
return (
int) ActorTypes.Prim; }
313 get {
return false; }
317 public override bool Grabbed
330 m_collisionscore = 0;
332 if ((IsPhysical && !_zeroFlag) || !value)
334 m_taintselected = value;
335 _parent_scene.AddPhysicsActorTaint(
this);
339 m_taintselected = value;
340 m_isSelected = value;
352 private void SetGeom(IntPtr geom)
359 d.GeomSetCategoryBits(prim_geom, 0);
360 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
364 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
365 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
368 _parent_scene.geom_name_map[prim_geom] = Name;
369 _parent_scene.actor_name_map[prim_geom] =
this;
373 if (_parent != null && _parent is OdePrim)
375 OdePrim parent = (OdePrim)_parent;
377 parent.ChildSetGeom(
this);
383 private void enableBodySoft()
387 if (IsPhysical && Body != IntPtr.Zero)
390 if (m_vehicle.Type !=
Vehicle.TYPE_NONE)
391 m_vehicle.Enable(
Body, _parent_scene);
398 private void disableBodySoft()
402 if (IsPhysical && Body != IntPtr.Zero)
411 private void enableBody()
418 Body = d.BodyCreate(_parent_scene.world);
421 d.BodySetPosition(
Body, _position.X, _position.Y, _position.Z);
422 d.Quaternion myrot =
new d.Quaternion();
423 myrot.X = _orientation.X;
424 myrot.Y = _orientation.Y;
425 myrot.Z = _orientation.Z;
426 myrot.W = _orientation.W;
427 d.BodySetQuaternion(Body, ref myrot);
428 d.GeomSetBody(prim_geom, Body);
432 d.GeomSetCategoryBits(prim_geom, 0);
433 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
437 m_collisionCategories |= CollisionCategories.Body;
438 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
441 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
442 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
444 d.BodySetAutoDisableFlag(
Body,
true);
445 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
448 d.BodySetGravityMode (Body,
false);
450 m_interpenetrationcount = 0;
451 m_collisionscore = 0;
455 if (m_angularlock != 0 && _parent == null)
457 createAMotor(m_angularlock);
459 if (m_vehicle.Type !=
Vehicle.TYPE_NONE)
461 m_vehicle.Enable(Body, _parent_scene);
464 _parent_scene.ActivatePrim(
this);
468 #region Mass Calculation
470 private float CalculateMass()
472 float volume = _size.X * _size.Y * _size.Z;
475 float returnMass = 0;
476 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
477 float hollowVolume = hollowAmount * hollowAmount;
479 switch (_pbs.ProfileShape)
481 case ProfileShape.Square:
484 if (_pbs.PathCurve == (byte)Extrusion.Straight)
486 if (hollowAmount > 0.0)
488 switch (_pbs.HollowShape)
490 case HollowShape.Square:
491 case HollowShape.Same:
494 case HollowShape.Circle:
496 hollowVolume *= 0.78539816339f;
499 case HollowShape.Triangle:
501 hollowVolume *= (0.5f * .5f);
508 volume *= (1.0f - hollowVolume);
512 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
516 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
517 tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY);
518 volume -= volume*tmp*tmp;
520 if (hollowAmount > 0.0)
522 hollowVolume *= hollowAmount;
524 switch (_pbs.HollowShape)
526 case HollowShape.Square:
527 case HollowShape.Same:
530 case HollowShape.Circle:
531 hollowVolume *= 0.78539816339f;;
534 case HollowShape.Triangle:
535 hollowVolume *= 0.5f * 0.5f;
541 volume *= (1.0f - hollowVolume);
547 case ProfileShape.Circle:
549 if (_pbs.PathCurve == (byte)Extrusion.Straight)
551 volume *= 0.78539816339f;
553 if (hollowAmount > 0.0)
555 switch (_pbs.HollowShape)
557 case HollowShape.Same:
558 case HollowShape.Circle:
561 case HollowShape.Square:
562 hollowVolume *= 0.5f * 2.5984480504799f;
565 case HollowShape.Triangle:
566 hollowVolume *= .5f * 1.27323954473516f;
573 volume *= (1.0f - hollowVolume);
577 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
579 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
580 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
581 volume *= (1.0f - tmp * tmp);
583 if (hollowAmount > 0.0)
587 hollowVolume *= hollowAmount;
589 switch (_pbs.HollowShape)
591 case HollowShape.Same:
592 case HollowShape.Circle:
595 case HollowShape.Square:
596 hollowVolume *= 0.5f * 2.5984480504799f;
599 case HollowShape.Triangle:
600 hollowVolume *= .5f * 1.27323954473516f;
607 volume *= (1.0f - hollowVolume);
612 case ProfileShape.HalfCircle:
613 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
615 volume *= 0.52359877559829887307710723054658f;
619 case ProfileShape.EquilateralTriangle:
621 if (_pbs.PathCurve == (byte)Extrusion.Straight)
623 volume *= 0.32475953f;
625 if (hollowAmount > 0.0)
629 switch (_pbs.HollowShape)
631 case HollowShape.Same:
632 case HollowShape.Triangle:
633 hollowVolume *= .25f;
636 case HollowShape.Square:
637 hollowVolume *= 0.499849f * 3.07920140172638f;
640 case HollowShape.Circle:
644 hollowVolume *= 0.1963495f * 3.07920140172638f;
651 volume *= (1.0f - hollowVolume);
654 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
656 volume *= 0.32475953f;
657 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
658 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
659 volume *= (1.0f - tmp * tmp);
661 if (hollowAmount > 0.0)
664 hollowVolume *= hollowAmount;
666 switch (_pbs.HollowShape)
668 case HollowShape.Same:
669 case HollowShape.Triangle:
670 hollowVolume *= .25f;
673 case HollowShape.Square:
674 hollowVolume *= 0.499849f * 3.07920140172638f;
677 case HollowShape.Circle:
679 hollowVolume *= 0.1963495f * 3.07920140172638f;
686 volume *= (1.0f - hollowVolume);
704 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)
Extrusion.Flexible)
706 taperX1 = _pbs.PathScaleX * 0.01f;
708 taperX1 = 2.0f - taperX1;
709 taperX = 1.0f - taperX1;
711 taperY1 = _pbs.PathScaleY * 0.01f;
713 taperY1 = 2.0f - taperY1;
714 taperY = 1.0f - taperY1;
718 taperX = _pbs.PathTaperX * 0.01f;
721 taperX1 = 1.0f - taperX;
723 taperY = _pbs.PathTaperY * 0.01f;
726 taperY1 = 1.0f - taperY;
729 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
731 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
732 pathEnd = 1.0f - (
float)_pbs.PathEnd * 2.0e-5f;
733 volume *= (pathEnd - pathBegin);
736 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
737 profileEnd = 1.0f - (
float)_pbs.ProfileEnd * 2.0e-5f;
738 volume *= (profileEnd - profileBegin);
740 returnMass = m_density * volume;
743 returnMass = 0.0001f;
748 bool HasChildPrim =
false;
751 if (childrenPrim.Count > 0)
759 OdePrim[] childPrimArr =
new OdePrim[0];
762 childPrimArr = childrenPrim.ToArray();
764 for (
int i = 0; i < childPrimArr.Length; i++)
766 if (childPrimArr[i] != null && !childPrimArr[i].m_taintremove)
767 returnMass += childPrimArr[i].CalculateMass();
774 if (returnMass > _parent_scene.maximumMassObject)
775 returnMass = _parent_scene.maximumMassObject;
782 private void setMass()
784 if (Body != (IntPtr) 0)
786 float newmass = CalculateMass();
790 d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z);
791 d.BodySetMass(Body, ref pMass);
795 private void setAngularVelocity(
float x,
float y,
float z)
797 if (Body != (IntPtr)0)
799 d.BodySetAngularVel(Body, x, y, z);
806 internal void disableBody()
813 if (Body != IntPtr.Zero)
815 _parent_scene.DeactivatePrim(
this);
817 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
821 d.GeomSetCategoryBits(prim_geom, 0);
822 d.GeomSetCollideBits(prim_geom, 0);
826 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
827 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
833 if (childrenPrim.Count > 0)
835 foreach (OdePrim prm
in childrenPrim)
837 _parent_scene.DeactivatePrim(prm);
838 prm.Body = IntPtr.Zero;
847 _parent_scene.DeactivatePrim(
this);
850 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
854 d.GeomSetCategoryBits(prim_geom, 0);
855 d.GeomSetCollideBits(prim_geom, 0);
860 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
861 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
869 m_collisionscore = 0;
872 private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap =
new Dictionary<IMesh, IntPtr>();
874 private void setMesh(OdeScene parent_scene,
IMesh mesh)
884 if (IsPhysical && Body != IntPtr.Zero)
890 OdePrim parent = (OdePrim)_parent;
891 parent.ChildDelink(
this);
900 IntPtr vertices, indices;
901 int vertexCount, indexCount;
902 int vertexStride, triStride;
903 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
904 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
905 m_expectedCollisionContacts = indexCount;
906 mesh.releaseSourceMeshData();
910 lock (m_MeshToTriMeshMap)
912 if (m_MeshToTriMeshMap.ContainsKey(mesh))
914 _triMeshData = m_MeshToTriMeshMap[mesh];
918 _triMeshData = d.GeomTriMeshDataCreate();
920 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
921 d.GeomTriMeshDataPreprocess(_triMeshData);
922 m_MeshToTriMeshMap[mesh] = _triMeshData;
929 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
931 catch (AccessViolationException)
933 m_log.ErrorFormat(
"[PHYSICS]: MESH LOCKED FOR {0}", Name);
947 internal void ProcessTaints()
950 Console.WriteLine(
"ZProcessTaints for " + Name);
958 if (!_position.ApproxEquals(m_taintposition, 0f))
961 if (m_taintrot != _orientation)
963 if (childPrim && IsPhysical)
968 OdePrim parent = (OdePrim)_parent;
978 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent))
979 changePhysicsStatus();
981 if (!_size.ApproxEquals(m_taintsize, 0f))
990 if (m_taintaddangularforce)
991 changeAddAngularForce();
993 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
999 if (m_taintselected != m_isSelected)
1000 changeSelectedStatus();
1002 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
1005 if (m_taintparent != _parent)
1008 if (m_taintCollidesWater != m_collidesWater)
1009 changefloatonwater();
1011 if (m_taintAngularLock != m_angularlock)
1012 changeAngularLock();
1018 private void changeAngularLock()
1021 if (Body != IntPtr.Zero)
1025 if (_parent == null)
1027 if (m_taintAngularLock != 0)
1029 createAMotor(m_taintAngularLock);
1033 if (Amotor != IntPtr.Zero)
1035 d.JointDestroy(Amotor);
1036 Amotor = IntPtr.Zero;
1042 m_angularlock = m_taintAngularLock;
1048 private void changelink()
1052 if (_parent == null && m_taintparent != null)
1054 if (m_taintparent.PhysicsActorType == (
int)
ActorTypes.Prim)
1056 OdePrim obj = (OdePrim)m_taintparent;
1059 obj.AddChildPrim(
this);
1074 else if (_parent != null && m_taintparent == null)
1078 if (_parent is OdePrim)
1080 OdePrim obj = (OdePrim)_parent;
1081 obj.ChildDelink(
this);
1095 _parent = m_taintparent;
1096 m_taintPhysics = IsPhysical;
1103 private void AddChildPrim(OdePrim prim)
1105 if (LocalID == prim.LocalID)
1108 if (Body == IntPtr.Zero)
1110 Body = d.BodyCreate(_parent_scene.world);
1116 if (childrenPrim.Contains(prim))
1122 childrenPrim.Add(prim);
1124 foreach (OdePrim prm
in childrenPrim)
1127 d.MassSetZero(out m2);
1128 d.MassSetBoxTotal(out m2, prm.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1130 d.Quaternion quat =
new d.Quaternion();
1131 quat.W = prm._orientation.W;
1132 quat.X = prm._orientation.X;
1133 quat.Y = prm._orientation.Y;
1134 quat.Z = prm._orientation.Z;
1136 d.Matrix3 mat =
new d.Matrix3();
1137 d.RfromQ(out mat, ref quat);
1138 d.MassRotate(ref m2, ref mat);
1139 d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
1140 d.MassAdd(ref pMass, ref m2);
1143 foreach (OdePrim prm
in childrenPrim)
1145 prm.m_collisionCategories |= CollisionCategories.Body;
1146 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1149 if (prm.m_assetFailed)
1151 d.GeomSetCategoryBits(prm.prim_geom, 0);
1152 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits);
1156 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1157 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1160 d.Quaternion quat =
new d.Quaternion();
1161 quat.W = prm._orientation.W;
1162 quat.X = prm._orientation.X;
1163 quat.Y = prm._orientation.Y;
1164 quat.Z = prm._orientation.Z;
1166 d.Matrix3 mat =
new d.Matrix3();
1167 d.RfromQ(out mat, ref quat);
1168 if (Body != IntPtr.Zero)
1170 d.GeomSetBody(prm.prim_geom, Body);
1171 prm.childPrim =
true;
1172 d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z);
1177 d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat);
1179 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1180 d.BodySetMass(Body, ref pMass);
1184 m_log.DebugFormat(
"[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name);
1187 prm.m_interpenetrationcount = 0;
1188 prm.m_collisionscore = 0;
1189 prm.m_disabled =
false;
1192 _parent_scene.ActivatePrim(prm);
1195 m_collisionCategories |= CollisionCategories.Body;
1196 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1200 d.GeomSetCategoryBits(prim_geom, 0);
1201 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
1206 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1208 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1211 d.Quaternion quat2 =
new d.Quaternion();
1212 quat2.W = _orientation.W;
1213 quat2.X = _orientation.X;
1214 quat2.Y = _orientation.Y;
1215 quat2.Z = _orientation.Z;
1217 d.Matrix3 mat2 =
new d.Matrix3();
1218 d.RfromQ(out mat2, ref quat2);
1219 d.GeomSetBody(prim_geom, Body);
1220 d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
1226 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1227 d.BodySetMass(Body, ref pMass);
1229 d.BodySetAutoDisableFlag(Body,
true);
1230 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1232 m_interpenetrationcount = 0;
1233 m_collisionscore = 0;
1238 if (_parent == null)
1240 createAMotor(m_angularlock);
1243 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
1245 if (m_vehicle.Type !=
Vehicle.TYPE_NONE)
1246 m_vehicle.Enable(Body, _parent_scene);
1248 _parent_scene.ActivatePrim(
this);
1252 private void ChildSetGeom(OdePrim odePrim)
1260 foreach (OdePrim prm
in childrenPrim)
1282 foreach (OdePrim prm
in childrenPrim)
1290 private void ChildDelink(OdePrim odePrim)
1298 foreach (OdePrim prm
in childrenPrim)
1300 prm.childPrim =
true;
1315 childrenPrim.Remove(odePrim);
1326 foreach (OdePrim prm
in childrenPrim)
1337 private void changeSelectedStatus()
1339 if (m_taintselected)
1341 m_collisionCategories = CollisionCategories.Selected;
1342 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
1373 d.GeomSetCategoryBits(prim_geom, 0);
1374 d.GeomSetCollideBits(prim_geom, 0);
1378 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1379 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1389 m_collisionCategories = CollisionCategories.Geom;
1392 m_collisionCategories |= CollisionCategories.Body;
1394 m_collisionFlags = m_default_collisionFlags;
1397 m_collisionFlags |= CollisionCategories.Land;
1398 if (m_collidesWater)
1399 m_collisionFlags |= CollisionCategories.Water;
1403 d.GeomSetCategoryBits(prim_geom, 0);
1404 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
1408 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1409 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1414 if (Body != IntPtr.Zero)
1416 d.BodySetLinearVel(Body, 0f, 0f, 0f);
1417 d.BodySetForce(Body, 0, 0, 0);
1423 resetCollisionAccounting();
1424 m_isSelected = m_taintselected;
1427 internal void ResetTaints()
1429 m_taintposition = _position;
1430 m_taintrot = _orientation;
1431 m_taintPhysics = IsPhysical;
1432 m_taintselected = m_isSelected;
1433 m_taintsize = _size;
1434 m_taintshape =
false;
1435 m_taintforce =
false;
1436 m_taintdisable =
false;
1437 m_taintVelocity = Vector3.Zero;
1445 private void CreateGeom(IntPtr m_targetSpace,
IMesh mesh)
1448 Console.WriteLine(
"CreateGeom:");
1452 setMesh(_parent_scene, mesh);
1458 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
1460 if (((_size.X / 2f) > 0f))
1466 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
1467 m_expectedCollisionContacts = 3;
1469 catch (AccessViolationException)
1471 m_log.WarnFormat(
"[PHYSICS]: Unable to create physics proxy for object {0}", Name);
1481 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1482 m_expectedCollisionContacts = 4;
1484 catch (AccessViolationException)
1486 m_log.WarnFormat(
"[PHYSICS]: Unable to create physics proxy for object {0}", Name);
1497 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1498 m_expectedCollisionContacts = 4;
1500 catch (AccessViolationException)
1502 m_log.WarnFormat(
"[PHYSICS]: Unable to create physics proxy for object {0}", Name);
1513 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1514 m_expectedCollisionContacts = 4;
1516 catch (AccessViolationException)
1518 m_log.WarnFormat(
"[PHYSICS]: Unable to create physics proxy for object {0}", Name);
1531 internal bool RemoveGeom()
1533 if (prim_geom != IntPtr.Zero)
1537 _parent_scene.geom_name_map.Remove(prim_geom);
1538 _parent_scene.actor_name_map.Remove(prim_geom);
1539 d.GeomDestroy(prim_geom);
1540 m_expectedCollisionContacts = 0;
1541 prim_geom = IntPtr.Zero;
1543 catch (System.AccessViolationException)
1545 prim_geom = IntPtr.Zero;
1546 m_expectedCollisionContacts = 0;
1547 m_log.ErrorFormat(
"[PHYSICS]: PrimGeom dead for {0}", Name);
1557 "[ODE PRIM]: Called RemoveGeom() on {0} {1} where geometry was already null.", Name, LocalID);
1565 private void changeadd()
1569 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
1570 IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
1572 if (targetspace == IntPtr.Zero)
1573 targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
1575 m_targetSpace = targetspace;
1579 if (_parent_scene.needsMeshing(_pbs))
1582 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
1588 m_assetFailed =
false;
1592 Console.WriteLine(
"changeadd 1");
1594 CreateGeom(m_targetSpace, mesh);
1596 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1597 d.Quaternion myrot =
new d.Quaternion();
1598 myrot.X = _orientation.X;
1599 myrot.Y = _orientation.Y;
1600 myrot.Z = _orientation.Z;
1601 myrot.W = _orientation.W;
1602 d.GeomSetQuaternion(prim_geom, ref myrot);
1604 if (IsPhysical && Body == IntPtr.Zero)
1607 changeSelectedStatus();
1615 private void changemove()
1619 if (!m_disabled && !m_taintremove && !childPrim)
1621 if (Body == IntPtr.Zero)
1626 if (_parent != null)
1628 if (m_linkJoint != IntPtr.Zero)
1630 d.JointDestroy(m_linkJoint);
1631 m_linkJoint = IntPtr.Zero;
1635 if (Body != IntPtr.Zero)
1637 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
1639 if (_parent != null)
1641 OdePrim odParent = (OdePrim)_parent;
1642 if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body)
1645 Console.WriteLine(
" JointCreateFixed");
1646 m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
1647 d.JointAttach(m_linkJoint, Body, odParent.Body);
1648 d.JointSetFixed(m_linkJoint);
1652 if (m_vehicle.Type !=
Vehicle.TYPE_NONE)
1654 m_vehicle.Enable(Body, _parent_scene);
1659 m_log.WarnFormat(
"[PHYSICS]: Body for {0} still null after enableBody(). This is a crash scenario.", Name);
1672 IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
1673 m_targetSpace = tempspace;
1677 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1680 d.SpaceAdd(m_targetSpace, prim_geom);
1682 changeSelectedStatus();
1684 resetCollisionAccounting();
1685 m_taintposition = _position;
1688 internal void Move(
float timestep)
1697 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim)
1699 if (m_vehicle.Type !=
Vehicle.TYPE_NONE)
1702 m_vehicle.Step(timestep, _parent_scene);
1707 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
1709 float m_mass = CalculateMass();
1719 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass;
1736 if ((m_PIDTau < 1) && (m_PIDTau != 0))
1742 if ((PID_G - m_PIDTau) <= 0)
1744 PID_G = m_PIDTau + 1;
1749 d.Vector3 vel = d.BodyGetLinearVel(Body);
1751 d.Vector3 pos = d.BodyGetPosition(Body);
1754 (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
1755 (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
1756 (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
1761 if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f))
1773 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
1774 d.BodySetLinearVel(Body, 0, 0, 0);
1775 d.BodyAddForce(Body, 0, 0, fz);
1783 fx = ((_target_velocity.X) - vel.X) * (PID_D);
1784 fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
1788 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1793 if (m_useHoverPID && !PIDActive)
1798 fz = (-1 * _parent_scene.gravityz) * m_mass;
1807 PID_G = PID_G / m_PIDTau;
1810 if ((PID_G - m_PIDTau) <= 0)
1812 PID_G = m_PIDTau + 1;
1816 d.Vector3 pos = d.BodyGetPosition(Body);
1817 d.Vector3 vel = d.BodyGetLinearVel(Body);
1821 switch (m_PIDHoverType)
1823 case PIDHoverType.Ground:
1824 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
1825 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
1827 case PIDHoverType.GroundAndWater:
1828 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
1829 m_waterHeight = _parent_scene.GetWaterLevel();
1830 if (m_groundHeight > m_waterHeight)
1832 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
1836 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
1844 new Vector3(0.0f, 0.0f,
1845 (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep)
1850 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
1859 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
1860 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
1861 d.BodyAddForce(Body, 0, 0, fz);
1869 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1882 if (fx != 0 || fy != 0 || fz != 0)
1887 if (!d.BodyIsEnabled(Body))
1892 d.BodySetLinearVel(Body, 0f, 0f, 0f);
1893 d.BodySetForce(Body, 0, 0, 0);
1898 float nmax = 35f * m_mass;
1899 float nmin = -35f * m_mass;
1909 d.BodyAddForce(Body, fx, fy, fz);
1923 private void rotate()
1925 d.Quaternion myrot =
new d.Quaternion();
1926 myrot.X = _orientation.X;
1927 myrot.Y = _orientation.Y;
1928 myrot.Z = _orientation.Z;
1929 myrot.W = _orientation.W;
1930 if (Body != IntPtr.Zero)
1933 d.BodySetQuaternion(Body, ref myrot);
1937 createAMotor(m_angularlock);
1943 d.GeomSetQuaternion(prim_geom, ref myrot);
1946 resetCollisionAccounting();
1947 m_taintrot = _orientation;
1950 private void resetCollisionAccounting()
1952 m_collisionscore = 0;
1953 m_interpenetrationcount = 0;
1960 private void changedisable()
1963 if (Body != IntPtr.Zero)
1965 d.BodyDisable(Body);
1969 m_taintdisable =
false;
1975 private void changePhysicsStatus()
1979 if (Body == IntPtr.Zero)
1981 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
1993 if (Body != IntPtr.Zero)
1995 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
2005 if (_parent != null)
2007 OdePrim parent = (OdePrim)_parent;
2008 parent.ChildDelink(
this);
2018 changeSelectedStatus();
2020 resetCollisionAccounting();
2021 m_taintPhysics = IsPhysical;
2030 m_log.DebugFormat(
"[ODE PRIM]: Called changesize");
2033 if (_size.X <= 0) _size.X = 0.01f;
2034 if (_size.Y <= 0) _size.Y = 0.01f;
2035 if (_size.Z <= 0) _size.Z = 0.01f;
2038 if (IsPhysical && Body != IntPtr.Zero)
2042 if (_parent != null)
2044 OdePrim parent = (OdePrim)_parent;
2045 parent.ChildDelink(
this);
2054 if (d.SpaceQuery(m_targetSpace, prim_geom))
2057 d.SpaceRemove(m_targetSpace, prim_geom);
2067 if (_parent_scene.needsMeshing(_pbs))
2069 float meshlod = _parent_scene.meshSculptLOD;
2072 meshlod = _parent_scene.MeshSculptphysicalLOD;
2075 if (_parent_scene.needsMeshing(_pbs))
2077 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
2081 m_assetFailed =
false;
2086 CreateGeom(m_targetSpace, mesh);
2087 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2088 d.Quaternion myrot =
new d.Quaternion();
2089 myrot.X = _orientation.X;
2090 myrot.Y = _orientation.Y;
2091 myrot.Z = _orientation.Z;
2092 myrot.W = _orientation.W;
2093 d.GeomSetQuaternion(prim_geom, ref myrot);
2096 if (IsPhysical && Body == IntPtr.Zero && !childPrim)
2104 changeSelectedStatus();
2108 if (_parent is OdePrim)
2110 OdePrim parent = (OdePrim)_parent;
2111 parent.ChildSetGeom(
this);
2114 resetCollisionAccounting();
2115 m_taintsize = _size;
2122 private void changefloatonwater()
2124 m_collidesWater = m_taintCollidesWater;
2126 if (m_collidesWater)
2128 m_collisionFlags |= CollisionCategories.Water;
2136 d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits);
2139 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
2144 private void changeshape()
2146 m_taintshape =
false;
2149 if (IsPhysical && Body != IntPtr.Zero)
2153 if (_parent != null)
2155 OdePrim parent = (OdePrim)_parent;
2156 parent.ChildDelink(
this);
2168 if (_size.X <= 0) _size.X = 0.01f;
2169 if (_size.Y <= 0) _size.Y = 0.01f;
2170 if (_size.Z <= 0) _size.Z = 0.01f;
2176 if (_parent_scene.needsMeshing(_pbs))
2179 float meshlod = _parent_scene.meshSculptLOD;
2182 meshlod = _parent_scene.MeshSculptphysicalLOD;
2185 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
2189 m_assetFailed =
false;
2192 CreateGeom(m_targetSpace, mesh);
2193 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2194 d.Quaternion myrot =
new d.Quaternion();
2196 myrot.W = _orientation.W;
2197 myrot.X = _orientation.X;
2198 myrot.Y = _orientation.Y;
2199 myrot.Z = _orientation.Z;
2200 d.GeomSetQuaternion(prim_geom, ref myrot);
2203 if (IsPhysical && Body == IntPtr.Zero)
2208 if (Body != IntPtr.Zero)
2214 changeSelectedStatus();
2218 if (_parent is OdePrim)
2220 OdePrim parent = (OdePrim)_parent;
2221 parent.ChildSetGeom(
this);
2225 resetCollisionAccounting();
2232 private void changeAddForce()
2241 Vector3 iforce = Vector3.Zero;
2245 for (i = 0; i < m_forcelist.Count; i++)
2248 iforce = iforce + (m_forcelist[i] * 100);
2251 catch (IndexOutOfRangeException)
2253 m_forcelist =
new List<Vector3>();
2254 m_collisionscore = 0;
2255 m_interpenetrationcount = 0;
2256 m_taintforce =
false;
2259 catch (ArgumentOutOfRangeException)
2261 m_forcelist =
new List<Vector3>();
2262 m_collisionscore = 0;
2263 m_interpenetrationcount = 0;
2264 m_taintforce =
false;
2268 d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z);
2270 m_forcelist.Clear();
2273 m_collisionscore = 0;
2274 m_interpenetrationcount = 0;
2277 m_taintforce =
false;
2283 private void changeSetTorque()
2287 if (IsPhysical && Body != IntPtr.Zero)
2289 d.BodySetTorque(Body, m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z);
2293 m_taintTorque = Vector3.Zero;
2299 private void changeAddAngularForce()
2303 lock (m_angularforcelist)
2308 Vector3 iforce = Vector3.Zero;
2309 for (
int i = 0; i < m_angularforcelist.Count; i++)
2311 iforce = iforce + (m_angularforcelist[i] * 100);
2314 d.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z);
2317 m_angularforcelist.Clear();
2320 m_collisionscore = 0;
2321 m_interpenetrationcount = 0;
2324 m_taintaddangularforce =
false;
2330 private void changevelocity()
2340 if (Body != IntPtr.Zero)
2342 d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
2349 m_taintVelocity = Vector3.Zero;
2352 internal void setPrimForRemoval()
2354 m_taintremove =
true;
2357 public override bool Flying
2360 get {
return false; }
2364 public override bool IsColliding
2366 get {
return iscolliding; }
2367 set { iscolliding = value; }
2370 public override bool CollidingGround
2372 get {
return false; }
2376 public override bool CollidingObj
2378 get {
return false; }
2382 public override bool ThrottleUpdates
2384 get {
return m_throttleUpdates; }
2385 set { m_throttleUpdates = value; }
2388 public override bool Stopped
2390 get {
return _zeroFlag; }
2395 get {
return _position; }
2397 set { _position = value;
2402 public override Vector3
Size
2404 get {
return _size; }
2407 if (value.IsFinite())
2414 m_log.WarnFormat(
"[PHYSICS]: Got NaN Size on object {0}", Name);
2419 public override float Mass
2421 get {
return CalculateMass(); }
2424 public override Vector3 Force
2427 get {
return m_force; }
2430 if (value.IsFinite())
2436 m_log.WarnFormat(
"[PHYSICS]: NaN in Force Applied to an Object {0}", Name);
2441 public override int VehicleType
2443 get {
return (
int)m_vehicle.Type; }
2444 set { m_vehicle.ProcessTypeChange((
Vehicle)value); }
2449 m_vehicle.ProcessFloatVehicleParam((
Vehicle) param, value);
2454 m_vehicle.ProcessVectorVehicleParam((
Vehicle) param, value);
2459 m_vehicle.ProcessRotationVehicleParam((
Vehicle) param, rotation);
2464 m_vehicle.ProcessVehicleFlags(param,
remove);
2471 lock (_parent_scene.OdeLock)
2473 m_isVolumeDetect = (param != 0);
2477 public override Vector3 CenterOfMass
2479 get {
return Vector3.Zero; }
2482 public override Vector3 GeometricCenter
2484 get {
return Vector3.Zero; }
2492 m_assetFailed =
false;
2493 m_taintshape =
true;
2504 return Vector3.Zero;
2506 Vector3 returnVelocity = Vector3.Zero;
2507 returnVelocity.X = (m_lastVelocity.X + _velocity.X) * 0.5f;
2508 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) * 0.5f;
2509 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) * 0.5f;
2510 return returnVelocity;
2514 if (value.IsFinite())
2518 m_taintVelocity = value;
2519 _parent_scene.AddPhysicsActorTaint(
this);
2523 m_log.WarnFormat(
"[PHYSICS]: Got NaN Velocity in Object {0}", Name);
2529 public override Vector3 Torque
2533 if (!IsPhysical || Body == IntPtr.Zero)
2534 return Vector3.Zero;
2541 if (value.IsFinite())
2543 m_taintTorque = value;
2544 _parent_scene.AddPhysicsActorTaint(
this);
2548 m_log.WarnFormat(
"[PHYSICS]: Got NaN Torque in Object {0}", Name);
2553 public override float CollisionScore
2555 get {
return m_collisionscore; }
2556 set { m_collisionscore = value; }
2559 public override bool Kinematic
2561 get {
return false; }
2565 public override Quaternion Orientation
2567 get {
return _orientation; }
2570 if (QuaternionIsFinite(value))
2571 _orientation = value;
2573 m_log.WarnFormat(
"[PHYSICS]: Got NaN quaternion Orientation from Scene in Object {0}", Name);
2577 private static bool QuaternionIsFinite(Quaternion q)
2579 if (Single.IsNaN(q.X) || Single.IsInfinity(q.X))
2581 if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y))
2583 if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z))
2585 if (Single.IsNaN(q.W) || Single.IsInfinity(q.W))
2592 get {
return _acceleration; }
2593 set { _acceleration = value; }
2596 public override void AddForce(Vector3 force,
bool pushforce)
2598 if (force.IsFinite())
2601 m_forcelist.Add(force);
2603 m_taintforce =
true;
2607 m_log.WarnFormat(
"[PHYSICS]: Got Invalid linear force vector from Scene in Object {0}", Name);
2614 if (force.IsFinite())
2616 m_angularforcelist.Add(force);
2617 m_taintaddangularforce =
true;
2621 m_log.WarnFormat(
"[PHYSICS]: Got Invalid Angular force vector from Scene in Object {0}", Name);
2625 public override Vector3 RotationalVelocity
2629 Vector3 pv = Vector3.Zero;
2632 m_lastUpdateSent =
false;
2634 if (m_rotationalVelocity.ApproxEquals(pv, 0.2f))
2637 return m_rotationalVelocity;
2641 if (value.IsFinite())
2643 m_rotationalVelocity = value;
2644 setAngularVelocity(value.X, value.Y, value.Z);
2648 m_log.WarnFormat(
"[PHYSICS]: Got NaN RotationalVelocity in Object {0}", Name);
2668 d.AllocateODEDataForThread(0U);
2670 _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f);
2671 _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f);
2672 _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
2674 m_lastposition = _position;
2679 m_lastVelocity = _velocity;
2681 if (Body != IntPtr.Zero)
2683 d.BodySetLinearVel(Body, 0, 0, 0);
2684 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
2687 if(m_vehicle != null && m_vehicle.Type !=
Vehicle.TYPE_NONE)
2692 outofBounds =
false;
2693 base.RequestPhysicsterseUpdate();
2697 public override float Buoyancy
2699 get {
return m_buoyancy; }
2700 set { m_buoyancy = value; }
2705 m_taintparent = obj;
2710 m_taintparent = null;
2716 m_taintAngularLock = axislocks;
2719 internal void UpdatePositionAndVelocity()
2724 if (_parent == null)
2726 Vector3 pv = Vector3.Zero;
2727 bool lastZeroFlag = _zeroFlag;
2728 float m_minvelocity = 0;
2729 if (Body != IntPtr.Zero)
2731 d.Vector3 vec = d.BodyGetPosition(Body);
2733 d.Vector3 vel = d.BodyGetLinearVel(Body);
2734 d.Vector3 rotvel = d.BodyGetAngularVel(Body);
2735 d.Vector3 torque = d.BodyGetTorque(Body);
2736 _torque =
new Vector3(torque.X, torque.Y, torque.Z);
2737 Vector3 l_position = Vector3.Zero;
2738 Quaternion l_orientation = Quaternion.Identity;
2740 m_lastposition = _position;
2741 m_lastorientation = _orientation;
2743 l_position.X = vec.X;
2744 l_position.Y = vec.Y;
2745 l_position.Z = vec.Z;
2746 l_orientation.X = ori.X;
2747 l_orientation.Y = ori.Y;
2748 l_orientation.Z = ori.Z;
2749 l_orientation.W = ori.W;
2751 if (l_position.Z < 0)
2761 _acceleration.X = 0;
2762 _acceleration.Y = 0;
2763 _acceleration.Z = 0;
2768 m_rotationalVelocity.X = 0;
2769 m_rotationalVelocity.Y = 0;
2770 m_rotationalVelocity.Z = 0;
2772 if (_parent == null)
2773 base.RaiseOutOfBounds(_position);
2775 if (_parent == null)
2776 base.RequestPhysicsterseUpdate();
2778 m_throttleUpdates =
false;
2779 throttleCounter = 0;
2785 if (l_position.X > ((
int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((
int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
2806 if (l_position.X < 0)
2807 Util.Clamp(l_position.X, -0.1f, -2f);
2809 Util.Clamp(l_position.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
2810 if (l_position.Y < 0)
2811 Util.Clamp(l_position.Y, -0.1f, -2f);
2813 Util.Clamp(l_position.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
2815 d.BodySetPosition(Body, l_position.X, l_position.Y, l_position.Z);
2818 d.BodySetAngularVel(Body, 0, 0, 0);
2819 d.BodySetLinearVel(Body, 0, 0, 0);
2822 _position = l_position;
2824 if (_parent == null)
2825 base.RequestPhysicsterseUpdate();
2832 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
2833 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
2834 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)
2836 && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001))
2840 m_throttleUpdates =
false;
2846 m_lastUpdateSent =
false;
2856 _acceleration.X = 0;
2857 _acceleration.Y = 0;
2858 _acceleration.Z = 0;
2864 m_rotationalVelocity.X = 0;
2865 m_rotationalVelocity.Y = 0;
2866 m_rotationalVelocity.Z = 0;
2867 if (!m_lastUpdateSent)
2869 m_throttleUpdates =
false;
2870 throttleCounter = 0;
2871 m_rotationalVelocity = pv;
2873 if (_parent == null)
2875 base.RequestPhysicsterseUpdate();
2878 m_lastUpdateSent =
true;
2883 if (lastZeroFlag != _zeroFlag)
2885 if (_parent == null)
2887 base.RequestPhysicsterseUpdate();
2891 m_lastVelocity = _velocity;
2893 _position = l_position;
2895 _velocity.X = vel.X;
2896 _velocity.Y = vel.Y;
2897 _velocity.Z = vel.Z;
2899 _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
2900 _acceleration =
new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f);
2907 if (m_throttleUpdates || PIDActive || (m_vehicle != null && m_vehicle.Type !=
Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero))
2909 m_minvelocity = 0.5f;
2913 m_minvelocity = 0.02f;
2916 if (_velocity.ApproxEquals(pv, m_minvelocity))
2918 m_rotationalVelocity = pv;
2922 m_rotationalVelocity =
new Vector3(rotvel.X, rotvel.Y, rotvel.Z);
2926 _orientation.X = ori.X;
2927 _orientation.Y = ori.Y;
2928 _orientation.Z = ori.Z;
2929 _orientation.W = ori.W;
2930 m_lastUpdateSent =
false;
2931 if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate)
2933 if (_parent == null)
2935 base.RequestPhysicsterseUpdate();
2943 m_lastposition = l_position;
2952 _acceleration.X = 0;
2953 _acceleration.Y = 0;
2954 _acceleration.Z = 0;
2956 m_rotationalVelocity.X = 0;
2957 m_rotationalVelocity.Y = 0;
2958 m_rotationalVelocity.Z = 0;
2964 public override bool FloatOnWater
2967 m_taintCollidesWater = value;
2968 _parent_scene.AddPhysicsActorTaint(
this);
2976 public override Vector3 PIDTarget
2980 if (value.IsFinite())
2982 m_PIDTarget = value;
2985 m_log.WarnFormat(
"[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name);
2989 public override bool PIDActive {
get; set; }
2990 public override float PIDTau { set { m_PIDTau = value; } }
2992 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2993 public override bool PIDHoverActive {
get {
return m_useHoverPID;} set { m_useHoverPID = value; } }
2995 public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
2997 public override Quaternion APIDTarget{ set {
return; } }
2999 public override bool APIDActive{ set {
return; } }
3001 public override float APIDStrength{ set {
return; } }
3003 public override float APIDDamping{ set {
return; } }
3005 private void createAMotor(byte axislock)
3007 if (Body == IntPtr.Zero)
3010 if (Amotor != IntPtr.Zero)
3012 d.JointDestroy(Amotor);
3013 Amotor = IntPtr.Zero;
3023 if((axislock & 0x02) != 0)
3028 if((axislock & 0x04) != 0)
3033 if((axislock & 0x08) != 0)
3042 d.BodySetTorque(Body, 0, 0, 0);
3043 d.BodySetAngularVel(Body, 0, 0, 0);
3045 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
3046 d.JointAttach(Amotor, Body, IntPtr.Zero);
3048 d.JointSetAMotorMode(Amotor, 0);
3050 d.JointSetAMotorNumAxes(Amotor, axisnum);
3054 d.Quaternion dcur = d.BodyGetQuaternion(Body);
3066 ax = (
new Vector3(1, 0, 0)) * curr;
3067 d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z);
3068 d.JointSetAMotorAngle(Amotor, 0, 0);
3069 d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, 0f);
3070 d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0f);
3071 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
3072 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f);
3073 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f);
3074 d.JointSetAMotorParam(Amotor, (int)d.JointParam.CFM, 0f);
3075 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f);
3076 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f);
3077 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f);
3084 ax = (
new Vector3(0, 1, 0)) * curr;
3085 d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z);
3086 d.JointSetAMotorAngle(Amotor, i, 0);
3087 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f);
3088 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f);
3089 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0);
3090 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
3091 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
3092 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f);
3093 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
3094 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
3095 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
3102 ax = (
new Vector3(0, 0, 1)) * curr;
3103 d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z);
3104 d.JointSetAMotorAngle(Amotor, i, 0);
3105 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f);
3106 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f);
3107 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0);
3108 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
3109 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
3110 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f);
3111 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
3112 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
3113 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
3119 m_eventsubscription = ms;
3120 _parent_scene.AddCollisionEventReporting(
this);
3125 _parent_scene.RemoveCollisionEventReporting(
this);
3126 m_eventsubscription = 0;
3131 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
3136 if (m_collisionsOnPreviousFrame || CollisionEventsThisFrame.Count > 0)
3138 base.SendCollisionUpdate(CollisionEventsThisFrame);
3140 if (CollisionEventsThisFrame.Count > 0)
3142 m_collisionsOnPreviousFrame =
true;
3143 CollisionEventsThisFrame.Clear();
3147 m_collisionsOnPreviousFrame =
false;
3154 if (m_eventsubscription > 0)
3161 m_material = pMaterial;
3164 private void CheckMeshAsset()
3166 if (_pbs.SculptEntry && !m_assetFailed && _pbs.SculptTexture != UUID.Zero)
3168 m_assetFailed =
true;
3169 Util.FireAndForget(delegate
3172 if (assetProvider != null)
3173 assetProvider(_pbs.SculptTexture, MeshAssetReceived);
3174 }, null,
"ODEPrim.CheckMeshAsset");
3178 private void MeshAssetReceived(
AssetBase asset)
3180 if (asset != null && asset.
Data != null && asset.
Data.Length > 0)
3182 if (!_pbs.SculptEntry)
3184 if (_pbs.SculptTexture.ToString() != asset.ID)
3187 _pbs.SculptData =
new byte[asset.Data.Length];
3188 asset.Data.CopyTo(_pbs.SculptData, 0);
3195 m_taintshape =
true;
3196 _parent_scene.AddPhysicsActorTaint(
this);
3201 "[ODE PRIM]: Could not get mesh/sculpt asset {0} for {1} at {2} in {3}",
3202 _pbs.SculptTexture, Name, _position, _parent_scene.PhysicsSceneName);
override void UnSubscribeEvents()
override void SetMomentum(Vector3 momentum)
override void VehicleVectorParam(int param, Vector3 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)
delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun)
override void AddAngularForce(Vector3 force, bool pushforce)
override void LockAngularMotion(byte axislocks)
Asset class. All Assets are reference by this class or a class derived from this class ...
Used to pass collision information to OnCollisionUpdate listeners.
Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ours...
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback)
override void VehicleFloatParam(int param, float value)
override void CrossingFailure()
override void link(PhysicsActor obj)
override void SubscribeEvents(int ms)
override void SetMaterial(int pMaterial)
override bool SubscribedEvents()
override void VehicleRotationParam(int param, Quaternion rotation)
Material
Material type for a primitive
override void VehicleFlags(int param, bool remove)
override void AddForce(Vector3 force, bool pushforce)