aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorBlueWall2012-12-12 16:15:32 -0500
committerBlueWall2012-12-12 16:15:32 -0500
commitc5d333c16cddbcbcceb1ed0bc937e5775c99c2bc (patch)
tree644d21cbd5b7e86d9ba3316979fd9a85bc028f51 /OpenSim
parentReplace Mono.Addins libraries (diff)
parentBulletSim: do not return the current velocity for targetVelocity. (diff)
downloadopensim-SC_OLD-c5d333c16cddbcbcceb1ed0bc937e5775c99c2bc.zip
opensim-SC_OLD-c5d333c16cddbcbcceb1ed0bc937e5775c99c2bc.tar.gz
opensim-SC_OLD-c5d333c16cddbcbcceb1ed0bc937e5775c99c2bc.tar.bz2
opensim-SC_OLD-c5d333c16cddbcbcceb1ed0bc937e5775c99c2bc.tar.xz
Merge branch 'master' of /home/opensim/var/repo/opensim
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs38
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs10
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs62
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs21
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs125
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSMotors.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs26
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs83
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs12
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs18
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs23
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt16
18 files changed, 353 insertions, 111 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index f8ec6de..7871eda 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
71 71
72 #region Internal functions 72 #region Internal functions
73 73
74 public AssetMetadata FetchMetadata(string url, UUID assetID) 74 private AssetMetadata FetchMetadata(string url, UUID assetID)
75 { 75 {
76 if (!url.EndsWith("/") && !url.EndsWith("=")) 76 if (!url.EndsWith("/") && !url.EndsWith("="))
77 url = url + "/"; 77 url = url + "/";
@@ -86,6 +86,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
86 return meta; 86 return meta;
87 } 87 }
88 88
89 private AssetBase FetchAsset(string url, UUID assetID)
90 {
91 // Test if it's already here
92 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
93 if (asset == null)
94 {
95 if (!url.EndsWith("/") && !url.EndsWith("="))
96 url = url + "/";
97
98 asset = m_scene.AssetService.Get(url + assetID.ToString());
99
100 //if (asset != null)
101 // m_log.DebugFormat("[HG ASSET MAPPER]: Fetched asset {0} of type {1} from {2} ", assetID, asset.Metadata.Type, url);
102 //else
103 // m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetch asset {0} from {1} ", assetID, url);
104
105 }
106
107 return asset;
108 }
109
89 public bool PostAsset(string url, AssetBase asset) 110 public bool PostAsset(string url, AssetBase asset)
90 { 111 {
91 if (asset != null) 112 if (asset != null)
@@ -228,11 +249,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
228 if (meta == null) 249 if (meta == null)
229 return; 250 return;
230 251
231 // The act of gathering UUIDs downloads the assets from the remote server 252 // The act of gathering UUIDs downloads some assets from the remote server
253 // but not all...
232 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 254 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
233 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); 255 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
234 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); 256 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids);
235 257 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count);
258 bool success = true;
259 foreach (UUID uuid in ids.Keys)
260 if (FetchAsset(userAssetURL, uuid) == null)
261 success = false;
262
263 // maybe all pieces got here...
264 if (!success)
265 m_log.DebugFormat("[HG ASSET MAPPER]: Problems getting item {0} from asset server {1}", assetID, userAssetURL);
266 else
267 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL);
236 } 268 }
237 269
238 270
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index e0f3c99..5c8b097 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -688,12 +688,10 @@ namespace OpenSim.Region.Framework.Scenes
688 itemCopy.SalePrice = item.SalePrice; 688 itemCopy.SalePrice = item.SalePrice;
689 itemCopy.SaleType = item.SaleType; 689 itemCopy.SaleType = item.SaleType;
690 690
691 if (AddInventoryItem(itemCopy)) 691 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
692 { 692 if (invAccess != null)
693 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 693 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
694 if (invAccess != null) 694 AddInventoryItem(itemCopy);
695 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
696 }
697 695
698 if (!Permissions.BypassPermissions()) 696 if (!Permissions.BypassPermissions())
699 { 697 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 21aa9be..83c78f6 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -124,7 +124,9 @@ public sealed class BSCharacter : BSPhysObject
124 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() 124 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
125 { 125 {
126 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 126 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
127 PhysBody.Clear();
127 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 128 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
129 PhysShape.Clear();
128 }); 130 });
129 } 131 }
130 132
@@ -194,8 +196,11 @@ public sealed class BSCharacter : BSPhysObject
194 196
195 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() 197 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
196 { 198 {
197 BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); 199 if (PhysShape.HasPhysicalShape)
198 UpdatePhysicalMassProperties(RawMass); 200 {
201 BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale);
202 UpdatePhysicalMassProperties(RawMass);
203 }
199 }); 204 });
200 205
201 } 206 }
@@ -236,7 +241,8 @@ public sealed class BSCharacter : BSPhysObject
236 // Zero some other properties directly into the physics engine 241 // Zero some other properties directly into the physics engine
237 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 242 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
238 { 243 {
239 BulletSimAPI.ClearAllForces2(PhysBody.ptr); 244 if (PhysBody.HasPhysicalBody)
245 BulletSimAPI.ClearAllForces2(PhysBody.ptr);
240 }); 246 });
241 } 247 }
242 public override void ZeroAngularMotion(bool inTaintTime) 248 public override void ZeroAngularMotion(bool inTaintTime)
@@ -245,10 +251,13 @@ public sealed class BSCharacter : BSPhysObject
245 251
246 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 252 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
247 { 253 {
248 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 254 if (PhysBody.HasPhysicalBody)
249 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 255 {
250 // The next also get rid of applied linear force but the linear velocity is untouched. 256 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
251 BulletSimAPI.ClearForces2(PhysBody.ptr); 257 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
258 // The next also get rid of applied linear force but the linear velocity is untouched.
259 BulletSimAPI.ClearForces2(PhysBody.ptr);
260 }
252 }); 261 });
253 } 262 }
254 263
@@ -273,7 +282,8 @@ public sealed class BSCharacter : BSPhysObject
273 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() 282 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
274 { 283 {
275 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 284 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
276 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 285 if (PhysBody.HasPhysicalBody)
286 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
277 }); 287 });
278 } 288 }
279 } 289 }
@@ -332,7 +342,8 @@ public sealed class BSCharacter : BSPhysObject
332 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() 342 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
333 { 343 {
334 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 344 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
335 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 345 if (PhysBody.HasPhysicalBody)
346 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
336 }); 347 });
337 ret = true; 348 ret = true;
338 } 349 }
@@ -359,7 +370,8 @@ public sealed class BSCharacter : BSPhysObject
359 PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() 370 PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
360 { 371 {
361 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); 372 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
362 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); 373 if (PhysBody.HasPhysicalBody)
374 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
363 }); 375 });
364 } 376 }
365 } 377 }
@@ -398,7 +410,8 @@ public sealed class BSCharacter : BSPhysObject
398 if (_currentFriction != PhysicsScene.Params.avatarStandingFriction) 410 if (_currentFriction != PhysicsScene.Params.avatarStandingFriction)
399 { 411 {
400 _currentFriction = PhysicsScene.Params.avatarStandingFriction; 412 _currentFriction = PhysicsScene.Params.avatarStandingFriction;
401 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); 413 if (PhysBody.HasPhysicalBody)
414 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
402 } 415 }
403 } 416 }
404 else 417 else
@@ -406,7 +419,8 @@ public sealed class BSCharacter : BSPhysObject
406 if (_currentFriction != PhysicsScene.Params.avatarFriction) 419 if (_currentFriction != PhysicsScene.Params.avatarFriction)
407 { 420 {
408 _currentFriction = PhysicsScene.Params.avatarFriction; 421 _currentFriction = PhysicsScene.Params.avatarFriction;
409 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); 422 if (PhysBody.HasPhysicalBody)
423 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
410 } 424 }
411 } 425 }
412 _velocity = value; 426 _velocity = value;
@@ -443,8 +457,11 @@ public sealed class BSCharacter : BSPhysObject
443 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 457 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
444 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() 458 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
445 { 459 {
446 // _position = BulletSimAPI.GetPosition2(BSBody.ptr); 460 if (PhysBody.HasPhysicalBody)
447 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 461 {
462 // _position = BulletSimAPI.GetPosition2(BSBody.ptr);
463 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
464 }
448 }); 465 });
449 } 466 }
450 } 467 }
@@ -517,10 +534,13 @@ public sealed class BSCharacter : BSPhysObject
517 _floatOnWater = value; 534 _floatOnWater = value;
518 PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() 535 PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate()
519 { 536 {
520 if (_floatOnWater) 537 if (PhysBody.HasPhysicalBody)
521 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); 538 {
522 else 539 if (_floatOnWater)
523 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); 540 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
541 else
542 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
543 }
524 }); 544 });
525 } 545 }
526 } 546 }
@@ -553,7 +573,8 @@ public sealed class BSCharacter : BSPhysObject
553 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 573 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
554 // Buoyancy is faked by changing the gravity applied to the object 574 // Buoyancy is faked by changing the gravity applied to the object
555 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); 575 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
556 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); 576 if (PhysBody.HasPhysicalBody)
577 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
557 } 578 }
558 } 579 }
559 580
@@ -599,7 +620,8 @@ public sealed class BSCharacter : BSPhysObject
599 PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() 620 PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
600 { 621 {
601 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); 622 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
602 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); 623 if (PhysBody.HasPhysicalBody)
624 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
603 }); 625 });
604 } 626 }
605 else 627 else
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 65fac00..6b1e304 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -57,7 +57,7 @@ public abstract class BSConstraint : IDisposable
57 if (m_enabled) 57 if (m_enabled)
58 { 58 {
59 m_enabled = false; 59 m_enabled = false;
60 if (m_constraint.ptr != IntPtr.Zero) 60 if (m_constraint.HasPhysicalConstraint)
61 { 61 {
62 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); 62 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr);
63 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", 63 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
@@ -65,7 +65,7 @@ public abstract class BSConstraint : IDisposable
65 m_body1.ID, m_body1.ptr.ToString("X"), 65 m_body1.ID, m_body1.ptr.ToString("X"),
66 m_body2.ID, m_body2.ptr.ToString("X"), 66 m_body2.ID, m_body2.ptr.ToString("X"),
67 success); 67 success);
68 m_constraint.ptr = System.IntPtr.Zero; 68 m_constraint.Clear();
69 } 69 }
70 } 70 }
71 } 71 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
index 23ef052..b073555 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
@@ -65,7 +65,7 @@ public sealed class BSConstraint6Dof : BSConstraint
65 m_world = world; 65 m_world = world;
66 m_body1 = obj1; 66 m_body1 = obj1;
67 m_body2 = obj2; 67 m_body2 = obj2;
68 if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero) 68 if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody)
69 { 69 {
70 world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", 70 world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
71 BSScene.DetailLogZero, world.worldID, 71 BSScene.DetailLogZero, world.worldID,
@@ -83,7 +83,7 @@ public sealed class BSConstraint6Dof : BSConstraint
83 world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", 83 world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
84 BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), 84 BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"),
85 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); 85 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
86 if (m_constraint.ptr == IntPtr.Zero) 86 if (!m_constraint.HasPhysicalConstraint)
87 { 87 {
88 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", 88 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
89 LogHeader, obj1.ID, obj2.ID); 89 LogHeader, obj1.ID, obj2.ID);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index fa3110c..82e829e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -570,8 +570,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
570 BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); 570 BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia);
571 BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); 571 BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr);
572 572
573 VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", 573 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}",
574 Prim.LocalID, friction, localInertia, angularDamping); 574 Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping);
575 } 575 }
576 else 576 else
577 { 577 {
@@ -818,6 +818,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
818 + hoverContribution 818 + hoverContribution
819 + limitMotorUpContribution; 819 + limitMotorUpContribution;
820 820
821 Vector3 newForce = buoyancyContribution;
822
821 // If not changing some axis, reduce out velocity 823 // If not changing some axis, reduce out velocity
822 if ((m_flags & (VehicleFlag.NO_X)) != 0) 824 if ((m_flags & (VehicleFlag.NO_X)) != 0)
823 newVelocity.X = 0; 825 newVelocity.X = 0;
@@ -845,7 +847,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
845 VehicleVelocity = newVelocity; 847 VehicleVelocity = newVelocity;
846 848
847 // Other linear forces are applied as forces. 849 // Other linear forces are applied as forces.
848 Vector3 totalDownForce = buoyancyContribution * m_vehicleMass; 850 Vector3 totalDownForce = newForce * m_vehicleMass;
849 if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) 851 if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f))
850 { 852 {
851 VehicleAddForce(totalDownForce); 853 VehicleAddForce(totalDownForce);
@@ -991,8 +993,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
991 993
992 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 994 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
993 { 995 {
994 // If the vehicle is motoring into the sky, get it going back down. 996 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
995 float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition); 997 float distanceAboveGround = VehiclePosition.Z - targetHeight;
996 // Not colliding if the vehicle is off the ground 998 // Not colliding if the vehicle is off the ground
997 if (!Prim.IsColliding) 999 if (!Prim.IsColliding)
998 { 1000 {
@@ -1005,8 +1007,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1005 // has a decay factor. This says this force should 1007 // has a decay factor. This says this force should
1006 // be computed with a motor. 1008 // be computed with a motor.
1007 // TODO: add interaction with banking. 1009 // TODO: add interaction with banking.
1008 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},downForce={2}", 1010 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
1009 Prim.LocalID, distanceAboveGround, ret); 1011 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
1010 } 1012 }
1011 return ret; 1013 return ret;
1012 } 1014 }
@@ -1055,7 +1057,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1055 // TODO: Should this be applied as an angular force (torque)? 1057 // TODO: Should this be applied as an angular force (torque)?
1056 if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) 1058 if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f))
1057 { 1059 {
1058 Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; 1060 // DEBUG DEBUG DEBUG: optionally scale the angular velocity. Debugging SL vs ODE turning functions.
1061 Vector3 scaledCorrection = m_lastAngularCorrection;
1062 if (PhysicsScene.VehicleScaleAngularVelocityByTimestep)
1063 scaledCorrection *= pTimestep;
1059 VehicleRotationalVelocity = scaledCorrection; 1064 VehicleRotationalVelocity = scaledCorrection;
1060 1065
1061 VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", 1066 VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}",
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 0df4310..777c5cb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -32,6 +32,14 @@ using OMV = OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35
36// A BSPrim can get individual information about its linkedness attached
37// to it through an instance of a subclass of LinksetInfo.
38// Each type of linkset will define the information needed for its type.
39public abstract class BSLinksetInfo
40{
41}
42
35public abstract class BSLinkset 43public abstract class BSLinkset
36{ 44{
37 // private static string LogHeader = "[BULLETSIM LINKSET]"; 45 // private static string LogHeader = "[BULLETSIM LINKSET]";
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 1f7c398..d2abdb4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -32,6 +32,31 @@ using OMV = OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35
36// When a child is linked, the relationship position of the child to the parent
37// is remembered so the child's world position can be recomputed when it is
38// removed from the linkset.
39sealed class BSLinksetCompoundInfo : BSLinksetInfo
40{
41 public OMV.Vector3 OffsetPos;
42 public OMV.Quaternion OffsetRot;
43 public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r)
44 {
45 OffsetPos = p;
46 OffsetRot = r;
47 }
48 public override string ToString()
49 {
50 StringBuilder buff = new StringBuilder();
51 buff.Append("<p=");
52 buff.Append(OffsetPos.ToString());
53 buff.Append(",r=");
54 buff.Append(OffsetRot.ToString());
55 buff.Append(">");
56 return buff.ToString();
57 }
58};
59
35public sealed class BSLinksetCompound : BSLinkset 60public sealed class BSLinksetCompound : BSLinkset
36{ 61{
37 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; 62 private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
@@ -44,6 +69,7 @@ public sealed class BSLinksetCompound : BSLinkset
44 // For compound implimented linksets, if there are children, use compound shape for the root. 69 // For compound implimented linksets, if there are children, use compound shape for the root.
45 public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) 70 public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor)
46 { 71 {
72 // Returning 'unknown' means we don't have a preference.
47 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; 73 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
48 if (IsRoot(requestor) && HasAnyChildren) 74 if (IsRoot(requestor) && HasAnyChildren)
49 { 75 {
@@ -63,10 +89,10 @@ public sealed class BSLinksetCompound : BSLinkset
63 // InternalRefresh(requestor); 89 // InternalRefresh(requestor);
64 } 90 }
65 91
92 // Schedule a refresh to happen after all the other taint processing.
66 private void InternalRefresh(BSPhysObject requestor) 93 private void InternalRefresh(BSPhysObject requestor)
67 { 94 {
68 DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); 95 DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID);
69 // Queue to happen after all the other taint processing
70 PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() 96 PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate()
71 { 97 {
72 if (IsRoot(requestor) && HasAnyChildren) 98 if (IsRoot(requestor) && HasAnyChildren)
@@ -84,12 +110,19 @@ public sealed class BSLinksetCompound : BSLinkset
84 { 110 {
85 bool ret = false; 111 bool ret = false;
86 DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); 112 DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
87 if (!IsRoot(child)) 113 if (IsRoot(child))
114 {
115 // The root is going dynamic. Make sure mass is properly set.
116 m_mass = ComputeLinksetMass();
117 }
118 else
88 { 119 {
89 // The origional prims are removed from the world as the shape of the root compound 120 // The origional prims are removed from the world as the shape of the root compound
90 // shape takes over. 121 // shape takes over.
91 BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); 122 BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
92 BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); 123 BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
124 // We don't want collisions from the old linkset children.
125 BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
93 ret = true; 126 ret = true;
94 } 127 }
95 return ret; 128 return ret;
@@ -108,7 +141,7 @@ public sealed class BSLinksetCompound : BSLinkset
108 { 141 {
109 // The non-physical children can come back to life. 142 // The non-physical children can come back to life.
110 BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); 143 BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
111 // Don't force activation so setting of DISABLE_SIMULATION can stay. 144 // Don't force activation so setting of DISABLE_SIMULATION can stay if used.
112 BulletSimAPI.Activate2(child.PhysBody.ptr, false); 145 BulletSimAPI.Activate2(child.PhysBody.ptr, false);
113 ret = true; 146 ret = true;
114 } 147 }
@@ -146,6 +179,10 @@ public sealed class BSLinksetCompound : BSLinkset
146 179
147 if (!IsRoot(child)) 180 if (!IsRoot(child))
148 { 181 {
182 // Because it is a convenient time, recompute child world position and rotation based on
183 // its position in the linkset.
184 RecomputeChildWorldPosition(child, true);
185
149 // Cause the current shape to be freed and the new one to be built. 186 // Cause the current shape to be freed and the new one to be built.
150 InternalRefresh(LinksetRoot); 187 InternalRefresh(LinksetRoot);
151 ret = true; 188 ret = true;
@@ -154,6 +191,42 @@ public sealed class BSLinksetCompound : BSLinkset
154 return ret; 191 return ret;
155 } 192 }
156 193
194 // When the linkset is built, the child shape is added
195 // to the compound shape relative to the root shape. The linkset then moves around but
196 // this does not move the actual child prim. The child prim's location must be recomputed
197 // based on the location of the root shape.
198 private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime)
199 {
200 BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;
201 if (lci != null)
202 {
203 if (inTaintTime)
204 {
205 OMV.Vector3 oldPos = child.RawPosition;
206 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos;
207 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
208 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
209 child.LocalID, oldPos, lci, child.RawPosition);
210 }
211 else
212 {
213 // TaintedObject is not used here so the raw position is set now and not at taint-time.
214 child.Position = LinksetRoot.RawPosition + lci.OffsetPos;
215 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
216 }
217 }
218 else
219 {
220 // This happens when children have been added to the linkset but the linkset
221 // has not been constructed yet. So like, at taint time, adding children to a linkset
222 // and then changing properties of the children (makePhysical, for instance)
223 // but the post-print action of actually rebuilding the linkset has not yet happened.
224 // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}",
225 // LogHeader, child.LocalID);
226 DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID);
227 }
228 }
229
157 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', 230 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
158 // this routine will restore the removed constraints. 231 // this routine will restore the removed constraints.
159 // Called at taint-time!! 232 // Called at taint-time!!
@@ -192,6 +265,7 @@ public sealed class BSLinksetCompound : BSLinkset
192 child.LocalID, child.PhysBody.ptr.ToString("X")); 265 child.LocalID, child.PhysBody.ptr.ToString("X"));
193 266
194 // Cause the child's body to be rebuilt and thus restored to normal operation 267 // Cause the child's body to be rebuilt and thus restored to normal operation
268 RecomputeChildWorldPosition(child, false);
195 child.ForceBodyShapeRebuild(false); 269 child.ForceBodyShapeRebuild(false);
196 270
197 if (!HasAnyChildren) 271 if (!HasAnyChildren)
@@ -226,42 +300,57 @@ public sealed class BSLinksetCompound : BSLinkset
226 { 300 {
227 if (!IsRoot(cPrim)) 301 if (!IsRoot(cPrim))
228 { 302 {
229 // Each child position and rotation is given relative to the root. 303 // Compute the displacement of the child from the root of the linkset.
230 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); 304 // This info is saved in the child prim so the relationship does not
231 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; 305 // change over time and the new child position can be computed
232 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; 306 // when the linkset is being disassembled (the linkset may have moved).
307 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
308 if (lci == null)
309 {
310 // Each child position and rotation is given relative to the root.
311 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
312 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
313 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
314
315 // Save relative position for recomputing child's world position after moving linkset.
316 lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
317 cPrim.LinksetInfo = lci;
318 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
319 }
233 320
234 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", 321 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
235 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, displacementPos, displacementRot); 322 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
236 323
237 if (cPrim.PhysShape.isNativeShape) 324 if (cPrim.PhysShape.isNativeShape)
238 { 325 {
239 // Native shapes are not shared so we need to create a new one. 326 // A native shape is turning into a hull collision shape because native
240 // A mesh or hull is created because scale is not available on a native shape. 327 // shapes are not shared so we have to hullify it so it will be tracked
241 // (TODO: Bullet does have a btScaledCollisionShape. Can that be used?) 328 // and freed at the correct time. This also solves the scaling problem
329 // (native shapes scaled but hull/meshes are assumed to not be).
330 // TODO: decide of the native shape can just be used in the compound shape.
331 // Use call to CreateGeomNonSpecial().
242 BulletShape saveShape = cPrim.PhysShape; 332 BulletShape saveShape = cPrim.PhysShape;
243 cPrim.PhysShape.ptr = IntPtr.Zero; // Don't let the create free the child's shape 333 cPrim.PhysShape.Clear(); // Don't let the create free the child's shape
334 // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
244 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); 335 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
245 BulletShape newShape = cPrim.PhysShape; 336 BulletShape newShape = cPrim.PhysShape;
246 cPrim.PhysShape = saveShape; 337 cPrim.PhysShape = saveShape;
247 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot); 338 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos , lci.OffsetRot);
248 } 339 }
249 else 340 else
250 { 341 {
251 // For the shared shapes (meshes and hulls), just use the shape in the child. 342 // For the shared shapes (meshes and hulls), just use the shape in the child.
343 // The reference count added here will be decremented when the compound shape
344 // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
252 if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) 345 if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
253 { 346 {
254 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 347 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
255 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 348 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
256 } 349 }
257 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); 350 BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos , lci.OffsetRot);
258 } 351 }
259 } 352 }
260 353
261 // TODO: need to phantomize the child prims left behind.
262 // Maybe just destroy the children bodies and shapes and have them rebuild on unlink.
263 // Selection/deselection might cause way too many build/destructions esp. for LARGE linksets.
264
265 return false; // 'false' says to move onto the next child in the list 354 return false; // 'false' says to move onto the next child in the list
266 }); 355 });
267 356
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
index 851d508..cf0a9dc 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
@@ -65,7 +65,7 @@ public abstract class BSMotor
65// Can all the incremental stepping be replaced with motor classes? 65// Can all the incremental stepping be replaced with motor classes?
66 66
67// Motor which moves CurrentValue to TargetValue over TimeScale seconds. 67// Motor which moves CurrentValue to TargetValue over TimeScale seconds.
68// The TargetValue is decays in TargetValueDecayTimeScale and 68// The TargetValue decays in TargetValueDecayTimeScale and
69// the CurrentValue will be held back by FrictionTimeScale. 69// the CurrentValue will be held back by FrictionTimeScale.
70// TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay. 70// TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay.
71 71
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index f6a890e..f3b6993 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -60,6 +60,9 @@ public abstract class BSPhysObject : PhysicsActor
60 Linkset = BSLinkset.Factory(PhysicsScene, this); 60 Linkset = BSLinkset.Factory(PhysicsScene, this);
61 LastAssetBuildFailed = false; 61 LastAssetBuildFailed = false;
62 62
63 // Default material type
64 Material = MaterialAttributes.Material.Wood;
65
63 CollisionCollection = new CollisionEventUpdate(); 66 CollisionCollection = new CollisionEventUpdate();
64 SubscribedEventsMs = 0; 67 SubscribedEventsMs = 0;
65 CollidingStep = 0; 68 CollidingStep = 0;
@@ -72,6 +75,7 @@ public abstract class BSPhysObject : PhysicsActor
72 public string TypeName { get; protected set; } 75 public string TypeName { get; protected set; }
73 76
74 public BSLinkset Linkset { get; set; } 77 public BSLinkset Linkset { get; set; }
78 public BSLinksetInfo LinksetInfo { get; set; }
75 79
76 // Return the object mass without calculating it or having side effects 80 // Return the object mass without calculating it or having side effects
77 public abstract float RawMass { get; } 81 public abstract float RawMass { get; }
@@ -109,6 +113,13 @@ public abstract class BSPhysObject : PhysicsActor
109 public abstract bool IsSolid { get; } 113 public abstract bool IsSolid { get; }
110 public abstract bool IsStatic { get; } 114 public abstract bool IsStatic { get; }
111 115
116 // Materialness
117 public MaterialAttributes.Material Material { get; private set; }
118 public override void SetMaterial(int material)
119 {
120 Material = (MaterialAttributes.Material)material;
121 }
122
112 // Stop all physical motion. 123 // Stop all physical motion.
113 public abstract void ZeroMotion(bool inTaintTime); 124 public abstract void ZeroMotion(bool inTaintTime);
114 public abstract void ZeroAngularMotion(bool inTaintTime); 125 public abstract void ZeroAngularMotion(bool inTaintTime);
@@ -128,6 +139,17 @@ public abstract class BSPhysObject : PhysicsActor
128 public abstract OMV.Quaternion RawOrientation { get; set; } 139 public abstract OMV.Quaternion RawOrientation { get; set; }
129 public abstract OMV.Quaternion ForceOrientation { get; set; } 140 public abstract OMV.Quaternion ForceOrientation { get; set; }
130 141
142 // The system is telling us the velocity it wants to move at.
143 protected OMV.Vector3 m_targetVelocity;
144 public override OMV.Vector3 TargetVelocity
145 {
146 get { return m_targetVelocity; }
147 set
148 {
149 m_targetVelocity = value;
150 Velocity = value;
151 }
152 }
131 public abstract OMV.Vector3 ForceVelocity { get; set; } 153 public abstract OMV.Vector3 ForceVelocity { get; set; }
132 154
133 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } 155 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
@@ -243,7 +265,9 @@ public abstract class BSPhysObject : PhysicsActor
243 SubscribedEventsMs = 0; 265 SubscribedEventsMs = 0;
244 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() 266 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
245 { 267 {
246 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 268 // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
269 if (PhysBody.HasPhysicalBody)
270 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
247 }); 271 });
248 } 272 }
249 // Return 'true' if the simulator wants collision events 273 // Return 'true' if the simulator wants collision events
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 4d203ff..35d22c0 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -108,8 +108,8 @@ public sealed class BSPrim : BSPhysObject
108 _mass = CalculateMass(); 108 _mass = CalculateMass();
109 109
110 // No body or shape yet 110 // No body or shape yet
111 PhysBody = new BulletBody(LocalID, IntPtr.Zero); 111 PhysBody = new BulletBody(LocalID);
112 PhysShape = new BulletShape(IntPtr.Zero); 112 PhysShape = new BulletShape();
113 113
114 DetailLog("{0},BSPrim.constructor,call", LocalID); 114 DetailLog("{0},BSPrim.constructor,call", LocalID);
115 // do the actual object creation at taint time 115 // do the actual object creation at taint time
@@ -143,7 +143,9 @@ public sealed class BSPrim : BSPhysObject
143 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 143 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
144 // If there are physical body and shape, release my use of same. 144 // If there are physical body and shape, release my use of same.
145 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 145 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
146 PhysBody.Clear();
146 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 147 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
148 PhysShape.Clear();
147 }); 149 });
148 } 150 }
149 151
@@ -189,7 +191,8 @@ public sealed class BSPrim : BSPhysObject
189 } 191 }
190 } 192 }
191 public override bool Selected { 193 public override bool Selected {
192 set { 194 set
195 {
193 if (value != _isSelected) 196 if (value != _isSelected)
194 { 197 {
195 _isSelected = value; 198 _isSelected = value;
@@ -247,7 +250,8 @@ public sealed class BSPrim : BSPhysObject
247 // Zero some other properties in the physics engine 250 // Zero some other properties in the physics engine
248 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 251 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
249 { 252 {
250 BulletSimAPI.ClearAllForces2(PhysBody.ptr); 253 if (PhysBody.HasPhysicalBody)
254 BulletSimAPI.ClearAllForces2(PhysBody.ptr);
251 }); 255 });
252 } 256 }
253 public override void ZeroAngularMotion(bool inTaintTime) 257 public override void ZeroAngularMotion(bool inTaintTime)
@@ -257,8 +261,11 @@ public sealed class BSPrim : BSPhysObject
257 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 261 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
258 { 262 {
259 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); 263 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
260 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); 264 if (PhysBody.HasPhysicalBody)
261 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); 265 {
266 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
267 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
268 }
262 }); 269 });
263 } 270 }
264 271
@@ -295,8 +302,11 @@ public sealed class BSPrim : BSPhysObject
295 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() 302 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
296 { 303 {
297 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 304 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
298 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 305 if (PhysBody.HasPhysicalBody)
299 ActivateIfPhysical(false); 306 {
307 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
308 ActivateIfPhysical(false);
309 }
300 }); 310 });
301 } 311 }
302 } 312 }
@@ -322,12 +332,12 @@ public sealed class BSPrim : BSPhysObject
322 332
323 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 333 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
324 OMV.Vector3 upForce = OMV.Vector3.Zero; 334 OMV.Vector3 upForce = OMV.Vector3.Zero;
325 if (Position.Z < terrainHeight) 335 if (RawPosition.Z < terrainHeight)
326 { 336 {
327 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 337 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
328 float targetHeight = terrainHeight + (Size.Z / 2f); 338 float targetHeight = terrainHeight + (Size.Z / 2f);
329 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. 339 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
330 upForce.Z = (terrainHeight - Position.Z) * 1f; 340 upForce.Z = (terrainHeight - RawPosition.Z) * 1f;
331 ret = true; 341 ret = true;
332 } 342 }
333 343
@@ -335,10 +345,10 @@ public sealed class BSPrim : BSPhysObject
335 { 345 {
336 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); 346 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
337 // TODO: a floating motor so object will bob in the water 347 // TODO: a floating motor so object will bob in the water
338 if (Math.Abs(Position.Z - waterHeight) > 0.1f) 348 if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
339 { 349 {
340 // Upforce proportional to the distance away from the water. Correct the error in 1 sec. 350 // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
341 upForce.Z = (waterHeight - Position.Z) * 1f; 351 upForce.Z = (waterHeight - RawPosition.Z) * 1f;
342 ret = true; 352 ret = true;
343 } 353 }
344 } 354 }
@@ -413,7 +423,8 @@ public sealed class BSPrim : BSPhysObject
413 PhysicsScene.TaintedObject("BSPrim.setForce", delegate() 423 PhysicsScene.TaintedObject("BSPrim.setForce", delegate()
414 { 424 {
415 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 425 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
416 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); 426 if (PhysBody.HasPhysicalBody)
427 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
417 }); 428 });
418 } 429 }
419 } 430 }
@@ -507,7 +518,8 @@ public sealed class BSPrim : BSPhysObject
507 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() 518 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
508 { 519 {
509 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 520 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
510 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); 521 if (PhysBody.HasPhysicalBody)
522 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
511 }); 523 });
512 } 524 }
513 } 525 }
@@ -556,9 +568,12 @@ public sealed class BSPrim : BSPhysObject
556 // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? 568 // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
557 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() 569 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
558 { 570 {
559 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); 571 if (PhysBody.HasPhysicalBody)
560 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 572 {
561 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 573 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
574 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
575 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
576 }
562 }); 577 });
563 } 578 }
564 } 579 }
@@ -683,8 +698,9 @@ public sealed class BSPrim : BSPhysObject
683 ZeroMotion(true); 698 ZeroMotion(true);
684 699
685 // Set various physical properties so other object interact properly 700 // Set various physical properties so other object interact properly
686 BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); 701 MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
687 BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); 702 BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
703 BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
688 704
689 // Mass is zero which disables a bunch of physics stuff in Bullet 705 // Mass is zero which disables a bunch of physics stuff in Bullet
690 UpdatePhysicalMassProperties(0f); 706 UpdatePhysicalMassProperties(0f);
@@ -711,9 +727,10 @@ public sealed class BSPrim : BSPhysObject
711 // Not a Bullet static object 727 // Not a Bullet static object
712 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 728 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
713 729
714 // Set various physical properties so internal dynamic properties will get computed correctly as they are set 730 // Set various physical properties so other object interact properly
715 BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); 731 MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
716 BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); 732 BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
733 BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
717 734
718 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 735 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
719 // Since this can be called multiple times, only zero forces when becoming physical 736 // Since this can be called multiple times, only zero forces when becoming physical
@@ -861,7 +878,8 @@ public sealed class BSPrim : BSPhysObject
861 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 878 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
862 { 879 {
863 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 880 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
864 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); 881 if (PhysBody.HasPhysicalBody)
882 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
865 }); 883 });
866 } 884 }
867 } 885 }
@@ -896,8 +914,11 @@ public sealed class BSPrim : BSPhysObject
896 _buoyancy = value; 914 _buoyancy = value;
897 // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 915 // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
898 // Buoyancy is faked by changing the gravity applied to the object 916 // Buoyancy is faked by changing the gravity applied to the object
899 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); 917 if (PhysBody.HasPhysicalBody)
900 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); 918 {
919 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
920 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
921 }
901 } 922 }
902 } 923 }
903 924
@@ -965,7 +986,8 @@ public sealed class BSPrim : BSPhysObject
965 } 986 }
966 DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); 987 DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum);
967 if (fSum != OMV.Vector3.Zero) 988 if (fSum != OMV.Vector3.Zero)
968 BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); 989 if (PhysBody.HasPhysicalBody)
990 BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum);
969 }); 991 });
970 } 992 }
971 993
@@ -976,7 +998,8 @@ public sealed class BSPrim : BSPhysObject
976 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate() 998 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate()
977 { 999 {
978 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse); 1000 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse);
979 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse); 1001 if (PhysBody.HasPhysicalBody)
1002 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse);
980 }); 1003 });
981 } 1004 }
982 1005
@@ -1012,7 +1035,8 @@ public sealed class BSPrim : BSPhysObject
1012 DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); 1035 DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum);
1013 if (fSum != OMV.Vector3.Zero) 1036 if (fSum != OMV.Vector3.Zero)
1014 { 1037 {
1015 BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); 1038 if (PhysBody.HasPhysicalBody)
1039 BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum);
1016 _torque = fSum; 1040 _torque = fSum;
1017 } 1041 }
1018 }); 1042 });
@@ -1026,7 +1050,8 @@ public sealed class BSPrim : BSPhysObject
1026 OMV.Vector3 applyImpulse = impulse; 1050 OMV.Vector3 applyImpulse = impulse;
1027 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1051 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
1028 { 1052 {
1029 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); 1053 if (PhysBody.HasPhysicalBody)
1054 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse);
1030 }); 1055 });
1031 } 1056 }
1032 1057
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index f72bd74..f4f2801 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -188,6 +188,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
188 private bool m_physicsLoggingDoFlush; 188 private bool m_physicsLoggingDoFlush;
189 // 'true' of the vehicle code is to log lots of details 189 // 'true' of the vehicle code is to log lots of details
190 public bool VehicleLoggingEnabled { get; private set; } 190 public bool VehicleLoggingEnabled { get; private set; }
191 public bool VehiclePhysicalLoggingEnabled { get; private set; }
192 public bool VehicleScaleAngularVelocityByTimestep { get; private set; }
191 193
192 #region Construction and Initialization 194 #region Construction and Initialization
193 public BSScene(string identifier) 195 public BSScene(string identifier)
@@ -297,6 +299,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
297 m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); 299 m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false);
298 // Very detailed logging for vehicle debugging 300 // Very detailed logging for vehicle debugging
299 VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 301 VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
302 VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false);
300 303
301 // Do any replacements in the parameters 304 // Do any replacements in the parameters
302 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); 305 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
@@ -501,7 +504,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
501 504
502 try 505 try
503 { 506 {
504 if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG 507 if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG
505 if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); 508 if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
506 509
507 numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, 510 numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
@@ -510,7 +513,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
510 if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); 513 if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
511 DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", 514 DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
512 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); 515 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
513 if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG 516 if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG
514 } 517 }
515 catch (Exception e) 518 catch (Exception e)
516 { 519 {
@@ -1226,6 +1229,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1226 (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, 1229 (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); },
1227 (s) => { return s.m_params[0].vehicleAngularDamping; }, 1230 (s) => { return s.m_params[0].vehicleAngularDamping; },
1228 (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), 1231 (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ),
1232 new ParameterDefn("VehicleScaleAngularVelocityByTimestep", "If true, scale angular turning by timestep",
1233 ConfigurationParameters.numericFalse,
1234 (s,cf,p,v) => { s.VehicleScaleAngularVelocityByTimestep = cf.GetBoolean(p, s.BoolNumeric(v)); },
1235 (s) => { return s.NumericBool(s.VehicleScaleAngularVelocityByTimestep); },
1236 (s,p,l,v) => { s.VehicleScaleAngularVelocityByTimestep = s.BoolNumeric(v); } ),
1229 1237
1230 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 1238 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
1231 0f, 1239 0f,
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 933f573..4ab9a99 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -149,7 +149,7 @@ public sealed class BSShapeCollection : IDisposable
149 // Called when releasing use of a BSBody. BSShape is handled separately. 149 // Called when releasing use of a BSBody. BSShape is handled separately.
150 public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) 150 public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback )
151 { 151 {
152 if (body.ptr == IntPtr.Zero) 152 if (!body.HasPhysicalBody)
153 return; 153 return;
154 154
155 lock (m_collectionActivityLock) 155 lock (m_collectionActivityLock)
@@ -243,12 +243,12 @@ public sealed class BSShapeCollection : IDisposable
243 // Release the usage of a shape. 243 // Release the usage of a shape.
244 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) 244 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
245 { 245 {
246 if (shape.ptr == IntPtr.Zero) 246 if (!shape.HasPhysicalShape)
247 return; 247 return;
248 248
249 PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() 249 PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate()
250 { 250 {
251 if (shape.ptr != IntPtr.Zero) 251 if (shape.HasPhysicalShape)
252 { 252 {
253 if (shape.isNativeShape) 253 if (shape.isNativeShape)
254 { 254 {
@@ -440,7 +440,7 @@ public sealed class BSShapeCollection : IDisposable
440 } 440 }
441 441
442 // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. 442 // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'.
443 private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) 443 public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
444 { 444 {
445 bool ret = false; 445 bool ret = false;
446 bool haveShape = false; 446 bool haveShape = false;
@@ -573,7 +573,7 @@ public sealed class BSShapeCollection : IDisposable
573 // Native shapes are scaled in Bullet so set the scaling to the size 573 // Native shapes are scaled in Bullet so set the scaling to the size
574 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); 574 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
575 } 575 }
576 if (newShape.ptr == IntPtr.Zero) 576 if (!newShape.HasPhysicalShape)
577 { 577 {
578 PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", 578 PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
579 LogHeader, prim.LocalID, shapeType); 579 LogHeader, prim.LocalID, shapeType);
@@ -590,7 +590,7 @@ public sealed class BSShapeCollection : IDisposable
590 // Called at taint-time! 590 // Called at taint-time!
591 private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) 591 private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
592 { 592 {
593 BulletShape newShape = new BulletShape(IntPtr.Zero); 593 BulletShape newShape = new BulletShape();
594 594
595 float lod; 595 float lod;
596 System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); 596 System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
@@ -793,7 +793,7 @@ public sealed class BSShapeCollection : IDisposable
793 BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL); 793 BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL);
794 newShape.shapeKey = newHullKey; 794 newShape.shapeKey = newHullKey;
795 795
796 return newShape; // 'true' means a new shape has been added to this prim 796 return newShape;
797 } 797 }
798 798
799 // Callback from convex hull creater with a newly created hull. 799 // Callback from convex hull creater with a newly created hull.
@@ -860,7 +860,7 @@ public sealed class BSShapeCollection : IDisposable
860 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) 860 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim)
861 { 861 {
862 // If the shape was successfully created, nothing more to do 862 // If the shape was successfully created, nothing more to do
863 if (newShape.ptr != IntPtr.Zero) 863 if (newShape.HasPhysicalShape)
864 return newShape; 864 return newShape;
865 865
866 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset 866 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
@@ -919,7 +919,7 @@ public sealed class BSShapeCollection : IDisposable
919 bool ret = false; 919 bool ret = false;
920 920
921 // the mesh, hull or native shape must have already been created in Bullet 921 // the mesh, hull or native shape must have already been created in Bullet
922 bool mustRebuild = (prim.PhysBody.ptr == IntPtr.Zero); 922 bool mustRebuild = !prim.PhysBody.HasPhysicalBody;
923 923
924 // If there is an existing body, verify it's of an acceptable type. 924 // If there is an existing body, verify it's of an acceptable type.
925 // If not a solid object, body is a GhostObject. Otherwise a RigidBody. 925 // If not a solid object, body is a GhostObject. Otherwise a RigidBody.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
index 83b9c37..2d379bb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
@@ -136,7 +136,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
136 { 136 {
137 if (m_mapInfo != null) 137 if (m_mapInfo != null)
138 { 138 {
139 if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) 139 if (m_mapInfo.terrainBody.HasPhysicalBody)
140 { 140 {
141 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); 141 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
142 // Frees both the body and the shape. 142 // Frees both the body and the shape.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 83df360..c28d69d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -151,13 +151,13 @@ public sealed class BSTerrainManager
151 // Release all the terrain structures we might have allocated 151 // Release all the terrain structures we might have allocated
152 public void ReleaseGroundPlaneAndTerrain() 152 public void ReleaseGroundPlaneAndTerrain()
153 { 153 {
154 if (m_groundPlane.ptr != IntPtr.Zero) 154 if (m_groundPlane.HasPhysicalBody)
155 { 155 {
156 if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) 156 if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr))
157 { 157 {
158 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); 158 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr);
159 } 159 }
160 m_groundPlane.ptr = IntPtr.Zero; 160 m_groundPlane.Clear();
161 } 161 }
162 162
163 ReleaseTerrain(); 163 ReleaseTerrain();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index 6ce767d..3473006 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -94,7 +94,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
94 m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, 94 m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
95 indicesCount, indices, verticesCount, vertices), 95 indicesCount, indices, verticesCount, vertices),
96 BSPhysicsShapeType.SHAPE_MESH); 96 BSPhysicsShapeType.SHAPE_MESH);
97 if (m_terrainShape.ptr == IntPtr.Zero) 97 if (!m_terrainShape.HasPhysicalShape)
98 { 98 {
99 // DISASTER!! 99 // DISASTER!!
100 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); 100 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID);
@@ -107,7 +107,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
107 Quaternion rot = Quaternion.Identity; 107 Quaternion rot = Quaternion.Identity;
108 108
109 m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); 109 m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot));
110 if (m_terrainBody.ptr == IntPtr.Zero) 110 if (!m_terrainBody.HasPhysicalBody)
111 { 111 {
112 // DISASTER!! 112 // DISASTER!!
113 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); 113 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
@@ -140,7 +140,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
140 140
141 public override void Dispose() 141 public override void Dispose()
142 { 142 {
143 if (m_terrainBody.ptr != IntPtr.Zero) 143 if (m_terrainBody.HasPhysicalBody)
144 { 144 {
145 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); 145 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
146 // Frees both the body and the shape. 146 // Frees both the body and the shape.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 2671995..1559025 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -53,6 +53,9 @@ public struct BulletSim
53// An allocated Bullet btRigidBody 53// An allocated Bullet btRigidBody
54public struct BulletBody 54public struct BulletBody
55{ 55{
56 public BulletBody(uint id) : this(id, IntPtr.Zero)
57 {
58 }
56 public BulletBody(uint id, IntPtr xx) 59 public BulletBody(uint id, IntPtr xx)
57 { 60 {
58 ID = id; 61 ID = id;
@@ -64,6 +67,13 @@ public struct BulletBody
64 public uint ID; 67 public uint ID;
65 public CollisionFilterGroups collisionGroup; 68 public CollisionFilterGroups collisionGroup;
66 public CollisionFilterGroups collisionMask; 69 public CollisionFilterGroups collisionMask;
70
71 public void Clear()
72 {
73 ptr = IntPtr.Zero;
74 }
75 public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
76
67 public override string ToString() 77 public override string ToString()
68 { 78 {
69 StringBuilder buff = new StringBuilder(); 79 StringBuilder buff = new StringBuilder();
@@ -103,6 +113,13 @@ public struct BulletShape
103 public BSPhysicsShapeType type; 113 public BSPhysicsShapeType type;
104 public System.UInt64 shapeKey; 114 public System.UInt64 shapeKey;
105 public bool isNativeShape; 115 public bool isNativeShape;
116
117 public void Clear()
118 {
119 ptr = IntPtr.Zero;
120 }
121 public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } }
122
106 public override string ToString() 123 public override string ToString()
107 { 124 {
108 StringBuilder buff = new StringBuilder(); 125 StringBuilder buff = new StringBuilder();
@@ -140,6 +157,12 @@ public struct BulletConstraint
140 ptr = xx; 157 ptr = xx;
141 } 158 }
142 public IntPtr ptr; 159 public IntPtr ptr;
160
161 public void Clear()
162 {
163 ptr = IntPtr.Zero;
164 }
165 public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } }
143} 166}
144 167
145// An allocated HeightMapThing which holds various heightmap info. 168// An allocated HeightMapThing which holds various heightmap info.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index a2161c3..1c7b577 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -11,12 +11,14 @@ CRASHES
11 11
12VEHICLES TODO LIST: 12VEHICLES TODO LIST:
13================================================= 13=================================================
14Neb car jiggling left and right 14Neb vehicle taking > 25ms of physics time!!
15 Happens on terrain and any other mesh object. Flat cubes are much smoother.
16Vehicles (Move smoothly) 15Vehicles (Move smoothly)
17Add vehicle collisions so IsColliding is properly reported. 16Add vehicle collisions so IsColliding is properly reported.
18 Needed for banking, limitMotorUp, movementLimiting, ... 17 Needed for banking, limitMotorUp, movementLimiting, ...
19Some vehicles should not be able to turn if no speed or off ground. 18Some vehicles should not be able to turn if no speed or off ground.
19Neb car jiggling left and right
20 Happens on terrain and any other mesh object. Flat cubes are much smoother.
21 This has been reduced but not eliminated.
20For limitMotorUp, use raycast down to find if vehicle is in the air. 22For limitMotorUp, use raycast down to find if vehicle is in the air.
21Implement function efficiency for lineaar and angular motion. 23Implement function efficiency for lineaar and angular motion.
22Should vehicle angular/linear movement friction happen after all the components 24Should vehicle angular/linear movement friction happen after all the components
@@ -30,6 +32,9 @@ Border crossing with linked vehicle causes crash
30 32
31BULLETSIM TODO LIST: 33BULLETSIM TODO LIST:
32================================================= 34=================================================
35Avatar height off after unsitting (float off ground)
36 Editting appearance then moving restores.
37 Must not be initializing height when recreating capsule after unsit.
33Duplicating a physical prim causes old prim to jump away 38Duplicating a physical prim causes old prim to jump away
34 Dup a phys prim and the original become unselected and thus interacts w/ selected prim. 39 Dup a phys prim and the original become unselected and thus interacts w/ selected prim.
35Disable activity of passive linkset children. 40Disable activity of passive linkset children.
@@ -38,7 +43,8 @@ Disable activity of passive linkset children.
38Scenes with hundred of thousands of static objects take a lot of physics CPU time. 43Scenes with hundred of thousands of static objects take a lot of physics CPU time.
39BSPrim.Force should set a continious force on the prim. The force should be 44BSPrim.Force should set a continious force on the prim. The force should be
40 applied each tick. Some limits? 45 applied each tick. Some limits?
41Single prim vehicles don't seem to properly vehiclize. 46Linksets should allow collisions to individual children
47 Add LocalID to children shapes in LinksetCompound and create events for individuals
42Gun sending shooter flying. 48Gun sending shooter flying.
43Collision margin (gap between physical objects lying on each other) 49Collision margin (gap between physical objects lying on each other)
44Boundry checking (crashes related to crossing boundry) 50Boundry checking (crashes related to crossing boundry)
@@ -145,4 +151,6 @@ Linkset implementation using compound shapes. (Resolution: implemented LinksetCo
145Light cycle falling over when driving (Resolution: implemented VerticalAttractor) 151Light cycle falling over when driving (Resolution: implemented VerticalAttractor)
146Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) 152Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.)
147Package Bullet source mods for Bullet internal stats output 153Package Bullet source mods for Bullet internal stats output
148 (Resolution: move code into WorldData.h rather than relying on patches) \ No newline at end of file 154 (Resolution: move code into WorldData.h rather than relying on patches)
155Single prim vehicles don't seem to properly vehiclize.
156 (Resolution: mass was not getting set properly for single prim linksets)