aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs138
1 files changed, 131 insertions, 7 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 3fe71e1..242aa80 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -39,26 +39,150 @@ namespace OpenSim.Region.Physics.BulletSPlugin
39// unless the difference is significant. 39// unless the difference is significant.
40public abstract class BSPhysObject : PhysicsActor 40public abstract class BSPhysObject : PhysicsActor
41{ 41{
42 public abstract BSLinkset Linkset { get; set; } 42 protected void BaseInitialize(BSScene parentScene)
43 {
44 PhysicsScene = parentScene;
45 Linkset = new BSLinkset(PhysicsScene, this);
43 46
44 public abstract bool Collide(uint collidingWith, BSPhysObject collidee, 47 CollisionCollection = new CollisionEventUpdate();
45 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); 48 SubscribedEventsMs = 0;
46 public abstract void SendCollisions(); 49 CollidingStep = 0;
50 CollidingGroundStep = 0;
51 }
47 52
48 // Return the object mass without calculating it or side effects 53 public BSScene PhysicsScene { get; protected set; }
54
55 public BSLinkset Linkset { get; set; }
56
57 // Return the object mass without calculating it or having side effects
49 public abstract float MassRaw { get; } 58 public abstract float MassRaw { get; }
50 59
51 // Reference to the physical body (btCollisionObject) of this object 60 // Reference to the physical body (btCollisionObject) of this object
52 public abstract BulletBody BSBody { get; set; } 61 public BulletBody BSBody { get; protected set; }
53 // Reference to the physical shape (btCollisionShape) of this object 62 // Reference to the physical shape (btCollisionShape) of this object
54 public abstract BulletShape BSShape { get; set; } 63 public BulletShape BSShape { get; protected set; }
55 64
65 // Stop all physical motion.
56 public abstract void ZeroMotion(); 66 public abstract void ZeroMotion();
57 67
68 // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
58 public virtual void StepVehicle(float timeStep) { } 69 public virtual void StepVehicle(float timeStep) { }
59 70
71 // Update the physical location and motion of the object. Called with data from Bullet.
60 public abstract void UpdateProperties(EntityProperties entprop); 72 public abstract void UpdateProperties(EntityProperties entprop);
61 73
74 // Tell the object to clean up.
62 public abstract void Destroy(); 75 public abstract void Destroy();
76
77 #region Collisions
78
79 // Requested number of milliseconds between collision events. Zero means disabled.
80 protected int SubscribedEventsMs { get; set; }
81 // Given subscription, the time that a collision may be passed up
82 protected int NextCollisionOkTime { get; set; }
83 // The simulation step that last had a collision
84 protected long CollidingStep { get; set; }
85 // The simulation step that last had a collision with the ground
86 protected long CollidingGroundStep { get; set; }
87 // The collision flags we think are set in Bullet
88 protected CollisionFlags CurrentCollisionFlags { get; set; }
89
90 // The collisions that have been collected this tick
91 protected CollisionEventUpdate CollisionCollection;
92
93 // The simulation step is telling this object about a collision.
94 // Return 'true' if a collision was processed and should be sent up.
95 // Called at taint time from within the Step() function
96 public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
97 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
98 {
99 bool ret = false;
100
101 // The following lines make IsColliding() and IsCollidingGround() work
102 CollidingStep = PhysicsScene.SimulationStep;
103 if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
104 {
105 CollidingGroundStep = PhysicsScene.SimulationStep;
106 }
107
108 // prims in the same linkset cannot collide with each other
109 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
110 {
111 return ret;
112 }
113
114 PhysicsScene.PhysicsLogging.Write("{0},BSPhysObject.Collison,call,with={1}", LocalID, collidingWith);
115
116 // if someone has subscribed for collision events....
117 if (SubscribedEvents()) {
118 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
119 PhysicsScene.PhysicsLogging.Write("{0},BSPhysObject.Collison.AddCollider,call,with={1},point={2},normal={3},depth={4},next={5}",
120 LocalID, collidingWith, contactPoint, contactNormal, pentrationDepth, NextCollisionOkTime.ToString("yyyyMMddHHmmssfff"));
121 ret = true;
122 }
123 return ret;
124 }
125
126 // Routine to send the collected collisions into the simulator.
127 // Also handles removal of this from the collection of objects with collisions if
128 // there are no collisions from this object. Mechanism is create one last
129 // collision event to make collision_end work.
130 public virtual void SendCollisions()
131 {
132 // throttle the collisions to the number of milliseconds specified in the subscription
133 int nowTime = PhysicsScene.SimulationNowTime;
134 if (nowTime >= NextCollisionOkTime)
135 {
136 NextCollisionOkTime = nowTime + SubscribedEventsMs;
137
138 // We are called if we previously had collisions. If there are no collisions
139 // this time, send up one last empty event so OpenSim can sense collision end.
140 if (CollisionCollection.Count == 0)
141 PhysicsScene.ObjectsWithNoMoreCollisions.Add(this);
142
143 base.SendCollisionUpdate(CollisionCollection);
144
145 // The collisionCollection structure is passed around in the simulator.
146 // Make sure we don't have a handle to that one and that a new one is used next time.
147 CollisionCollection = new CollisionEventUpdate();
148 }
149 }
150
151 // Subscribe for collision events.
152 // Parameter is the millisecond rate the caller wishes collision events to occur.
153 public override void SubscribeEvents(int ms) {
154 SubscribedEventsMs = ms;
155 if (ms > 0)
156 {
157 // make sure first collision happens
158 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
159 PhysicsScene.PhysicsLogging.Write("{0},SubscribeEvents,call,ms={1},nextOKTime={2}",
160 LocalID, SubscribedEventsMs, NextCollisionOkTime.ToString("yyyyMMddHHmmssfff"));
161
162 PhysicsScene.TaintedObject("BSPhysObject.SubscribeEvents", delegate()
163 {
164 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
165 });
166 }
167 else
168 {
169 // Subscribing for zero or less is the same as unsubscribing
170 UnSubscribeEvents();
171 }
172 }
173 public override void UnSubscribeEvents() {
174 SubscribedEventsMs = 0;
175 PhysicsScene.PhysicsLogging.Write("{0},UnSubscribeEvents,call", LocalID);
176 PhysicsScene.TaintedObject("BSPhysObject.UnSubscribeEvents", delegate()
177 {
178 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
179 });
180 }
181 // Return 'true' if the simulator wants collision events
182 public override bool SubscribedEvents() {
183 return (SubscribedEventsMs > 0);
184 }
185
186 #endregion // Collisions
63} 187}
64} 188}