diff options
Diffstat (limited to 'OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs')
-rw-r--r-- | OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs new file mode 100644 index 0000000..1c0ad20 --- /dev/null +++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs | |||
@@ -0,0 +1,420 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | |||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | |||
35 | using OpenSim.Framework; | ||
36 | using OpenMetaverse; | ||
37 | |||
38 | namespace OpenSim.Region.PhysicsModules.SharedBase | ||
39 | { | ||
40 | public delegate void physicsCrash(); | ||
41 | |||
42 | public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); | ||
43 | public delegate void RayCallback(List<ContactResult> list); | ||
44 | public delegate void ProbeBoxCallback(List<ContactResult> list); | ||
45 | public delegate void ProbeSphereCallback(List<ContactResult> list); | ||
46 | public delegate void ProbePlaneCallback(List<ContactResult> list); | ||
47 | public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation); | ||
48 | |||
49 | public delegate void JointMoved(PhysicsJoint joint); | ||
50 | public delegate void JointDeactivated(PhysicsJoint joint); | ||
51 | public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" | ||
52 | |||
53 | public enum RayFilterFlags : ushort | ||
54 | { | ||
55 | // the flags | ||
56 | water = 0x01, | ||
57 | land = 0x02, | ||
58 | agent = 0x04, | ||
59 | nonphysical = 0x08, | ||
60 | physical = 0x10, | ||
61 | phantom = 0x20, | ||
62 | volumedtc = 0x40, | ||
63 | |||
64 | // ray cast colision control (may only work for meshs) | ||
65 | ContactsUnImportant = 0x2000, | ||
66 | BackFaceCull = 0x4000, | ||
67 | ClosestHit = 0x8000, | ||
68 | |||
69 | // some combinations | ||
70 | LSLPhantom = phantom | volumedtc, | ||
71 | PrimsNonPhantom = nonphysical | physical, | ||
72 | PrimsNonPhantomAgents = nonphysical | physical | agent, | ||
73 | |||
74 | AllPrims = nonphysical | phantom | volumedtc | physical, | ||
75 | AllButLand = agent | nonphysical | physical | phantom | volumedtc, | ||
76 | |||
77 | ClosestAndBackCull = ClosestHit | BackFaceCull, | ||
78 | |||
79 | All = 0x3f | ||
80 | } | ||
81 | |||
82 | public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback); | ||
83 | public delegate void AssetReceivedDelegate(AssetBase asset); | ||
84 | |||
85 | /// <summary> | ||
86 | /// Contact result from a raycast. | ||
87 | /// </summary> | ||
88 | public struct ContactResult | ||
89 | { | ||
90 | public Vector3 Pos; | ||
91 | public float Depth; | ||
92 | public uint ConsumerID; | ||
93 | public Vector3 Normal; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | public abstract class PhysicsScene | ||
99 | { | ||
100 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
101 | |||
102 | /// <summary> | ||
103 | /// A unique identifying string for this instance of the physics engine. | ||
104 | /// Useful in debug messages to distinguish one OdeScene instance from another. | ||
105 | /// Usually set to include the region name that the physics engine is acting for. | ||
106 | /// </summary> | ||
107 | public string PhysicsSceneName { get; protected set; } | ||
108 | |||
109 | /// <summary> | ||
110 | /// A string identifying the family of this physics engine. Most common values returned | ||
111 | /// are "OpenDynamicsEngine" and "BulletSim" but others are possible. | ||
112 | /// </summary> | ||
113 | public string EngineType { get; protected set; } | ||
114 | |||
115 | // The only thing that should register for this event is the SceneGraph | ||
116 | // Anything else could cause problems. | ||
117 | public event physicsCrash OnPhysicsCrash; | ||
118 | |||
119 | public static PhysicsScene Null | ||
120 | { | ||
121 | get { return new NullPhysicsScene(); } | ||
122 | } | ||
123 | |||
124 | public RequestAssetDelegate RequestAssetMethod { get; set; } | ||
125 | |||
126 | protected void Initialise(RequestAssetDelegate m, float[] terrain, float waterHeight) | ||
127 | { | ||
128 | RequestAssetMethod = m; | ||
129 | SetTerrain(terrain); | ||
130 | SetWaterLevel(waterHeight); | ||
131 | |||
132 | } | ||
133 | |||
134 | public virtual void TriggerPhysicsBasedRestart() | ||
135 | { | ||
136 | physicsCrash handler = OnPhysicsCrash; | ||
137 | if (handler != null) | ||
138 | { | ||
139 | OnPhysicsCrash(); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | /// <summary> | ||
144 | /// Add an avatar | ||
145 | /// </summary> | ||
146 | /// <param name="avName"></param> | ||
147 | /// <param name="position"></param> | ||
148 | /// <param name="velocity"></param> | ||
149 | /// <param name="size"></param> | ||
150 | /// <param name="isFlying"></param> | ||
151 | /// <returns></returns> | ||
152 | |||
153 | public abstract PhysicsActor AddAvatar( | ||
154 | string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying); | ||
155 | |||
156 | /// <summary> | ||
157 | /// Add an avatar | ||
158 | /// </summary> | ||
159 | /// <param name="localID"></param> | ||
160 | /// <param name="avName"></param> | ||
161 | /// <param name="position"></param> | ||
162 | /// <param name="velocity"></param> | ||
163 | /// <param name="size"></param> | ||
164 | /// <param name="isFlying"></param> | ||
165 | /// <returns></returns> | ||
166 | public virtual PhysicsActor AddAvatar( | ||
167 | uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) | ||
168 | { | ||
169 | PhysicsActor ret = AddAvatar(avName, position, velocity, size, isFlying); | ||
170 | |||
171 | if (ret != null) | ||
172 | ret.LocalID = localID; | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | public virtual PhysicsActor AddAvatar( | ||
178 | uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) | ||
179 | { | ||
180 | PhysicsActor ret = AddAvatar(localID, avName, position, Vector3.Zero, size, isFlying); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | public virtual PhysicsActor AddAvatar( | ||
185 | uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying) | ||
186 | { | ||
187 | PhysicsActor ret = AddAvatar(localID, avName, position, Vector3.Zero, size, isFlying); | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | /// <summary> | ||
192 | /// Remove an avatar. | ||
193 | /// </summary> | ||
194 | /// <param name="actor"></param> | ||
195 | public abstract void RemoveAvatar(PhysicsActor actor); | ||
196 | |||
197 | /// <summary> | ||
198 | /// Remove a prim. | ||
199 | /// </summary> | ||
200 | /// <param name="prim"></param> | ||
201 | public abstract void RemovePrim(PhysicsActor prim); | ||
202 | |||
203 | public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, | ||
204 | Vector3 size, Quaternion rotation, bool isPhysical, uint localid); | ||
205 | |||
206 | public virtual PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position, | ||
207 | uint localid, byte[] sdata) | ||
208 | { | ||
209 | return null; | ||
210 | } | ||
211 | |||
212 | public virtual PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, | ||
213 | Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid) | ||
214 | { | ||
215 | return AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid); | ||
216 | } | ||
217 | |||
218 | |||
219 | public virtual PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, | ||
220 | Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapetype, uint localid) | ||
221 | { | ||
222 | return AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid); | ||
223 | } | ||
224 | |||
225 | public virtual float TimeDilation | ||
226 | { | ||
227 | get { return 1.0f; } | ||
228 | } | ||
229 | |||
230 | public virtual bool SupportsNINJAJoints | ||
231 | { | ||
232 | get { return false; } | ||
233 | } | ||
234 | |||
235 | public virtual PhysicsJoint RequestJointCreation(string objectNameInScene, PhysicsJointType jointType, Vector3 position, | ||
236 | Quaternion rotation, string parms, List<string> bodyNames, string trackedBodyName, Quaternion localRotation) | ||
237 | { return null; } | ||
238 | |||
239 | public virtual void RequestJointDeletion(string objectNameInScene) | ||
240 | { return; } | ||
241 | |||
242 | public virtual void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor) | ||
243 | { return; } | ||
244 | |||
245 | public virtual void DumpJointInfo() | ||
246 | { return; } | ||
247 | |||
248 | public event JointMoved OnJointMoved; | ||
249 | |||
250 | protected virtual void DoJointMoved(PhysicsJoint joint) | ||
251 | { | ||
252 | // We need this to allow subclasses (but not other classes) to invoke the event; C# does | ||
253 | // not allow subclasses to invoke the parent class event. | ||
254 | if (OnJointMoved != null) | ||
255 | { | ||
256 | OnJointMoved(joint); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | public event JointDeactivated OnJointDeactivated; | ||
261 | |||
262 | protected virtual void DoJointDeactivated(PhysicsJoint joint) | ||
263 | { | ||
264 | // We need this to allow subclasses (but not other classes) to invoke the event; C# does | ||
265 | // not allow subclasses to invoke the parent class event. | ||
266 | if (OnJointDeactivated != null) | ||
267 | { | ||
268 | OnJointDeactivated(joint); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | public event JointErrorMessage OnJointErrorMessage; | ||
273 | |||
274 | protected virtual void DoJointErrorMessage(PhysicsJoint joint, string message) | ||
275 | { | ||
276 | // We need this to allow subclasses (but not other classes) to invoke the event; C# does | ||
277 | // not allow subclasses to invoke the parent class event. | ||
278 | if (OnJointErrorMessage != null) | ||
279 | { | ||
280 | OnJointErrorMessage(joint, message); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | public virtual Vector3 GetJointAnchor(PhysicsJoint joint) | ||
285 | { return Vector3.Zero; } | ||
286 | |||
287 | public virtual Vector3 GetJointAxis(PhysicsJoint joint) | ||
288 | { return Vector3.Zero; } | ||
289 | |||
290 | public abstract void AddPhysicsActorTaint(PhysicsActor prim); | ||
291 | |||
292 | |||
293 | public virtual void PrepareSimulation() { } | ||
294 | |||
295 | /// <summary> | ||
296 | /// Perform a simulation of the current physics scene over the given timestep. | ||
297 | /// </summary> | ||
298 | /// <param name="timeStep"></param> | ||
299 | /// <returns>The number of frames simulated over that period.</returns> | ||
300 | public abstract float Simulate(float timeStep); | ||
301 | |||
302 | /// <summary> | ||
303 | /// Get statistics about this scene. | ||
304 | /// </summary> | ||
305 | /// <remarks>This facility is currently experimental and subject to change.</remarks> | ||
306 | /// <returns> | ||
307 | /// A dictionary where the key is the statistic name. If no statistics are supplied then returns null. | ||
308 | /// </returns> | ||
309 | public virtual Dictionary<string, float> GetStats() { return null; } | ||
310 | |||
311 | public abstract void GetResults(); | ||
312 | |||
313 | public abstract void SetTerrain(float[] heightMap); | ||
314 | |||
315 | public abstract void SetWaterLevel(float baseheight); | ||
316 | |||
317 | public abstract void DeleteTerrain(); | ||
318 | |||
319 | public abstract void Dispose(); | ||
320 | |||
321 | public abstract Dictionary<uint, float> GetTopColliders(); | ||
322 | |||
323 | public abstract bool IsThreaded { get; } | ||
324 | |||
325 | /// <summary> | ||
326 | /// True if the physics plugin supports raycasting against the physics scene | ||
327 | /// </summary> | ||
328 | public virtual bool SupportsRayCast() | ||
329 | { | ||
330 | return false; | ||
331 | } | ||
332 | |||
333 | public virtual bool SupportsCombining() | ||
334 | { | ||
335 | return false; | ||
336 | } | ||
337 | |||
338 | public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {} | ||
339 | public virtual void CombineTerrain(float[] heightMap, Vector3 pOffset) {} | ||
340 | public virtual void UnCombine(PhysicsScene pScene) {} | ||
341 | |||
342 | /// <summary> | ||
343 | /// Queue a raycast against the physics scene. | ||
344 | /// The provided callback method will be called when the raycast is complete | ||
345 | /// | ||
346 | /// Many physics engines don't support collision testing at the same time as | ||
347 | /// manipulating the physics scene, so we queue the request up and callback | ||
348 | /// a custom method when the raycast is complete. | ||
349 | /// This allows physics engines that give an immediate result to callback immediately | ||
350 | /// and ones that don't, to callback when it gets a result back. | ||
351 | /// | ||
352 | /// ODE for example will not allow you to change the scene while collision testing or | ||
353 | /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene. | ||
354 | /// | ||
355 | /// This is named RayCastWorld to not conflict with modrex's Raycast method. | ||
356 | /// </summary> | ||
357 | /// <param name="position">Origin of the ray</param> | ||
358 | /// <param name="direction">Direction of the ray</param> | ||
359 | /// <param name="length">Length of ray in meters</param> | ||
360 | /// <param name="retMethod">Method to call when the raycast is complete</param> | ||
361 | public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) | ||
362 | { | ||
363 | if (retMethod != null) | ||
364 | retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); | ||
365 | } | ||
366 | |||
367 | public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) | ||
368 | { | ||
369 | if (retMethod != null) | ||
370 | retMethod(new List<ContactResult>()); | ||
371 | } | ||
372 | |||
373 | public virtual List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) | ||
374 | { | ||
375 | return new List<ContactResult>(); | ||
376 | } | ||
377 | |||
378 | public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | ||
379 | { | ||
380 | return null; | ||
381 | } | ||
382 | |||
383 | public virtual bool SupportsRaycastWorldFiltered() | ||
384 | { | ||
385 | return false; | ||
386 | } | ||
387 | |||
388 | public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) | ||
389 | { | ||
390 | return new List<ContactResult>(); | ||
391 | } | ||
392 | |||
393 | public virtual List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags) | ||
394 | { | ||
395 | return new List<ContactResult>(); | ||
396 | } | ||
397 | |||
398 | public virtual List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags) | ||
399 | { | ||
400 | return new List<ContactResult>(); | ||
401 | } | ||
402 | |||
403 | public virtual List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags) | ||
404 | { | ||
405 | return new List<ContactResult>(); | ||
406 | } | ||
407 | |||
408 | public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) | ||
409 | { | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | // Extendable interface for new, physics engine specific operations | ||
414 | public virtual object Extension(string pFunct, params object[] pParams) | ||
415 | { | ||
416 | // A NOP if the extension thing is not implemented by the physics engine | ||
417 | return null; | ||
418 | } | ||
419 | } | ||
420 | } | ||