OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
PhysicsActor.cs
Go to the documentation of this file.
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 log4net;
29 using System;
30 using System.Collections.Generic;
31 using System.Reflection;
32 using OpenSim.Framework;
33 using OpenMetaverse;
34 
35 namespace OpenSim.Region.PhysicsModules.SharedBase
36 {
37  public delegate void PositionUpdate(Vector3 position);
38  public delegate void VelocityUpdate(Vector3 velocity);
39  public delegate void OrientationUpdate(Quaternion orientation);
40 
41  public enum ActorTypes : int
42  {
43  Unknown = 0,
44  Agent = 1,
45  Prim = 2,
46  Ground = 3,
47  Water = 4
48  }
49 
50  public enum PIDHoverType
51  {
52  Ground,
54  Water,
55  Absolute
56  }
57 
58  public struct ContactPoint
59  {
60  public Vector3 Position;
61  public Vector3 SurfaceNormal;
62  public float PenetrationDepth;
63  public float RelativeSpeed;
64  public bool CharacterFeet;
65 
66  public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
67  {
68  Position = position;
69  SurfaceNormal = surfaceNormal;
70  PenetrationDepth = penetrationDepth;
71  RelativeSpeed = 0f; // for now let this one be set explicity
72  CharacterFeet = true; // keep other plugins work as before
73  }
74 
75  public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth, bool feet)
76  {
77  Position = position;
78  SurfaceNormal = surfaceNormal;
79  PenetrationDepth = penetrationDepth;
80  RelativeSpeed = 0f; // for now let this one be set explicity
81  CharacterFeet = feet; // keep other plugins work as before
82  }
83  }
84 
85  public struct ContactData
86  {
87  public float mu;
88  public float bounce;
89  public bool softcolide;
90 
91  public ContactData(float _mu, float _bounce, bool _softcolide)
92  {
93  mu = _mu;
94  bounce = _bounce;
95  softcolide = _softcolide;
96  }
97  }
101  public class CollisionEventUpdate : EventArgs
102  {
106  public int Count { get { return m_objCollisionList.Count; } }
107 
108  public bool CollisionsOnPreviousFrame { get; private set; }
109 
110  public Dictionary<uint, ContactPoint> m_objCollisionList;
111 
112  public CollisionEventUpdate(Dictionary<uint, ContactPoint> objCollisionList)
113  {
114  m_objCollisionList = objCollisionList;
115  }
116 
118  {
119  m_objCollisionList = new Dictionary<uint, ContactPoint>();
120  }
121 
122  public void AddCollider(uint localID, ContactPoint contact)
123  {
124  if (!m_objCollisionList.ContainsKey(localID))
125  {
126  m_objCollisionList.Add(localID, contact);
127  }
128  else
129  {
130  if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth)
131  m_objCollisionList[localID] = contact;
132  }
133  }
134 
138  public void Clear()
139  {
140  m_objCollisionList.Clear();
141  }
142  }
143 
144  public abstract class PhysicsActor
145  {
146 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
147 
148  public delegate void RequestTerseUpdate();
149  public delegate void CollisionUpdate(EventArgs e);
150  public delegate void OutOfBounds(Vector3 pos);
151 
152 // disable warning: public events
153 #pragma warning disable 67
157  public event RequestTerseUpdate OnRequestTerseUpdate;
158 
163  public event CollisionUpdate OnCollisionUpdate;
164 
165  public event OutOfBounds OnOutOfBounds;
166 #pragma warning restore 67
167 
168  public static PhysicsActor Null
169  {
170  get { return new NullPhysicsActor(); }
171  }
172 
173  public virtual bool Building { get; set; }
174 
175  public virtual void getContactData(ref ContactData cdata)
176  {
177  cdata.mu = 0;
178  cdata.bounce = 0;
179  }
180 
181  public abstract bool Stopped { get; }
182 
183  public abstract Vector3 Size { get; set; }
184 
185  public virtual void setAvatarSize(Vector3 size, float feetOffset)
186  {
187  Size = size;
188  }
189 
190  public virtual bool Phantom { get; set; }
191 
192  public virtual bool IsVolumeDtc
193  {
194  get { return false; }
195  set { return; }
196  }
197 
198  public virtual byte PhysicsShapeType { get; set; }
199 
200  public abstract PrimitiveBaseShape Shape { set; }
201 
202  uint m_baseLocalID;
203  public virtual uint LocalID
204  {
205  set { m_baseLocalID = value; }
206  get { return m_baseLocalID; }
207  }
208 
209  public abstract bool Grabbed { set; }
210 
211  public abstract bool Selected { set; }
212 
220  public string Name { get; set; }
221 
225  public string SOPName;
226 
227  public abstract void CrossingFailure();
228 
229  public abstract void link(PhysicsActor obj);
230 
231  public abstract void delink();
232 
233  public abstract void LockAngularMotion(byte axislocks);
234 
235  public virtual void RequestPhysicsterseUpdate()
236  {
237  // Make a temporary copy of the event to avoid possibility of
238  // a race condition if the last subscriber unsubscribes
239  // immediately after the null check and before the event is raised.
240  RequestTerseUpdate handler = OnRequestTerseUpdate;
241 
242  if (handler != null)
243  {
244  handler();
245  }
246  }
247 
248  public virtual void RaiseOutOfBounds(Vector3 pos)
249  {
250  // Make a temporary copy of the event to avoid possibility of
251  // a race condition if the last subscriber unsubscribes
252  // immediately after the null check and before the event is raised.
253  OutOfBounds handler = OnOutOfBounds;
254 
255  if (handler != null)
256  {
257  handler(pos);
258  }
259  }
260 
261  public virtual void SendCollisionUpdate(EventArgs e)
262  {
263  CollisionUpdate handler = OnCollisionUpdate;
264 
265 // m_log.DebugFormat("[PHYSICS ACTOR]: Sending collision for {0}", LocalID);
266 
267  if (handler != null)
268  handler(e);
269  }
270 
271  public virtual void SetMaterial (int material) { }
272  public virtual float Density { get; set; }
273  public virtual float GravModifier { get; set; }
274  public virtual float Friction { get; set; }
275  public virtual float Restitution { get; set; }
276 
285  public abstract Vector3 Position { get; set; }
286 
287  public abstract float Mass { get; }
288  public abstract Vector3 Force { get; set; }
289 
290  public abstract int VehicleType { get; set; }
291  public abstract void VehicleFloatParam(int param, float value);
292  public abstract void VehicleVectorParam(int param, Vector3 value);
293  public abstract void VehicleRotationParam(int param, Quaternion rotation);
294  public abstract void VehicleFlags(int param, bool remove);
295 
296  // This is an overridable version of SetVehicle() that works for all physics engines.
297  // This is VERY inefficient. It behoves any physics engine to override this and
298  // implement a more efficient setting of all the vehicle parameters.
299  public virtual void SetVehicle(object pvdata)
300  {
301  VehicleData vdata = (VehicleData)pvdata;
302  // vehicleActor.ProcessSetVehicle((VehicleData)vdata);
303 
304  this.VehicleType = (int)vdata.m_type;
305  this.VehicleFlags(-1, false); // clears all flags
306  this.VehicleFlags((int)vdata.m_flags, false);
307 
308  // Linear properties
309  this.VehicleVectorParam((int)Vehicle.LINEAR_MOTOR_DIRECTION, vdata.m_linearMotorDirection);
310  this.VehicleVectorParam((int)Vehicle.LINEAR_FRICTION_TIMESCALE, vdata.m_linearFrictionTimescale);
311  this.VehicleFloatParam((int)Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE, vdata.m_linearMotorDecayTimescale);
312  this.VehicleFloatParam((int)Vehicle.LINEAR_MOTOR_TIMESCALE, vdata.m_linearMotorTimescale);
313  this.VehicleVectorParam((int)Vehicle.LINEAR_MOTOR_OFFSET, vdata.m_linearMotorOffset);
314 
315  //Angular properties
316  this.VehicleVectorParam((int)Vehicle.ANGULAR_MOTOR_DIRECTION, vdata.m_angularMotorDirection);
317  this.VehicleFloatParam((int)Vehicle.ANGULAR_MOTOR_TIMESCALE, vdata.m_angularMotorTimescale);
318  this.VehicleFloatParam((int)Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE, vdata.m_angularMotorDecayTimescale);
319  this.VehicleVectorParam((int)Vehicle.ANGULAR_FRICTION_TIMESCALE, vdata.m_angularFrictionTimescale);
320 
321  //Deflection properties
322  this.VehicleFloatParam((int)Vehicle.ANGULAR_DEFLECTION_EFFICIENCY, vdata.m_angularDeflectionEfficiency);
323  this.VehicleFloatParam((int)Vehicle.ANGULAR_DEFLECTION_TIMESCALE, vdata.m_angularDeflectionTimescale);
324  this.VehicleFloatParam((int)Vehicle.LINEAR_DEFLECTION_EFFICIENCY, vdata.m_linearDeflectionEfficiency);
325  this.VehicleFloatParam((int)Vehicle.LINEAR_DEFLECTION_TIMESCALE, vdata.m_linearDeflectionTimescale);
326 
327  //Banking properties
328  this.VehicleFloatParam((int)Vehicle.BANKING_EFFICIENCY, vdata.m_bankingEfficiency);
329  this.VehicleFloatParam((int)Vehicle.BANKING_MIX, vdata.m_bankingMix);
330  this.VehicleFloatParam((int)Vehicle.BANKING_TIMESCALE, vdata.m_bankingTimescale);
331 
332  //Hover and Buoyancy properties
333  this.VehicleFloatParam((int)Vehicle.HOVER_HEIGHT, vdata.m_VhoverHeight);
334  this.VehicleFloatParam((int)Vehicle.HOVER_EFFICIENCY, vdata.m_VhoverEfficiency);
335  this.VehicleFloatParam((int)Vehicle.HOVER_TIMESCALE, vdata.m_VhoverTimescale);
336  this.VehicleFloatParam((int)Vehicle.BUOYANCY, vdata.m_VehicleBuoyancy);
337 
338  //Attractor properties
339  this.VehicleFloatParam((int)Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, vdata.m_verticalAttractionEfficiency);
340  this.VehicleFloatParam((int)Vehicle.VERTICAL_ATTRACTION_TIMESCALE, vdata.m_verticalAttractionTimescale);
341 
342  this.VehicleRotationParam((int)Vehicle.REFERENCE_FRAME, vdata.m_referenceFrame);
343  }
344 
345 
349  public abstract void SetVolumeDetect(int param);
350 
351  public abstract Vector3 GeometricCenter { get; }
352  public abstract Vector3 CenterOfMass { get; }
353 
354  public virtual float PhysicsCost
355  {
356  get
357  {
358  return 0.1f;
359  }
360  }
361 
362  public virtual float StreamCost
363  {
364  get
365  {
366  return 1.0f;
367  }
368  }
369 
377  protected Vector3 m_targetVelocity;
378  public virtual Vector3 TargetVelocity
379  {
380  get { return m_targetVelocity; }
381  set {
382  m_targetVelocity = value;
383  Velocity = m_targetVelocity;
384  }
385  }
386 
387  public abstract Vector3 Velocity { get; set; }
388 
389  public abstract Vector3 Torque { get; set; }
390  public abstract float CollisionScore { get; set;}
391  public abstract Vector3 Acceleration { get; set; }
392  public abstract Quaternion Orientation { get; set; }
393  public abstract int PhysicsActorType { get; set; }
394  public abstract bool IsPhysical { get; set; }
395  public abstract bool Flying { get; set; }
396  public abstract bool SetAlwaysRun { get; set; }
397  public abstract bool ThrottleUpdates { get; set; }
398  public abstract bool IsColliding { get; set; }
399  public abstract bool CollidingGround { get; set; }
400  public abstract bool CollidingObj { get; set; }
401  public abstract bool FloatOnWater { set; }
402  public abstract Vector3 RotationalVelocity { get; set; }
403  public abstract bool Kinematic { get; set; }
404  public abstract float Buoyancy { get; set; }
405 
406  // Used for MoveTo
407  public abstract Vector3 PIDTarget { set; }
408  public abstract bool PIDActive { get; set; }
409  public abstract float PIDTau { set; }
410 
411  // Used for llSetHoverHeight and maybe vehicle height
412  // Hover Height will override MoveTo target's Z
413  public abstract bool PIDHoverActive {get; set;}
414  public abstract float PIDHoverHeight { set;}
415  public abstract PIDHoverType PIDHoverType { set;}
416  public abstract float PIDHoverTau { set;}
417 
418  // For RotLookAt
419  public abstract Quaternion APIDTarget { set;}
420  public abstract bool APIDActive { set;}
421  public abstract float APIDStrength { set;}
422  public abstract float APIDDamping { set;}
423 
424  public abstract void AddForce(Vector3 force, bool pushforce);
425  public abstract void AddAngularForce(Vector3 force, bool pushforce);
426  public abstract void SetMomentum(Vector3 momentum);
427  public abstract void SubscribeEvents(int ms);
428  public abstract void UnSubscribeEvents();
429  public abstract bool SubscribedEvents();
430 
431  public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { }
432 
433  // Warning in a parent part it returns itself, not null
434  public virtual PhysicsActor ParentActor { get { return this; } }
435 
436 
437  // Extendable interface for new, physics engine specific operations
438  public virtual object Extension(string pFunct, params object[] pParams)
439  {
440  // A NOP of the physics engine does not implement this feature
441  return null;
442  }
443  }
444 
446  {
447  private ActorTypes m_actorType = ActorTypes.Unknown;
448 
449  public override bool Stopped
450  {
451  get{ return true; }
452  }
453 
454  public override Vector3 Position
455  {
456  get { return Vector3.Zero; }
457  set { return; }
458  }
459 
460  public override bool SetAlwaysRun
461  {
462  get { return false; }
463  set { return; }
464  }
465 
466  public override uint LocalID
467  {
468  get { return 0; }
469  set { return; }
470  }
471 
472  public override bool Grabbed
473  {
474  set { return; }
475  }
476 
477  public override bool Selected
478  {
479  set { return; }
480  }
481 
482  public override float Buoyancy
483  {
484  get { return 0f; }
485  set { return; }
486  }
487 
488  public override bool FloatOnWater
489  {
490  set { return; }
491  }
492 
493  public override bool CollidingGround
494  {
495  get { return false; }
496  set { return; }
497  }
498 
499  public override bool CollidingObj
500  {
501  get { return false; }
502  set { return; }
503  }
504 
505  public override Vector3 Size
506  {
507  get { return Vector3.Zero; }
508  set { return; }
509  }
510 
511  public override float Mass
512  {
513  get { return 0f; }
514  }
515 
516  public override Vector3 Force
517  {
518  get { return Vector3.Zero; }
519  set { return; }
520  }
521 
522  public override int VehicleType
523  {
524  get { return 0; }
525  set { return; }
526  }
527 
528  public override void VehicleFloatParam(int param, float value) {}
529  public override void VehicleVectorParam(int param, Vector3 value) { }
530  public override void VehicleRotationParam(int param, Quaternion rotation) { }
531  public override void VehicleFlags(int param, bool remove) { }
532  public override void SetVolumeDetect(int param) {}
533  public override void SetMaterial(int material) {}
534  public override Vector3 CenterOfMass { get { return Vector3.Zero; }}
535 
536  public override Vector3 GeometricCenter { get { return Vector3.Zero; }}
537 
538  public override PrimitiveBaseShape Shape { set { return; }}
539 
540  public override Vector3 Velocity
541  {
542  get { return Vector3.Zero; }
543  set { return; }
544  }
545 
546  public override Vector3 Torque
547  {
548  get { return Vector3.Zero; }
549  set { return; }
550  }
551 
552  public override float CollisionScore
553  {
554  get { return 0f; }
555  set { }
556  }
557 
558  public override void CrossingFailure() {}
559 
560  public override Quaternion Orientation
561  {
562  get { return Quaternion.Identity; }
563  set { }
564  }
565 
566  public override Vector3 Acceleration
567  {
568  get { return Vector3.Zero; }
569  set { }
570  }
571 
572  public override bool IsPhysical
573  {
574  get { return false; }
575  set { return; }
576  }
577 
578  public override bool Flying
579  {
580  get { return false; }
581  set { return; }
582  }
583 
584  public override bool ThrottleUpdates
585  {
586  get { return false; }
587  set { return; }
588  }
589 
590  public override bool IsColliding
591  {
592  get { return false; }
593  set { return; }
594  }
595 
596  public override int PhysicsActorType
597  {
598  get { return (int)m_actorType; }
599  set {
600  ActorTypes type = (ActorTypes)value;
601  switch (type)
602  {
603  case ActorTypes.Ground:
604  case ActorTypes.Water:
605  m_actorType = type;
606  break;
607  default:
608  m_actorType = ActorTypes.Unknown;
609  break;
610  }
611  }
612  }
613 
614  public override bool Kinematic
615  {
616  get { return true; }
617  set { return; }
618  }
619 
620  public override void link(PhysicsActor obj) { }
621  public override void delink() { }
622  public override void LockAngularMotion(byte axislocks) { }
623  public override void AddForce(Vector3 force, bool pushforce) { }
624  public override void AddAngularForce(Vector3 force, bool pushforce) { }
625 
626  public override Vector3 RotationalVelocity
627  {
628  get { return Vector3.Zero; }
629  set { return; }
630  }
631 
632  public override Vector3 PIDTarget { set { return; } }
633 
634  public override bool PIDActive
635  {
636  get { return false; }
637  set { return; }
638  }
639 
640  public override float PIDTau { set { return; } }
641 
642  public override float PIDHoverHeight { set { return; } }
643  public override bool PIDHoverActive {get {return false;} set { return; } }
644  public override PIDHoverType PIDHoverType { set { return; } }
645  public override float PIDHoverTau { set { return; } }
646 
647  public override Quaternion APIDTarget { set { return; } }
648  public override bool APIDActive { set { return; } }
649  public override float APIDStrength { set { return; } }
650  public override float APIDDamping { set { return; } }
651 
652  public override void SetMomentum(Vector3 momentum) { }
653 
654  public override void SubscribeEvents(int ms) { }
655  public override void UnSubscribeEvents() { }
656  public override bool SubscribedEvents() { return false; }
657  }
658 }
override void VehicleRotationParam(int param, Quaternion rotation)
virtual void setAvatarSize(Vector3 size, float feetOffset)
ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
Definition: PhysicsActor.cs:66
virtual object Extension(string pFunct, params object[] pParams)
override void VehicleVectorParam(int param, Vector3 value)
Vector3 m_targetVelocity
The desired velocity of this actor.
delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun)
ContactData(float _mu, float _bounce, bool _softcolide)
Definition: PhysicsActor.cs:91
Used to pass collision information to OnCollisionUpdate listeners.
override void AddForce(Vector3 force, bool pushforce)
virtual void getContactData(ref ContactData cdata)
delegate void PositionUpdate(Vector3 position)
override void SetVolumeDetect(int param)
Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more ...
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
Definition: ICM_Api.cs:32
string SOPName
This is being used by ODE joint code.
override void AddAngularForce(Vector3 force, bool pushforce)
ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth, bool feet)
Definition: PhysicsActor.cs:75
Unthrottled packets
CollisionEventUpdate(Dictionary< uint, ContactPoint > objCollisionList)
void AddCollider(uint localID, ContactPoint contact)
virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
override void VehicleFlags(int param, bool remove)
delegate void OrientationUpdate(Quaternion orientation)
override void VehicleFloatParam(int param, float value)
CollisionUpdate OnCollisionUpdate
Subscribers to this event must synchronously handle the dictionary of collisions received, since the event object is reused in subsequent physics frames.
delegate void VelocityUpdate(Vector3 velocity)