diff options
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 78 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 13 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 139 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 55 |
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 |
39 | public struct BulletSim | 39 | public 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 | ||
48 | public 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 |
49 | public struct BulletBody | 55 | public struct BulletBody |
50 | { | 56 | { |
@@ -66,18 +72,22 @@ public struct BulletConstraint | |||
66 | // than making copies. | 72 | // than making copies. |
67 | public class BulletHeightMapInfo | 73 | public 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 | // =============================================================================== |
249 | static class BulletSimAPI { | 259 | static class BulletSimAPI { |
250 | 260 | ||
261 | // Link back to the managed code for outputting log messages | ||
262 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] | ||
263 | public 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)] |
253 | public static extern string GetVersion(); | 267 | public 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] |
256 | public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, | 270 | public 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] |
261 | public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID); | 276 | public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID); |
@@ -372,8 +387,6 @@ public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); | |||
372 | public static extern void DumpBulletStatistics(); | 387 | public static extern void DumpBulletStatistics(); |
373 | 388 | ||
374 | // Log a debug message | 389 | // Log a debug message |
375 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] | ||
376 | public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); | ||
377 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 390 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
378 | public static extern void SetDebugLogCallback(DebugLogCallback callback); | 391 | public static extern void SetDebugLogCallback(DebugLogCallback callback); |
379 | 392 | ||
@@ -407,7 +420,7 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, | |||
407 | public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); | 420 | public 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] |
410 | public static extern void SetHeightmap2(IntPtr world, float[] heightmap); | 423 | public static extern void SetHeightMap2(IntPtr world, float[] heightmap); |
411 | 424 | ||
412 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 425 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
413 | public static extern void Shutdown2(IntPtr sim); | 426 | public 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] |
443 | public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); | 456 | public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); |
444 | 457 | ||
458 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
459 | public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot); | ||
460 | |||
461 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
462 | public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot); | ||
463 | |||
464 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
465 | public 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] |
447 | public static extern IntPtr CreateGroundPlaneBody2(uint id, float height, float collisionMargin); | 468 | public 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] |
450 | public static extern IntPtr CreateTerrainBody2(uint id, | 472 | public 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] |
455 | public static extern IntPtr CreateHeightmap2(Vector3 minCoords, Vector3 maxCoords, | 476 | public 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] |
459 | public static extern bool ReleaseHeightmapInfo2(IntPtr heightMapInfo); | 479 | public 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] |
462 | public static extern void UpdateHeightMap2(IntPtr world, IntPtr heightMapInfo, | 482 | public 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] |