aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs17
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs17
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs625
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs16
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs4
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs183
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs381
7 files changed, 801 insertions, 442 deletions
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 5af6373..9338130 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -61,6 +61,7 @@ namespace OpenSim.Region.Physics.Manager
61 public Vector3 SurfaceNormal; 61 public Vector3 SurfaceNormal;
62 public float PenetrationDepth; 62 public float PenetrationDepth;
63 public float RelativeSpeed; 63 public float RelativeSpeed;
64 public bool CharacterFeet;
64 65
65 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth) 66 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
66 { 67 {
@@ -68,6 +69,16 @@ namespace OpenSim.Region.Physics.Manager
68 SurfaceNormal = surfaceNormal; 69 SurfaceNormal = surfaceNormal;
69 PenetrationDepth = penetrationDepth; 70 PenetrationDepth = penetrationDepth;
70 RelativeSpeed = 0f; // for now let this one be set explicity 71 RelativeSpeed = 0f; // for now let this one be set explicity
72 CharacterFeet = true; // keep other plugins work as before
73 }
74
75 public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth, bool feet)
76 {
77 Position = position;
78 SurfaceNormal = surfaceNormal;
79 PenetrationDepth = penetrationDepth;
80 RelativeSpeed = 0f; // for now let this one be set explicity
81 CharacterFeet = feet; // keep other plugins work as before
71 } 82 }
72 } 83 }
73 84
@@ -173,6 +184,11 @@ namespace OpenSim.Region.Physics.Manager
173 184
174 public abstract Vector3 Size { get; set; } 185 public abstract Vector3 Size { get; set; }
175 186
187 public virtual void setAvatarSize(Vector3 size, float feetOffset)
188 {
189 Size = size;
190 }
191
176 public virtual bool Phantom { get; set; } 192 public virtual bool Phantom { get; set; }
177 193
178 public virtual bool IsVolumeDtc 194 public virtual bool IsVolumeDtc
@@ -395,6 +411,7 @@ namespace OpenSim.Region.Physics.Manager
395 // Warning in a parent part it returns itself, not null 411 // Warning in a parent part it returns itself, not null
396 public virtual PhysicsActor ParentActor { get { return this; } } 412 public virtual PhysicsActor ParentActor { get { return this; } }
397 413
414
398 } 415 }
399 416
400 public class NullPhysicsActor : PhysicsActor 417 public class NullPhysicsActor : PhysicsActor
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index ce269fa..a442cf0 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -38,6 +38,7 @@ namespace OpenSim.Region.Physics.Manager
38 38
39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); 39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal);
40 public delegate void RayCallback(List<ContactResult> list); 40 public delegate void RayCallback(List<ContactResult> list);
41 public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
41 42
42 public delegate void JointMoved(PhysicsJoint joint); 43 public delegate void JointMoved(PhysicsJoint joint);
43 public delegate void JointDeactivated(PhysicsJoint joint); 44 public delegate void JointDeactivated(PhysicsJoint joint);
@@ -127,8 +128,10 @@ namespace OpenSim.Region.Physics.Manager
127 /// <param name="size"></param> 128 /// <param name="size"></param>
128 /// <param name="isFlying"></param> 129 /// <param name="isFlying"></param>
129 /// <returns></returns> 130 /// <returns></returns>
130 public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); 131 public virtual PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
131 132 {
133 return null;
134 }
132 /// <summary> 135 /// <summary>
133 /// Add an avatar 136 /// Add an avatar
134 /// </summary> 137 /// </summary>
@@ -145,6 +148,12 @@ namespace OpenSim.Region.Physics.Manager
145 return ret; 148 return ret;
146 } 149 }
147 150
151 public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
152 {
153 PhysicsActor ret = AddAvatar(localID, avName, position, size, isFlying);
154 return ret;
155 }
156
148 /// <summary> 157 /// <summary>
149 /// Remove an avatar. 158 /// Remove an avatar.
150 /// </summary> 159 /// </summary>
@@ -349,5 +358,9 @@ namespace OpenSim.Region.Physics.Manager
349 return new List<ContactResult>(); 358 return new List<ContactResult>();
350 } 359 }
351 360
361 public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
362 {
363 return 0;
364 }
352 } 365 }
353} 366}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 3d5be3e..bb04ea7 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -74,31 +74,31 @@ namespace OpenSim.Region.Physics.OdePlugin
74 74
75 private Vector3 _position; 75 private Vector3 _position;
76 private Vector3 _zeroPosition; 76 private Vector3 _zeroPosition;
77 private bool _zeroFlag = false;
78 private Vector3 _velocity; 77 private Vector3 _velocity;
79 private Vector3 _target_velocity; 78 private Vector3 _target_velocity;
80 private Vector3 _acceleration; 79 private Vector3 _acceleration;
81 private Vector3 m_rotationalVelocity; 80 private Vector3 m_rotationalVelocity;
82 private Vector3 m_size; 81 private Vector3 m_size;
83 private Quaternion m_orientation; 82 private Quaternion m_orientation;
83 private Quaternion m_orientation2D;
84 private float m_mass = 80f; 84 private float m_mass = 80f;
85 public float m_density = 60f; 85 public float m_density = 60f;
86 private bool m_pidControllerActive = true; 86 private bool m_pidControllerActive = true;
87 public float PID_D = 800.0f;
88 public float PID_P = 900.0f;
89 //private static float POSTURE_SERVO = 10000.0f;
90 87
88 const float basePID_D = 0.55f; // scaled for unit mass unit time (2200 /(50*80))
89 const float basePID_P = 0.225f; // scaled for unit mass unit time (900 /(50*80))
90 public float PID_D;
91 public float PID_P;
91 92
92 private float m_invElipSizeX; 93 private float timeStep;
93 private float m_invElipSizeY; 94 private float invtimeStep;
94 95
96 private float m_feetOffset = 0;
95 private float feetOff = 0; 97 private float feetOff = 0;
96 private float feetSZ = 0.5f; 98 private float feetSZ = 0.5f;
97 const float feetScale = 0.9f; 99 const float feetScale = 0.8f;
98 const float invFeetScale = 1.0f / 0.9f;
99 const float sizeZAdjust = 0.15f;
100 private float boneOff = 0; 100 private float boneOff = 0;
101 101 private float m_lastVelocitySqr = 0;
102 102
103 public float walkDivisor = 1.3f; 103 public float walkDivisor = 1.3f;
104 public float runDivisor = 0.8f; 104 public float runDivisor = 0.8f;
@@ -107,6 +107,9 @@ namespace OpenSim.Region.Physics.OdePlugin
107 private bool m_iscollidingGround = false; 107 private bool m_iscollidingGround = false;
108 private bool m_iscollidingObj = false; 108 private bool m_iscollidingObj = false;
109 private bool m_alwaysRun = false; 109 private bool m_alwaysRun = false;
110
111 private bool _zeroFlag = false;
112
110 private int m_requestedUpdateFrequency = 0; 113 private int m_requestedUpdateFrequency = 0;
111 private uint m_localID = 0; 114 private uint m_localID = 0;
112 public bool m_returnCollisions = false; 115 public bool m_returnCollisions = false;
@@ -124,6 +127,7 @@ namespace OpenSim.Region.Physics.OdePlugin
124 int m_colliderfilter = 0; 127 int m_colliderfilter = 0;
125 int m_colliderGroundfilter = 0; 128 int m_colliderGroundfilter = 0;
126 int m_colliderObjectfilter = 0; 129 int m_colliderObjectfilter = 0;
130 bool m_collisionException = false;
127 131
128 // Default we're a Character 132 // Default we're a Character
129 private CollisionCategories m_collisionCategories = (CollisionCategories.Character); 133 private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
@@ -136,10 +140,11 @@ namespace OpenSim.Region.Physics.OdePlugin
136 // we do land collisions not ode | CollisionCategories.Land); 140 // we do land collisions not ode | CollisionCategories.Land);
137 public IntPtr Body = IntPtr.Zero; 141 public IntPtr Body = IntPtr.Zero;
138 private OdeScene _parent_scene; 142 private OdeScene _parent_scene;
139 public IntPtr topbox = IntPtr.Zero; 143 private IntPtr topbox = IntPtr.Zero;
140 public IntPtr midbox = IntPtr.Zero; 144 private IntPtr midbox = IntPtr.Zero;
141 public IntPtr feetbox = IntPtr.Zero; 145 private IntPtr feetbox = IntPtr.Zero;
142 public IntPtr bonebox = IntPtr.Zero; 146 private IntPtr bbox = IntPtr.Zero;
147 public IntPtr collider = IntPtr.Zero;
143 148
144 public IntPtr Amotor = IntPtr.Zero; 149 public IntPtr Amotor = IntPtr.Zero;
145 150
@@ -147,6 +152,7 @@ namespace OpenSim.Region.Physics.OdePlugin
147 152
148 153
149 154
155
150 public int m_eventsubscription = 0; 156 public int m_eventsubscription = 0;
151 private int m_cureventsubscription = 0; 157 private int m_cureventsubscription = 0;
152 private CollisionEventUpdate CollisionEventsThisFrame = null; 158 private CollisionEventUpdate CollisionEventsThisFrame = null;
@@ -160,9 +166,13 @@ namespace OpenSim.Region.Physics.OdePlugin
160 166
161 167
162 168
163 public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pid_d, float pid_p, float density, float walk_divisor, float rundivisor) 169 public OdeCharacter(uint localID, String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor)
164 { 170 {
165 m_uuid = UUID.Random(); 171 m_uuid = UUID.Random();
172 m_localID = localID;
173
174 timeStep = parent_scene.ODE_STEPSIZE;
175 invtimeStep = 1 / timeStep;
166 176
167 if (pos.IsFinite()) 177 if (pos.IsFinite())
168 { 178 {
@@ -184,8 +194,6 @@ namespace OpenSim.Region.Physics.OdePlugin
184 194
185 _parent_scene = parent_scene; 195 _parent_scene = parent_scene;
186 196
187 PID_D = pid_d;
188 PID_P = pid_p;
189 197
190 m_size.X = pSize.X; 198 m_size.X = pSize.X;
191 m_size.Y = pSize.Y; 199 m_size.Y = pSize.Y;
@@ -198,12 +206,16 @@ namespace OpenSim.Region.Physics.OdePlugin
198 if(m_size.Z <0.01f) 206 if(m_size.Z <0.01f)
199 m_size.Z = 0.01f; 207 m_size.Z = 0.01f;
200 208
209 m_feetOffset = pfeetOffset;
201 m_orientation = Quaternion.Identity; 210 m_orientation = Quaternion.Identity;
211 m_orientation2D = Quaternion.Identity;
202 m_density = density; 212 m_density = density;
203 213
204 // force lower density for testing 214 // force lower density for testing
205 m_density = 3.0f; 215 m_density = 3.0f;
206 216
217 m_density *= 1.4f; // scale to have mass similar to capsule
218
207 mu = parent_scene.AvatarFriction; 219 mu = parent_scene.AvatarFriction;
208 220
209 walkDivisor = walk_divisor; 221 walkDivisor = walk_divisor;
@@ -211,6 +223,9 @@ namespace OpenSim.Region.Physics.OdePlugin
211 223
212 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default 224 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default
213 225
226 PID_D = basePID_D * m_mass * invtimeStep;
227 PID_P = basePID_P * m_mass * invtimeStep;
228
214 m_isPhysical = false; // current status: no ODE information exists 229 m_isPhysical = false; // current status: no ODE information exists
215 230
216 Name = avName; 231 Name = avName;
@@ -292,7 +307,7 @@ namespace OpenSim.Region.Physics.OdePlugin
292 set 307 set
293 { 308 {
294 flying = value; 309 flying = value;
295 // m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); 310// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying);
296 } 311 }
297 } 312 }
298 313
@@ -336,25 +351,25 @@ namespace OpenSim.Region.Physics.OdePlugin
336 get { return m_iscollidingGround; } 351 get { return m_iscollidingGround; }
337 set 352 set
338 { 353 {
339 /* we now control this 354/* we now control this
340 if (value) 355 if (value)
341 { 356 {
342 m_colliderGroundfilter += 2; 357 m_colliderGroundfilter += 2;
343 if (m_colliderGroundfilter > 2) 358 if (m_colliderGroundfilter > 2)
344 m_colliderGroundfilter = 2; 359 m_colliderGroundfilter = 2;
345 } 360 }
346 else 361 else
347 { 362 {
348 m_colliderGroundfilter--; 363 m_colliderGroundfilter--;
349 if (m_colliderGroundfilter < 0) 364 if (m_colliderGroundfilter < 0)
350 m_colliderGroundfilter = 0; 365 m_colliderGroundfilter = 0;
351 } 366 }
352 367
353 if (m_colliderGroundfilter == 0) 368 if (m_colliderGroundfilter == 0)
354 m_iscollidingGround = false; 369 m_iscollidingGround = false;
355 else 370 else
356 m_iscollidingGround = true; 371 m_iscollidingGround = true;
357 */ 372 */
358 } 373 }
359 374
360 } 375 }
@@ -386,7 +401,7 @@ namespace OpenSim.Region.Physics.OdePlugin
386 else 401 else
387 m_iscollidingObj = true; 402 m_iscollidingObj = true;
388 403
389 // m_iscollidingObj = value; 404// m_iscollidingObj = value;
390 405
391 if (m_iscollidingObj) 406 if (m_iscollidingObj)
392 m_pidControllerActive = false; 407 m_pidControllerActive = false;
@@ -475,6 +490,28 @@ namespace OpenSim.Region.Physics.OdePlugin
475 } 490 }
476 } 491 }
477 492
493 public override void setAvatarSize(Vector3 size, float feetOffset)
494 {
495 if (size.IsFinite())
496 {
497 if (size.X < 0.01f)
498 size.X = 0.01f;
499 if (size.Y < 0.01f)
500 size.Y = 0.01f;
501 if (size.Z < 0.01f)
502 size.Z = 0.01f;
503
504 strAvatarSize st = new strAvatarSize();
505 st.size = size;
506 st.offset = feetOffset;
507 AddChange(changes.AvatarSize, st);
508 }
509 else
510 {
511 m_log.Warn("[PHYSICS]: Got a NaN AvatarSize from Scene on a Character");
512 }
513
514 }
478 /// <summary> 515 /// <summary>
479 /// This creates the Avatar's physical Surrogate at the position supplied 516 /// This creates the Avatar's physical Surrogate at the position supplied
480 /// </summary> 517 /// </summary>
@@ -491,7 +528,7 @@ namespace OpenSim.Region.Physics.OdePlugin
491 { 528 {
492 get 529 get
493 { 530 {
494 return m_density * m_size.X * m_size.Y * m_size.Z; 531 return m_mass;
495 } 532 }
496 } 533 }
497 public override void link(PhysicsActor obj) 534 public override void link(PhysicsActor obj)
@@ -612,9 +649,8 @@ namespace OpenSim.Region.Physics.OdePlugin
612 get { return m_orientation; } 649 get { return m_orientation; }
613 set 650 set
614 { 651 {
615 // fakeori = value; 652// fakeori = value;
616 // givefakeori++; 653// givefakeori++;
617
618 value.Normalize(); 654 value.Normalize();
619 AddChange(changes.Orientation, value); 655 AddChange(changes.Orientation, value);
620 } 656 }
@@ -668,33 +704,72 @@ namespace OpenSim.Region.Physics.OdePlugin
668 AddChange(changes.Momentum, momentum); 704 AddChange(changes.Momentum, momentum);
669 } 705 }
670 706
707 private void ajustCollider()
708 {
709 float vq = _velocity.LengthSquared();
710 if (m_lastVelocitySqr != vq)
711 {
712 m_lastVelocitySqr = vq;
713 if (vq > 100.0f)
714 {
715 Vector3 off = _velocity;
716 float t = 0.5f * timeStep;
717 off = off * t;
718 d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
719 off.X = 2.0f * (m_size.X + Math.Abs(off.X));
720 off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
721 off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
722 d.GeomBoxSetLengths(bbox, off.X, off.Y, off.Z);
723
724 d.GeomSetCategoryBits(bbox, (uint)m_collisionCategories);
725 d.GeomSetCollideBits(bbox, (uint)m_collisionFlags);
726 d.GeomSetCategoryBits(topbox, 0);
727 d.GeomSetCollideBits(topbox, 0);
728 d.GeomSetCategoryBits(midbox, 0);
729 d.GeomSetCollideBits(midbox, 0);
730 d.GeomSetCategoryBits(feetbox, 0);
731 d.GeomSetCollideBits(feetbox, 0);
732 }
733 else
734 {
735 d.GeomSetCategoryBits(bbox, 0);
736 d.GeomSetCollideBits(bbox, 0);
737 d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories);
738 d.GeomSetCollideBits(topbox, (uint)m_collisionFlags);
739 d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories);
740 d.GeomSetCollideBits(midbox, (uint)m_collisionFlags);
741 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
742 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
743 }
744 }
745 }
746
671 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) 747 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
672 { 748 {
673 // sizes one day should came from visual parameters 749 // sizes one day should came from visual parameters
674 float sz = m_size.Z + sizeZAdjust; 750 float sx = m_size.X;
675 751 float sy = m_size.Y;
676 m_invElipSizeX = 1.0f / m_size.X; 752 float sz = m_size.Z;
677 m_invElipSizeY = 1.0f / m_size.Y; 753
678 754 float topsx = sx * 0.9f;
679 float topsx = m_size.X; 755 float midsx = sx;
680 float midsx = m_size.X; 756 float feetsx = sx * feetScale;
681 float feetsx = m_size.X * feetScale; 757 float bonesx = sx * 0.2f;
682 float bonesx = feetsx * 0.2f; 758
683 759 float topsy = sy * 0.4f;
684 float topsy = m_size.Y * 0.5f; 760 float midsy = sy;
685 float midsy = m_size.Y; 761 float feetsy = sy * feetScale * 0.8f;
686 float feetsy = m_size.Y * feetScale;
687 float bonesy = feetsy * 0.2f; 762 float bonesy = feetsy * 0.2f;
688 763
689 float topsz = sz * 0.15f; 764 float topsz = sz * 0.15f;
690 float feetsz = sz * 0.3f; 765 float feetsz = sz * 0.45f;
691 if (feetsz > 0.6f) 766 if (feetsz > 0.6f)
692 feetsz = 0.6f; 767 feetsz = 0.6f;
693 768
694 float midsz = sz - topsz - feetsz; 769 float midsz = sz - topsz - feetsz;
695 float bonesz = sz; 770 float bonesz = sz;
696 771
697 float bot = -sz * 0.5f; 772 float bot = -sz * 0.5f + m_feetOffset;
698 773
699 boneOff = bot + 0.3f; 774 boneOff = bot + 0.3f;
700 775
@@ -708,47 +783,37 @@ namespace OpenSim.Region.Physics.OdePlugin
708 bot += midsz; 783 bot += midsz;
709 float topz = bot + topsz * 0.5f; 784 float topz = bot + topsz * 0.5f;
710 785
711 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 786 _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace);
712
713 feetbox = d.CreateBox(_parent_scene.ActiveSpace, feetsx, feetsy, feetsz);
714 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
715 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
716
717 midbox = d.CreateBox(_parent_scene.ActiveSpace, midsx, midsy, midsz);
718 d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories);
719 d.GeomSetCollideBits(midbox, (uint)m_collisionFlags);
720
721 topbox = d.CreateBox(_parent_scene.ActiveSpace, topsx, topsy, topsz);
722 d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories);
723 d.GeomSetCollideBits(topbox, (uint)m_collisionFlags);
724 787
725 bonebox = d.CreateBox(_parent_scene.ActiveSpace, bonesx, bonesy, bonesz); 788 collider = d.HashSpaceCreate(_parent_scene.CharsSpace);
726 d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); 789 d.HashSpaceSetLevels(collider, -4, 3);
727 d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); 790 d.SpaceSetSublevel(collider, 3);
791 d.SpaceSetCleanup(collider, false);
792 d.GeomSetCategoryBits(collider, (uint)m_collisionCategories);
793 d.GeomSetCollideBits(collider, (uint)m_collisionFlags);
728 794
729 d.MassSetBox(out ShellMass, m_density, m_size.X , m_size.Y, m_size.Z); 795 feetbox = d.CreateBox(collider, feetsx, feetsy, feetsz);
796 midbox = d.CreateBox(collider, midsx, midsy, midsz);
797 topbox = d.CreateBox(collider, topsx, topsy, topsz);
798 bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z);
730 799
731 m_mass = ShellMass.mass; // update mass 800 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass
732 801
733 // rescale PID parameters 802 d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z);
734 PID_D = _parent_scene.avPIDD;
735 PID_P = _parent_scene.avPIDP;
736 803
737 // rescale PID parameters so that this aren't affected by mass 804 PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE;
738 // and so don't get unstable for some masses 805 PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE;
739 // also scale by ode time step so you don't need to refix them
740
741 PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
742 PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
743 PID_P /= 50 * 80;
744 PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
745 806
746 Body = d.BodyCreate(_parent_scene.world); 807 Body = d.BodyCreate(_parent_scene.world);
747 808
748 _zeroFlag = false; 809 _zeroFlag = false;
810 m_collisionException = false;
749 m_pidControllerActive = true; 811 m_pidControllerActive = true;
750 m_freemove = false; 812 m_freemove = false;
751 813
814 _velocity = Vector3.Zero;
815 m_lastVelocitySqr = 0;
816
752 d.BodySetAutoDisableFlag(Body, false); 817 d.BodySetAutoDisableFlag(Body, false);
753 d.BodySetPosition(Body, npositionX, npositionY, npositionZ); 818 d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
754 819
@@ -760,12 +825,15 @@ namespace OpenSim.Region.Physics.OdePlugin
760 d.GeomSetBody(feetbox, Body); 825 d.GeomSetBody(feetbox, Body);
761 d.GeomSetBody(midbox, Body); 826 d.GeomSetBody(midbox, Body);
762 d.GeomSetBody(topbox, Body); 827 d.GeomSetBody(topbox, Body);
763 d.GeomSetBody(bonebox, Body); 828 d.GeomSetBody(bbox, Body);
764 829
765 d.GeomSetOffsetPosition(feetbox, 0, 0, feetz); 830 d.GeomSetOffsetPosition(feetbox, 0, 0, feetz);
766 d.GeomSetOffsetPosition(midbox, 0, 0, midz); 831 d.GeomSetOffsetPosition(midbox, 0, 0, midz);
767 d.GeomSetOffsetPosition(topbox, 0, 0, topz); 832 d.GeomSetOffsetPosition(topbox, 0, 0, topz);
768 833
834 ajustCollider();
835
836
769 // The purpose of the AMotor here is to keep the avatar's physical 837 // The purpose of the AMotor here is to keep the avatar's physical
770 // surrogate from rotating while moving 838 // surrogate from rotating while moving
771 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); 839 Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
@@ -828,142 +896,212 @@ namespace OpenSim.Region.Physics.OdePlugin
828 if (topbox != IntPtr.Zero) 896 if (topbox != IntPtr.Zero)
829 { 897 {
830 _parent_scene.actor_name_map.Remove(topbox); 898 _parent_scene.actor_name_map.Remove(topbox);
831 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 899 _parent_scene.waitForSpaceUnlock(collider);
832 d.GeomDestroy(topbox); 900 d.GeomDestroy(topbox);
833 topbox = IntPtr.Zero; 901 topbox = IntPtr.Zero;
834 } 902 }
835 if (midbox != IntPtr.Zero) 903 if (midbox != IntPtr.Zero)
836 { 904 {
837 _parent_scene.actor_name_map.Remove(midbox); 905 _parent_scene.actor_name_map.Remove(midbox);
838 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 906 _parent_scene.waitForSpaceUnlock(collider);
839 d.GeomDestroy(midbox); 907 d.GeomDestroy(midbox);
840 midbox = IntPtr.Zero; 908 midbox = IntPtr.Zero;
841 } 909 }
842 if (feetbox != IntPtr.Zero) 910 if (feetbox != IntPtr.Zero)
843 { 911 {
844 _parent_scene.actor_name_map.Remove(feetbox); 912 _parent_scene.actor_name_map.Remove(feetbox);
845 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 913 _parent_scene.waitForSpaceUnlock(collider);
846 d.GeomDestroy(feetbox); 914 d.GeomDestroy(feetbox);
847 feetbox = IntPtr.Zero; 915 feetbox = IntPtr.Zero;
848 } 916 }
849 917
850 if (bonebox != IntPtr.Zero) 918 if (bbox != IntPtr.Zero)
919 {
920 _parent_scene.actor_name_map.Remove(bbox);
921 _parent_scene.waitForSpaceUnlock(collider);
922 d.GeomDestroy(bbox);
923 bbox = IntPtr.Zero;
924 }
925
926 if (collider != IntPtr.Zero)
851 { 927 {
852 _parent_scene.actor_name_map.Remove(bonebox); 928 d.SpaceDestroy(collider);
853 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 929 collider = IntPtr.Zero;
854 d.GeomDestroy(bonebox);
855 bonebox = IntPtr.Zero;
856 } 930 }
857 931
858 } 932 }
859 933
860 public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact) 934 //in place 2D rotation around Z assuming rot is normalised and is a rotation around Z
935 public void RotateXYonZ(ref float x, ref float y, ref Quaternion rot)
861 { 936 {
937 float sin = 2.0f * rot.Z * rot.W;
938 float cos = rot.W * rot.W - rot.Z * rot.Z;
939 float tx = x;
862 940
863 if (me == bonebox) // inner bone 941 x = tx * cos - y * sin;
864 { 942 y = tx * sin + y * cos;
865 if (contact.pos.Z - _position.Z < boneOff) 943 }
866 IsColliding = true; 944 public void RotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
867 return true; 945 {
868 } 946 float tx = x;
947 x = tx * cos - y * sin;
948 y = tx * sin + y * cos;
949 }
950 public void invRotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
951 {
952 float tx = x;
953 x = tx * cos + y * sin;
954 y = -tx * sin + y * cos;
955 }
869 956
870 if (me == topbox) // keep a box head 957 public void invRotateXYonZ(ref float x, ref float y, ref Quaternion rot)
871 return true; 958 {
959 float sin = - 2.0f * rot.Z * rot.W;
960 float cos = rot.W * rot.W - rot.Z * rot.Z;
961 float tx = x;
872 962
873 // rotate elipsoide assuming only rotation around Z 963 x = tx * cos - y * sin;
874 float ca = m_orientation.W * m_orientation.W - m_orientation.Z * m_orientation.Z; 964 y = tx * sin + y * cos;
875 float sa = 2 * m_orientation.W * m_orientation.Z; 965 }
876 966
877 float isx;
878 float isy;
879 967
880 if (me == feetbox) // feet have narrow bounds 968 public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision)
881 { 969 {
970 feetcollision = false;
971 if (m_collisionException)
972 return false;
882 973
883 isx = m_invElipSizeX * invFeetScale; 974 Vector3 offset;
884 isy = m_invElipSizeY * invFeetScale; 975
885 } 976 if (me == bbox) // if moving fast
886 else
887 { 977 {
888 isx = m_invElipSizeX; 978 // force a full inelastic collision
889 isy = m_invElipSizeY; 979 m_collisionException = true;
980
981 offset = m_size * m_orientation2D;
982
983 offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth;
984 offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth;
985 offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth;
986
987 if (reverse)
988 {
989 offset.X *= -contact.normal.X;
990 offset.Y *= -contact.normal.Y;
991 offset.Z *= -contact.normal.Z;
992 }
993 else
994 {
995 offset.X *= contact.normal.X;
996 offset.Y *= contact.normal.Y;
997 offset.Z *= contact.normal.Z;
998 }
999
1000 offset.X += contact.pos.X;
1001 offset.Y += contact.pos.Y;
1002 offset.Z += contact.pos.Z;
1003
1004 _position = offset;
1005 return false;
890 } 1006 }
891 1007
892 float a = isx * ca - isy * sa; 1008 offset.X = contact.pos.X - _position.X;
893 float b = isx * sa + isy * ca; 1009 offset.Y = contact.pos.Y - _position.Y;
894 1010
895 float offx = contact.pos.X - _position.X; 1011 if (me == topbox)
896 float er = offx * a; 1012 {
897 er *= er; 1013 offset.Z = contact.pos.Z - _position.Z;
898 1014
899 float offy = contact.pos.Y - _position.Y; 1015 offset.Normalize();
900 float ty = offy * b; 1016
901 er += ty * ty; 1017 if (reverse)
1018 {
1019 contact.normal.X = offset.X;
1020 contact.normal.Y = offset.Y;
1021 contact.normal.Z = offset.Z;
1022 }
1023 else
1024 {
1025 contact.normal.X = -offset.X;
1026 contact.normal.Y = -offset.Y;
1027 contact.normal.Z = -offset.Z;
1028 }
1029 return true;
1030 }
902 1031
903 if (me == midbox) 1032 if (me == midbox)
904 { 1033 {
905 if (er > 4.0f) // no collision 1034 if (Math.Abs(contact.normal.Z) > 0.95f)
906 return false; 1035 offset.Z = contact.pos.Z - _position.Z;
907 if (er < 0.2f) 1036 else
908 return true; 1037 offset.Z = contact.normal.Z;
909 1038
910 float t = offx * offx + offy * offy; 1039 offset.Normalize();
911 t = (float)Math.Sqrt(t);
912 t = 1 / t;
913 offx *= t;
914 offy *= t;
915 1040
916 if (reverse) 1041 if (reverse)
917 { 1042 {
918 contact.normal.X = offx; 1043 contact.normal.X = offset.X;
919 contact.normal.Y = offy; 1044 contact.normal.Y = offset.Y;
1045 contact.normal.Z = offset.Z;
920 } 1046 }
921 else 1047 else
922 { 1048 {
923 contact.normal.X = -offx; 1049 contact.normal.X = -offset.X;
924 contact.normal.Y = -offy; 1050 contact.normal.Y = -offset.Y;
1051 contact.normal.Z = -offset.Z;
925 } 1052 }
926 1053
927 contact.normal.Z = 0;
928 return true; 1054 return true;
929 } 1055 }
930 1056
931 else if (me == feetbox) 1057 else if (me == feetbox)
932 { 1058 {
933 float c = feetSZ * 2;
934 float h = contact.pos.Z - _position.Z; 1059 float h = contact.pos.Z - _position.Z;
935 float offz = h - feetOff; // distance from top of feetbox
936 1060
937 float tz = offz / c; 1061 if (Math.Abs(contact.normal.Z) > 0.95f)
938 er += tz * tz; 1062 {
1063 if (contact.normal.Z > 0)
1064 contact.normal.Z = 1.0f;
1065 else
1066 contact.normal.Z = -1.0f;
1067 contact.normal.X = 0.0f;
1068 contact.normal.Y = 0.0f;
1069 feetcollision = true;
1070 if (h < boneOff)
1071 IsColliding = true;
1072 return true;
1073 }
1074
1075 offset.Z = h - feetOff; // distance from top of feetbox
939 1076
940 if (er > 4.0f) // no collision 1077 if (offset.Z > 0)
941 return false; 1078 return false;
942 1079
943 if (er > 0.2f) 1080 if (offset.Z > -0.01)
944 { 1081 {
945 float t = offx * offx + offy * offy + offz * offz; 1082 offset.X = 0;
946 t = (float)Math.Sqrt(t); 1083 offset.Y = 0;
947 t = 1 / t; 1084 offset.Z = -1.0f;
948 offx *= t; 1085 }
949 offy *= t; 1086 else
950 offz *= t; 1087 {
951 1088 offset.Normalize();
952 if (reverse)
953 {
954 contact.normal.X = offx;
955 contact.normal.Y = offy;
956 contact.normal.Z = offz;
957 }
958 else
959 {
960 contact.normal.X = -offx;
961 contact.normal.Y = -offy;
962 contact.normal.Z = -offz;
963 }
964 } 1089 }
965 1090
966 if(h < boneOff) 1091 if (reverse)
1092 {
1093 contact.normal.X = offset.X;
1094 contact.normal.Y = offset.Y;
1095 contact.normal.Z = offset.Z;
1096 }
1097 else
1098 {
1099 contact.normal.X = -offset.X;
1100 contact.normal.Y = -offset.Y;
1101 contact.normal.Z = -offset.Z;
1102 }
1103 feetcollision = true;
1104 if (h < boneOff)
967 IsColliding = true; 1105 IsColliding = true;
968 } 1106 }
969 else 1107 else
@@ -977,11 +1115,28 @@ namespace OpenSim.Region.Physics.OdePlugin
977 /// This is the avatar's movement control + PID Controller 1115 /// This is the avatar's movement control + PID Controller
978 /// </summary> 1116 /// </summary>
979 /// <param name="timeStep"></param> 1117 /// <param name="timeStep"></param>
980 public void Move(float timeStep, List<OdeCharacter> defects) 1118 public void Move(List<OdeCharacter> defects)
981 { 1119 {
982 if (Body == IntPtr.Zero) 1120 if (Body == IntPtr.Zero)
983 return; 1121 return;
984 1122
1123 if (m_collisionException)
1124 {
1125 d.BodySetPosition(Body,_position.X, _position.Y, _position.Z);
1126 d.BodySetLinearVel(Body, 0, 0, 0);
1127
1128 float v = _velocity.Length();
1129 if (v != 0)
1130 {
1131 v = 5.0f / v;
1132 _velocity = _velocity * v;
1133 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
1134 }
1135 ajustCollider();
1136 m_collisionException = false;
1137 return;
1138 }
1139
985 d.Vector3 dtmp = d.BodyGetPosition(Body); 1140 d.Vector3 dtmp = d.BodyGetPosition(Body);
986 Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); 1141 Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
987 1142
@@ -989,10 +1144,10 @@ namespace OpenSim.Region.Physics.OdePlugin
989 // so force it back to identity 1144 // so force it back to identity
990 1145
991 d.Quaternion qtmp; 1146 d.Quaternion qtmp;
992 qtmp.W = m_orientation.W; 1147 qtmp.W = m_orientation2D.W;
993 qtmp.X = m_orientation.X; 1148 qtmp.X = m_orientation2D.X;
994 qtmp.Y = m_orientation.Y; 1149 qtmp.Y = m_orientation2D.Y;
995 qtmp.Z = m_orientation.Z; 1150 qtmp.Z = m_orientation2D.Z;
996 d.BodySetQuaternion(Body, ref qtmp); 1151 d.BodySetQuaternion(Body, ref qtmp);
997 1152
998 if (m_pidControllerActive == false) 1153 if (m_pidControllerActive == false)
@@ -1055,9 +1210,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1055 1210
1056 //****************************************** 1211 //******************************************
1057 // colide with land 1212 // colide with land
1213
1058 d.AABB aabb; 1214 d.AABB aabb;
1059 d.GeomGetAABB(feetbox, out aabb); 1215 d.GeomGetAABB(feetbox, out aabb);
1060 float chrminZ = aabb.MinZ - 0.04f; // move up a bit 1216 float chrminZ = aabb.MinZ; ; // move up a bit
1061 Vector3 posch = localpos; 1217 Vector3 posch = localpos;
1062 1218
1063 float ftmp; 1219 float ftmp;
@@ -1100,11 +1256,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1100 contact.PenetrationDepth = depth; 1256 contact.PenetrationDepth = depth;
1101 contact.Position.X = localpos.X; 1257 contact.Position.X = localpos.X;
1102 contact.Position.Y = localpos.Y; 1258 contact.Position.Y = localpos.Y;
1103 contact.Position.Z = chrminZ; 1259 contact.Position.Z = terrainheight;
1104 contact.SurfaceNormal.X = 0f; 1260 contact.SurfaceNormal.X = 0.0f;
1105 contact.SurfaceNormal.Y = 0f; 1261 contact.SurfaceNormal.Y = 0.0f;
1106 contact.SurfaceNormal.Z = -1f; 1262 contact.SurfaceNormal.Z = -1f;
1107 contact.RelativeSpeed = -vel.Z; 1263 contact.RelativeSpeed = -vel.Z;
1264 contact.CharacterFeet = true;
1108 AddCollisionEvent(0, contact); 1265 AddCollisionEvent(0, contact);
1109 1266
1110 vec.Z *= 0.5f; 1267 vec.Z *= 0.5f;
@@ -1123,6 +1280,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1123 m_iscollidingGround = false; 1280 m_iscollidingGround = false;
1124 } 1281 }
1125 1282
1283
1126 //****************************************** 1284 //******************************************
1127 1285
1128 bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f); 1286 bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f);
@@ -1258,21 +1416,58 @@ namespace OpenSim.Region.Physics.OdePlugin
1258 } 1416 }
1259 1417
1260 // update our local ideia of position velocity and aceleration 1418 // update our local ideia of position velocity and aceleration
1419 // _position = localpos;
1261 _position = localpos; 1420 _position = localpos;
1421
1262 if (_zeroFlag) 1422 if (_zeroFlag)
1263 { 1423 {
1264 _velocity = Vector3.Zero; 1424 _velocity = Vector3.Zero;
1265 _acceleration = Vector3.Zero; 1425 _acceleration = Vector3.Zero;
1426 m_rotationalVelocity = Vector3.Zero;
1266 } 1427 }
1267 else 1428 else
1268 { 1429 {
1269 _acceleration = _velocity; // previus velocity 1430 Vector3 a =_velocity; // previus velocity
1270 _velocity = vel; 1431 SetSmooth(ref _velocity, ref vel, 2);
1271 _acceleration = (vel - _acceleration) / timeStep; 1432 a = (_velocity - a) * invtimeStep;
1433 SetSmooth(ref _acceleration, ref a, 2);
1434
1435 dtmp = d.BodyGetAngularVel(Body);
1436 m_rotationalVelocity.X = 0f;
1437 m_rotationalVelocity.Y = 0f;
1438 m_rotationalVelocity.Z = dtmp.Z;
1439 Math.Round(m_rotationalVelocity.Z,3);
1272 } 1440 }
1273 1441 ajustCollider();
1442 }
1443
1444 public void round(ref Vector3 v, int digits)
1445 {
1446 v.X = (float)Math.Round(v.X, digits);
1447 v.Y = (float)Math.Round(v.Y, digits);
1448 v.Z = (float)Math.Round(v.Z, digits);
1449 }
1450
1451 public void SetSmooth(ref Vector3 dst, ref Vector3 value)
1452 {
1453 dst.X = 0.1f * dst.X + 0.9f * value.X;
1454 dst.Y = 0.1f * dst.Y + 0.9f * value.Y;
1455 dst.Z = 0.1f * dst.Z + 0.9f * value.Z;
1456 }
1457
1458 public void SetSmooth(ref Vector3 dst, ref Vector3 value, int rounddigits)
1459 {
1460 dst.X = 0.4f * dst.X + 0.6f * value.X;
1461 dst.X = (float)Math.Round(dst.X, rounddigits);
1462
1463 dst.Y = 0.4f * dst.Y + 0.6f * value.Y;
1464 dst.Y = (float)Math.Round(dst.Y, rounddigits);
1465
1466 dst.Z = 0.4f * dst.Z + 0.6f * value.Z;
1467 dst.Z = (float)Math.Round(dst.Z, rounddigits);
1274 } 1468 }
1275 1469
1470
1276 /// <summary> 1471 /// <summary>
1277 /// Updates the reported position and velocity. 1472 /// Updates the reported position and velocity.
1278 /// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording 1473 /// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording
@@ -1399,10 +1594,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1399 1594
1400 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); 1595 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
1401 1596
1402 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; 1597 _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1403 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1404 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; 1598 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1405 _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; 1599 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1600 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1601 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
1406 _parent_scene.AddCharacter(this); 1602 _parent_scene.AddCharacter(this);
1407 } 1603 }
1408 else 1604 else
@@ -1431,6 +1627,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1431 { 1627 {
1432 } 1628 }
1433 1629
1630 private void changeAvatarSize(strAvatarSize st)
1631 {
1632 m_feetOffset = st.offset;
1633 changeSize(st.size);
1634 }
1635
1434 private void changeSize(Vector3 pSize) 1636 private void changeSize(Vector3 pSize)
1435 { 1637 {
1436 if (pSize.IsFinite()) 1638 if (pSize.IsFinite())
@@ -1449,13 +1651,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1449 _position.Z + (m_size.Z - oldsz) * 0.5f); 1651 _position.Z + (m_size.Z - oldsz) * 0.5f);
1450 1652
1451 Velocity = Vector3.Zero; 1653 Velocity = Vector3.Zero;
1654
1452 1655
1453 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; 1656 _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1454 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1455 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; 1657 _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1456 _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; 1658 _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1659 _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1660 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
1457 } 1661 }
1458 m_freemove = false; 1662 m_freemove = false;
1663 m_collisionException = false;
1459 m_pidControllerActive = true; 1664 m_pidControllerActive = true;
1460 } 1665 }
1461 else 1666 else
@@ -1475,14 +1680,36 @@ namespace OpenSim.Region.Physics.OdePlugin
1475 1680
1476 private void changeOrientation(Quaternion newOri) 1681 private void changeOrientation(Quaternion newOri)
1477 { 1682 {
1478 d.Quaternion myrot = new d.Quaternion(); 1683 if (m_orientation != newOri)
1479 myrot.X = newOri.X; 1684 {
1480 myrot.Y = newOri.Y; 1685 m_orientation = newOri; // keep a copy for core use
1481 myrot.Z = newOri.Z; 1686 // but only use rotations around Z
1482 myrot.W = newOri.W; 1687
1483 float t = d.JointGetAMotorAngle(Amotor, 2); 1688 m_orientation2D.W = newOri.W;
1484 d.BodySetQuaternion(Body,ref myrot); 1689 m_orientation2D.Z = newOri.Z;
1485 m_orientation = newOri; 1690
1691 float t = m_orientation2D.W * m_orientation2D.W + m_orientation2D.Z * m_orientation2D.Z;
1692 if (t > 0)
1693 {
1694 t = 1.0f / (float)Math.Sqrt(t);
1695 m_orientation2D.W *= t;
1696 m_orientation2D.Z *= t;
1697 }
1698 else
1699 {
1700 m_orientation2D.W = 1.0f;
1701 m_orientation2D.Z = 0f;
1702 }
1703 m_orientation2D.Y = 0f;
1704 m_orientation2D.X = 0f;
1705
1706 d.Quaternion myrot = new d.Quaternion();
1707 myrot.X = m_orientation2D.X;
1708 myrot.Y = m_orientation2D.Y;
1709 myrot.Z = m_orientation2D.Z;
1710 myrot.W = m_orientation2D.W;
1711 d.BodySetQuaternion(Body, ref myrot);
1712 }
1486 } 1713 }
1487 1714
1488 private void changeVelocity(Vector3 newVel) 1715 private void changeVelocity(Vector3 newVel)
@@ -1564,6 +1791,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1564 1791
1565 if (Body != IntPtr.Zero) 1792 if (Body != IntPtr.Zero)
1566 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); 1793 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1794 ajustCollider();
1567 } 1795 }
1568 1796
1569 private void donullchange() 1797 private void donullchange()
@@ -1572,7 +1800,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1572 1800
1573 public bool DoAChange(changes what, object arg) 1801 public bool DoAChange(changes what, object arg)
1574 { 1802 {
1575 if (topbox == IntPtr.Zero && what != changes.Add && what != changes.Remove) 1803 if (collider == IntPtr.Zero && what != changes.Add && what != changes.Remove)
1576 { 1804 {
1577 return false; 1805 return false;
1578 } 1806 }
@@ -1638,6 +1866,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1638 changeSize((Vector3)arg); 1866 changeSize((Vector3)arg);
1639 break; 1867 break;
1640 1868
1869 case changes.AvatarSize:
1870 changeAvatarSize((strAvatarSize)arg);
1871 break;
1872
1641 case changes.Momentum: 1873 case changes.Momentum:
1642 changeMomentum((Vector3)arg); 1874 changeMomentum((Vector3)arg);
1643 break; 1875 break;
@@ -1685,5 +1917,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1685 { 1917 {
1686 _parent_scene.AddChange((PhysicsActor)this, what, arg); 1918 _parent_scene.AddChange((PhysicsActor)this, what, arg);
1687 } 1919 }
1920
1921 private struct strAvatarSize
1922 {
1923 public Vector3 size;
1924 public float offset;
1925 }
1926
1688 } 1927 }
1689} 1928}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index dc247a9..faa9488 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Region.Physics.OdePlugin
84 84
85 private Vector3 _position; 85 private Vector3 _position;
86 private Vector3 _velocity; 86 private Vector3 _velocity;
87 private Vector3 _torque; 87 private Vector3 m_torque;
88 private Vector3 m_lastVelocity; 88 private Vector3 m_lastVelocity;
89 private Vector3 m_lastposition; 89 private Vector3 m_lastposition;
90 private Vector3 m_rotationalVelocity; 90 private Vector3 m_rotationalVelocity;
@@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.OdePlugin
597 if (!IsPhysical || Body == IntPtr.Zero) 597 if (!IsPhysical || Body == IntPtr.Zero)
598 return Vector3.Zero; 598 return Vector3.Zero;
599 599
600 return _torque; 600 return m_torque;
601 } 601 }
602 602
603 set 603 set
@@ -2425,10 +2425,10 @@ namespace OpenSim.Region.Physics.OdePlugin
2425 { 2425 {
2426 if (!childPrim) 2426 if (!childPrim)
2427 { 2427 {
2428 m_force = Vector3.Zero; 2428// m_force = Vector3.Zero;
2429 m_forceacc = Vector3.Zero; 2429 m_forceacc = Vector3.Zero;
2430 m_angularForceacc = Vector3.Zero; 2430 m_angularForceacc = Vector3.Zero;
2431 _torque = Vector3.Zero; 2431// m_torque = Vector3.Zero;
2432 _velocity = Vector3.Zero; 2432 _velocity = Vector3.Zero;
2433 _acceleration = Vector3.Zero; 2433 _acceleration = Vector3.Zero;
2434 m_rotationalVelocity = Vector3.Zero; 2434 m_rotationalVelocity = Vector3.Zero;
@@ -2521,7 +2521,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2521 prm.m_collisionCategories = m_collisionCategories; 2521 prm.m_collisionCategories = m_collisionCategories;
2522 prm.m_collisionFlags = m_collisionFlags; 2522 prm.m_collisionFlags = m_collisionFlags;
2523 2523
2524 if (prm.prim_geom != null) 2524 if (prm.prim_geom != IntPtr.Zero)
2525 { 2525 {
2526 2526
2527 if (prm.m_NoColide) 2527 if (prm.m_NoColide)
@@ -2542,7 +2542,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2542// ((OdePrim)_parent).ChildSelectedChange(true); 2542// ((OdePrim)_parent).ChildSelectedChange(true);
2543 2543
2544 2544
2545 if (prim_geom != null) 2545 if (prim_geom != IntPtr.Zero)
2546 { 2546 {
2547 if (m_NoColide) 2547 if (m_NoColide)
2548 { 2548 {
@@ -2968,7 +2968,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2968 d.BodyEnable(Body); 2968 d.BodyEnable(Body);
2969 2969
2970 } 2970 }
2971 _torque = newtorque; 2971 m_torque = newtorque;
2972 } 2972 }
2973 } 2973 }
2974 2974
@@ -3364,7 +3364,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3364 3364
3365 Vector3 trq; 3365 Vector3 trq;
3366 3366
3367 trq = _torque; 3367 trq = m_torque;
3368 trq += m_angularForceacc; 3368 trq += m_angularForceacc;
3369 m_angularForceacc = Vector3.Zero; 3369 m_angularForceacc = Vector3.Zero;
3370 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) 3370 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 799a324..561ab1c 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -324,7 +324,10 @@ namespace OpenSim.Region.Physics.OdePlugin
324 { 324 {
325 // Collide tests 325 // Collide tests
326 if ((CurrentRayFilter & FilterActiveSpace) != 0) 326 if ((CurrentRayFilter & FilterActiveSpace) != 0)
327 {
327 d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); 328 d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
329 d.SpaceCollide2(ray, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
330 }
328 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) 331 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
329 d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback); 332 d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
330 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) 333 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
@@ -552,7 +555,6 @@ namespace OpenSim.Region.Physics.OdePlugin
552 break; 555 break;
553 556
554 default: 557 default:
555 return;
556 break; 558 break;
557 } 559 }
558 } 560 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
new file mode 100644
index 0000000..225bff8
--- /dev/null
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
@@ -0,0 +1,183 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27// Ubit 2012
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Runtime.InteropServices;
32using System.Text;
33using OpenSim.Framework;
34using OpenSim.Region.Physics.Manager;
35using OdeAPI;
36using log4net;
37using OpenMetaverse;
38
39namespace OpenSim.Region.Physics.OdePlugin
40{
41 /// <summary>
42 /// </summary>
43 public class ODESitAvatar
44 {
45 private OdeScene m_scene;
46 private ODERayCastRequestManager m_raymanager;
47
48 public ODESitAvatar(OdeScene pScene, ODERayCastRequestManager raymanager)
49 {
50 m_scene = pScene;
51 m_raymanager = raymanager;
52 }
53
54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
55
56 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
57 {
58 if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero)
59 {
60 PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
61 return;
62 }
63
64 IntPtr geom = ((OdePrim)actor).prim_geom;
65
66 d.Vector3 dtmp = d.GeomGetPosition(geom);
67 Vector3 geopos;
68 geopos.X = dtmp.X;
69 geopos.Y = dtmp.Y;
70 geopos.Z = dtmp.Z;
71
72
73 d.AABB aabb;
74 Quaternion ori;
75 d.Quaternion qtmp;
76 d.GeomCopyQuaternion(geom, out qtmp);
77 Quaternion geomOri;
78 geomOri.X = qtmp.X;
79 geomOri.Y = qtmp.Y;
80 geomOri.Z = qtmp.Z;
81 geomOri.W = qtmp.W;
82 Quaternion geomInvOri;
83 geomInvOri.X = -qtmp.X;
84 geomInvOri.Y = -qtmp.Y;
85 geomInvOri.Z = -qtmp.Z;
86 geomInvOri.W = qtmp.W;
87
88 Vector3 target = geopos + offset;
89 Vector3 rayDir = target - avCameraPosition;
90 float raylen = rayDir.Length();
91 float t = 1 / raylen;
92 rayDir.X *= t;
93 rayDir.Y *= t;
94 rayDir.Z *= t;
95
96 raylen += 0.5f;
97 List<ContactResult> rayResults;
98
99 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1);
100 if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID)
101 {
102 d.GeomGetAABB(geom,out aabb);
103 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
104 ori = geomInvOri;
105 offset *= geomInvOri;
106
107 PhysicsSitResponse(1, actor.LocalID, offset, ori);
108 return;
109 }
110
111 offset = rayResults[0].Pos - geopos;
112 double ang;
113 float s;
114 float c;
115
116 d.GeomClassID geoclass = d.GeomGetClass(geom);
117
118 if (geoclass == d.GeomClassID.SphereClass)
119 {
120 float r = d.GeomSphereGetRadius(geom);
121
122 offset.Normalize();
123 offset *= r;
124
125 ang = Math.Atan2(offset.Y, offset.X);
126 ang *= 0.5d;
127 s = (float)Math.Sin(ang);
128 c = (float)Math.Cos(ang);
129
130 ori = new Quaternion(0, 0, s, c);
131
132 if (r < 0.4f)
133 {
134 offset = new Vector3(0, 0, r);
135 }
136 else if (offset.Z < 0.4f)
137 {
138 t = offset.Z;
139 float rsq = r * r;
140
141 t = 1.0f / (rsq - t * t);
142 offset.X *= t;
143 offset.Y *= t;
144 offset.Z = 0.4f;
145 t = rsq - 0.16f;
146 offset.X *= t;
147 offset.Y *= t;
148 }
149
150 offset += avOffset * ori;
151
152 ori = geomInvOri * ori;
153 offset *= geomInvOri;
154
155 PhysicsSitResponse(1, actor.LocalID, offset, ori);
156 return;
157 }
158
159 Vector3 norm = rayResults[0].Normal;
160
161 if (norm.Z < 0)
162 {
163 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
164 return;
165 }
166
167 ang = Math.Atan2(-rayDir.Y, -rayDir.X);
168 ang *= 0.5d;
169 s = (float)Math.Sin(ang);
170 c = (float)Math.Cos(ang);
171
172 ori = new Quaternion(0, 0, s, c);
173
174 offset += avOffset * ori;
175
176 ori = geomInvOri * ori;
177 offset *= geomInvOri;
178
179 PhysicsSitResponse(1, actor.LocalID, offset, ori);
180 return;
181 }
182 }
183} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 003a91c..fbf2f0d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -147,6 +147,7 @@ namespace OpenSim.Region.Physics.OdePlugin
147 PIDHoverActive, 147 PIDHoverActive,
148 148
149 Size, 149 Size,
150 AvatarSize,
150 Shape, 151 Shape,
151 PhysRepData, 152 PhysRepData,
152 AddPhysRep, 153 AddPhysRep,
@@ -177,7 +178,9 @@ namespace OpenSim.Region.Physics.OdePlugin
177 public changes what; 178 public changes what;
178 public Object arg; 179 public Object arg;
179 } 180 }
180 181
182
183
181 public class OdeScene : PhysicsScene 184 public class OdeScene : PhysicsScene
182 { 185 {
183 private readonly ILog m_log; 186 private readonly ILog m_log;
@@ -224,9 +227,6 @@ namespace OpenSim.Region.Physics.OdePlugin
224// private IntPtr WaterHeightmapData = IntPtr.Zero; 227// private IntPtr WaterHeightmapData = IntPtr.Zero;
225// private GCHandle WaterMapHandler = new GCHandle(); 228// private GCHandle WaterMapHandler = new GCHandle();
226 229
227 public float avPIDD = 2200f; // make it visible
228 public float avPIDP = 900f; // make it visible
229 private float avCapRadius = 0.37f;
230 private float avDensity = 3f; 230 private float avDensity = 3f;
231 private float avMovementDivisorWalk = 1.3f; 231 private float avMovementDivisorWalk = 1.3f;
232 private float avMovementDivisorRun = 0.8f; 232 private float avMovementDivisorRun = 0.8f;
@@ -299,9 +299,12 @@ namespace OpenSim.Region.Physics.OdePlugin
299 299
300 public IntPtr TopSpace; // the global space 300 public IntPtr TopSpace; // the global space
301 public IntPtr ActiveSpace; // space for active prims 301 public IntPtr ActiveSpace; // space for active prims
302 public IntPtr CharsSpace; // space for active prims
302 public IntPtr StaticSpace; // space for the static things around 303 public IntPtr StaticSpace; // space for the static things around
303 public IntPtr GroundSpace; // space for ground 304 public IntPtr GroundSpace; // space for ground
304 305
306 public IntPtr SharedRay;
307
305 // some speedup variables 308 // some speedup variables
306 private int spaceGridMaxX; 309 private int spaceGridMaxX;
307 private int spaceGridMaxY; 310 private int spaceGridMaxY;
@@ -359,8 +362,7 @@ namespace OpenSim.Region.Physics.OdePlugin
359 362
360 nearCallback = near; 363 nearCallback = near;
361 364
362 m_rayCastManager = new ODERayCastRequestManager(this); 365 m_rayCastManager = new ODERayCastRequestManager(this);
363
364 366
365 lock (OdeLock) 367 lock (OdeLock)
366 { 368 {
@@ -372,21 +374,25 @@ namespace OpenSim.Region.Physics.OdePlugin
372 374
373 // now the major subspaces 375 // now the major subspaces
374 ActiveSpace = d.HashSpaceCreate(TopSpace); 376 ActiveSpace = d.HashSpaceCreate(TopSpace);
377 CharsSpace = d.HashSpaceCreate(TopSpace);
375 StaticSpace = d.HashSpaceCreate(TopSpace); 378 StaticSpace = d.HashSpaceCreate(TopSpace);
376 GroundSpace = d.HashSpaceCreate(TopSpace); 379 GroundSpace = d.HashSpaceCreate(TopSpace);
377 } 380 }
378 catch 381 catch
379 { 382 {
380 // i must RtC#FM 383 // i must RtC#FM
384 // i did!
381 } 385 }
382 386
383 d.HashSpaceSetLevels(TopSpace, -2, 8); 387 d.HashSpaceSetLevels(TopSpace, -2, 8);
384 d.HashSpaceSetLevels(ActiveSpace, -2, 8); 388 d.HashSpaceSetLevels(ActiveSpace, -2, 8);
389 d.HashSpaceSetLevels(CharsSpace, -4, 3);
385 d.HashSpaceSetLevels(StaticSpace, -2, 8); 390 d.HashSpaceSetLevels(StaticSpace, -2, 8);
386 d.HashSpaceSetLevels(GroundSpace, 0, 8); 391 d.HashSpaceSetLevels(GroundSpace, 0, 8);
387 392
388 // demote to second level 393 // demote to second level
389 d.SpaceSetSublevel(ActiveSpace, 1); 394 d.SpaceSetSublevel(ActiveSpace, 1);
395 d.SpaceSetSublevel(CharsSpace, 1);
390 d.SpaceSetSublevel(StaticSpace, 1); 396 d.SpaceSetSublevel(StaticSpace, 1);
391 d.SpaceSetSublevel(GroundSpace, 1); 397 d.SpaceSetSublevel(GroundSpace, 1);
392 398
@@ -396,11 +402,24 @@ namespace OpenSim.Region.Physics.OdePlugin
396 CollisionCategories.Phantom | 402 CollisionCategories.Phantom |
397 CollisionCategories.VolumeDtc 403 CollisionCategories.VolumeDtc
398 )); 404 ));
399 d.GeomSetCollideBits(ActiveSpace, 0); 405 d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space |
406 CollisionCategories.Geom |
407 CollisionCategories.Character |
408 CollisionCategories.Phantom |
409 CollisionCategories.VolumeDtc
410 ));
411 d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space |
412 CollisionCategories.Geom |
413 CollisionCategories.Character |
414 CollisionCategories.Phantom |
415 CollisionCategories.VolumeDtc
416 ));
417 d.GeomSetCollideBits(CharsSpace, 0);
418
400 d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | 419 d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space |
401 CollisionCategories.Geom | 420 CollisionCategories.Geom |
402 CollisionCategories.Land | 421// CollisionCategories.Land |
403 CollisionCategories.Water | 422// CollisionCategories.Water |
404 CollisionCategories.Phantom | 423 CollisionCategories.Phantom |
405 CollisionCategories.VolumeDtc 424 CollisionCategories.VolumeDtc
406 )); 425 ));
@@ -412,6 +431,8 @@ namespace OpenSim.Region.Physics.OdePlugin
412 contactgroup = d.JointGroupCreate(0); 431 contactgroup = d.JointGroupCreate(0);
413 //contactgroup 432 //contactgroup
414 433
434 SharedRay = d.CreateRay(TopSpace, 1.0f);
435
415 d.WorldSetAutoDisableFlag(world, false); 436 d.WorldSetAutoDisableFlag(world, false);
416 } 437 }
417 } 438 }
@@ -468,7 +489,6 @@ namespace OpenSim.Region.Physics.OdePlugin
468 avDensity = physicsconfig.GetFloat("av_density", avDensity); 489 avDensity = physicsconfig.GetFloat("av_density", avDensity);
469 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); 490 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
470 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun); 491 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
471 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius);
472 492
473 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); 493 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
474 494
@@ -494,7 +514,7 @@ namespace OpenSim.Region.Physics.OdePlugin
494 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); 514 odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
495 515
496 ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); 516 ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
497 GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); 517 GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf);
498 518
499 m_materialContactsData[(int)Material.Stone].mu = 0.8f; 519 m_materialContactsData[(int)Material.Stone].mu = 0.8f;
500 m_materialContactsData[(int)Material.Stone].bounce = 0.4f; 520 m_materialContactsData[(int)Material.Stone].bounce = 0.4f;
@@ -718,35 +738,35 @@ namespace OpenSim.Region.Physics.OdePlugin
718 738
719 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 739 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
720 return; 740 return;
721/* 741 /*
722// debug 742 // debug
723 PhysicsActor dp2; 743 PhysicsActor dp2;
724 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) 744 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
725 { 745 {
726 d.AABB aabb; 746 d.AABB aabb;
727 d.GeomGetAABB(g2, out aabb); 747 d.GeomGetAABB(g2, out aabb);
728 float x = aabb.MaxX - aabb.MinX; 748 float x = aabb.MaxX - aabb.MinX;
729 float y = aabb.MaxY - aabb.MinY; 749 float y = aabb.MaxY - aabb.MinY;
730 float z = aabb.MaxZ - aabb.MinZ; 750 float z = aabb.MaxZ - aabb.MinZ;
731 if (x > 60.0f || y > 60.0f || z > 60.0f) 751 if (x > 60.0f || y > 60.0f || z > 60.0f)
732 { 752 {
733 if (!actor_name_map.TryGetValue(g2, out dp2)) 753 if (!actor_name_map.TryGetValue(g2, out dp2))
734 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2"); 754 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2");
735 else 755 else
736 m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})", 756 m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})",
737 dp2.Name, dp2.Size, x, y, z, 757 dp2.Name, dp2.Size, x, y, z,
738 dp2.Position.ToString(), 758 dp2.Position.ToString(),
739 dp2.Orientation.ToString(), 759 dp2.Orientation.ToString(),
740 dp2.Orientation.Length()); 760 dp2.Orientation.Length());
741 return; 761 return;
742 } 762 }
743 } 763 }
744// 764 //
745*/ 765 */
746 766
747 767
748 if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || 768 if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||
749 d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc) 769 d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc)
750 { 770 {
751 int cflags; 771 int cflags;
752 unchecked 772 unchecked
@@ -761,7 +781,7 @@ namespace OpenSim.Region.Physics.OdePlugin
761 catch (SEHException) 781 catch (SEHException)
762 { 782 {
763 m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); 783 m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
764// ode.drelease(world); 784 // ode.drelease(world);
765 base.TriggerPhysicsBasedRestart(); 785 base.TriggerPhysicsBasedRestart();
766 } 786 }
767 catch (Exception e) 787 catch (Exception e)
@@ -801,26 +821,25 @@ namespace OpenSim.Region.Physics.OdePlugin
801 821
802 // get first contact 822 // get first contact
803 d.ContactGeom curContact = new d.ContactGeom(); 823 d.ContactGeom curContact = new d.ContactGeom();
824
804 if (!GetCurContactGeom(0, ref curContact)) 825 if (!GetCurContactGeom(0, ref curContact))
805 return; 826 return;
806 // for now it's the one with max depth 827
807 ContactPoint maxDepthContact = new ContactPoint(
808 new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
809 new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
810 curContact.depth
811 );
812 // do volume detection case 828 // do volume detection case
813 if ( 829 if ((p1.IsVolumeDtc || p2.IsVolumeDtc))
814 (p1.IsVolumeDtc || p2.IsVolumeDtc))
815 { 830 {
831 ContactPoint maxDepthContact = new ContactPoint(
832 new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
833 new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
834 curContact.depth, false
835 );
836
816 collision_accounting_events(p1, p2, maxDepthContact); 837 collision_accounting_events(p1, p2, maxDepthContact);
817 return; 838 return;
818 } 839 }
819 840
820 // big messy collision analises 841 // big messy collision analises
821 842
822 Vector3 normoverride = Vector3.Zero; //damm c#
823
824 float mu = 0; 843 float mu = 0;
825 float bounce = 0; 844 float bounce = 0;
826 float cfm = 0.0001f; 845 float cfm = 0.0001f;
@@ -831,36 +850,15 @@ namespace OpenSim.Region.Physics.OdePlugin
831 ContactData contactdata1 = new ContactData(0, 0, false); 850 ContactData contactdata1 = new ContactData(0, 0, false);
832 ContactData contactdata2 = new ContactData(0, 0, false); 851 ContactData contactdata2 = new ContactData(0, 0, false);
833 852
834 bool dop1foot = false; 853 bool dop1ava = false;
835 bool dop2foot = false; 854 bool dop2ava = false;
836 bool ignore = false; 855 bool ignore = false;
837 bool AvanormOverride = false;
838 856
839 switch (p1.PhysicsActorType) 857 switch (p1.PhysicsActorType)
840 { 858 {
841 case (int)ActorTypes.Agent: 859 case (int)ActorTypes.Agent:
842 { 860 {
843 dop1foot = true; 861 dop1ava = true;
844
845 AvanormOverride = true;
846 Vector3 tmp = p2.Position - p1.Position;
847 normoverride = p2.Velocity - p1.Velocity;
848 mu = normoverride.LengthSquared();
849
850 if (mu > 1e-6)
851 {
852 mu = 1.0f / (float)Math.Sqrt(mu);
853 normoverride *= mu;
854 mu = Vector3.Dot(tmp, normoverride);
855 if (mu > 0)
856 normoverride *= -1;
857 }
858 else
859 {
860 tmp.Normalize();
861 normoverride = -tmp;
862 }
863
864 switch (p2.PhysicsActorType) 862 switch (p2.PhysicsActorType)
865 { 863 {
866 case (int)ActorTypes.Agent: 864 case (int)ActorTypes.Agent:
@@ -871,7 +869,6 @@ namespace OpenSim.Region.Physics.OdePlugin
871 case (int)ActorTypes.Prim: 869 case (int)ActorTypes.Prim:
872 if (p2.Velocity.LengthSquared() > 0.0f) 870 if (p2.Velocity.LengthSquared() > 0.0f)
873 p2.CollidingObj = true; 871 p2.CollidingObj = true;
874 dop1foot = true;
875 break; 872 break;
876 873
877 default: 874 default:
@@ -886,33 +883,8 @@ namespace OpenSim.Region.Physics.OdePlugin
886 { 883 {
887 case (int)ActorTypes.Agent: 884 case (int)ActorTypes.Agent:
888 885
886 dop2ava = true;
889 887
890 dop2foot = true;
891
892 AvanormOverride = true;
893
894 Vector3 tmp = p2.Position - p1.Position;
895 normoverride = p2.Velocity - p1.Velocity;
896 mu = normoverride.LengthSquared();
897 if (mu > 1e-6)
898 {
899 mu = 1.0f / (float)Math.Sqrt(mu);
900 normoverride *= mu;
901 mu = Vector3.Dot(tmp, normoverride);
902 if (mu > 0)
903 normoverride *= -1;
904 }
905 else
906 {
907 tmp.Normalize();
908 normoverride = -tmp;
909 }
910
911 bounce = 0;
912 mu = 0;
913 cfm = 0.0001f;
914
915 dop2foot = true;
916 if (p1.Velocity.LengthSquared() > 0.0f) 888 if (p1.Velocity.LengthSquared() > 0.0f)
917 p1.CollidingObj = true; 889 p1.CollidingObj = true;
918 break; 890 break;
@@ -1017,166 +989,78 @@ namespace OpenSim.Region.Physics.OdePlugin
1017 default: 989 default:
1018 break; 990 break;
1019 } 991 }
992
1020 if (ignore) 993 if (ignore)
1021 return; 994 return;
1022 995
1023 IntPtr Joint;
1024 996
1025 int i = 0; 997 d.ContactGeom maxContact = curContact;
998// if (IgnoreNegSides && curContact.side1 < 0)
999// maxContact.depth = float.MinValue;
1000
1001 d.ContactGeom minContact = curContact;
1002// if (IgnoreNegSides && curContact.side1 < 0)
1003// minContact.depth = float.MaxValue;
1004
1005 IntPtr Joint;
1006 bool FeetCollision = false;
1026 int ncontacts = 0; 1007 int ncontacts = 0;
1027 while(true)
1028 {
1029 1008
1030 if (IgnoreNegSides && curContact.side1 < 0)
1031 {
1032 if (++i >= count)
1033 break;
1034 1009
1035 if (!GetCurContactGeom(i, ref curContact)) 1010 int i = 0;
1036 break;
1037 }
1038 else
1039 1011
1012 while (true)
1040 { 1013 {
1041 if(dop1foot) 1014 if (m_global_contactcount >= maxContactsbeforedeath)
1042 { 1015 break;
1043 if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact))) 1016
1044 { 1017// if (!(IgnoreNegSides && curContact.side1 < 0))
1045 if (++i >= count)
1046 break;
1047 else
1048 continue;
1049 }
1050 }
1051 else if(dop2foot)
1052 { 1018 {
1053 if(!(((OdeCharacter) p2).Collide(g2,true,ref curContact))) 1019 bool noskip = true;
1020 if (dop1ava)
1054 { 1021 {
1055 if (++i >= count) 1022 if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact, ref FeetCollision)))
1056 break;
1057 else
1058 continue;
1059 }
1060 }
1061 1023
1062/* 1024 noskip = false;
1063 if (AvanormOverride) 1025 }
1064 { 1026 else if (dop2ava)
1065 if (curContact.depth > 0.3f)
1066 { 1027 {
1067 if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f) 1028 if (!(((OdeCharacter)p2).Collide(g2,true, ref curContact, ref FeetCollision)))
1068 p1.IsColliding = true; 1029 noskip = false;
1069 if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
1070 p2.IsColliding = true;
1071 curContact.normal.X = normoverride.X;
1072 curContact.normal.Y = normoverride.Y;
1073 curContact.normal.Z = normoverride.Z;
1074 } 1030 }
1075 1031
1076 else 1032 if (noskip)
1077 { 1033 {
1078 if (dop1foot) 1034 m_global_contactcount++;
1079 { 1035 ncontacts++;
1080 float sz = p1.Size.Z;
1081 Vector3 vtmp = p1.Position;
1082 float ppos = curContact.pos.Z - vtmp.Z + (sz - avCapRadius) * 0.5f;
1083 if (ppos > 0f)
1084 {
1085 if (!p1.Flying)
1086 {
1087 d.AABB aabb;
1088 d.GeomGetAABB(g2, out aabb);
1089 float tmp = vtmp.Z - sz * .18f;
1090
1091 if (aabb.MaxZ < tmp)
1092 {
1093 vtmp.X = curContact.pos.X - vtmp.X;
1094 vtmp.Y = curContact.pos.Y - vtmp.Y;
1095 vtmp.Z = -0.2f;
1096 vtmp.Normalize();
1097 curContact.normal.X = vtmp.X;
1098 curContact.normal.Y = vtmp.Y;
1099 curContact.normal.Z = vtmp.Z;
1100 }
1101 }
1102 }
1103 else
1104 p1.IsColliding = true;
1105 1036
1106 } 1037 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
1038 d.JointAttach(Joint, b1, b2);
1107 1039
1108 if (dop2foot) 1040 if (curContact.depth > maxContact.depth)
1109 { 1041 maxContact = curContact;
1110 float sz = p2.Size.Z;
1111 Vector3 vtmp = p2.Position;
1112 vtmp.Z -= sz * 0.5f;
1113 vtmp.Z += 0.5f;
1114 float ppos = vtmp.Z - curContact.pos.Z;
1115 if (ppos > 0f)
1116 {
1117 if (!p2.Flying)
1118 {
1119 float tmp = vtmp.Z - sz * .18f;
1120 vtmp.X = curContact.pos.X - vtmp.X;
1121 vtmp.Y = curContact.pos.Y - vtmp.Y;
1122 vtmp.Z = curContact.pos.Z - vtmp.Z;
1123 vtmp.Normalize();
1124 curContact.normal.X = vtmp.X;
1125 curContact.normal.Y = vtmp.Y;
1126 curContact.normal.Z = vtmp.Z;
1127 }
1128 }
1129// else
1130 p2.IsColliding = true;
1131 1042
1132 } 1043 if (curContact.depth < minContact.depth)
1044 minContact = curContact;
1133 } 1045 }
1134 } 1046 }
1135*/
1136 ncontacts++;
1137 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
1138 d.JointAttach(Joint, b1, b2);
1139
1140 if (++m_global_contactcount >= maxContactsbeforedeath)
1141 break;
1142 1047
1143 if (++i >= count) 1048 if (++i >= count)
1144 break; 1049 break;
1145 1050
1146 if (!GetCurContactGeom(i, ref curContact)) 1051 if (!GetCurContactGeom(i, ref curContact))
1147 break; 1052 break;
1148
1149 if (curContact.depth > maxDepthContact.PenetrationDepth)
1150 {
1151 maxDepthContact.Position.X = curContact.pos.X;
1152 maxDepthContact.Position.Y = curContact.pos.Y;
1153 maxDepthContact.Position.Z = curContact.pos.Z;
1154 maxDepthContact.SurfaceNormal.X = curContact.normal.X;
1155 maxDepthContact.SurfaceNormal.Y = curContact.normal.Y;
1156 maxDepthContact.SurfaceNormal.Z = curContact.normal.Z;
1157 maxDepthContact.PenetrationDepth = curContact.depth;
1158 }
1159 } 1053 }
1160 }
1161 1054
1162 if(ncontacts > 0) 1055 if (ncontacts > 0)
1163 collision_accounting_events(p1, p2, maxDepthContact);
1164
1165/*
1166 if (notskipedcount > geomContactPointsStartthrottle)
1167 { 1056 {
1168 // If there are more then 3 contact points, it's likely 1057 ContactPoint maxDepthContact = new ContactPoint(
1169 // that we've got a pile of objects, so ... 1058 new Vector3(maxContact.pos.X, maxContact.pos.Y, maxContact.pos.Z),
1170 // We don't want to send out hundreds of terse updates over and over again 1059 new Vector3(minContact.normal.X, minContact.normal.Y, minContact.normal.Z),
1171 // so lets throttle them and send them again after it's somewhat sorted out. 1060 maxContact.depth, FeetCollision
1172 this needs checking so out for now 1061 );
1173 if (b1 != IntPtr.Zero) 1062 collision_accounting_events(p1, p2, maxDepthContact);
1174 p1.ThrottleUpdates = true;
1175 if (b2 != IntPtr.Zero)
1176 p2.ThrottleUpdates = true;
1177
1178 } 1063 }
1179 */
1180 } 1064 }
1181 1065
1182 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) 1066 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
@@ -1267,10 +1151,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1267 // chr.CollidingGround = false; not done here 1151 // chr.CollidingGround = false; not done here
1268 chr.CollidingObj = false; 1152 chr.CollidingObj = false;
1269 // do colisions with static space 1153 // do colisions with static space
1270 d.SpaceCollide2(StaticSpace, chr.topbox, IntPtr.Zero, nearCallback); 1154 d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback);
1271 d.SpaceCollide2(StaticSpace, chr.midbox, IntPtr.Zero, nearCallback); 1155
1272 d.SpaceCollide2(StaticSpace, chr.feetbox, IntPtr.Zero, nearCallback); 1156 // chars with chars
1273 d.SpaceCollide2(StaticSpace, chr.bonebox, IntPtr.Zero, nearCallback); 1157 d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback);
1274 // no coll with gnd 1158 // no coll with gnd
1275 } 1159 }
1276 } 1160 }
@@ -1312,16 +1196,25 @@ namespace OpenSim.Region.Physics.OdePlugin
1312 m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); 1196 m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
1313 } 1197 }
1314 } 1198 }
1315 // finally colide active things amoung them 1199 // colide active amoung them
1316 try 1200 try
1317 { 1201 {
1318 d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); 1202 d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
1319 } 1203 }
1320 catch (AccessViolationException) 1204 catch (AccessViolationException)
1321 { 1205 {
1206 m_log.Warn("[PHYSICS]: Unable to collide Active with Characters space");
1207 }
1208 // and with chars
1209 try
1210 {
1211 d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback);
1212 }
1213 catch (AccessViolationException)
1214 {
1322 m_log.Warn("[PHYSICS]: Unable to collide in Active space"); 1215 m_log.Warn("[PHYSICS]: Unable to collide in Active space");
1323 } 1216 }
1324// _perloopContact.Clear(); 1217 // _perloopContact.Clear();
1325 } 1218 }
1326 1219
1327 #endregion 1220 #endregion
@@ -1357,13 +1250,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1357 1250
1358 #region Add/Remove Entities 1251 #region Add/Remove Entities
1359 1252
1360 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 1253 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
1361 { 1254 {
1362 Vector3 pos; 1255 Vector3 pos;
1363 pos.X = position.X; 1256 pos.X = position.X;
1364 pos.Y = position.Y; 1257 pos.Y = position.Y;
1365 pos.Z = position.Z; 1258 pos.Z = position.Z;
1366 OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avPIDD, avPIDP, avDensity, avMovementDivisorWalk, avMovementDivisorRun); 1259 OdeCharacter newAv = new OdeCharacter(localID,avName, this, pos, size, feetOffset, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
1367 newAv.Flying = isFlying; 1260 newAv.Flying = isFlying;
1368 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; 1261 newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
1369 1262
@@ -1806,7 +1699,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1806 foreach (OdeCharacter actor in _characters) 1699 foreach (OdeCharacter actor in _characters)
1807 { 1700 {
1808 if (actor != null) 1701 if (actor != null)
1809 actor.Move(ODE_STEPSIZE, defects); 1702 actor.Move(defects);
1810 } 1703 }
1811 if (defects.Count != 0) 1704 if (defects.Count != 0)
1812 { 1705 {
@@ -2817,5 +2710,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2817 } 2710 }
2818 return new List<ContactResult>(); 2711 return new List<ContactResult>();
2819 } 2712 }
2713
2714 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
2715 {
2716 Util.FireAndForget( delegate
2717 {
2718 ODESitAvatar sitAvatar = new ODESitAvatar(this, m_rayCastManager);
2719 if(sitAvatar != null)
2720 sitAvatar.Sit(actor, AbsolutePosition, CameraPosition, offset, AvatarSize, PhysicsSitResponse);
2721 });
2722 return 1;
2723 }
2724
2820 } 2725 }
2821} 2726}