aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs232
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