aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs331
1 files changed, 217 insertions, 114 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 130f1ca..71a4303 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -42,6 +42,8 @@ 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); }
46
45 private IMesh _mesh; 47 private IMesh _mesh;
46 private PrimitiveBaseShape _pbs; 48 private PrimitiveBaseShape _pbs;
47 private ShapeData.PhysicsShapeType _shapeType; 49 private ShapeData.PhysicsShapeType _shapeType;
@@ -50,6 +52,7 @@ public sealed class BSPrim : PhysicsActor
50 private List<ConvexResult> _hulls; 52 private List<ConvexResult> _hulls;
51 53
52 private BSScene _scene; 54 private BSScene _scene;
55 public BSScene Scene { get { return _scene; } }
53 private String _avName; 56 private String _avName;
54 private uint _localID = 0; 57 private uint _localID = 0;
55 58
@@ -86,8 +89,8 @@ public sealed class BSPrim : PhysicsActor
86 private bool _kinematic; 89 private bool _kinematic;
87 private float _buoyancy; 90 private float _buoyancy;
88 91
89 private List<BSPrim> _childrenPrims;
90 private BSPrim _parentPrim; 92 private BSPrim _parentPrim;
93 private List<BSPrim> _childrenPrims;
91 94
92 private int _subscribedEventsMs = 0; 95 private int _subscribedEventsMs = 0;
93 private int _nextCollisionOkTime = 0; 96 private int _nextCollisionOkTime = 0;
@@ -145,9 +148,19 @@ public sealed class BSPrim : PhysicsActor
145 public void Destroy() 148 public void Destroy()
146 { 149 {
147 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 150 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
151 // DetailLog("{0},Destroy", LocalID);
148 // Undo any vehicle properties 152 // Undo any vehicle properties
149 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); 153 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
150 _scene.RemoveVehiclePrim(this); // just to make sure 154 _scene.RemoveVehiclePrim(this); // just to make sure
155
156 // undo any dependance with/on other objects
157 if (_parentPrim != null)
158 {
159 // If I'm someone's child, tell them to forget about me.
160 _parentPrim.RemoveChildFromLinkset(this);
161 _parentPrim = null;
162 }
163
151 _scene.TaintedObject(delegate() 164 _scene.TaintedObject(delegate()
152 { 165 {
153 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. 166 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
@@ -202,7 +215,8 @@ public sealed class BSPrim : PhysicsActor
202 // link me to the specified parent 215 // link me to the specified parent
203 public override void link(PhysicsActor obj) { 216 public override void link(PhysicsActor obj) {
204 BSPrim parent = obj as BSPrim; 217 BSPrim parent = obj as BSPrim;
205 // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); 218 DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
219 DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
206 // TODO: decide if this parent checking needs to happen at taint time 220 // TODO: decide if this parent checking needs to happen at taint time
207 if (_parentPrim == null) 221 if (_parentPrim == null)
208 { 222 {
@@ -225,7 +239,7 @@ public sealed class BSPrim : PhysicsActor
225 else 239 else
226 { 240 {
227 // asking to reparent a prim should not happen 241 // asking to reparent a prim should not happen
228 m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader); 242 m_log.ErrorFormat("{0}: link(): Reparenting a prim. ", LogHeader);
229 } 243 }
230 } 244 }
231 } 245 }
@@ -236,7 +250,9 @@ public sealed class BSPrim : PhysicsActor
236 public override void delink() { 250 public override void delink() {
237 // TODO: decide if this parent checking needs to happen at taint time 251 // TODO: decide if this parent checking needs to happen at taint time
238 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 252 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
239 // m_log.DebugFormat("{0}: delink {1}/{2}", LogHeader, _avName, _localID); 253 DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
254 (_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString()));
255 DetailLog("{0},delink,parent={1}", LocalID, (_parentPrim==null ? "NULL" : _parentPrim.LocalID.ToString()));
240 if (_parentPrim != null) 256 if (_parentPrim != null)
241 { 257 {
242 _parentPrim.RemoveChildFromLinkset(this); 258 _parentPrim.RemoveChildFromLinkset(this);
@@ -252,8 +268,10 @@ public sealed class BSPrim : PhysicsActor
252 { 268 {
253 if (!_childrenPrims.Contains(child)) 269 if (!_childrenPrims.Contains(child))
254 { 270 {
271 DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID);
272 DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID);
255 _childrenPrims.Add(child); 273 _childrenPrims.Add(child);
256 child.ParentPrim = this; // the child has gained a parent 274 child._parentPrim = this; // the child has gained a parent
257 RecreateGeomAndObject(); // rebuild my shape with the new child added 275 RecreateGeomAndObject(); // rebuild my shape with the new child added
258 } 276 }
259 }); 277 });
@@ -269,9 +287,14 @@ public sealed class BSPrim : PhysicsActor
269 { 287 {
270 if (_childrenPrims.Contains(child)) 288 if (_childrenPrims.Contains(child))
271 { 289 {
272 BulletSimAPI.RemoveConstraint(_scene.WorldID, child.LocalID, this.LocalID); 290 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
291 DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID);
292 if (!BulletSimAPI.RemoveConstraintByID(_scene.WorldID, child.LocalID))
293 {
294 m_log.ErrorFormat("{0}: RemoveChildFromLinkset: Failed remove constraint for {1}", LogHeader, child.LocalID);
295 }
273 _childrenPrims.Remove(child); 296 _childrenPrims.Remove(child);
274 child.ParentPrim = null; // the child has lost its parent 297 child._parentPrim = null; // the child has lost its parent
275 RecreateGeomAndObject(); // rebuild my shape with the child removed 298 RecreateGeomAndObject(); // rebuild my shape with the child removed
276 } 299 }
277 else 300 else
@@ -282,11 +305,6 @@ public sealed class BSPrim : PhysicsActor
282 return; 305 return;
283 } 306 }
284 307
285 public BSPrim ParentPrim
286 {
287 set { _parentPrim = value; }
288 }
289
290 // return true if we are the root of a linkset (there are children to manage) 308 // return true if we are the root of a linkset (there are children to manage)
291 public bool IsRootOfLinkset 309 public bool IsRootOfLinkset
292 { 310 {
@@ -304,20 +322,28 @@ public sealed class BSPrim : PhysicsActor
304 base.RequestPhysicsterseUpdate(); 322 base.RequestPhysicsterseUpdate();
305 } 323 }
306 324
307 public override void LockAngularMotion(OMV.Vector3 axis) { return; } 325 public override void LockAngularMotion(OMV.Vector3 axis)
326 {
327 DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis);
328 return;
329 }
308 330
309 public override OMV.Vector3 Position { 331 public override OMV.Vector3 Position {
310 get { 332 get {
311 // don't do the following GetObjectPosition because this function is called a zillion times 333 // child prims move around based on their parent. Need to get the latest location
334 if (_parentPrim != null)
335 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
336 // don't do the GetObjectPosition for root elements because this function is called a zillion times
312 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 337 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
313 return _position; 338 return _position;
314 } 339 }
315 set { 340 set {
316 _position = value; 341 _position = value;
342 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
317 _scene.TaintedObject(delegate() 343 _scene.TaintedObject(delegate()
318 { 344 {
345 DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
319 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 346 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
320 // m_log.DebugFormat("{0}: setPosition: id={1}, position={2}", LogHeader, _localID, _position);
321 }); 347 });
322 } 348 }
323 } 349 }
@@ -330,6 +356,7 @@ public sealed class BSPrim : PhysicsActor
330 _force = value; 356 _force = value;
331 _scene.TaintedObject(delegate() 357 _scene.TaintedObject(delegate()
332 { 358 {
359 DetailLog("{0},SetForce,taint,force={1}", LocalID, _force);
333 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 360 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
334 }); 361 });
335 } 362 }
@@ -341,15 +368,23 @@ public sealed class BSPrim : PhysicsActor
341 } 368 }
342 set { 369 set {
343 Vehicle type = (Vehicle)value; 370 Vehicle type = (Vehicle)value;
344 _vehicle.ProcessTypeChange(type);
345 _scene.TaintedObject(delegate() 371 _scene.TaintedObject(delegate()
346 { 372 {
373 DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type);
374 _vehicle.ProcessTypeChange(type);
347 if (type == Vehicle.TYPE_NONE) 375 if (type == Vehicle.TYPE_NONE)
348 { 376 {
349 _scene.RemoveVehiclePrim(this); 377 _scene.RemoveVehiclePrim(this);
350 } 378 }
351 else 379 else
352 { 380 {
381 _scene.TaintedObject(delegate()
382 {
383 // Tell the physics engine to clear state
384 IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID);
385 BulletSimAPI.ClearForces2(obj);
386 });
387
353 // make it so the scene will call us each tick to do vehicle things 388 // make it so the scene will call us each tick to do vehicle things
354 _scene.AddVehiclePrim(this); 389 _scene.AddVehiclePrim(this);
355 } 390 }
@@ -359,37 +394,52 @@ public sealed class BSPrim : PhysicsActor
359 } 394 }
360 public override void VehicleFloatParam(int param, float value) 395 public override void VehicleFloatParam(int param, float value)
361 { 396 {
362 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); 397 m_log.DebugFormat("{0} VehicleFloatParam. {1} <= {2}", LogHeader, param, value);
398 _scene.TaintedObject(delegate()
399 {
400 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
401 });
363 } 402 }
364 public override void VehicleVectorParam(int param, OMV.Vector3 value) 403 public override void VehicleVectorParam(int param, OMV.Vector3 value)
365 { 404 {
366 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); 405 m_log.DebugFormat("{0} VehicleVectorParam. {1} <= {2}", LogHeader, param, value);
406 _scene.TaintedObject(delegate()
407 {
408 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
409 });
367 } 410 }
368 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) 411 public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
369 { 412 {
370 _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); 413 m_log.DebugFormat("{0} VehicleRotationParam. {1} <= {2}", LogHeader, param, rotation);
414 _scene.TaintedObject(delegate()
415 {
416 _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
417 });
371 } 418 }
372 public override void VehicleFlags(int param, bool remove) 419 public override void VehicleFlags(int param, bool remove)
373 { 420 {
374 _vehicle.ProcessVehicleFlags(param, remove); 421 m_log.DebugFormat("{0} VehicleFlags. {1}. Remove={2}", LogHeader, param, remove);
422 _scene.TaintedObject(delegate()
423 {
424 _vehicle.ProcessVehicleFlags(param, remove);
425 });
375 } 426 }
376 // Called each simulation step to advance vehicle characteristics 427
428 // Called each simulation step to advance vehicle characteristics.
429 // Called from Scene when doing simulation step so we're in taint processing time.
377 public void StepVehicle(float timeStep) 430 public void StepVehicle(float timeStep)
378 { 431 {
379 _vehicle.Step(timeStep, _scene); 432 _vehicle.Step(timeStep);
380 } 433 }
381 434
382 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more 435 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
383 public override void SetVolumeDetect(int param) { 436 public override void SetVolumeDetect(int param) {
384 bool newValue = (param != 0); 437 bool newValue = (param != 0);
385 if (_isVolumeDetect != newValue) 438 _isVolumeDetect = newValue;
439 _scene.TaintedObject(delegate()
386 { 440 {
387 _isVolumeDetect = newValue; 441 SetObjectDynamic();
388 _scene.TaintedObject(delegate() 442 });
389 {
390 SetObjectDynamic();
391 });
392 }
393 return; 443 return;
394 } 444 }
395 445
@@ -397,9 +447,11 @@ public sealed class BSPrim : PhysicsActor
397 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } 447 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
398 public override OMV.Vector3 Velocity { 448 public override OMV.Vector3 Velocity {
399 get { return _velocity; } 449 get { return _velocity; }
400 set { _velocity = value; 450 set {
451 _velocity = value;
401 _scene.TaintedObject(delegate() 452 _scene.TaintedObject(delegate()
402 { 453 {
454 DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity);
403 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 455 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
404 }); 456 });
405 } 457 }
@@ -407,6 +459,7 @@ public sealed class BSPrim : PhysicsActor
407 public override OMV.Vector3 Torque { 459 public override OMV.Vector3 Torque {
408 get { return _torque; } 460 get { return _torque; }
409 set { _torque = value; 461 set { _torque = value;
462 DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque);
410 } 463 }
411 } 464 }
412 public override float CollisionScore { 465 public override float CollisionScore {
@@ -419,13 +472,21 @@ public sealed class BSPrim : PhysicsActor
419 set { _acceleration = value; } 472 set { _acceleration = value; }
420 } 473 }
421 public override OMV.Quaternion Orientation { 474 public override OMV.Quaternion Orientation {
422 get { return _orientation; } 475 get {
476 if (_parentPrim != null)
477 {
478 // children move around because tied to parent. Get a fresh value.
479 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
480 }
481 return _orientation;
482 }
423 set { 483 set {
424 _orientation = value; 484 _orientation = value;
425 // m_log.DebugFormat("{0}: set orientation: id={1}, ori={2}", LogHeader, LocalID, _orientation); 485 // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
426 _scene.TaintedObject(delegate() 486 _scene.TaintedObject(delegate()
427 { 487 {
428 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 488 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
489 DetailLog("{0},SetOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
429 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 490 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
430 }); 491 });
431 } 492 }
@@ -458,8 +519,9 @@ public sealed class BSPrim : PhysicsActor
458 get { return !IsPhantom && !_isVolumeDetect; } 519 get { return !IsPhantom && !_isVolumeDetect; }
459 } 520 }
460 521
461 // make gravity work if the object is physical and not selected 522 // Make gravity work if the object is physical and not selected
462 // no locking here because only called when it is safe 523 // No locking here because only called when it is safe
524 // Only called at taint time so it is save to call into Bullet.
463 private void SetObjectDynamic() 525 private void SetObjectDynamic()
464 { 526 {
465 // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); 527 // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid);
@@ -476,6 +538,7 @@ public sealed class BSPrim : PhysicsActor
476 RecreateGeomAndObject(); 538 RecreateGeomAndObject();
477 539
478 } 540 }
541 DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, _mass);
479 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); 542 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass);
480 } 543 }
481 544
@@ -516,11 +579,24 @@ public sealed class BSPrim : PhysicsActor
516 set { _floatOnWater = value; } 579 set { _floatOnWater = value; }
517 } 580 }
518 public override OMV.Vector3 RotationalVelocity { 581 public override OMV.Vector3 RotationalVelocity {
519 get { return _rotationalVelocity; } 582 get {
520 set { _rotationalVelocity = value; 583 /*
584 OMV.Vector3 pv = OMV.Vector3.Zero;
585 // if close to zero, report zero
586 // This is copied from ODE but I'm not sure why it returns zero but doesn't
587 // zero the property in the physics engine.
588 if (_rotationalVelocity.ApproxEquals(pv, 0.2f))
589 return pv;
590 */
591
592 return _rotationalVelocity;
593 }
594 set {
595 _rotationalVelocity = value;
521 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 596 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
522 _scene.TaintedObject(delegate() 597 _scene.TaintedObject(delegate()
523 { 598 {
599 DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
524 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 600 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
525 }); 601 });
526 } 602 }
@@ -533,11 +609,13 @@ public sealed class BSPrim : PhysicsActor
533 } 609 }
534 public override float Buoyancy { 610 public override float Buoyancy {
535 get { return _buoyancy; } 611 get { return _buoyancy; }
536 set { _buoyancy = value; 612 set {
537 _scene.TaintedObject(delegate() 613 _buoyancy = value;
538 { 614 _scene.TaintedObject(delegate()
539 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 615 {
540 }); 616 DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
617 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
618 });
541 } 619 }
542 } 620 }
543 621
@@ -573,27 +651,45 @@ public sealed class BSPrim : PhysicsActor
573 public override float APIDStrength { set { return; } } 651 public override float APIDStrength { set { return; } }
574 public override float APIDDamping { set { return; } } 652 public override float APIDDamping { set { return; } }
575 653
654 private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>();
576 public override void AddForce(OMV.Vector3 force, bool pushforce) { 655 public override void AddForce(OMV.Vector3 force, bool pushforce) {
577 if (force.IsFinite()) 656 if (force.IsFinite())
578 { 657 {
579 _force.X += force.X; 658 // _force += force;
580 _force.Y += force.Y; 659 lock (m_accumulatedForces)
581 _force.Z += force.Z; 660 m_accumulatedForces.Add(new OMV.Vector3(force));
582 } 661 }
583 else 662 else
584 { 663 {
585 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); 664 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
665 return;
586 } 666 }
587 _scene.TaintedObject(delegate() 667 _scene.TaintedObject(delegate()
588 { 668 {
589 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 669 lock (m_accumulatedForces)
670 {
671 if (m_accumulatedForces.Count > 0)
672 {
673 OMV.Vector3 fSum = OMV.Vector3.Zero;
674 foreach (OMV.Vector3 v in m_accumulatedForces)
675 {
676 fSum += v;
677 }
678 m_accumulatedForces.Clear();
679
680 DetailLog("{0},SetObjectForce,taint,force={1}", LocalID, fSum);
681 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, fSum);
682 }
683 }
590 }); 684 });
591 } 685 }
592 686
593 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 687 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
688 DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
594 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); 689 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
595 } 690 }
596 public override void SetMomentum(OMV.Vector3 momentum) { 691 public override void SetMomentum(OMV.Vector3 momentum) {
692 DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum);
597 } 693 }
598 public override void SubscribeEvents(int ms) { 694 public override void SubscribeEvents(int ms) {
599 _subscribedEventsMs = ms; 695 _subscribedEventsMs = ms;
@@ -918,6 +1014,7 @@ public sealed class BSPrim : PhysicsActor
918 { 1014 {
919 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 1015 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
920 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 1016 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
1017 DetailLog("{0},CreateGeom,sphere", LocalID);
921 // Bullet native objects are scaled by the Bullet engine so pass the size in 1018 // Bullet native objects are scaled by the Bullet engine so pass the size in
922 _scale = _size; 1019 _scale = _size;
923 } 1020 }
@@ -925,6 +1022,7 @@ public sealed class BSPrim : PhysicsActor
925 else 1022 else
926 { 1023 {
927 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); 1024 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
1025 DetailLog("{0},CreateGeom,box", LocalID);
928 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1026 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
929 _scale = _size; 1027 _scale = _size;
930 } 1028 }
@@ -961,10 +1059,12 @@ public sealed class BSPrim : PhysicsActor
961 // if this new shape is the same as last time, don't recreate the mesh 1059 // if this new shape is the same as last time, don't recreate the mesh
962 if (_meshKey == newMeshKey) return; 1060 if (_meshKey == newMeshKey) return;
963 1061
1062 DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, _meshKey);
964 // Since we're recreating new, get rid of any previously generated shape 1063 // Since we're recreating new, get rid of any previously generated shape
965 if (_meshKey != 0) 1064 if (_meshKey != 0)
966 { 1065 {
967 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); 1066 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
1067 DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
968 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1068 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
969 _mesh = null; 1069 _mesh = null;
970 _meshKey = 0; 1070 _meshKey = 0;
@@ -981,7 +1081,6 @@ public sealed class BSPrim : PhysicsActor
981 int vi = 0; 1081 int vi = 0;
982 foreach (OMV.Vector3 vv in vertices) 1082 foreach (OMV.Vector3 vv in vertices)
983 { 1083 {
984 // m_log.DebugFormat("{0}: {1}: <{2:0.00}, {3:0.00}, {4:0.00}>", LogHeader, vi / 3, vv.X, vv.Y, vv.Z);
985 verticesAsFloats[vi++] = vv.X; 1084 verticesAsFloats[vi++] = vv.X;
986 verticesAsFloats[vi++] = vv.Y; 1085 verticesAsFloats[vi++] = vv.Y;
987 verticesAsFloats[vi++] = vv.Z; 1086 verticesAsFloats[vi++] = vv.Z;
@@ -995,6 +1094,7 @@ public sealed class BSPrim : PhysicsActor
995 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1094 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
996 // meshes are already scaled by the meshmerizer 1095 // meshes are already scaled by the meshmerizer
997 _scale = new OMV.Vector3(1f, 1f, 1f); 1096 _scale = new OMV.Vector3(1f, 1f, 1f);
1097 DetailLog("{0},CreateGeomMesh,done", LocalID);
998 return; 1098 return;
999 } 1099 }
1000 1100
@@ -1008,13 +1108,17 @@ public sealed class BSPrim : PhysicsActor
1008 // if the hull hasn't changed, don't rebuild it 1108 // if the hull hasn't changed, don't rebuild it
1009 if (newHullKey == _hullKey) return; 1109 if (newHullKey == _hullKey) return;
1010 1110
1111 DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey);
1112
1011 // Since we're recreating new, get rid of any previously generated shape 1113 // Since we're recreating new, get rid of any previously generated shape
1012 if (_hullKey != 0) 1114 if (_hullKey != 0)
1013 { 1115 {
1014 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); 1116 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1117 DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey);
1015 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); 1118 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1016 _hullKey = 0; 1119 _hullKey = 0;
1017 _hulls.Clear(); 1120 _hulls.Clear();
1121 DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey);
1018 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1122 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1019 _mesh = null; // the mesh cannot match either 1123 _mesh = null; // the mesh cannot match either
1020 _meshKey = 0; 1124 _meshKey = 0;
@@ -1111,6 +1215,7 @@ public sealed class BSPrim : PhysicsActor
1111 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1215 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1112 // meshes are already scaled by the meshmerizer 1216 // meshes are already scaled by the meshmerizer
1113 _scale = new OMV.Vector3(1f, 1f, 1f); 1217 _scale = new OMV.Vector3(1f, 1f, 1f);
1218 DetailLog("{0},CreateGeomHull,done", LocalID);
1114 return; 1219 return;
1115 } 1220 }
1116 1221
@@ -1129,7 +1234,6 @@ public sealed class BSPrim : PhysicsActor
1129 if (IsRootOfLinkset) 1234 if (IsRootOfLinkset)
1130 { 1235 {
1131 // Create a linkset around this object 1236 // Create a linkset around this object
1132 // CreateLinksetWithCompoundHull();
1133 CreateLinksetWithConstraints(); 1237 CreateLinksetWithConstraints();
1134 } 1238 }
1135 else 1239 else
@@ -1191,33 +1295,33 @@ public sealed class BSPrim : PhysicsActor
1191 // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added 1295 // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
1192 void CreateLinksetWithConstraints() 1296 void CreateLinksetWithConstraints()
1193 { 1297 {
1194 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); 1298 DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
1195 1299
1196 // remove any constraints that might be in place 1300 // remove any constraints that might be in place
1197 foreach (BSPrim prim in _childrenPrims) 1301 foreach (BSPrim prim in _childrenPrims)
1198 { 1302 {
1199 // m_log.DebugFormat("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); 1303 DebugLog("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1200 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID); 1304 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
1201 } 1305 }
1202 // create constraints between the root prim and each of the children 1306 // create constraints between the root prim and each of the children
1203 foreach (BSPrim prim in _childrenPrims) 1307 foreach (BSPrim prim in _childrenPrims)
1204 { 1308 {
1205 // m_log.DebugFormat("{0}: CreateLinkset: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1206
1207 // Zero motion for children so they don't interpolate 1309 // Zero motion for children so they don't interpolate
1208 prim.ZeroMotion(); 1310 prim.ZeroMotion();
1209 1311
1210 // relative position normalized to the root prim 1312 // relative position normalized to the root prim
1211 OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation); 1313 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
1314 OMV.Vector3 childRelativePosition = (prim._position - this._position) * invThisOrientation;
1212 1315
1213 // relative rotation of the child to the parent 1316 // relative rotation of the child to the parent
1214 OMV.Quaternion relativeRotation = OMV.Quaternion.Inverse(prim._orientation) * this._orientation; 1317 OMV.Quaternion childRelativeRotation = invThisOrientation * prim._orientation;
1215 1318
1216 // this is a constraint that allows no freedom of movement between the two objects 1319 // this is a constraint that allows no freedom of movement between the two objects
1217 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 1320 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1321 DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1218 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, 1322 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
1219 childRelativePosition, 1323 childRelativePosition,
1220 relativeRotation, 1324 childRelativeRotation,
1221 OMV.Vector3.Zero, 1325 OMV.Vector3.Zero,
1222 OMV.Quaternion.Identity, 1326 OMV.Quaternion.Identity,
1223 OMV.Vector3.Zero, OMV.Vector3.Zero, 1327 OMV.Vector3.Zero, OMV.Vector3.Zero,
@@ -1252,78 +1356,71 @@ public sealed class BSPrim : PhysicsActor
1252 const float POSITION_TOLERANCE = 0.05f; 1356 const float POSITION_TOLERANCE = 0.05f;
1253 const float ACCELERATION_TOLERANCE = 0.01f; 1357 const float ACCELERATION_TOLERANCE = 0.01f;
1254 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; 1358 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1255 const bool SHOULD_DAMP_UPDATES = false;
1256 1359
1257 public void UpdateProperties(EntityProperties entprop) 1360 public void UpdateProperties(EntityProperties entprop)
1258 { 1361 {
1362 /*
1259 UpdatedProperties changed = 0; 1363 UpdatedProperties changed = 0;
1260 if (SHOULD_DAMP_UPDATES) 1364 // assign to the local variables so the normal set action does not happen
1365 // if (_position != entprop.Position)
1366 if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
1261 { 1367 {
1262 // assign to the local variables so the normal set action does not happen 1368 _position = entprop.Position;
1263 // if (_position != entprop.Position) 1369 changed |= UpdatedProperties.Position;
1264 if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
1265 {
1266 _position = entprop.Position;
1267 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position);
1268 changed |= UpdatedProperties.Position;
1269 }
1270 // if (_orientation != entprop.Rotation)
1271 if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
1272 {
1273 _orientation = entprop.Rotation;
1274 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation);
1275 changed |= UpdatedProperties.Rotation;
1276 }
1277 // if (_velocity != entprop.Velocity)
1278 if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
1279 {
1280 _velocity = entprop.Velocity;
1281 // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
1282 changed |= UpdatedProperties.Velocity;
1283 }
1284 // if (_acceleration != entprop.Acceleration)
1285 if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
1286 {
1287 _acceleration = entprop.Acceleration;
1288 // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
1289 changed |= UpdatedProperties.Acceleration;
1290 }
1291 // if (_rotationalVelocity != entprop.RotationalVelocity)
1292 if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
1293 {
1294 _rotationalVelocity = entprop.RotationalVelocity;
1295 // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity);
1296 changed |= UpdatedProperties.RotationalVel;
1297 }
1298 if (changed != 0)
1299 {
1300 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1301 // Only update the position of single objects and linkset roots
1302 if (this._parentPrim == null)
1303 {
1304 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1305 base.RequestPhysicsterseUpdate();
1306 }
1307 }
1308 } 1370 }
1309 else 1371 // if (_orientation != entprop.Rotation)
1372 if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
1310 { 1373 {
1311 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1374 _orientation = entprop.Rotation;
1312 1375 changed |= UpdatedProperties.Rotation;
1313 // Only updates only for individual prims and for the root object of a linkset. 1376 }
1377 // if (_velocity != entprop.Velocity)
1378 if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
1379 {
1380 _velocity = entprop.Velocity;
1381 changed |= UpdatedProperties.Velocity;
1382 }
1383 // if (_acceleration != entprop.Acceleration)
1384 if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
1385 {
1386 _acceleration = entprop.Acceleration;
1387 changed |= UpdatedProperties.Acceleration;
1388 }
1389 // if (_rotationalVelocity != entprop.RotationalVelocity)
1390 if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
1391 {
1392 _rotationalVelocity = entprop.RotationalVelocity;
1393 changed |= UpdatedProperties.RotationalVel;
1394 }
1395 if (changed != 0)
1396 {
1397 // Only update the position of single objects and linkset roots
1314 if (this._parentPrim == null) 1398 if (this._parentPrim == null)
1315 { 1399 {
1316 // Assign to the local variables so the normal set action does not happen
1317 _position = entprop.Position;
1318 _orientation = entprop.Rotation;
1319 _velocity = entprop.Velocity;
1320 _acceleration = entprop.Acceleration;
1321 _rotationalVelocity = entprop.RotationalVelocity;
1322 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
1323 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1324 base.RequestPhysicsterseUpdate(); 1400 base.RequestPhysicsterseUpdate();
1325 } 1401 }
1326 } 1402 }
1403 */
1404
1405 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1406
1407 // Updates only for individual prims and for the root object of a linkset.
1408 if (this._parentPrim == null)
1409 {
1410 // Assign to the local variables so the normal set action does not happen
1411 _position = entprop.Position;
1412 _orientation = entprop.Rotation;
1413 _velocity = entprop.Velocity;
1414 _acceleration = entprop.Acceleration;
1415 _rotationalVelocity = entprop.RotationalVelocity;
1416
1417 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
1418 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1419 DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1420 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1421
1422 base.RequestPhysicsterseUpdate();
1423 }
1327 } 1424 }
1328 1425
1329 // I've collided with something 1426 // I've collided with something
@@ -1362,5 +1459,11 @@ public sealed class BSPrim : PhysicsActor
1362 collisionCollection.Clear(); 1459 collisionCollection.Clear();
1363 } 1460 }
1364 } 1461 }
1462
1463 // Invoke the detailed logger and output something if it's enabled.
1464 private void DetailLog(string msg, params Object[] args)
1465 {
1466 Scene.PhysicsLogging.Write(msg, args);
1467 }
1365} 1468}
1366} 1469}