aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs78
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs13
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs139
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs55
4 files changed, 183 insertions, 102 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e76d8a4..fa21233 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -39,8 +39,7 @@ public class BSCharacter : BSPhysObject
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;
@@ -92,7 +91,7 @@ public class BSCharacter : BSPhysObject
92 { 91 {
93 _localID = localID; 92 _localID = localID;
94 _avName = avName; 93 _avName = avName;
95 _scene = parent_scene; 94 Scene = parent_scene;
96 _position = pos; 95 _position = pos;
97 _size = size; 96 _size = size;
98 _flying = isFlying; 97 _flying = isFlying;
@@ -101,11 +100,11 @@ public class BSCharacter : BSPhysObject
101 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 100 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
102 // The dimensions of the avatar capsule are kept in the scale. 101 // The dimensions of the avatar capsule are kept in the scale.
103 // Physics creates a unit capsule which is scaled by the physics engine. 102 // Physics creates a unit capsule which is scaled by the physics engine.
104 _scale = new Vector3(_scene.Params.avatarCapsuleRadius, _scene.Params.avatarCapsuleRadius, size.Z); 103 _scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z);
105 _density = _scene.Params.avatarDensity; 104 _density = Scene.Params.avatarDensity;
106 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 105 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
107 106
108 Linkset = new BSLinkset(_scene, this); 107 Linkset = new BSLinkset(Scene, this);
109 108
110 ShapeData shapeData = new ShapeData(); 109 ShapeData shapeData = new ShapeData();
111 shapeData.ID = _localID; 110 shapeData.ID = _localID;
@@ -117,19 +116,19 @@ public class BSCharacter : BSPhysObject
117 shapeData.Mass = _mass; 116 shapeData.Mass = _mass;
118 shapeData.Buoyancy = _buoyancy; 117 shapeData.Buoyancy = _buoyancy;
119 shapeData.Static = ShapeData.numericFalse; 118 shapeData.Static = ShapeData.numericFalse;
120 shapeData.Friction = _scene.Params.avatarFriction; 119 shapeData.Friction = Scene.Params.avatarFriction;
121 shapeData.Restitution = _scene.Params.avatarRestitution; 120 shapeData.Restitution = Scene.Params.avatarRestitution;
122 121
123 // do actual create at taint time 122 // do actual create at taint time
124 _scene.TaintedObject("BSCharacter.create", delegate() 123 Scene.TaintedObject("BSCharacter.create", delegate()
125 { 124 {
126 DetailLog("{0},BSCharacter.create", _localID); 125 DetailLog("{0},BSCharacter.create", _localID);
127 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); 126 BulletSimAPI.CreateObject(Scene.WorldID, shapeData);
128 127
129 // Set the buoyancy for flying. This will be refactored when all the settings happen in C# 128 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
130 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 129 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
131 130
132 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 131 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
133 // avatars get all collisions no matter what (makes walking on ground and such work) 132 // avatars get all collisions no matter what (makes walking on ground and such work)
134 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 133 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
135 }); 134 });
@@ -141,9 +140,9 @@ public class BSCharacter : BSPhysObject
141 public override void Destroy() 140 public override void Destroy()
142 { 141 {
143 DetailLog("{0},BSCharacter.Destroy", LocalID); 142 DetailLog("{0},BSCharacter.Destroy", LocalID);
144 _scene.TaintedObject("BSCharacter.destroy", delegate() 143 Scene.TaintedObject("BSCharacter.destroy", delegate()
145 { 144 {
146 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 145 BulletSimAPI.DestroyObject(Scene.WorldID, _localID);
147 }); 146 });
148 } 147 }
149 148
@@ -172,9 +171,9 @@ public class BSCharacter : BSPhysObject
172 171
173 ComputeAvatarVolumeAndMass(); 172 ComputeAvatarVolumeAndMass();
174 173
175 _scene.TaintedObject("BSCharacter.setSize", delegate() 174 Scene.TaintedObject("BSCharacter.setSize", delegate()
176 { 175 {
177 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true); 176 BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true);
178 }); 177 });
179 178
180 } 179 }
@@ -203,17 +202,17 @@ public class BSCharacter : BSPhysObject
203 202
204 public override Vector3 Position { 203 public override Vector3 Position {
205 get { 204 get {
206 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 205 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
207 return _position; 206 return _position;
208 } 207 }
209 set { 208 set {
210 _position = value; 209 _position = value;
211 PositionSanityCheck(); 210 PositionSanityCheck();
212 211
213 _scene.TaintedObject("BSCharacter.setPosition", delegate() 212 Scene.TaintedObject("BSCharacter.setPosition", delegate()
214 { 213 {
215 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 214 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
216 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 215 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
217 }); 216 });
218 } 217 }
219 } 218 }
@@ -229,10 +228,8 @@ public class BSCharacter : BSPhysObject
229 float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); 228 float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position);
230 if (Position.Z < terrainHeight) 229 if (Position.Z < terrainHeight)
231 { 230 {
232 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 231 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
233 Vector3 newPos = _position; 232 _position.Z = terrainHeight + 2.0f;
234 newPos.Z = terrainHeight + 2.0f;
235 _position = newPos;
236 ret = true; 233 ret = true;
237 } 234 }
238 235
@@ -250,10 +247,10 @@ public class BSCharacter : BSPhysObject
250 { 247 {
251 // The new position value must be pushed into the physics engine but we can't 248 // The new position value must be pushed into the physics engine but we can't
252 // just assign to "Position" because of potential call loops. 249 // just assign to "Position" because of potential call loops.
253 _scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate() 250 Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
254 { 251 {
255 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 252 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
256 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 253 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
257 }); 254 });
258 ret = true; 255 ret = true;
259 } 256 }
@@ -301,10 +298,10 @@ public class BSCharacter : BSPhysObject
301 set { 298 set {
302 _velocity = value; 299 _velocity = value;
303 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); 300 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
304 _scene.TaintedObject("BSCharacter.setVelocity", delegate() 301 Scene.TaintedObject("BSCharacter.setVelocity", delegate()
305 { 302 {
306 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); 303 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
307 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); 304 BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity);
308 }); 305 });
309 } 306 }
310 } 307 }
@@ -327,10 +324,10 @@ public class BSCharacter : BSPhysObject
327 set { 324 set {
328 _orientation = value; 325 _orientation = value;
329 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 326 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
330 _scene.TaintedObject("BSCharacter.setOrientation", delegate() 327 Scene.TaintedObject("BSCharacter.setOrientation", delegate()
331 { 328 {
332 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 329 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
333 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 330 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
334 }); 331 });
335 } 332 }
336 } 333 }
@@ -367,11 +364,11 @@ public class BSCharacter : BSPhysObject
367 set { _throttleUpdates = value; } 364 set { _throttleUpdates = value; }
368 } 365 }
369 public override bool IsColliding { 366 public override bool IsColliding {
370 get { return (_collidingStep == _scene.SimulationStep); } 367 get { return (_collidingStep == Scene.SimulationStep); }
371 set { _isColliding = value; } 368 set { _isColliding = value; }
372 } 369 }
373 public override bool CollidingGround { 370 public override bool CollidingGround {
374 get { return (_collidingGroundStep == _scene.SimulationStep); } 371 get { return (_collidingGroundStep == Scene.SimulationStep); }
375 set { _collidingGround = value; } 372 set { _collidingGround = value; }
376 } 373 }
377 public override bool CollidingObj { 374 public override bool CollidingObj {
@@ -393,10 +390,10 @@ public class BSCharacter : BSPhysObject
393 public override float Buoyancy { 390 public override float Buoyancy {
394 get { return _buoyancy; } 391 get { return _buoyancy; }
395 set { _buoyancy = value; 392 set { _buoyancy = value;
396 _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() 393 Scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
397 { 394 {
398 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 395 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
399 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 396 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
400 }); 397 });
401 } 398 }
402 } 399 }
@@ -440,7 +437,7 @@ public class BSCharacter : BSPhysObject
440 _force.Y += force.Y; 437 _force.Y += force.Y;
441 _force.Z += force.Z; 438 _force.Z += force.Z;
442 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); 439 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
443 _scene.TaintedObject("BSCharacter.AddForce", delegate() 440 Scene.TaintedObject("BSCharacter.AddForce", delegate()
444 { 441 {
445 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); 442 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
446 BulletSimAPI.AddObjectForce2(Body.Ptr, _force); 443 BulletSimAPI.AddObjectForce2(Body.Ptr, _force);
@@ -524,10 +521,9 @@ public class BSCharacter : BSPhysObject
524 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 521 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
525 PositionSanityCheck2(); 522 PositionSanityCheck2();
526 523
527 float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // just for debug 524 float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
528 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}", 525 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
529 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 526 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
530 entprop.Acceleration, entprop.RotationalVelocity, heightHere);
531 } 527 }
532 528
533 // Called by the scene when a collision with this object is reported 529 // Called by the scene when a collision with this object is reported
@@ -539,16 +535,16 @@ public class BSCharacter : BSPhysObject
539 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 535 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
540 536
541 // The following makes IsColliding() and IsCollidingGround() work 537 // The following makes IsColliding() and IsCollidingGround() work
542 _collidingStep = _scene.SimulationStep; 538 _collidingStep = Scene.SimulationStep;
543 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) 539 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
544 { 540 {
545 _collidingGroundStep = _scene.SimulationStep; 541 _collidingGroundStep = Scene.SimulationStep;
546 } 542 }
547 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); 543 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
548 544
549 // throttle collisions to the rate specified in the subscription 545 // throttle collisions to the rate specified in the subscription
550 if (_subscribedEventsMs != 0) { 546 if (_subscribedEventsMs != 0) {
551 int nowTime = _scene.SimulationNowTime; 547 int nowTime = Scene.SimulationNowTime;
552 if (nowTime >= _nextCollisionOkTime) { 548 if (nowTime >= _nextCollisionOkTime) {
553 _nextCollisionOkTime = nowTime + _subscribedEventsMs; 549 _nextCollisionOkTime = nowTime + _subscribedEventsMs;
554 550
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7b4802e..2f55ba4 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -232,15 +232,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters
232 } 232 }
233 233
234 // If Debug logging level, enable logging from the unmanaged code 234 // If Debug logging level, enable logging from the unmanaged code
235 m_DebugLogCallbackHandle = null;
235 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) 236 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
236 { 237 {
237 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);
238 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
239 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); 241 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
240 else 242 else
241 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 243 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
242 // The handle is saved in a variable to make sure it doesn't get freed after this call
243 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
244 } 244 }
245 245
246 // Get the version of the DLL 246 // Get the version of the DLL
@@ -257,7 +257,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
257 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 257 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
258 WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), 258 WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
259 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), 259 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
260 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); 260 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(),
261 m_DebugLogCallbackHandle);
261 262
262 // 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
263 // 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.
@@ -265,8 +266,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
265 266
266 Constraints = new BSConstraintCollection(World); 267 Constraints = new BSConstraintCollection(World);
267 268
268 // Note: choose one of the two following lines
269 // BulletSimAPI.CreateInitialGroundPlaneAndTerrain(WorldID);
270 TerrainManager = new BSTerrainManager(this); 269 TerrainManager = new BSTerrainManager(this);
271 TerrainManager.CreateInitialGroundPlaneAndTerrain(); 270 TerrainManager.CreateInitialGroundPlaneAndTerrain();
272 271
@@ -378,7 +377,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
378 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 377 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
379 lock (PhysObjects) PhysObjects.Add(localID, actor); 378 lock (PhysObjects) PhysObjects.Add(localID, actor);
380 379
381 // Remove kludge someday 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.
382 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor); 383 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
383 384
384 return actor; 385 return actor;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 28c1940..733d9c2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -44,8 +44,22 @@ public class BSTerrainManager
44{ 44{
45 static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; 45 static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
46 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.2f;
58
59 // The scene that I am part of
47 BSScene m_physicsScene; 60 BSScene m_physicsScene;
48 61
62 // The ground plane created to keep thing from falling to infinity.
49 private BulletBody m_groundPlane; 63 private BulletBody m_groundPlane;
50 64
51 // If doing mega-regions, if we're region zero we will be managing multiple 65 // If doing mega-regions, if we're region zero we will be managing multiple
@@ -53,6 +67,10 @@ public class BSTerrainManager
53 private Dictionary<Vector2, BulletBody> m_terrains; 67 private Dictionary<Vector2, BulletBody> m_terrains;
54 private Dictionary<Vector2, BulletHeightMapInfo> m_heightMaps; 68 private Dictionary<Vector2, BulletHeightMapInfo> m_heightMaps;
55 69
70 // True of the terrain has been modified.
71 // Used to force recalculation of terrain height after terrain has been modified
72 private bool m_terrainModified;
73
56 // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount. 74 // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount.
57 // This is incremented before assigning to new region so it is the last ID allocated. 75 // This is incremented before assigning to new region so it is the last ID allocated.
58 private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1; 76 private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1;
@@ -69,6 +87,7 @@ public class BSTerrainManager
69 m_physicsScene = physicsScene; 87 m_physicsScene = physicsScene;
70 m_terrains = new Dictionary<Vector2,BulletBody>(); 88 m_terrains = new Dictionary<Vector2,BulletBody>();
71 m_heightMaps = new Dictionary<Vector2,BulletHeightMapInfo>(); 89 m_heightMaps = new Dictionary<Vector2,BulletHeightMapInfo>();
90 m_terrainModified = false;
72 } 91 }
73 92
74 // Create the initial instance of terrain and the underlying ground plane. 93 // Create the initial instance of terrain and the underlying ground plane.
@@ -80,17 +99,18 @@ public class BSTerrainManager
80 public void CreateInitialGroundPlaneAndTerrain() 99 public void CreateInitialGroundPlaneAndTerrain()
81 { 100 {
82 // The ground plane is here to catch things that are trying to drop to negative infinity 101 // The ground plane is here to catch things that are trying to drop to negative infinity
102 BulletShape groundPlaneShape = new BulletShape(BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN));
83 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, 103 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
84 BulletSimAPI.CreateGroundPlaneBody2(BSScene.GROUNDPLANE_ID, 1f, 0.4f)); 104 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.Ptr, Vector3.Zero, Quaternion.Identity));
85 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr); 105 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
86 106
87 Vector3 minTerrainCoords = new Vector3(0f, 0f, 24f); 107 Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE);
88 Vector3 maxTerrainCoords = new Vector3(Constants.RegionSize, Constants.RegionSize, 25f); 108 Vector3 maxTerrainCoords = new Vector3(Constants.RegionSize, Constants.RegionSize, HEIGHT_INITIALIZATION);
89 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; 109 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
90 float[] initialMap = new float[totalHeights]; 110 float[] initialMap = new float[totalHeights];
91 for (int ii = 0; ii < totalHeights; ii++) 111 for (int ii = 0; ii < totalHeights; ii++)
92 { 112 {
93 initialMap[ii] = 25f; 113 initialMap[ii] = HEIGHT_INITIALIZATION;
94 } 114 }
95 CreateNewTerrainSegment(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords); 115 CreateNewTerrainSegment(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords);
96 } 116 }
@@ -108,7 +128,7 @@ public class BSTerrainManager
108 if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, kvp.Value.Ptr)) 128 if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, kvp.Value.Ptr))
109 { 129 {
110 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, kvp.Value.Ptr); 130 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, kvp.Value.Ptr);
111 BulletSimAPI.ReleaseHeightmapInfo2(m_heightMaps[kvp.Key].Ptr); 131 BulletSimAPI.ReleaseHeightMapInfo2(m_heightMaps[kvp.Key].Ptr);
112 } 132 }
113 } 133 }
114 m_terrains.Clear(); 134 m_terrains.Clear();
@@ -128,30 +148,41 @@ public class BSTerrainManager
128 int hSize = heightMap.Length; 148 int hSize = heightMap.Length;
129 for (int ii = 0; ii < hSize; ii++) 149 for (int ii = 0; ii < hSize; ii++)
130 { 150 {
131 minZ = heightMap[ii] < minZ ? heightMap[ii] : minZ; 151 float height = heightMap[ii];
132 maxZ = heightMap[ii] > maxZ ? heightMap[ii] : maxZ; 152 if (height < minZ) minZ = height;
153 if (height > maxZ) maxZ = height;
133 } 154 }
155 // If the terrain is flat, make a difference so we get a bounding box
156 if (minZ == maxZ)
157 minZ -= HEIGHT_EQUAL_FUDGE;
158
134 minCoords.Z = minZ; 159 minCoords.Z = minZ;
135 maxCoords.Z = maxZ; 160 maxCoords.Z = maxZ;
136 // If the terrain is flat, make a difference so we get a good bounding box
137 if (minZ == maxZ)
138 minZ -= 0.2f;
139 Vector2 terrainRegionBase = new Vector2(minCoords.X, minCoords.Y); 161 Vector2 terrainRegionBase = new Vector2(minCoords.X, minCoords.Y);
140 162
141 // Create the heightmap data structure in the unmanaged space 163 // Create the heightmap data structure in the unmanaged space
142 BulletHeightMapInfo mapInfo = new BulletHeightMapInfo( 164 BulletHeightMapInfo mapInfo = new BulletHeightMapInfo(id, heightMap,
143 BulletSimAPI.CreateHeightmap2(minCoords, maxCoords, heightMap), heightMap); 165 BulletSimAPI.CreateHeightMapInfo2(id, minCoords, maxCoords, heightMap, TERRAIN_COLLISION_MARGIN));
144 mapInfo.terrainRegionBase = terrainRegionBase; 166 mapInfo.terrainRegionBase = terrainRegionBase;
145 mapInfo.maxRegionExtent = maxCoords; 167 mapInfo.minCoords = minCoords;
168 mapInfo.maxCoords = maxCoords;
146 mapInfo.minZ = minZ; 169 mapInfo.minZ = minZ;
147 mapInfo.maxZ = maxZ; 170 mapInfo.maxZ = maxZ;
148 mapInfo.sizeX = maxCoords.X - minCoords.X; 171 mapInfo.sizeX = maxCoords.X - minCoords.X;
149 mapInfo.sizeY = maxCoords.Y - minCoords.Y; 172 mapInfo.sizeY = maxCoords.Y - minCoords.Y;
150 173
174 Vector3 centerPos;
175 centerPos.X = minCoords.X + (mapInfo.sizeX / 2f);
176 centerPos.Y = minCoords.Y + (mapInfo.sizeY / 2f);
177 centerPos.Z = minZ + (maxZ - minZ) / 2f;
178
151 DetailLog("{0},BSScene.CreateNewTerrainSegment,call,minZ={1},maxZ={2},hMapPtr={3},minC={4},maxC={5}", 179 DetailLog("{0},BSScene.CreateNewTerrainSegment,call,minZ={1},maxZ={2},hMapPtr={3},minC={4},maxC={5}",
152 BSScene.DetailLogZero, minZ, maxZ, mapInfo.Ptr, minCoords, maxCoords); 180 BSScene.DetailLogZero, minZ, maxZ, mapInfo.Ptr, minCoords, maxCoords);
153 // Create the terrain body from that heightmap 181 // Create the terrain shape from the mapInfo
154 BulletBody terrainBody = new BulletBody(id, BulletSimAPI.CreateTerrainBody2(id, mapInfo.Ptr, 0.01f)); 182 BulletShape terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
183
184 BulletBody terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2(terrainShape.Ptr,
185 centerPos, Quaternion.Identity));
155 186
156 BulletSimAPI.SetFriction2(terrainBody.Ptr, m_physicsScene.Params.terrainFriction); 187 BulletSimAPI.SetFriction2(terrainBody.Ptr, m_physicsScene.Params.terrainFriction);
157 BulletSimAPI.SetHitFraction2(terrainBody.Ptr, m_physicsScene.Params.terrainHitFraction); 188 BulletSimAPI.SetHitFraction2(terrainBody.Ptr, m_physicsScene.Params.terrainHitFraction);
@@ -163,11 +194,12 @@ public class BSTerrainManager
163 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, terrainBody.Ptr); 194 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, terrainBody.Ptr);
164 BulletSimAPI.UpdateSingleAabb2(m_physicsScene.World.Ptr, terrainBody.Ptr); 195 BulletSimAPI.UpdateSingleAabb2(m_physicsScene.World.Ptr, terrainBody.Ptr);
165 196
166
167 // Add the created terrain to the management set. If we are doing mega-regions, 197 // Add the created terrain to the management set. If we are doing mega-regions,
168 // the terrains of our children will be added. 198 // the terrains of our children will be added.
169 m_terrains.Add(terrainRegionBase, terrainBody); 199 m_terrains.Add(terrainRegionBase, terrainBody);
170 m_heightMaps.Add(terrainRegionBase, mapInfo); 200 m_heightMaps.Add(terrainRegionBase, mapInfo);
201
202 m_terrainModified = true;
171 } 203 }
172 204
173 public void SetTerrain(float[] heightMap) { 205 public void SetTerrain(float[] heightMap) {
@@ -191,34 +223,57 @@ public class BSTerrainManager
191 { 223 {
192 float minZ = float.MaxValue; 224 float minZ = float.MaxValue;
193 float maxZ = float.MinValue; 225 float maxZ = float.MinValue;
226 Vector2 terrainRegionBase = new Vector2(tOffset.X, tOffset.Y);
194 227
195 // Copy heightMap local and compute some statistics.
196 // Not really sure if we need to do this deep copy but, given
197 // the magic that happens to make the closure for taint
198 // below, I don't want there to be any problem with sharing
199 // locations of there are multiple calls to this routine
200 // within one tick.
201 int heightMapSize = heightMap.Length; 228 int heightMapSize = heightMap.Length;
202 float[] localHeightMap = new float[heightMapSize];
203 for (int ii = 0; ii < heightMapSize; ii++) 229 for (int ii = 0; ii < heightMapSize; ii++)
204 { 230 {
205 float height = heightMap[ii]; 231 float height = heightMap[ii];
206 if (height < minZ) minZ = height; 232 if (height < minZ) minZ = height;
207 if (height > maxZ) maxZ = height; 233 if (height > maxZ) maxZ = height;
208 localHeightMap[ii] = height;
209 } 234 }
210 235
211 Vector2 terrainRegionBase = new Vector2(tOffset.X, tOffset.Y); 236 // The shape of the terrain is from its base to its extents.
237 Vector3 minCoords, maxCoords;
238 minCoords = tOffset;
239 minCoords.Z = minZ;
240 maxCoords = tOffset;
241 maxCoords.X += Constants.RegionSize;
242 maxCoords.Y += Constants.RegionSize;
243 maxCoords.Z = maxZ;
244
245 BulletBody terrainBody;
212 BulletHeightMapInfo mapInfo; 246 BulletHeightMapInfo mapInfo;
213 if (m_heightMaps.TryGetValue(terrainRegionBase, out mapInfo)) 247 if (m_heightMaps.TryGetValue(terrainRegionBase, out mapInfo))
214 { 248 {
249 terrainBody = m_terrains[terrainRegionBase];
250 // Copy heightMap local and compute some statistics.
251 for (int ii = 0; ii < heightMapSize; ii++)
252 {
253 mapInfo.heightMap[ii] = heightMap[ii];
254 }
255
215 // If this is terrain we know about, it's easy to update 256 // If this is terrain we know about, it's easy to update
216 mapInfo.heightMap = localHeightMap;
217 m_physicsScene.TaintedObject("BSScene.SetTerrain:UpdateExisting", delegate() 257 m_physicsScene.TaintedObject("BSScene.SetTerrain:UpdateExisting", delegate()
218 { 258 {
219 DetailLog("{0},SetTerrain:UpdateExisting,baseX={1},baseY={2},minZ={3},maxZ={4}", 259 DetailLog("{0},SetTerrain:UpdateExisting,baseX={1},baseY={2},minZ={3},maxZ={4}",
220 BSScene.DetailLogZero, tOffset.X, tOffset.Y, minZ, maxZ); 260 BSScene.DetailLogZero, tOffset.X, tOffset.Y, minZ, maxZ);
221 BulletSimAPI.UpdateHeightMap2(m_physicsScene.World.Ptr, mapInfo.Ptr, mapInfo.heightMap); 261 // Fill the existing height map info with the new location and size information
262 BulletSimAPI.FillHeightMapInfo2(mapInfo.Ptr, mapInfo.ID, minCoords, maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
263
264 // Create a terrain shape based on the new info
265 BulletShape terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
266
267 // Swap the shape in the terrain body (this also deletes the old shape)
268 bool success = BulletSimAPI.ReplaceBodyShape2(m_physicsScene.World.Ptr, terrainBody.Ptr, terrainShape.Ptr);
269
270 if (!success)
271 {
272 DetailLog("{0},SetTerrain:UpdateExisting,Failed", BSScene.DetailLogZero);
273 m_physicsScene.Logger.ErrorFormat("{0} Failed updating terrain heightmap. Region={1}",
274 LogHeader, m_physicsScene.RegionName);
275
276 }
222 }); 277 });
223 } 278 }
224 else 279 else
@@ -226,11 +281,6 @@ public class BSTerrainManager
226 // Our mega-prim child is giving us a new terrain to add to the phys world 281 // Our mega-prim child is giving us a new terrain to add to the phys world
227 uint newTerrainID = ++m_terrainCount; 282 uint newTerrainID = ++m_terrainCount;
228 283
229 Vector3 minCoords = tOffset;
230 minCoords.Z = minZ;
231 Vector3 maxCoords = new Vector3(tOffset.X + Constants.RegionSize,
232 tOffset.Y + Constants.RegionSize,
233 maxZ);
234 m_physicsScene.TaintedObject("BSScene.SetTerrain:NewTerrain", delegate() 284 m_physicsScene.TaintedObject("BSScene.SetTerrain:NewTerrain", delegate()
235 { 285 {
236 DetailLog("{0},SetTerrain:NewTerrain,baseX={1},baseY={2}", BSScene.DetailLogZero, tOffset.X, tOffset.Y); 286 DetailLog("{0},SetTerrain:NewTerrain,baseX={1},baseY={2}", BSScene.DetailLogZero, tOffset.X, tOffset.Y);
@@ -240,9 +290,9 @@ public class BSTerrainManager
240 } 290 }
241 291
242 // Someday we will have complex terrain with caves and tunnels 292 // Someday we will have complex terrain with caves and tunnels
243 // For the moment, it's flat and convex
244 public float GetTerrainHeightAtXYZ(Vector3 loc) 293 public float GetTerrainHeightAtXYZ(Vector3 loc)
245 { 294 {
295 // For the moment, it's flat and convex
246 return GetTerrainHeightAtXY(loc.X, loc.Y); 296 return GetTerrainHeightAtXY(loc.X, loc.Y);
247 } 297 }
248 298
@@ -252,9 +302,19 @@ public class BSTerrainManager
252 // the same size and that is the default. 302 // the same size and that is the default.
253 // Once the heightMapInfo is found, we have all the information to 303 // Once the heightMapInfo is found, we have all the information to
254 // compute the offset into the array. 304 // compute the offset into the array.
305 private float lastHeightTX = 999999f;
306 private float lastHeightTY = 999999f;
307 private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
255 public float GetTerrainHeightAtXY(float tX, float tY) 308 public float GetTerrainHeightAtXY(float tX, float tY)
256 { 309 {
257 float ret = 30f; 310 // You'd be surprized at the number of times this routine is called
311 // with the same parameters as last time.
312 if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
313 return lastHeight;
314
315 lastHeightTX = tX;
316 lastHeightTY = tY;
317 float ret = HEIGHT_GETHEIGHT_RET;
258 318
259 int offsetX = ((int)(tX / (int)Constants.RegionSize)) * (int)Constants.RegionSize; 319 int offsetX = ((int)(tX / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
260 int offsetY = ((int)(tY / (int)Constants.RegionSize)) * (int)Constants.RegionSize; 320 int offsetY = ((int)(tY / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
@@ -265,15 +325,20 @@ public class BSTerrainManager
265 { 325 {
266 float regionX = tX - offsetX; 326 float regionX = tX - offsetX;
267 float regionY = tY - offsetY; 327 float regionY = tY - offsetY;
268 regionX = regionX > mapInfo.sizeX ? 0 : regionX; 328 if (regionX > mapInfo.sizeX) regionX = 0;
269 regionY = regionY > mapInfo.sizeY ? 0 : regionY; 329 if (regionY > mapInfo.sizeY) regionY = 0;
270 ret = mapInfo.heightMap[(int)(regionX * mapInfo.sizeX + regionY)]; 330 int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX;
331 ret = mapInfo.heightMap[mapIndex];
332 m_terrainModified = false;
333 DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}",
334 BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret);
271 } 335 }
272 else 336 else
273 { 337 {
274 m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: x={1}, y={2}", 338 m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: x={1}, y={2}",
275 LogHeader, tX, tY); 339 LogHeader, tX, tY);
276 } 340 }
341 lastHeight = ret;
277 return ret; 342 return ret;
278 } 343 }
279 344
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 3b319fb..804d2ea 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -38,13 +38,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin {
38// The physics engine controller class created at initialization 38// The physics engine controller class created at initialization
39public struct BulletSim 39public struct BulletSim
40{ 40{
41 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; }
42 public uint ID; 42 public uint worldID;
43 // 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
44 public BSScene scene; 44 public BSScene scene;
45 public IntPtr Ptr; 45 public IntPtr Ptr;
46} 46}
47 47
48public struct BulletShape
49{
50 public BulletShape(IntPtr xx) { Ptr = xx; }
51 public IntPtr Ptr;
52}
53
48// An allocated Bullet btRigidBody 54// An allocated Bullet btRigidBody
49public struct BulletBody 55public struct BulletBody
50{ 56{
@@ -66,18 +72,22 @@ public struct BulletConstraint
66// than making copies. 72// than making copies.
67public class BulletHeightMapInfo 73public class BulletHeightMapInfo
68{ 74{
69 public BulletHeightMapInfo(IntPtr xx, float[] hm) { 75 public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
76 ID = id;
70 Ptr = xx; 77 Ptr = xx;
71 heightMap = hm; 78 heightMap = hm;
72 terrainRegionBase = new Vector2(0f, 0f); 79 terrainRegionBase = new Vector2(0f, 0f);
73 maxRegionExtent = new Vector3(100f, 100f, 25f); 80 minCoords = new Vector3(100f, 100f, 25f);
81 maxCoords = new Vector3(101f, 101f, 26f);
74 minZ = maxZ = 0f; 82 minZ = maxZ = 0f;
75 sizeX = sizeY = 256f; 83 sizeX = sizeY = 256f;
76 } 84 }
85 public uint ID;
77 public IntPtr Ptr; 86 public IntPtr Ptr;
78 public float[] heightMap; 87 public float[] heightMap;
79 public Vector2 terrainRegionBase; 88 public Vector2 terrainRegionBase;
80 public Vector3 maxRegionExtent; 89 public Vector3 minCoords;
90 public Vector3 maxCoords;
81 public float sizeX, sizeY; 91 public float sizeX, sizeY;
82 public float minZ, maxZ; 92 public float minZ, maxZ;
83} 93}
@@ -248,6 +258,10 @@ public enum ConstraintParamAxis : int
248// =============================================================================== 258// ===============================================================================
249static class BulletSimAPI { 259static class BulletSimAPI {
250 260
261// Link back to the managed code for outputting log messages
262[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
263public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
264
251[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 265[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
252[return: MarshalAs(UnmanagedType.LPStr)] 266[return: MarshalAs(UnmanagedType.LPStr)]
253public static extern string GetVersion(); 267public static extern string GetVersion();
@@ -255,7 +269,8 @@ public static extern string GetVersion();
255[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 269[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
256public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, 270public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
257 int maxCollisions, IntPtr collisionArray, 271 int maxCollisions, IntPtr collisionArray,
258 int maxUpdates, IntPtr updateArray); 272 int maxUpdates, IntPtr updateArray,
273 DebugLogCallback logRoutine);
259 274
260[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 275[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
261public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID); 276public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID);
@@ -372,8 +387,6 @@ public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
372public static extern void DumpBulletStatistics(); 387public static extern void DumpBulletStatistics();
373 388
374// Log a debug message 389// Log a debug message
375[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
376public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
377[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 390[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
378public static extern void SetDebugLogCallback(DebugLogCallback callback); 391public static extern void SetDebugLogCallback(DebugLogCallback callback);
379 392
@@ -407,7 +420,7 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
407public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); 420public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value);
408 421
409[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 422[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
410public static extern void SetHeightmap2(IntPtr world, float[] heightmap); 423public static extern void SetHeightMap2(IntPtr world, float[] heightmap);
411 424
412[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 425[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
413public static extern void Shutdown2(IntPtr sim); 426public static extern void Shutdown2(IntPtr sim);
@@ -442,25 +455,31 @@ public static extern IntPtr BuildNativeShape2(IntPtr world,
442[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 455[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
443public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); 456public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
444 457
458[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
459public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
460
461[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
462public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot);
463
464[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
465public static extern bool ReplaceBodyShape2(IntPtr sim, IntPtr obj, IntPtr shape);
445// ===================================================================================== 466// =====================================================================================
446[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 467[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
447public static extern IntPtr CreateGroundPlaneBody2(uint id, float height, float collisionMargin); 468public static extern IntPtr CreateHeightMapInfo2(uint id, Vector3 minCoords, Vector3 maxCoords,
469 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
448 470
449[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 471[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
450public static extern IntPtr CreateTerrainBody2(uint id, 472public static extern IntPtr FillHeightMapInfo2(IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords,
451 IntPtr heightMapInfo, 473 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
452 float collisionMargin);
453 474
454[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 475[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
455public static extern IntPtr CreateHeightmap2(Vector3 minCoords, Vector3 maxCoords, 476public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo);
456 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
457 477
458[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 478[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
459public static extern bool ReleaseHeightmapInfo2(IntPtr heightMapInfo); 479public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin);
460 480
461[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 481[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
462public static extern void UpdateHeightMap2(IntPtr world, IntPtr heightMapInfo, 482public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo);
463 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
464 483
465// ===================================================================================== 484// =====================================================================================
466[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 485[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]