From ebb63b55aab98da6d44e82fc0ecfd5d22f245172 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 7 Feb 2013 11:53:49 -0800
Subject: BulletSim: add user setting of friction, density and restitution.

---
 .../Region/Physics/BulletSPlugin/BSCharacter.cs    |  5 +-
 .../Region/Physics/BulletSPlugin/BSPhysObject.cs   | 17 ++--
 OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs     | 99 +++++++++++++++++-----
 3 files changed, 94 insertions(+), 27 deletions(-)

diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 192bcb5..d694a6a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -749,9 +749,10 @@ public sealed class BSCharacter : BSPhysObject
             _buoyancy = value;
             DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
             // Buoyancy is faked by changing the gravity applied to the object
-            float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
+            float  grav = BSParam.Gravity * (1f - _buoyancy);
+            Gravity = new OMV.Vector3(0f, 0f, grav);
             if (PhysBody.HasPhysicalBody)
-                PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav));
+                PhysicsScene.PE.SetGravity(PhysBody, Gravity);
         }
     }
 
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index ec25aa9..0b35f3a 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor
         Name = name;    // PhysicsActor also has the name of the object. Someday consolidate.
         TypeName = typeName;
 
+        // Initialize variables kept in base.
+        GravityModifier = 1.0f;
+        Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
+
         // We don't have any physical representation yet.
         PhysBody = new BulletBody(localID);
         PhysShape = new BulletShape();
@@ -88,8 +92,8 @@ public abstract class BSPhysObject : PhysicsActor
 
         LastAssetBuildFailed = false;
 
-        // Default material type
-        Material = MaterialAttributes.Material.Wood;
+        // Default material type. Also sets Friction, Restitution and Density.
+        SetMaterial((int)MaterialAttributes.Material.Wood);
 
         CollisionCollection = new CollisionEventUpdate();
         CollisionsLastTick = CollisionCollection;
@@ -122,6 +126,8 @@ public abstract class BSPhysObject : PhysicsActor
     // 'inWorld' true if the object has already been added to the dynamic world.
     public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
 
+    // The gravity being applied to the object. A function of default grav, GravityModifier and Buoyancy.
+    public virtual OMV.Vector3 Gravity { get; set; }
     // The last value calculated for the prim's inertia
     public OMV.Vector3 Inertia { get; set; }
 
@@ -164,15 +170,16 @@ public abstract class BSPhysObject : PhysicsActor
     public override void SetMaterial(int material)
     {
         Material = (MaterialAttributes.Material)material;
+        MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
+        Friction = matAttrib.friction;
+        Restitution = matAttrib.restitution;
+        Density = matAttrib.density;
     }
 
     // Stop all physical motion.
     public abstract void ZeroMotion(bool inTaintTime);
     public abstract void ZeroAngularMotion(bool inTaintTime);
 
-    // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
-    public virtual void StepVehicle(float timeStep) { }
-
     // Update the physical location and motion of the object. Called with data from Bullet.
     public abstract void UpdateProperties(EntityProperties entprop);
 
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 54bf063..a86932a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -55,7 +55,6 @@ public sealed class BSPrim : BSPhysObject
     private OMV.Vector3 _position;
 
     private float _mass;    // the mass of this object
-    private float _density;
     private OMV.Vector3 _force;
     private OMV.Vector3 _velocity;
     private OMV.Vector3 _torque;
@@ -64,8 +63,6 @@ public sealed class BSPrim : BSPhysObject
     private int _physicsActorType;
     private bool _isPhysical;
     private bool _flying;
-    private float _friction;
-    private float _restitution;
     private bool _setAlwaysRun;
     private bool _throttleUpdates;
     private bool _floatOnWater;
@@ -101,12 +98,6 @@ public sealed class BSPrim : BSPhysObject
         _isPhysical = pisPhysical;
         _isVolumeDetect = false;
 
-        // Someday set default attributes based on the material but, for now, we don't know the prim material yet.
-        // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical);
-        _density = PhysicsScene.Params.defaultDensity;
-        _friction = PhysicsScene.Params.defaultFriction;
-        _restitution = PhysicsScene.Params.defaultRestitution;
-
         VehicleController = new BSDynamics(PhysicsScene, this);            // add vehicleness
 
         _mass = CalculateMass();
@@ -457,11 +448,6 @@ public sealed class BSPrim : BSPhysObject
                 {
                     AddObjectToPhysicalWorld();
                 }
-
-                // Must set gravity after it has been added to the world because, for unknown reasons,
-                //     adding the object resets the object's gravity to world gravity
-                PhysicsScene.PE.SetGravity(PhysBody, grav);
-
             }
         }
     }
@@ -469,7 +455,7 @@ public sealed class BSPrim : BSPhysObject
     // Return what gravity should be set to this very moment
     public OMV.Vector3 ComputeGravity(float buoyancy)
     {
-        OMV.Vector3 ret = PhysicsScene.DefaultGravity;
+        OMV.Vector3 ret = PhysicsScene.DefaultGravity * GravityModifier;
 
         if (!IsStatic)
             ret *= (1f - buoyancy);
@@ -596,6 +582,74 @@ public sealed class BSPrim : BSPhysObject
         }
         return;
     }
+    public override void SetMaterial(int material)
+    {
+        base.SetMaterial(material);
+        PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate()
+        {
+            UpdatePhysicalParameters();
+        });
+    }
+    public override float Friction
+    {
+        get { return base.Friction; }
+        set
+        {
+            if (base.Friction != value)
+            {
+                base.Friction = value;
+                PhysicsScene.TaintedObject("BSPrim.setFriction", delegate()
+                {
+                    UpdatePhysicalParameters();
+                });
+            }
+        }
+    }
+    public override float Restitution
+    {
+        get { return base.Restitution; }
+        set
+        {
+            if (base.Restitution != value)
+            {
+                base.Restitution = value;
+                PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate()
+                {
+                    UpdatePhysicalParameters();
+                });
+            }
+        }
+    }
+    public override float Density
+    {
+        get { return base.Density; }
+        set
+        {
+            if (base.Density != value)
+            {
+                base.Density = value;
+                PhysicsScene.TaintedObject("BSPrim.setDensity", delegate()
+                {
+                    UpdatePhysicalParameters();
+                });
+            }
+        }
+    }
+    public override float GravityModifier
+    {
+        get { return base.GravityModifier; }
+        set
+        {
+            if (base.GravityModifier != value)
+            {
+                base.GravityModifier = value;
+                PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate()
+                {
+                    UpdatePhysicalParameters();
+                });
+            }
+        }
+    }
     public override OMV.Vector3 RawVelocity
     {
         get { return _velocity; }
@@ -810,8 +864,8 @@ public sealed class BSPrim : BSPhysObject
 
             // Set various physical properties so other object interact properly
             MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
-            PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
-            PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
+            PhysicsScene.PE.SetFriction(PhysBody, Friction);
+            PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
 
             // Mass is zero which disables a bunch of physics stuff in Bullet
             UpdatePhysicalMassProperties(0f, false);
@@ -840,8 +894,8 @@ public sealed class BSPrim : BSPhysObject
 
             // Set various physical properties so other object interact properly
             MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
-            PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
-            PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
+            PhysicsScene.PE.SetFriction(PhysBody, Friction);
+            PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
 
             // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
             // Since this can be called multiple times, only zero forces when becoming physical
@@ -940,6 +994,11 @@ public sealed class BSPrim : BSPhysObject
         if (PhysBody.HasPhysicalBody)
         {
             PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
+
+            // Must set gravity after it has been added to the world because, for unknown reasons,
+            //     adding the object resets the object's gravity to world gravity
+            OMV.Vector3 grav = ComputeGravity(Buoyancy);
+            PhysicsScene.PE.SetGravity(PhysBody, grav);
         }
         else
         {
@@ -1581,7 +1640,7 @@ public sealed class BSPrim : BSPhysObject
         profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f;
         volume *= (profileEnd - profileBegin);
 
-        returnMass = _density * volume;
+        returnMass = Density * volume;
 
         /* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
         if (IsRootOfLinkset)
-- 
cgit v1.1