diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Manager/PhysicsScene.cs | 21 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 583 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs | 260 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 254 |
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) |