diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 56 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 16 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 114 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 110 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 3 |
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 | }; |