diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 138 |
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. |
40 | public abstract class BSPhysObject : PhysicsActor | 40 | public 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 | } |