aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs151
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs7
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs237
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs93
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs64
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs272
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs437
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs464
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs559
9 files changed, 1646 insertions, 638 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e2f7af9..fa22c78 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -34,13 +34,12 @@ using OpenSim.Region.Physics.Manager;
34 34
35namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public class BSCharacter : PhysicsActor 37public class BSCharacter : BSPhysObject
38{ 38{
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 private BSScene _scene; 42 public BSScene Scene { get; private set; }
43 public BSScene Scene { get { return _scene; } }
44 private String _avName; 43 private String _avName;
45 // private bool _stopped; 44 // private bool _stopped;
46 private Vector3 _size; 45 private Vector3 _size;
@@ -74,11 +73,9 @@ public class BSCharacter : PhysicsActor
74 private bool _kinematic; 73 private bool _kinematic;
75 private float _buoyancy; 74 private float _buoyancy;
76 75
77 private BulletBody m_body; 76 public override BulletBody BSBody { get; set; }
78 public BulletBody Body { 77 public override BulletShape BSShape { get; set; }
79 get { return m_body; } 78 public override BSLinkset Linkset { get; set; }
80 set { m_body = value; }
81 }
82 79
83 private int _subscribedEventsMs = 0; 80 private int _subscribedEventsMs = 0;
84 private int _nextCollisionOkTime = 0; 81 private int _nextCollisionOkTime = 0;
@@ -95,7 +92,8 @@ public class BSCharacter : PhysicsActor
95 { 92 {
96 _localID = localID; 93 _localID = localID;
97 _avName = avName; 94 _avName = avName;
98 _scene = parent_scene; 95 Scene = parent_scene;
96 _physicsActorType = (int)ActorTypes.Agent;
99 _position = pos; 97 _position = pos;
100 _size = size; 98 _size = size;
101 _flying = isFlying; 99 _flying = isFlying;
@@ -104,10 +102,12 @@ public class BSCharacter : PhysicsActor
104 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 102 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
105 // The dimensions of the avatar capsule are kept in the scale. 103 // The dimensions of the avatar capsule are kept in the scale.
106 // Physics creates a unit capsule which is scaled by the physics engine. 104 // Physics creates a unit capsule which is scaled by the physics engine.
107 _scale = new Vector3(_scene.Params.avatarCapsuleRadius, _scene.Params.avatarCapsuleRadius, size.Z); 105 _scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z);
108 _density = _scene.Params.avatarDensity; 106 _density = Scene.Params.avatarDensity;
109 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 107 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
110 108
109 Linkset = new BSLinkset(Scene, this);
110
111 ShapeData shapeData = new ShapeData(); 111 ShapeData shapeData = new ShapeData();
112 shapeData.ID = _localID; 112 shapeData.ID = _localID;
113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; 113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
@@ -118,29 +118,33 @@ public class BSCharacter : PhysicsActor
118 shapeData.Mass = _mass; 118 shapeData.Mass = _mass;
119 shapeData.Buoyancy = _buoyancy; 119 shapeData.Buoyancy = _buoyancy;
120 shapeData.Static = ShapeData.numericFalse; 120 shapeData.Static = ShapeData.numericFalse;
121 shapeData.Friction = _scene.Params.avatarFriction; 121 shapeData.Friction = Scene.Params.avatarFriction;
122 shapeData.Restitution = _scene.Params.avatarRestitution; 122 shapeData.Restitution = Scene.Params.avatarRestitution;
123 123
124 // do actual create at taint time 124 // do actual create at taint time
125 _scene.TaintedObject("BSCharacter.create", delegate() 125 Scene.TaintedObject("BSCharacter.create", delegate()
126 { 126 {
127 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); 127 DetailLog("{0},BSCharacter.create", _localID);
128 BulletSimAPI.CreateObject(Scene.WorldID, shapeData);
129
130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
131 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
128 132
129 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 133 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
130 // avatars get all collisions no matter what 134 // avatars get all collisions no matter what (makes walking on ground and such work)
131 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 135 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
132 }); 136 });
133 137
134 return; 138 return;
135 } 139 }
136 140
137 // called when this character is being destroyed and the resources should be released 141 // called when this character is being destroyed and the resources should be released
138 public void Destroy() 142 public override void Destroy()
139 { 143 {
140 // DetailLog("{0},BSCharacter.Destroy", LocalID); 144 DetailLog("{0},BSCharacter.Destroy", LocalID);
141 _scene.TaintedObject("BSCharacter.destroy", delegate() 145 Scene.TaintedObject("BSCharacter.destroy", delegate()
142 { 146 {
143 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 147 BulletSimAPI.DestroyObject(Scene.WorldID, _localID);
144 }); 148 });
145 } 149 }
146 150
@@ -169,9 +173,9 @@ public class BSCharacter : PhysicsActor
169 173
170 ComputeAvatarVolumeAndMass(); 174 ComputeAvatarVolumeAndMass();
171 175
172 _scene.TaintedObject("BSCharacter.setSize", delegate() 176 Scene.TaintedObject("BSCharacter.setSize", delegate()
173 { 177 {
174 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true); 178 BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true);
175 }); 179 });
176 180
177 } 181 }
@@ -200,17 +204,17 @@ public class BSCharacter : PhysicsActor
200 204
201 public override Vector3 Position { 205 public override Vector3 Position {
202 get { 206 get {
203 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 207 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
204 return _position; 208 return _position;
205 } 209 }
206 set { 210 set {
207 _position = value; 211 _position = value;
208 PositionSanityCheck(); 212 PositionSanityCheck();
209 213
210 _scene.TaintedObject("BSCharacter.setPosition", delegate() 214 Scene.TaintedObject("BSCharacter.setPosition", delegate()
211 { 215 {
212 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 216 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
213 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 217 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
214 }); 218 });
215 } 219 }
216 } 220 }
@@ -223,16 +227,35 @@ public class BSCharacter : PhysicsActor
223 bool ret = false; 227 bool ret = false;
224 228
225 // If below the ground, move the avatar up 229 // If below the ground, move the avatar up
226 float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); 230 float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position);
227 if (_position.Z < terrainHeight) 231 if (Position.Z < terrainHeight)
228 { 232 {
229 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); 233 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
230 _position.Z = terrainHeight + 2.0f; 234 _position.Z = terrainHeight + 2.0f;
231 ret = true; 235 ret = true;
232 } 236 }
233 237
234 // TODO: check for out of bounds 238 // TODO: check for out of bounds
239 return ret;
240 }
235 241
242 // A version of the sanity check that also makes sure a new position value is
243 // pushed back to the physics engine. This routine would be used by anyone
244 // who is not already pushing the value.
245 private bool PositionSanityCheck2()
246 {
247 bool ret = false;
248 if (PositionSanityCheck())
249 {
250 // The new position value must be pushed into the physics engine but we can't
251 // just assign to "Position" because of potential call loops.
252 Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
253 {
254 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
255 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
256 });
257 ret = true;
258 }
236 return ret; 259 return ret;
237 } 260 }
238 261
@@ -241,6 +264,10 @@ public class BSCharacter : PhysicsActor
241 return _mass; 264 return _mass;
242 } 265 }
243 } 266 }
267
268 // used when we only want this prim's mass and not the linkset thing
269 public override float MassRaw { get {return _mass; } }
270
244 public override Vector3 Force { 271 public override Vector3 Force {
245 get { return _force; } 272 get { return _force; }
246 set { 273 set {
@@ -273,10 +300,10 @@ public class BSCharacter : PhysicsActor
273 set { 300 set {
274 _velocity = value; 301 _velocity = value;
275 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); 302 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
276 _scene.TaintedObject("BSCharacter.setVelocity", delegate() 303 Scene.TaintedObject("BSCharacter.setVelocity", delegate()
277 { 304 {
278 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); 305 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
279 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); 306 BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity);
280 }); 307 });
281 } 308 }
282 } 309 }
@@ -299,10 +326,10 @@ public class BSCharacter : PhysicsActor
299 set { 326 set {
300 _orientation = value; 327 _orientation = value;
301 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 328 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
302 _scene.TaintedObject("BSCharacter.setOrientation", delegate() 329 Scene.TaintedObject("BSCharacter.setOrientation", delegate()
303 { 330 {
304 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 331 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
305 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 332 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
306 }); 333 });
307 } 334 }
308 } 335 }
@@ -319,14 +346,13 @@ public class BSCharacter : PhysicsActor
319 public override bool Flying { 346 public override bool Flying {
320 get { return _flying; } 347 get { return _flying; }
321 set { 348 set {
322 if (_flying != value) 349 _flying = value;
323 { 350 // simulate flying by changing the effect of gravity
324 _flying = value; 351 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
325 // simulate flying by changing the effect of gravity
326 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
327 }
328 } 352 }
329 } 353 }
354 // Flying is implimented by changing the avatar's buoyancy.
355 // Would this be done better with a vehicle type?
330 private float ComputeBuoyancyFromFlying(bool ifFlying) { 356 private float ComputeBuoyancyFromFlying(bool ifFlying) {
331 return ifFlying ? 1f : 0f; 357 return ifFlying ? 1f : 0f;
332 } 358 }
@@ -340,11 +366,11 @@ public class BSCharacter : PhysicsActor
340 set { _throttleUpdates = value; } 366 set { _throttleUpdates = value; }
341 } 367 }
342 public override bool IsColliding { 368 public override bool IsColliding {
343 get { return (_collidingStep == _scene.SimulationStep); } 369 get { return (_collidingStep == Scene.SimulationStep); }
344 set { _isColliding = value; } 370 set { _isColliding = value; }
345 } 371 }
346 public override bool CollidingGround { 372 public override bool CollidingGround {
347 get { return (_collidingGroundStep == _scene.SimulationStep); } 373 get { return (_collidingGroundStep == Scene.SimulationStep); }
348 set { _collidingGround = value; } 374 set { _collidingGround = value; }
349 } 375 }
350 public override bool CollidingObj { 376 public override bool CollidingObj {
@@ -366,10 +392,10 @@ public class BSCharacter : PhysicsActor
366 public override float Buoyancy { 392 public override float Buoyancy {
367 get { return _buoyancy; } 393 get { return _buoyancy; }
368 set { _buoyancy = value; 394 set { _buoyancy = value;
369 _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() 395 Scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
370 { 396 {
371 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 397 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
372 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 398 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
373 }); 399 });
374 } 400 }
375 } 401 }
@@ -413,10 +439,10 @@ public class BSCharacter : PhysicsActor
413 _force.Y += force.Y; 439 _force.Y += force.Y;
414 _force.Z += force.Z; 440 _force.Z += force.Z;
415 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); 441 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
416 _scene.TaintedObject("BSCharacter.AddForce", delegate() 442 Scene.TaintedObject("BSCharacter.AddForce", delegate()
417 { 443 {
418 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); 444 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
419 BulletSimAPI.AddObjectForce2(Body.Ptr, _force); 445 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
420 }); 446 });
421 } 447 }
422 else 448 else
@@ -441,10 +467,16 @@ public class BSCharacter : PhysicsActor
441 467
442 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate() 468 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
443 { 469 {
444 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 470 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
445 }); 471 });
446 } 472 }
447 } 473 }
474
475 public override void ZeroMotion()
476 {
477 return;
478 }
479
448 // Stop collision events 480 // Stop collision events
449 public override void UnSubscribeEvents() { 481 public override void UnSubscribeEvents() {
450 _subscribedEventsMs = 0; 482 _subscribedEventsMs = 0;
@@ -478,7 +510,7 @@ public class BSCharacter : PhysicsActor
478 510
479 // The physics engine says that properties have updated. Update same and inform 511 // The physics engine says that properties have updated. Update same and inform
480 // the world that things have changed. 512 // the world that things have changed.
481 public void UpdateProperties(EntityProperties entprop) 513 public override void UpdateProperties(EntityProperties entprop)
482 { 514 {
483 _position = entprop.Position; 515 _position = entprop.Position;
484 _orientation = entprop.Rotation; 516 _orientation = entprop.Rotation;
@@ -488,32 +520,33 @@ public class BSCharacter : PhysicsActor
488 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 520 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
489 // base.RequestPhysicsterseUpdate(); 521 // base.RequestPhysicsterseUpdate();
490 522
491 /* 523 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
492 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 524 PositionSanityCheck2();
493 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 525
494 entprop.Acceleration, entprop.RotationalVelocity); 526 float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
495 */ 527 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
528 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
496 } 529 }
497 530
498 // Called by the scene when a collision with this object is reported 531 // Called by the scene when a collision with this object is reported
499 // The collision, if it should be reported to the character, is placed in a collection 532 // The collision, if it should be reported to the character, is placed in a collection
500 // that will later be sent to the simulator when SendCollisions() is called. 533 // that will later be sent to the simulator when SendCollisions() is called.
501 CollisionEventUpdate collisionCollection = null; 534 CollisionEventUpdate collisionCollection = null;
502 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) 535 public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
503 { 536 {
504 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 537 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
505 538
506 // The following makes IsColliding() and IsCollidingGround() work 539 // The following makes IsColliding() and IsCollidingGround() work
507 _collidingStep = _scene.SimulationStep; 540 _collidingStep = Scene.SimulationStep;
508 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) 541 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
509 { 542 {
510 _collidingGroundStep = _scene.SimulationStep; 543 _collidingGroundStep = Scene.SimulationStep;
511 } 544 }
512 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); 545 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
513 546
514 // throttle collisions to the rate specified in the subscription 547 // throttle collisions to the rate specified in the subscription
515 if (_subscribedEventsMs != 0) { 548 if (_subscribedEventsMs != 0) {
516 int nowTime = _scene.SimulationNowTime; 549 int nowTime = Scene.SimulationNowTime;
517 if (nowTime >= _nextCollisionOkTime) { 550 if (nowTime >= _nextCollisionOkTime) {
518 _nextCollisionOkTime = nowTime + _subscribedEventsMs; 551 _nextCollisionOkTime = nowTime + _subscribedEventsMs;
519 552
@@ -524,7 +557,7 @@ public class BSCharacter : PhysicsActor
524 } 557 }
525 } 558 }
526 559
527 public void SendCollisions() 560 public override void SendCollisions()
528 { 561 {
529 /* 562 /*
530 if (collisionCollection != null && collisionCollection.Count > 0) 563 if (collisionCollection != null && collisionCollection.Count > 0)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 25084d8..2e15ced 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -48,11 +48,10 @@ public abstract class BSConstraint : IDisposable
48 { 48 {
49 if (m_enabled) 49 if (m_enabled)
50 { 50 {
51 // BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID); 51 m_enabled = false;
52 bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); 52 bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
53 m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); 53 m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
54 m_constraint.Ptr = System.IntPtr.Zero; 54 m_constraint.Ptr = System.IntPtr.Zero;
55 m_enabled = false;
56 } 55 }
57 } 56 }
58 57
@@ -99,6 +98,10 @@ public abstract class BSConstraint : IDisposable
99 { 98 {
100 // m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}", 99 // m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}",
101 // BSScene.DetailLogZero, Body1.ID, Body2.ID); 100 // BSScene.DetailLogZero, Body1.ID, Body2.ID);
101
102 // Setting an object's mass to zero (making it static like when it's selected)
103 // automatically disables the constraints.
104 // If enabled, be sure to set the constraint itself to enabled.
102 BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true)); 105 BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
103 } 106 }
104 else 107 else
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 5a9f135..8169e99 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
57 private int frcount = 0; // Used to limit dynamics debug output to 57 private int frcount = 0; // Used to limit dynamics debug output to
58 // every 100th frame 58 // every 100th frame
59 59
60 private BSScene m_physicsScene;
60 private BSPrim m_prim; // the prim this dynamic controller belongs to 61 private BSPrim m_prim; // the prim this dynamic controller belongs to
61 62
62 // Vehicle properties 63 // Vehicle properties
@@ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
74 // HOVER_UP_ONLY 75 // HOVER_UP_ONLY
75 // LIMIT_MOTOR_UP 76 // LIMIT_MOTOR_UP
76 // LIMIT_ROLL_ONLY 77 // LIMIT_ROLL_ONLY
77 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
78 private Vector3 m_BlockingEndPoint = Vector3.Zero; 78 private Vector3 m_BlockingEndPoint = Vector3.Zero;
79 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 79 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
80 // Linear properties 80 // Linear properties
@@ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 private float m_verticalAttractionEfficiency = 1.0f; // damped 124 private float m_verticalAttractionEfficiency = 1.0f; // damped
125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
126 126
127 public BSDynamics(BSPrim myPrim) 127 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 128 {
129 m_physicsScene = myScene;
129 m_prim = myPrim; 130 m_prim = myPrim;
130 m_type = Vehicle.TYPE_NONE; 131 m_type = Vehicle.TYPE_NONE;
131 } 132 }
132 133
133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) 134 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
134 { 135 {
135 DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 136 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
136 switch (pParam) 137 switch (pParam)
137 { 138 {
138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 139 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
231 232
232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) 233 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
233 { 234 {
234 DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 235 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
235 switch (pParam) 236 switch (pParam)
236 { 237 {
237 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 238 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
266 267
267 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 268 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
268 { 269 {
269 DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 270 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
270 switch (pParam) 271 switch (pParam)
271 { 272 {
272 case Vehicle.REFERENCE_FRAME: 273 case Vehicle.REFERENCE_FRAME:
@@ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
280 281
281 internal void ProcessVehicleFlags(int pParam, bool remove) 282 internal void ProcessVehicleFlags(int pParam, bool remove)
282 { 283 {
283 DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); 284 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
285 VehicleFlag parm = (VehicleFlag)pParam;
284 if (remove) 286 if (remove)
285 { 287 {
286 if (pParam == -1) 288 if (pParam == -1)
287 { 289 {
288 m_flags = (VehicleFlag)0; 290 m_flags = (VehicleFlag)0;
289 m_Hoverflags = (VehicleFlag)0;
290 return;
291 } 291 }
292 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) 292 else
293 {
294 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
295 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
296 }
297 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 {
299 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
300 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
301 }
302 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
303 {
304 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
305 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
306 }
307 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
308 {
309 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
310 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
311 }
312 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
313 {
314 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
315 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
316 }
317 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
318 {
319 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
320 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
321 }
322 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
323 {
324 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
325 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
326 }
327 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
328 {
329 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
330 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
331 }
332 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
333 {
334 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
335 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
336 }
337 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
338 {
339 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
340 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
341 }
342 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
343 {
344 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
345 m_flags &= ~(VehicleFlag.NO_X);
346 }
347 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
348 {
349 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
350 m_flags &= ~(VehicleFlag.NO_Y);
351 }
352 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
353 {
354 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
355 m_flags &= ~(VehicleFlag.NO_Z);
356 }
357 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
358 {
359 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
360 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
361 }
362 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
363 {
364 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
365 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
366 }
367 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
368 { 293 {
369 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) 294 m_flags &= ~parm;
370 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
371 } 295 }
372 } 296 }
373 else 297 else {
374 { 298 m_flags |= parm;
375 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
376 {
377 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
378 }
379 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
380 {
381 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
382 }
383 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
384 {
385 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
386 }
387 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
388 {
389 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
390 }
391 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
392 {
393 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
394 }
395 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
396 {
397 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
398 }
399 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
400 {
401 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
402 }
403 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
404 {
405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
406 }
407 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
408 {
409 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
410 }
411 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
412 {
413 m_flags |= (VehicleFlag.NO_X);
414 }
415 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
416 {
417 m_flags |= (VehicleFlag.NO_Y);
418 }
419 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
420 {
421 m_flags |= (VehicleFlag.NO_Z);
422 }
423 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
424 {
425 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
426 }
427 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
428 {
429 m_flags |= (VehicleFlag.NO_DEFLECTION);
430 }
431 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
432 {
433 m_flags |= (VehicleFlag.LOCK_ROTATION);
434 }
435 } 299 }
436 }//end ProcessVehicleFlags 300 }//end ProcessVehicleFlags
437 301
438 internal void ProcessTypeChange(Vehicle pType) 302 internal void ProcessTypeChange(Vehicle pType, float stepSize)
439 { 303 {
440 DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); 304 VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
441 // Set Defaults For Type 305 // Set Defaults For Type
442 m_type = pType; 306 m_type = pType;
443 switch (pType) 307 switch (pType)
@@ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
478 // m_bankingMix = 1; 342 // m_bankingMix = 1;
479 // m_bankingTimescale = 10; 343 // m_bankingTimescale = 10;
480 // m_referenceFrame = Quaternion.Identity; 344 // m_referenceFrame = Quaternion.Identity;
481 m_Hoverflags &= 345 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
346 m_flags &=
482 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 347 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
483 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 348 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
484 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
485 break; 349 break;
486 case Vehicle.TYPE_CAR: 350 case Vehicle.TYPE_CAR:
487 m_linearFrictionTimescale = new Vector3(100, 2, 1000); 351 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
@@ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
506 // m_bankingMix = 1; 370 // m_bankingMix = 1;
507 // m_bankingTimescale = 1; 371 // m_bankingTimescale = 1;
508 // m_referenceFrame = Quaternion.Identity; 372 // m_referenceFrame = Quaternion.Identity;
509 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
510 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | 373 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
511 VehicleFlag.LIMIT_MOTOR_UP); 374 VehicleFlag.LIMIT_MOTOR_UP);
512 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); 375 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
376 m_flags |= (VehicleFlag.HOVER_UP_ONLY);
513 break; 377 break;
514 case Vehicle.TYPE_BOAT: 378 case Vehicle.TYPE_BOAT:
515 m_linearFrictionTimescale = new Vector3(10, 3, 2); 379 m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
534 // m_bankingMix = 0.8f; 398 // m_bankingMix = 0.8f;
535 // m_bankingTimescale = 1; 399 // m_bankingTimescale = 1;
536 // m_referenceFrame = Quaternion.Identity; 400 // m_referenceFrame = Quaternion.Identity;
537 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | 401 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
538 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 402 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
539 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); 403 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
540 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | 404 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
541 VehicleFlag.LIMIT_MOTOR_UP); 405 VehicleFlag.LIMIT_MOTOR_UP);
542 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); 406 m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
543 break; 407 break;
544 case Vehicle.TYPE_AIRPLANE: 408 case Vehicle.TYPE_AIRPLANE:
545 m_linearFrictionTimescale = new Vector3(200, 10, 5); 409 m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
564 // m_bankingMix = 0.7f; 428 // m_bankingMix = 0.7f;
565 // m_bankingTimescale = 2; 429 // m_bankingTimescale = 2;
566 // m_referenceFrame = Quaternion.Identity; 430 // m_referenceFrame = Quaternion.Identity;
567 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 431 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
568 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 432 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
569 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 433 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
570 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 434 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@@ -592,15 +456,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
592 // m_bankingMix = 0.7f; 456 // m_bankingMix = 0.7f;
593 // m_bankingTimescale = 5; 457 // m_bankingTimescale = 5;
594 // m_referenceFrame = Quaternion.Identity; 458 // m_referenceFrame = Quaternion.Identity;
595 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 459 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
596 VehicleFlag.HOVER_UP_ONLY); 460 VehicleFlag.HOVER_UP_ONLY);
597 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 461 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
598 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 462 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
599 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); 463 m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
600 break; 464 break;
601 } 465 }
602 }//end SetDefaultsForType 466 }//end SetDefaultsForType
603 467
468 // One step of the vehicle properties for the next 'pTimestep' seconds.
604 internal void Step(float pTimestep) 469 internal void Step(float pTimestep)
605 { 470 {
606 if (m_type == Vehicle.TYPE_NONE) return; 471 if (m_type == Vehicle.TYPE_NONE) return;
@@ -613,7 +478,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
613 MoveAngular(pTimestep); 478 MoveAngular(pTimestep);
614 LimitRotation(pTimestep); 479 LimitRotation(pTimestep);
615 480
616 DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 481 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
617 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); 482 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
618 }// end Step 483 }// end Step
619 484
@@ -657,7 +522,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
657 522
658 */ 523 */
659 524
660 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", 525 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
661 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); 526 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
662 } 527 }
663 else 528 else
@@ -669,7 +534,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
669 m_lastLinearVelocityVector = Vector3.Zero; 534 m_lastLinearVelocityVector = Vector3.Zero;
670 } 535 }
671 536
672 // convert requested object velocity to world-referenced vector 537 // convert requested object velocity to object relative vector
673 Quaternion rotq = m_prim.Orientation; 538 Quaternion rotq = m_prim.Orientation;
674 m_dir = m_lastLinearVelocityVector * rotq; 539 m_dir = m_lastLinearVelocityVector * rotq;
675 540
@@ -722,42 +587,42 @@ namespace OpenSim.Region.Physics.BulletSPlugin
722 if (changed) 587 if (changed)
723 { 588 {
724 m_prim.Position = pos; 589 m_prim.Position = pos;
725 DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 590 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
726 m_prim.LocalID, m_BlockingEndPoint, posChange, pos); 591 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
727 } 592 }
728 } 593 }
729 594
730 // If below the terrain, move us above the ground a little. 595 // If below the terrain, move us above the ground a little.
731 if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos)) 596 if (pos.Z < m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos))
732 { 597 {
733 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; 598 pos.Z = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2;
734 m_prim.Position = pos; 599 m_prim.Position = pos;
735 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); 600 VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
736 } 601 }
737 602
738 // Check if hovering 603 // Check if hovering
739 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 604 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
740 { 605 {
741 // We should hover, get the target height 606 // We should hover, get the target height
742 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) 607 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
743 { 608 {
744 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; 609 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
745 } 610 }
746 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 611 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
747 { 612 {
748 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; 613 m_VhoverTargetHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
749 } 614 }
750 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) 615 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
751 { 616 {
752 m_VhoverTargetHeight = m_VhoverHeight; 617 m_VhoverTargetHeight = m_VhoverHeight;
753 } 618 }
754 619
755 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) 620 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
756 { 621 {
757 // If body is aready heigher, use its height as target height 622 // If body is aready heigher, use its height as target height
758 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 623 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
759 } 624 }
760 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 625 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
761 { 626 {
762 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 627 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
763 { 628 {
@@ -779,7 +644,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
779 } 644 }
780 } 645 }
781 646
782 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); 647 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
783 648
784// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped 649// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
785// m_VhoverTimescale = 0f; // time to acheive height 650// m_VhoverTimescale = 0f; // time to acheive height
@@ -809,13 +674,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
809 { 674 {
810 grav.Z = (float)(grav.Z * 1.125); 675 grav.Z = (float)(grav.Z * 1.125);
811 } 676 }
812 float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos); 677 float terraintemp = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
813 float postemp = (pos.Z - terraintemp); 678 float postemp = (pos.Z - terraintemp);
814 if (postemp > 2.5f) 679 if (postemp > 2.5f)
815 { 680 {
816 grav.Z = (float)(grav.Z * 1.037125); 681 grav.Z = (float)(grav.Z * 1.037125);
817 } 682 }
818 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); 683 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
819 //End Experimental Values 684 //End Experimental Values
820 } 685 }
821 if ((m_flags & (VehicleFlag.NO_X)) != 0) 686 if ((m_flags & (VehicleFlag.NO_X)) != 0)
@@ -844,7 +709,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
844 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); 709 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
845 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; 710 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
846 711
847 DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", 712 VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
848 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); 713 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
849 714
850 } // end MoveLinear() 715 } // end MoveLinear()
@@ -870,13 +735,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
870 // There are m_angularMotorApply steps. 735 // There are m_angularMotorApply steps.
871 Vector3 origAngularVelocity = m_angularMotorVelocity; 736 Vector3 origAngularVelocity = m_angularMotorVelocity;
872 // ramp up to new value 737 // ramp up to new value
873 // current velocity += error / (time to get there / step interval) 738 // current velocity += error / (time to get there / step interval)
874 // requested speed - last motor speed 739 // requested speed - last motor speed
875 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); 740 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
876 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); 741 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
877 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); 742 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
878 743
879 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", 744 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
880 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); 745 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
881 746
882 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected 747 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
@@ -887,6 +752,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
887 // No motor recently applied, keep the body velocity 752 // No motor recently applied, keep the body velocity
888 // and decay the velocity 753 // and decay the velocity
889 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); 754 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
755 if (m_angularMotorVelocity.LengthSquared() < 0.00001)
756 m_angularMotorVelocity = Vector3.Zero;
890 } // end motor section 757 } // end motor section
891 758
892 // Vertical attractor section 759 // Vertical attractor section
@@ -924,7 +791,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
924 vertattr.X += bounce * angularVelocity.X; 791 vertattr.X += bounce * angularVelocity.X;
925 vertattr.Y += bounce * angularVelocity.Y; 792 vertattr.Y += bounce * angularVelocity.Y;
926 793
927 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 794 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
928 m_prim.LocalID, verterr, bounce, vertattr); 795 m_prim.LocalID, verterr, bounce, vertattr);
929 796
930 } // else vertical attractor is off 797 } // else vertical attractor is off
@@ -942,13 +809,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
942 { 809 {
943 m_lastAngularVelocity.X = 0; 810 m_lastAngularVelocity.X = 0;
944 m_lastAngularVelocity.Y = 0; 811 m_lastAngularVelocity.Y = 0;
945 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 812 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
946 } 813 }
947 814
948 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 815 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
949 { 816 {
950 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 817 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
951 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 818 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
952 } 819 }
953 820
954 // apply friction 821 // apply friction
@@ -958,7 +825,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
958 // Apply to the body 825 // Apply to the body
959 m_prim.RotationalVelocity = m_lastAngularVelocity; 826 m_prim.RotationalVelocity = m_lastAngularVelocity;
960 827
961 DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); 828 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
962 } //end MoveAngular 829 } //end MoveAngular
963 830
964 internal void LimitRotation(float timestep) 831 internal void LimitRotation(float timestep)
@@ -1005,11 +872,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1005 if (changed) 872 if (changed)
1006 m_prim.Orientation = m_rot; 873 m_prim.Orientation = m_rot;
1007 874
1008 DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); 875 VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
1009 } 876 }
1010 877
1011 // Invoke the detailed logger and output something if it's enabled. 878 // Invoke the detailed logger and output something if it's enabled.
1012 private void DetailLog(string msg, params Object[] args) 879 private void VDetailLog(string msg, params Object[] args)
1013 { 880 {
1014 if (m_prim.Scene.VehicleLoggingEnabled) 881 if (m_prim.Scene.VehicleLoggingEnabled)
1015 m_prim.Scene.PhysicsLogging.Write(msg, args); 882 m_prim.Scene.PhysicsLogging.Write(msg, args);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 087b9bb..5f6601d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -36,14 +36,17 @@ public class BSLinkset
36{ 36{
37 private static string LogHeader = "[BULLETSIM LINKSET]"; 37 private static string LogHeader = "[BULLETSIM LINKSET]";
38 38
39 private BSPrim m_linksetRoot; 39 private BSPhysObject m_linksetRoot;
40 public BSPrim LinksetRoot { get { return m_linksetRoot; } } 40 public BSPhysObject LinksetRoot { get { return m_linksetRoot; } }
41 41
42 private BSScene m_physicsScene; 42 private BSScene m_physicsScene;
43 public BSScene PhysicsScene { get { return m_physicsScene; } } 43 public BSScene PhysicsScene { get { return m_physicsScene; } }
44 44
45 static int m_nextLinksetID = 1;
46 public int LinksetID { get; private set; }
47
45 // The children under the root in this linkset 48 // The children under the root in this linkset
46 private List<BSPrim> m_children; 49 private List<BSPhysObject> m_children;
47 50
48 // We lock the diddling of linkset classes to prevent any badness. 51 // We lock the diddling of linkset classes to prevent any badness.
49 // This locks the modification of the instances of this class. Changes 52 // This locks the modification of the instances of this class. Changes
@@ -71,19 +74,23 @@ public class BSLinkset
71 get { return ComputeLinksetGeometricCenter(); } 74 get { return ComputeLinksetGeometricCenter(); }
72 } 75 }
73 76
74 public BSLinkset(BSScene scene, BSPrim parent) 77 public BSLinkset(BSScene scene, BSPhysObject parent)
75 { 78 {
76 // A simple linkset of one (no children) 79 // A simple linkset of one (no children)
80 LinksetID = m_nextLinksetID++;
81 // We create LOTS of linksets.
82 if (m_nextLinksetID < 0)
83 m_nextLinksetID = 1;
77 m_physicsScene = scene; 84 m_physicsScene = scene;
78 m_linksetRoot = parent; 85 m_linksetRoot = parent;
79 m_children = new List<BSPrim>(); 86 m_children = new List<BSPhysObject>();
80 m_mass = parent.MassRaw; 87 m_mass = parent.MassRaw;
81 } 88 }
82 89
83 // Link to a linkset where the child knows the parent. 90 // Link to a linkset where the child knows the parent.
84 // Parent changing should not happen so do some sanity checking. 91 // Parent changing should not happen so do some sanity checking.
85 // We return the parent's linkset so the child can track its membership. 92 // We return the parent's linkset so the child can track its membership.
86 public BSLinkset AddMeToLinkset(BSPrim child) 93 public BSLinkset AddMeToLinkset(BSPhysObject child)
87 { 94 {
88 lock (m_linksetActivityLock) 95 lock (m_linksetActivityLock)
89 { 96 {
@@ -95,7 +102,7 @@ public class BSLinkset
95 // Remove a child from a linkset. 102 // Remove a child from a linkset.
96 // Returns a new linkset for the child which is a linkset of one (just the 103 // Returns a new linkset for the child which is a linkset of one (just the
97 // orphened child). 104 // orphened child).
98 public BSLinkset RemoveMeFromLinkset(BSPrim child) 105 public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
99 { 106 {
100 lock (m_linksetActivityLock) 107 lock (m_linksetActivityLock)
101 { 108 {
@@ -122,7 +129,7 @@ public class BSLinkset
122 } 129 }
123 130
124 // Return 'true' if the passed object is the root object of this linkset 131 // Return 'true' if the passed object is the root object of this linkset
125 public bool IsRoot(BSPrim requestor) 132 public bool IsRoot(BSPhysObject requestor)
126 { 133 {
127 return (requestor.LocalID == m_linksetRoot.LocalID); 134 return (requestor.LocalID == m_linksetRoot.LocalID);
128 } 135 }
@@ -133,12 +140,12 @@ public class BSLinkset
133 public bool HasAnyChildren { get { return (m_children.Count > 0); } } 140 public bool HasAnyChildren { get { return (m_children.Count > 0); } }
134 141
135 // Return 'true' if this child is in this linkset 142 // Return 'true' if this child is in this linkset
136 public bool HasChild(BSPrim child) 143 public bool HasChild(BSPhysObject child)
137 { 144 {
138 bool ret = false; 145 bool ret = false;
139 lock (m_linksetActivityLock) 146 lock (m_linksetActivityLock)
140 { 147 {
141 foreach (BSPrim bp in m_children) 148 foreach (BSPhysObject bp in m_children)
142 { 149 {
143 if (child.LocalID == bp.LocalID) 150 if (child.LocalID == bp.LocalID)
144 { 151 {
@@ -153,7 +160,7 @@ public class BSLinkset
153 private float ComputeLinksetMass() 160 private float ComputeLinksetMass()
154 { 161 {
155 float mass = m_linksetRoot.MassRaw; 162 float mass = m_linksetRoot.MassRaw;
156 foreach (BSPrim bp in m_children) 163 foreach (BSPhysObject bp in m_children)
157 { 164 {
158 mass += bp.MassRaw; 165 mass += bp.MassRaw;
159 } 166 }
@@ -167,7 +174,7 @@ public class BSLinkset
167 174
168 lock (m_linksetActivityLock) 175 lock (m_linksetActivityLock)
169 { 176 {
170 foreach (BSPrim bp in m_children) 177 foreach (BSPhysObject bp in m_children)
171 { 178 {
172 com += bp.Position * bp.MassRaw; 179 com += bp.Position * bp.MassRaw;
173 totalMass += bp.MassRaw; 180 totalMass += bp.MassRaw;
@@ -185,7 +192,7 @@ public class BSLinkset
185 192
186 lock (m_linksetActivityLock) 193 lock (m_linksetActivityLock)
187 { 194 {
188 foreach (BSPrim bp in m_children) 195 foreach (BSPhysObject bp in m_children)
189 { 196 {
190 com += bp.Position * bp.MassRaw; 197 com += bp.Position * bp.MassRaw;
191 } 198 }
@@ -197,7 +204,7 @@ public class BSLinkset
197 204
198 // When physical properties are changed the linkset needs to recalculate 205 // When physical properties are changed the linkset needs to recalculate
199 // its internal properties. 206 // its internal properties.
200 public void Refresh(BSPrim requestor) 207 public void Refresh(BSPhysObject requestor)
201 { 208 {
202 // If there are no children, there aren't any constraints to recompute 209 // If there are no children, there aren't any constraints to recompute
203 if (!HasAnyChildren) 210 if (!HasAnyChildren)
@@ -223,10 +230,10 @@ public class BSLinkset
223 float linksetMass = LinksetMass; 230 float linksetMass = LinksetMass;
224 lock (m_linksetActivityLock) 231 lock (m_linksetActivityLock)
225 { 232 {
226 foreach (BSPrim child in m_children) 233 foreach (BSPhysObject child in m_children)
227 { 234 {
228 BSConstraint constrain; 235 BSConstraint constrain;
229 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain)) 236 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain))
230 { 237 {
231 // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", 238 // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
232 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); 239 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
@@ -238,8 +245,8 @@ public class BSLinkset
238 // their constraints have not been created yet. 245 // their constraints have not been created yet.
239 // Caused by the fact that m_children is built at run time but building constraints 246 // Caused by the fact that m_children is built at run time but building constraints
240 // happens at taint time. 247 // happens at taint time.
241 // m_physicsScene.Logger.ErrorFormat("[BULLETSIM LINKSET] RecomputeLinksetConstraintVariables: constraint not found for root={0}, child={1}", 248 // m_physicsScene.Logger.ErrorFormat("{0} RecomputeLinksetConstraintVariables: constraint not found for root={1}, child={2}",
242 // m_linksetRoot.Body.ID, child.Body.ID); 249 // LogHeader, m_linksetRoot.Body.ID, child.Body.ID);
243 } 250 }
244 } 251 }
245 } 252 }
@@ -248,18 +255,17 @@ public class BSLinkset
248 255
249 // I am the root of a linkset and a new child is being added 256 // I am the root of a linkset and a new child is being added
250 // Called while LinkActivity is locked. 257 // Called while LinkActivity is locked.
251 private void AddChildToLinkset(BSPrim child) 258 private void AddChildToLinkset(BSPhysObject child)
252 { 259 {
253 if (!HasChild(child)) 260 if (!HasChild(child))
254 { 261 {
255 m_children.Add(child); 262 m_children.Add(child);
256 263
257 BSPrim rootx = LinksetRoot; // capture the root as of now 264 BSPhysObject rootx = LinksetRoot; // capture the root as of now
258 BSPrim childx = child; 265 BSPhysObject childx = child;
259 m_physicsScene.TaintedObject("AddChildToLinkset", delegate() 266 m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
260 { 267 {
261 // DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); 268 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
262 // DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
263 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child 269 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
264 }); 270 });
265 } 271 }
@@ -271,7 +277,7 @@ public class BSLinkset
271 // it's still connected to the linkset. 277 // it's still connected to the linkset.
272 // Normal OpenSimulator operation will never do this because other SceneObjectPart information 278 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
273 // has to be updated also (like pointer to prim's parent). 279 // has to be updated also (like pointer to prim's parent).
274 private void RemoveChildFromOtherLinkset(BSPrim pchild) 280 private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
275 { 281 {
276 pchild.Linkset = new BSLinkset(m_physicsScene, pchild); 282 pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
277 RemoveChildFromLinkset(pchild); 283 RemoveChildFromLinkset(pchild);
@@ -279,16 +285,15 @@ public class BSLinkset
279 285
280 // I am the root of a linkset and one of my children is being removed. 286 // I am the root of a linkset and one of my children is being removed.
281 // Safe to call even if the child is not really in my linkset. 287 // Safe to call even if the child is not really in my linkset.
282 private void RemoveChildFromLinkset(BSPrim child) 288 private void RemoveChildFromLinkset(BSPhysObject child)
283 { 289 {
284 if (m_children.Remove(child)) 290 if (m_children.Remove(child))
285 { 291 {
286 BSPrim rootx = LinksetRoot; // capture the root as of now 292 BSPhysObject rootx = LinksetRoot; // capture the root as of now
287 BSPrim childx = child; 293 BSPhysObject childx = child;
288 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 294 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
289 { 295 {
290 // DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 296 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
291 // DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
292 297
293 PhysicallyUnlinkAChildFromRoot(rootx, childx); 298 PhysicallyUnlinkAChildFromRoot(rootx, childx);
294 }); 299 });
@@ -305,7 +310,7 @@ public class BSLinkset
305 310
306 // Create a constraint between me (root of linkset) and the passed prim (the child). 311 // Create a constraint between me (root of linkset) and the passed prim (the child).
307 // Called at taint time! 312 // Called at taint time!
308 private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim) 313 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
309 { 314 {
310 // Zero motion for children so they don't interpolate 315 // Zero motion for children so they don't interpolate
311 childPrim.ZeroMotion(); 316 childPrim.ZeroMotion();
@@ -319,19 +324,18 @@ public class BSLinkset
319 324
320 // create a constraint that allows no freedom of movement between the two objects 325 // create a constraint that allows no freedom of movement between the two objects
321 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 326 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
322 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
323 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", 327 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
324 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); 328 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
325 BS6DofConstraint constrain = new BS6DofConstraint( 329 BS6DofConstraint constrain = new BS6DofConstraint(
326 m_physicsScene.World, rootPrim.Body, childPrim.Body, 330 m_physicsScene.World, rootPrim.BSBody, childPrim.BSBody,
327 midPoint, 331 midPoint,
328 true, 332 true,
329 true 333 true
330 ); 334 );
331 /* NOTE: attempt to build constraint with full frame computation, etc. 335 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
332 * Using the midpoint is easier since it lets the Bullet code use the transforms 336 * Using the midpoint is easier since it lets the Bullet code use the transforms
333 * of the objects. 337 * of the objects.
334 * Code left here as an example. 338 * Code left as a warning to future programmers.
335 // ================================================================================== 339 // ==================================================================================
336 // relative position normalized to the root prim 340 // relative position normalized to the root prim
337 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); 341 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@@ -343,7 +347,6 @@ public class BSLinkset
343 347
344 // create a constraint that allows no freedom of movement between the two objects 348 // create a constraint that allows no freedom of movement between the two objects
345 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 349 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
346 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
347 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 350 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
348 BS6DofConstraint constrain = new BS6DofConstraint( 351 BS6DofConstraint constrain = new BS6DofConstraint(
349 PhysicsScene.World, rootPrim.Body, childPrim.Body, 352 PhysicsScene.World, rootPrim.Body, childPrim.Body,
@@ -380,34 +383,24 @@ public class BSLinkset
380 383
381 // Remove linkage between myself and a particular child 384 // Remove linkage between myself and a particular child
382 // Called at taint time! 385 // Called at taint time!
383 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) 386 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
384 { 387 {
385 // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
386 // LogHeader, rootPrim.LocalID, childPrim.LocalID);
387 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 388 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
388 389
389 // Find the constraint for this link and get rid of it from the overall collection and from my list 390 // Find the constraint for this link and get rid of it from the overall collection and from my list
390 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); 391 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody);
391 392
392 // Make the child refresh its location 393 // Make the child refresh its location
393 BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); 394 BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr);
394 } 395 }
395 396
396 // Remove linkage between myself and any possible children I might have 397 // Remove linkage between myself and any possible children I might have
397 // Called at taint time! 398 // Called at taint time!
398 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) 399 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
399 { 400 {
400 // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
402 402
403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); 403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody);
404 }
405
406 // Invoke the detailed logger and output something if it's enabled.
407 private void DebugLog(string msg, params Object[] args)
408 {
409 if (m_physicsScene.ShouldDebugLog)
410 m_physicsScene.Logger.DebugFormat(msg, args);
411 } 404 }
412 405
413 // Invoke the detailed logger and output something if it's enabled. 406 // Invoke the detailed logger and output something if it's enabled.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
new file mode 100755
index 0000000..e411fcb
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OMV = OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37// Class to wrap all objects.
38// The rest of BulletSim doesn't need to keep checking for avatars or prims
39// unless the difference is significant.
40public abstract class BSPhysObject : PhysicsActor
41{
42 public abstract BSLinkset Linkset { get; set; }
43
44 public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
45 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
46 public abstract void SendCollisions();
47
48 // Return the object mass without calculating it or side effects
49 public abstract float MassRaw { get; }
50
51 // Reference to the physical body (btCollisionObject) of this object
52 public abstract BulletBody BSBody { get; set; }
53 // Reference to the physical shape (btCollisionShape) of this object
54 public abstract BulletShape BSShape { get; set; }
55
56 public abstract void ZeroMotion();
57
58 public virtual void StepVehicle(float timeStep) { }
59
60 public abstract void UpdateProperties(EntityProperties entprop);
61
62 public abstract void Destroy();
63}
64}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 9c20004..6d0af63 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -37,13 +37,11 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37namespace OpenSim.Region.Physics.BulletSPlugin 37namespace OpenSim.Region.Physics.BulletSPlugin
38{ 38{
39 [Serializable] 39 [Serializable]
40public sealed class BSPrim : PhysicsActor 40public sealed class BSPrim : BSPhysObject
41{ 41{
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
47 private IMesh _mesh; 45 private IMesh _mesh;
48 private PrimitiveBaseShape _pbs; 46 private PrimitiveBaseShape _pbs;
49 private ShapeData.PhysicsShapeType _shapeType; 47 private ShapeData.PhysicsShapeType _shapeType;
@@ -90,23 +88,16 @@ public sealed class BSPrim : PhysicsActor
90 private float _buoyancy; 88 private float _buoyancy;
91 89
92 // Membership in a linkset is controlled by this class. 90 // Membership in a linkset is controlled by this class.
93 private BSLinkset _linkset; 91 public override BSLinkset Linkset { get; set; }
94 public BSLinkset Linkset
95 {
96 get { return _linkset; }
97 set { _linkset = value; }
98 }
99 92
100 private int _subscribedEventsMs = 0; 93 private int _subscribedEventsMs = 0;
101 private int _nextCollisionOkTime = 0; 94 private int _nextCollisionOkTime = 0;
102 long _collidingStep; 95 long _collidingStep;
103 long _collidingGroundStep; 96 long _collidingGroundStep;
97 CollisionFlags m_currentCollisionFlags = 0;
104 98
105 private BulletBody m_body; 99 public override BulletBody BSBody { get; set; }
106 public BulletBody Body { 100 public override BulletShape BSShape { get; set; }
107 get { return m_body; }
108 set { m_body = value; }
109 }
110 101
111 private BSDynamics _vehicle; 102 private BSDynamics _vehicle;
112 103
@@ -124,6 +115,7 @@ public sealed class BSPrim : PhysicsActor
124 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); 115 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
125 _localID = localID; 116 _localID = localID;
126 _avName = primName; 117 _avName = primName;
118 _physicsActorType = (int)ActorTypes.Prim;
127 _scene = parent_scene; 119 _scene = parent_scene;
128 _position = pos; 120 _position = pos;
129 _size = size; 121 _size = size;
@@ -141,8 +133,8 @@ public sealed class BSPrim : PhysicsActor
141 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material 133 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
142 _density = _scene.Params.defaultDensity; // TODO: compute based on object material 134 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
143 _restitution = _scene.Params.defaultRestitution; 135 _restitution = _scene.Params.defaultRestitution;
144 _linkset = new BSLinkset(_scene, this); // a linkset of one 136 Linkset = new BSLinkset(Scene, this); // a linkset of one
145 _vehicle = new BSDynamics(this); // add vehicleness 137 _vehicle = new BSDynamics(Scene, this); // add vehicleness
146 _mass = CalculateMass(); 138 _mass = CalculateMass();
147 // do the actual object creation at taint time 139 // do the actual object creation at taint time
148 DetailLog("{0},BSPrim.constructor,call", LocalID); 140 DetailLog("{0},BSPrim.constructor,call", LocalID);
@@ -153,23 +145,25 @@ public sealed class BSPrim : PhysicsActor
153 // Get the pointer to the physical body for this object. 145 // Get the pointer to the physical body for this object.
154 // At the moment, we're still letting BulletSim manage the creation and destruction 146 // At the moment, we're still letting BulletSim manage the creation and destruction
155 // of the object. Someday we'll move that into the C# code. 147 // of the object. Someday we'll move that into the C# code.
156 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 148 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
149 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
150 m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
157 }); 151 });
158 } 152 }
159 153
160 // called when this prim is being destroyed and we should free all the resources 154 // called when this prim is being destroyed and we should free all the resources
161 public void Destroy() 155 public override void Destroy()
162 { 156 {
163 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 157 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
164 158
165 // Undo any links between me and any other object 159 // Undo any links between me and any other object
166 BSPrim parentBefore = _linkset.LinksetRoot; 160 BSPhysObject parentBefore = Linkset.LinksetRoot;
167 int childrenBefore = _linkset.NumberOfChildren; 161 int childrenBefore = Linkset.NumberOfChildren;
168 162
169 _linkset = _linkset.RemoveMeFromLinkset(this); 163 Linkset = Linkset.RemoveMeFromLinkset(this);
170 164
171 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", 165 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
172 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 166 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
173 167
174 // Undo any vehicle properties 168 // Undo any vehicle properties
175 this.VehicleType = (int)Vehicle.TYPE_NONE; 169 this.VehicleType = (int)Vehicle.TYPE_NONE;
@@ -193,7 +187,7 @@ public sealed class BSPrim : PhysicsActor
193 { 187 {
194 _mass = CalculateMass(); // changing size changes the mass 188 _mass = CalculateMass(); // changing size changes the mass
195 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); 189 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
196 // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); 190 DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
197 RecreateGeomAndObject(); 191 RecreateGeomAndObject();
198 }); 192 });
199 } 193 }
@@ -232,14 +226,13 @@ public sealed class BSPrim : PhysicsActor
232 BSPrim parent = obj as BSPrim; 226 BSPrim parent = obj as BSPrim;
233 if (parent != null) 227 if (parent != null)
234 { 228 {
235 DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); 229 BSPhysObject parentBefore = Linkset.LinksetRoot;
236 BSPrim parentBefore = _linkset.LinksetRoot; 230 int childrenBefore = Linkset.NumberOfChildren;
237 int childrenBefore = _linkset.NumberOfChildren;
238 231
239 _linkset = parent.Linkset.AddMeToLinkset(this); 232 Linkset = parent.Linkset.AddMeToLinkset(this);
240 233
241 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", 234 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
242 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 235 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
243 } 236 }
244 return; 237 return;
245 } 238 }
@@ -248,16 +241,14 @@ public sealed class BSPrim : PhysicsActor
248 public override void delink() { 241 public override void delink() {
249 // TODO: decide if this parent checking needs to happen at taint time 242 // TODO: decide if this parent checking needs to happen at taint time
250 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 243 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
251 DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
252 _linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
253 244
254 BSPrim parentBefore = _linkset.LinksetRoot; 245 BSPhysObject parentBefore = Linkset.LinksetRoot;
255 int childrenBefore = _linkset.NumberOfChildren; 246 int childrenBefore = Linkset.NumberOfChildren;
256 247
257 _linkset = _linkset.RemoveMeFromLinkset(this); 248 Linkset = Linkset.RemoveMeFromLinkset(this);
258 249
259 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", 250 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
260 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 251 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
261 return; 252 return;
262 } 253 }
263 254
@@ -265,28 +256,28 @@ public sealed class BSPrim : PhysicsActor
265 // Do it to the properties so the values get set in the physics engine. 256 // Do it to the properties so the values get set in the physics engine.
266 // Push the setting of the values to the viewer. 257 // Push the setting of the values to the viewer.
267 // Called at taint time! 258 // Called at taint time!
268 public void ZeroMotion() 259 public override void ZeroMotion()
269 { 260 {
270 _velocity = OMV.Vector3.Zero; 261 _velocity = OMV.Vector3.Zero;
271 _acceleration = OMV.Vector3.Zero; 262 _acceleration = OMV.Vector3.Zero;
272 _rotationalVelocity = OMV.Vector3.Zero; 263 _rotationalVelocity = OMV.Vector3.Zero;
273 264
274 // Zero some other properties directly into the physics engine 265 // Zero some other properties directly into the physics engine
275 BulletSimAPI.SetVelocity2(Body.Ptr, OMV.Vector3.Zero); 266 BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
276 BulletSimAPI.SetAngularVelocity2(Body.Ptr, OMV.Vector3.Zero); 267 BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
277 BulletSimAPI.SetInterpolation2(Body.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); 268 BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
278 BulletSimAPI.ClearForces2(Body.Ptr); 269 BulletSimAPI.ClearForces2(BSBody.Ptr);
279 } 270 }
280 271
281 public override void LockAngularMotion(OMV.Vector3 axis) 272 public override void LockAngularMotion(OMV.Vector3 axis)
282 { 273 {
283 // DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 274 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
284 return; 275 return;
285 } 276 }
286 277
287 public override OMV.Vector3 Position { 278 public override OMV.Vector3 Position {
288 get { 279 get {
289 if (!_linkset.IsRoot(this)) 280 if (!Linkset.IsRoot(this))
290 // child prims move around based on their parent. Need to get the latest location 281 // child prims move around based on their parent. Need to get the latest location
291 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 282 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
292 283
@@ -299,7 +290,7 @@ public sealed class BSPrim : PhysicsActor
299 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 290 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
300 _scene.TaintedObject("BSPrim.setPosition", delegate() 291 _scene.TaintedObject("BSPrim.setPosition", delegate()
301 { 292 {
302 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 293 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
303 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 294 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
304 }); 295 });
305 } 296 }
@@ -311,23 +302,23 @@ public sealed class BSPrim : PhysicsActor
311 { 302 {
312 get 303 get
313 { 304 {
314 return _linkset.LinksetMass; 305 return Linkset.LinksetMass;
315 } 306 }
316 } 307 }
317 308
318 // used when we only want this prim's mass and not the linkset thing 309 // used when we only want this prim's mass and not the linkset thing
319 public float MassRaw { get { return _mass; } } 310 public override float MassRaw { get { return _mass; } }
320 311
321 // Is this used? 312 // Is this used?
322 public override OMV.Vector3 CenterOfMass 313 public override OMV.Vector3 CenterOfMass
323 { 314 {
324 get { return _linkset.CenterOfMass; } 315 get { return Linkset.CenterOfMass; }
325 } 316 }
326 317
327 // Is this used? 318 // Is this used?
328 public override OMV.Vector3 GeometricCenter 319 public override OMV.Vector3 GeometricCenter
329 { 320 {
330 get { return _linkset.GeometricCenter; } 321 get { return Linkset.GeometricCenter; }
331 } 322 }
332 323
333 public override OMV.Vector3 Force { 324 public override OMV.Vector3 Force {
@@ -336,9 +327,9 @@ public sealed class BSPrim : PhysicsActor
336 _force = value; 327 _force = value;
337 _scene.TaintedObject("BSPrim.setForce", delegate() 328 _scene.TaintedObject("BSPrim.setForce", delegate()
338 { 329 {
339 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 330 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
340 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 331 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
341 BulletSimAPI.SetObjectForce2(Body.Ptr, _force); 332 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
342 }); 333 });
343 } 334 }
344 } 335 }
@@ -354,7 +345,7 @@ public sealed class BSPrim : PhysicsActor
354 { 345 {
355 // Done at taint time so we're sure the physics engine is not using the variables 346 // 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. 347 // Vehicle code changes the parameters for this vehicle type.
357 _vehicle.ProcessTypeChange(type); 348 _vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
358 // Tell the scene about the vehicle so it will get processing each frame. 349 // Tell the scene about the vehicle so it will get processing each frame.
359 _scene.VehicleInSceneTypeChanged(this, type); 350 _scene.VehicleInSceneTypeChanged(this, type);
360 }); 351 });
@@ -391,7 +382,7 @@ public sealed class BSPrim : PhysicsActor
391 382
392 // Called each simulation step to advance vehicle characteristics. 383 // Called each simulation step to advance vehicle characteristics.
393 // Called from Scene when doing simulation step so we're in taint processing time. 384 // Called from Scene when doing simulation step so we're in taint processing time.
394 public void StepVehicle(float timeStep) 385 public override void StepVehicle(float timeStep)
395 { 386 {
396 if (IsPhysical) 387 if (IsPhysical)
397 _vehicle.Step(timeStep); 388 _vehicle.Step(timeStep);
@@ -414,7 +405,7 @@ public sealed class BSPrim : PhysicsActor
414 _velocity = value; 405 _velocity = value;
415 _scene.TaintedObject("BSPrim.setVelocity", delegate() 406 _scene.TaintedObject("BSPrim.setVelocity", delegate()
416 { 407 {
417 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 408 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
418 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 409 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
419 }); 410 });
420 } 411 }
@@ -422,7 +413,7 @@ public sealed class BSPrim : PhysicsActor
422 public override OMV.Vector3 Torque { 413 public override OMV.Vector3 Torque {
423 get { return _torque; } 414 get { return _torque; }
424 set { _torque = value; 415 set { _torque = value;
425 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 416 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
426 } 417 }
427 } 418 }
428 public override float CollisionScore { 419 public override float CollisionScore {
@@ -436,7 +427,7 @@ public sealed class BSPrim : PhysicsActor
436 } 427 }
437 public override OMV.Quaternion Orientation { 428 public override OMV.Quaternion Orientation {
438 get { 429 get {
439 if (!_linkset.IsRoot(this)) 430 if (!Linkset.IsRoot(this))
440 { 431 {
441 // Children move around because tied to parent. Get a fresh value. 432 // Children move around because tied to parent. Get a fresh value.
442 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); 433 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
@@ -449,15 +440,14 @@ public sealed class BSPrim : PhysicsActor
449 _scene.TaintedObject("BSPrim.setOrientation", delegate() 440 _scene.TaintedObject("BSPrim.setOrientation", delegate()
450 { 441 {
451 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 442 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
452 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 443 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
453 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 444 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
454 }); 445 });
455 } 446 }
456 } 447 }
457 public override int PhysicsActorType { 448 public override int PhysicsActorType {
458 get { return _physicsActorType; } 449 get { return _physicsActorType; }
459 set { _physicsActorType = value; 450 set { _physicsActorType = value; }
460 }
461 } 451 }
462 public override bool IsPhysical { 452 public override bool IsPhysical {
463 get { return _isPhysical; } 453 get { return _isPhysical; }
@@ -484,30 +474,88 @@ public sealed class BSPrim : PhysicsActor
484 474
485 // Make gravity work if the object is physical and not selected 475 // Make gravity work if the object is physical and not selected
486 // No locking here because only called when it is safe 476 // No locking here because only called when it is safe
477 // There are four flags we're interested in:
478 // IsStatic: Object does not move, otherwise the object has mass and moves
479 // isSolid: other objects bounce off of this object
480 // isVolumeDetect: other objects pass through but can generate collisions
481 // collisionEvents: whether this object returns collision events
487 private void SetObjectDynamic() 482 private void SetObjectDynamic()
488 { 483 {
489 // RA: remove this for the moment. 484 // If it's becoming dynamic, it will need hullness
490 // The problem is that dynamic objects are hulls so if we are becoming physical 485 VerifyCorrectPhysicalShape();
491 // the shape has to be checked and possibly built.
492 // Maybe a VerifyCorrectPhysicalShape() routine?
493 // RecreateGeomAndObject();
494 486
495 // Bullet wants static objects to have a mass of zero 487 // Bullet wants static objects to have a mass of zero
496 float mass = IsStatic ? 0f : _mass; 488 float mass = IsStatic ? 0f : _mass;
497 489
498 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); 490 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
491 /*
492 BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
499 493
500 // recompute any linkset parameters 494 // Set up the object physicalness (static or dynamic)
501 _linkset.Refresh(this); 495 MakeDynamic();
502 496
503 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); 497 // Make solid or not and arrange for collisions, etc
504 // DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); 498 MakeSolid();
499
500 m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
501
502 BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
503 */
504
505 // Recompute any linkset parameters.
506 // When going from non-physical to physical, this re-enables the constraints that
507 // had been automatically disabled when the mass was set to zero.
508 Linkset.Refresh(this);
509
510 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, m_currentCollisionFlags);
511 }
512
513 // "Making dynamic" means changing to and from static.
514 // When static, gravity does not effect the object and it is fixed in space.
515 // When dynamic, the object can fall and be pushed by others.
516 // This is independent of its 'solidness' which controls what passes through
517 // this object and what interacts with it.
518 private void MakeDynamic()
519 {
520 if (IsStatic)
521 {
522 // Become a Bullet 'static' object type
523 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
524 // Stop all movement
525 BulletSimAPI.ClearAllForces2(BSBody.Ptr);
526 // Mass is zero which disables a bunch of physics stuff in Bullet
527 BulletSimAPI.SetMassProps2(BSBody.Ptr, 0f, OMV.Vector3.Zero);
528 // There is no inertia in a static object
529 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
530 // The activation state is 'sleeping' so Bullet will not try to act on it
531 BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
532 }
533 else
534 {
535 // Not a Bullet static object
536 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
537 // A dynamic object has mass
538 BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, OMV.Vector3.Zero);
539 // The shape is interesting and has mass and a center of gravity
540 IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr);
541 BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass, OMV.Vector3.Zero);
542 // Inertia is based on our new mass
543 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
544 // Force activation of the object so Bullet will act on it.
545 BulletSimAPI.Activate2(BSBody.Ptr, true);
546 }
547 }
548
549 private void MakeSolid()
550 {
505 } 551 }
506 552
507 // prims don't fly 553 // prims don't fly
508 public override bool Flying { 554 public override bool Flying {
509 get { return _flying; } 555 get { return _flying; }
510 set { _flying = value; } 556 set {
557 _flying = value;
558 }
511 } 559 }
512 public override bool SetAlwaysRun { 560 public override bool SetAlwaysRun {
513 get { return _setAlwaysRun; } 561 get { return _setAlwaysRun; }
@@ -558,7 +606,7 @@ public sealed class BSPrim : PhysicsActor
558 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 606 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
559 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 607 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
560 { 608 {
561 // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 609 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
562 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 610 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
563 }); 611 });
564 } 612 }
@@ -575,7 +623,7 @@ public sealed class BSPrim : PhysicsActor
575 _buoyancy = value; 623 _buoyancy = value;
576 _scene.TaintedObject("BSPrim.setBuoyancy", delegate() 624 _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
577 { 625 {
578 // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 626 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
579 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 627 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
580 }); 628 });
581 } 629 }
@@ -624,7 +672,7 @@ public sealed class BSPrim : PhysicsActor
624 } 672 }
625 else 673 else
626 { 674 {
627 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); 675 m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
628 return; 676 return;
629 } 677 }
630 _scene.TaintedObject("BSPrim.AddForce", delegate() 678 _scene.TaintedObject("BSPrim.AddForce", delegate()
@@ -638,17 +686,18 @@ public sealed class BSPrim : PhysicsActor
638 } 686 }
639 m_accumulatedForces.Clear(); 687 m_accumulatedForces.Clear();
640 } 688 }
641 // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); 689 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
642 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); 690 // For unknown reason, "ApplyCentralForce" is really additive.
691 BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum);
643 }); 692 });
644 } 693 }
645 694
646 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 695 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
647 // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); 696 DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
648 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); 697 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
649 } 698 }
650 public override void SetMomentum(OMV.Vector3 momentum) { 699 public override void SetMomentum(OMV.Vector3 momentum) {
651 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); 700 DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
652 } 701 }
653 public override void SubscribeEvents(int ms) { 702 public override void SubscribeEvents(int ms) {
654 _subscribedEventsMs = ms; 703 _subscribedEventsMs = ms;
@@ -659,7 +708,7 @@ public sealed class BSPrim : PhysicsActor
659 708
660 Scene.TaintedObject("BSPrim.SubscribeEvents", delegate() 709 Scene.TaintedObject("BSPrim.SubscribeEvents", delegate()
661 { 710 {
662 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 711 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
663 }); 712 });
664 } 713 }
665 } 714 }
@@ -667,7 +716,7 @@ public sealed class BSPrim : PhysicsActor
667 _subscribedEventsMs = 0; 716 _subscribedEventsMs = 0;
668 Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate() 717 Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
669 { 718 {
670 BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 719 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
671 }); 720 });
672 } 721 }
673 public override bool SubscribedEvents() { 722 public override bool SubscribedEvents() {
@@ -992,7 +1041,7 @@ public sealed class BSPrim : PhysicsActor
992 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 1041 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
993 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) 1042 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
994 { 1043 {
995 // DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 1044 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
996 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 1045 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
997 // Bullet native objects are scaled by the Bullet engine so pass the size in 1046 // Bullet native objects are scaled by the Bullet engine so pass the size in
998 _scale = _size; 1047 _scale = _size;
@@ -1006,7 +1055,7 @@ public sealed class BSPrim : PhysicsActor
1006 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); 1055 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1007 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) 1056 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1008 { 1057 {
1009 // DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1058 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1010 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1059 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1011 _scale = _size; 1060 _scale = _size;
1012 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1061 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1042,19 +1091,26 @@ public sealed class BSPrim : PhysicsActor
1042 // No locking here because this is done when we know physics is not simulating 1091 // No locking here because this is done when we know physics is not simulating
1043 private void CreateGeomMesh() 1092 private void CreateGeomMesh()
1044 { 1093 {
1045 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1094 // level of detail based on size and type of the object
1095 float lod = _scene.MeshLOD;
1096 if (_pbs.SculptEntry)
1097 lod = _scene.SculptLOD;
1098 float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
1099 if (maxAxis > _scene.MeshMegaPrimThreshold)
1100 lod = _scene.MeshMegaPrimLOD;
1101
1046 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); 1102 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
1047 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); 1103 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
1048 1104
1049 // if this new shape is the same as last time, don't recreate the mesh 1105 // if this new shape is the same as last time, don't recreate the mesh
1050 if (_meshKey == newMeshKey) return; 1106 if (_meshKey == newMeshKey) return;
1051 1107
1052 // DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); 1108 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1053 // Since we're recreating new, get rid of any previously generated shape 1109 // Since we're recreating new, get rid of any previously generated shape
1054 if (_meshKey != 0) 1110 if (_meshKey != 0)
1055 { 1111 {
1056 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); 1112 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
1057 // DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); 1113 DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
1058 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1114 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1059 _mesh = null; 1115 _mesh = null;
1060 _meshKey = 0; 1116 _meshKey = 0;
@@ -1084,7 +1140,7 @@ public sealed class BSPrim : PhysicsActor
1084 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1140 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1085 // meshes are already scaled by the meshmerizer 1141 // meshes are already scaled by the meshmerizer
1086 _scale = new OMV.Vector3(1f, 1f, 1f); 1142 _scale = new OMV.Vector3(1f, 1f, 1f);
1087 // DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); 1143 DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
1088 return; 1144 return;
1089 } 1145 }
1090 1146
@@ -1098,13 +1154,13 @@ public sealed class BSPrim : PhysicsActor
1098 // if the hull hasn't changed, don't rebuild it 1154 // if the hull hasn't changed, don't rebuild it
1099 if (newHullKey == _hullKey) return; 1155 if (newHullKey == _hullKey) return;
1100 1156
1101 // DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); 1157 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1102 1158
1103 // Since we're recreating new, get rid of any previously generated shape 1159 // Since we're recreating new, get rid of any previously generated shape
1104 if (_hullKey != 0) 1160 if (_hullKey != 0)
1105 { 1161 {
1106 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); 1162 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1107 // DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); 1163 DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
1108 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); 1164 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1109 _hullKey = 0; 1165 _hullKey = 0;
1110 } 1166 }
@@ -1198,7 +1254,7 @@ public sealed class BSPrim : PhysicsActor
1198 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1254 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1199 // meshes are already scaled by the meshmerizer 1255 // meshes are already scaled by the meshmerizer
1200 _scale = new OMV.Vector3(1f, 1f, 1f); 1256 _scale = new OMV.Vector3(1f, 1f, 1f);
1201 // DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); 1257 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1202 return; 1258 return;
1203 } 1259 }
1204 1260
@@ -1210,6 +1266,27 @@ public sealed class BSPrim : PhysicsActor
1210 return; 1266 return;
1211 } 1267 }
1212 1268
1269 private void VerifyCorrectPhysicalShape()
1270 {
1271 if (IsStatic)
1272 {
1273 // if static, we don't need a hull so, if there is one, rebuild without it
1274 if (_hullKey != 0)
1275 {
1276 RecreateGeomAndObject();
1277 }
1278 }
1279 else
1280 {
1281 // if not static, it will need a hull to efficiently collide with things
1282 if (_hullKey == 0)
1283 {
1284 RecreateGeomAndObject();
1285 }
1286
1287 }
1288 }
1289
1213 // Create an object in Bullet if it has not already been created 1290 // Create an object in Bullet if it has not already been created
1214 // No locking here because this is done when the physics engine is not simulating 1291 // No locking here because this is done when the physics engine is not simulating
1215 // Returns 'true' if an object was actually created. 1292 // Returns 'true' if an object was actually created.
@@ -1224,7 +1301,7 @@ public sealed class BSPrim : PhysicsActor
1224 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); 1301 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
1225 1302
1226 // the CreateObject() may have recreated the rigid body. Make sure we have the latest. 1303 // the CreateObject() may have recreated the rigid body. Make sure we have the latest.
1227 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 1304 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
1228 1305
1229 return ret; 1306 return ret;
1230 } 1307 }
@@ -1277,7 +1354,7 @@ public sealed class BSPrim : PhysicsActor
1277 const float ACCELERATION_TOLERANCE = 0.01f; 1354 const float ACCELERATION_TOLERANCE = 0.01f;
1278 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; 1355 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1279 1356
1280 public void UpdateProperties(EntityProperties entprop) 1357 public override void UpdateProperties(EntityProperties entprop)
1281 { 1358 {
1282 /* 1359 /*
1283 UpdatedProperties changed = 0; 1360 UpdatedProperties changed = 0;
@@ -1325,7 +1402,7 @@ public sealed class BSPrim : PhysicsActor
1325 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1402 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1326 1403
1327 // Updates only for individual prims and for the root object of a linkset. 1404 // Updates only for individual prims and for the root object of a linkset.
1328 if (_linkset.IsRoot(this)) 1405 if (Linkset.IsRoot(this))
1329 { 1406 {
1330 // Assign to the local variables so the normal set action does not happen 1407 // Assign to the local variables so the normal set action does not happen
1331 _position = entprop.Position; 1408 _position = entprop.Position;
@@ -1334,10 +1411,8 @@ public sealed class BSPrim : PhysicsActor
1334 _acceleration = entprop.Acceleration; 1411 _acceleration = entprop.Acceleration;
1335 _rotationalVelocity = entprop.RotationalVelocity; 1412 _rotationalVelocity = entprop.RotationalVelocity;
1336 1413
1337 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", 1414 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1338 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 1415 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1339 // DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1340 // LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1341 1416
1342 base.RequestPhysicsterseUpdate(); 1417 base.RequestPhysicsterseUpdate();
1343 } 1418 }
@@ -1353,8 +1428,9 @@ public sealed class BSPrim : PhysicsActor
1353 } 1428 }
1354 1429
1355 // I've collided with something 1430 // I've collided with something
1431 // Called at taint time from within the Step() function
1356 CollisionEventUpdate collisionCollection; 1432 CollisionEventUpdate collisionCollection;
1357 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1433 public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1358 { 1434 {
1359 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1435 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
1360 1436
@@ -1367,8 +1443,14 @@ public sealed class BSPrim : PhysicsActor
1367 1443
1368 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); 1444 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
1369 1445
1370 // if someone is subscribed to collision events.... 1446 // prims in the same linkset cannot collide with each other
1371 if (_subscribedEventsMs != 0) { 1447 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
1448 {
1449 return;
1450 }
1451
1452 // if someone has subscribed for collision events....
1453 if (SubscribedEvents()) {
1372 // throttle the collisions to the number of milliseconds specified in the subscription 1454 // throttle the collisions to the number of milliseconds specified in the subscription
1373 int nowTime = _scene.SimulationNowTime; 1455 int nowTime = _scene.SimulationNowTime;
1374 if (nowTime >= _nextCollisionOkTime) { 1456 if (nowTime >= _nextCollisionOkTime) {
@@ -1382,7 +1464,7 @@ public sealed class BSPrim : PhysicsActor
1382 } 1464 }
1383 1465
1384 // The scene is telling us it's time to pass our collected collisions into the simulator 1466 // The scene is telling us it's time to pass our collected collisions into the simulator
1385 public void SendCollisions() 1467 public override void SendCollisions()
1386 { 1468 {
1387 if (collisionCollection != null && collisionCollection.Count > 0) 1469 if (collisionCollection != null && collisionCollection.Count > 0)
1388 { 1470 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index a31c578..4a468af 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -39,8 +39,6 @@ using log4net;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) 41// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
42// Debug linkset
43// Test with multiple regions in one simulator
44// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) 42// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
45// Test sculpties 43// Test sculpties
46// Compute physics FPS reasonably 44// Compute physics FPS reasonably
@@ -54,10 +52,8 @@ using OpenMetaverse;
54// Use collision masks for collision with terrain and phantom objects 52// Use collision masks for collision with terrain and phantom objects
55// Check out llVolumeDetect. Must do something for that. 53// Check out llVolumeDetect. Must do something for that.
56// Should prim.link() and prim.delink() membership checking happen at taint time? 54// Should prim.link() and prim.delink() membership checking happen at taint time?
57// changing the position and orientation of a linked prim must rebuild the constraint with the root.
58// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once 55// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
59// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect 56// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
60// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
61// Implement LockAngularMotion 57// Implement LockAngularMotion
62// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) 58// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
63// Does NeedsMeshing() really need to exclude all the different shapes? 59// Does NeedsMeshing() really need to exclude all the different shapes?
@@ -73,62 +69,61 @@ public class BSScene : PhysicsScene, IPhysicsParameters
73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 69 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
74 private static readonly string LogHeader = "[BULLETS SCENE]"; 70 private static readonly string LogHeader = "[BULLETS SCENE]";
75 71
76 public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } 72 // The name of the region we're working for.
73 public string RegionName { get; private set; }
77 74
78 public string BulletSimVersion = "?"; 75 public string BulletSimVersion = "?";
79 76
80 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 77 public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
81 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 78
79 private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
80 // Following is a kludge and can be removed when avatar animation updating is
81 // moved to a better place.
82 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); 82 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
83 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); 83
84 private List<BSPrim> m_vehicles = new List<BSPrim>(); 84 // List of all the objects that have vehicle properties and should be called
85 private float[] m_heightMap; 85 // to update each physics step.
86 private float m_waterLevel; 86 private List<BSPhysObject> m_vehicles = new List<BSPhysObject>();
87 private uint m_worldID;
88 public uint WorldID { get { return m_worldID; } }
89 87
90 // let my minuions use my logger 88 // let my minuions use my logger
91 public ILog Logger { get { return m_log; } } 89 public ILog Logger { get { return m_log; } }
92 90
93 private bool m_initialized = false; 91 // If non-zero, the number of simulation steps between calls to the physics
94 92 // engine to output detailed physics stats. Debug logging level must be on also.
95 private int m_detailedStatsStep = 0; 93 private int m_detailedStatsStep = 0;
96 94
97 public IMesher mesher; 95 public IMesher mesher;
98 private float m_meshLOD; 96 // Level of Detail values kept as float because that's what the Meshmerizer wants
99 public float MeshLOD 97 public float MeshLOD { get; private set; }
100 { 98 public float MeshMegaPrimLOD { get; private set; }
101 get { return m_meshLOD; } 99 public float MeshMegaPrimThreshold { get; private set; }
102 } 100 public float SculptLOD { get; private set; }
103 private float m_sculptLOD;
104 public float SculptLOD
105 {
106 get { return m_sculptLOD; }
107 }
108 101
109 private BulletSim m_worldSim; 102 public uint WorldID { get; private set; }
110 public BulletSim World 103 public BulletSim World { get; private set; }
111 {
112 get { return m_worldSim; }
113 }
114 private BSConstraintCollection m_constraintCollection;
115 public BSConstraintCollection Constraints
116 {
117 get { return m_constraintCollection; }
118 }
119 104
105 // All the constraints that have been allocated in this instance.
106 public BSConstraintCollection Constraints { get; private set; }
107
108 // Simulation parameters
120 private int m_maxSubSteps; 109 private int m_maxSubSteps;
121 private float m_fixedTimeStep; 110 private float m_fixedTimeStep;
122 private long m_simulationStep = 0; 111 private long m_simulationStep = 0;
123 public long SimulationStep { get { return m_simulationStep; } } 112 public long SimulationStep { get { return m_simulationStep; } }
124 113
114 // The length of the last timestep we were asked to simulate.
115 // This is used by the vehicle code. Since the vehicle code is called
116 // once per simulation step, its constants need to be scaled by this.
125 public float LastSimulatedTimestep { get; private set; } 117 public float LastSimulatedTimestep { get; private set; }
126 118
127 // A value of the time now so all the collision and update routines do not have to get their own 119 // A value of the time now so all the collision and update routines do not have to get their own
128 // Set to 'now' just before all the prims and actors are called for collisions and updates 120 // Set to 'now' just before all the prims and actors are called for collisions and updates
129 private int m_simulationNowTime; 121 public int SimulationNowTime { get; private set; }
130 public int SimulationNowTime { get { return m_simulationNowTime; } } 122
123 // True if initialized and ready to do simulation steps
124 private bool m_initialized = false;
131 125
126 // Pinned memory used to pass step information between managed and unmanaged
132 private int m_maxCollisionsPerFrame; 127 private int m_maxCollisionsPerFrame;
133 private CollisionDesc[] m_collisionArray; 128 private CollisionDesc[] m_collisionArray;
134 private GCHandle m_collisionArrayPinnedHandle; 129 private GCHandle m_collisionArrayPinnedHandle;
@@ -145,6 +140,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
145 140
146 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 141 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
147 public const uint GROUNDPLANE_ID = 1; 142 public const uint GROUNDPLANE_ID = 1;
143 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
144
145 private float m_waterLevel;
146 public BSTerrainManager TerrainManager { get; private set; }
148 147
149 public ConfigurationParameters Params 148 public ConfigurationParameters Params
150 { 149 {
@@ -155,12 +154,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
155 get { return new Vector3(0f, 0f, Params.gravity); } 154 get { return new Vector3(0f, 0f, Params.gravity); }
156 } 155 }
157 156
158 private float m_maximumObjectMass; 157 public float MaximumObjectMass { get; private set; }
159 public float MaximumObjectMass
160 {
161 get { return m_maximumObjectMass; }
162 }
163 158
159 // When functions in the unmanaged code must be called, it is only
160 // done at a known time just before the simulation step. The taint
161 // system saves all these function calls and executes them in
162 // order before the simulation.
164 public delegate void TaintCallback(); 163 public delegate void TaintCallback();
165 private struct TaintCallbackEntry 164 private struct TaintCallbackEntry
166 { 165 {
@@ -176,11 +175,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
176 private Object _taintLock = new Object(); 175 private Object _taintLock = new Object();
177 176
178 // A pointer to an instance if this structure is passed to the C++ code 177 // A pointer to an instance if this structure is passed to the C++ code
178 // Used to pass basic configuration values to the unmanaged code.
179 ConfigurationParameters[] m_params; 179 ConfigurationParameters[] m_params;
180 GCHandle m_paramsHandle; 180 GCHandle m_paramsHandle;
181 181
182 public bool ShouldDebugLog { get; private set; } 182 // Handle to the callback used by the unmanaged code to call into the managed code.
183 183 // Used for debug logging.
184 // Need to store the handle in a persistant variable so it won't be freed.
184 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; 185 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
185 186
186 // Sometimes you just have to log everything. 187 // Sometimes you just have to log everything.
@@ -189,13 +190,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters
189 private string m_physicsLoggingDir; 190 private string m_physicsLoggingDir;
190 private string m_physicsLoggingPrefix; 191 private string m_physicsLoggingPrefix;
191 private int m_physicsLoggingFileMinutes; 192 private int m_physicsLoggingFileMinutes;
193 // 'true' of the vehicle code is to log lots of details
194 public bool VehicleLoggingEnabled { get; private set; }
192 195
193 private bool m_vehicleLoggingEnabled; 196 #region Construction and Initialization
194 public bool VehicleLoggingEnabled { get { return m_vehicleLoggingEnabled; } }
195
196 public BSScene(string identifier) 197 public BSScene(string identifier)
197 { 198 {
198 m_initialized = false; 199 m_initialized = false;
200 // we are passed the name of the region we're working for.
201 RegionName = identifier;
199 } 202 }
200 203
201 public override void Initialise(IMesher meshmerizer, IConfigSource config) 204 public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -213,6 +216,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
213 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; 216 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
214 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); 217 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
215 218
219 mesher = meshmerizer;
220 _taintedObjects = new List<TaintCallbackEntry>();
221
216 // Enable very detailed logging. 222 // Enable very detailed logging.
217 // By creating an empty logger when not logging, the log message invocation code 223 // By creating an empty logger when not logging, the log message invocation code
218 // can be left in and every call doesn't have to check for null. 224 // can be left in and every call doesn't have to check for null.
@@ -225,38 +231,43 @@ public class BSScene : PhysicsScene, IPhysicsParameters
225 PhysicsLogging = new Logging.LogWriter(); 231 PhysicsLogging = new Logging.LogWriter();
226 } 232 }
227 233
228 // Get the version of the DLL 234 // If Debug logging level, enable logging from the unmanaged code
229 // TODO: this doesn't work yet. Something wrong with marshaling the returned string. 235 m_DebugLogCallbackHandle = null;
230 // BulletSimVersion = BulletSimAPI.GetVersion();
231 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
232
233 // if Debug, enable logging from the unmanaged code
234 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) 236 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
235 { 237 {
236 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); 238 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
237 if (PhysicsLogging.Enabled) 239 if (PhysicsLogging.Enabled)
240 // The handle is saved in a variable to make sure it doesn't get freed after this call
238 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); 241 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
239 else 242 else
240 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 243 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
241 // the handle is saved in a variable to make sure it doesn't get freed after this call
242 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
243 } 244 }
244 245
245 _taintedObjects = new List<TaintCallbackEntry>(); 246 // Get the version of the DLL
247 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
248 // BulletSimVersion = BulletSimAPI.GetVersion();
249 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
246 250
247 mesher = meshmerizer; 251 // The bounding box for the simulated world. The origin is 0,0,0 unless we're
248 // The bounding box for the simulated world 252 // a child in a mega-region.
253 // Turns out that Bullet really doesn't care about the extents of the simulated
254 // area. It tracks active objects no matter where they are.
249 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); 255 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
250 256
251 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 257 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
252 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), 258 WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
253 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), 259 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
254 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); 260 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(),
261 m_DebugLogCallbackHandle);
255 262
256 // Initialization to support the transition to a new API which puts most of the logic 263 // Initialization to support the transition to a new API which puts most of the logic
257 // into the C# code so it is easier to modify and add to. 264 // into the C# code so it is easier to modify and add to.
258 m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID)); 265 World = new BulletSim(WorldID, this, BulletSimAPI.GetSimHandle2(WorldID));
259 m_constraintCollection = new BSConstraintCollection(World); 266
267 Constraints = new BSConstraintCollection(World);
268
269 TerrainManager = new BSTerrainManager(this);
270 TerrainManager.CreateInitialGroundPlaneAndTerrain();
260 271
261 m_initialized = true; 272 m_initialized = true;
262 } 273 }
@@ -281,10 +292,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
281 // Very detailed logging for physics debugging 292 // Very detailed logging for physics debugging
282 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); 293 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
283 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); 294 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
284 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); 295 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
285 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); 296 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
286 // Very detailed logging for vehicle debugging 297 // Very detailed logging for vehicle debugging
287 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 298 VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
299
300 // Do any replacements in the parameters
301 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
288 } 302 }
289 } 303 }
290 } 304 }
@@ -316,6 +330,38 @@ public class BSScene : PhysicsScene, IPhysicsParameters
316 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); 330 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg);
317 } 331 }
318 332
333 public override void Dispose()
334 {
335 // m_log.DebugFormat("{0}: Dispose()", LogHeader);
336
337 // make sure no stepping happens while we're deleting stuff
338 m_initialized = false;
339
340 TerrainManager.ReleaseGroundPlaneAndTerrain();
341
342 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
343 {
344 kvp.Value.Destroy();
345 }
346 PhysObjects.Clear();
347
348 // Now that the prims are all cleaned up, there should be no constraints left
349 if (Constraints != null)
350 {
351 Constraints.Dispose();
352 Constraints = null;
353 }
354
355 // Anything left in the unmanaged code should be cleaned out
356 BulletSimAPI.Shutdown(WorldID);
357
358 // Not logging any more
359 PhysicsLogging.Close();
360 }
361 #endregion // Construction and Initialization
362
363 #region Prim and Avatar addition and removal
364
319 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 365 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
320 { 366 {
321 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); 367 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
@@ -329,7 +375,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
329 if (!m_initialized) return null; 375 if (!m_initialized) return null;
330 376
331 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 377 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
332 lock (m_avatars) m_avatars.Add(localID, actor); 378 lock (PhysObjects) PhysObjects.Add(localID, actor);
379
380 // TODO: Remove kludge someday.
381 // We must generate a collision for avatars whether they collide or not.
382 // This is required by OpenSim to update avatar animations, etc.
383 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
384
333 return actor; 385 return actor;
334 } 386 }
335 387
@@ -344,7 +396,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
344 { 396 {
345 try 397 try
346 { 398 {
347 lock (m_avatars) m_avatars.Remove(actor.LocalID); 399 lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
400 // Remove kludge someday
401 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor);
348 } 402 }
349 catch (Exception e) 403 catch (Exception e)
350 { 404 {
@@ -362,11 +416,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
362 BSPrim bsprim = prim as BSPrim; 416 BSPrim bsprim = prim as BSPrim;
363 if (bsprim != null) 417 if (bsprim != null)
364 { 418 {
365 // DetailLog("{0},RemovePrim,call", bsprim.LocalID); 419 DetailLog("{0},RemovePrim,call", bsprim.LocalID);
366 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); 420 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
367 try 421 try
368 { 422 {
369 lock (m_prims) m_prims.Remove(bsprim.LocalID); 423 lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
370 } 424 }
371 catch (Exception e) 425 catch (Exception e)
372 { 426 {
@@ -388,10 +442,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
388 442
389 if (!m_initialized) return null; 443 if (!m_initialized) return null;
390 444
391 // DetailLog("{0},AddPrimShape,call", localID); 445 DetailLog("{0},AddPrimShape,call", localID);
392 446
393 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 447 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
394 lock (m_prims) m_prims.Add(localID, prim); 448 lock (PhysObjects) PhysObjects.Add(localID, prim);
395 return prim; 449 return prim;
396 } 450 }
397 451
@@ -400,6 +454,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
400 // information call is not needed. 454 // information call is not needed.
401 public override void AddPhysicsActorTaint(PhysicsActor prim) { } 455 public override void AddPhysicsActorTaint(PhysicsActor prim) { }
402 456
457 #endregion // Prim and Avatar addition and removal
458
459 #region Simulation
403 // Simulate one timestep 460 // Simulate one timestep
404 public override float Simulate(float timeStep) 461 public override float Simulate(float timeStep)
405 { 462 {
@@ -416,6 +473,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
416 int simulateStartTime = Util.EnvironmentTickCount(); 473 int simulateStartTime = Util.EnvironmentTickCount();
417 474
418 // update the prim states while we know the physics engine is not busy 475 // update the prim states while we know the physics engine is not busy
476 int numTaints = _taintedObjects.Count;
419 ProcessTaints(); 477 ProcessTaints();
420 478
421 // Some of the prims operate with special vehicle properties 479 // Some of the prims operate with special vehicle properties
@@ -427,15 +485,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
427 int numSubSteps = 0; 485 int numSubSteps = 0;
428 try 486 try
429 { 487 {
430 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 488 numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
431 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 489 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
432 // DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 490 DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}",
491 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
433 } 492 }
434 catch (Exception e) 493 catch (Exception e)
435 { 494 {
436 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); 495 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
437 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 496 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
438 // updatedEntityCount = 0; 497 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
498 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
499 updatedEntityCount = 0;
439 collidersCount = 0; 500 collidersCount = 0;
440 } 501 }
441 502
@@ -443,7 +504,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
443 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in 504 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
444 505
445 // Get a value for 'now' so all the collision and update routines don't have to get their own 506 // Get a value for 'now' so all the collision and update routines don't have to get their own
446 m_simulationNowTime = Util.EnvironmentTickCount(); 507 SimulationNowTime = Util.EnvironmentTickCount();
447 508
448 // If there were collisions, process them by sending the event to the prim. 509 // If there were collisions, process them by sending the event to the prim.
449 // Collisions must be processed before updates. 510 // Collisions must be processed before updates.
@@ -462,19 +523,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
462 523
463 // The above SendCollision's batch up the collisions on the objects. 524 // The above SendCollision's batch up the collisions on the objects.
464 // Now push the collisions into the simulator. 525 // Now push the collisions into the simulator.
465 foreach (BSPrim bsp in m_primsWithCollisions) 526 foreach (BSPhysObject bsp in m_objectsWithCollisions)
466 bsp.SendCollisions(); 527 bsp.SendCollisions();
467 m_primsWithCollisions.Clear(); 528 m_objectsWithCollisions.Clear();
468 529
469 // This is a kludge to get avatar movement updated. 530 // This is a kludge to get avatar movement updated.
470 // Don't send collisions only if there were collisions -- send everytime.
471 // ODE sends collisions even if there are none and this is used to update 531 // ODE sends collisions even if there are none and this is used to update
472 // avatar animations and stuff. 532 // avatar animations and stuff.
473 // foreach (BSCharacter bsc in m_avatarsWithCollisions) 533 foreach (BSPhysObject bpo in m_avatarsWithCollisions)
474 // bsc.SendCollisions(); 534 bpo.SendCollisions();
475 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) 535 // m_avatarsWithCollisions.Clear();
476 kvp.Value.SendCollisions();
477 m_avatarsWithCollisions.Clear();
478 536
479 // If any of the objects had updated properties, tell the object it has been changed by the physics engine 537 // If any of the objects had updated properties, tell the object it has been changed by the physics engine
480 if (updatedEntityCount > 0) 538 if (updatedEntityCount > 0)
@@ -482,16 +540,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
482 for (int ii = 0; ii < updatedEntityCount; ii++) 540 for (int ii = 0; ii < updatedEntityCount; ii++)
483 { 541 {
484 EntityProperties entprop = m_updateArray[ii]; 542 EntityProperties entprop = m_updateArray[ii];
485 BSPrim prim; 543 BSPhysObject pobj;
486 if (m_prims.TryGetValue(entprop.ID, out prim)) 544 if (PhysObjects.TryGetValue(entprop.ID, out pobj))
487 { 545 {
488 prim.UpdateProperties(entprop); 546 pobj.UpdateProperties(entprop);
489 continue;
490 }
491 BSCharacter actor;
492 if (m_avatars.TryGetValue(entprop.ID, out actor))
493 {
494 actor.UpdateProperties(entprop);
495 continue; 547 continue;
496 } 548 }
497 } 549 }
@@ -521,56 +573,47 @@ public class BSScene : PhysicsScene, IPhysicsParameters
521 } 573 }
522 574
523 // Something has collided 575 // Something has collided
524 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration) 576 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
525 { 577 {
526 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) 578 if (localID <= TerrainManager.HighestTerrainID)
527 { 579 {
528 return; // don't send collisions to the terrain 580 return; // don't send collisions to the terrain
529 } 581 }
530 582
583 BSPhysObject collider = PhysObjects[localID];
584 // TODO: as of this code, terrain was not in the physical object list.
585 // When BSTerrain is created and it will be in the list, we can remove
586 // the possibility that it's not there and just fetch the collidee.
587 BSPhysObject collidee = null;
588
531 ActorTypes type = ActorTypes.Prim; 589 ActorTypes type = ActorTypes.Prim;
532 if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) 590 if (collidingWith <= TerrainManager.HighestTerrainID)
591 {
533 type = ActorTypes.Ground; 592 type = ActorTypes.Ground;
534 else if (m_avatars.ContainsKey(collidingWith))
535 type = ActorTypes.Agent;
536
537 BSPrim prim;
538 if (m_prims.TryGetValue(localID, out prim)) {
539 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
540 m_primsWithCollisions.Add(prim);
541 return;
542 } 593 }
543 BSCharacter actor; 594 else
544 if (m_avatars.TryGetValue(localID, out actor)) { 595 {
545 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 596 collidee = PhysObjects[collidingWith];
546 m_avatarsWithCollisions.Add(actor); 597 if (collidee is BSCharacter)
547 return; 598 type = ActorTypes.Agent;
548 } 599 }
600
601 // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
602
603 collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration);
604 m_objectsWithCollisions.Add(collider);
605
549 return; 606 return;
550 } 607 }
551 608
552 public override void GetResults() { } 609 #endregion // Simulation
553 610
554 public override void SetTerrain(float[] heightMap) { 611 public override void GetResults() { }
555 m_heightMap = heightMap;
556 this.TaintedObject("BSScene.SetTerrain", delegate()
557 {
558 BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
559 });
560 }
561 612
562 // Someday we will have complex terrain with caves and tunnels 613 #region Terrain
563 // For the moment, it's flat and convex
564 public float GetTerrainHeightAtXYZ(Vector3 loc)
565 {
566 return GetTerrainHeightAtXY(loc.X, loc.Y);
567 }
568 614
569 public float GetTerrainHeightAtXY(float tX, float tY) 615 public override void SetTerrain(float[] heightMap) {
570 { 616 TerrainManager.SetTerrain(heightMap);
571 if (tX < 0 || tX >= Constants.RegionSize || tY < 0 || tY >= Constants.RegionSize)
572 return 30;
573 return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)];
574 } 617 }
575 618
576 public override void SetWaterLevel(float baseheight) 619 public override void SetWaterLevel(float baseheight)
@@ -588,39 +631,27 @@ public class BSScene : PhysicsScene, IPhysicsParameters
588 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); 631 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
589 } 632 }
590 633
591 public override void Dispose() 634 // Although no one seems to check this, I do support combining.
635 public override bool SupportsCombining()
592 { 636 {
593 // m_log.DebugFormat("{0}: Dispose()", LogHeader); 637 return TerrainManager.SupportsCombining();
594 638 }
595 // make sure no stepping happens while we're deleting stuff 639 // This call says I am a child to region zero in a mega-region. 'pScene' is that
596 m_initialized = false; 640 // of region zero, 'offset' is my offset from regions zero's origin, and
597 641 // 'extents' is the largest XY that is handled in my region.
598 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) 642 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
599 { 643 {
600 kvp.Value.Destroy(); 644 TerrainManager.Combine(pScene, offset, extents);
601 } 645 }
602 m_avatars.Clear();
603
604 foreach (KeyValuePair<uint, BSPrim> kvp in m_prims)
605 {
606 kvp.Value.Destroy();
607 }
608 m_prims.Clear();
609
610 // Now that the prims are all cleaned up, there should be no constraints left
611 if (m_constraintCollection != null)
612 {
613 m_constraintCollection.Dispose();
614 m_constraintCollection = null;
615 }
616
617 // Anything left in the unmanaged code should be cleaned out
618 BulletSimAPI.Shutdown(WorldID);
619 646
620 // Not logging any more 647 // Unhook all the combining that I know about.
621 PhysicsLogging.Close(); 648 public override void UnCombine(PhysicsScene pScene)
649 {
650 TerrainManager.UnCombine(pScene);
622 } 651 }
623 652
653 #endregion // Terrain
654
624 public override Dictionary<uint, float> GetTopColliders() 655 public override Dictionary<uint, float> GetTopColliders()
625 { 656 {
626 return new Dictionary<uint, float>(); 657 return new Dictionary<uint, float>();
@@ -830,14 +861,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
830 // no locking because only called when physics engine is not busy 861 // no locking because only called when physics engine is not busy
831 private void ProcessVehicles(float timeStep) 862 private void ProcessVehicles(float timeStep)
832 { 863 {
833 foreach (BSPrim prim in m_vehicles) 864 foreach (BSPhysObject pobj in m_vehicles)
834 { 865 {
835 prim.StepVehicle(timeStep); 866 pobj.StepVehicle(timeStep);
836 } 867 }
837 } 868 }
838 #endregion Vehicles 869 #endregion Vehicles
839 870
840 #region Parameters 871 #region INI and command line parameter processing
841 872
842 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); 873 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
843 delegate float ParamGet(BSScene scene); 874 delegate float ParamGet(BSScene scene);
@@ -897,16 +928,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters
897 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, 928 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
898 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), 929 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
899 930
900 new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 931 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
901 8f, 932 8f,
902 (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, 933 (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
903 (s) => { return (float)s.m_meshLOD; }, 934 (s) => { return s.MeshLOD; },
904 (s,p,l,v) => { s.m_meshLOD = (int)v; } ), 935 (s,p,l,v) => { s.MeshLOD = v; } ),
905 new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 936 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
937 16f,
938 (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
939 (s) => { return s.MeshMegaPrimLOD; },
940 (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
941 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
942 10f,
943 (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
944 (s) => { return s.MeshMegaPrimThreshold; },
945 (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
946 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
906 32f, 947 32f,
907 (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, 948 (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
908 (s) => { return (float)s.m_sculptLOD; }, 949 (s) => { return s.SculptLOD; },
909 (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), 950 (s,p,l,v) => { s.SculptLOD = v; } ),
910 951
911 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", 952 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
912 10f, 953 10f,
@@ -930,9 +971,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
930 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), 971 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
931 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", 972 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
932 10000.01f, 973 10000.01f,
933 (s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); }, 974 (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); },
934 (s) => { return (float)s.m_maximumObjectMass; }, 975 (s) => { return (float)s.MaximumObjectMass; },
935 (s,p,l,v) => { s.m_maximumObjectMass = v; } ), 976 (s,p,l,v) => { s.MaximumObjectMass = v; } ),
936 977
937 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 978 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
938 2200f, 979 2200f,
@@ -976,42 +1017,42 @@ public class BSScene : PhysicsScene, IPhysicsParameters
976 0f, 1017 0f,
977 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, 1018 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
978 (s) => { return s.m_params[0].linearDamping; }, 1019 (s) => { return s.m_params[0].linearDamping; },
979 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ), 1020 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ),
980 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 1021 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
981 0f, 1022 0f,
982 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, 1023 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
983 (s) => { return s.m_params[0].angularDamping; }, 1024 (s) => { return s.m_params[0].angularDamping; },
984 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ), 1025 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ),
985 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 1026 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
986 0.2f, 1027 0.2f,
987 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, 1028 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
988 (s) => { return s.m_params[0].deactivationTime; }, 1029 (s) => { return s.m_params[0].deactivationTime; },
989 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ), 1030 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ),
990 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 1031 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
991 0.8f, 1032 0.8f,
992 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, 1033 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
993 (s) => { return s.m_params[0].linearSleepingThreshold; }, 1034 (s) => { return s.m_params[0].linearSleepingThreshold; },
994 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), 1035 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
995 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1036 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
996 1.0f, 1037 1.0f,
997 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, 1038 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
998 (s) => { return s.m_params[0].angularSleepingThreshold; }, 1039 (s) => { return s.m_params[0].angularSleepingThreshold; },
999 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), 1040 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
1000 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 1041 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
1001 0f, // set to zero to disable 1042 0f, // set to zero to disable
1002 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, 1043 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
1003 (s) => { return s.m_params[0].ccdMotionThreshold; }, 1044 (s) => { return s.m_params[0].ccdMotionThreshold; },
1004 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), 1045 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
1005 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 1046 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
1006 0f, 1047 0f,
1007 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, 1048 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
1008 (s) => { return s.m_params[0].ccdSweptSphereRadius; }, 1049 (s) => { return s.m_params[0].ccdSweptSphereRadius; },
1009 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), 1050 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
1010 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 1051 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
1011 0.1f, 1052 0.1f,
1012 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, 1053 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
1013 (s) => { return s.m_params[0].contactProcessingThreshold; }, 1054 (s) => { return s.m_params[0].contactProcessingThreshold; },
1014 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), 1055 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
1015 1056
1016 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 1057 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
1017 0.5f, 1058 0.5f,
@@ -1029,35 +1070,35 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1029 (s) => { return s.m_params[0].terrainRestitution; }, 1070 (s) => { return s.m_params[0].terrainRestitution; },
1030 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ), 1071 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ),
1031 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 1072 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
1032 0.5f, 1073 0.2f,
1033 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, 1074 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
1034 (s) => { return s.m_params[0].avatarFriction; }, 1075 (s) => { return s.m_params[0].avatarFriction; },
1035 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ), 1076 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
1036 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", 1077 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
1037 60f, 1078 60f,
1038 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, 1079 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
1039 (s) => { return s.m_params[0].avatarDensity; }, 1080 (s) => { return s.m_params[0].avatarDensity; },
1040 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ), 1081 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ),
1041 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 1082 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
1042 0f, 1083 0f,
1043 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, 1084 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
1044 (s) => { return s.m_params[0].avatarRestitution; }, 1085 (s) => { return s.m_params[0].avatarRestitution; },
1045 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ), 1086 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
1046 new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", 1087 new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
1047 0.37f, 1088 0.37f,
1048 (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, 1089 (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
1049 (s) => { return s.m_params[0].avatarCapsuleRadius; }, 1090 (s) => { return s.m_params[0].avatarCapsuleRadius; },
1050 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), 1091 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
1051 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 1092 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
1052 1.5f, 1093 1.5f,
1053 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, 1094 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
1054 (s) => { return s.m_params[0].avatarCapsuleHeight; }, 1095 (s) => { return s.m_params[0].avatarCapsuleHeight; },
1055 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), 1096 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
1056 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 1097 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
1057 0.1f, 1098 0.1f,
1058 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, 1099 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
1059 (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, 1100 (s) => { return s.m_params[0].avatarContactProcessingThreshold; },
1060 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), 1101 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
1061 1102
1062 1103
1063 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 1104 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
@@ -1137,12 +1178,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1137 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, 1178 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
1138 (s) => { return (float)s.m_detailedStatsStep; }, 1179 (s) => { return (float)s.m_detailedStatsStep; },
1139 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), 1180 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
1140 new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
1141 ConfigurationParameters.numericFalse,
1142 (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
1143 (s) => { return s.NumericBool(s.ShouldDebugLog); },
1144 (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
1145
1146 }; 1181 };
1147 1182
1148 // Convert a boolean to our numeric true and false values 1183 // Convert a boolean to our numeric true and false values
@@ -1200,6 +1235,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1200 1235
1201 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; 1236 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
1202 1237
1238 // This creates an array in the correct format for returning the list of
1239 // parameters. This is used by the 'list' option of the 'physics' command.
1203 private void BuildParameterTable() 1240 private void BuildParameterTable()
1204 { 1241 {
1205 if (SettableParameters.Length < ParameterDefinitions.Length) 1242 if (SettableParameters.Length < ParameterDefinitions.Length)
@@ -1250,18 +1287,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1250 } 1287 }
1251 1288
1252 // check to see if we are updating a parameter for a particular or all of the prims 1289 // check to see if we are updating a parameter for a particular or all of the prims
1253 protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) 1290 protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val)
1254 {
1255 List<uint> operateOn;
1256 lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
1257 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1258 }
1259
1260 // check to see if we are updating a parameter for a particular or all of the avatars
1261 protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
1262 { 1291 {
1263 List<uint> operateOn; 1292 List<uint> operateOn;
1264 lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys); 1293 lock (PhysObjects) operateOn = new List<uint>(PhysObjects.Keys);
1265 UpdateParameterSet(operateOn, ref loc, parm, localID, val); 1294 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1266 } 1295 }
1267 1296
@@ -1284,7 +1313,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1284 TaintedObject("BSScene.UpdateParameterSet", delegate() { 1313 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1285 foreach (uint lID in objectIDs) 1314 foreach (uint lID in objectIDs)
1286 { 1315 {
1287 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); 1316 BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval);
1288 } 1317 }
1289 }); 1318 });
1290 break; 1319 break;
@@ -1302,7 +1331,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1302 string xparm = parm.ToLower(); 1331 string xparm = parm.ToLower();
1303 float xval = val; 1332 float xval = val;
1304 TaintedObject("BSScene.TaintedUpdateParameter", delegate() { 1333 TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
1305 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); 1334 BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval);
1306 }); 1335 });
1307 } 1336 }
1308 1337
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
new file mode 100755
index 0000000..47d7199
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -0,0 +1,464 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OpenSim.Framework;
32using OpenSim.Region.Framework;
33using OpenSim.Region.CoreModules;
34using OpenSim.Region.Physics.Manager;
35
36using Nini.Config;
37using log4net;
38
39using OpenMetaverse;
40
41namespace OpenSim.Region.Physics.BulletSPlugin
42{
43public class BSTerrainManager
44{
45 static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
46
47 // These height values are fractional so the odd values will be
48 // noticable when debugging.
49 public const float HEIGHT_INITIALIZATION = 24.987f;
50 public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
51 public const float HEIGHT_GETHEIGHT_RET = 24.765f;
52
53 // If the min and max height are equal, we reduce the min by this
54 // amount to make sure that a bounding box is built for the terrain.
55 public const float HEIGHT_EQUAL_FUDGE = 0.2f;
56
57 public const float TERRAIN_COLLISION_MARGIN = 0.0f;
58
59 // Until the whole simulator is changed to pass us the region size, we rely on constants.
60 public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, 0f);
61
62 // The scene that I am part of
63 private BSScene m_physicsScene;
64
65 // The ground plane created to keep thing from falling to infinity.
66 private BulletBody m_groundPlane;
67
68 // If doing mega-regions, if we're region zero we will be managing multiple
69 // region terrains since region zero does the physics for the whole mega-region.
70 private Dictionary<Vector2, BulletHeightMapInfo> m_heightMaps;
71
72 // True of the terrain has been modified.
73 // Used to force recalculation of terrain height after terrain has been modified
74 private bool m_terrainModified;
75
76 // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount.
77 // This is incremented before assigning to new region so it is the last ID allocated.
78 private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1;
79 public uint HighestTerrainID { get {return m_terrainCount; } }
80
81 // If doing mega-regions, this holds our offset from region zero of
82 // the mega-regions. "parentScene" points to the PhysicsScene of region zero.
83 private Vector3 m_worldOffset;
84 // If the parent region (region 0), this is the extent of the combined regions
85 // relative to the origin of region zero
86 private Vector3 m_worldMax;
87 private PhysicsScene m_parentScene;
88
89 public BSTerrainManager(BSScene physicsScene)
90 {
91 m_physicsScene = physicsScene;
92 m_heightMaps = new Dictionary<Vector2,BulletHeightMapInfo>();
93 m_terrainModified = false;
94
95 // Assume one region of default size
96 m_worldOffset = Vector3.Zero;
97 m_worldMax = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, 4096f);
98 m_parentScene = null;
99 }
100
101 // Create the initial instance of terrain and the underlying ground plane.
102 // The objects are allocated in the unmanaged space and the pointers are tracked
103 // by the managed code.
104 // The terrains and the groundPlane are not added to the list of PhysObjects.
105 // This is called from the initialization routine so we presume it is
106 // safe to call Bullet in real time. We hope no one is moving prims around yet.
107 public void CreateInitialGroundPlaneAndTerrain()
108 {
109 // The ground plane is here to catch things that are trying to drop to negative infinity
110 BulletShape groundPlaneShape = new BulletShape(BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN));
111 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
112 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.Ptr, Vector3.Zero, Quaternion.Identity));
113 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
114
115 Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE);
116 Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION);
117 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
118 float[] initialMap = new float[totalHeights];
119 for (int ii = 0; ii < totalHeights; ii++)
120 {
121 initialMap[ii] = HEIGHT_INITIALIZATION;
122 }
123 UpdateOrCreateTerrain(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords, true);
124 }
125
126 // Release all the terrain structures we might have allocated
127 public void ReleaseGroundPlaneAndTerrain()
128 {
129 if (m_groundPlane.Ptr != IntPtr.Zero)
130 {
131 if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr))
132 {
133 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
134 }
135 m_groundPlane.Ptr = IntPtr.Zero;
136 }
137
138 ReleaseTerrain();
139 }
140
141 // Release all the terrain we have allocated
142 public void ReleaseTerrain()
143 {
144 foreach (KeyValuePair<Vector2, BulletHeightMapInfo> kvp in m_heightMaps)
145 {
146 if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, kvp.Value.terrainBody.Ptr))
147 {
148 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, kvp.Value.terrainBody.Ptr);
149 BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr);
150 }
151 }
152 m_heightMaps.Clear();
153 }
154
155 // The simulator wants to set a new heightmap for the terrain.
156 public void SetTerrain(float[] heightMap) {
157 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
158 {
159 // If a child of a mega-region, we shouldn't have any terrain allocated for us
160 ReleaseGroundPlaneAndTerrain();
161 // If doing the mega-prim stuff and we are the child of the zero region,
162 // the terrain is added to our parent
163 if (m_parentScene is BSScene)
164 {
165 DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}",
166 BSScene.DetailLogZero, m_worldOffset, m_worldMax);
167 ((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID,
168 heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
169 }
170 }
171 else
172 {
173 // If not doing the mega-prim thing, just change the terrain
174 DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero);
175
176 UpdateOrCreateTerrain(BSScene.TERRAIN_ID, heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
177 }
178 }
179
180 // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
181 // based on the passed information. The 'id' should be either the terrain id or
182 // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used.
183 // The latter feature is for creating child terrains for mega-regions.
184 // If called with a mapInfo in m_heightMaps but the terrain has no body yet (mapInfo.terrainBody.Ptr == 0)
185 // then a new body and shape is created and the mapInfo is filled.
186 // This call is used for doing the initial terrain creation.
187 // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new
188 // terrain shape is created and added to the body.
189 // This call is most often used to update the heightMap and parameters of the terrain.
190 // The 'doNow' boolean says whether to do all the unmanaged activities right now (like when
191 // calling this routine from initialization or taint-time routines) or whether to delay
192 // all the unmanaged activities to taint-time.
193 private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool doNow)
194 {
195 DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},doNow={3}",
196 BSScene.DetailLogZero, minCoords, maxCoords, doNow);
197
198 float minZ = float.MaxValue;
199 float maxZ = float.MinValue;
200 Vector2 terrainRegionBase = new Vector2(minCoords.X, minCoords.Y);
201
202 int heightMapSize = heightMap.Length;
203 for (int ii = 0; ii < heightMapSize; ii++)
204 {
205 float height = heightMap[ii];
206 if (height < minZ) minZ = height;
207 if (height > maxZ) maxZ = height;
208 }
209
210 // The shape of the terrain is from its base to its extents.
211 minCoords.Z = minZ;
212 maxCoords.Z = maxZ;
213
214 BulletHeightMapInfo mapInfo;
215 if (m_heightMaps.TryGetValue(terrainRegionBase, out mapInfo))
216 {
217 // If this is terrain we know about, it's easy to update
218
219 mapInfo.heightMap = heightMap;
220 mapInfo.minCoords = minCoords;
221 mapInfo.maxCoords = maxCoords;
222 mapInfo.minZ = minZ;
223 mapInfo.maxZ = maxZ;
224 mapInfo.sizeX = maxCoords.X - minCoords.X;
225 mapInfo.sizeY = maxCoords.Y - minCoords.Y;
226 DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,call,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
227 BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
228
229 BSScene.TaintCallback rebuildOperation = delegate()
230 {
231 if (m_parentScene != null)
232 {
233 // It's possible that Combine() was called after this code was queued.
234 // If we are a child of combined regions, we don't create any terrain for us.
235 DetailLog("{0},UpdateOrCreateTerrain:AmACombineChild,taint", BSScene.DetailLogZero);
236
237 // Get rid of any terrain that may have been allocated for us.
238 ReleaseGroundPlaneAndTerrain();
239
240 // I hate doing this, but just bail
241 return;
242 }
243
244 if (mapInfo.terrainBody.Ptr != IntPtr.Zero)
245 {
246 // Updating an existing terrain.
247 DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
248 BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
249
250 // Remove from the dynamics world because we're going to mangle this object
251 BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
252
253 // Get rid of the old terrain
254 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
255 BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr);
256 mapInfo.Ptr = IntPtr.Zero;
257
258 /*
259 // NOTE: This routine is half here because I can't get the terrain shape replacement
260 // to work. In the short term, the above three lines completely delete the old
261 // terrain and the code below recreates one from scratch.
262 // Hopefully the Bullet community will help me out on this one.
263
264 // First, release the old collision shape (there is only one terrain)
265 BulletSimAPI.DeleteCollisionShape2(m_physicsScene.World.Ptr, mapInfo.terrainShape.Ptr);
266
267 // Fill the existing height map info with the new location and size information
268 BulletSimAPI.FillHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.Ptr, mapInfo.ID,
269 mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
270
271 // Create a terrain shape based on the new info
272 mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
273
274 // Stuff the shape into the existing terrain body
275 BulletSimAPI.SetBodyShape2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr, mapInfo.terrainShape.Ptr);
276 */
277 }
278 // else
279 {
280 // Creating a new terrain.
281 DetailLog("{0},UpdateOrCreateTerrain:CreateNewTerrain,taint,baseX={1},baseY={2},minZ={3},maxZ={4}",
282 BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ);
283
284 mapInfo.ID = id;
285 mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.ID,
286 mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
287
288 // The terrain object initial position is at the center of the object
289 Vector3 centerPos;
290 centerPos.X = minCoords.X + (mapInfo.sizeX / 2f);
291 centerPos.Y = minCoords.Y + (mapInfo.sizeY / 2f);
292 centerPos.Z = minZ + ((maxZ - minZ) / 2f);
293
294 // Create the terrain shape from the mapInfo
295 mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
296
297 mapInfo.terrainBody = new BulletBody(mapInfo.ID,
298 BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.Ptr,
299 centerPos, Quaternion.Identity));
300 }
301
302 // Make sure the entry is in the heightmap table
303 m_heightMaps[terrainRegionBase] = mapInfo;
304
305 // Set current terrain attributes
306 BulletSimAPI.SetFriction2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainFriction);
307 BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainHitFraction);
308 BulletSimAPI.SetRestitution2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainRestitution);
309 BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
310
311 BulletSimAPI.SetMassProps2(mapInfo.terrainBody.Ptr, 0f, Vector3.Zero);
312 BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.Ptr);
313
314 // Return the new terrain to the world of physical objects
315 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
316
317 // redo its bounding box now that it is in the world
318 BulletSimAPI.UpdateSingleAabb2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
319
320 // Make sure the new shape is processed.
321 BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true);
322 };
323
324 // There is the option to do the changes now (we're already in 'taint time'), or
325 // to do the Bullet operations later.
326 if (doNow)
327 rebuildOperation();
328 else
329 m_physicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation);
330 }
331 else
332 {
333 // We don't know about this terrain so either we are creating a new terrain or
334 // our mega-prim child is giving us a new terrain to add to the phys world
335
336 // if this is a child terrain, calculate a unique terrain id
337 uint newTerrainID = id;
338 if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
339 newTerrainID = ++m_terrainCount;
340
341 float[] heightMapX = heightMap;
342 Vector3 minCoordsX = minCoords;
343 Vector3 maxCoordsX = maxCoords;
344
345 DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}",
346 BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
347
348 // Code that must happen at taint-time
349 BSScene.TaintCallback createOperation = delegate()
350 {
351 DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y);
352 // Create a new mapInfo that will be filled with the new info
353 mapInfo = new BulletHeightMapInfo(id, heightMapX,
354 BulletSimAPI.CreateHeightMapInfo2(m_physicsScene.World.Ptr, newTerrainID,
355 minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN));
356 // Put the unfilled heightmap info into the collection of same
357 m_heightMaps.Add(terrainRegionBase, mapInfo);
358 // Build the terrain
359 UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true);
360 };
361
362 // If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
363 if (doNow)
364 createOperation();
365 else
366 m_physicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation);
367 }
368 }
369
370 // Someday we will have complex terrain with caves and tunnels
371 public float GetTerrainHeightAtXYZ(Vector3 loc)
372 {
373 // For the moment, it's flat and convex
374 return GetTerrainHeightAtXY(loc.X, loc.Y);
375 }
376
377 // Given an X and Y, find the height of the terrain.
378 // Since we could be handling multiple terrains for a mega-region,
379 // the base of the region is calcuated assuming all regions are
380 // the same size and that is the default.
381 // Once the heightMapInfo is found, we have all the information to
382 // compute the offset into the array.
383 private float lastHeightTX = 999999f;
384 private float lastHeightTY = 999999f;
385 private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
386 public float GetTerrainHeightAtXY(float tX, float tY)
387 {
388 // You'd be surprized at the number of times this routine is called
389 // with the same parameters as last time.
390 if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
391 return lastHeight;
392
393 lastHeightTX = tX;
394 lastHeightTY = tY;
395 float ret = HEIGHT_GETHEIGHT_RET;
396
397 int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
398 int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
399 Vector2 terrainBaseXY = new Vector2(offsetX, offsetY);
400
401 BulletHeightMapInfo mapInfo;
402 if (m_heightMaps.TryGetValue(terrainBaseXY, out mapInfo))
403 {
404 float regionX = tX - offsetX;
405 float regionY = tY - offsetY;
406 if (regionX >= mapInfo.sizeX || regionX < 0f) regionX = 0;
407 if (regionY >= mapInfo.sizeY || regionY < 0f) regionY = 0;
408 int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX;
409 ret = mapInfo.heightMap[mapIndex];
410 m_terrainModified = false;
411 // DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}",
412 // BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret);
413 }
414 else
415 {
416 m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
417 LogHeader, m_physicsScene.RegionName, tX, tY);
418 }
419 lastHeight = ret;
420 return ret;
421 }
422
423 // Although no one seems to check this, I do support combining.
424 public bool SupportsCombining()
425 {
426 return true;
427 }
428
429 // This routine is called two ways:
430 // One with 'offset' and 'pScene' zero and null but 'extents' giving the maximum
431 // extent of the combined regions. This is to inform the parent of the size
432 // of the combined regions.
433 // and one with 'offset' as the offset of the child region to the base region,
434 // 'pScene' pointing to the parent and 'extents' of zero. This informs the
435 // child of its relative base and new parent.
436 public void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
437 {
438 m_worldOffset = offset;
439 m_worldMax = extents;
440 m_parentScene = pScene;
441 if (pScene != null)
442 {
443 // We are a child.
444 // We want m_worldMax to be the highest coordinate of our piece of terrain.
445 m_worldMax = offset + DefaultRegionSize;
446 }
447 DetailLog("{0},BSTerrainManager.Combine,offset={1},extents={2},wOffset={3},wMax={4}",
448 BSScene.DetailLogZero, offset, extents, m_worldOffset, m_worldMax);
449 }
450
451 // Unhook all the combining that I know about.
452 public void UnCombine(PhysicsScene pScene)
453 {
454 // Just like ODE, for the moment a NOP
455 DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero);
456 }
457
458
459 private void DetailLog(string msg, params Object[] args)
460 {
461 m_physicsScene.PhysicsLogging.Write(msg, args);
462 }
463}
464}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 504bd3c..e579cf2 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -33,15 +33,25 @@ using OpenMetaverse;
33namespace OpenSim.Region.Physics.BulletSPlugin { 33namespace OpenSim.Region.Physics.BulletSPlugin {
34 34
35// Classes to allow some type checking for the API 35// Classes to allow some type checking for the API
36// These hold pointers to allocated objects in the unmanaged space.
37
38// The physics engine controller class created at initialization
36public struct BulletSim 39public struct BulletSim
37{ 40{
38 public BulletSim(uint id, BSScene bss, IntPtr xx) { ID = id; scene = bss; Ptr = xx; } 41 public BulletSim(uint worldId, BSScene bss, IntPtr xx) { worldID = worldId; scene = bss; Ptr = xx; }
39 public uint ID; 42 public uint worldID;
40 // The scene is only in here so very low level routines have a handle to print debug/error messages 43 // The scene is only in here so very low level routines have a handle to print debug/error messages
41 public BSScene scene; 44 public BSScene scene;
42 public IntPtr Ptr; 45 public IntPtr Ptr;
43} 46}
44 47
48public struct BulletShape
49{
50 public BulletShape(IntPtr xx) { Ptr = xx; }
51 public IntPtr Ptr;
52}
53
54// An allocated Bullet btRigidBody
45public struct BulletBody 55public struct BulletBody
46{ 56{
47 public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; } 57 public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; }
@@ -49,12 +59,41 @@ public struct BulletBody
49 public uint ID; 59 public uint ID;
50} 60}
51 61
62// An allocated Bullet btConstraint
52public struct BulletConstraint 63public struct BulletConstraint
53{ 64{
54 public BulletConstraint(IntPtr xx) { Ptr = xx; } 65 public BulletConstraint(IntPtr xx) { Ptr = xx; }
55 public IntPtr Ptr; 66 public IntPtr Ptr;
56} 67}
57 68
69// An allocated HeightMapThing which hold various heightmap info
70// Made a class rather than a struct so there would be only one
71// instance of this and C# will pass around pointers rather
72// than making copies.
73public class BulletHeightMapInfo
74{
75 public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
76 ID = id;
77 Ptr = xx;
78 heightMap = hm;
79 terrainRegionBase = new Vector2(0f, 0f);
80 minCoords = new Vector3(100f, 100f, 25f);
81 maxCoords = new Vector3(101f, 101f, 26f);
82 minZ = maxZ = 0f;
83 sizeX = sizeY = 256f;
84 }
85 public uint ID;
86 public IntPtr Ptr;
87 public float[] heightMap;
88 public Vector2 terrainRegionBase;
89 public Vector3 minCoords;
90 public Vector3 maxCoords;
91 public float sizeX, sizeY;
92 public float minZ, maxZ;
93 public BulletShape terrainShape;
94 public BulletBody terrainBody;
95}
96
58// =============================================================================== 97// ===============================================================================
59[StructLayout(LayoutKind.Sequential)] 98[StructLayout(LayoutKind.Sequential)]
60public struct ConvexHull 99public struct ConvexHull
@@ -179,7 +218,20 @@ public struct ConfigurationParameters
179 public const float numericFalse = 0f; 218 public const float numericFalse = 0f;
180} 219}
181 220
182// Values used by Bullet and BulletSim to control collisions 221
222// The states a bullet collision object can have
223public enum ActivationState : uint
224{
225 ACTIVE_TAG = 1,
226 ISLAND_SLEEPING,
227 WANTS_DEACTIVATION,
228 DISABLE_DEACTIVATION,
229 DISABLE_SIMULATION
230}
231
232// Values used by Bullet and BulletSim to control object properties.
233// Bullet's "CollisionFlags" has more to do with operations on the
234// object (if collisions happen, if gravity effects it, ...).
183public enum CollisionFlags : uint 235public enum CollisionFlags : uint
184{ 236{
185 CF_STATIC_OBJECT = 1 << 0, 237 CF_STATIC_OBJECT = 1 << 0,
@@ -194,8 +246,75 @@ public enum CollisionFlags : uint
194 BS_VOLUME_DETECT_OBJECT = 1 << 11, 246 BS_VOLUME_DETECT_OBJECT = 1 << 11,
195 BS_PHANTOM_OBJECT = 1 << 12, 247 BS_PHANTOM_OBJECT = 1 << 12,
196 BS_PHYSICAL_OBJECT = 1 << 13, 248 BS_PHYSICAL_OBJECT = 1 << 13,
249 BS_TERRAIN_OBJECT = 1 << 14,
250 BS_NONE = 0,
251 BS_ALL = 0xFFFFFFFF
197}; 252};
198 253
254// Values for collisions groups and masks
255public enum CollisionFilterGroups : uint
256{
257 NoneFilter = 0,
258 DefaultFilter = 1 << 0,
259 StaticFilter = 1 << 1,
260 KinematicFilter = 1 << 2,
261 DebrisFilter = 1 << 3,
262 SensorTrigger = 1 << 4,
263 CharacterFilter = 1 << 5,
264 AllFilter = 0xFFFFFFFF,
265 // Filter groups defined by BulletSim
266 GroundPlaneFilter = 1 << 10,
267 TerrainFilter = 1 << 11,
268 RaycastFilter = 1 << 12,
269 SolidFilter = 1 << 13,
270};
271
272 // For each type, we first clear and then set the collision flags
273public enum ClearCollisionFlag : uint
274{
275 Terrain = CollisionFlags.BS_ALL,
276 Phantom = CollisionFlags.BS_ALL,
277 VolumeDetect = CollisionFlags.BS_ALL,
278 PhysicalObject = CollisionFlags.BS_ALL,
279 StaticObject = CollisionFlags.BS_ALL
280}
281
282public enum SetCollisionFlag : uint
283{
284 Terrain = CollisionFlags.CF_STATIC_OBJECT
285 | CollisionFlags.BS_TERRAIN_OBJECT,
286 Phantom = CollisionFlags.CF_STATIC_OBJECT
287 | CollisionFlags.BS_PHANTOM_OBJECT
288 | CollisionFlags.CF_NO_CONTACT_RESPONSE,
289 VolumeDetect = CollisionFlags.CF_STATIC_OBJECT
290 | CollisionFlags.BS_VOLUME_DETECT_OBJECT
291 | CollisionFlags.CF_NO_CONTACT_RESPONSE,
292 PhysicalObject = CollisionFlags.BS_PHYSICAL_OBJECT,
293 StaticObject = CollisionFlags.CF_STATIC_OBJECT,
294}
295
296// Collision filters used for different types of objects
297public enum SetCollisionFilter : uint
298{
299 Terrain = CollisionFilterGroups.AllFilter,
300 Phantom = CollisionFilterGroups.GroundPlaneFilter
301 | CollisionFilterGroups.TerrainFilter,
302 VolumeDetect = CollisionFilterGroups.AllFilter,
303 PhysicalObject = CollisionFilterGroups.AllFilter,
304 StaticObject = CollisionFilterGroups.AllFilter,
305}
306
307// Collision masks used for different types of objects
308public enum SetCollisionMask : uint
309{
310 Terrain = CollisionFilterGroups.AllFilter,
311 Phantom = CollisionFilterGroups.GroundPlaneFilter
312 | CollisionFilterGroups.TerrainFilter,
313 VolumeDetect = CollisionFilterGroups.AllFilter,
314 PhysicalObject = CollisionFilterGroups.AllFilter,
315 StaticObject = CollisionFilterGroups.AllFilter
316}
317
199// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 318// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
200// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2. 319// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
201public enum ConstraintParams : int 320public enum ConstraintParams : int
@@ -221,6 +340,10 @@ public enum ConstraintParamAxis : int
221// =============================================================================== 340// ===============================================================================
222static class BulletSimAPI { 341static class BulletSimAPI {
223 342
343// Link back to the managed code for outputting log messages
344[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
345public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
346
224[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 347[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
225[return: MarshalAs(UnmanagedType.LPStr)] 348[return: MarshalAs(UnmanagedType.LPStr)]
226public static extern string GetVersion(); 349public static extern string GetVersion();
@@ -228,7 +351,11 @@ public static extern string GetVersion();
228[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 351[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
229public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, 352public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
230 int maxCollisions, IntPtr collisionArray, 353 int maxCollisions, IntPtr collisionArray,
231 int maxUpdates, IntPtr updateArray); 354 int maxUpdates, IntPtr updateArray,
355 DebugLogCallback logRoutine);
356
357[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
358public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID);
232 359
233[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 360[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
234public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); 361public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
@@ -300,6 +427,7 @@ public static extern bool SetObjectVelocity(uint worldID, uint id, Vector3 veloc
300[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 427[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
301public static extern bool SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity); 428public static extern bool SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity);
302 429
430// Set the current force acting on the object
303[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 431[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
304public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force); 432public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force);
305 433
@@ -342,8 +470,6 @@ public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
342public static extern void DumpBulletStatistics(); 470public static extern void DumpBulletStatistics();
343 471
344// Log a debug message 472// Log a debug message
345[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
346public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
347[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 473[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
348public static extern void SetDebugLogCallback(DebugLogCallback callback); 474public static extern void SetDebugLogCallback(DebugLogCallback callback);
349 475
@@ -358,6 +484,7 @@ public static extern void SetDebugLogCallback(DebugLogCallback callback);
358// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt 484// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt
359// and the old code is removed. 485// and the old code is removed.
360 486
487// Functions use while converting from API1 to API2. Can be removed when totally converted.
361[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 488[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
362public static extern IntPtr GetSimHandle2(uint worldID); 489public static extern IntPtr GetSimHandle2(uint worldID);
363 490
@@ -368,6 +495,7 @@ public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
368public static extern IntPtr GetBodyHandle2(IntPtr world, uint id); 495public static extern IntPtr GetBodyHandle2(IntPtr world, uint id);
369 496
370// =============================================================================== 497// ===============================================================================
498// Initialization and simulation
371[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 499[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
372public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, 500public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
373 int maxCollisions, IntPtr collisionArray, 501 int maxCollisions, IntPtr collisionArray,
@@ -377,7 +505,7 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
377public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); 505public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value);
378 506
379[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 507[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
380public static extern void SetHeightmap2(IntPtr world, float[] heightmap); 508public static extern void SetHeightMap2(IntPtr world, float[] heightmap);
381 509
382[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 510[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
383public static extern void Shutdown2(IntPtr sim); 511public static extern void Shutdown2(IntPtr sim);
@@ -392,23 +520,69 @@ public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSt
392[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 520[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
393public static extern bool PushUpdate2(IntPtr obj); 521public static extern bool PushUpdate2(IntPtr obj);
394 522
395/* 523// =====================================================================================
524// Mesh, hull, shape and body creation helper routines
525[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
526public static extern IntPtr CreateMeshShape2(IntPtr world,
527 int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
528 int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
529
530[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
531public static extern IntPtr CreateHullShape2(IntPtr world,
532 int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
533
534[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
535public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape);
536
537[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
538public static extern IntPtr BuildNativeShape2(IntPtr world,
539 float shapeType, float collisionMargin, Vector3 scale);
540
541[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
542public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
543
544[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
545public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
546
547[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
548public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo);
549
550[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
551public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot);
552
553[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
554public static extern IntPtr AllocateBodyInfo2(IntPtr obj);
555
556[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
557public static extern void ReleaseBodyInfo2(IntPtr obj);
558
559[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
560public static extern void DestroyObject2(IntPtr sim, IntPtr obj);
561
562// =====================================================================================
563// Terrain creation and helper routines
564[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
565public static extern void DumpMapInfo(IntPtr sim, IntPtr manInfo);
566
396[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 567[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
397public static extern IntPtr CreateMesh2(IntPtr world, int indicesCount, int* indices, int verticesCount, float* vertices ); 568public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords,
569 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
398 570
399[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 571[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
400public static extern bool BuildHull2(IntPtr world, IntPtr mesh); 572public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords,
573 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
401 574
402[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 575[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
403public static extern bool ReleaseHull2(IntPtr world, IntPtr mesh); 576public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo);
404 577
405[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 578[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
406public static extern bool DestroyMesh2(IntPtr world, IntPtr mesh); 579public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin);
407 580
408[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 581[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
409public static extern IntPtr CreateObject2(IntPtr world, ShapeData shapeData); 582public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo);
410*/
411 583
584// =====================================================================================
585// Constraint creation and helper routines
412[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 586[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
413public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, 587public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2,
414 Vector3 frame1loc, Quaternion frame1rot, 588 Vector3 frame1loc, Quaternion frame1rot,
@@ -460,11 +634,108 @@ public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams
460[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 634[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
461public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); 635public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain);
462 636
637// =====================================================================================
638// btCollisionWorld entries
463[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 639[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
464public static extern Vector3 AddObjectToWorld2(IntPtr world, IntPtr obj); 640public static extern void UpdateSingleAabb2(IntPtr world, IntPtr obj);
465 641
466[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 642[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
467public static extern Vector3 RemoveObjectFromWorld2(IntPtr world, IntPtr obj); 643public static extern void UpdateAabbs2(IntPtr world);
644
645[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
646public static extern bool GetForceUpdateAllAabbs2(IntPtr world);
647
648[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
649public static extern void SetForceUpdateAllAabbs2(IntPtr world, bool force);
650
651// =====================================================================================
652// btDynamicsWorld entries
653[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
654public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
655
656[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
657public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
658
659[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
660public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects);
661
662[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
663public static extern bool RemoveConstraintFromWorld2(IntPtr world, IntPtr constrain);
664// =====================================================================================
665// btCollisionObject entries
666[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
667public static extern Vector3 GetAnisotripicFriction2(IntPtr constrain);
668
669[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
670public static extern Vector3 SetAnisotripicFriction2(IntPtr constrain, Vector3 frict);
671
672[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
673public static extern bool HasAnisotripicFriction2(IntPtr constrain);
674
675[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
676public static extern void SetContactProcessingThreshold2(IntPtr obj, float val);
677
678[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
679public static extern float GetContactProcessingThreshold2(IntPtr obj);
680
681[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
682public static extern bool IsStaticObject2(IntPtr obj);
683
684[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
685public static extern bool IsKinematicObject2(IntPtr obj);
686
687[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
688public static extern bool IsStaticOrKinematicObject2(IntPtr obj);
689
690[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
691public static extern bool HasContactResponse2(IntPtr obj);
692
693[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
694public static extern void SetCollisionShape2(IntPtr sim, IntPtr obj, IntPtr shape);
695
696[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
697public static extern IntPtr GetCollisionShape2(IntPtr obj);
698
699[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
700public static extern int GetActivationState2(IntPtr obj);
701
702[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
703public static extern void SetActivationState2(IntPtr obj, int state);
704
705[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
706public static extern void SetDeactivationTime2(IntPtr obj, float dtime);
707
708[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
709public static extern float GetDeactivationTime2(IntPtr obj);
710
711[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
712public static extern void ForceActivationState2(IntPtr obj, ActivationState state);
713
714[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
715public static extern void Activate2(IntPtr obj, bool forceActivation);
716
717[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
718public static extern bool IsActive2(IntPtr obj);
719
720[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
721public static extern void SetRestitution2(IntPtr obj, float val);
722
723[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
724public static extern float GetRestitution2(IntPtr obj);
725
726[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
727public static extern void SetFriction2(IntPtr obj, float val);
728
729[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
730public static extern float GetFriction2(IntPtr obj);
731
732 /* Haven't defined the type 'Transform'
733[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
734public static extern Transform GetWorldTransform2(IntPtr obj);
735
736[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
737public static extern void setWorldTransform2(IntPtr obj, Transform trans);
738 */
468 739
469[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 740[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
470public static extern Vector3 GetPosition2(IntPtr obj); 741public static extern Vector3 GetPosition2(IntPtr obj);
@@ -473,86 +744,288 @@ public static extern Vector3 GetPosition2(IntPtr obj);
473public static extern Quaternion GetOrientation2(IntPtr obj); 744public static extern Quaternion GetOrientation2(IntPtr obj);
474 745
475[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 746[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
476public static extern bool SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation); 747public static extern void SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation);
477 748
478[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 749[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
479public static extern bool SetVelocity2(IntPtr obj, Vector3 velocity); 750public static extern IntPtr GetBroadphaseHandle2(IntPtr obj);
480 751
481[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 752[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
482public static extern bool SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity); 753public static extern void SetBroadphaseHandle2(IntPtr obj, IntPtr handle);
483 754
755 /*
484[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 756[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
485public static extern bool SetObjectForce2(IntPtr obj, Vector3 force); 757public static extern Transform GetInterpolationWorldTransform2(IntPtr obj);
486 758
487[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 759[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
488public static extern bool AddObjectForce2(IntPtr obj, Vector3 force); 760public static extern void SetInterpolationWorldTransform2(IntPtr obj, Transform trans);
761 */
489 762
490[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 763[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
491public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val); 764public static extern void SetInterpolationLinearVelocity2(IntPtr obj, Vector3 vel);
492 765
493[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 766[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
494public static extern bool SetCcdSweepSphereRadius2(IntPtr obj, float val); 767public static extern void SetInterpolationAngularVelocity2(IntPtr obj, Vector3 vel);
495 768
496[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 769[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
497public static extern bool SetDamping2(IntPtr obj, float lin_damping, float ang_damping); 770public static extern void SetInterpolationVelocity2(IntPtr obj, Vector3 linearVel, Vector3 angularVel);
498 771
499[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 772[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
500public static extern bool SetDeactivationTime2(IntPtr obj, float val); 773public static extern float GetHitFraction2(IntPtr obj);
501 774
502[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 775[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
503public static extern bool SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold); 776public static extern void SetHitFraction2(IntPtr obj, float val);
504 777
505[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 778[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
506public static extern bool SetContactProcessingThreshold2(IntPtr obj, float val); 779public static extern CollisionFlags GetCollisionFlags2(IntPtr obj);
507 780
508[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 781[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
509public static extern bool SetFriction2(IntPtr obj, float val); 782public static extern CollisionFlags SetCollisionFlags2(IntPtr obj, CollisionFlags flags);
510 783
511[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 784[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
512public static extern bool SetRestitution2(IntPtr obj, float val); 785public static extern CollisionFlags AddToCollisionFlags2(IntPtr obj, CollisionFlags flags);
513 786
514[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 787[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
515public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val); 788public static extern CollisionFlags RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags);
516 789
517[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 790[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
518public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang); 791public static extern float GetCcdMotionThreshold2(IntPtr obj);
519 792
520[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 793[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
521public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); 794public static extern void SetCcdMotionThreshold2(IntPtr obj, float val);
795
796[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
797public static extern float GetCcdSweepSphereRadius2(IntPtr obj);
798
799[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
800public static extern void SetCcdSweepSphereRadius2(IntPtr obj, float val);
801
802[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
803public static extern IntPtr GetUserPointer2(IntPtr obj);
804
805[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
806public static extern void SetUserPointer2(IntPtr obj, IntPtr val);
807
808// =====================================================================================
809// btRigidBody entries
810[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
811public static extern void ApplyGravity2(IntPtr obj);
812
813[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
814public static extern void SetGravity2(IntPtr obj, Vector3 val);
815
816[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
817public static extern Vector3 GetGravity2(IntPtr obj);
818
819[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
820public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
821
822[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
823public static extern float GetLinearDamping2(IntPtr obj);
824
825[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
826public static extern float GetAngularDamping2(IntPtr obj);
827
828[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
829public static extern float GetLinearSleepingThreshold2(IntPtr obj);
830
831[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
832public static extern float GetAngularSleepingThreshold2(IntPtr obj);
833
834[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
835public static extern void ApplyDamping2(IntPtr obj, float timeStep);
836
837[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
838public static extern void SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
839
840[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
841public static extern Vector3 GetLinearFactor2(IntPtr obj);
842
843[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
844public static extern void SetLinearFactor2(IntPtr obj, Vector3 factor);
845
846 /*
847[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
848public static extern void SetCenterOfMassTransform2(IntPtr obj, Transform trans);
849 */
850
851[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
852public static extern void SetCenterOfMassByPosRot2(IntPtr obj, Vector3 pos, Quaternion rot);
853
854// Add a force to the object as if its mass is one.
855[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
856public static extern void ApplyCentralForce2(IntPtr obj, Vector3 force);
857
858// Set the force being applied to the object as if its mass is one.
859[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
860public static extern void SetObjectForce2(IntPtr obj, Vector3 force);
861
862[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
863public static extern Vector3 GetTotalForce2(IntPtr obj);
864
865[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
866public static extern Vector3 GetTotalTorque2(IntPtr obj);
867
868[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
869public static extern Vector3 GetInvInertiaDiagLocal2(IntPtr obj);
870
871[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
872public static extern void SetInvInertiaDiagLocal2(IntPtr obj, Vector3 inert);
873
874[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
875public static extern void SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold);
876
877[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
878public static extern void ApplyTorque2(IntPtr obj, Vector3 torque);
879
880// Apply force at the given point. Will add torque to the object.
881[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
882public static extern void ApplyForce2(IntPtr obj, Vector3 force, Vector3 pos);
883
884// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass.
885[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
886public static extern void ApplyCentralImpulse2(IntPtr obj, Vector3 imp);
887
888// Apply impulse to the object's torque. Force is scaled by object's mass.
889[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
890public static extern void ApplyTorqueImpulse2(IntPtr obj, Vector3 imp);
891
892// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces.
893[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
894public static extern void ApplyImpulse2(IntPtr obj, Vector3 imp, Vector3 pos);
895
896[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
897public static extern void ClearForces2(IntPtr obj);
898
899[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
900public static extern void ClearAllForces2(IntPtr obj);
901
902[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
903public static extern void UpdateInertiaTensor2(IntPtr obj);
904
905[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
906public static extern Vector3 GetCenterOfMassPosition2(IntPtr obj);
907
908 /*
909[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
910public static extern Transform GetCenterOfMassTransform2(IntPtr obj);
911 */
912
913[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
914public static extern Vector3 GetLinearVelocity2(IntPtr obj);
915
916[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
917public static extern Vector3 GetAngularVelocity2(IntPtr obj);
918
919[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
920public static extern void SetLinearVelocity2(IntPtr obj, Vector3 val);
921
922[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
923public static extern void SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity);
924
925[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
926public static extern Vector3 GetVelocityInLocalPoint2(IntPtr obj, Vector3 pos);
927
928[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
929public static extern void Translate2(IntPtr obj, Vector3 trans);
930
931[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
932public static extern void UpdateDeactivation2(IntPtr obj, float timeStep);
933
934[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
935public static extern bool WantsSleeping2(IntPtr obj);
936
937[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
938public static extern void SetAngularFactor2(IntPtr obj, float factor);
939
940[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
941public static extern void SetAngularFactorV2(IntPtr obj, Vector3 factor);
942
943[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
944public static extern Vector3 GetAngularFactor2(IntPtr obj);
945
946[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
947public static extern bool IsInWorld2(IntPtr obj);
948
949[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
950public static extern void AddConstraintRef2(IntPtr obj, IntPtr constrain);
951
952[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
953public static extern void RemoveConstraintRef2(IntPtr obj, IntPtr constrain);
954
955[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
956public static extern IntPtr GetConstraintRef2(IntPtr obj, int index);
957
958[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
959public static extern int GetNumConstraintRefs2(IntPtr obj);
960
961[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
962public static extern Vector3 GetDeltaLinearVelocity2(IntPtr obj);
963
964[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
965public static extern Vector3 GetDeltaAngularVelocity2(IntPtr obj);
966
967[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
968public static extern Vector3 GetPushVelocity2(IntPtr obj);
969
970[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
971public static extern Vector3 GetTurnVelocity2(IntPtr obj);
972
973// =====================================================================================
974// btCollisionShape entries
975
976[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
977public static extern float GetAngularMotionDisc2(IntPtr shape);
978
979[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
980public static extern float GetContactBreakingThreshold2(IntPtr shape, float defaultFactor);
981
982[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
983public static extern bool IsPolyhedral2(IntPtr shape);
984
985[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
986public static extern bool IsConvex2d2(IntPtr shape);
987
988[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
989public static extern bool IsConvex2(IntPtr shape);
990
991[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
992public static extern bool IsNonMoving2(IntPtr shape);
522 993
523[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 994[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
524public static extern IntPtr SetCollisionFlags2(IntPtr obj, CollisionFlags flags); 995public static extern bool IsConcave2(IntPtr shape);
525 996
526[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 997[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
527public static extern IntPtr AddToCollisionFlags2(IntPtr obj, CollisionFlags flags); 998public static extern bool IsCompound2(IntPtr shape);
528 999
529[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1000[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
530public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags); 1001public static extern bool IsSoftBody2(IntPtr shape);
531 1002
532[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1003[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
533public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia); 1004public static extern bool IsInfinite2(IntPtr shape);
534 1005
535[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1006[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
536public static extern bool UpdateInertiaTensor2(IntPtr obj); 1007public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale);
537 1008
538[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1009[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
539public static extern bool SetGravity2(IntPtr obj, Vector3 val); 1010public static extern Vector3 GetLocalScaling2(IntPtr shape);
540 1011
541[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1012[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
542public static extern IntPtr ClearForces2(IntPtr obj); 1013public static extern void CalculateLocalInertia2(IntPtr shape, float mass, Vector3 inertia);
543 1014
544[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1015[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
545public static extern IntPtr ClearAllForces2(IntPtr obj); 1016public static extern int GetShapeType2(IntPtr shape);
546 1017
547[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1018[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
548public static extern bool SetMargin2(IntPtr obj, float val); 1019public static extern void SetMargin2(IntPtr shape, float val);
549 1020
550[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1021[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
551public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj); 1022public static extern float GetMargin2(IntPtr shape);
552 1023
553[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1024[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
554public static extern bool DestroyObject2(IntPtr world, uint id); 1025public static extern void SetCollisionFilterMask(IntPtr shape, uint filter, uint mask);
555 1026
1027// =====================================================================================
1028// Debugging
556[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1029[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
557public static extern void DumpPhysicsStatistics2(IntPtr sim); 1030public static extern void DumpPhysicsStatistics2(IntPtr sim);
558 1031