aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-07-12 22:13:15 +0100
committerJustin Clark-Casey (justincc)2011-07-12 22:13:15 +0100
commit3e456163dd284fa04ab17465041a1a27f7b632b9 (patch)
treebaaa8a470f4afa7637e8919d41e161ec4215ce21 /OpenSim/Region/Physics
parenttemporarily fix the build break with building the OdePlugin tests assembly. (diff)
downloadopensim-SC-3e456163dd284fa04ab17465041a1a27f7b632b9.zip
opensim-SC-3e456163dd284fa04ab17465041a1a27f7b632b9.tar.gz
opensim-SC-3e456163dd284fa04ab17465041a1a27f7b632b9.tar.bz2
opensim-SC-3e456163dd284fa04ab17465041a1a27f7b632b9.tar.xz
Port implementation of llCastRay() from Aurora.
I haven't been able to test this since the viewer won't parse the llCastRay() function. Maybe some activation cap is missing. Could wait until it is activated by default in the viewer.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs24
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs92
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs28
3 files changed, 126 insertions, 18 deletions
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 13ea084..0de4626 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -37,6 +37,18 @@ namespace OpenSim.Region.Physics.Manager
37 public delegate void physicsCrash(); 37 public delegate void physicsCrash();
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);
41
42 /// <summary>
43 /// Contact result from a raycast.
44 /// </summary>
45 public struct ContactResult
46 {
47 public Vector3 Pos;
48 public float Depth;
49 public uint ConsumerID;
50 public Vector3 Normal;
51 }
40 52
41 public abstract class PhysicsScene 53 public abstract class PhysicsScene
42 { 54 {
@@ -61,7 +73,6 @@ namespace OpenSim.Region.Physics.Manager
61 } 73 }
62 } 74 }
63 75
64
65 public abstract void Initialise(IMesher meshmerizer, IConfigSource config); 76 public abstract void Initialise(IMesher meshmerizer, IConfigSource config);
66 77
67 public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); 78 public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying);
@@ -225,6 +236,17 @@ namespace OpenSim.Region.Physics.Manager
225 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); 236 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero);
226 } 237 }
227 238
239 public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
240 {
241 if (retMethod != null)
242 retMethod(new List<ContactResult>());
243 }
244
245 public virtual List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
246 {
247 return new List<ContactResult>();
248 }
249
228 private class NullPhysicsScene : PhysicsScene 250 private class NullPhysicsScene : PhysicsScene
229 { 251 {
230 private static int m_workIndicator; 252 private static int m_workIndicator;
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index ba77dae..6c2bdde 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -45,11 +45,16 @@ namespace OpenSim.Region.Physics.OdePlugin
45 public class ODERayCastRequestManager 45 public class ODERayCastRequestManager
46 { 46 {
47 /// <summary> 47 /// <summary>
48 /// Pending Raycast Requests 48 /// Pending raycast requests
49 /// </summary> 49 /// </summary>
50 protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>(); 50 protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>();
51 51
52 /// <summary> 52 /// <summary>
53 /// Pending ray requests
54 /// </summary>
55 protected List<ODERayRequest> m_PendingRayRequests = new List<ODERayRequest>();
56
57 /// <summary>
53 /// Scene that created this object. 58 /// Scene that created this object.
54 /// </summary> 59 /// </summary>
55 private OdeScene m_scene; 60 private OdeScene m_scene;
@@ -96,6 +101,29 @@ namespace OpenSim.Region.Physics.OdePlugin
96 } 101 }
97 102
98 /// <summary> 103 /// <summary>
104 /// Queues a raycast
105 /// </summary>
106 /// <param name="position">Origin of Ray</param>
107 /// <param name="direction">Ray normal</param>
108 /// <param name="length">Ray length</param>
109 /// <param name="count"></param>
110 /// <param name="retMethod">Return method to send the results</param>
111 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
112 {
113 lock (m_PendingRequests)
114 {
115 ODERayRequest req = new ODERayRequest();
116 req.callbackMethod = retMethod;
117 req.length = length;
118 req.Normal = direction;
119 req.Origin = position;
120 req.Count = count;
121
122 m_PendingRayRequests.Add(req);
123 }
124 }
125
126 /// <summary>
99 /// Process all queued raycast requests 127 /// Process all queued raycast requests
100 /// </summary> 128 /// </summary>
101 /// <returns>Time in MS the raycasts took to process.</returns> 129 /// <returns>Time in MS the raycasts took to process.</returns>
@@ -112,15 +140,23 @@ namespace OpenSim.Region.Physics.OdePlugin
112 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast 140 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
113 RayCast(reqs[i]); // if there isn't anyone to send results 141 RayCast(reqs[i]); // if there isn't anyone to send results
114 } 142 }
115 /* 143
116 foreach (ODERayCastRequest req in m_PendingRequests) 144 m_PendingRequests.Clear();
145 }
146 }
147
148 lock (m_PendingRayRequests)
149 {
150 if (m_PendingRayRequests.Count > 0)
151 {
152 ODERayRequest[] reqs = m_PendingRayRequests.ToArray();
153 for (int i = 0; i < reqs.Length; i++)
117 { 154 {
118 if (req.callbackMethod != null) // quick optimization here, don't raycast 155 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
119 RayCast(req); // if there isn't anyone to send results to 156 RayCast(reqs[i]); // if there isn't anyone to send results
120
121 } 157 }
122 */ 158
123 m_PendingRequests.Clear(); 159 m_PendingRayRequests.Clear();
124 } 160 }
125 } 161 }
126 162
@@ -146,7 +182,6 @@ namespace OpenSim.Region.Physics.OdePlugin
146 // Remove Ray 182 // Remove Ray
147 d.GeomDestroy(ray); 183 d.GeomDestroy(ray);
148 184
149
150 // Define default results 185 // Define default results
151 bool hitYN = false; 186 bool hitYN = false;
152 uint hitConsumerID = 0; 187 uint hitConsumerID = 0;
@@ -177,6 +212,31 @@ namespace OpenSim.Region.Physics.OdePlugin
177 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); 212 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
178 } 213 }
179 214
215 /// <summary>
216 /// Method that actually initiates the raycast
217 /// </summary>
218 /// <param name="req"></param>
219 private void RayCast(ODERayRequest req)
220 {
221 // Create the ray
222 IntPtr ray = d.CreateRay(m_scene.space, req.length);
223 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
224
225 // Collide test
226 d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
227
228 // Remove Ray
229 d.GeomDestroy(ray);
230
231 // Find closest contact and object.
232 lock (m_contactResults)
233 {
234 // Return results
235 if (req.callbackMethod != null)
236 req.callbackMethod(m_contactResults);
237 }
238 }
239
180 // This is the standard Near. Uses space AABBs to speed up detection. 240 // This is the standard Near. Uses space AABBs to speed up detection.
181 private void near(IntPtr space, IntPtr g1, IntPtr g2) 241 private void near(IntPtr space, IntPtr g1, IntPtr g2)
182 { 242 {
@@ -342,10 +402,7 @@ namespace OpenSim.Region.Physics.OdePlugin
342 m_contactResults.Add(collisionresult); 402 m_contactResults.Add(collisionresult);
343 } 403 }
344 } 404 }
345
346
347 } 405 }
348
349 } 406 }
350 407
351 /// <summary> 408 /// <summary>
@@ -365,11 +422,12 @@ namespace OpenSim.Region.Physics.OdePlugin
365 public RaycastCallback callbackMethod; 422 public RaycastCallback callbackMethod;
366 } 423 }
367 424
368 public struct ContactResult 425 public struct ODERayRequest
369 { 426 {
370 public Vector3 Pos; 427 public Vector3 Origin;
371 public float Depth;
372 public uint ConsumerID;
373 public Vector3 Normal; 428 public Vector3 Normal;
429 public int Count;
430 public float length;
431 public RayCallback callbackMethod;
374 } 432 }
375} 433} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 7b8a80c..ba8cba4 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -3736,6 +3736,34 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3736 } 3736 }
3737 } 3737 }
3738 3738
3739 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
3740 {
3741 if (retMethod != null)
3742 {
3743 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
3744 }
3745 }
3746
3747 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
3748 {
3749 ContactResult[] ourResults = null;
3750 RayCallback retMethod = delegate(List<ContactResult> results)
3751 {
3752 ourResults = new ContactResult[results.Count];
3753 results.CopyTo(ourResults, 0);
3754 };
3755 int waitTime = 0;
3756 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
3757 while (ourResults == null && waitTime < 1000)
3758 {
3759 Thread.Sleep(1);
3760 waitTime++;
3761 }
3762 if (ourResults == null)
3763 return new List<ContactResult> ();
3764 return new List<ContactResult>(ourResults);
3765 }
3766
3739#if USE_DRAWSTUFF 3767#if USE_DRAWSTUFF
3740 // Keyboard callback 3768 // Keyboard callback
3741 public void command(int cmd) 3769 public void command(int cmd)