aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs')
-rw-r--r--OpenSim/Region/PhysicsModules/SharedBase/PhysicsScene.cs420
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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31
32using log4net;
33using Nini.Config;
34
35using OpenSim.Framework;
36using OpenMetaverse;
37
38namespace 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}