aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs56
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs16
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs114
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs110
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs3
5 files changed, 138 insertions, 161 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 7bc6b69..8e1171a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -114,17 +114,9 @@ public class BSCharacter : BSPhysObject
114 PhysicsScene.TaintedObject("BSCharacter.create", delegate() 114 PhysicsScene.TaintedObject("BSCharacter.create", delegate()
115 { 115 {
116 DetailLog("{0},BSCharacter.create,taint", LocalID); 116 DetailLog("{0},BSCharacter.create,taint", LocalID);
117 PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null); 117 PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null);
118 118
119 SetPhysicalProperties(); 119 SetPhysicalProperties();
120
121 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#.
122 // If not set at creation, the avatar will stop flying when created after crossing a region boundry.
123 ForceBuoyancy = _buoyancy;
124
125 // This works here because CreateObject has already put the character into the physical world.
126 BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr,
127 (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask);
128 }); 120 });
129 return; 121 return;
130 } 122 }
@@ -146,27 +138,32 @@ public class BSCharacter : BSPhysObject
146 138
147 ZeroMotion(); 139 ZeroMotion();
148 140
149 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); 141 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw);
150 BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); 142 BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
151 143
144 ForcePosition = _position;
152 // Set the velocity and compute the proper friction 145 // Set the velocity and compute the proper friction
153 ForceVelocity = _velocity; 146 ForceVelocity = _velocity;
154
155 BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction);
156 BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution); 147 BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution);
157
158 BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); 148 BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale);
159 BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); 149 BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
160
161 if (PhysicsScene.Params.ccdMotionThreshold > 0f) 150 if (PhysicsScene.Params.ccdMotionThreshold > 0f)
162 { 151 {
163 BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); 152 BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold);
164 BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); 153 BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
165 } 154 }
166 155
167 BulletSimAPI.SetActivationState2(BSBody.ptr, (int)ActivationState.DISABLE_DEACTIVATION); 156 BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT);
168 157
169 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); 158 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr);
159
160 BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_DEACTIVATION);
161 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr);
162
163 // Do this after the object has been added to the world
164 BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr,
165 (uint)CollisionFilterGroups.AvatarFilter,
166 (uint)CollisionFilterGroups.AvatarMask);
170 } 167 }
171 168
172 public override void RequestPhysicsterseUpdate() 169 public override void RequestPhysicsterseUpdate()
@@ -174,9 +171,7 @@ public class BSCharacter : BSPhysObject
174 base.RequestPhysicsterseUpdate(); 171 base.RequestPhysicsterseUpdate();
175 } 172 }
176 // No one calls this method so I don't know what it could possibly mean 173 // No one calls this method so I don't know what it could possibly mean
177 public override bool Stopped { 174 public override bool Stopped { get { return false; } }
178 get { return false; }
179 }
180 public override OMV.Vector3 Size { 175 public override OMV.Vector3 Size {
181 get 176 get
182 { 177 {
@@ -185,18 +180,14 @@ public class BSCharacter : BSPhysObject
185 } 180 }
186 181
187 set { 182 set {
188 // When an avatar's size is set, only the height is changed 183 // When an avatar's size is set, only the height is changed.
189 // and that really only depends on the radius.
190 _size = value; 184 _size = value;
191 ComputeAvatarScale(_size); 185 ComputeAvatarScale(_size);
192
193 // TODO: something has to be done with the avatar's vertical position
194
195 ComputeAvatarVolumeAndMass(); 186 ComputeAvatarVolumeAndMass();
196 187
197 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() 188 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
198 { 189 {
199 BulletSimAPI.SetLocalScaling2(BSBody.ptr, Scale); 190 BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale);
200 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSBody.ptr, MassRaw); 191 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSBody.ptr, MassRaw);
201 BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); 192 BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
202 }); 193 });
@@ -300,7 +291,7 @@ public class BSCharacter : BSPhysObject
300 // A version of the sanity check that also makes sure a new position value is 291 // A version of the sanity check that also makes sure a new position value is
301 // pushed back to the physics engine. This routine would be used by anyone 292 // pushed back to the physics engine. This routine would be used by anyone
302 // who is not already pushing the value. 293 // who is not already pushing the value.
303 private bool PositionSanityCheck2(bool inTaintTime) 294 private bool PositionSanityCheck(bool inTaintTime)
304 { 295 {
305 bool ret = false; 296 bool ret = false;
306 if (PositionSanityCheck()) 297 if (PositionSanityCheck())
@@ -378,14 +369,16 @@ public class BSCharacter : BSPhysObject
378 } 369 }
379 else 370 else
380 { 371 {
381 if (_currentFriction == 999f) 372 if (_currentFriction != PhysicsScene.Params.avatarFriction)
382 { 373 {
383 _currentFriction = PhysicsScene.Params.avatarFriction; 374 _currentFriction = PhysicsScene.Params.avatarFriction;
384 BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); 375 BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction);
385 } 376 }
386 } 377 }
387 _velocity = value; 378 _velocity = value;
379 // Remember the set velocity so we can suppress the reduction by friction, ...
388 _appliedVelocity = value; 380 _appliedVelocity = value;
381
389 BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); 382 BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity);
390 BulletSimAPI.Activate2(BSBody.ptr, true); 383 BulletSimAPI.Activate2(BSBody.ptr, true);
391 } 384 }
@@ -590,7 +583,8 @@ public class BSCharacter : BSPhysObject
590 583
591 // The 1.15 came from ODE but it seems to cause the avatar to float off the ground 584 // The 1.15 came from ODE but it seems to cause the avatar to float off the ground
592 // Scale.Z = (_size.Z * 1.15f) - (Scale.X + Scale.Y); 585 // Scale.Z = (_size.Z * 1.15f) - (Scale.X + Scale.Y);
593 newScale.Z = (_size.Z) - (Scale.X + Scale.Y); 586 // From the total height, remove the capsule half spheres that are at each end
587 newScale.Z = (size.Z) - (Math.Min(newScale.X, newScale.Y) * 2f);
594 Scale = newScale; 588 Scale = newScale;
595 } 589 }
596 590
@@ -621,7 +615,7 @@ public class BSCharacter : BSPhysObject
621 _acceleration = entprop.Acceleration; 615 _acceleration = entprop.Acceleration;
622 _rotationalVelocity = entprop.RotationalVelocity; 616 _rotationalVelocity = entprop.RotationalVelocity;
623 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 617 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
624 PositionSanityCheck2(true); 618 PositionSanityCheck(true);
625 619
626 // remember the current and last set values 620 // remember the current and last set values
627 LastEntityProperties = CurrentEntityProperties; 621 LastEntityProperties = CurrentEntityProperties;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 3421e30..b9e1908 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -333,7 +333,7 @@ public sealed class BSPrim : BSPhysObject
333 // just assign to "Position" because of potential call loops. 333 // just assign to "Position" because of potential call loops.
334 BSScene.TaintCallback sanityOperation = delegate() 334 BSScene.TaintCallback sanityOperation = delegate()
335 { 335 {
336 DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 336 DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
337 ForcePosition = _position; 337 ForcePosition = _position;
338 }; 338 };
339 if (inTaintTime) 339 if (inTaintTime)
@@ -822,7 +822,7 @@ public sealed class BSPrim : BSPhysObject
822 set { 822 set {
823 _buoyancy = value; 823 _buoyancy = value;
824 PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() 824 PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate()
825 { 825 {
826 ForceBuoyancy = _buoyancy; 826 ForceBuoyancy = _buoyancy;
827 }); 827 });
828 } 828 }
@@ -1286,8 +1286,8 @@ public sealed class BSPrim : BSPhysObject
1286 const float VELOCITY_TOLERANCE = 0.001f; 1286 const float VELOCITY_TOLERANCE = 0.001f;
1287 const float POSITION_TOLERANCE = 0.05f; 1287 const float POSITION_TOLERANCE = 0.05f;
1288 const float ACCELERATION_TOLERANCE = 0.01f; 1288 const float ACCELERATION_TOLERANCE = 0.01f;
1289 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; 1289 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1290 1290
1291 public override void UpdateProperties(EntityProperties entprop) 1291 public override void UpdateProperties(EntityProperties entprop)
1292 { 1292 {
1293 /* 1293 /*
@@ -1343,10 +1343,10 @@ public sealed class BSPrim : BSPhysObject
1343 _orientation = entprop.Rotation; 1343 _orientation = entprop.Rotation;
1344 _velocity = entprop.Velocity; 1344 _velocity = entprop.Velocity;
1345 _acceleration = entprop.Acceleration; 1345 _acceleration = entprop.Acceleration;
1346 _rotationalVelocity = entprop.RotationalVelocity; 1346 _rotationalVelocity = entprop.RotationalVelocity;
1347 1347
1348 // remember the current and last set values 1348 // remember the current and last set values
1349 LastEntityProperties = CurrentEntityProperties; 1349 LastEntityProperties = CurrentEntityProperties;
1350 CurrentEntityProperties = entprop; 1350 CurrentEntityProperties = entprop;
1351 1351
1352 PositionSanityCheck(true); 1352 PositionSanityCheck(true);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7998b08..c6e8bc4 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -795,7 +795,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
795 795
796 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); 796 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
797 delegate float ParamGet(BSScene scene); 797 delegate float ParamGet(BSScene scene);
798 delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); 798 delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
799 delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val);
799 800
800 private struct ParameterDefn 801 private struct ParameterDefn
801 { 802 {
@@ -804,7 +805,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
804 public float defaultValue; // default value if not specified anywhere else 805 public float defaultValue; // default value if not specified anywhere else
805 public ParamUser userParam; // get the value from the configuration file 806 public ParamUser userParam; // get the value from the configuration file
806 public ParamGet getter; // return the current value stored for this parameter 807 public ParamGet getter; // return the current value stored for this parameter
807 public ParamSet setter; // set the current value for this parameter 808 public ParamSet setter; // set the current value for this parameter
809 public SetOnObject onObject; // set the value on an object in the physical domain
808 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) 810 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
809 { 811 {
810 name = n; 812 name = n;
@@ -812,7 +814,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
812 defaultValue = v; 814 defaultValue = v;
813 userParam = u; 815 userParam = u;
814 getter = g; 816 getter = g;
815 setter = s; 817 setter = s;
818 onObject = null;
819 }
820 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o)
821 {
822 name = n;
823 desc = d;
824 defaultValue = v;
825 userParam = u;
826 getter = g;
827 setter = s;
828 onObject = o;
816 } 829 }
817 } 830 }
818 831
@@ -834,6 +847,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
834 // 847 //
835 // The single letter parameters for the delegates are: 848 // The single letter parameters for the delegates are:
836 // s = BSScene 849 // s = BSScene
850 // o = BSPhysObject
837 // p = string parameter name 851 // p = string parameter name
838 // l = localID of referenced object 852 // l = localID of referenced object
839 // v = float value 853 // v = float value
@@ -943,65 +957,74 @@ public class BSScene : PhysicsScene, IPhysicsParameters
943 -9.80665f, 957 -9.80665f,
944 (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); }, 958 (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); },
945 (s) => { return s.m_params[0].gravity; }, 959 (s) => { return s.m_params[0].gravity; },
946 (s,p,l,v) => { s.m_params[0].gravity = v; s.TaintedUpdateParameter(p,l,v); } ), 960 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].gravity, p, PhysParameterEntry.APPLY_TO_NONE, v); },
961 (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ),
947 962
948 963
949 new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", 964 new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
950 0f, 965 0f,
951 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, 966 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
952 (s) => { return s.m_params[0].linearDamping; }, 967 (s) => { return s.m_params[0].linearDamping; },
953 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ), 968 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); },
969 (s,o,v) => { BulletSimAPI.SetDamping2(o.BSBody.ptr, v, v); } ),
954 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 970 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
955 0f, 971 0f,
956 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, 972 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
957 (s) => { return s.m_params[0].angularDamping; }, 973 (s) => { return s.m_params[0].angularDamping; },
958 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ), 974 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); },
975 (s,o,v) => { BulletSimAPI.SetDamping2(o.BSBody.ptr, v, v); } ),
959 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 976 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
960 0.2f, 977 0.2f,
961 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, 978 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
962 (s) => { return s.m_params[0].deactivationTime; }, 979 (s) => { return s.m_params[0].deactivationTime; },
963 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ), 980 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); },
981 (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.BSBody.ptr, v); } ),
964 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 982 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
965 0.8f, 983 0.8f,
966 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, 984 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
967 (s) => { return s.m_params[0].linearSleepingThreshold; }, 985 (s) => { return s.m_params[0].linearSleepingThreshold; },
968 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), 986 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); },
987 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.BSBody.ptr, v, v); } ),
969 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 988 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
970 1.0f, 989 1.0f,
971 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, 990 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
972 (s) => { return s.m_params[0].angularSleepingThreshold; }, 991 (s) => { return s.m_params[0].angularSleepingThreshold; },
973 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), 992 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); },
993 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.BSBody.ptr, v, v); } ),
974 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 994 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
975 0f, // set to zero to disable 995 0f, // set to zero to disable
976 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, 996 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
977 (s) => { return s.m_params[0].ccdMotionThreshold; }, 997 (s) => { return s.m_params[0].ccdMotionThreshold; },
978 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), 998 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); },
999 (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.BSBody.ptr, v); } ),
979 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 1000 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
980 0f, 1001 0f,
981 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, 1002 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
982 (s) => { return s.m_params[0].ccdSweptSphereRadius; }, 1003 (s) => { return s.m_params[0].ccdSweptSphereRadius; },
983 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), 1004 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); },
1005 (s,o,v) => { BulletSimAPI.SetCcdSweepSphereRadius2(o.BSBody.ptr, v); } ),
984 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 1006 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
985 0.1f, 1007 0.1f,
986 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, 1008 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
987 (s) => { return s.m_params[0].contactProcessingThreshold; }, 1009 (s) => { return s.m_params[0].contactProcessingThreshold; },
988 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), 1010 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); },
1011 (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.BSBody.ptr, v); } ),
989 1012
990 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 1013 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
991 0.5f, 1014 0.5f,
992 (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, 1015 (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); },
993 (s) => { return s.m_params[0].terrainFriction; }, 1016 (s) => { return s.m_params[0].terrainFriction; },
994 (s,p,l,v) => { s.m_params[0].terrainFriction = v; s.TaintedUpdateParameter(p,l,v); } ), 1017 (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ),
995 new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , 1018 new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
996 0.8f, 1019 0.8f,
997 (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); }, 1020 (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); },
998 (s) => { return s.m_params[0].terrainHitFraction; }, 1021 (s) => { return s.m_params[0].terrainHitFraction; },
999 (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; s.TaintedUpdateParameter(p,l,v); } ), 1022 (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; /* TODO: set on real terrain */ } ),
1000 new ParameterDefn("TerrainRestitution", "Bouncyness" , 1023 new ParameterDefn("TerrainRestitution", "Bouncyness" ,
1001 0f, 1024 0f,
1002 (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, 1025 (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); },
1003 (s) => { return s.m_params[0].terrainRestitution; }, 1026 (s) => { return s.m_params[0].terrainRestitution; },
1004 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ), 1027 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ),
1005 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 1028 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
1006 0.2f, 1029 0.2f,
1007 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, 1030 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
@@ -1228,58 +1251,55 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1228 return ret; 1251 return ret;
1229 } 1252 }
1230 1253
1231 // check to see if we are updating a parameter for a particular or all of the prims
1232 protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val)
1233 {
1234 List<uint> operateOn;
1235 lock (PhysObjects) operateOn = new List<uint>(PhysObjects.Keys);
1236 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1237 }
1238
1239 // update all the localIDs specified 1254 // update all the localIDs specified
1240 // If the local ID is APPLY_TO_NONE, just change the default value 1255 // If the local ID is APPLY_TO_NONE, just change the default value
1241 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs 1256 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
1242 // If the localID is a specific object, apply the parameter change to only that object 1257 // If the localID is a specific object, apply the parameter change to only that object
1243 protected void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val) 1258 protected void UpdateParameterObject(ref float defaultLoc, string parm, uint localID, float val)
1244 { 1259 {
1260 List<uint> objectIDs = new List<uint>();
1245 switch (localID) 1261 switch (localID)
1246 { 1262 {
1247 case PhysParameterEntry.APPLY_TO_NONE: 1263 case PhysParameterEntry.APPLY_TO_NONE:
1248 defaultLoc = val; // setting only the default value 1264 defaultLoc = val; // setting only the default value
1265 // This will cause a call into the physical world if some operation is specified (SetOnObject).
1266 objectIDs.Add(TERRAIN_ID);
1267 TaintedUpdateParameter(parm, objectIDs, val);
1249 break; 1268 break;
1250 case PhysParameterEntry.APPLY_TO_ALL: 1269 case PhysParameterEntry.APPLY_TO_ALL:
1251 defaultLoc = val; // setting ALL also sets the default value 1270 defaultLoc = val; // setting ALL also sets the default value
1252 /* 1271 lock (PhysObjects) objectIDs = new List<uint>(PhysObjects.Keys);
1253 List<uint> objectIDs = lIDs; 1272 TaintedUpdateParameter(parm, objectIDs, val);
1254 string xparm = parm.ToLower();
1255 float xval = val;
1256 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1257 foreach (uint lID in objectIDs)
1258 {
1259 BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval);
1260 }
1261 });
1262 */
1263 break; 1273 break;
1264 default: 1274 default:
1265 // setting only one localID 1275 // setting only one localID
1266 TaintedUpdateParameter(parm, localID, val); 1276 objectIDs.Add(localID);
1277 TaintedUpdateParameter(parm, objectIDs, val);
1267 break; 1278 break;
1268 } 1279 }
1269 } 1280 }
1270 1281
1271 // schedule the actual updating of the paramter to when the phys engine is not busy 1282 // schedule the actual updating of the paramter to when the phys engine is not busy
1272 protected void TaintedUpdateParameter(string parm, uint localID, float val) 1283 protected void TaintedUpdateParameter(string parm, List<uint> lIDs, float val)
1273 { 1284 {
1274 /* Settings in the C++ code are not working at the moment. TODO: fix the settings. 1285 float xval = val;
1275 m_log.ErrorFormat("{0} Cannot change parameters of base objects. Someday it will be added.", LogHeader); 1286 List<uint> xlIDs = lIDs;
1276 uint xlocalID = localID; 1287 string xparm = parm;
1277 string xparm = parm.ToLower(); 1288 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1278 float xval = val; 1289 ParameterDefn thisParam;
1279 TaintedObject("BSScene.TaintedUpdateParameter", delegate() { 1290 if (TryGetParameter(xparm, out thisParam))
1280 BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval); 1291 {
1292 if (thisParam.onObject != null)
1293 {
1294 foreach (uint lID in xlIDs)
1295 {
1296 BSPhysObject theObject = null;
1297 PhysObjects.TryGetValue(lID, out theObject);
1298 thisParam.onObject(this, theObject, xval);
1299 }
1300 }
1301 }
1281 }); 1302 });
1282 */
1283 } 1303 }
1284 1304
1285 // Get parameter. 1305 // Get parameter.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 5a77e52..bbfdac6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -51,7 +51,7 @@ public class BSShapeCollection : IDisposable
51 } 51 }
52 52
53 // Description of a hull. 53 // Description of a hull.
54 // Meshes and hulls have the same shape hash key but we only need hulls for efficient physical objects 54 // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations.
55 private struct HullDesc 55 private struct HullDesc
56 { 56 {
57 public IntPtr ptr; 57 public IntPtr ptr;
@@ -59,17 +59,9 @@ public class BSShapeCollection : IDisposable
59 public DateTime lastReferenced; 59 public DateTime lastReferenced;
60 } 60 }
61 61
62 private struct BodyDesc 62 // The sharable set of meshes and hulls. Indexed by their shape hash.
63 {
64 public IntPtr ptr;
65 // Bodies are only used once so reference count is always either one or zero
66 public int referenceCount;
67 public DateTime lastReferenced;
68 }
69
70 private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>(); 63 private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>();
71 private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>(); 64 private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>();
72 private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>();
73 65
74 public BSShapeCollection(BSScene physScene) 66 public BSShapeCollection(BSScene physScene)
75 { 67 {
@@ -92,6 +84,10 @@ public class BSShapeCollection : IDisposable
92 // First checks the shape and updates that if necessary then makes 84 // First checks the shape and updates that if necessary then makes
93 // sure the body is of the right type. 85 // sure the body is of the right type.
94 // Return 'true' if either the body or the shape changed. 86 // Return 'true' if either the body or the shape changed.
87 // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before
88 // the current shape or body is destroyed. This allows the caller to remove any
89 // higher level dependencies on the shape or body. Mostly used for LinkSets to
90 // remove the physical constraints before the body is destroyed.
95 // Called at taint-time!! 91 // Called at taint-time!!
96 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, 92 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim,
97 ShapeData shapeData, PrimitiveBaseShape pbs, 93 ShapeData shapeData, PrimitiveBaseShape pbs,
@@ -103,7 +99,8 @@ public class BSShapeCollection : IDisposable
103 lock (m_collectionActivityLock) 99 lock (m_collectionActivityLock)
104 { 100 {
105 // Do we have the correct geometry for this type of object? 101 // Do we have the correct geometry for this type of object?
106 // Updates prim.BSShape with information/pointers to requested shape 102 // Updates prim.BSShape with information/pointers to shape.
103 // CreateGeom returns 'true' of BSShape as changed to a new shape.
107 bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback); 104 bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback);
108 // If we had to select a new shape geometry for the object, 105 // If we had to select a new shape geometry for the object,
109 // rebuild the body around it. 106 // rebuild the body around it.
@@ -125,35 +122,19 @@ public class BSShapeCollection : IDisposable
125 { 122 {
126 lock (m_collectionActivityLock) 123 lock (m_collectionActivityLock)
127 { 124 {
128 BodyDesc bodyDesc; 125 DetailLog("{0},BSShapeCollection.ReferenceBody,newBody", body.ID, body);
129 if (Bodies.TryGetValue(body.ID, out bodyDesc)) 126 BSScene.TaintCallback createOperation = delegate()
130 { 127 {
131 bodyDesc.referenceCount++; 128 if (!BulletSimAPI.IsInWorld2(body.ptr))
132 DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,body={1},ref={2}", body.ID, body, bodyDesc.referenceCount);
133 }
134 else
135 {
136 // New entry
137 bodyDesc.ptr = body.ptr;
138 bodyDesc.referenceCount = 1;
139 DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={2}",
140 body.ID, body, bodyDesc.referenceCount);
141 BSScene.TaintCallback createOperation = delegate()
142 { 129 {
143 if (!BulletSimAPI.IsInWorld2(body.ptr)) 130 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
144 { 131 DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
145 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); 132 }
146 DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", 133 };
147 body.ID, body); 134 if (inTaintTime)
148 } 135 createOperation();
149 }; 136 else
150 if (inTaintTime) 137 PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
151 createOperation();
152 else
153 PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
154 }
155 bodyDesc.lastReferenced = System.DateTime.Now;
156 Bodies[body.ID] = bodyDesc;
157 } 138 }
158 } 139 }
159 140
@@ -166,43 +147,25 @@ public class BSShapeCollection : IDisposable
166 147
167 lock (m_collectionActivityLock) 148 lock (m_collectionActivityLock)
168 { 149 {
169 BodyDesc bodyDesc; 150 BSScene.TaintCallback removeOperation = delegate()
170 if (Bodies.TryGetValue(body.ID, out bodyDesc))
171 { 151 {
172 bodyDesc.referenceCount--; 152 DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}",
173 bodyDesc.lastReferenced = System.DateTime.Now; 153 body.ID, body.ptr.ToString("X"), inTaintTime);
174 Bodies[body.ID] = bodyDesc; 154 // If the caller needs to know the old body is going away, pass the event up.
175 DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount); 155 if (bodyCallback != null) bodyCallback(body);
176 156
177 // If body is no longer being used, free it -- bodies can never be shared. 157 // It may have already been removed from the world in which case the next is a NOOP.
178 if (bodyDesc.referenceCount == 0) 158 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
179 { 159
180 Bodies.Remove(body.ID); 160 // Zero any reference to the shape so it is not freed when the body is deleted.
181 BSScene.TaintCallback removeOperation = delegate() 161 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
182 { 162 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
183 DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", 163 };
184 body.ID, body.ptr.ToString("X"), inTaintTime); 164 // If already in taint-time, do the operations now. Otherwise queue for later.
185 // If the caller needs to know the old body is going away, pass the event up. 165 if (inTaintTime)
186 if (bodyCallback != null) bodyCallback(body); 166 removeOperation();
187
188 // It may have already been removed from the world in which case the next is a NOOP.
189 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
190
191 // Zero any reference to the shape so it is not freed when the body is deleted.
192 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
193 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
194 };
195 // If already in taint-time, do the operations now. Otherwise queue for later.
196 if (inTaintTime)
197 removeOperation();
198 else
199 PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation);
200 }
201 }
202 else 167 else
203 { 168 PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation);
204 DetailLog("{0},BSShapeCollection.DereferenceBody,DID NOT FIND BODY", body.ID, bodyDesc.referenceCount);
205 }
206 } 169 }
207 } 170 }
208 171
@@ -271,7 +234,6 @@ public class BSShapeCollection : IDisposable
271 } 234 }
272 235
273 // Release the usage of a shape. 236 // Release the usage of a shape.
274 // The collisionObject is released since it is a copy of the real collision shape.
275 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) 237 public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
276 { 238 {
277 if (shape.ptr == IntPtr.Zero) 239 if (shape.ptr == IntPtr.Zero)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index caf411e..9743d94 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -334,7 +334,8 @@ public class BSTerrainManager
334 334
335 // Make sure the new shape is processed. 335 // Make sure the new shape is processed.
336 // BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true); 336 // BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true);
337 BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); 337 BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.ISLAND_SLEEPING);
338 // BulletSimAPI.ForceActivationState2(mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
338 339
339 m_terrainModified = true; 340 m_terrainModified = true;
340 }; 341 };