diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 140 |
1 files changed, 86 insertions, 54 deletions
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 | ||