32 using System.Collections.Generic;
33 using System.Reflection;
36 using OpenSim.Framework;
37 using OpenSim.Region.PhysicsModules.SharedBase;
73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
75 private Vector3 _position;
76 private Vector3 _zeroPosition;
77 private Vector3 _velocity;
78 private Vector3 _target_velocity;
79 private Vector3 _acceleration;
80 private Vector3 m_rotationalVelocity;
81 private Vector3 m_size;
82 private Vector3 m_collideNormal;
83 private Quaternion m_orientation;
84 private Quaternion m_orientation2D;
85 private float m_mass = 80f;
86 public float m_density = 60f;
87 private bool m_pidControllerActive =
true;
89 const float basePID_D = 0.55f;
90 const float basePID_P = 0.225f;
94 private float timeStep;
95 private float invtimeStep;
97 private float m_feetOffset = 0;
98 private float feetOff = 0;
99 private float boneOff = 0;
100 private float AvaAvaSizeXsq = 0.3f;
101 private float AvaAvaSizeYsq = 0.2f;
103 public float walkDivisor = 1.3f;
104 public float runDivisor = 0.8f;
105 private bool flying =
false;
106 private bool m_iscolliding =
false;
107 private bool m_iscollidingGround =
false;
108 private bool m_iscollidingObj =
false;
109 private bool m_alwaysRun =
false;
111 private bool _zeroFlag =
false;
114 private uint m_localID = 0;
115 public bool m_returnCollisions =
false;
117 public bool m_isPhysical =
false;
118 public float MinimumGroundFlightOffset = 3f;
120 private float m_buoyancy = 0f;
122 private bool m_freemove =
false;
127 int m_colliderfilter = 0;
128 int m_colliderGroundfilter = 0;
129 int m_colliderObjectfilter = 0;
136 | CollisionCategories.Geom
137 | CollisionCategories.VolumeDtc
140 public IntPtr Body = IntPtr.Zero;
142 private IntPtr capsule = IntPtr.Zero;
143 public IntPtr collider = IntPtr.Zero;
145 public IntPtr Amotor = IntPtr.Zero;
149 public int m_eventsubscription = 0;
150 private int m_cureventsubscription = 0;
152 private bool SentEmptyCollisionsEvent;
156 public bool bad =
false;
161 private float m_PIDHoverHeight;
162 private float m_PIDHoverTau;
163 private bool m_useHoverPID;
165 private float m_targetHoverHeight;
168 public OdeCharacter(uint localID, String avName,
ODEScene parent_scene, Vector3 pos, Vector3 pSize,
float pfeetOffset,
float density,
float walk_divisor,
float rundivisor)
170 m_uuid = UUID.Random();
173 timeStep = parent_scene.ODE_STEPSIZE;
174 invtimeStep = 1 / timeStep;
180 pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
184 pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
190 _position =
new Vector3(((
float)_parent_scene.WorldExtents.X * 0.5f), ((
float)_parent_scene.WorldExtents.Y * 0.5f), parent_scene.
GetTerrainHeightAtXY(128f, 128f) + 10f);
191 m_log.Warn(
"[PHYSICS]: Got NaN Position on Character Create");
194 _parent_scene = parent_scene;
208 m_feetOffset = pfeetOffset;
209 m_orientation = Quaternion.Identity;
210 m_orientation2D = Quaternion.Identity;
216 mu = parent_scene.AvatarFriction;
218 walkDivisor = walk_divisor;
219 runDivisor = rundivisor;
221 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ;
223 PID_D = basePID_D * m_mass * invtimeStep;
224 PID_P = basePID_P * m_mass * invtimeStep;
226 m_isPhysical =
false;
233 public override int PhysicsActorType
235 get {
return (
int)ActorTypes.Agent; }
243 cdata.softcolide =
false;
246 public override bool Building {
get; set; }
253 get {
return m_alwaysRun; }
254 set { m_alwaysRun = value; }
257 public override uint LocalID
259 get {
return m_localID; }
260 set { m_localID = value; }
268 public override bool Grabbed
273 public override bool Selected
280 get {
return m_buoyancy; }
281 set { m_buoyancy = value; }
284 public override bool FloatOnWater
289 public override bool IsPhysical
291 get {
return m_isPhysical; }
295 public override bool ThrottleUpdates
297 get {
return false; }
301 public override bool Flying
303 get {
return flying; }
315 public override bool IsColliding
317 get {
return (m_iscolliding || m_iscollidingGround); }
322 m_colliderfilter += 3;
323 if (m_colliderfilter > 3)
324 m_colliderfilter = 3;
329 if (m_colliderfilter < 0)
330 m_colliderfilter = 0;
333 if (m_colliderfilter == 0)
334 m_iscolliding =
false;
337 m_pidControllerActive =
true;
338 m_iscolliding =
true;
347 public override bool CollidingGround
349 get {
return m_iscollidingGround; }
378 public override bool CollidingObj
380 get {
return m_iscollidingObj; }
386 m_colliderObjectfilter += 2;
387 if (m_colliderObjectfilter > 2)
388 m_colliderObjectfilter = 2;
392 m_colliderObjectfilter--;
393 if (m_colliderObjectfilter < 0)
394 m_colliderObjectfilter = 0;
397 if (m_colliderObjectfilter == 0)
398 m_iscollidingObj =
false;
400 m_iscollidingObj =
true;
404 if (m_iscollidingObj)
405 m_pidControllerActive =
false;
407 m_pidControllerActive =
true;
418 m_pidControllerActive = status;
421 public override bool Stopped
423 get {
return _zeroFlag; }
433 get {
return _position; }
436 if (value.IsFinite())
438 if (value.Z > 9999999f)
440 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
444 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
446 AddChange(
changes.Position, value);
450 m_log.Warn(
"[PHYSICS]: Got a NaN Position from Scene on a Character");
455 public override Vector3 RotationalVelocity
457 get {
return m_rotationalVelocity; }
458 set { m_rotationalVelocity = value; }
465 public override Vector3
Size
473 if (value.IsFinite())
482 AddChange(
changes.Size, value);
486 m_log.Warn(
"[PHYSICS]: Got a NaN Size from Scene on a Character");
502 strAvatarSize st =
new strAvatarSize();
504 st.offset = feetOffset;
505 AddChange(
changes.AvatarSize, st);
509 m_log.Warn(
"[PHYSICS]: Got a NaN AvatarSize from Scene on a Character");
525 public override float Mass
548 public override Vector3
Force
550 get {
return _target_velocity; }
585 public override Vector3 CenterOfMass
589 Vector3 pos = _position;
594 public override Vector3 GeometricCenter
598 Vector3 pos = _position;
616 if (value.IsFinite())
618 AddChange(
changes.Velocity, value);
622 m_log.Warn(
"[PHYSICS]: Got a NaN velocity from Scene in a Character");
627 public override Vector3
Torque
629 get {
return Vector3.Zero; }
633 public override float CollisionScore
639 public override bool Kinematic
641 get {
return false; }
645 public override Quaternion Orientation
647 get {
return m_orientation; }
653 AddChange(
changes.Orientation, value);
659 get {
return _acceleration; }
665 m_pidControllerActive =
true;
666 _acceleration = accel;
674 public override void AddForce(Vector3 force,
bool pushforce)
676 if (force.IsFinite())
680 AddChange(
changes.Force, force * m_density / (_parent_scene.ODE_STEPSIZE * 28f));
684 AddChange(
changes.Velocity, force);
689 m_log.Warn(
"[PHYSICS]: Got a NaN force applied to a Character");
701 if (momentum.IsFinite())
702 AddChange(
changes.Momentum, momentum);
706 private void AvatarGeomAndBodyCreation(
float npositionX,
float npositionY,
float npositionZ)
713 float bot = -sz * 0.5f + m_feetOffset;
714 boneOff = bot + 0.3f;
716 float feetsz = sz * 0.45f;
720 feetOff = bot + feetsz;
722 AvaAvaSizeXsq = 0.4f * sx;
723 AvaAvaSizeXsq *= AvaAvaSizeXsq;
724 AvaAvaSizeYsq = 0.5f * sy;
725 AvaAvaSizeYsq *= AvaAvaSizeYsq;
727 _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace);
729 collider = d.HashSpaceCreate(_parent_scene.CharsSpace);
730 d.HashSpaceSetLevels(collider, -4, 3);
731 d.SpaceSetSublevel(collider, 3);
732 d.SpaceSetCleanup(collider,
false);
733 d.GeomSetCategoryBits(collider, (uint)m_collisionCategories);
734 d.GeomSetCollideBits(collider, (uint)m_collisionFlags);
739 float l = m_size.Z - r;
742 capsule = d.CreateCapsule(collider, r, l);
744 m_mass = m_density * m_size.X * m_size.Y * m_size.Z;
746 d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z);
748 PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE;
749 PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE;
751 Body = d.BodyCreate(_parent_scene.world);
754 m_pidControllerActive =
true;
757 _velocity = Vector3.Zero;
759 d.BodySetAutoDisableFlag(Body,
false);
760 d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
762 _position.X = npositionX;
763 _position.Y = npositionY;
764 _position.Z = npositionZ;
766 d.BodySetMass(Body, ref ShellMass);
767 d.GeomSetBody(capsule, Body);
771 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
772 d.JointAttach(Amotor, Body, IntPtr.Zero);
774 d.JointSetAMotorMode(Amotor, 0);
775 d.JointSetAMotorNumAxes(Amotor, 3);
776 d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
777 d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
778 d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
780 d.JointSetAMotorAngle(Amotor, 0, 0);
781 d.JointSetAMotorAngle(Amotor, 1, 0);
782 d.JointSetAMotorAngle(Amotor, 2, 0);
784 d.JointSetAMotorParam(Amotor, (int)
dParam.StopCFM, 0f);
785 d.JointSetAMotorParam(Amotor, (int)
dParam.StopCFM2, 0f);
786 d.JointSetAMotorParam(Amotor, (int)
dParam.StopCFM3, 0f);
787 d.JointSetAMotorParam(Amotor, (int)
dParam.StopERP, 0.8f);
788 d.JointSetAMotorParam(Amotor, (int)
dParam.StopERP2, 0.8f);
789 d.JointSetAMotorParam(Amotor, (int)
dParam.StopERP3, 0.8f);
792 d.JointSetAMotorParam(Amotor, (int)
dParam.LowStop, -1e-5f);
793 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop, 1e-5f);
794 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop2, -1e-5f);
795 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop2, 1e-5f);
796 d.JointSetAMotorParam(Amotor, (int)
dParam.LoStop3, -1e-5f);
797 d.JointSetAMotorParam(Amotor, (int)
dParam.HiStop3, 1e-5f);
799 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
800 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
801 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
803 d.JointSetAMotorParam(Amotor, (int)
dParam.FMax, 5e8f);
804 d.JointSetAMotorParam(Amotor, (int)
dParam.FMax2, 5e8f);
805 d.JointSetAMotorParam(Amotor, (int)
dParam.FMax3, 5e8f);
811 private void AvatarGeomAndBodyDestroy()
814 if (Amotor != IntPtr.Zero)
816 d.JointDestroy(Amotor);
817 Amotor = IntPtr.Zero;
820 if (Body != IntPtr.Zero)
828 if (capsule != IntPtr.Zero)
830 _parent_scene.actor_name_map.Remove(capsule);
831 _parent_scene.waitForSpaceUnlock(collider);
832 d.GeomDestroy(capsule);
833 capsule = IntPtr.Zero;
836 if (collider != IntPtr.Zero)
838 d.SpaceDestroy(collider);
839 collider = IntPtr.Zero;
845 public void RotateXYonZ(ref
float x, ref
float y, ref Quaternion rot)
847 float sin = 2.0f * rot.Z * rot.W;
848 float cos = rot.W * rot.W - rot.Z * rot.Z;
851 x = tx * cos - y * sin;
852 y = tx * sin + y * cos;
854 public void RotateXYonZ(ref
float x, ref
float y, ref
float sin, ref
float cos)
857 x = tx * cos - y * sin;
858 y = tx * sin + y * cos;
860 public void invRotateXYonZ(ref
float x, ref
float y, ref
float sin, ref
float cos)
863 x = tx * cos + y * sin;
864 y = -tx * sin + y * cos;
869 float sin = - 2.0f * rot.Z * rot.W;
870 float cos = rot.W * rot.W - rot.Z * rot.Z;
873 x = tx * cos - y * sin;
874 y = tx * sin + y * cos;
877 public bool Collide(IntPtr me, IntPtr other,
bool reverse, ref d.ContactGeom contact,
878 ref d.ContactGeom altContact , ref
bool useAltcontact, ref
bool feetcollision)
880 feetcollision =
false;
881 useAltcontact =
false;
887 float h = contact.pos.Z - _position.Z;
888 offset.Z = h - feetOff;
890 offset.X = contact.pos.X - _position.X;
891 offset.Y = contact.pos.Y - _position.Y;
893 d.GeomClassID gtype = d.GeomGetClass(other);
894 if (gtype == d.GeomClassID.CapsuleClass)
896 Vector3 roff = offset * Quaternion.Inverse(m_orientation2D);
897 float r = roff.X *roff.X / AvaAvaSizeXsq;
898 r += (roff.Y * roff.Y) / AvaAvaSizeYsq;
902 float dp = 1.0f -(float)Math.Sqrt((
double)r);
910 feetcollision =
true;
913 m_collideNormal.X = contact.normal.X;
914 m_collideNormal.Y = contact.normal.Y;
915 m_collideNormal.Z = contact.normal.Z;
927 if (offset.Z > 0 || contact.normal.Z > 0.35f)
931 feetcollision =
true;
934 m_collideNormal.X = contact.normal.X;
935 m_collideNormal.Y = contact.normal.Y;
936 m_collideNormal.Z = contact.normal.Z;
943 altContact = contact;
944 useAltcontact =
true;
950 if (contact.depth > 0.1f)
951 contact.depth = 0.1f;
955 altContact.normal.X = offset.X;
956 altContact.normal.Y = offset.Y;
957 altContact.normal.Z = offset.Z;
961 altContact.normal.X = -offset.X;
962 altContact.normal.Y = -offset.Y;
963 altContact.normal.Z = -offset.Z;
966 feetcollision =
true;
969 m_collideNormal.X = contact.normal.X;
970 m_collideNormal.Y = contact.normal.Y;
971 m_collideNormal.Z = contact.normal.Z;
984 public void Move(List<OdeCharacter> defects)
986 if (Body == IntPtr.Zero)
989 d.Vector3 dtmp = d.BodyGetPosition(Body);
990 Vector3 localpos =
new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
996 qtmp.W = m_orientation2D.W;
997 qtmp.X = m_orientation2D.X;
998 qtmp.Y = m_orientation2D.Y;
999 qtmp.Z = m_orientation2D.Z;
1000 d.BodySetQuaternion(Body, ref qtmp);
1002 if (m_pidControllerActive ==
false)
1004 _zeroPosition = localpos;
1007 if (!localpos.IsFinite())
1009 m_log.Warn(
"[PHYSICS]: Avatar Position is non-finite!");
1014 AvatarGeomAndBodyDestroy();
1019 bool fixbody =
false;
1020 if (localpos.X < 0.0f)
1025 else if (localpos.X > _parent_scene.WorldExtents.X - 0.1f)
1028 localpos.X = _parent_scene.WorldExtents.X - 0.1f;
1030 if (localpos.Y < 0.0f)
1035 else if (localpos.Y > _parent_scene.WorldExtents.Y - 0.1)
1038 localpos.Y = _parent_scene.WorldExtents.Y - 0.1f;
1043 d.BodySetPosition(Body, localpos.X, localpos.Y, localpos.Z);
1048 Vector3 vec = Vector3.Zero;
1049 dtmp = d.BodyGetLinearVel(Body);
1050 Vector3 vel =
new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
1051 float velLengthSquared = vel.LengthSquared();
1053 Vector3 ctz = _target_velocity;
1055 float movementdivisor = 1f;
1058 movementdivisor = 1 / walkDivisor;
1060 movementdivisor = 1 / runDivisor;
1062 ctz.X *= movementdivisor;
1063 ctz.Y *= movementdivisor;
1070 d.GeomGetAABB(capsule, out aabb);
1071 float chrminZ = aabb.MinZ;
1072 Vector3 posch = localpos;
1079 posch.X += vel.X * ftmp;
1080 posch.Y += vel.Y * ftmp;
1083 float terrainheight = _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y);
1084 if (chrminZ < terrainheight)
1089 Vector3 n = _parent_scene.GetTerrainNormalAtXY(posch.X, posch.Y);
1090 float depth = terrainheight - chrminZ;
1092 vec.Z = depth * PID_P * 50;
1095 vec.Z += -vel.Z * PID_D;
1099 m_colliderGroundfilter++;
1100 if (m_colliderGroundfilter > 2)
1102 m_iscolliding =
true;
1103 m_colliderfilter = 2;
1105 if (m_colliderGroundfilter > 10)
1107 m_colliderGroundfilter = 10;
1111 m_collideNormal.X = n.X;
1112 m_collideNormal.Y = n.Y;
1113 m_collideNormal.Z = n.Z;
1115 m_iscollidingGround =
true;
1119 contact.PenetrationDepth = depth;
1120 contact.Position.X = localpos.X;
1121 contact.Position.Y = localpos.Y;
1122 contact.Position.Z = terrainheight;
1123 contact.SurfaceNormal.X = -n.X;
1124 contact.SurfaceNormal.Y = -n.Y;
1125 contact.SurfaceNormal.Z = -n.Z;
1126 contact.RelativeSpeed = -vel.Z;
1127 contact.CharacterFeet =
true;
1128 AddCollisionEvent(0, contact);
1136 m_colliderGroundfilter -= 5;
1137 if (m_colliderGroundfilter <= 0)
1139 m_colliderGroundfilter = 0;
1140 m_iscollidingGround =
false;
1146 m_colliderGroundfilter -= 5;
1147 if (m_colliderGroundfilter <= 0)
1149 m_colliderGroundfilter = 0;
1150 m_iscollidingGround =
false;
1154 bool hoverPIDActive =
false;
1156 if (m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0)
1158 hoverPIDActive =
true;
1160 switch (m_PIDHoverType)
1162 case PIDHoverType.Ground:
1163 m_targetHoverHeight = terrainheight + m_PIDHoverHeight;
1166 case PIDHoverType.GroundAndWater:
1167 float waterHeight = _parent_scene.GetWaterLevel();
1168 if (terrainheight > waterHeight)
1169 m_targetHoverHeight = terrainheight + m_PIDHoverHeight;
1171 m_targetHoverHeight = waterHeight + m_PIDHoverHeight;
1176 if (m_targetHoverHeight > terrainheight + 0.5f * (aabb.MaxZ - aabb.MinZ))
1178 float fz = (m_targetHoverHeight - localpos.Z);
1181 if (Math.Abs(fz) < 0.01f)
1188 fz /= m_PIDHoverTau;
1190 float tmp = Math.Abs(fz);
1192 fz = 50 * Math.Sign(fz);
1194 fz = 0.1f * Math.Sign(fz);
1203 m_collideNormal.Z = 0;
1205 bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f);
1213 if (m_iscolliding && !flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f)
1215 float p = ctz.X * m_collideNormal.X + ctz.Y * m_collideNormal.Y;
1216 ctz.X *= (float)Math.Sqrt(1 - m_collideNormal.X * m_collideNormal.X);
1217 ctz.Y *= (float)Math.Sqrt(1 - m_collideNormal.Y * m_collideNormal.Y);
1230 if (tviszero && m_iscolliding && !flying)
1236 _zeroPosition = localpos;
1238 if (m_pidControllerActive)
1245 vec.X = -vel.X * PID_D * 2f + (_zeroPosition.X - localpos.X) * (PID_P * 5);
1246 vec.Y = -vel.Y * PID_D * 2f + (_zeroPosition.Y - localpos.Y) * (PID_P * 5);
1248 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P;
1250 vec.Z += (-vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P) * 0.2f;
1262 m_pidControllerActive =
true;
1273 vec.Z += (ctz.Z - vel.Z) * PID_D * 2f;
1274 vec.X += (ctz.X - vel.X) * (PID_D);
1275 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1283 vec.Z -= vel.Z * PID_D * 2f;
1284 vec.X += (ctz.X - vel.X) * (PID_D);
1285 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1291 vec.Z += (ctz.Z - vel.Z) * PID_D;
1296 if (Math.Abs(ctz.X) > Math.Abs(vel.X))
1297 vec.X += (ctz.X - vel.X) * (PID_D);
1298 if (Math.Abs(ctz.Y) > Math.Abs(vel.Y))
1299 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1308 vec.X += (ctz.X - vel.X) * (PID_D * 0.0625f);
1309 vec.Y += (ctz.Y - vel.Y) * (PID_D * 0.0625f);
1310 vec.Z += (ctz.Z - vel.Z) * (PID_D * 0.0625f);
1315 if (flying || hoverPIDActive)
1318 vec.X += (ctz.X - vel.X) * (PID_D);
1319 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1320 vec.Z += (ctz.Z - vel.Z) * (PID_D);
1329 vec.X += (ctz.X - vel.X) * PID_D * 0.833f;
1330 vec.Y += (ctz.Y - vel.Y) * PID_D * 0.833f;
1332 if (ctz.Z == -9999f)
1333 vec.Z += -vel.Z * PID_D - _parent_scene.gravityz * m_mass;
1338 if (velLengthSquared > 2500.0f)
1340 breakfactor = 0.16f * m_mass;
1341 vec.X -= breakfactor * vel.X;
1342 vec.Y -= breakfactor * vel.Y;
1343 vec.Z -= breakfactor * vel.Z;
1348 breakfactor = m_mass;
1349 vec.X -= breakfactor * vel.X;
1350 vec.Y -= breakfactor * vel.Y;
1352 vec.Z -= 0.5f * breakfactor * vel.Z;
1354 vec.Z -= .16f* m_mass * vel.Z;
1357 if (flying || hoverPIDActive)
1359 vec.Z -= _parent_scene.gravityz * m_mass;
1364 float target_altitude = terrainheight + MinimumGroundFlightOffset;
1366 if (localpos.Z < target_altitude)
1368 vec.Z += (target_altitude - localpos.Z) * PID_P * 5.0f;
1376 if (vec.X != 0 || vec.Y !=0 || vec.Z !=0)
1377 d.BodyAddForce(Body, vec.X, vec.Y, vec.Z);
1381 m_log.Warn(
"[PHYSICS]: Got a NaN force vector in Move()");
1382 m_log.Warn(
"[PHYSICS]: Avatar Position is non-finite!");
1386 AvatarGeomAndBodyDestroy();
1392 _position = localpos;
1396 _velocity = Vector3.Zero;
1397 _acceleration = Vector3.Zero;
1398 m_rotationalVelocity = Vector3.Zero;
1402 Vector3 a =_velocity;
1403 SetSmooth(ref _velocity, ref vel, 2);
1404 a = (_velocity - a) * invtimeStep;
1405 SetSmooth(ref _acceleration, ref a, 2);
1407 dtmp = d.BodyGetAngularVel(Body);
1408 m_rotationalVelocity.X = 0f;
1409 m_rotationalVelocity.Y = 0f;
1410 m_rotationalVelocity.Z = dtmp.Z;
1411 Math.Round(m_rotationalVelocity.Z,3);
1415 public void round(ref Vector3 v,
int digits)
1417 v.X = (float)Math.Round(v.X, digits);
1418 v.Y = (float)Math.Round(v.Y, digits);
1419 v.Z = (float)Math.Round(v.Z, digits);
1424 dst.X = 0.1f * dst.X + 0.9f * value.X;
1425 dst.Y = 0.1f * dst.Y + 0.9f * value.Y;
1426 dst.Z = 0.1f * dst.Z + 0.9f * value.Z;
1429 public void SetSmooth(ref Vector3 dst, ref Vector3 value,
int rounddigits)
1431 dst.X = 0.4f * dst.X + 0.6f * value.X;
1432 dst.X = (float)Math.Round(dst.X, rounddigits);
1434 dst.Y = 0.4f * dst.Y + 0.6f * value.Y;
1435 dst.Y = (float)Math.Round(dst.Y, rounddigits);
1437 dst.Z = 0.4f * dst.Z + 0.6f * value.Z;
1438 dst.Z = (float)Math.Round(dst.Z, rounddigits);
1463 AddChange(
changes.Remove, null);
1471 public override bool PIDActive {
get {
return m_pidControllerActive;} set {
return; } }
1472 public override float PIDTau { set {
return; } }
1478 AddChange(
changes.PIDHoverHeight,value);
1485 return m_useHoverPID;
1489 AddChange(
changes.PIDHoverActive, value);
1497 AddChange(
changes.PIDHoverType,value);
1508 float mint = (0.05f > timeStep ? 0.05f : timeStep);
1514 AddChange(
changes.PIDHoverTau, tmp);
1518 public override Quaternion APIDTarget { set {
return; } }
1520 public override bool APIDActive { set {
return; } }
1522 public override float APIDStrength { set {
return; } }
1524 public override float APIDDamping { set {
return; } }
1529 m_eventsubscription = ms;
1530 m_cureventsubscription = 0;
1531 if (CollisionEventsThisFrame == null)
1533 SentEmptyCollisionsEvent =
false;
1538 if (CollisionEventsThisFrame != null)
1540 lock (CollisionEventsThisFrame)
1542 CollisionEventsThisFrame.Clear();
1543 CollisionEventsThisFrame = null;
1546 m_eventsubscription = 0;
1551 if (CollisionEventsThisFrame == null)
1553 lock (CollisionEventsThisFrame)
1555 CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
1556 _parent_scene.AddCollisionEventReporting(
this);
1562 if (CollisionEventsThisFrame == null)
1565 lock (CollisionEventsThisFrame)
1567 if (m_cureventsubscription < m_eventsubscription)
1570 m_cureventsubscription = 0;
1572 int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count;
1574 if (!SentEmptyCollisionsEvent || ncolisions > 0)
1576 base.SendCollisionUpdate(CollisionEventsThisFrame);
1578 if (ncolisions == 0)
1580 SentEmptyCollisionsEvent =
true;
1581 _parent_scene.RemoveCollisionEventReporting(
this);
1585 SentEmptyCollisionsEvent =
false;
1586 CollisionEventsThisFrame.Clear();
1592 internal void AddCollisionFrameTime(
int t)
1595 if (m_cureventsubscription < 50000)
1596 m_cureventsubscription += t;
1601 if (m_eventsubscription > 0)
1606 private void changePhysicsStatus(
bool NewStatus)
1608 if (NewStatus != m_isPhysical)
1612 AvatarGeomAndBodyDestroy();
1614 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
1616 _parent_scene.actor_name_map[collider] = (
PhysicsActor)
this;
1617 _parent_scene.actor_name_map[capsule] = (
PhysicsActor)
this;
1618 _parent_scene.AddCharacter(
this);
1622 _parent_scene.RemoveCollisionEventReporting(
this);
1623 _parent_scene.RemoveCharacter(
this);
1625 AvatarGeomAndBodyDestroy();
1628 m_isPhysical = NewStatus;
1632 private void changeAdd()
1634 changePhysicsStatus(
true);
1637 private void changeRemove()
1639 changePhysicsStatus(
false);
1646 private void changeAvatarSize(strAvatarSize st)
1648 m_feetOffset = st.offset;
1649 changeSize(st.size);
1652 private void changeSize(Vector3 pSize)
1654 if (pSize.IsFinite())
1657 if (pSize.Z != m_size.Z)
1659 AvatarGeomAndBodyDestroy();
1662 float oldsz = m_size.Z;
1666 AvatarGeomAndBodyCreation(_position.X, _position.Y,
1667 _position.Z + (m_size.Z - oldsz) * 0.5f);
1672 _parent_scene.actor_name_map[collider] = (
PhysicsActor)
this;
1673 _parent_scene.actor_name_map[capsule] = (
PhysicsActor)
this;
1676 m_pidControllerActive =
true;
1680 m_log.Warn(
"[PHYSICS]: Got a NaN Size from Scene on a Character");
1684 private void changePosition( Vector3 newPos)
1686 if (Body != IntPtr.Zero)
1687 d.BodySetPosition(
Body, newPos.X, newPos.Y, newPos.Z);
1690 m_pidControllerActive =
true;
1693 private void changeOrientation(Quaternion newOri)
1695 if (m_orientation != newOri)
1697 m_orientation = newOri;
1700 m_orientation2D.W = newOri.W;
1701 m_orientation2D.Z = newOri.Z;
1703 float t = m_orientation2D.W * m_orientation2D.W + m_orientation2D.Z * m_orientation2D.Z;
1706 t = 1.0f / (float)Math.Sqrt(t);
1707 m_orientation2D.W *= t;
1708 m_orientation2D.Z *= t;
1712 m_orientation2D.W = 1.0f;
1713 m_orientation2D.Z = 0f;
1715 m_orientation2D.Y = 0f;
1716 m_orientation2D.X = 0f;
1719 myrot.X = m_orientation2D.X;
1720 myrot.Y = m_orientation2D.Y;
1721 myrot.Z = m_orientation2D.Z;
1722 myrot.W = m_orientation2D.W;
1723 d.BodySetQuaternion(
Body, ref myrot);
1727 private void changeVelocity(Vector3 newVel)
1729 m_pidControllerActive =
true;
1731 _target_velocity = newVel;
1734 private void changeSetTorque(Vector3 newTorque)
1738 private void changeAddForce(Vector3 newForce)
1742 private void changeAddAngularForce(Vector3 arg)
1746 private void changeAngularLock(byte arg)
1750 private void changeFloatOnWater(
bool arg)
1754 private void changeVolumedetetion(
bool arg)
1758 private void changeSelectedStatus(
bool arg)
1762 private void changeDisable(
bool arg)
1766 private void changeBuilding(
bool arg)
1770 private void setFreeMove()
1772 m_pidControllerActive =
true;
1774 _target_velocity = Vector3.Zero;
1776 m_colliderfilter = -1;
1777 m_colliderObjectfilter = -1;
1778 m_colliderGroundfilter = -1;
1780 m_iscolliding =
false;
1781 m_iscollidingGround =
false;
1782 m_iscollidingObj =
false;
1784 CollisionEventsThisFrame.Clear();
1787 private void changeForce(Vector3 newForce)
1791 if (Body != IntPtr.Zero)
1793 if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0)
1794 d.BodyAddForce(
Body, newForce.X, newForce.Y, newForce.Z);
1799 private void changeMomentum(Vector3 newmomentum)
1801 _velocity = newmomentum;
1804 if (Body != IntPtr.Zero)
1805 d.BodySetLinearVel(
Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1808 private void changePIDHoverHeight(
float val)
1810 m_PIDHoverHeight = val;
1812 m_useHoverPID =
false;
1817 m_PIDHoverType = type;
1820 private void changePIDHoverTau(
float tau)
1822 m_PIDHoverTau = tau;
1825 private void changePIDHoverActive(
bool active)
1827 m_useHoverPID = active;
1830 private void donullchange()
1836 if (collider == IntPtr.Zero && what !=
changes.Add && what !=
changes.Remove)
1847 case changes.Remove:
1851 case changes.Position:
1852 changePosition((Vector3)arg);
1855 case changes.Orientation:
1856 changeOrientation((Quaternion)arg);
1859 case changes.PosOffset:
1863 case changes.OriOffset:
1867 case changes.Velocity:
1868 changeVelocity((Vector3)arg);
1879 changeForce((Vector3)arg);
1882 case changes.Torque:
1883 changeSetTorque((Vector3)arg);
1886 case changes.AddForce:
1887 changeAddForce((Vector3)arg);
1890 case changes.AddAngForce:
1891 changeAddAngularForce((Vector3)arg);
1894 case changes.AngLock:
1895 changeAngularLock((byte)arg);
1899 changeSize((Vector3)arg);
1902 case changes.AvatarSize:
1903 changeAvatarSize((strAvatarSize)arg);
1906 case changes.Momentum:
1907 changeMomentum((Vector3)arg);
1910 case changes.PIDHoverHeight:
1911 changePIDHoverHeight((
float)arg);
1914 case changes.PIDHoverType:
1918 case changes.PIDHoverTau:
1919 changePIDHoverTau((
float)arg);
1922 case changes.PIDHoverActive:
1923 changePIDHoverActive((
bool)arg);
1968 _parent_scene.AddChange((
PhysicsActor)
this, what, arg);
1971 private struct strAvatarSize
1973 public Vector3 size;
1974 public float offset;
bool DoAChange(changes what, object arg)
override void VehicleFloatParam(int param, float value)
void RotateXYonZ(ref float x, ref float y, ref Quaternion rot)
override void LockAngularMotion(byte axislocks)
void AddChange(changes what, object arg)
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 SetMomentum(Vector3 momentum)
override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
override void VehicleVectorParam(int param, Vector3 value)
delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun)
override bool SubscribedEvents()
override void UnSubscribeEvents()
void UpdatePositionAndVelocity()
Updates the reported position and velocity. Used to copy variables from unmanaged space at heartbeat ...
void SetAcceleration(Vector3 accel)
OdeCharacter(uint localID, String avName, ODEScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor)
override void setAvatarSize(Vector3 size, float feetOffset)
override void AddAngularForce(Vector3 force, bool pushforce)
void invRotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
void Move(List< OdeCharacter > defects)
Called from Simulate This is the avatar's movement control + PID Controller
Used to pass collision information to OnCollisionUpdate listeners.
override void AddForce(Vector3 force, bool pushforce)
Adds the force supplied to the Target Velocity The PID controller takes this target velocity and trie...
void RotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
float GetTerrainHeightAtXY(float x, float y)
void SetSmooth(ref Vector3 dst, ref Vector3 value, int rounddigits)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
override void VehicleRotationParam(int param, Quaternion rotation)
override void CrossingFailure()
override void getContactData(ref ContactData cdata)
override void SubscribeEvents(int ms)
void SetSmooth(ref Vector3 dst, ref Vector3 value)
void invRotateXYonZ(ref float x, ref float y, ref Quaternion rot)
dParam
Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ours...
override void VehicleFlags(int param, bool remove)
void round(ref Vector3 v, int digits)
Interactive OpenSim region server
bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact, ref d.ContactGeom altContact, ref bool useAltcontact, ref bool feetcollision)
void Destroy()
Cleanup the things we use in the scene.
override void SetVolumeDetect(int param)
Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more ...
override void link(PhysicsActor obj)