diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 232 |
1 files changed, 123 insertions, 109 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index ebfd85b..9c20004 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -42,7 +42,7 @@ public sealed class BSPrim : PhysicsActor | |||
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | private static readonly string LogHeader = "[BULLETS PRIM]"; | 43 | private static readonly string LogHeader = "[BULLETS PRIM]"; |
44 | 44 | ||
45 | private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); } | 45 | private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); } |
46 | 46 | ||
47 | private IMesh _mesh; | 47 | private IMesh _mesh; |
48 | private PrimitiveBaseShape _pbs; | 48 | private PrimitiveBaseShape _pbs; |
@@ -138,14 +138,15 @@ public sealed class BSPrim : PhysicsActor | |||
138 | _isPhysical = pisPhysical; | 138 | _isPhysical = pisPhysical; |
139 | _isVolumeDetect = false; | 139 | _isVolumeDetect = false; |
140 | _subscribedEventsMs = 0; | 140 | _subscribedEventsMs = 0; |
141 | _friction = _scene.Params.defaultFriction; // TODO: compute based on object material | 141 | _friction = _scene.Params.defaultFriction; // TODO: compute based on object material |
142 | _density = _scene.Params.defaultDensity; // TODO: compute based on object material | 142 | _density = _scene.Params.defaultDensity; // TODO: compute based on object material |
143 | _restitution = _scene.Params.defaultRestitution; | 143 | _restitution = _scene.Params.defaultRestitution; |
144 | _linkset = new BSLinkset(_scene, this); // a linkset of one | 144 | _linkset = new BSLinkset(_scene, this); // a linkset of one |
145 | _vehicle = new BSDynamics(this); // add vehicleness | 145 | _vehicle = new BSDynamics(this); // add vehicleness |
146 | _mass = CalculateMass(); | 146 | _mass = CalculateMass(); |
147 | // do the actual object creation at taint time | 147 | // do the actual object creation at taint time |
148 | _scene.TaintedObject(delegate() | 148 | DetailLog("{0},BSPrim.constructor,call", LocalID); |
149 | _scene.TaintedObject("BSPrim.create", delegate() | ||
149 | { | 150 | { |
150 | RecreateGeomAndObject(); | 151 | RecreateGeomAndObject(); |
151 | 152 | ||
@@ -160,17 +161,22 @@ public sealed class BSPrim : PhysicsActor | |||
160 | public void Destroy() | 161 | public void Destroy() |
161 | { | 162 | { |
162 | // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); | 163 | // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); |
163 | // DetailLog("{0},Destroy", LocalID); | 164 | |
165 | // Undo any links between me and any other object | ||
166 | BSPrim parentBefore = _linkset.LinksetRoot; | ||
167 | int childrenBefore = _linkset.NumberOfChildren; | ||
168 | |||
169 | _linkset = _linkset.RemoveMeFromLinkset(this); | ||
170 | |||
171 | DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", | ||
172 | LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); | ||
164 | 173 | ||
165 | // Undo any vehicle properties | 174 | // Undo any vehicle properties |
166 | _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); | 175 | this.VehicleType = (int)Vehicle.TYPE_NONE; |
167 | _scene.RemoveVehiclePrim(this); // just to make sure | ||
168 | 176 | ||
169 | _scene.TaintedObject(delegate() | 177 | _scene.TaintedObject("BSPrim.destroy", delegate() |
170 | { | 178 | { |
171 | // Undo any links between me and any other object | 179 | DetailLog("{0},BSPrim.Destroy,taint,", LocalID); |
172 | _linkset = _linkset.RemoveMeFromLinkset(this); | ||
173 | |||
174 | // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. | 180 | // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. |
175 | BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); | 181 | BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); |
176 | }); | 182 | }); |
@@ -183,11 +189,11 @@ public sealed class BSPrim : PhysicsActor | |||
183 | get { return _size; } | 189 | get { return _size; } |
184 | set { | 190 | set { |
185 | _size = value; | 191 | _size = value; |
186 | _scene.TaintedObject(delegate() | 192 | _scene.TaintedObject("BSPrim.setSize", delegate() |
187 | { | 193 | { |
188 | _mass = CalculateMass(); // changing size changes the mass | 194 | _mass = CalculateMass(); // changing size changes the mass |
189 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); | 195 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); |
190 | DetailLog("{0}: setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); | 196 | // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); |
191 | RecreateGeomAndObject(); | 197 | RecreateGeomAndObject(); |
192 | }); | 198 | }); |
193 | } | 199 | } |
@@ -195,7 +201,7 @@ public sealed class BSPrim : PhysicsActor | |||
195 | public override PrimitiveBaseShape Shape { | 201 | public override PrimitiveBaseShape Shape { |
196 | set { | 202 | set { |
197 | _pbs = value; | 203 | _pbs = value; |
198 | _scene.TaintedObject(delegate() | 204 | _scene.TaintedObject("BSPrim.setShape", delegate() |
199 | { | 205 | { |
200 | _mass = CalculateMass(); // changing the shape changes the mass | 206 | _mass = CalculateMass(); // changing the shape changes the mass |
201 | RecreateGeomAndObject(); | 207 | RecreateGeomAndObject(); |
@@ -213,7 +219,7 @@ public sealed class BSPrim : PhysicsActor | |||
213 | public override bool Selected { | 219 | public override bool Selected { |
214 | set { | 220 | set { |
215 | _isSelected = value; | 221 | _isSelected = value; |
216 | _scene.TaintedObject(delegate() | 222 | _scene.TaintedObject("BSPrim.setSelected", delegate() |
217 | { | 223 | { |
218 | SetObjectDynamic(); | 224 | SetObjectDynamic(); |
219 | }); | 225 | }); |
@@ -224,10 +230,17 @@ public sealed class BSPrim : PhysicsActor | |||
224 | // link me to the specified parent | 230 | // link me to the specified parent |
225 | public override void link(PhysicsActor obj) { | 231 | public override void link(PhysicsActor obj) { |
226 | BSPrim parent = obj as BSPrim; | 232 | BSPrim parent = obj as BSPrim; |
227 | DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); | 233 | if (parent != null) |
228 | DetailLog("{0},link,parent={1}", LocalID, obj.LocalID); | 234 | { |
235 | DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); | ||
236 | BSPrim parentBefore = _linkset.LinksetRoot; | ||
237 | int childrenBefore = _linkset.NumberOfChildren; | ||
229 | 238 | ||
230 | _linkset = _linkset.AddMeToLinkset(this, parent); | 239 | _linkset = parent.Linkset.AddMeToLinkset(this); |
240 | |||
241 | DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", | ||
242 | LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); | ||
243 | } | ||
231 | return; | 244 | return; |
232 | } | 245 | } |
233 | 246 | ||
@@ -236,10 +249,15 @@ public sealed class BSPrim : PhysicsActor | |||
236 | // TODO: decide if this parent checking needs to happen at taint time | 249 | // TODO: decide if this parent checking needs to happen at taint time |
237 | // Race condition here: if link() and delink() in same simulation tick, the delink will not happen | 250 | // Race condition here: if link() and delink() in same simulation tick, the delink will not happen |
238 | DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, | 251 | DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, |
239 | _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString()); | 252 | _linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString()); |
240 | DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString()); | 253 | |
254 | BSPrim parentBefore = _linkset.LinksetRoot; | ||
255 | int childrenBefore = _linkset.NumberOfChildren; | ||
256 | |||
257 | _linkset = _linkset.RemoveMeFromLinkset(this); | ||
241 | 258 | ||
242 | _linkset.RemoveMeFromLinkset(this); | 259 | DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", |
260 | LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); | ||
243 | return; | 261 | return; |
244 | } | 262 | } |
245 | 263 | ||
@@ -262,7 +280,7 @@ public sealed class BSPrim : PhysicsActor | |||
262 | 280 | ||
263 | public override void LockAngularMotion(OMV.Vector3 axis) | 281 | public override void LockAngularMotion(OMV.Vector3 axis) |
264 | { | 282 | { |
265 | DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis); | 283 | // DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); |
266 | return; | 284 | return; |
267 | } | 285 | } |
268 | 286 | ||
@@ -279,9 +297,9 @@ public sealed class BSPrim : PhysicsActor | |||
279 | set { | 297 | set { |
280 | _position = value; | 298 | _position = value; |
281 | // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? | 299 | // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? |
282 | _scene.TaintedObject(delegate() | 300 | _scene.TaintedObject("BSPrim.setPosition", delegate() |
283 | { | 301 | { |
284 | DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 302 | // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
285 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); | 303 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); |
286 | }); | 304 | }); |
287 | } | 305 | } |
@@ -316,9 +334,9 @@ public sealed class BSPrim : PhysicsActor | |||
316 | get { return _force; } | 334 | get { return _force; } |
317 | set { | 335 | set { |
318 | _force = value; | 336 | _force = value; |
319 | _scene.TaintedObject(delegate() | 337 | _scene.TaintedObject("BSPrim.setForce", delegate() |
320 | { | 338 | { |
321 | DetailLog("{0},SetForce,taint,force={1}", LocalID, _force); | 339 | // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); |
322 | // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); | 340 | // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); |
323 | BulletSimAPI.SetObjectForce2(Body.Ptr, _force); | 341 | BulletSimAPI.SetObjectForce2(Body.Ptr, _force); |
324 | }); | 342 | }); |
@@ -331,53 +349,41 @@ public sealed class BSPrim : PhysicsActor | |||
331 | } | 349 | } |
332 | set { | 350 | set { |
333 | Vehicle type = (Vehicle)value; | 351 | Vehicle type = (Vehicle)value; |
334 | _scene.TaintedObject(delegate() | 352 | BSPrim vehiclePrim = this; |
353 | _scene.TaintedObject("setVehicleType", delegate() | ||
335 | { | 354 | { |
336 | DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type); | 355 | // Done at taint time so we're sure the physics engine is not using the variables |
356 | // Vehicle code changes the parameters for this vehicle type. | ||
337 | _vehicle.ProcessTypeChange(type); | 357 | _vehicle.ProcessTypeChange(type); |
338 | if (type == Vehicle.TYPE_NONE) | 358 | // Tell the scene about the vehicle so it will get processing each frame. |
339 | { | 359 | _scene.VehicleInSceneTypeChanged(this, type); |
340 | _scene.RemoveVehiclePrim(this); | ||
341 | } | ||
342 | else | ||
343 | { | ||
344 | _scene.TaintedObject(delegate() | ||
345 | { | ||
346 | // Tell the physics engine to clear state | ||
347 | BulletSimAPI.ClearForces2(this.Body.Ptr); | ||
348 | }); | ||
349 | |||
350 | // make it so the scene will call us each tick to do vehicle things | ||
351 | _scene.AddVehiclePrim(this); | ||
352 | } | ||
353 | return; | ||
354 | }); | 360 | }); |
355 | } | 361 | } |
356 | } | 362 | } |
357 | public override void VehicleFloatParam(int param, float value) | 363 | public override void VehicleFloatParam(int param, float value) |
358 | { | 364 | { |
359 | _scene.TaintedObject(delegate() | 365 | _scene.TaintedObject("BSPrim.VehicleFloatParam", delegate() |
360 | { | 366 | { |
361 | _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); | 367 | _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); |
362 | }); | 368 | }); |
363 | } | 369 | } |
364 | public override void VehicleVectorParam(int param, OMV.Vector3 value) | 370 | public override void VehicleVectorParam(int param, OMV.Vector3 value) |
365 | { | 371 | { |
366 | _scene.TaintedObject(delegate() | 372 | _scene.TaintedObject("BSPrim.VehicleVectorParam", delegate() |
367 | { | 373 | { |
368 | _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); | 374 | _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); |
369 | }); | 375 | }); |
370 | } | 376 | } |
371 | public override void VehicleRotationParam(int param, OMV.Quaternion rotation) | 377 | public override void VehicleRotationParam(int param, OMV.Quaternion rotation) |
372 | { | 378 | { |
373 | _scene.TaintedObject(delegate() | 379 | _scene.TaintedObject("BSPrim.VehicleRotationParam", delegate() |
374 | { | 380 | { |
375 | _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); | 381 | _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); |
376 | }); | 382 | }); |
377 | } | 383 | } |
378 | public override void VehicleFlags(int param, bool remove) | 384 | public override void VehicleFlags(int param, bool remove) |
379 | { | 385 | { |
380 | _scene.TaintedObject(delegate() | 386 | _scene.TaintedObject("BSPrim.VehicleFlags", delegate() |
381 | { | 387 | { |
382 | _vehicle.ProcessVehicleFlags(param, remove); | 388 | _vehicle.ProcessVehicleFlags(param, remove); |
383 | }); | 389 | }); |
@@ -395,7 +401,7 @@ public sealed class BSPrim : PhysicsActor | |||
395 | public override void SetVolumeDetect(int param) { | 401 | public override void SetVolumeDetect(int param) { |
396 | bool newValue = (param != 0); | 402 | bool newValue = (param != 0); |
397 | _isVolumeDetect = newValue; | 403 | _isVolumeDetect = newValue; |
398 | _scene.TaintedObject(delegate() | 404 | _scene.TaintedObject("BSPrim.SetVolumeDetect", delegate() |
399 | { | 405 | { |
400 | SetObjectDynamic(); | 406 | SetObjectDynamic(); |
401 | }); | 407 | }); |
@@ -406,9 +412,9 @@ public sealed class BSPrim : PhysicsActor | |||
406 | get { return _velocity; } | 412 | get { return _velocity; } |
407 | set { | 413 | set { |
408 | _velocity = value; | 414 | _velocity = value; |
409 | _scene.TaintedObject(delegate() | 415 | _scene.TaintedObject("BSPrim.setVelocity", delegate() |
410 | { | 416 | { |
411 | DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity); | 417 | // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); |
412 | BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); | 418 | BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); |
413 | }); | 419 | }); |
414 | } | 420 | } |
@@ -416,7 +422,7 @@ public sealed class BSPrim : PhysicsActor | |||
416 | public override OMV.Vector3 Torque { | 422 | public override OMV.Vector3 Torque { |
417 | get { return _torque; } | 423 | get { return _torque; } |
418 | set { _torque = value; | 424 | set { _torque = value; |
419 | DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque); | 425 | // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); |
420 | } | 426 | } |
421 | } | 427 | } |
422 | public override float CollisionScore { | 428 | public override float CollisionScore { |
@@ -440,10 +446,10 @@ public sealed class BSPrim : PhysicsActor | |||
440 | set { | 446 | set { |
441 | _orientation = value; | 447 | _orientation = value; |
442 | // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? | 448 | // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? |
443 | _scene.TaintedObject(delegate() | 449 | _scene.TaintedObject("BSPrim.setOrientation", delegate() |
444 | { | 450 | { |
445 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); | 451 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); |
446 | DetailLog("{0},SetOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 452 | // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
447 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); | 453 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); |
448 | }); | 454 | }); |
449 | } | 455 | } |
@@ -457,7 +463,7 @@ public sealed class BSPrim : PhysicsActor | |||
457 | get { return _isPhysical; } | 463 | get { return _isPhysical; } |
458 | set { | 464 | set { |
459 | _isPhysical = value; | 465 | _isPhysical = value; |
460 | _scene.TaintedObject(delegate() | 466 | _scene.TaintedObject("BSPrim.setIsPhysical", delegate() |
461 | { | 467 | { |
462 | SetObjectDynamic(); | 468 | SetObjectDynamic(); |
463 | }); | 469 | }); |
@@ -478,7 +484,6 @@ public sealed class BSPrim : PhysicsActor | |||
478 | 484 | ||
479 | // Make gravity work if the object is physical and not selected | 485 | // Make gravity work if the object is physical and not selected |
480 | // No locking here because only called when it is safe | 486 | // No locking here because only called when it is safe |
481 | // Only called at taint time so it is save to call into Bullet. | ||
482 | private void SetObjectDynamic() | 487 | private void SetObjectDynamic() |
483 | { | 488 | { |
484 | // RA: remove this for the moment. | 489 | // RA: remove this for the moment. |
@@ -487,13 +492,16 @@ public sealed class BSPrim : PhysicsActor | |||
487 | // Maybe a VerifyCorrectPhysicalShape() routine? | 492 | // Maybe a VerifyCorrectPhysicalShape() routine? |
488 | // RecreateGeomAndObject(); | 493 | // RecreateGeomAndObject(); |
489 | 494 | ||
490 | float mass = _mass; | 495 | // Bullet wants static objects to have a mass of zero |
491 | // Bullet wants static objects have a mass of zero | 496 | float mass = IsStatic ? 0f : _mass; |
492 | if (IsStatic) | ||
493 | mass = 0f; | ||
494 | 497 | ||
495 | DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); | ||
496 | BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); | 498 | BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); |
499 | |||
500 | // recompute any linkset parameters | ||
501 | _linkset.Refresh(this); | ||
502 | |||
503 | CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); | ||
504 | // DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); | ||
497 | } | 505 | } |
498 | 506 | ||
499 | // prims don't fly | 507 | // prims don't fly |
@@ -548,9 +556,9 @@ public sealed class BSPrim : PhysicsActor | |||
548 | set { | 556 | set { |
549 | _rotationalVelocity = value; | 557 | _rotationalVelocity = value; |
550 | // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); | 558 | // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); |
551 | _scene.TaintedObject(delegate() | 559 | _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() |
552 | { | 560 | { |
553 | DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); | 561 | // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); |
554 | BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); | 562 | BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); |
555 | }); | 563 | }); |
556 | } | 564 | } |
@@ -565,9 +573,9 @@ public sealed class BSPrim : PhysicsActor | |||
565 | get { return _buoyancy; } | 573 | get { return _buoyancy; } |
566 | set { | 574 | set { |
567 | _buoyancy = value; | 575 | _buoyancy = value; |
568 | _scene.TaintedObject(delegate() | 576 | _scene.TaintedObject("BSPrim.setBuoyancy", delegate() |
569 | { | 577 | { |
570 | DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 578 | // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
571 | BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); | 579 | BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); |
572 | }); | 580 | }); |
573 | } | 581 | } |
@@ -607,6 +615,7 @@ public sealed class BSPrim : PhysicsActor | |||
607 | 615 | ||
608 | private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>(); | 616 | private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>(); |
609 | public override void AddForce(OMV.Vector3 force, bool pushforce) { | 617 | public override void AddForce(OMV.Vector3 force, bool pushforce) { |
618 | // for an object, doesn't matter if force is a pushforce or not | ||
610 | if (force.IsFinite()) | 619 | if (force.IsFinite()) |
611 | { | 620 | { |
612 | // _force += force; | 621 | // _force += force; |
@@ -618,40 +627,48 @@ public sealed class BSPrim : PhysicsActor | |||
618 | m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); | 627 | m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); |
619 | return; | 628 | return; |
620 | } | 629 | } |
621 | _scene.TaintedObject(delegate() | 630 | _scene.TaintedObject("BSPrim.AddForce", delegate() |
622 | { | 631 | { |
632 | OMV.Vector3 fSum = OMV.Vector3.Zero; | ||
623 | lock (m_accumulatedForces) | 633 | lock (m_accumulatedForces) |
624 | { | 634 | { |
625 | if (m_accumulatedForces.Count > 0) | 635 | foreach (OMV.Vector3 v in m_accumulatedForces) |
626 | { | 636 | { |
627 | OMV.Vector3 fSum = OMV.Vector3.Zero; | 637 | fSum += v; |
628 | foreach (OMV.Vector3 v in m_accumulatedForces) | ||
629 | { | ||
630 | fSum += v; | ||
631 | } | ||
632 | m_accumulatedForces.Clear(); | ||
633 | |||
634 | DetailLog("{0},SetObjectForce,taint,force={1}", LocalID, fSum); | ||
635 | BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, fSum); | ||
636 | } | 638 | } |
639 | m_accumulatedForces.Clear(); | ||
637 | } | 640 | } |
641 | // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); | ||
642 | BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); | ||
638 | }); | 643 | }); |
639 | } | 644 | } |
640 | 645 | ||
641 | public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { | 646 | public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { |
642 | DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); | 647 | // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); |
643 | // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); | 648 | // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); |
644 | } | 649 | } |
645 | public override void SetMomentum(OMV.Vector3 momentum) { | 650 | public override void SetMomentum(OMV.Vector3 momentum) { |
646 | DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum); | 651 | // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); |
647 | } | 652 | } |
648 | public override void SubscribeEvents(int ms) { | 653 | public override void SubscribeEvents(int ms) { |
649 | _subscribedEventsMs = ms; | 654 | _subscribedEventsMs = ms; |
650 | // make sure first collision happens | 655 | if (ms > 0) |
651 | _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; | 656 | { |
657 | // make sure first collision happens | ||
658 | _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; | ||
659 | |||
660 | Scene.TaintedObject("BSPrim.SubscribeEvents", delegate() | ||
661 | { | ||
662 | BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
663 | }); | ||
664 | } | ||
652 | } | 665 | } |
653 | public override void UnSubscribeEvents() { | 666 | public override void UnSubscribeEvents() { |
654 | _subscribedEventsMs = 0; | 667 | _subscribedEventsMs = 0; |
668 | Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate() | ||
669 | { | ||
670 | BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
671 | }); | ||
655 | } | 672 | } |
656 | public override bool SubscribedEvents() { | 673 | public override bool SubscribedEvents() { |
657 | return (_subscribedEventsMs > 0); | 674 | return (_subscribedEventsMs > 0); |
@@ -970,26 +987,26 @@ public sealed class BSPrim : PhysicsActor | |||
970 | { | 987 | { |
971 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) | 988 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) |
972 | { | 989 | { |
973 | if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) | 990 | // if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) |
974 | { | 991 | // { |
975 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); | 992 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); |
976 | if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) | 993 | if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) |
977 | { | 994 | { |
978 | DetailLog("{0},CreateGeom,sphere", LocalID); | 995 | // DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); |
979 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; | 996 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; |
980 | // Bullet native objects are scaled by the Bullet engine so pass the size in | 997 | // Bullet native objects are scaled by the Bullet engine so pass the size in |
981 | _scale = _size; | 998 | _scale = _size; |
982 | // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? | 999 | // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? |
983 | ret = true; | 1000 | ret = true; |
984 | } | 1001 | } |
985 | } | 1002 | // } |
986 | } | 1003 | } |
987 | else | 1004 | else |
988 | { | 1005 | { |
989 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); | 1006 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); |
990 | if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) | 1007 | if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) |
991 | { | 1008 | { |
992 | DetailLog("{0},CreateGeom,box", LocalID); | 1009 | // DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); |
993 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; | 1010 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; |
994 | _scale = _size; | 1011 | _scale = _size; |
995 | // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? | 1012 | // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? |
@@ -1032,12 +1049,12 @@ public sealed class BSPrim : PhysicsActor | |||
1032 | // if this new shape is the same as last time, don't recreate the mesh | 1049 | // if this new shape is the same as last time, don't recreate the mesh |
1033 | if (_meshKey == newMeshKey) return; | 1050 | if (_meshKey == newMeshKey) return; |
1034 | 1051 | ||
1035 | DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, _meshKey); | 1052 | // DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); |
1036 | // Since we're recreating new, get rid of any previously generated shape | 1053 | // Since we're recreating new, get rid of any previously generated shape |
1037 | if (_meshKey != 0) | 1054 | if (_meshKey != 0) |
1038 | { | 1055 | { |
1039 | // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); | 1056 | // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); |
1040 | DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); | 1057 | // DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); |
1041 | BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); | 1058 | BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); |
1042 | _mesh = null; | 1059 | _mesh = null; |
1043 | _meshKey = 0; | 1060 | _meshKey = 0; |
@@ -1067,7 +1084,7 @@ public sealed class BSPrim : PhysicsActor | |||
1067 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; | 1084 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; |
1068 | // meshes are already scaled by the meshmerizer | 1085 | // meshes are already scaled by the meshmerizer |
1069 | _scale = new OMV.Vector3(1f, 1f, 1f); | 1086 | _scale = new OMV.Vector3(1f, 1f, 1f); |
1070 | DetailLog("{0},CreateGeomMesh,done", LocalID); | 1087 | // DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); |
1071 | return; | 1088 | return; |
1072 | } | 1089 | } |
1073 | 1090 | ||
@@ -1081,28 +1098,21 @@ public sealed class BSPrim : PhysicsActor | |||
1081 | // if the hull hasn't changed, don't rebuild it | 1098 | // if the hull hasn't changed, don't rebuild it |
1082 | if (newHullKey == _hullKey) return; | 1099 | if (newHullKey == _hullKey) return; |
1083 | 1100 | ||
1084 | DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey); | 1101 | // DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); |
1085 | 1102 | ||
1086 | // Since we're recreating new, get rid of any previously generated shape | 1103 | // Since we're recreating new, get rid of any previously generated shape |
1087 | if (_hullKey != 0) | 1104 | if (_hullKey != 0) |
1088 | { | 1105 | { |
1089 | // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); | 1106 | // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); |
1090 | DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey); | 1107 | // DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); |
1091 | BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); | 1108 | BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); |
1092 | _hullKey = 0; | 1109 | _hullKey = 0; |
1093 | _hulls.Clear(); | ||
1094 | DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); | ||
1095 | BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); | ||
1096 | _mesh = null; // the mesh cannot match either | ||
1097 | _meshKey = 0; | ||
1098 | } | 1110 | } |
1099 | 1111 | ||
1100 | _hullKey = newHullKey; | 1112 | _hullKey = newHullKey; |
1101 | if (_meshKey != _hullKey) | 1113 | |
1102 | { | 1114 | // Make sure the underlying mesh exists and is correct |
1103 | // if the underlying mesh has changed, rebuild it | 1115 | CreateGeomMesh(); |
1104 | CreateGeomMesh(); | ||
1105 | } | ||
1106 | 1116 | ||
1107 | int[] indices = _mesh.getIndexListAsInt(); | 1117 | int[] indices = _mesh.getIndexListAsInt(); |
1108 | List<OMV.Vector3> vertices = _mesh.getVertexList(); | 1118 | List<OMV.Vector3> vertices = _mesh.getVertexList(); |
@@ -1128,7 +1138,7 @@ public sealed class BSPrim : PhysicsActor | |||
1128 | // create the hull into the _hulls variable | 1138 | // create the hull into the _hulls variable |
1129 | convexBuilder.process(dcomp); | 1139 | convexBuilder.process(dcomp); |
1130 | 1140 | ||
1131 | // Convert the vertices and indices for passing to unmanaged | 1141 | // Convert the vertices and indices for passing to unmanaged. |
1132 | // The hull information is passed as a large floating point array. | 1142 | // The hull information is passed as a large floating point array. |
1133 | // The format is: | 1143 | // The format is: |
1134 | // convHulls[0] = number of hulls | 1144 | // convHulls[0] = number of hulls |
@@ -1188,7 +1198,7 @@ public sealed class BSPrim : PhysicsActor | |||
1188 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; | 1198 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; |
1189 | // meshes are already scaled by the meshmerizer | 1199 | // meshes are already scaled by the meshmerizer |
1190 | _scale = new OMV.Vector3(1f, 1f, 1f); | 1200 | _scale = new OMV.Vector3(1f, 1f, 1f); |
1191 | DetailLog("{0},CreateGeomHull,done", LocalID); | 1201 | // DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); |
1192 | return; | 1202 | return; |
1193 | } | 1203 | } |
1194 | 1204 | ||
@@ -1214,7 +1224,7 @@ public sealed class BSPrim : PhysicsActor | |||
1214 | bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); | 1224 | bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); |
1215 | 1225 | ||
1216 | // the CreateObject() may have recreated the rigid body. Make sure we have the latest. | 1226 | // the CreateObject() may have recreated the rigid body. Make sure we have the latest. |
1217 | m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID); | 1227 | Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); |
1218 | 1228 | ||
1219 | return ret; | 1229 | return ret; |
1220 | } | 1230 | } |
@@ -1326,8 +1336,8 @@ public sealed class BSPrim : PhysicsActor | |||
1326 | 1336 | ||
1327 | // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", | 1337 | // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", |
1328 | // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | 1338 | // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); |
1329 | DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 1339 | // DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
1330 | LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | 1340 | // LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); |
1331 | 1341 | ||
1332 | base.RequestPhysicsterseUpdate(); | 1342 | base.RequestPhysicsterseUpdate(); |
1333 | } | 1343 | } |
@@ -1335,7 +1345,7 @@ public sealed class BSPrim : PhysicsActor | |||
1335 | else | 1345 | else |
1336 | { | 1346 | { |
1337 | // For debugging, we also report the movement of children | 1347 | // For debugging, we also report the movement of children |
1338 | DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 1348 | DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
1339 | LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, | 1349 | LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, |
1340 | entprop.Acceleration, entprop.RotationalVelocity); | 1350 | entprop.Acceleration, entprop.RotationalVelocity); |
1341 | } | 1351 | } |
@@ -1343,7 +1353,7 @@ public sealed class BSPrim : PhysicsActor | |||
1343 | } | 1353 | } |
1344 | 1354 | ||
1345 | // I've collided with something | 1355 | // I've collided with something |
1346 | CollisionEventUpdate collisionCollection = null; | 1356 | CollisionEventUpdate collisionCollection; |
1347 | public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) | 1357 | public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) |
1348 | { | 1358 | { |
1349 | // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); | 1359 | // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); |
@@ -1355,6 +1365,8 @@ public sealed class BSPrim : PhysicsActor | |||
1355 | _collidingGroundStep = _scene.SimulationStep; | 1365 | _collidingGroundStep = _scene.SimulationStep; |
1356 | } | 1366 | } |
1357 | 1367 | ||
1368 | // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); | ||
1369 | |||
1358 | // if someone is subscribed to collision events.... | 1370 | // if someone is subscribed to collision events.... |
1359 | if (_subscribedEventsMs != 0) { | 1371 | if (_subscribedEventsMs != 0) { |
1360 | // throttle the collisions to the number of milliseconds specified in the subscription | 1372 | // throttle the collisions to the number of milliseconds specified in the subscription |
@@ -1375,7 +1387,9 @@ public sealed class BSPrim : PhysicsActor | |||
1375 | if (collisionCollection != null && collisionCollection.Count > 0) | 1387 | if (collisionCollection != null && collisionCollection.Count > 0) |
1376 | { | 1388 | { |
1377 | base.SendCollisionUpdate(collisionCollection); | 1389 | base.SendCollisionUpdate(collisionCollection); |
1378 | collisionCollection.Clear(); | 1390 | // The collisionCollection structure is passed around in the simulator. |
1391 | // Make sure we don't have a handle to that one and that a new one is used next time. | ||
1392 | collisionCollection = null; | ||
1379 | } | 1393 | } |
1380 | } | 1394 | } |
1381 | 1395 | ||