aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorRobert.Adams2011-07-22 10:22:21 -0700
committerDan Lake2011-07-22 10:23:40 -0700
commit5ffec1cd648bc8dcc333fc528707c09bb8dce27d (patch)
treea9c6be19df834d4d53eeff7dec267b75d4c7bacb /OpenSim/Region/Physics
parentMerge branch 'master' into bulletsim (diff)
downloadopensim-SC_OLD-5ffec1cd648bc8dcc333fc528707c09bb8dce27d.zip
opensim-SC_OLD-5ffec1cd648bc8dcc333fc528707c09bb8dce27d.tar.gz
opensim-SC_OLD-5ffec1cd648bc8dcc333fc528707c09bb8dce27d.tar.bz2
opensim-SC_OLD-5ffec1cd648bc8dcc333fc528707c09bb8dce27d.tar.xz
Pass collisions and updates in pinned memory (saves marshaling).
Fix folding feet by using collision normals. Add constraint specification.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs5
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs140
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs86
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs18
4 files changed, 151 insertions, 98 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index d9e236f..dbd7285 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -185,7 +185,7 @@ public class BSCharacter : PhysicsActor
185 get { return _force; } 185 get { return _force; }
186 set { 186 set {
187 _force = value; 187 _force = value;
188 m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); 188 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
189 _scene.TaintedObject(delegate() 189 _scene.TaintedObject(delegate()
190 { 190 {
191 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 191 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
@@ -411,8 +411,9 @@ public class BSCharacter : PhysicsActor
411 _collidingGroundStep = _scene.SimulationStep; 411 _collidingGroundStep = _scene.SimulationStep;
412 } 412 }
413 413
414 // throttle collisions to the rate specified in the subscription
414 if (_subscribedEventsMs == 0) return; // don't want collisions 415 if (_subscribedEventsMs == 0) return; // don't want collisions
415 int nowTime = Util.EnvironmentTickCount(); 416 int nowTime = _scene.SimulationNowTime;
416 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; 417 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
417 _lastCollisionTime = nowTime; 418 _lastCollisionTime = nowTime;
418 419
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 82a8803..f2ab2d9 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -261,6 +261,7 @@ public sealed class BSPrim : PhysicsActor
261 { 261 {
262 if (_childrenPrims.Contains(child)) 262 if (_childrenPrims.Contains(child))
263 { 263 {
264 BulletSimAPI.RemoveConstraint(_scene.WorldID, child.LocalID, this.LocalID);
264 _childrenPrims.Remove(child); 265 _childrenPrims.Remove(child);
265 child.ParentPrim = null; // the child has lost its parent 266 child.ParentPrim = null; // the child has lost its parent
266 RecreateGeomAndObject(); // rebuild my shape with the child removed 267 RecreateGeomAndObject(); // rebuild my shape with the child removed
@@ -1018,47 +1019,8 @@ public sealed class BSPrim : PhysicsActor
1018 if (IsRootOfLinkset) 1019 if (IsRootOfLinkset)
1019 { 1020 {
1020 // Create a linkset around this object 1021 // Create a linkset around this object
1021 /* 1022 CreateLinksetWithCompoundHull();
1022 * NOTE: the original way of creating a linkset was to create a compound hull in the 1023 // CreateLinksetWithConstraints();
1023 * root which consisted of the hulls of all the children. This didn't work well because
1024 * OpenSimulator needs updates and collisions for all the children and the physics
1025 * engine didn't create events for the children when the root hull was moved.
1026 * This code creates the compound hull.
1027 // If I am the root prim of a linkset, replace my physical shape with all the
1028 // pieces of the children.
1029 // All of the children should have called CreateGeom so they have a hull
1030 // in the physics engine already. Here we pull together all of those hulls
1031 // into one shape.
1032 int totalPrimsInLinkset = _childrenPrims.Count + 1;
1033 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset);
1034 ShapeData[] shapes = new ShapeData[totalPrimsInLinkset];
1035 FillShapeInfo(out shapes[0]);
1036 int ii = 1;
1037 foreach (BSPrim prim in _childrenPrims)
1038 {
1039 // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID);
1040 prim.FillShapeInfo(out shapes[ii]);
1041 ii++;
1042 }
1043 BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
1044 */
1045 // Create the linkset by putting constraints between the objects of the set so they cannot move
1046 // relative to each other.
1047 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
1048
1049 // remove any constraints that might be in place
1050 foreach (BSPrim prim in _childrenPrims)
1051 {
1052 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
1053 }
1054 // create constraints between the root prim and each of the children
1055 foreach (BSPrim prim in _childrenPrims)
1056 {
1057 // this is a constraint that allows no freedom of movement between the two objects
1058 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1059 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, OMV.Vector3.Zero, OMV.Vector3.Zero,
1060 OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero);
1061 }
1062 } 1024 }
1063 else 1025 else
1064 { 1026 {
@@ -1070,6 +1032,73 @@ public sealed class BSPrim : PhysicsActor
1070 } 1032 }
1071 } 1033 }
1072 1034
1035 // Create a linkset by creating a compound hull at the root prim that consists of all
1036 // the children.
1037 void CreateLinksetWithCompoundHull()
1038 {
1039 // If I am the root prim of a linkset, replace my physical shape with all the
1040 // pieces of the children.
1041 // All of the children should have called CreateGeom so they have a hull
1042 // in the physics engine already. Here we pull together all of those hulls
1043 // into one shape.
1044 int totalPrimsInLinkset = _childrenPrims.Count + 1;
1045 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset);
1046 ShapeData[] shapes = new ShapeData[totalPrimsInLinkset];
1047 FillShapeInfo(out shapes[0]);
1048 int ii = 1;
1049 foreach (BSPrim prim in _childrenPrims)
1050 {
1051 // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID);
1052 prim.FillShapeInfo(out shapes[ii]);
1053 ii++;
1054 }
1055 BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
1056 }
1057
1058 // Create the linkset by putting constraints between the objects of the set so they cannot move
1059 // relative to each other.
1060 void CreateLinksetWithConstraints()
1061 {
1062 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
1063
1064 // remove any constraints that might be in place
1065 foreach (BSPrim prim in _childrenPrims)
1066 {
1067 // m_log.DebugFormat("{0}: CreateObject: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1068 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
1069 }
1070 // create constraints between the root prim and each of the children
1071 foreach (BSPrim prim in _childrenPrims)
1072 {
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);
1076
1077 // relative position normalized to the root prim
1078 OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation);
1079 // OMV.Quaternion relativeRotation = OMV.Quaternion.Identity;
1080
1081 // rotation is pointing up the vector between the object centers
1082 OMV.Quaternion relativeRotation = OMV.Quaternion.CreateFromAxisAngle(childRelativePosition, 0f);
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
1092 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
1093 childRelativePosition / 2,
1094 relativeRotation,
1095 -childRelativePosition / 2,
1096 relativeRotation,
1097 OMV.Vector3.Zero, OMV.Vector3.Zero,
1098 OMV.Vector3.Zero, OMV.Vector3.Zero);
1099 }
1100 }
1101
1073 // Copy prim's info into the BulletSim shape description structure 1102 // Copy prim's info into the BulletSim shape description structure
1074 public void FillShapeInfo(out ShapeData shape) 1103 public void FillShapeInfo(out ShapeData shape)
1075 { 1104 {
@@ -1118,50 +1147,53 @@ public sealed class BSPrim : PhysicsActor
1118 // The physics engine says that properties have updated. Update same and inform 1147 // The physics engine says that properties have updated. Update same and inform
1119 // the world that things have changed. 1148 // the world that things have changed.
1120 // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() 1149 // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate()
1121 private int UpPropPosition = 1 << 0; 1150 enum UpdatedProperties {
1122 private int UpPropRotation = 1 << 1; 1151 Position = 1 << 0,
1123 private int UpPropVelocity = 1 << 2; 1152 Rotation = 1 << 1,
1124 private int UpPropAcceleration = 1 << 3; 1153 Velocity = 1 << 2,
1125 private int UpPropAngularVel = 1 << 4; 1154 Acceleration = 1 << 3,
1155 AngularVel = 1 << 4
1156 }
1126 1157
1127 public void UpdateProperties(EntityProperties entprop) 1158 public void UpdateProperties(EntityProperties entprop)
1128 { 1159 {
1129 int changed = 0; 1160 UpdatedProperties changed = 0;
1130 // assign to the local variables so the normal set action does not happen 1161 // assign to the local variables so the normal set action does not happen
1131 if (_position != entprop.Position) 1162 if (_position != entprop.Position)
1132 { 1163 {
1133 _position = entprop.Position; 1164 _position = entprop.Position;
1134 // m_log.DebugFormat("{0}: UpdateProperties: position = {1}", LogHeader, _position); 1165 // m_log.DebugFormat("{0}: UpdateProperties: position = {1}", LogHeader, _position);
1135 changed |= UpPropPosition; 1166 changed |= UpdatedProperties.Position;
1136 } 1167 }
1137 if (_orientation != entprop.Rotation) 1168 if (_orientation != entprop.Rotation)
1138 { 1169 {
1139 _orientation = entprop.Rotation; 1170 _orientation = entprop.Rotation;
1140 // m_log.DebugFormat("{0}: UpdateProperties: rotation = {1}", LogHeader, _orientation); 1171 // m_log.DebugFormat("{0}: UpdateProperties: rotation = {1}", LogHeader, _orientation);
1141 changed |= UpPropRotation; 1172 changed |= UpdatedProperties.Rotation;
1142 } 1173 }
1143 if (_velocity != entprop.Velocity) 1174 if (_velocity != entprop.Velocity)
1144 { 1175 {
1145 _velocity = entprop.Velocity; 1176 _velocity = entprop.Velocity;
1146 // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity); 1177 // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
1147 changed |= UpPropVelocity; 1178 changed |= UpdatedProperties.Velocity;
1148 } 1179 }
1149 if (_acceleration != entprop.Acceleration) 1180 if (_acceleration != entprop.Acceleration)
1150 { 1181 {
1151 _acceleration = entprop.Acceleration; 1182 _acceleration = entprop.Acceleration;
1152 // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration); 1183 // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
1153 changed |= UpPropAcceleration; 1184 changed |= UpdatedProperties.Acceleration;
1154 } 1185 }
1155 if (_rotationalVelocity != entprop.AngularVelocity) 1186 if (_rotationalVelocity != entprop.AngularVelocity)
1156 { 1187 {
1157 _rotationalVelocity = entprop.AngularVelocity; 1188 _rotationalVelocity = entprop.AngularVelocity;
1158 // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); 1189 // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity);
1159 changed |= UpPropAngularVel; 1190 changed |= UpdatedProperties.AngularVel;
1160 } 1191 }
1161 if (changed != 0) 1192 if (changed != 0)
1162 { 1193 {
1163 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); 1194 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1164 base.RequestPhysicsterseUpdate(); 1195 if (this._parentPrim == null)
1196 base.RequestPhysicsterseUpdate();
1165 } 1197 }
1166 } 1198 }
1167 1199
@@ -1178,7 +1210,7 @@ public sealed class BSPrim : PhysicsActor
1178 1210
1179 if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events 1211 if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events
1180 // throttle the collisions to the number of milliseconds specified in the subscription 1212 // throttle the collisions to the number of milliseconds specified in the subscription
1181 int nowTime = Util.EnvironmentTickCount(); 1213 int nowTime = _scene.SimulationNowTime;
1182 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; 1214 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
1183 _lastCollisionTime = nowTime; 1215 _lastCollisionTime = nowTime;
1184 1216
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index beffd21..062945f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -38,9 +38,7 @@ using OpenSim.Region.Framework;
38 38
39// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) 39// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
40// Fix folding up feet 40// Fix folding up feet
41// Fix terrain. Only flat terrain works. Terrain with shape is oriented wrong? Origined wrong?
42// Parameterize BulletSim. Pass a structure of parameters to the C++ code. Capsule size, friction, ... 41// Parameterize BulletSim. Pass a structure of parameters to the C++ code. Capsule size, friction, ...
43// Shift drag duplication of objects does not work
44// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) 42// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
45// Test sculpties 43// Test sculpties
46// Compute physics FPS reasonably 44// Compute physics FPS reasonably
@@ -82,6 +80,19 @@ public class BSScene : PhysicsScene
82 private long m_simulationStep = 0; 80 private long m_simulationStep = 0;
83 public long SimulationStep { get { return m_simulationStep; } } 81 public long SimulationStep { get { return m_simulationStep; } }
84 82
83 // A value of the time now so all the collision and update routines do not have to get their own
84 // Set to 'now' just before all the prims and actors are called for collisions and updates
85 private int m_simulationNowTime;
86 public int SimulationNowTime { get { return m_simulationNowTime; } }
87
88 private int m_maxCollisionsPerFrame = 2048;
89 private CollisionDesc[] m_collisionArray;
90 private GCHandle m_collisionArrayPinnedHandle;
91
92 private int m_maxUpdatesPerFrame = 2048;
93 private EntityProperties[] m_updateArray;
94 private GCHandle m_updateArrayPinnedHandle;
95
85 private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed 96 private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed
86 private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes 97 private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes
87 public float maximumMassObject = 10000.01f; 98 public float maximumMassObject = 10000.01f;
@@ -129,8 +140,19 @@ public class BSScene : PhysicsScene
129 _taintedObjects = new List<TaintCallback>(); 140 _taintedObjects = new List<TaintCallback>();
130 141
131 mesher = meshmerizer; 142 mesher = meshmerizer;
143 // The bounding box for the simulated world
144 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f);
145
146 // Allocate pinned memory to pass back object property updates and collisions from simulation step
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
132 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 152 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
133 m_worldID = BulletSimAPI.Initialize(new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f)); 153 m_worldID = BulletSimAPI.Initialize(worldExtent,
154 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
155 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject());
134 } 156 }
135 157
136 // Called directly from unmanaged code so don't do much 158 // Called directly from unmanaged code so don't do much
@@ -188,19 +210,7 @@ public class BSScene : PhysicsScene
188 } 210 }
189 211
190 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 212 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
191 Vector3 size, Quaternion rotation) // deprecated 213 Vector3 size, Quaternion rotation, bool isPhysical, uint localID)
192 {
193 return null;
194 }
195 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
196 Vector3 size, Quaternion rotation, bool isPhysical)
197 {
198 m_log.ErrorFormat("{0}: CALL TO AddPrimShape in BSScene. NOT IMPLEMENTED", LogHeader);
199 return null;
200 }
201
202 public override PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position,
203 Vector3 size, Quaternion rotation, bool isPhysical)
204 { 214 {
205 // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); 215 // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName);
206 IMesh mesh = null; 216 IMesh mesh = null;
@@ -225,10 +235,8 @@ public class BSScene : PhysicsScene
225 { 235 {
226 int updatedEntityCount; 236 int updatedEntityCount;
227 IntPtr updatedEntitiesPtr; 237 IntPtr updatedEntitiesPtr;
228 IntPtr[] updatedEntities;
229 int collidersCount; 238 int collidersCount;
230 IntPtr collidersPtr; 239 IntPtr collidersPtr;
231 int[] colliders; // should be uint but Marshal.Copy does not have that overload
232 240
233 // update the prim states while we know the physics engine is not busy 241 // update the prim states while we know the physics engine is not busy
234 ProcessTaints(); 242 ProcessTaints();
@@ -242,32 +250,33 @@ public class BSScene : PhysicsScene
242 int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 250 int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
243 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 251 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
244 252
245 // if there were collisions, they show up here 253 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
254
255 // Get a value for 'now' so all the collision and update routines don't have to get their own
256 m_simulationNowTime = Util.EnvironmentTickCount();
257
258 // If there were collisions, process them by sending the event to the prim.
259 // Collisions must be processed before updates.
246 if (collidersCount > 0) 260 if (collidersCount > 0)
247 { 261 {
248 colliders = new int[collidersCount]; 262 for (int ii = 0; ii < collidersCount; ii++)
249 Marshal.Copy(collidersPtr, colliders, 0, collidersCount);
250 for (int ii = 0; ii < collidersCount; ii+=2)
251 { 263 {
252 uint cA = (uint)colliders[ii]; 264 uint cA = m_collisionArray[ii].aID;
253 uint cB = (uint)colliders[ii+1]; 265 uint cB = m_collisionArray[ii].bID;
254 SendCollision(cA, cB); 266 Vector3 point = m_collisionArray[ii].point;
255 SendCollision(cB, cA); 267 Vector3 normal = m_collisionArray[ii].normal;
268 SendCollision(cA, cB, point, normal, 0.01f);
269 SendCollision(cB, cA, point, -normal, 0.01f);
256 } 270 }
257 } 271 }
258 272
259 // if any of the objects had updated properties, they are returned in the updatedEntity structure 273 // If any of the objects had updated properties, tell the object it has been changed by the physics engine
260 // TODO: figure out how to pass all of the EntityProperties structures in one marshal call.
261 if (updatedEntityCount > 0) 274 if (updatedEntityCount > 0)
262 { 275 {
263 updatedEntities = new IntPtr[updatedEntityCount];
264 // fetch all the pointers to all the EntityProperties structures for these updates
265 Marshal.Copy(updatedEntitiesPtr, updatedEntities, 0, updatedEntityCount);
266 for (int ii = 0; ii < updatedEntityCount; ii++) 276 for (int ii = 0; ii < updatedEntityCount; ii++)
267 { 277 {
268 IntPtr updatePointer = updatedEntities[ii]; 278 EntityProperties entprop = m_updateArray[ii];
269 EntityProperties entprop = (EntityProperties)Marshal.PtrToStructure(updatePointer, typeof(EntityProperties)); 279 // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position);
270 // m_log.DebugFormat("{0}: entprop: id={1}, pos={2}", LogHeader, entprop.ID, entprop.Position);
271 BSCharacter actor; 280 BSCharacter actor;
272 if (m_avatars.TryGetValue(entprop.ID, out actor)) 281 if (m_avatars.TryGetValue(entprop.ID, out actor))
273 { 282 {
@@ -282,12 +291,12 @@ public class BSScene : PhysicsScene
282 } 291 }
283 } 292 }
284 293
285 // fps calculation wrong. This calculation returns about 1 in normal operation. 294 // fps calculation wrong. This calculation always returns about 1 in normal operation.
286 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 295 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
287 } 296 }
288 297
289 // Something has collided 298 // Something has collided
290 private void SendCollision(uint localID, uint collidingWith) 299 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration)
291 { 300 {
292 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) 301 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
293 { 302 {
@@ -303,12 +312,12 @@ public class BSScene : PhysicsScene
303 312
304 BSPrim prim; 313 BSPrim prim;
305 if (m_prims.TryGetValue(localID, out prim)) { 314 if (m_prims.TryGetValue(localID, out prim)) {
306 prim.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f); 315 prim.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f);
307 return; 316 return;
308 } 317 }
309 BSCharacter actor; 318 BSCharacter actor;
310 if (m_avatars.TryGetValue(localID, out actor)) { 319 if (m_avatars.TryGetValue(localID, out actor)) {
311 actor.Collide(collidingWith, type, Vector3.Zero, Vector3.UnitZ, 0.01f); 320 actor.Collide(collidingWith, type, collidePoint, collideNormal, 0.01f);
312 return; 321 return;
313 } 322 }
314 return; 323 return;
@@ -317,7 +326,6 @@ public class BSScene : PhysicsScene
317 public override void GetResults() { } 326 public override void GetResults() { }
318 327
319 public override void SetTerrain(float[] heightMap) { 328 public override void SetTerrain(float[] heightMap) {
320 m_log.DebugFormat("{0}: SetTerrain", LogHeader);
321 m_heightMap = heightMap; 329 m_heightMap = heightMap;
322 this.TaintedObject(delegate() 330 this.TaintedObject(delegate()
323 { 331 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index b2bc0d7..ace8158 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -78,7 +78,13 @@ public struct RaycastHit
78 public float Fraction; 78 public float Fraction;
79 public Vector3 Normal; 79 public Vector3 Normal;
80} 80}
81 81public struct CollisionDesc
82{
83 public uint aID;
84 public uint bID;
85 public Vector3 point;
86 public Vector3 normal;
87}
82public struct EntityProperties 88public struct EntityProperties
83{ 89{
84 public uint ID; 90 public uint ID;
@@ -92,7 +98,8 @@ public struct EntityProperties
92static class BulletSimAPI { 98static class BulletSimAPI {
93 99
94[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 100[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
95public static extern uint Initialize(Vector3 maxPosition); 101public static extern uint Initialize(Vector3 maxPosition, int maxCollisions, IntPtr collisionArray,
102 int maxUpdates, IntPtr updateArray);
96 103
97[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 104[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
98public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); 105public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
@@ -124,7 +131,12 @@ public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData
124 131
125[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 132[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
126public static extern void AddConstraint(uint worldID, uint id1, uint id2, 133public static extern void AddConstraint(uint worldID, uint id1, uint id2,
127 Vector3 frame1, Vector3 frame2, Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular); 134 Vector3 frame1, Quaternion frame1rot,
135 Vector3 frame2, Quaternion frame2rot,
136 Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular);
137
138[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
139public static extern bool RemoveConstraintByID(uint worldID, uint id1);
128 140
129[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 141[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
130public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); 142public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);