diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 140 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 86 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 18 |
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 | 81 | public struct CollisionDesc | |
82 | { | ||
83 | public uint aID; | ||
84 | public uint bID; | ||
85 | public Vector3 point; | ||
86 | public Vector3 normal; | ||
87 | } | ||
82 | public struct EntityProperties | 88 | public struct EntityProperties |
83 | { | 89 | { |
84 | public uint ID; | 90 | public uint ID; |
@@ -92,7 +98,8 @@ public struct EntityProperties | |||
92 | static class BulletSimAPI { | 98 | static class BulletSimAPI { |
93 | 99 | ||
94 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 100 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
95 | public static extern uint Initialize(Vector3 maxPosition); | 101 | public 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] |
98 | public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); | 105 | public 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] |
126 | public static extern void AddConstraint(uint worldID, uint id1, uint id2, | 133 | public 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] | ||
139 | public static extern bool RemoveConstraintByID(uint worldID, uint id1); | ||
128 | 140 | ||
129 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 141 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
130 | public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); | 142 | public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); |