aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
authorMelanie2013-07-24 04:45:07 +0100
committerMelanie2013-07-24 04:45:07 +0100
commite82d4154a2e348e4a38f01cb1877878c94569bba (patch)
tree7b27e6d30d04f6089fd17d5779cfb0a81e50d508 /OpenSim/Region/Physics/BulletSPlugin
parentMerge branch 'master' into careminster (diff)
parentFor unknown user issue, bump GUN7 to GUN8 and UMMAU3 to UMMAU4 to assess what... (diff)
downloadopensim-SC_OLD-e82d4154a2e348e4a38f01cb1877878c94569bba.zip
opensim-SC_OLD-e82d4154a2e348e4a38f01cb1877878c94569bba.tar.gz
opensim-SC_OLD-e82d4154a2e348e4a38f01cb1877878c94569bba.tar.bz2
opensim-SC_OLD-e82d4154a2e348e4a38f01cb1877878c94569bba.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs OpenSim/Region/Framework/Scenes/ScenePresence.cs OpenSim/Region/Physics/Manager/PhysicsActor.cs OpenSim/Region/Physics/Manager/PhysicsScene.cs
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActors.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs37
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs95
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs37
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs82
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs11
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs52
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs32
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs2
10 files changed, 297 insertions, 65 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
index fff63e4..e0ccc50 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
@@ -69,7 +69,7 @@ public class BSActorCollection
69 { 69 {
70 lock (m_actors) 70 lock (m_actors)
71 { 71 {
72 Release(); 72 ForEachActor(a => a.Dispose());
73 m_actors.Clear(); 73 m_actors.Clear();
74 } 74 }
75 } 75 }
@@ -98,10 +98,6 @@ public class BSActorCollection
98 { 98 {
99 ForEachActor(a => a.SetEnabled(enabl)); 99 ForEachActor(a => a.SetEnabled(enabl));
100 } 100 }
101 public void Release()
102 {
103 ForEachActor(a => a.Dispose());
104 }
105 public void Refresh() 101 public void Refresh()
106 { 102 {
107 ForEachActor(a => a.Refresh()); 103 ForEachActor(a => a.Refresh());
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 0204967..82d7c44 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
45 private static string LogHeader = "[BULLETSIM VEHICLE]"; 45 private static string LogHeader = "[BULLETSIM VEHICLE]";
46 46
47 // the prim this dynamic controller belongs to 47 // the prim this dynamic controller belongs to
48 private BSPrim ControllingPrim { get; set; } 48 private BSPrimLinkable ControllingPrim { get; set; }
49 49
50 private bool m_haveRegisteredForSceneEvents; 50 private bool m_haveRegisteredForSceneEvents;
51 51
@@ -128,9 +128,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
128 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) 128 public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
129 : base(myScene, myPrim, actorName) 129 : base(myScene, myPrim, actorName)
130 { 130 {
131 ControllingPrim = myPrim;
132 Type = Vehicle.TYPE_NONE; 131 Type = Vehicle.TYPE_NONE;
133 m_haveRegisteredForSceneEvents = false; 132 m_haveRegisteredForSceneEvents = false;
133
134 ControllingPrim = myPrim as BSPrimLinkable;
135 if (ControllingPrim == null)
136 {
137 // THIS CANNOT HAPPEN!!
138 }
139 VDetailLog("{0},Creation", ControllingPrim.LocalID);
134 } 140 }
135 141
136 // Return 'true' if this vehicle is doing vehicle things 142 // Return 'true' if this vehicle is doing vehicle things
@@ -585,6 +591,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
585 // Friction affects are handled by this vehicle code 591 // Friction affects are handled by this vehicle code
586 m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction); 592 m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction);
587 m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution); 593 m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution);
594 // ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction);
595 // ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution);
588 596
589 // Moderate angular movement introduced by Bullet. 597 // Moderate angular movement introduced by Bullet.
590 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. 598 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
@@ -595,17 +603,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
595 603
596 // Vehicles report collision events so we know when it's on the ground 604 // Vehicles report collision events so we know when it's on the ground
597 m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 605 m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
606 // ControllingPrim.Linkset.SetPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS);
598 607
599 Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); 608 Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
600 ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor; 609 ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor;
601 m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); 610 m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
602 m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); 611 m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
612 // ControllingPrim.Linkset.ComputeLocalInertia(BSParam.VehicleInertiaFactor);
603 613
604 // Set the gravity for the vehicle depending on the buoyancy 614 // Set the gravity for the vehicle depending on the buoyancy
605 // TODO: what should be done if prim and vehicle buoyancy differ? 615 // TODO: what should be done if prim and vehicle buoyancy differ?
606 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy); 616 m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
607 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. 617 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
608 m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero); 618 m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero);
619 // ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero);
609 620
610 VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", 621 VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
611 ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity, 622 ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
@@ -617,6 +628,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
617 { 628 {
618 if (ControllingPrim.PhysBody.HasPhysicalBody) 629 if (ControllingPrim.PhysBody.HasPhysicalBody)
619 m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 630 m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
631 // ControllingPrim.Linkset.RemoveFromPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS);
620 } 632 }
621 } 633 }
622 634
@@ -629,6 +641,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
629 // BSActor.Release() 641 // BSActor.Release()
630 public override void Dispose() 642 public override void Dispose()
631 { 643 {
644 VDetailLog("{0},Dispose", ControllingPrim.LocalID);
632 UnregisterForSceneEvents(); 645 UnregisterForSceneEvents();
633 Type = Vehicle.TYPE_NONE; 646 Type = Vehicle.TYPE_NONE;
634 Enabled = false; 647 Enabled = false;
@@ -1001,7 +1014,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1001 else if (newVelocityLengthSq < 0.001f) 1014 else if (newVelocityLengthSq < 0.001f)
1002 VehicleVelocity = Vector3.Zero; 1015 VehicleVelocity = Vector3.Zero;
1003 1016
1004 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.IsColliding, VehicleVelocity ); 1017 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, VehicleVelocity );
1005 1018
1006 } // end MoveLinear() 1019 } // end MoveLinear()
1007 1020
@@ -1029,8 +1042,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1029 // Add this correction to the velocity to make it faster/slower. 1042 // Add this correction to the velocity to make it faster/slower.
1030 VehicleVelocity += linearMotorVelocityW; 1043 VehicleVelocity += linearMotorVelocityW;
1031 1044
1032 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}", 1045 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},tgt={3},correctV={4},correctW={5},newVelW={6},fricFact={7}",
1033 ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, 1046 ControllingPrim.LocalID, origVelW, currentVelV, m_linearMotor.TargetValue, linearMotorCorrectionV,
1034 linearMotorVelocityW, VehicleVelocity, frictionFactorV); 1047 linearMotorVelocityW, VehicleVelocity, frictionFactorV);
1035 } 1048 }
1036 1049
@@ -1062,7 +1075,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1062 Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation; 1075 Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation;
1063 1076
1064 // Optionally, if not colliding, don't effect world downward velocity. Let falling things fall. 1077 // Optionally, if not colliding, don't effect world downward velocity. Let falling things fall.
1065 if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.IsColliding) 1078 if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.HasSomeCollision)
1066 { 1079 {
1067 linearDeflectionW.Z = 0f; 1080 linearDeflectionW.Z = 0f;
1068 } 1081 }
@@ -1222,7 +1235,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1222 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); 1235 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
1223 distanceAboveGround = VehiclePosition.Z - targetHeight; 1236 distanceAboveGround = VehiclePosition.Z - targetHeight;
1224 // Not colliding if the vehicle is off the ground 1237 // Not colliding if the vehicle is off the ground
1225 if (!Prim.IsColliding) 1238 if (!Prim.HasSomeCollision)
1226 { 1239 {
1227 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); 1240 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
1228 VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); 1241 VehicleVelocity += new Vector3(0, 0, -distanceAboveGround);
@@ -1233,12 +1246,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1233 // be computed with a motor. 1246 // be computed with a motor.
1234 // TODO: add interaction with banking. 1247 // TODO: add interaction with banking.
1235 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", 1248 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
1236 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); 1249 Prim.LocalID, distanceAboveGround, Prim.HasSomeCollision, ret);
1237 */ 1250 */
1238 1251
1239 // Another approach is to measure if we're going up. If going up and not colliding, 1252 // Another approach is to measure if we're going up. If going up and not colliding,
1240 // the vehicle is in the air. Fix that by pushing down. 1253 // the vehicle is in the air. Fix that by pushing down.
1241 if (!ControllingPrim.IsColliding && VehicleVelocity.Z > 0.1) 1254 if (!ControllingPrim.HasSomeCollision && VehicleVelocity.Z > 0.1)
1242 { 1255 {
1243 // Get rid of any of the velocity vector that is pushing us up. 1256 // Get rid of any of the velocity vector that is pushing us up.
1244 float upVelocity = VehicleVelocity.Z; 1257 float upVelocity = VehicleVelocity.Z;
@@ -1260,7 +1273,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1260 } 1273 }
1261 */ 1274 */
1262 VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}", 1275 VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
1263 ControllingPrim.LocalID, ControllingPrim.IsColliding, upVelocity, VehicleVelocity); 1276 ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, upVelocity, VehicleVelocity);
1264 } 1277 }
1265 } 1278 }
1266 } 1279 }
@@ -1270,14 +1283,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1270 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; 1283 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1271 1284
1272 // Hack to reduce downward force if the vehicle is probably sitting on the ground 1285 // Hack to reduce downward force if the vehicle is probably sitting on the ground
1273 if (ControllingPrim.IsColliding && IsGroundVehicle) 1286 if (ControllingPrim.HasSomeCollision && IsGroundVehicle)
1274 appliedGravity *= BSParam.VehicleGroundGravityFudge; 1287 appliedGravity *= BSParam.VehicleGroundGravityFudge;
1275 1288
1276 VehicleAddForce(appliedGravity); 1289 VehicleAddForce(appliedGravity);
1277 1290
1278 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={5}", 1291 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={5}",
1279 ControllingPrim.LocalID, m_VehicleGravity, 1292 ControllingPrim.LocalID, m_VehicleGravity,
1280 ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity); 1293 ControllingPrim.HasSomeCollision, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
1281 } 1294 }
1282 1295
1283 // ======================================================================= 1296 // =======================================================================
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index ad8e10f..960c0b4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -203,6 +203,33 @@ public abstract class BSLinkset
203 return ret; 203 return ret;
204 } 204 }
205 205
206 // Called after a simulation step to post a collision with this object.
207 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
208 // anything to add for the collision and it should be passed through normal processing.
209 // Default processing for a linkset.
210 public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee,
211 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
212 {
213 bool ret = false;
214
215 // prims in the same linkset cannot collide with each other
216 BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
217 if (convCollidee != null && (LinksetID == convCollidee.Linkset.LinksetID))
218 {
219 // By returning 'true', we tell the caller the collision has been 'handled' so it won't
220 // do anything about this collision and thus, effectivily, ignoring the collision.
221 ret = true;
222 }
223 else
224 {
225 // Not a collision between members of the linkset. Must be a real collision.
226 // So the linkset root can know if there is a collision anywhere in the linkset.
227 LinksetRoot.SomeCollisionSimulationStep = m_physicsScene.SimulationStep;
228 }
229
230 return ret;
231 }
232
206 // I am the root of a linkset and a new child is being added 233 // I am the root of a linkset and a new child is being added
207 // Called while LinkActivity is locked. 234 // Called while LinkActivity is locked.
208 protected abstract void AddChildToLinkset(BSPrimLinkable child); 235 protected abstract void AddChildToLinkset(BSPrimLinkable child);
@@ -251,6 +278,73 @@ public abstract class BSLinkset
251 public abstract bool RemoveDependencies(BSPrimLinkable child); 278 public abstract bool RemoveDependencies(BSPrimLinkable child);
252 279
253 // ================================================================ 280 // ================================================================
281 // Some physical setting happen to all members of the linkset
282 public virtual void SetPhysicalFriction(float friction)
283 {
284 ForEachMember((member) =>
285 {
286 if (member.PhysBody.HasPhysicalBody)
287 m_physicsScene.PE.SetFriction(member.PhysBody, friction);
288 return false; // 'false' says to continue looping
289 }
290 );
291 }
292 public virtual void SetPhysicalRestitution(float restitution)
293 {
294 ForEachMember((member) =>
295 {
296 if (member.PhysBody.HasPhysicalBody)
297 m_physicsScene.PE.SetRestitution(member.PhysBody, restitution);
298 return false; // 'false' says to continue looping
299 }
300 );
301 }
302 public virtual void SetPhysicalGravity(OMV.Vector3 gravity)
303 {
304 ForEachMember((member) =>
305 {
306 if (member.PhysBody.HasPhysicalBody)
307 m_physicsScene.PE.SetGravity(member.PhysBody, gravity);
308 return false; // 'false' says to continue looping
309 }
310 );
311 }
312 public virtual void ComputeLocalInertia(OMV.Vector3 inertiaFactor)
313 {
314 ForEachMember((member) =>
315 {
316 if (member.PhysBody.HasPhysicalBody)
317 {
318 OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, member.Mass);
319 member.Inertia = inertia * inertiaFactor;
320 m_physicsScene.PE.SetMassProps(member.PhysBody, member.Mass, member.Inertia);
321 m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody);
322 }
323 return false; // 'false' says to continue looping
324 }
325 );
326 }
327 public virtual void SetPhysicalCollisionFlags(CollisionFlags collFlags)
328 {
329 ForEachMember((member) =>
330 {
331 if (member.PhysBody.HasPhysicalBody)
332 m_physicsScene.PE.SetCollisionFlags(member.PhysBody, collFlags);
333 return false; // 'false' says to continue looping
334 }
335 );
336 }
337 public virtual void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
338 {
339 ForEachMember((member) =>
340 {
341 if (member.PhysBody.HasPhysicalBody)
342 m_physicsScene.PE.RemoveFromCollisionFlags(member.PhysBody, collFlags);
343 return false; // 'false' says to continue looping
344 }
345 );
346 }
347 // ================================================================
254 protected virtual float ComputeLinksetMass() 348 protected virtual float ComputeLinksetMass()
255 { 349 {
256 float mass = LinksetRoot.RawMass; 350 float mass = LinksetRoot.RawMass;
@@ -311,6 +405,5 @@ public abstract class BSLinkset
311 if (m_physicsScene.PhysicsLogging.Enabled) 405 if (m_physicsScene.PhysicsLogging.Enabled)
312 m_physicsScene.DetailLog(msg, args); 406 m_physicsScene.DetailLog(msg, args);
313 } 407 }
314
315} 408}
316} 409}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 1d94142..33ae5a5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -44,6 +44,42 @@ public sealed class BSLinksetCompound : BSLinkset
44 { 44 {
45 } 45 }
46 46
47 // ================================================================
48 // Changing the physical property of the linkset only needs to change the root
49 public override void SetPhysicalFriction(float friction)
50 {
51 if (LinksetRoot.PhysBody.HasPhysicalBody)
52 m_physicsScene.PE.SetFriction(LinksetRoot.PhysBody, friction);
53 }
54 public override void SetPhysicalRestitution(float restitution)
55 {
56 if (LinksetRoot.PhysBody.HasPhysicalBody)
57 m_physicsScene.PE.SetRestitution(LinksetRoot.PhysBody, restitution);
58 }
59 public override void SetPhysicalGravity(OMV.Vector3 gravity)
60 {
61 if (LinksetRoot.PhysBody.HasPhysicalBody)
62 m_physicsScene.PE.SetGravity(LinksetRoot.PhysBody, gravity);
63 }
64 public override void ComputeLocalInertia(OMV.Vector3 inertiaFactor)
65 {
66 OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(LinksetRoot.PhysShape.physShapeInfo, LinksetRoot.Mass);
67 LinksetRoot.Inertia = inertia * inertiaFactor;
68 m_physicsScene.PE.SetMassProps(LinksetRoot.PhysBody, LinksetRoot.Mass, LinksetRoot.Inertia);
69 m_physicsScene.PE.UpdateInertiaTensor(LinksetRoot.PhysBody);
70 }
71 public override void SetPhysicalCollisionFlags(CollisionFlags collFlags)
72 {
73 if (LinksetRoot.PhysBody.HasPhysicalBody)
74 m_physicsScene.PE.SetCollisionFlags(LinksetRoot.PhysBody, collFlags);
75 }
76 public override void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
77 {
78 if (LinksetRoot.PhysBody.HasPhysicalBody)
79 m_physicsScene.PE.RemoveFromCollisionFlags(LinksetRoot.PhysBody, collFlags);
80 }
81 // ================================================================
82
47 // When physical properties are changed the linkset needs to recalculate 83 // When physical properties are changed the linkset needs to recalculate
48 // its internal properties. 84 // its internal properties.
49 public override void Refresh(BSPrimLinkable requestor) 85 public override void Refresh(BSPrimLinkable requestor)
@@ -59,6 +95,7 @@ public sealed class BSLinksetCompound : BSLinkset
59 { 95 {
60 DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}", 96 DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
61 requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren)); 97 requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
98
62 // When rebuilding, it is possible to set properties that would normally require a rebuild. 99 // When rebuilding, it is possible to set properties that would normally require a rebuild.
63 // If already rebuilding, don't request another rebuild. 100 // If already rebuilding, don't request another rebuild.
64 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding. 101 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index a06a44d..f17d698 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -48,12 +48,22 @@ public sealed class BSLinksetConstraints : BSLinkset
48 { 48 {
49 base.Refresh(requestor); 49 base.Refresh(requestor);
50 50
51 if (HasAnyChildren && IsRoot(requestor)) 51 }
52
53 private void ScheduleRebuild(BSPrimLinkable requestor)
54 {
55 DetailLog("{0},BSLinksetConstraint.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
56 requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
57
58 // When rebuilding, it is possible to set properties that would normally require a rebuild.
59 // If already rebuilding, don't request another rebuild.
60 // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
61 if (!Rebuilding && HasAnyChildren)
52 { 62 {
53 // Queue to happen after all the other taint processing 63 // Queue to happen after all the other taint processing
54 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() 64 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
55 { 65 {
56 if (HasAnyChildren && IsRoot(requestor)) 66 if (HasAnyChildren)
57 RecomputeLinksetConstraints(); 67 RecomputeLinksetConstraints();
58 }); 68 });
59 } 69 }
@@ -67,8 +77,14 @@ public sealed class BSLinksetConstraints : BSLinkset
67 // Called at taint-time! 77 // Called at taint-time!
68 public override bool MakeDynamic(BSPrimLinkable child) 78 public override bool MakeDynamic(BSPrimLinkable child)
69 { 79 {
70 // What is done for each object in BSPrim is what we want. 80 bool ret = false;
71 return false; 81 DetailLog("{0},BSLinksetConstraints.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
82 if (IsRoot(child))
83 {
84 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
85 ScheduleRebuild(LinksetRoot);
86 }
87 return ret;
72 } 88 }
73 89
74 // The object is going static (non-physical). Do any setup necessary for a static linkset. 90 // The object is going static (non-physical). Do any setup necessary for a static linkset.
@@ -78,8 +94,16 @@ public sealed class BSLinksetConstraints : BSLinkset
78 // Called at taint-time! 94 // Called at taint-time!
79 public override bool MakeStatic(BSPrimLinkable child) 95 public override bool MakeStatic(BSPrimLinkable child)
80 { 96 {
81 // What is done for each object in BSPrim is what we want. 97 bool ret = false;
82 return false; 98
99 DetailLog("{0},BSLinksetConstraint.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
100 child.ClearDisplacement();
101 if (IsRoot(child))
102 {
103 // Schedule a rebuild to verify that the root shape is set to the real shape.
104 ScheduleRebuild(LinksetRoot);
105 }
106 return ret;
83 } 107 }
84 108
85 // Called at taint-time!! 109 // Called at taint-time!!
@@ -105,7 +129,7 @@ public sealed class BSLinksetConstraints : BSLinkset
105 // Just undo all the constraints for this linkset. Rebuild at the end of the step. 129 // Just undo all the constraints for this linkset. Rebuild at the end of the step.
106 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); 130 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
107 // Cause the constraints, et al to be rebuilt before the next simulation step. 131 // Cause the constraints, et al to be rebuilt before the next simulation step.
108 Refresh(LinksetRoot); 132 ScheduleRebuild(LinksetRoot);
109 } 133 }
110 return ret; 134 return ret;
111 } 135 }
@@ -123,7 +147,7 @@ public sealed class BSLinksetConstraints : BSLinkset
123 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 147 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
124 148
125 // Cause constraints and assorted properties to be recomputed before the next simulation step. 149 // Cause constraints and assorted properties to be recomputed before the next simulation step.
126 Refresh(LinksetRoot); 150 ScheduleRebuild(LinksetRoot);
127 } 151 }
128 return; 152 return;
129 } 153 }
@@ -147,7 +171,7 @@ public sealed class BSLinksetConstraints : BSLinkset
147 PhysicallyUnlinkAChildFromRoot(rootx, childx); 171 PhysicallyUnlinkAChildFromRoot(rootx, childx);
148 }); 172 });
149 // See that the linkset parameters are recomputed at the end of the taint time. 173 // See that the linkset parameters are recomputed at the end of the taint time.
150 Refresh(LinksetRoot); 174 ScheduleRebuild(LinksetRoot);
151 } 175 }
152 else 176 else
153 { 177 {
@@ -165,6 +189,7 @@ public sealed class BSLinksetConstraints : BSLinkset
165 Refresh(rootPrim); 189 Refresh(rootPrim);
166 } 190 }
167 191
192 // Create a static constraint between the two passed objects
168 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) 193 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
169 { 194 {
170 // Zero motion for children so they don't interpolate 195 // Zero motion for children so they don't interpolate
@@ -281,24 +306,39 @@ public sealed class BSLinksetConstraints : BSLinkset
281 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", 306 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
282 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); 307 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
283 308
284 foreach (BSPrimLinkable child in m_children) 309 try
285 { 310 {
286 // A child in the linkset physically shows the mass of the whole linkset. 311 Rebuilding = true;
287 // This allows Bullet to apply enough force on the child to move the whole linkset.
288 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
289 child.UpdatePhysicalMassProperties(linksetMass, true);
290 312
291 BSConstraint constrain; 313 // There is no reason to build all this physical stuff for a non-physical linkset.
292 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) 314 if (!LinksetRoot.IsPhysicallyActive)
293 { 315 {
294 // If constraint doesn't exist yet, create it. 316 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID);
295 constrain = BuildConstraint(LinksetRoot, child); 317 return; // Note the 'finally' clause at the botton which will get executed.
296 } 318 }
297 constrain.RecomputeConstraintVariables(linksetMass);
298 319
299 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG 320 foreach (BSPrimLinkable child in m_children)
300 } 321 {
322 // A child in the linkset physically shows the mass of the whole linkset.
323 // This allows Bullet to apply enough force on the child to move the whole linkset.
324 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
325 child.UpdatePhysicalMassProperties(linksetMass, true);
326
327 BSConstraint constrain;
328 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
329 {
330 // If constraint doesn't exist yet, create it.
331 constrain = BuildConstraint(LinksetRoot, child);
332 }
333 constrain.RecomputeConstraintVariables(linksetMass);
301 334
335 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
336 }
337 }
338 finally
339 {
340 Rebuilding = false;
341 }
302 } 342 }
303} 343}
304} 344}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index dcf1e83..0bdb5f1 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -461,8 +461,9 @@ public static class BSParam
461 (s) => { return MaxAddForceMagnitude; }, 461 (s) => { return MaxAddForceMagnitude; },
462 (s,v) => { MaxAddForceMagnitude = v; MaxAddForceMagnitudeSquared = v * v; } ), 462 (s,v) => { MaxAddForceMagnitude = v; MaxAddForceMagnitudeSquared = v * v; } ),
463 // Density is passed around as 100kg/m3. This scales that to 1kg/m3. 463 // Density is passed around as 100kg/m3. This scales that to 1kg/m3.
464 // Reduce by power of 100 because Bullet doesn't seem to handle objects with large mass very well
464 new ParameterDefn<float>("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", 465 new ParameterDefn<float>("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)",
465 0.01f ), 466 0.0001f ),
466 467
467 new ParameterDefn<float>("PID_D", "Derivitive factor for motion smoothing", 468 new ParameterDefn<float>("PID_D", "Derivitive factor for motion smoothing",
468 2200f ), 469 2200f ),
@@ -607,8 +608,9 @@ public static class BSParam
607 0.0f ), 608 0.0f ),
608 new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", 609 new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
609 0.0f ), 610 0.0f ),
611 // Turn off fudge with DensityScaleFactor = 0.0001. Value used to be 0.2f;
610 new ParameterDefn<float>("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", 612 new ParameterDefn<float>("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)",
611 0.2f ), 613 1.0f ),
612 new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", 614 new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.",
613 60.0f ), 615 60.0f ),
614 new ParameterDefn<bool>("VehicleEnableLinearDeflection", "Turn on/off vehicle linear deflection effect", 616 new ParameterDefn<bool>("VehicleEnableLinearDeflection", "Turn on/off vehicle linear deflection effect",
@@ -701,7 +703,7 @@ public static class BSParam
701 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", 703 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
702 (float)BSLinkset.LinksetImplementation.Compound ), 704 (float)BSLinkset.LinksetImplementation.Compound ),
703 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same", 705 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same",
704 false ), 706 true ),
705 new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", 707 new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
706 false ), 708 false ),
707 new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", 709 new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index fc4545f..d34b797 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -353,6 +353,16 @@ public abstract class BSPhysObject : PhysicsActor
353 CollidingStep = BSScene.NotASimulationStep; 353 CollidingStep = BSScene.NotASimulationStep;
354 } 354 }
355 } 355 }
356 // Complex objects (like linksets) need to know if there is a collision on any part of
357 // their shape. 'IsColliding' has an existing definition of reporting a collision on
358 // only this specific prim or component of linksets.
359 // 'HasSomeCollision' is defined as reporting if there is a collision on any part of
360 // the complex body that this prim is the root of.
361 public virtual bool HasSomeCollision
362 {
363 get { return IsColliding; }
364 set { IsColliding = value; }
365 }
356 public override bool CollidingGround { 366 public override bool CollidingGround {
357 get { return (CollidingGroundStep == PhysScene.SimulationStep); } 367 get { return (CollidingGroundStep == PhysScene.SimulationStep); }
358 set 368 set
@@ -386,6 +396,7 @@ public abstract class BSPhysObject : PhysicsActor
386 // Return 'true' if a collision was processed and should be sent up. 396 // Return 'true' if a collision was processed and should be sent up.
387 // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. 397 // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
388 // Called at taint time from within the Step() function 398 // Called at taint time from within the Step() function
399 public delegate bool CollideCall(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
389 public virtual bool Collide(uint collidingWith, BSPhysObject collidee, 400 public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
390 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 401 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
391 { 402 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index d43448e..e92a1d2 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -96,7 +96,7 @@ public class BSPrim : BSPhysObject
96 _isVolumeDetect = false; 96 _isVolumeDetect = false;
97 97
98 // Add a dynamic vehicle to our set of actors that can move this prim. 98 // Add a dynamic vehicle to our set of actors that can move this prim.
99 PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysScene, this, VehicleActorName)); 99 // PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysScene, this, VehicleActorName));
100 100
101 _mass = CalculateMass(); 101 _mass = CalculateMass();
102 102
@@ -440,8 +440,8 @@ public class BSPrim : BSPhysObject
440 Gravity = ComputeGravity(Buoyancy); 440 Gravity = ComputeGravity(Buoyancy);
441 PhysScene.PE.SetGravity(PhysBody, Gravity); 441 PhysScene.PE.SetGravity(PhysBody, Gravity);
442 442
443 OMV.Vector3 currentScale = PhysScene.PE.GetLocalScaling(PhysShape.physShapeInfo); // DEBUG DEBUG 443 // OMV.Vector3 currentScale = PhysScene.PE.GetLocalScaling(PhysShape.physShapeInfo); // DEBUG DEBUG
444 DetailLog("{0},BSPrim.UpdateMassProperties,currentScale{1},shape={2}", LocalID, currentScale, PhysShape.physShapeInfo); // DEBUG DEBUG 444 // DetailLog("{0},BSPrim.UpdateMassProperties,currentScale{1},shape={2}", LocalID, currentScale, PhysShape.physShapeInfo); // DEBUG DEBUG
445 445
446 Inertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass); 446 Inertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
447 PhysScene.PE.SetMassProps(PhysBody, physMass, Inertia); 447 PhysScene.PE.SetMassProps(PhysBody, physMass, Inertia);
@@ -495,9 +495,9 @@ public class BSPrim : BSPhysObject
495 } 495 }
496 } 496 }
497 497
498 // Find and return a handle to the current vehicle actor. 498 // Find and return a handle to the current vehicle actor.
499 // Return 'null' if there is no vehicle actor. 499 // Return 'null' if there is no vehicle actor.
500 public BSDynamics GetVehicleActor() 500 public BSDynamics GetVehicleActor(bool createIfNone)
501 { 501 {
502 BSDynamics ret = null; 502 BSDynamics ret = null;
503 BSActor actor; 503 BSActor actor;
@@ -505,12 +505,21 @@ public class BSPrim : BSPhysObject
505 { 505 {
506 ret = actor as BSDynamics; 506 ret = actor as BSDynamics;
507 } 507 }
508 else
509 {
510 if (createIfNone)
511 {
512 ret = new BSDynamics(PhysScene, this, VehicleActorName);
513 PhysicalActors.Add(ret.ActorName, ret);
514 }
515 }
508 return ret; 516 return ret;
509 } 517 }
518
510 public override int VehicleType { 519 public override int VehicleType {
511 get { 520 get {
512 int ret = (int)Vehicle.TYPE_NONE; 521 int ret = (int)Vehicle.TYPE_NONE;
513 BSDynamics vehicleActor = GetVehicleActor(); 522 BSDynamics vehicleActor = GetVehicleActor(false /* createIfNone */);
514 if (vehicleActor != null) 523 if (vehicleActor != null)
515 ret = (int)vehicleActor.Type; 524 ret = (int)vehicleActor.Type;
516 return ret; 525 return ret;
@@ -524,11 +533,24 @@ public class BSPrim : BSPhysObject
524 // change all the parameters. Like a plane changing to CAR when on the 533 // change all the parameters. Like a plane changing to CAR when on the
525 // ground. In this case, don't want to zero motion. 534 // ground. In this case, don't want to zero motion.
526 // ZeroMotion(true /* inTaintTime */); 535 // ZeroMotion(true /* inTaintTime */);
527 BSDynamics vehicleActor = GetVehicleActor(); 536 if (type == Vehicle.TYPE_NONE)
528 if (vehicleActor != null)
529 { 537 {
530 vehicleActor.ProcessTypeChange(type); 538 // Vehicle type is 'none' so get rid of any actor that may have been allocated.
531 ActivateIfPhysical(false); 539 BSDynamics vehicleActor = GetVehicleActor(false /* createIfNone */);
540 if (vehicleActor != null)
541 {
542 PhysicalActors.RemoveAndRelease(vehicleActor.ActorName);
543 }
544 }
545 else
546 {
547 // Vehicle type is not 'none' so create an actor and set it running.
548 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
549 if (vehicleActor != null)
550 {
551 vehicleActor.ProcessTypeChange(type);
552 ActivateIfPhysical(false);
553 }
532 } 554 }
533 }); 555 });
534 } 556 }
@@ -537,7 +559,7 @@ public class BSPrim : BSPhysObject
537 { 559 {
538 PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 560 PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
539 { 561 {
540 BSDynamics vehicleActor = GetVehicleActor(); 562 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
541 if (vehicleActor != null) 563 if (vehicleActor != null)
542 { 564 {
543 vehicleActor.ProcessFloatVehicleParam((Vehicle)param, value); 565 vehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
@@ -549,7 +571,7 @@ public class BSPrim : BSPhysObject
549 { 571 {
550 PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 572 PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
551 { 573 {
552 BSDynamics vehicleActor = GetVehicleActor(); 574 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
553 if (vehicleActor != null) 575 if (vehicleActor != null)
554 { 576 {
555 vehicleActor.ProcessVectorVehicleParam((Vehicle)param, value); 577 vehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
@@ -561,7 +583,7 @@ public class BSPrim : BSPhysObject
561 { 583 {
562 PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 584 PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
563 { 585 {
564 BSDynamics vehicleActor = GetVehicleActor(); 586 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
565 if (vehicleActor != null) 587 if (vehicleActor != null)
566 { 588 {
567 vehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation); 589 vehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
@@ -573,7 +595,7 @@ public class BSPrim : BSPhysObject
573 { 595 {
574 PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate() 596 PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate()
575 { 597 {
576 BSDynamics vehicleActor = GetVehicleActor(); 598 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
577 if (vehicleActor != null) 599 if (vehicleActor != null)
578 { 600 {
579 vehicleActor.ProcessVehicleFlags(param, remove); 601 vehicleActor.ProcessVehicleFlags(param, remove);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index 1fbcfcc..2f392da 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -200,20 +200,38 @@ public class BSPrimLinkable : BSPrimDisplaced
200 } 200 }
201 201
202 // Called after a simulation step to post a collision with this object. 202 // Called after a simulation step to post a collision with this object.
203 // This returns 'true' if the collision has been queued and the SendCollisions call must
204 // be made at the end of the simulation step.
203 public override bool Collide(uint collidingWith, BSPhysObject collidee, 205 public override bool Collide(uint collidingWith, BSPhysObject collidee,
204 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 206 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
205 { 207 {
206 // prims in the same linkset cannot collide with each other 208 bool ret = false;
207 BSPrimLinkable convCollidee = collidee as BSPrimLinkable; 209 // Ask the linkset if it wants to handle the collision
208 if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID)) 210 if (!Linkset.HandleCollide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth))
209 { 211 {
210 return false; 212 // The linkset didn't handle it so pass the collision through normal processing
213 ret = base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
211 } 214 }
215 return ret;
216 }
212 217
213 // TODO: handle collisions of other objects with with children of linkset. 218 // A linkset reports any collision on any part of the linkset.
214 // This is a problem for LinksetCompound since the children are packed into the root. 219 public long SomeCollisionSimulationStep = 0;
220 public override bool HasSomeCollision
221 {
222 get
223 {
224 return (SomeCollisionSimulationStep == PhysScene.SimulationStep) || base.IsColliding;
225 }
226 set
227 {
228 if (value)
229 SomeCollisionSimulationStep = PhysScene.SimulationStep;
230 else
231 SomeCollisionSimulationStep = 0;
215 232
216 return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth); 233 base.HasSomeCollision = value;
234 }
217 } 235 }
218} 236}
219} 237}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
index 48d3742..48e74eb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs
@@ -116,7 +116,7 @@ public class BasicVehicles : OpenSimTestCase
116 // Instead the appropriate values are set and calls are made just the parts of the 116 // Instead the appropriate values are set and calls are made just the parts of the
117 // controller we want to exercise. Stepping the physics engine then applies 117 // controller we want to exercise. Stepping the physics engine then applies
118 // the actions of that one feature. 118 // the actions of that one feature.
119 BSDynamics vehicleActor = TestVehicle.GetVehicleActor(); 119 BSDynamics vehicleActor = TestVehicle.GetVehicleActor(true /* createIfNone */);
120 if (vehicleActor != null) 120 if (vehicleActor != null)
121 { 121 {
122 vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency); 122 vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);