aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs6
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs21
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs13
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs583
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs260
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs254
6 files changed, 805 insertions, 332 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 85f4ee5..2a39ffd 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2280,8 +2280,10 @@ namespace OpenSim.Region.Framework.Scenes
2280 2280
2281 ParentPart = part; 2281 ParentPart = part;
2282 ParentID = part.LocalId; 2282 ParentID = part.LocalId;
2283 2283 if(status == 3)
2284 Animator.TrySetMovementAnimation("SIT"); 2284 Animator.TrySetMovementAnimation("SIT_GROUND");
2285 else
2286 Animator.TrySetMovementAnimation("SIT");
2285 SendAvatarDataToAllAgents(); 2287 SendAvatarDataToAllAgents();
2286 2288
2287 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2289 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 86e0713..d24ab2a 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -38,6 +38,9 @@ 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 ProbeBoxCallback(List<ContactResult> list);
42 public delegate void ProbeSphereCallback(List<ContactResult> list);
43 public delegate void ProbePlaneCallback(List<ContactResult> list);
41 public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation); 44 public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
42 45
43 public delegate void JointMoved(PhysicsJoint joint); 46 public delegate void JointMoved(PhysicsJoint joint);
@@ -56,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager
56 volumedtc = 0x40, 59 volumedtc = 0x40,
57 60
58 // ray cast colision control (may only work for meshs) 61 // ray cast colision control (may only work for meshs)
62 ContactsUnImportant = 0x2000,
59 BackFaceCull = 0x4000, 63 BackFaceCull = 0x4000,
60 ClosestHit = 0x8000, 64 ClosestHit = 0x8000,
61 65
@@ -351,13 +355,26 @@ namespace OpenSim.Region.Physics.Manager
351 return false; 355 return false;
352 } 356 }
353 357
354 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
355 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
356 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) 358 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
357 { 359 {
358 return new List<ContactResult>(); 360 return new List<ContactResult>();
359 } 361 }
360 362
363 public virtual List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
364 {
365 return new List<ContactResult>();
366 }
367
368 public virtual List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
369 {
370 return new List<ContactResult>();
371 }
372
373 public virtual List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
374 {
375 return new List<ContactResult>();
376 }
377
361 public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) 378 public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
362 { 379 {
363 return 0; 380 return 0;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index bb04ea7..e1d694e 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -715,7 +715,17 @@ namespace OpenSim.Region.Physics.OdePlugin
715 Vector3 off = _velocity; 715 Vector3 off = _velocity;
716 float t = 0.5f * timeStep; 716 float t = 0.5f * timeStep;
717 off = off * t; 717 off = off * t;
718 d.Quaternion qtmp;
719 d.GeomCopyQuaternion(bbox, out qtmp);
720 Quaternion q;
721 q.X = qtmp.X;
722 q.Y = qtmp.Y;
723 q.Z = qtmp.Z;
724 q.W = qtmp.W;
725 off *= Quaternion.Conjugate(q);
726
718 d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z); 727 d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
728
719 off.X = 2.0f * (m_size.X + Math.Abs(off.X)); 729 off.X = 2.0f * (m_size.X + Math.Abs(off.X));
720 off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y)); 730 off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
721 off.Z = m_size.Z + 2.0f * Math.Abs(off.Z); 731 off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
@@ -741,6 +751,9 @@ namespace OpenSim.Region.Physics.OdePlugin
741 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); 751 d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
742 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); 752 d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
743 } 753 }
754 uint cat1 = d.GeomGetCategoryBits(bbox);
755 uint col1 = d.GeomGetCollideBits(bbox);
756
744 } 757 }
745 } 758 }
746 759
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 54a83c2..31757a9 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -56,8 +56,11 @@ namespace OpenSim.Region.Physics.OdePlugin
56 private OdeScene m_scene; 56 private OdeScene m_scene;
57 57
58 IntPtr ray; // the ray. we only need one for our lifetime 58 IntPtr ray; // the ray. we only need one for our lifetime
59 IntPtr Sphere;
60 IntPtr Box;
61 IntPtr Plane;
59 62
60 private const int ColisionContactGeomsPerTest = 5; 63 private int CollisionContactGeomsPerTest = 25;
61 private const int DefaultMaxCount = 25; 64 private const int DefaultMaxCount = 25;
62 private const int MaxTimePerCallMS = 30; 65 private const int MaxTimePerCallMS = 30;
63 66
@@ -65,6 +68,7 @@ namespace OpenSim.Region.Physics.OdePlugin
65 /// ODE near callback delegate 68 /// ODE near callback delegate
66 /// </summary> 69 /// </summary>
67 private d.NearCallback nearCallback; 70 private d.NearCallback nearCallback;
71 private d.NearCallback nearProbeCallback;
68 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
69 private List<ContactResult> m_contactResults = new List<ContactResult>(); 73 private List<ContactResult> m_contactResults = new List<ContactResult>();
70 private RayFilterFlags CurrentRayFilter; 74 private RayFilterFlags CurrentRayFilter;
@@ -74,169 +78,21 @@ namespace OpenSim.Region.Physics.OdePlugin
74 { 78 {
75 m_scene = pScene; 79 m_scene = pScene;
76 nearCallback = near; 80 nearCallback = near;
81 nearProbeCallback = nearProbe;
77 ray = d.CreateRay(IntPtr.Zero, 1.0f); 82 ray = d.CreateRay(IntPtr.Zero, 1.0f);
78 d.GeomSetCategoryBits(ray,0); 83 d.GeomSetCategoryBits(ray, 0);
84 Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
85 d.GeomSetCategoryBits(Box, 0);
86 Sphere = d.CreateSphere(IntPtr.Zero,1.0f);
87 d.GeomSetCategoryBits(Sphere, 0);
88 Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f);
89 d.GeomSetCategoryBits(Sphere, 0);
79 } 90 }
80 91
81 /// <summary> 92 public void QueueRequest(ODERayRequest req)
82 /// Queues request for a raycast to all world
83 /// </summary>
84 /// <param name="position">Origin of Ray</param>
85 /// <param name="direction">Ray direction</param>
86 /// <param name="length">Ray length</param>
87 /// <param name="retMethod">Return method to send the results</param>
88 public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
89 {
90 ODERayRequest req = new ODERayRequest();
91 req.geom = IntPtr.Zero;
92 req.callbackMethod = retMethod;
93 req.Count = DefaultMaxCount;
94 req.length = length;
95 req.Normal = direction;
96 req.Origin = position;
97 req.filter = RayFilterFlags.AllPrims;
98
99 m_PendingRequests.Enqueue(req);
100 }
101
102 /// <summary>
103 /// Queues request for a raycast to particular part
104 /// </summary>
105 /// <param name="position">Origin of Ray</param>
106 /// <param name="direction">Ray direction</param>
107 /// <param name="length">Ray length</param>
108 /// <param name="retMethod">Return method to send the results</param>
109 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
110 {
111 ODERayRequest req = new ODERayRequest();
112 req.geom = geom;
113 req.callbackMethod = retMethod;
114 req.length = length;
115 req.Normal = direction;
116 req.Origin = position;
117 req.Count = DefaultMaxCount;
118 req.filter = RayFilterFlags.AllPrims;
119
120 m_PendingRequests.Enqueue(req);
121 }
122
123 public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
124 {
125 ODERayRequest req = new ODERayRequest();
126 req.geom = IntPtr.Zero;
127 req.callbackMethod = retMethod;
128 req.Count = DefaultMaxCount;
129 req.length = length;
130 req.Normal = direction;
131 req.Origin = position;
132 req.filter = RayFilterFlags.AllPrims | RayFilterFlags.land;
133
134 m_PendingRequests.Enqueue(req);
135 }
136
137 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
138 {
139 ODERayRequest req = new ODERayRequest();
140 req.geom = geom;
141 req.callbackMethod = retMethod;
142 req.length = length;
143 req.Normal = direction;
144 req.Origin = position;
145 req.Count = DefaultMaxCount;
146 req.filter = RayFilterFlags.AllPrims;
147
148 m_PendingRequests.Enqueue(req);
149 }
150
151 /// <summary>
152 /// Queues a raycast
153 /// </summary>
154 /// <param name="position">Origin of Ray</param>
155 /// <param name="direction">Ray normal</param>
156 /// <param name="length">Ray length</param>
157 /// <param name="count"></param>
158 /// <param name="retMethod">Return method to send the results</param>
159 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
160 {
161 ODERayRequest req = new ODERayRequest();
162 req.geom = IntPtr.Zero;
163 req.callbackMethod = retMethod;
164 req.length = length;
165 req.Normal = direction;
166 req.Origin = position;
167 req.Count = count;
168 req.filter = RayFilterFlags.AllPrims;
169
170 m_PendingRequests.Enqueue(req);
171 }
172
173
174 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod)
175 {
176 ODERayRequest req = new ODERayRequest();
177 req.geom = IntPtr.Zero;
178 req.callbackMethod = retMethod;
179 req.length = length;
180 req.Normal = direction;
181 req.Origin = position;
182 req.Count = count;
183 req.filter = filter;
184
185 m_PendingRequests.Enqueue(req);
186 }
187
188 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
189 {
190 ODERayRequest req = new ODERayRequest();
191 req.geom = geom;
192 req.callbackMethod = retMethod;
193 req.length = length;
194 req.Normal = direction;
195 req.Origin = position;
196 req.Count = count;
197 req.filter = RayFilterFlags.AllPrims;
198
199 m_PendingRequests.Enqueue(req);
200 }
201
202 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count,RayFilterFlags flags, RayCallback retMethod)
203 {
204 ODERayRequest req = new ODERayRequest();
205 req.geom = geom;
206 req.callbackMethod = retMethod;
207 req.length = length;
208 req.Normal = direction;
209 req.Origin = position;
210 req.Count = count;
211 req.filter = flags;
212
213 m_PendingRequests.Enqueue(req);
214 }
215
216 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
217 {
218 ODERayRequest req = new ODERayRequest();
219 req.geom = IntPtr.Zero;
220 req.callbackMethod = retMethod;
221 req.length = length;
222 req.Normal = direction;
223 req.Origin = position;
224 req.Count = count;
225 req.filter = RayFilterFlags.AllPrims;
226
227 m_PendingRequests.Enqueue(req);
228 }
229
230 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
231 { 93 {
232 ODERayRequest req = new ODERayRequest(); 94 if (req.Count == 0)
233 req.geom = geom; 95 req.Count = DefaultMaxCount;
234 req.callbackMethod = retMethod;
235 req.length = length;
236 req.Normal = direction;
237 req.Origin = position;
238 req.Count = count;
239 req.filter = RayFilterFlags.AllPrims;
240 96
241 m_PendingRequests.Enqueue(req); 97 m_PendingRequests.Enqueue(req);
242 } 98 }
@@ -272,21 +128,64 @@ namespace OpenSim.Region.Physics.OdePlugin
272 CurrentRayFilter = req.filter; 128 CurrentRayFilter = req.filter;
273 CurrentMaxCount = req.Count; 129 CurrentMaxCount = req.Count;
274 130
131 CollisionContactGeomsPerTest = req.Count & 0xffff;
132
275 closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1); 133 closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
276 backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1); 134 backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
277 135
278 d.GeomRaySetLength(ray, req.length); 136 if (req.callbackMethod is ProbeBoxCallback)
279 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); 137 {
280 d.GeomRaySetParams(ray, 0, backfacecull); 138 if (CollisionContactGeomsPerTest > 80)
281 d.GeomRaySetClosestHit(ray, closestHit); 139 CollisionContactGeomsPerTest = 80;
140 d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z);
141 d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z);
142 d.Quaternion qtmp;
143 qtmp.X = req.orientation.X;
144 qtmp.Y = req.orientation.Y;
145 qtmp.Z = req.orientation.Z;
146 qtmp.W = req.orientation.W;
147 d.GeomSetOffsetWorldQuaternion(Box, ref qtmp);
148 }
149 else if (req.callbackMethod is ProbeSphereCallback)
150 {
151 if (CollisionContactGeomsPerTest > 80)
152 CollisionContactGeomsPerTest = 80;
153
154 d.GeomSphereSetRadius(Sphere, req.length);
155 d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z);
156 }
157 else if (req.callbackMethod is ProbePlaneCallback)
158 {
159 if (CollisionContactGeomsPerTest > 80)
160 CollisionContactGeomsPerTest = 80;
161
162 d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length);
163 }
164
165 else
166 {
167 if (CollisionContactGeomsPerTest > 25)
168 CollisionContactGeomsPerTest = 25;
282 169
283 if (req.callbackMethod is RaycastCallback) 170 d.GeomRaySetLength(ray, req.length);
284 // if we only want one get only one per colision pair saving memory 171 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
285 CurrentRayFilter |= RayFilterFlags.ClosestHit; 172 d.GeomRaySetParams(ray, 0, backfacecull);
173 d.GeomRaySetClosestHit(ray, closestHit);
174
175 if (req.callbackMethod is RaycastCallback)
176 // if we only want one get only one per Collision pair saving memory
177 CurrentRayFilter |= RayFilterFlags.ClosestHit;
178 }
179
180 if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0)
181 unchecked
182 {
183 CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
184 }
286 185
287 if (req.geom == IntPtr.Zero) 186 if (req.geom == IntPtr.Zero)
288 { 187 {
289 // translate ray filter to colision flags 188 // translate ray filter to Collision flags
290 catflags = 0; 189 catflags = 0;
291 if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0) 190 if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
292 catflags |= CollisionCategories.VolumeDtc; 191 catflags |= CollisionCategories.VolumeDtc;
@@ -303,15 +202,48 @@ namespace OpenSim.Region.Physics.OdePlugin
303 202
304 if (catflags != 0) 203 if (catflags != 0)
305 { 204 {
306 d.GeomSetCollideBits(ray, (uint)catflags); 205 if (req.callbackMethod is ProbeBoxCallback)
307 doSpaceRay(req); 206 {
207 catflags |= CollisionCategories.Space;
208 d.GeomSetCollideBits(Box, (uint)catflags);
209 d.GeomSetCategoryBits(Box, (uint)catflags);
210 doProbe(req, Box);
211 }
212 else if (req.callbackMethod is ProbeSphereCallback)
213 {
214 catflags |= CollisionCategories.Space;
215 d.GeomSetCollideBits(Sphere, (uint)catflags);
216 d.GeomSetCategoryBits(Sphere, (uint)catflags);
217 doProbe(req, Sphere);
218 }
219 else if (req.callbackMethod is ProbePlaneCallback)
220 {
221 catflags |= CollisionCategories.Space;
222 d.GeomSetCollideBits(Plane, (uint)catflags);
223 d.GeomSetCategoryBits(Plane, (uint)catflags);
224 doPlane(req);
225 }
226 else
227 {
228 d.GeomSetCollideBits(ray, (uint)catflags);
229 doSpaceRay(req);
230 }
308 } 231 }
309 } 232 }
310 else 233 else
311 { 234 {
312 // if we select a geom don't use filters 235 // if we select a geom don't use filters
313 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); 236
314 doGeomRay(req); 237 if (req.callbackMethod is ProbePlaneCallback)
238 {
239 d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
240 doPlane(req);
241 }
242 else
243 {
244 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
245 doGeomRay(req);
246 }
315 } 247 }
316 } 248 }
317 249
@@ -396,6 +328,61 @@ namespace OpenSim.Region.Physics.OdePlugin
396 } 328 }
397 } 329 }
398 330
331 private void doProbe(ODERayRequest req, IntPtr probe)
332 {
333 // Collide tests
334 if ((CurrentRayFilter & FilterActiveSpace) != 0)
335 {
336 d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
337 d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
338 }
339 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
340 d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
341 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
342 d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
343
344 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
345 lock (m_PendingRequests)
346 {
347 cresult.AddRange(m_contactResults);
348 m_contactResults.Clear();
349 }
350 if (req.callbackMethod is ProbeBoxCallback)
351 ((ProbeBoxCallback)req.callbackMethod)(cresult);
352 else if (req.callbackMethod is ProbeSphereCallback)
353 ((ProbeSphereCallback)req.callbackMethod)(cresult);
354 }
355
356 private void doPlane(ODERayRequest req)
357 {
358 // Collide tests
359 if (req.geom == IntPtr.Zero)
360 {
361 if ((CurrentRayFilter & FilterActiveSpace) != 0)
362 {
363 d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
364 d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
365 }
366 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
367 d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
368 if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
369 d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
370 }
371 else
372 {
373 d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback);
374 }
375
376 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
377 lock (m_PendingRequests)
378 {
379 cresult.AddRange(m_contactResults);
380 m_contactResults.Clear();
381 }
382
383 ((ProbePlaneCallback)req.callbackMethod)(cresult);
384 }
385
399 /// <summary> 386 /// <summary>
400 /// Method that actually initiates the raycast with a geom 387 /// Method that actually initiates the raycast with a geom
401 /// </summary> 388 /// </summary>
@@ -450,7 +437,7 @@ namespace OpenSim.Region.Physics.OdePlugin
450 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) 437 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
451 { 438 {
452 IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; 439 IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
453 if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest) 440 if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest)
454 return false; 441 return false;
455 442
456 IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); 443 IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
@@ -483,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin
483 int count = 0; 470 int count = 0;
484 try 471 try
485 { 472 {
486 count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); 473 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
487 } 474 }
488 catch (Exception e) 475 catch (Exception e)
489 { 476 {
@@ -494,84 +481,210 @@ namespace OpenSim.Region.Physics.OdePlugin
494 if (count == 0) 481 if (count == 0)
495 return; 482 return;
496 483
484 uint cat1 = d.GeomGetCategoryBits(g1);
485 uint cat2 = d.GeomGetCategoryBits(g2);
486 uint col1 = d.GeomGetCollideBits(g1);
487 uint col2 = d.GeomGetCollideBits(g2);
488
489
497 uint ID = 0; 490 uint ID = 0;
498 PhysicsActor p2 = null; 491 PhysicsActor p2 = null;
499 492
500 m_scene.actor_name_map.TryGetValue(g2, out p2); 493 m_scene.actor_name_map.TryGetValue(g2, out p2);
501 494
502 if (p2 == null) 495 if (p2 == null)
503 {
504 /*
505 string name;
506
507 if (!m_scene.geom_name_map.TryGetValue(g2, out name))
508 return;
509
510 if (name == "Terrain")
511 {
512 // land colision
513 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
514 return;
515 }
516 else if (name == "Water")
517 {
518 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
519 return;
520 }
521 else
522 return;
523 */
524 return; 496 return;
525 } 497
526 else 498 switch (p2.PhysicsActorType)
527 { 499 {
528 switch (p2.PhysicsActorType) 500 case (int)ActorTypes.Prim:
529 {
530 case (int)ActorTypes.Prim:
531 501
532 RayFilterFlags thisFlags; 502 RayFilterFlags thisFlags;
533 503
534 if (p2.IsPhysical) 504 if (p2.IsPhysical)
535 thisFlags = RayFilterFlags.physical; 505 thisFlags = RayFilterFlags.physical;
536 else 506 else
537 thisFlags = RayFilterFlags.nonphysical; 507 thisFlags = RayFilterFlags.nonphysical;
538 508
539 if (p2.Phantom) 509 if (p2.Phantom)
540 thisFlags |= RayFilterFlags.phantom; 510 thisFlags |= RayFilterFlags.phantom;
541 511
542 if (p2.IsVolumeDtc) 512 if (p2.IsVolumeDtc)
543 thisFlags |= RayFilterFlags.volumedtc; 513 thisFlags |= RayFilterFlags.volumedtc;
544 514
545 if ((thisFlags & CurrentRayFilter) == 0) 515 if ((thisFlags & CurrentRayFilter) == 0)
546 return; 516 return;
547 517
548 ID = ((OdePrim)p2).LocalID; 518 ID = ((OdePrim)p2).LocalID;
549 break; 519 break;
550 520
551 case (int)ActorTypes.Agent: 521 case (int)ActorTypes.Agent:
552 522
553 if ((CurrentRayFilter & RayFilterFlags.agent) == 0) 523 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
554 return; 524 return;
555 else 525 else
556 ID = ((OdeCharacter)p2).LocalID; 526 ID = ((OdeCharacter)p2).LocalID;
557 break; 527 break;
558 528
559 case (int)ActorTypes.Ground: 529 case (int)ActorTypes.Ground:
560 530
561 if ((CurrentRayFilter & RayFilterFlags.land) == 0) 531 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
562 return; 532 return;
563 break; 533 break;
564 534
565 case (int)ActorTypes.Water: 535 case (int)ActorTypes.Water:
566 536
567 if ((CurrentRayFilter & RayFilterFlags.water) == 0) 537 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
568 return; 538 return;
539 break;
540
541 default:
542 break;
543 }
544
545 d.ContactGeom curcontact = new d.ContactGeom();
546
547 // closestHit for now only works for meshs, so must do it for others
548 if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
549 {
550 // Loop all contacts, build results.
551 for (int i = 0; i < count; i++)
552 {
553 if (!GetCurContactGeom(i, ref curcontact))
569 break; 554 break;
570 555
571 default: 556 ContactResult collisionresult = new ContactResult();
557 collisionresult.ConsumerID = ID;
558 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
559 collisionresult.Depth = curcontact.depth;
560 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
561 curcontact.normal.Z);
562 lock (m_contactResults)
563 {
564 m_contactResults.Add(collisionresult);
565 if (m_contactResults.Count >= CurrentMaxCount)
566 return;
567 }
568 }
569 }
570 else
571 {
572 // keep only closest contact
573 ContactResult collisionresult = new ContactResult();
574 collisionresult.ConsumerID = ID;
575 collisionresult.Depth = float.MaxValue;
576
577 for (int i = 0; i < count; i++)
578 {
579 if (!GetCurContactGeom(i, ref curcontact))
572 break; 580 break;
581
582 if (curcontact.depth < collisionresult.Depth)
583 {
584 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
585 collisionresult.Depth = curcontact.depth;
586 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
587 curcontact.normal.Z);
588 }
589 }
590
591 if (collisionresult.Depth != float.MaxValue)
592 {
593 lock (m_contactResults)
594 m_contactResults.Add(collisionresult);
573 } 595 }
574 } 596 }
597 }
598
599 private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
600 {
601 if (g1 == IntPtr.Zero || g1 == g2)
602 return;
603
604 if (m_contactResults.Count >= CurrentMaxCount)
605 return;
606
607 if (d.GeomIsSpace(g1))
608 {
609 try
610 {
611 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
612 }
613 catch (Exception e)
614 {
615 m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
616 }
617 return;
618 }
619
620 int count = 0;
621 try
622 {
623 count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
624 }
625 catch (Exception e)
626 {
627 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
628 return;
629 }
630
631 if (count == 0)
632 return;
633
634 uint ID = 0;
635 PhysicsActor p1 = null;
636
637 m_scene.actor_name_map.TryGetValue(g1, out p1);
638
639 if (p1 == null)
640 return;
641
642 switch (p1.PhysicsActorType)
643 {
644 case (int)ActorTypes.Prim:
645
646 RayFilterFlags thisFlags;
647
648 if (p1.IsPhysical)
649 thisFlags = RayFilterFlags.physical;
650 else
651 thisFlags = RayFilterFlags.nonphysical;
652
653 if (p1.Phantom)
654 thisFlags |= RayFilterFlags.phantom;
655
656 if (p1.IsVolumeDtc)
657 thisFlags |= RayFilterFlags.volumedtc;
658
659 if ((thisFlags & CurrentRayFilter) == 0)
660 return;
661
662 ID = ((OdePrim)p1).LocalID;
663 break;
664
665 case (int)ActorTypes.Agent:
666
667 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
668 return;
669 else
670 ID = ((OdeCharacter)p1).LocalID;
671 break;
672
673 case (int)ActorTypes.Ground:
674
675 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
676 return;
677 break;
678
679 case (int)ActorTypes.Water:
680
681 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
682 return;
683 break;
684
685 default:
686 break;
687 }
575 688
576 d.ContactGeom curcontact = new d.ContactGeom(); 689 d.ContactGeom curcontact = new d.ContactGeom();
577 690
@@ -638,6 +751,21 @@ namespace OpenSim.Region.Physics.OdePlugin
638 d.GeomDestroy(ray); 751 d.GeomDestroy(ray);
639 ray = IntPtr.Zero; 752 ray = IntPtr.Zero;
640 } 753 }
754 if (Box != IntPtr.Zero)
755 {
756 d.GeomDestroy(Box);
757 Box = IntPtr.Zero;
758 }
759 if (Sphere != IntPtr.Zero)
760 {
761 d.GeomDestroy(Sphere);
762 Sphere = IntPtr.Zero;
763 }
764 if (Plane != IntPtr.Zero)
765 {
766 d.GeomDestroy(Plane);
767 Plane = IntPtr.Zero;
768 }
641 } 769 }
642 } 770 }
643 771
@@ -650,5 +778,6 @@ namespace OpenSim.Region.Physics.OdePlugin
650 public float length; 778 public float length;
651 public object callbackMethod; 779 public object callbackMethod;
652 public RayFilterFlags filter; 780 public RayFilterFlags filter;
781 public Quaternion orientation;
653 } 782 }
654} \ No newline at end of file 783} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
index fd3a3ba..9e23763 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
@@ -54,6 +54,20 @@ namespace OpenSim.Region.Physics.OdePlugin
54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f); 54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
55 private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit; 55 private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit;
56 56
57 private void RotAroundZ(float x, float y, ref Quaternion ori)
58 {
59 double ang = Math.Atan2(y, x);
60 ang *= 0.5d;
61 float s = (float)Math.Sin(ang);
62 float c = (float)Math.Cos(ang);
63
64 ori.X = 0;
65 ori.Y = 0;
66 ori.Z = s;
67 ori.W = c;
68 }
69
70
57 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse) 71 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
58 { 72 {
59 if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero) 73 if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero)
@@ -72,7 +86,7 @@ namespace OpenSim.Region.Physics.OdePlugin
72 86
73 87
74 d.AABB aabb; 88 d.AABB aabb;
75 Quaternion ori; 89 Quaternion ori = Quaternion.Identity;
76 d.Quaternion qtmp; 90 d.Quaternion qtmp;
77 d.GeomCopyQuaternion(geom, out qtmp); 91 d.GeomCopyQuaternion(geom, out qtmp);
78 Quaternion geomOri; 92 Quaternion geomOri;
@@ -86,9 +100,14 @@ namespace OpenSim.Region.Physics.OdePlugin
86 geomInvOri.Z = -qtmp.Z; 100 geomInvOri.Z = -qtmp.Z;
87 geomInvOri.W = qtmp.W; 101 geomInvOri.W = qtmp.W;
88 102
89 Vector3 target = geopos + offset; 103 Vector3 rayDir = geopos + offset - avCameraPosition;
90 Vector3 rayDir = target - avCameraPosition;
91 float raylen = rayDir.Length(); 104 float raylen = rayDir.Length();
105 if (raylen < 0.001f)
106 {
107 PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
108 return;
109 }
110
92 float t = 1 / raylen; 111 float t = 1 / raylen;
93 rayDir.X *= t; 112 rayDir.X *= t;
94 rayDir.Y *= t; 113 rayDir.Y *= t;
@@ -98,9 +117,9 @@ namespace OpenSim.Region.Physics.OdePlugin
98 List<ContactResult> rayResults; 117 List<ContactResult> rayResults;
99 118
100 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags); 119 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags);
101 if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID) 120 if (rayResults.Count == 0)
102 { 121 {
103 d.GeomGetAABB(geom,out aabb); 122 d.GeomGetAABB(geom, out aabb);
104 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z); 123 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
105 ori = geomInvOri; 124 ori = geomInvOri;
106 offset *= geomInvOri; 125 offset *= geomInvOri;
@@ -109,44 +128,45 @@ namespace OpenSim.Region.Physics.OdePlugin
109 return; 128 return;
110 } 129 }
111 130
112
113 offset = rayResults[0].Pos - geopos; 131 offset = rayResults[0].Pos - geopos;
114 double ang;
115 float s;
116 float c;
117 132
118 d.GeomClassID geoclass = d.GeomGetClass(geom); 133 d.GeomClassID geoclass = d.GeomGetClass(geom);
119 134
120 if (geoclass == d.GeomClassID.SphereClass) 135 if (geoclass == d.GeomClassID.SphereClass)
121 { 136 {
122 float r = d.GeomSphereGetRadius(geom); 137 int status = 1;
138 float r = d.GeomSphereGetRadius(geom);
123 139
124 offset.Normalize(); 140 offset.Normalize();
125 offset *= r; 141 offset *= r;
126 142
127 ang = Math.Atan2(offset.Y, offset.X); 143 RotAroundZ(offset.X, offset.Y, ref ori);
128 ang *= 0.5d;
129 s = (float)Math.Sin(ang);
130 c = (float)Math.Cos(ang);
131
132 ori = new Quaternion(0, 0, s, c);
133 144
134 if (r < 0.4f) 145 if (r < 0.4f)
135 { 146 {
136 offset = new Vector3(0, 0, r); 147 offset = new Vector3(0, 0, r);
137 } 148 }
138 else if (offset.Z < 0.4f) 149 else
139 { 150 {
140 t = offset.Z; 151 if (offset.Z < 0.4f)
141 float rsq = r * r; 152 {
142 153 t = offset.Z;
143 t = 1.0f / (rsq - t * t); 154 float rsq = r * r;
144 offset.X *= t; 155
145 offset.Y *= t; 156 t = 1.0f / (rsq - t * t);
146 offset.Z = 0.4f; 157 offset.X *= t;
147 t = rsq - 0.16f; 158 offset.Y *= t;
148 offset.X *= t; 159 offset.Z = 0.4f;
149 offset.Y *= t; 160 t = rsq - 0.16f;
161 offset.X *= t;
162 offset.Y *= t;
163 }
164 else if (r > 0.8f && offset.Z > 0.8f * r)
165 {
166 status = 3;
167 avOffset.X = -avOffset.X;
168 avOffset.Z += 0.4f;
169 }
150 } 170 }
151 171
152 offset += avOffset * ori; 172 offset += avOffset * ori;
@@ -154,27 +174,189 @@ namespace OpenSim.Region.Physics.OdePlugin
154 ori = geomInvOri * ori; 174 ori = geomInvOri * ori;
155 offset *= geomInvOri; 175 offset *= geomInvOri;
156 176
157 PhysicsSitResponse(1, actor.LocalID, offset, ori); 177 PhysicsSitResponse(status, actor.LocalID, offset, ori);
158 return; 178 return;
159 } 179 }
160 180
161/* 181 Vector3 norm = rayResults[0].Normal;
162 // contact normals aren't reliable on meshs or sculpts it seems
163 Vector3 norm = rayResults[0].Normal;
164 182
165 if (norm.Z < 0) 183 if (norm.Z < -0.4f)
184 {
185 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
186 return;
187 }
188
189 float SitNormX = -rayDir.X;
190 float SitNormY = -rayDir.Y;
191
192 Vector3 pivot = geopos + offset;
193
194 float edgeNormalX = norm.X;
195 float edgeNormalY = norm.Y;
196 float edgeDirX = -rayDir.X;
197 float edgeDirY = -rayDir.Y;
198 Vector3 edgePos = rayResults[0].Pos;
199 float edgeDist = float.MaxValue;
200
201 bool foundEdge = false;
202
203 if (norm.Z < 0.5f)
204 {
205 float rayDist = 4.0f;
206 float curEdgeDist = 0.0f;
207 pivot = geopos + offset;
208
209 for (int i = 0; i < 6; i++)
166 { 210 {
167 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); 211 pivot.X -= 0.005f * norm.X;
212 pivot.Y -= 0.005f * norm.Y;
213 pivot.Z -= 0.005f * norm.Z;
214
215 rayDir.X = -norm.X * norm.Z;
216 rayDir.Y = -norm.Y * norm.Z;
217 rayDir.Z = 1.0f - norm.Z * norm.Z;
218 rayDir.Normalize();
219
220 rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
221 if (rayResults.Count == 0)
222 break;
223
224 curEdgeDist += rayResults[0].Depth;
225
226 if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
227 {
228 rayDist -= rayResults[0].Depth;
229 if (rayDist < 0f)
230 break;
231
232 pivot = rayResults[0].Pos;
233 norm = rayResults[0].Normal;
234 edgeNormalX = norm.X;
235 edgeNormalY = norm.Y;
236 edgeDirX = rayDir.X;
237 edgeDirY = rayDir.Y;
238 }
239 else
240 {
241 foundEdge = true;
242 if (curEdgeDist < edgeDist)
243 {
244 edgeDist = curEdgeDist;
245 edgePos = rayResults[0].Pos;
246 }
247 break;
248 }
249 }
250
251 if (!foundEdge)
252 {
253 PhysicsSitResponse(0, actor.LocalID, offset, ori);
168 return; 254 return;
169 } 255 }
170*/ 256 avOffset.X *= 0.5f;
257 }
171 258
172 ang = Math.Atan2(-rayDir.Y, -rayDir.X); 259 else if (norm.Z > 0.866f)
173 ang *= 0.5d; 260 {
174 s = (float)Math.Sin(ang); 261 float toCamBaseX = avCameraPosition.X - pivot.X;
175 c = (float)Math.Cos(ang); 262 float toCamBaseY = avCameraPosition.Y - pivot.Y;
263 float toCamX = toCamBaseX;
264 float toCamY = toCamBaseY;
265
266 for (int j = 0; j < 4; j++)
267 {
268 float rayDist = 1.0f;
269 float curEdgeDist = 0.0f;
270 pivot = geopos + offset;
271
272 for (int i = 0; i < 3; i++)
273 {
274 pivot.Z -= 0.005f;
275 rayDir.X = toCamX;
276 rayDir.Y = toCamY;
277 rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
278 rayDir.Normalize();
279
280 rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
281 if (rayResults.Count == 0)
282 break;
283
284 curEdgeDist += rayResults[0].Depth;
285
286 if (rayResults[0].Normal.Z > 0.5f)
287 {
288 rayDist -= rayResults[0].Depth;
289 if (rayDist < 0f)
290 break;
291
292 pivot = rayResults[0].Pos;
293 norm = rayResults[0].Normal;
294 }
295 else
296 {
297 foundEdge = true;
298 if (curEdgeDist < edgeDist)
299 {
300 edgeDist = curEdgeDist;
301 edgeNormalX = rayResults[0].Normal.X;
302 edgeNormalY = rayResults[0].Normal.Y;
303 edgeDirX = rayDir.X;
304 edgeDirY = rayDir.Y;
305 edgePos = rayResults[0].Pos;
306 }
307 break;
308 }
309 }
310 if (foundEdge && edgeDist < 0.2f)
311 break;
312
313 switch (j)
314 {
315 case 0:
316 toCamX = -toCamBaseY;
317 toCamY = toCamBaseX;
318 break;
319 case 1:
320 toCamX = toCamBaseY;
321 toCamY = -toCamBaseX;
322 break;
323 case 2:
324 toCamX = -toCamBaseX;
325 toCamY = -toCamBaseY;
326 break;
327 default:
328 break;
329 }
330 }
331
332 if (!foundEdge)
333 {
334 avOffset.X = -avOffset.X;
335 avOffset.Z += 0.4f;
336
337 RotAroundZ(SitNormX, SitNormY, ref ori);
338
339 offset += avOffset * ori;
340
341 ori = geomInvOri * ori;
342 offset *= geomInvOri;
343
344 PhysicsSitResponse(3, actor.LocalID, offset, ori);
345 return;
346 }
347 avOffset.X *= 0.5f;
348 }
349
350 SitNormX = edgeNormalX;
351 SitNormY = edgeNormalY;
352 offset = edgePos - geopos;
353 if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0)
354 {
355 SitNormX = -SitNormX;
356 SitNormY = -SitNormY;
357 }
176 358
177 ori = new Quaternion(0, 0, s, c); 359 RotAroundZ(SitNormX, SitNormY, ref ori);
178 360
179 offset += avOffset * ori; 361 offset += avOffset * ori;
180 362
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index d344d4d..d045b59 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -2579,7 +2579,16 @@ namespace OpenSim.Region.Physics.OdePlugin
2579 { 2579 {
2580 if (retMethod != null) 2580 if (retMethod != null)
2581 { 2581 {
2582 m_rayCastManager.QueueRequest(position, direction, length, retMethod); 2582 ODERayRequest req = new ODERayRequest();
2583 req.geom = IntPtr.Zero;
2584 req.callbackMethod = retMethod;
2585 req.length = length;
2586 req.Normal = direction;
2587 req.Origin = position;
2588 req.Count = 0;
2589 req.filter = RayFilterFlags.All;
2590
2591 m_rayCastManager.QueueRequest(req);
2583 } 2592 }
2584 } 2593 }
2585 2594
@@ -2587,29 +2596,51 @@ namespace OpenSim.Region.Physics.OdePlugin
2587 { 2596 {
2588 if (retMethod != null) 2597 if (retMethod != null)
2589 { 2598 {
2590 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); 2599 ODERayRequest req = new ODERayRequest();
2600 req.geom = IntPtr.Zero;
2601 req.callbackMethod = retMethod;
2602 req.length = length;
2603 req.Normal = direction;
2604 req.Origin = position;
2605 req.Count = Count;
2606 req.filter = RayFilterFlags.All;
2607
2608 m_rayCastManager.QueueRequest(req);
2591 } 2609 }
2592 } 2610 }
2593 2611
2594 // don't like this 2612
2595 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) 2613 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
2596 { 2614 {
2597 ContactResult[] ourResults = null; 2615 List<ContactResult> ourresults = new List<ContactResult>();
2616 object SyncObject = new object();
2617
2598 RayCallback retMethod = delegate(List<ContactResult> results) 2618 RayCallback retMethod = delegate(List<ContactResult> results)
2599 { 2619 {
2600 ourResults = new ContactResult[results.Count]; 2620 lock (SyncObject)
2601 results.CopyTo(ourResults, 0); 2621 {
2622 ourresults = results;
2623 Monitor.PulseAll(SyncObject);
2624 }
2602 }; 2625 };
2603 int waitTime = 0; 2626
2604 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); 2627 ODERayRequest req = new ODERayRequest();
2605 while (ourResults == null && waitTime < 1000) 2628 req.geom = IntPtr.Zero;
2629 req.callbackMethod = retMethod;
2630 req.length = length;
2631 req.Normal = direction;
2632 req.Origin = position;
2633 req.Count = Count;
2634 req.filter = RayFilterFlags.All;
2635
2636 lock (SyncObject)
2606 { 2637 {
2607 Thread.Sleep(1); 2638 m_rayCastManager.QueueRequest(req);
2608 waitTime++; 2639 if (!Monitor.Wait(SyncObject, 500))
2640 return null;
2641 else
2642 return ourresults;
2609 } 2643 }
2610 if (ourResults == null)
2611 return new List<ContactResult>();
2612 return new List<ContactResult>(ourResults);
2613 } 2644 }
2614 2645
2615 public override bool SuportsRaycastWorldFiltered() 2646 public override bool SuportsRaycastWorldFiltered()
@@ -2631,9 +2662,18 @@ namespace OpenSim.Region.Physics.OdePlugin
2631 } 2662 }
2632 }; 2663 };
2633 2664
2665 ODERayRequest req = new ODERayRequest();
2666 req.geom = IntPtr.Zero;
2667 req.callbackMethod = retMethod;
2668 req.length = length;
2669 req.Normal = direction;
2670 req.Origin = position;
2671 req.Count = Count;
2672 req.filter = filter;
2673
2634 lock (SyncObject) 2674 lock (SyncObject)
2635 { 2675 {
2636 m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod); 2676 m_rayCastManager.QueueRequest(req);
2637 if (!Monitor.Wait(SyncObject, 500)) 2677 if (!Monitor.Wait(SyncObject, 500))
2638 return null; 2678 return null;
2639 else 2679 else
@@ -2641,73 +2681,163 @@ namespace OpenSim.Region.Physics.OdePlugin
2641 } 2681 }
2642 } 2682 }
2643 2683
2644 public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) 2684 public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
2645 { 2685 {
2646 if (retMethod != null && actor !=null) 2686 if (actor == null)
2687 return new List<ContactResult>();
2688
2689 IntPtr geom;
2690 if (actor is OdePrim)
2691 geom = ((OdePrim)actor).prim_geom;
2692 else if (actor is OdeCharacter)
2693 geom = ((OdePrim)actor).prim_geom;
2694 else
2695 return new List<ContactResult>();
2696
2697 if (geom == IntPtr.Zero)
2698 return new List<ContactResult>();
2699
2700 List<ContactResult> ourResults = null;
2701 object SyncObject = new object();
2702
2703 RayCallback retMethod = delegate(List<ContactResult> results)
2647 { 2704 {
2648 IntPtr geom; 2705 lock (SyncObject)
2649 if (actor is OdePrim) 2706 {
2650 geom = ((OdePrim)actor).prim_geom; 2707 ourResults = results;
2651 else if (actor is OdeCharacter) 2708 Monitor.PulseAll(SyncObject);
2652 geom = ((OdePrim)actor).prim_geom; 2709 }
2653 else 2710 };
2654 return; 2711
2655 if (geom == IntPtr.Zero) 2712 ODERayRequest req = new ODERayRequest();
2656 return; 2713 req.geom = geom;
2657 m_rayCastManager.QueueRequest(geom, position, direction, length, retMethod); 2714 req.callbackMethod = retMethod;
2715 req.length = length;
2716 req.Normal = direction;
2717 req.Origin = position;
2718 req.Count = Count;
2719 req.filter = flags;
2720
2721 lock (SyncObject)
2722 {
2723 m_rayCastManager.QueueRequest(req);
2724 if (!Monitor.Wait(SyncObject, 500))
2725 return new List<ContactResult>();
2658 } 2726 }
2727
2728 if (ourResults == null)
2729 return new List<ContactResult>();
2730 return ourResults;
2659 } 2731 }
2660 2732
2661 public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) 2733 public override List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
2662 { 2734 {
2663 if (retMethod != null && actor != null) 2735 List<ContactResult> ourResults = null;
2736 object SyncObject = new object();
2737
2738 ProbeBoxCallback retMethod = delegate(List<ContactResult> results)
2664 { 2739 {
2665 IntPtr geom; 2740 lock (SyncObject)
2666 if (actor is OdePrim) 2741 {
2667 geom = ((OdePrim)actor).prim_geom; 2742 ourResults = results;
2668 else if (actor is OdeCharacter) 2743 Monitor.PulseAll(SyncObject);
2669 geom = ((OdePrim)actor).prim_geom; 2744 }
2670 else 2745 };
2671 return; 2746
2672 if (geom == IntPtr.Zero) 2747 ODERayRequest req = new ODERayRequest();
2673 return; 2748 req.geom = IntPtr.Zero;
2749 req.callbackMethod = retMethod;
2750 req.Normal = size;
2751 req.Origin = position;
2752 req.orientation = orientation;
2753 req.Count = Count;
2754 req.filter = flags;
2674 2755
2675 m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod); 2756 lock (SyncObject)
2757 {
2758 m_rayCastManager.QueueRequest(req);
2759 if (!Monitor.Wait(SyncObject, 500))
2760 return new List<ContactResult>();
2676 } 2761 }
2762
2763 if (ourResults == null)
2764 return new List<ContactResult>();
2765 return ourResults;
2677 } 2766 }
2678 2767
2679 public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) 2768 public override List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
2769 {
2770 List<ContactResult> ourResults = null;
2771 object SyncObject = new object();
2772
2773 ProbeSphereCallback retMethod = delegate(List<ContactResult> results)
2774 {
2775 ourResults = results;
2776 Monitor.PulseAll(SyncObject);
2777 };
2778
2779 ODERayRequest req = new ODERayRequest();
2780 req.geom = IntPtr.Zero;
2781 req.callbackMethod = retMethod;
2782 req.length = radius;
2783 req.Origin = position;
2784 req.Count = Count;
2785 req.filter = flags;
2786
2787
2788 lock (SyncObject)
2789 {
2790 m_rayCastManager.QueueRequest(req);
2791 if (!Monitor.Wait(SyncObject, 500))
2792 return new List<ContactResult>();
2793 }
2794
2795 if (ourResults == null)
2796 return new List<ContactResult>();
2797 return ourResults;
2798 }
2799
2800 public override List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
2680 { 2801 {
2802 IntPtr geom = IntPtr.Zero;;
2803
2681 if (actor != null) 2804 if (actor != null)
2682 { 2805 {
2683 IntPtr geom;
2684 if (actor is OdePrim) 2806 if (actor is OdePrim)
2685 geom = ((OdePrim)actor).prim_geom; 2807 geom = ((OdePrim)actor).prim_geom;
2686 else if (actor is OdeCharacter) 2808 else if (actor is OdeCharacter)
2687 geom = ((OdePrim)actor).prim_geom; 2809 geom = ((OdePrim)actor).prim_geom;
2688 else 2810 }
2689 return new List<ContactResult>();
2690 if (geom == IntPtr.Zero)
2691 return new List<ContactResult>();
2692 2811
2693 ContactResult[] ourResults = null; 2812 List<ContactResult> ourResults = null;
2694 RayCallback retMethod = delegate(List<ContactResult> results) 2813 object SyncObject = new object();
2695 { 2814
2696 ourResults = new ContactResult[results.Count]; 2815 ProbePlaneCallback retMethod = delegate(List<ContactResult> results)
2697 results.CopyTo(ourResults, 0); 2816 {
2698 }; 2817 ourResults = results;
2699 int waitTime = 0; 2818 Monitor.PulseAll(SyncObject);
2700 m_rayCastManager.QueueRequest(geom,position, direction, length, Count, flags, retMethod); 2819 };
2701 while (ourResults == null && waitTime < 1000) 2820
2702 { 2821 ODERayRequest req = new ODERayRequest();
2703 Thread.Sleep(1); 2822 req.geom = geom;
2704 waitTime++; 2823 req.callbackMethod = retMethod;
2705 } 2824 req.length = plane.W;
2706 if (ourResults == null) 2825 req.Normal.X = plane.X;
2826 req.Normal.Y = plane.Y;
2827 req.Normal.Z = plane.Z;
2828 req.Count = Count;
2829 req.filter = flags;
2830
2831 lock (SyncObject)
2832 {
2833 m_rayCastManager.QueueRequest(req);
2834 if (!Monitor.Wait(SyncObject, 500))
2707 return new List<ContactResult>(); 2835 return new List<ContactResult>();
2708 return new List<ContactResult>(ourResults);
2709 } 2836 }
2710 return new List<ContactResult>(); 2837
2838 if (ourResults == null)
2839 return new List<ContactResult>();
2840 return ourResults;
2711 } 2841 }
2712 2842
2713 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) 2843 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)