aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs11
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs267
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs207
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs44
4 files changed, 316 insertions, 213 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 82361ad..9f9ebcc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -51,8 +51,6 @@ public class BSCharacter : PhysicsActor
51 private Vector3 _position; 51 private Vector3 _position;
52 private float _mass = 80f; 52 private float _mass = 80f;
53 public float _density = 60f; 53 public float _density = 60f;
54 public float CAPSULE_RADIUS = 0.37f;
55 public float CAPSULE_LENGTH = 2.140599f;
56 private Vector3 _force; 54 private Vector3 _force;
57 private Vector3 _velocity; 55 private Vector3 _velocity;
58 private Vector3 _torque; 56 private Vector3 _torque;
@@ -96,7 +94,8 @@ public class BSCharacter : PhysicsActor
96 _velocity = Vector3.Zero; 94 _velocity = Vector3.Zero;
97 _buoyancy = 0f; // characters return a buoyancy of zero 95 _buoyancy = 0f; // characters return a buoyancy of zero
98 _scale = new Vector3(1f, 1f, 1f); 96 _scale = new Vector3(1f, 1f, 1f);
99 float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH); 97 float AVvolume = (float) (Math.PI*Math.Pow(_scene.Params.avatarCapsuleRadius, 2)*_scene.Params.avatarCapsuleHeight);
98 _density = _scene.Params.avatarDensity;
100 _mass = _density*AVvolume; 99 _mass = _density*AVvolume;
101 100
102 ShapeData shapeData = new ShapeData(); 101 ShapeData shapeData = new ShapeData();
@@ -109,6 +108,8 @@ public class BSCharacter : PhysicsActor
109 shapeData.Mass = _mass; 108 shapeData.Mass = _mass;
110 shapeData.Buoyancy = isFlying ? 1f : 0f; 109 shapeData.Buoyancy = isFlying ? 1f : 0f;
111 shapeData.Static = ShapeData.numericFalse; 110 shapeData.Static = ShapeData.numericFalse;
111 shapeData.Friction = _scene.Params.avatarFriction;
112 shapeData.Restitution = _scene.Params.defaultRestitution;
112 113
113 // do actual create at taint time 114 // do actual create at taint time
114 _scene.TaintedObject(delegate() 115 _scene.TaintedObject(delegate()
@@ -395,9 +396,9 @@ public class BSCharacter : PhysicsActor
395 _acceleration = entprop.Acceleration; 396 _acceleration = entprop.Acceleration;
396 changed = true; 397 changed = true;
397 } 398 }
398 if (_rotationalVelocity != entprop.AngularVelocity) 399 if (_rotationalVelocity != entprop.RotationalVelocity)
399 { 400 {
400 _rotationalVelocity = entprop.AngularVelocity; 401 _rotationalVelocity = entprop.RotationalVelocity;
401 changed = true; 402 changed = true;
402 } 403 }
403 if (changed) 404 if (changed)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index f2ab2d9..04cb452 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -71,6 +71,7 @@ public sealed class BSPrim : PhysicsActor
71 private bool _isPhysical; 71 private bool _isPhysical;
72 private bool _flying; 72 private bool _flying;
73 private float _friction; 73 private float _friction;
74 private float _restitution;
74 private bool _setAlwaysRun; 75 private bool _setAlwaysRun;
75 private bool _throttleUpdates; 76 private bool _throttleUpdates;
76 private bool _isColliding; 77 private bool _isColliding;
@@ -101,7 +102,7 @@ public sealed class BSPrim : PhysicsActor
101 private float _PIDHoverTao; 102 private float _PIDHoverTao;
102 103
103 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, 104 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
104 OMV.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical) 105 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
105 { 106 {
106 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); 107 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
107 _localID = localID; 108 _localID = localID;
@@ -113,15 +114,16 @@ public sealed class BSPrim : PhysicsActor
113 _orientation = rotation; 114 _orientation = rotation;
114 _buoyancy = 1f; 115 _buoyancy = 1f;
115 _velocity = OMV.Vector3.Zero; 116 _velocity = OMV.Vector3.Zero;
117 _rotationalVelocity = OMV.Vector3.Zero;
116 _angularVelocity = OMV.Vector3.Zero; 118 _angularVelocity = OMV.Vector3.Zero;
117 _mesh = mesh;
118 _hullKey = 0; 119 _hullKey = 0;
119 _pbs = pbs; 120 _pbs = pbs;
120 _isPhysical = pisPhysical; 121 _isPhysical = pisPhysical;
121 _isVolumeDetect = false; 122 _isVolumeDetect = false;
122 _subscribedEventsMs = 0; 123 _subscribedEventsMs = 0;
123 _friction = _scene.DefaultFriction; // TODO: compute based on object material 124 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
124 _density = _scene.DefaultDensity; // TODO: compute based on object material 125 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
126 _restitution = _scene.Params.defaultRestitution;
125 _parentPrim = null; // not a child or a parent 127 _parentPrim = null; // not a child or a parent
126 _vehicle = new BSDynamics(this); // add vehicleness 128 _vehicle = new BSDynamics(this); // add vehicleness
127 _childrenPrims = new List<BSPrim>(); 129 _childrenPrims = new List<BSPrim>();
@@ -132,8 +134,7 @@ public sealed class BSPrim : PhysicsActor
132 // do the actual object creation at taint time 134 // do the actual object creation at taint time
133 _scene.TaintedObject(delegate() 135 _scene.TaintedObject(delegate()
134 { 136 {
135 CreateGeom(); 137 RecreateGeomAndObject();
136 CreateObject();
137 }); 138 });
138 } 139 }
139 140
@@ -239,6 +240,7 @@ public sealed class BSPrim : PhysicsActor
239 return; 240 return;
240 } 241 }
241 242
243 // I am the root of a linkset and a new child is being added
242 public void AddChildToLinkset(BSPrim pchild) 244 public void AddChildToLinkset(BSPrim pchild)
243 { 245 {
244 BSPrim child = pchild; 246 BSPrim child = pchild;
@@ -254,6 +256,8 @@ public sealed class BSPrim : PhysicsActor
254 return; 256 return;
255 } 257 }
256 258
259 // I am the root of a linkset and one of my children is being removed.
260 // Safe to call even if the child is not really in my linkset.
257 public void RemoveChildFromLinkset(BSPrim pchild) 261 public void RemoveChildFromLinkset(BSPrim pchild)
258 { 262 {
259 BSPrim child = pchild; 263 BSPrim child = pchild;
@@ -290,6 +294,17 @@ public sealed class BSPrim : PhysicsActor
290 get { return (_parentPrim == null && _childrenPrims.Count != 0); } 294 get { return (_parentPrim == null && _childrenPrims.Count != 0); }
291 } 295 }
292 296
297 // Set motion values to zero.
298 // Do it to the properties so the values get set in the physics engine.
299 // Push the setting of the values to the viewer.
300 private void ZeroMotion()
301 {
302 Velocity = OMV.Vector3.Zero;
303 _acceleration = OMV.Vector3.Zero;
304 RotationalVelocity = OMV.Vector3.Zero;
305 base.RequestPhysicsterseUpdate();
306 }
307
293 public override void LockAngularMotion(OMV.Vector3 axis) { return; } 308 public override void LockAngularMotion(OMV.Vector3 axis) { return; }
294 309
295 public override OMV.Vector3 Position { 310 public override OMV.Vector3 Position {
@@ -390,18 +405,6 @@ public sealed class BSPrim : PhysicsActor
390 }); 405 });
391 } 406 }
392 } 407 }
393 public OMV.Vector3 AngularVelocity
394 {
395 get { return _angularVelocity; }
396 set
397 {
398 _angularVelocity = value;
399 _scene.TaintedObject(delegate()
400 {
401 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _angularVelocity);
402 });
403 }
404 }
405 public override OMV.Vector3 Torque { 408 public override OMV.Vector3 Torque {
406 get { return _torque; } 409 get { return _torque; }
407 set { _torque = value; 410 set { _torque = value;
@@ -419,11 +422,11 @@ public sealed class BSPrim : PhysicsActor
419 get { return _orientation; } 422 get { return _orientation; }
420 set { 423 set {
421 _orientation = value; 424 _orientation = value;
425 // m_log.DebugFormat("{0}: set orientation: id={1}, ori={2}", LogHeader, LocalID, _orientation);
422 _scene.TaintedObject(delegate() 426 _scene.TaintedObject(delegate()
423 { 427 {
424 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 428 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
425 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 429 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
426 // m_log.DebugFormat("{0}: set orientation: {1}", LogHeader, _orientation);
427 }); 430 });
428 } 431 }
429 } 432 }
@@ -505,8 +508,16 @@ public sealed class BSPrim : PhysicsActor
505 get { return _rotationalVelocity; } 508 get { return _rotationalVelocity; }
506 set { _rotationalVelocity = value; 509 set { _rotationalVelocity = value;
507 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 510 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
511 _scene.TaintedObject(delegate()
512 {
513 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
514 });
508 } 515 }
509 } 516 }
517 public OMV.Vector3 AngularVelocity {
518 get { return _angularVelocity; }
519 set { _angularVelocity = value; }
520 }
510 public override bool Kinematic { 521 public override bool Kinematic {
511 get { return _kinematic; } 522 get { return _kinematic; }
512 set { _kinematic = value; 523 set { _kinematic = value;
@@ -866,9 +877,6 @@ public sealed class BSPrim : PhysicsActor
866 877
867 returnMass = _density * volume; 878 returnMass = _density * volume;
868 879
869 if (returnMass <= 0)
870 returnMass = 0.0001f;//ckrinke: Mass must be greater then zero.
871
872 if (IsRootOfLinkset) 880 if (IsRootOfLinkset)
873 { 881 {
874 foreach (BSPrim prim in _childrenPrims) 882 foreach (BSPrim prim in _childrenPrims)
@@ -877,8 +885,12 @@ public sealed class BSPrim : PhysicsActor
877 } 885 }
878 } 886 }
879 887
880 if (returnMass > _scene.maximumMassObject) 888 if (returnMass <= 0)
881 returnMass = _scene.maximumMassObject; 889 returnMass = 0.0001f;
890
891 if (returnMass > _scene.MaximumObjectMass)
892 returnMass = _scene.MaximumObjectMass;
893
882 return returnMass; 894 return returnMass;
883 }// end CalculateMass 895 }// end CalculateMass
884 #endregion Mass Calculation 896 #endregion Mass Calculation
@@ -887,6 +899,15 @@ public sealed class BSPrim : PhysicsActor
887 // No locking here because this is done when we know physics is not simulating 899 // No locking here because this is done when we know physics is not simulating
888 private void CreateGeom() 900 private void CreateGeom()
889 { 901 {
902 // Since we're recreating new, get rid of any previously generated shape
903 if (_hullKey != 0)
904 {
905 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
906 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
907 _hullKey = 0;
908 _hulls.Clear();
909 }
910
890 if (_mesh == null) 911 if (_mesh == null)
891 { 912 {
892 // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. 913 // the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
@@ -902,21 +923,13 @@ public sealed class BSPrim : PhysicsActor
902 } 923 }
903 else 924 else
904 { 925 {
905 // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to box of size {1}", LogHeader, _size); 926 // m_log.DebugFormat("{0}: CreateGeom: mesh null. Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
906 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 927 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
907 _scale = _size; 928 _scale = _size;
908 } 929 }
909 } 930 }
910 else 931 else
911 { 932 {
912 if (_hullKey != 0)
913 {
914 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
915 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
916 _hullKey = 0;
917 _hulls.Clear();
918 }
919
920 int[] indices = _mesh.getIndexListAsInt(); 933 int[] indices = _mesh.getIndexListAsInt();
921 List<OMV.Vector3> vertices = _mesh.getVertexList(); 934 List<OMV.Vector3> vertices = _mesh.getVertexList();
922 935
@@ -997,7 +1010,7 @@ public sealed class BSPrim : PhysicsActor
997 1010
998 // create the hull definition in Bullet 1011 // create the hull definition in Bullet
999 _hullKey = (ulong)_pbs.GetHashCode(); 1012 _hullKey = (ulong)_pbs.GetHashCode();
1000 // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid= {1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); 1013 // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount);
1001 BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); 1014 BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls);
1002 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1015 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1003 // meshes are already scaled by the meshmerizer 1016 // meshes are already scaled by the meshmerizer
@@ -1006,6 +1019,8 @@ public sealed class BSPrim : PhysicsActor
1006 return; 1019 return;
1007 } 1020 }
1008 1021
1022 // Callback from convex hull creater with a newly created hull.
1023 // Just add it to the collection of hulls for this shape.
1009 private void HullReturn(ConvexResult result) 1024 private void HullReturn(ConvexResult result)
1010 { 1025 {
1011 _hulls.Add(result); 1026 _hulls.Add(result);
@@ -1019,13 +1034,12 @@ public sealed class BSPrim : PhysicsActor
1019 if (IsRootOfLinkset) 1034 if (IsRootOfLinkset)
1020 { 1035 {
1021 // Create a linkset around this object 1036 // Create a linkset around this object
1022 CreateLinksetWithCompoundHull(); 1037 // CreateLinksetWithCompoundHull();
1023 // CreateLinksetWithConstraints(); 1038 CreateLinksetWithConstraints();
1024 } 1039 }
1025 else 1040 else
1026 { 1041 {
1027 // simple object 1042 // simple object
1028 // m_log.DebugFormat("{0}: CreateObject. ID={1}", LogHeader, LocalID);
1029 ShapeData shape; 1043 ShapeData shape;
1030 FillShapeInfo(out shape); 1044 FillShapeInfo(out shape);
1031 BulletSimAPI.CreateObject(_scene.WorldID, shape); 1045 BulletSimAPI.CreateObject(_scene.WorldID, shape);
@@ -1034,6 +1048,7 @@ public sealed class BSPrim : PhysicsActor
1034 1048
1035 // Create a linkset by creating a compound hull at the root prim that consists of all 1049 // Create a linkset by creating a compound hull at the root prim that consists of all
1036 // the children. 1050 // the children.
1051 // NOTE: This does not allow proper collisions with the children prims so it is not a workable solution
1037 void CreateLinksetWithCompoundHull() 1052 void CreateLinksetWithCompoundHull()
1038 { 1053 {
1039 // If I am the root prim of a linkset, replace my physical shape with all the 1054 // If I am the root prim of a linkset, replace my physical shape with all the
@@ -1055,8 +1070,27 @@ public sealed class BSPrim : PhysicsActor
1055 BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes); 1070 BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
1056 } 1071 }
1057 1072
1073 // Copy prim's info into the BulletSim shape description structure
1074 public void FillShapeInfo(out ShapeData shape)
1075 {
1076 shape.ID = _localID;
1077 shape.Type = _shapeType;
1078 shape.Position = _position;
1079 shape.Rotation = _orientation;
1080 shape.Velocity = _velocity;
1081 shape.Scale = _scale;
1082 shape.Mass = _isPhysical ? _mass : 0f;
1083 shape.Buoyancy = _buoyancy;
1084 shape.MeshKey = _hullKey;
1085 shape.Friction = _friction;
1086 shape.Restitution = _restitution;
1087 shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse;
1088 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1089 }
1090
1058 // Create the linkset by putting constraints between the objects of the set so they cannot move 1091 // Create the linkset by putting constraints between the objects of the set so they cannot move
1059 // relative to each other. 1092 // relative to each other.
1093 // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
1060 void CreateLinksetWithConstraints() 1094 void CreateLinksetWithConstraints()
1061 { 1095 {
1062 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); 1096 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
@@ -1070,76 +1104,48 @@ public sealed class BSPrim : PhysicsActor
1070 // create constraints between the root prim and each of the children 1104 // create constraints between the root prim and each of the children
1071 foreach (BSPrim prim in _childrenPrims) 1105 foreach (BSPrim prim in _childrenPrims)
1072 { 1106 {
1073 // this is a constraint that allows no freedom of movement between the two objects
1074 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1075 // m_log.DebugFormat("{0}: CreateObject: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); 1107 // m_log.DebugFormat("{0}: CreateObject: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1076 1108
1109 // Zero motion for children so they don't interpolate
1110 prim.ZeroMotion();
1111
1077 // relative position normalized to the root prim 1112 // relative position normalized to the root prim
1078 OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation); 1113 OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation);
1079 // OMV.Quaternion relativeRotation = OMV.Quaternion.Identity;
1080 1114
1081 // rotation is pointing up the vector between the object centers 1115 // relative rotation of the child to the parent
1082 OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromAxisAngle(childRelativePosition, 0f); 1116 OMV.Quaternion relativeRotation = OMV.Quaternion.Inverse(prim._orientation) * this._orientation;
1083
1084 /* // the logic for relative rotation from http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6391
1085 OMV.Vector3 rrn = childRelativePosition;
1086 rrn.Normalize();
1087 rrn /= rrn.X;
1088 OMV.Matrix4 rotmat = new OMV.Matrix4(rrn.X, rrn.Y, rrn.Z, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1089 OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromRotationMatrix(rotmat);
1090 */
1091 1117
1118 // this is a constraint that allows no freedom of movement between the two objects
1119 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1092 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, 1120 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
1093 childRelativePosition / 2, 1121 childRelativePosition,
1094 relativeRotation,
1095 -childRelativePosition / 2,
1096 relativeRotation, 1122 relativeRotation,
1123 OMV.Vector3.Zero,
1124 OMV.Quaternion.Identity,
1097 OMV.Vector3.Zero, OMV.Vector3.Zero, 1125 OMV.Vector3.Zero, OMV.Vector3.Zero,
1098 OMV.Vector3.Zero, OMV.Vector3.Zero); 1126 OMV.Vector3.Zero, OMV.Vector3.Zero);
1099 } 1127 }
1100 } 1128 }
1101 1129
1102 // Copy prim's info into the BulletSim shape description structure
1103 public void FillShapeInfo(out ShapeData shape)
1104 {
1105 shape.ID = _localID;
1106 shape.Type = _shapeType;
1107 shape.Position = _position;
1108 shape.Rotation = _orientation;
1109 shape.Velocity = _velocity;
1110 shape.Scale = _scale;
1111 shape.Mass = _isPhysical ? _mass : 0f;
1112 shape.Buoyancy = _buoyancy;
1113 shape.MeshKey = _hullKey;
1114 shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse;
1115 shape.Friction = _friction;
1116 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1117 }
1118
1119 // Rebuild the geometry and object. 1130 // Rebuild the geometry and object.
1120 // This is called when the shape changes so we need to recreate the mesh/hull. 1131 // This is called when the shape changes so we need to recreate the mesh/hull.
1121 // No locking here because this is done when the physics engine is not simulating 1132 // No locking here because this is done when the physics engine is not simulating
1122 private void RecreateGeomAndObject() 1133 private void RecreateGeomAndObject()
1123 { 1134 {
1124 if (_hullKey != 0)
1125 {
1126 // if a hull already exists, delete the old one
1127 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1128 _hullKey = 0;
1129 }
1130 // If this object is complex or we are the root of a linkset, build a mesh. 1135 // If this object is complex or we are the root of a linkset, build a mesh.
1131 // The root of a linkset must be a mesh so we can create the linked compound object. 1136 // The root of a linkset must be a mesh so we can create the linked compound object.
1132 if (_scene.NeedsMeshing(_pbs) || IsRootOfLinkset ) 1137 // if (_scene.NeedsMeshing(_pbs) || IsRootOfLinkset )
1138 if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh
1133 { 1139 {
1134 // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); 1140 // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader);
1135 _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.meshLOD, _isPhysical); 1141 _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.MeshLOD, _isPhysical);
1136 } 1142 }
1137 else 1143 else
1138 { 1144 {
1139 // it's a BulletSim native shape. 1145 // implement the shape with a Bullet native shape.
1140 _mesh = null; 1146 _mesh = null;
1141 } 1147 }
1142 CreateGeom(); // create the geometry for this prim 1148 CreateGeom();
1143 CreateObject(); 1149 CreateObject();
1144 return; 1150 return;
1145 } 1151 }
@@ -1152,48 +1158,82 @@ public sealed class BSPrim : PhysicsActor
1152 Rotation = 1 << 1, 1158 Rotation = 1 << 1,
1153 Velocity = 1 << 2, 1159 Velocity = 1 << 2,
1154 Acceleration = 1 << 3, 1160 Acceleration = 1 << 3,
1155 AngularVel = 1 << 4 1161 RotationalVel = 1 << 4
1156 } 1162 }
1157 1163
1164 const float ROTATION_TOLERANCE = 0.01f;
1165 const float VELOCITY_TOLERANCE = 0.001f;
1166 const float POSITION_TOLERANCE = 0.05f;
1167 const float ACCELERATION_TOLERANCE = 0.01f;
1168 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1169 const bool SHOULD_DAMP_UPDATES = false;
1170
1158 public void UpdateProperties(EntityProperties entprop) 1171 public void UpdateProperties(EntityProperties entprop)
1159 { 1172 {
1160 UpdatedProperties changed = 0; 1173 UpdatedProperties changed = 0;
1161 // assign to the local variables so the normal set action does not happen 1174 if (SHOULD_DAMP_UPDATES)
1162 if (_position != entprop.Position)
1163 {
1164 _position = entprop.Position;
1165 // m_log.DebugFormat("{0}: UpdateProperties: position = {1}", LogHeader, _position);
1166 changed |= UpdatedProperties.Position;
1167 }
1168 if (_orientation != entprop.Rotation)
1169 {
1170 _orientation = entprop.Rotation;
1171 // m_log.DebugFormat("{0}: UpdateProperties: rotation = {1}", LogHeader, _orientation);
1172 changed |= UpdatedProperties.Rotation;
1173 }
1174 if (_velocity != entprop.Velocity)
1175 {
1176 _velocity = entprop.Velocity;
1177 // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
1178 changed |= UpdatedProperties.Velocity;
1179 }
1180 if (_acceleration != entprop.Acceleration)
1181 {
1182 _acceleration = entprop.Acceleration;
1183 // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
1184 changed |= UpdatedProperties.Acceleration;
1185 }
1186 if (_rotationalVelocity != entprop.AngularVelocity)
1187 { 1175 {
1188 _rotationalVelocity = entprop.AngularVelocity; 1176 // assign to the local variables so the normal set action does not happen
1189 // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); 1177 // if (_position != entprop.Position)
1190 changed |= UpdatedProperties.AngularVel; 1178 if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
1179 {
1180 _position = entprop.Position;
1181 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position);
1182 changed |= UpdatedProperties.Position;
1183 }
1184 // if (_orientation != entprop.Rotation)
1185 if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
1186 {
1187 _orientation = entprop.Rotation;
1188 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation);
1189 changed |= UpdatedProperties.Rotation;
1190 }
1191 // if (_velocity != entprop.Velocity)
1192 if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
1193 {
1194 _velocity = entprop.Velocity;
1195 // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
1196 changed |= UpdatedProperties.Velocity;
1197 }
1198 // if (_acceleration != entprop.Acceleration)
1199 if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
1200 {
1201 _acceleration = entprop.Acceleration;
1202 // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
1203 changed |= UpdatedProperties.Acceleration;
1204 }
1205 // if (_rotationalVelocity != entprop.RotationalVelocity)
1206 if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
1207 {
1208 _rotationalVelocity = entprop.RotationalVelocity;
1209 // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity);
1210 changed |= UpdatedProperties.RotationalVel;
1211 }
1212 if (changed != 0)
1213 {
1214 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1215 // Only update the position of single objects and linkset roots
1216 if (this._parentPrim == null)
1217 {
1218 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1219 base.RequestPhysicsterseUpdate();
1220 }
1221 }
1191 } 1222 }
1192 if (changed != 0) 1223 else
1193 { 1224 {
1194 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); 1225 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1195 if (this._parentPrim == null) 1226 if (this._parentPrim == null)
1227 {
1228 // Assign to the local variables so the normal set action does not happen
1229 _position = entprop.Position;
1230 _orientation = entprop.Rotation;
1231 _velocity = entprop.Velocity;
1232 _acceleration = entprop.Acceleration;
1233 _rotationalVelocity = entprop.RotationalVelocity;
1234 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1196 base.RequestPhysicsterseUpdate(); 1235 base.RequestPhysicsterseUpdate();
1236 }
1197 } 1237 }
1198 } 1238 }
1199 1239
@@ -1201,7 +1241,8 @@ public sealed class BSPrim : PhysicsActor
1201 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1241 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1202 { 1242 {
1203 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1243 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
1204 // The following makes IsColliding() and IsCollidingGround() work 1244
1245 // The following lines make IsColliding() and IsCollidingGround() work
1205 _collidingStep = _scene.SimulationStep; 1246 _collidingStep = _scene.SimulationStep;
1206 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) 1247 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
1207 { 1248 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7c11f2b..de86d59 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -71,11 +71,17 @@ public class BSScene : PhysicsScene
71 private uint m_worldID; 71 private uint m_worldID;
72 public uint WorldID { get { return m_worldID; } } 72 public uint WorldID { get { return m_worldID; } }
73 73
74 private bool m_initialized = false;
75
74 public IMesher mesher; 76 public IMesher mesher;
75 public int meshLOD = 32; 77 private int m_meshLOD;
78 public int MeshLOD
79 {
80 get { return m_meshLOD; }
81 }
76 82
77 private int m_maxSubSteps = 10; 83 private int m_maxSubSteps;
78 private float m_fixedTimeStep = 1f / 60f; 84 private float m_fixedTimeStep;
79 private long m_simulationStep = 0; 85 private long m_simulationStep = 0;
80 public long SimulationStep { get { return m_simulationStep; } } 86 public long SimulationStep { get { return m_simulationStep; } }
81 87
@@ -84,68 +90,65 @@ public class BSScene : PhysicsScene
84 private int m_simulationNowTime; 90 private int m_simulationNowTime;
85 public int SimulationNowTime { get { return m_simulationNowTime; } } 91 public int SimulationNowTime { get { return m_simulationNowTime; } }
86 92
87 private int m_maxCollisionsPerFrame = 2048; 93 private int m_maxCollisionsPerFrame;
88 private CollisionDesc[] m_collisionArray; 94 private CollisionDesc[] m_collisionArray;
89 private GCHandle m_collisionArrayPinnedHandle; 95 private GCHandle m_collisionArrayPinnedHandle;
90 96
91 private int m_maxUpdatesPerFrame = 2048; 97 private int m_maxUpdatesPerFrame;
92 private EntityProperties[] m_updateArray; 98 private EntityProperties[] m_updateArray;
93 private GCHandle m_updateArrayPinnedHandle; 99 private GCHandle m_updateArrayPinnedHandle;
94 100
95 private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed 101 private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed
96 private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes 102 private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes
97 public float maximumMassObject = 10000.01f;
98 103
99 public const uint TERRAIN_ID = 0; 104 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
100 public const uint GROUNDPLANE_ID = 1; 105 public const uint GROUNDPLANE_ID = 1;
101 106
102 public float DefaultFriction = 0.70f; 107 public ConfigurationParameters Params
103 public float DefaultDensity = 10.000006836f; // Aluminum g/cm3; TODO: compute based on object material 108 {
104 public Vector3 DefaultGravity = new Vector3(0, 0, -9.80665f); 109 get { return m_params[0]; }
110 }
111 public Vector3 DefaultGravity
112 {
113 get { return new Vector3(0f, 0f, Params.gravity); }
114 }
115
116 private float m_maximumObjectMass;
117 public float MaximumObjectMass
118 {
119 get { return m_maximumObjectMass; }
120 }
105 121
106 public delegate void TaintCallback(); 122 public delegate void TaintCallback();
107 private List<TaintCallback> _taintedObjects; 123 private List<TaintCallback> _taintedObjects;
108 private Object _taintLock = new Object(); 124 private Object _taintLock = new Object();
109 125
110 // A pointer to an instance if this structure is passed to the C++ code 126 // A pointer to an instance if this structure is passed to the C++ code
111 // Format of this structure must match the definition in the C++ code 127 ConfigurationParameters[] m_params;
112 private struct ConfigurationParameters
113 {
114 public float defaultFriction;
115 public float defaultDensity;
116 public float collisionMargin;
117 public float gravity;
118
119 public float linearDamping;
120 public float angularDamping;
121 public float deactivationTime;
122 public float linearSleepingThreshold;
123 public float angularSleepingThreshold;
124
125 public float terrainFriction;
126 public float terrainHitFriction;
127 public float terrainRestitution;
128 public float avatarFriction;
129 public float avatarCapsuleRadius;
130 public float avatarCapsuleHeight;
131 }
132 ConfigurationParameters m_params;
133 GCHandle m_paramsHandle; 128 GCHandle m_paramsHandle;
134 129
135 private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; 130 private BulletSimAPI.DebugLogCallback debugLogCallbackHandle;
136 131
137 public BSScene(string identifier) 132 public BSScene(string identifier)
138 { 133 {
134 m_initialized = false;
139 } 135 }
140 136
141 public override void Initialise(IMesher meshmerizer, IConfigSource config) 137 public override void Initialise(IMesher meshmerizer, IConfigSource config)
142 { 138 {
143 m_params = new ConfigurationParameters(); 139 // Allocate pinned memory to pass parameters.
140 m_params = new ConfigurationParameters[1];
144 m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned); 141 m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned);
145 142
146 // Set default values for physics parameters plus any overrides from the ini file 143 // Set default values for physics parameters plus any overrides from the ini file
147 GetInitialParameterValues(config); 144 GetInitialParameterValues(config);
148 145
146 // allocate more pinned memory close to the above in an attempt to get the memory all together
147 m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
148 m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
149 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
150 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
151
149 // if Debug, enable logging from the unmanaged code 152 // if Debug, enable logging from the unmanaged code
150 if (m_log.IsDebugEnabled) 153 if (m_log.IsDebugEnabled)
151 { 154 {
@@ -160,68 +163,95 @@ public class BSScene : PhysicsScene
160 // The bounding box for the simulated world 163 // The bounding box for the simulated world
161 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f); 164 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f);
162 165
163 // Allocate pinned memory to pass back object property updates and collisions from simulation step
164 m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
165 m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
166 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
167 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
168
169 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 166 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
170 m_worldID = BulletSimAPI.Initialize(worldExtent, 167 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
171 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), 168 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
172 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); 169 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject());
170
171 m_initialized = true;
173 } 172 }
174 173
174 // All default parameter values are set here. There should be no values set in the
175 // variable definitions.
175 private void GetInitialParameterValues(IConfigSource config) 176 private void GetInitialParameterValues(IConfigSource config)
176 { 177 {
178 ConfigurationParameters parms = new ConfigurationParameters();
179
177 _meshSculptedPrim = true; // mesh sculpted prims 180 _meshSculptedPrim = true; // mesh sculpted prims
178 _forceSimplePrimMeshing = false; // use complex meshing if called for 181 _forceSimplePrimMeshing = false; // use complex meshing if called for
179 182
180 // Set the default values for the physics parameters 183 m_meshLOD = 32;
181 m_params.defaultFriction = 0.70f; 184
182 m_params.defaultDensity = 10.000006836f; // Aluminum g/cm3 185 m_maxSubSteps = 10;
183 m_params.collisionMargin = 0.0f; 186 m_fixedTimeStep = 1f / 60f;
184 m_params.gravity = -9.80665f; 187 m_maxCollisionsPerFrame = 2048;
185 188 m_maxUpdatesPerFrame = 2048;
186 m_params.linearDamping = 0.1f; 189 m_maximumObjectMass = 10000.01f;
187 m_params.angularDamping = 0.85f; 190
188 m_params.deactivationTime = 0.2f; 191 parms.defaultFriction = 0.70f;
189 m_params.linearSleepingThreshold = 0.8f; 192 parms.defaultDensity = 10.000006836f; // Aluminum g/cm3
190 m_params.angularSleepingThreshold = 1.0f; 193 parms.defaultRestitution = 0f;
191 194 parms.collisionMargin = 0.0f;
192 m_params.terrainFriction = 0.85f; 195 parms.gravity = -9.80665f;
193 m_params.terrainHitFriction = 0.8f; 196
194 m_params.terrainRestitution = 0.2f; 197 parms.linearDamping = 0.0f;
195 m_params.avatarFriction = 0.85f; 198 parms.angularDamping = 0.0f;
196 m_params.avatarCapsuleRadius = 0.37f; 199 parms.deactivationTime = 0.2f;
197 m_params.avatarCapsuleHeight = 1.5f; // 2.140599f 200 parms.linearSleepingThreshold = 0.8f;
201 parms.angularSleepingThreshold = 1.0f;
202 parms.ccdMotionThreshold = 0.5f; // set to zero to disable
203 parms.ccdSweptSphereRadius = 0.2f;
204
205 parms.terrainFriction = 0.85f;
206 parms.terrainHitFriction = 0.8f;
207 parms.terrainRestitution = 0.2f;
208 parms.avatarFriction = 0.85f;
209 parms.avatarDensity = 60f;
210 parms.avatarCapsuleRadius = 0.37f;
211 parms.avatarCapsuleHeight = 1.5f; // 2.140599f
198 212
199 if (config != null) 213 if (config != null)
200 { 214 {
201 // If there are specifications in the ini file, use those values 215 // If there are specifications in the ini file, use those values
216 // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO ALSO UPDATE OpenSimDefaults.ini
202 IConfig pConfig = config.Configs["BulletSim"]; 217 IConfig pConfig = config.Configs["BulletSim"];
203 if (pConfig != null) 218 if (pConfig != null)
204 { 219 {
205 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", true); 220 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim);
206 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", false); 221 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing);
207 222
208 m_params.defaultFriction = pConfig.GetFloat("DefaultFriction", m_params.defaultFriction); 223 m_meshLOD = pConfig.GetInt("MeshLevelOfDetail", m_meshLOD);
209 m_params.defaultDensity = pConfig.GetFloat("DefaultDensity", m_params.defaultDensity); 224
210 m_params.collisionMargin = pConfig.GetFloat("CollisionMargin", m_params.collisionMargin); 225 m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps);
211 m_params.gravity = pConfig.GetFloat("Gravity", m_params.gravity); 226 m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep);
212 m_params.linearDamping = pConfig.GetFloat("LinearDamping", m_params.linearDamping); 227 m_maxCollisionsPerFrame = pConfig.GetInt("MaxCollisionsPerFrame", m_maxCollisionsPerFrame);
213 m_params.angularDamping = pConfig.GetFloat("AngularDamping", m_params.angularDamping); 228 m_maxUpdatesPerFrame = pConfig.GetInt("MaxUpdatesPerFrame", m_maxUpdatesPerFrame);
214 m_params.deactivationTime = pConfig.GetFloat("DeactivationTime", m_params.deactivationTime); 229 m_maximumObjectMass = pConfig.GetFloat("MaxObjectMass", m_maximumObjectMass);
215 m_params.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", m_params.linearSleepingThreshold); 230
216 m_params.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", m_params.angularSleepingThreshold); 231 parms.defaultFriction = pConfig.GetFloat("DefaultFriction", parms.defaultFriction);
217 m_params.terrainFriction = pConfig.GetFloat("TerrainFriction", m_params.terrainFriction); 232 parms.defaultDensity = pConfig.GetFloat("DefaultDensity", parms.defaultDensity);
218 m_params.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", m_params.terrainHitFriction); 233 parms.defaultRestitution = pConfig.GetFloat("DefaultRestitution", parms.defaultRestitution);
219 m_params.terrainRestitution = pConfig.GetFloat("TerrainRestitution", m_params.terrainRestitution); 234 parms.collisionMargin = pConfig.GetFloat("CollisionMargin", parms.collisionMargin);
220 m_params.avatarFriction = pConfig.GetFloat("AvatarFriction", m_params.avatarFriction); 235 parms.gravity = pConfig.GetFloat("Gravity", parms.gravity);
221 m_params.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", m_params.avatarCapsuleRadius); 236
222 m_params.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", m_params.avatarCapsuleHeight); 237 parms.linearDamping = pConfig.GetFloat("LinearDamping", parms.linearDamping);
238 parms.angularDamping = pConfig.GetFloat("AngularDamping", parms.angularDamping);
239 parms.deactivationTime = pConfig.GetFloat("DeactivationTime", parms.deactivationTime);
240 parms.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", parms.linearSleepingThreshold);
241 parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold);
242 parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold);
243 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
244
245 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
246 parms.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", parms.terrainHitFriction);
247 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
248 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
249 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
250 parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius);
251 parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight);
223 } 252 }
224 } 253 }
254 m_params[0] = parms;
225 } 255 }
226 256
227 // Called directly from unmanaged code so don't do much 257 // Called directly from unmanaged code so don't do much
@@ -282,20 +312,13 @@ public class BSScene : PhysicsScene
282 Vector3 size, Quaternion rotation, bool isPhysical, uint localID) 312 Vector3 size, Quaternion rotation, bool isPhysical, uint localID)
283 { 313 {
284 // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); 314 // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName);
285 IMesh mesh = null; 315 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
286 if (NeedsMeshing(pbs))
287 {
288 // if the prim is complex, create the mesh for it.
289 // If simple (box or sphere) leave 'mesh' null and physics will do a native shape.
290 mesh = mesher.CreateMesh(primName, pbs, size, this.meshLOD, isPhysical);
291 }
292 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, mesh, pbs, isPhysical);
293 lock (m_prims) m_prims.Add(localID, prim); 316 lock (m_prims) m_prims.Add(localID, prim);
294 return prim; 317 return prim;
295 } 318 }
296 319
297 // This is a call from the simulator saying that some physical property has been updated. 320 // This is a call from the simulator saying that some physical property has been updated.
298 // The BulletS driver senses the changing of relevant properties so this taint 321 // The BulletSim driver senses the changing of relevant properties so this taint
299 // information call is not needed. 322 // information call is not needed.
300 public override void AddPhysicsActorTaint(PhysicsActor prim) { } 323 public override void AddPhysicsActorTaint(PhysicsActor prim) { }
301 324
@@ -307,6 +330,9 @@ public class BSScene : PhysicsScene
307 int collidersCount; 330 int collidersCount;
308 IntPtr collidersPtr; 331 IntPtr collidersPtr;
309 332
333 // prevent simulation until we've been initialized
334 if (!m_initialized) return 10.0f;
335
310 // update the prim states while we know the physics engine is not busy 336 // update the prim states while we know the physics engine is not busy
311 ProcessTaints(); 337 ProcessTaints();
312 338
@@ -360,7 +386,7 @@ public class BSScene : PhysicsScene
360 } 386 }
361 } 387 }
362 388
363 // fps calculation wrong. This calculation always returns about 1 in normal operation. 389 // FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
364 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 390 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
365 } 391 }
366 392
@@ -369,8 +395,7 @@ public class BSScene : PhysicsScene
369 { 395 {
370 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) 396 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
371 { 397 {
372 // we never send collisions to the terrain 398 return; // don't send collisions to the terrain
373 return;
374 } 399 }
375 400
376 ActorTypes type = ActorTypes.Prim; 401 ActorTypes type = ActorTypes.Prim;
@@ -381,12 +406,12 @@ public class BSScene : PhysicsScene
381 406
382 BSPrim prim; 407 BSPrim prim;
383 if (m_prims.TryGetValue(localID, out prim)) { 408 if (m_prims.TryGetValue(localID, out prim)) {
384 prim.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f); 409 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
385 return; 410 return;
386 } 411 }
387 BSCharacter actor; 412 BSCharacter actor;
388 if (m_avatars.TryGetValue(localID, out actor)) { 413 if (m_avatars.TryGetValue(localID, out actor)) {
389 actor.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f); 414 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
390 return; 415 return;
391 } 416 }
392 return; 417 return;
@@ -448,7 +473,7 @@ public class BSScene : PhysicsScene
448 473
449 if (pbs.SculptEntry && !_meshSculptedPrim) 474 if (pbs.SculptEntry && !_meshSculptedPrim)
450 { 475 {
451 // m_log.DebugFormat("{0}: NeedsMeshing: scultpy mesh", LogHeader); 476 // Render sculpties as boxes
452 return false; 477 return false;
453 } 478 }
454 479
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index ace8158..819fce1 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -32,12 +32,14 @@ using OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin { 33namespace OpenSim.Region.Physics.BulletSPlugin {
34 34
35[StructLayout(LayoutKind.Sequential)]
35public struct ConvexHull 36public struct ConvexHull
36{ 37{
37 Vector3 Offset; 38 Vector3 Offset;
38 int VertexCount; 39 int VertexCount;
39 Vector3[] Vertices; 40 Vector3[] Vertices;
40} 41}
42[StructLayout(LayoutKind.Sequential)]
41public struct ShapeData 43public struct ShapeData
42{ 44{
43 public enum PhysicsShapeType 45 public enum PhysicsShapeType
@@ -49,6 +51,7 @@ public struct ShapeData
49 SHAPE_SPHERE = 4, 51 SHAPE_SPHERE = 4,
50 SHAPE_HULL = 5 52 SHAPE_HULL = 5
51 }; 53 };
54 // note that bools are passed as ints since bool size changes by language
52 public const int numericTrue = 1; 55 public const int numericTrue = 1;
53 public const int numericFalse = 0; 56 public const int numericFalse = 0;
54 public uint ID; 57 public uint ID;
@@ -60,11 +63,12 @@ public struct ShapeData
60 public float Mass; 63 public float Mass;
61 public float Buoyancy; 64 public float Buoyancy;
62 public System.UInt64 MeshKey; 65 public System.UInt64 MeshKey;
63 public int Collidable;
64 public float Friction; 66 public float Friction;
67 public float Restitution;
68 public int Collidable;
65 public int Static; // true if a static object. Otherwise gravity, etc. 69 public int Static; // true if a static object. Otherwise gravity, etc.
66 // note that bools are passed as ints since bool size changes by language
67} 70}
71[StructLayout(LayoutKind.Sequential)]
68public struct SweepHit 72public struct SweepHit
69{ 73{
70 public uint ID; 74 public uint ID;
@@ -72,12 +76,14 @@ public struct SweepHit
72 public Vector3 Normal; 76 public Vector3 Normal;
73 public Vector3 Point; 77 public Vector3 Point;
74} 78}
79[StructLayout(LayoutKind.Sequential)]
75public struct RaycastHit 80public struct RaycastHit
76{ 81{
77 public uint ID; 82 public uint ID;
78 public float Fraction; 83 public float Fraction;
79 public Vector3 Normal; 84 public Vector3 Normal;
80} 85}
86[StructLayout(LayoutKind.Sequential)]
81public struct CollisionDesc 87public struct CollisionDesc
82{ 88{
83 public uint aID; 89 public uint aID;
@@ -85,6 +91,7 @@ public struct CollisionDesc
85 public Vector3 point; 91 public Vector3 point;
86 public Vector3 normal; 92 public Vector3 normal;
87} 93}
94[StructLayout(LayoutKind.Sequential)]
88public struct EntityProperties 95public struct EntityProperties
89{ 96{
90 public uint ID; 97 public uint ID;
@@ -92,13 +99,42 @@ public struct EntityProperties
92 public Quaternion Rotation; 99 public Quaternion Rotation;
93 public Vector3 Velocity; 100 public Vector3 Velocity;
94 public Vector3 Acceleration; 101 public Vector3 Acceleration;
95 public Vector3 AngularVelocity; 102 public Vector3 RotationalVelocity;
103}
104
105// Format of this structure must match the definition in the C++ code
106[StructLayout(LayoutKind.Sequential)]
107public struct ConfigurationParameters
108{
109 public float defaultFriction;
110 public float defaultDensity;
111 public float defaultRestitution;
112 public float collisionMargin;
113 public float gravity;
114
115 public float linearDamping;
116 public float angularDamping;
117 public float deactivationTime;
118 public float linearSleepingThreshold;
119 public float angularSleepingThreshold;
120 public float ccdMotionThreshold;
121 public float ccdSweptSphereRadius;
122
123 public float terrainFriction;
124 public float terrainHitFriction;
125 public float terrainRestitution;
126 public float avatarFriction;
127 public float avatarDensity;
128 public float avatarRestitution;
129 public float avatarCapsuleRadius;
130 public float avatarCapsuleHeight;
96} 131}
97 132
98static class BulletSimAPI { 133static class BulletSimAPI {
99 134
100[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 135[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
101public static extern uint Initialize(Vector3 maxPosition, int maxCollisions, IntPtr collisionArray, 136public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
137 int maxCollisions, IntPtr collisionArray,
102 int maxUpdates, IntPtr updateArray); 138 int maxUpdates, IntPtr updateArray);
103 139
104[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 140[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]