diff options
Diffstat (limited to 'OpenSim/Region')
9 files changed, 868 insertions, 109 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index 9daf9d7..ff4afbf 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs | |||
@@ -66,6 +66,7 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
66 | public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType"; | 66 | public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType"; |
67 | public const string PhysFunctGetLinkType = "BulletSim.GetLinkType"; | 67 | public const string PhysFunctGetLinkType = "BulletSim.GetLinkType"; |
68 | public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; | 68 | public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; |
69 | public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits"; | ||
69 | 70 | ||
70 | // ============================================================= | 71 | // ============================================================= |
71 | 72 | ||
@@ -176,6 +177,71 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
176 | return ret; | 177 | return ret; |
177 | } | 178 | } |
178 | 179 | ||
180 | // Code for specifying params. | ||
181 | // The choice if 14700 is arbitrary and only serves to catch parameter code misuse. | ||
182 | [ScriptConstant] | ||
183 | public const int PHYS_AXIS_LOCK_LINEAR = 14700; | ||
184 | [ScriptConstant] | ||
185 | public const int PHYS_AXIS_LOCK_LINEAR_X = 14701; | ||
186 | [ScriptConstant] | ||
187 | public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702; | ||
188 | [ScriptConstant] | ||
189 | public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703; | ||
190 | [ScriptConstant] | ||
191 | public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704; | ||
192 | [ScriptConstant] | ||
193 | public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705; | ||
194 | [ScriptConstant] | ||
195 | public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706; | ||
196 | [ScriptConstant] | ||
197 | public const int PHYS_AXIS_LOCK_ANGULAR = 14707; | ||
198 | [ScriptConstant] | ||
199 | public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708; | ||
200 | [ScriptConstant] | ||
201 | public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709; | ||
202 | [ScriptConstant] | ||
203 | public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710; | ||
204 | [ScriptConstant] | ||
205 | public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711; | ||
206 | [ScriptConstant] | ||
207 | public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712; | ||
208 | [ScriptConstant] | ||
209 | public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713; | ||
210 | [ScriptConstant] | ||
211 | public const int PHYS_AXIS_UNLOCK_LINEAR = 14714; | ||
212 | [ScriptConstant] | ||
213 | public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715; | ||
214 | [ScriptConstant] | ||
215 | public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716; | ||
216 | [ScriptConstant] | ||
217 | public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717; | ||
218 | [ScriptConstant] | ||
219 | public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718; | ||
220 | [ScriptConstant] | ||
221 | public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719; | ||
222 | [ScriptConstant] | ||
223 | public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720; | ||
224 | [ScriptConstant] | ||
225 | public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721; | ||
226 | [ScriptConstant] | ||
227 | public const int PHYS_AXIS_UNLOCK = 14722; | ||
228 | // physAxisLockLimits() | ||
229 | [ScriptInvocation] | ||
230 | public int physAxisLock(UUID hostID, UUID scriptID, object[] parms) | ||
231 | { | ||
232 | int ret = -1; | ||
233 | if (!Enabled) return ret; | ||
234 | |||
235 | PhysicsActor rootPhysActor; | ||
236 | if (GetRootPhysActor(hostID, out rootPhysActor)) | ||
237 | { | ||
238 | object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms); | ||
239 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2)); | ||
240 | } | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
179 | [ScriptConstant] | 245 | [ScriptConstant] |
180 | public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0; | 246 | public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0; |
181 | [ScriptConstant] | 247 | [ScriptConstant] |
@@ -187,7 +253,6 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
187 | public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) | 253 | public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) |
188 | { | 254 | { |
189 | int ret = -1; | 255 | int ret = -1; |
190 | |||
191 | if (!Enabled) return ret; | 256 | if (!Enabled) return ret; |
192 | 257 | ||
193 | // The part that is requesting the change. | 258 | // The part that is requesting the change. |
@@ -259,34 +324,11 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
259 | int ret = -1; | 324 | int ret = -1; |
260 | if (!Enabled) return ret; | 325 | if (!Enabled) return ret; |
261 | 326 | ||
262 | // The part that is requesting the change. | 327 | PhysicsActor rootPhysActor; |
263 | SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); | 328 | if (GetRootPhysActor(hostID, out rootPhysActor)) |
264 | |||
265 | if (requestingPart != null) | ||
266 | { | 329 | { |
267 | // The type is is always on the root of a linkset. | 330 | object[] parms2 = { rootPhysActor, null }; |
268 | SceneObjectGroup containingGroup = requestingPart.ParentGroup; | 331 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2)); |
269 | SceneObjectPart rootPart = containingGroup.RootPart; | ||
270 | |||
271 | if (rootPart != null) | ||
272 | { | ||
273 | PhysicsActor rootPhysActor = rootPart.PhysActor; | ||
274 | if (rootPhysActor != null) | ||
275 | { | ||
276 | object[] parms2 = { rootPhysActor, null }; | ||
277 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2)); | ||
278 | } | ||
279 | else | ||
280 | { | ||
281 | m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}", | ||
282 | LogHeader, rootPart.Name, hostID); | ||
283 | } | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}", | ||
288 | LogHeader, requestingPart.Name, hostID); | ||
289 | } | ||
290 | } | 332 | } |
291 | else | 333 | else |
292 | { | 334 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs index 7e61007..48cab64 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs | |||
@@ -37,12 +37,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
37 | public class BSActorLockAxis : BSActor | 37 | public class BSActorLockAxis : BSActor |
38 | { | 38 | { |
39 | BSConstraint LockAxisConstraint = null; | 39 | BSConstraint LockAxisConstraint = null; |
40 | // The lock access flags (which axises were locked) when the contraint was built. | ||
41 | // Used to see if locking has changed since when the constraint was built. | ||
42 | OMV.Vector3 LockAxisLinearFlags; | ||
43 | OMV.Vector3 LockAxisAngularFlags; | ||
40 | 44 | ||
41 | public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) | 45 | public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) |
42 | : base(physicsScene, pObj, actorName) | 46 | : base(physicsScene, pObj, actorName) |
43 | { | 47 | { |
44 | m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); | 48 | m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); |
45 | LockAxisConstraint = null; | 49 | LockAxisConstraint = null; |
50 | |||
51 | // we place our constraint just before the simulation step to make sure the linkset is complete | ||
52 | m_physicsScene.BeforeStep += PhysicsScene_BeforeStep; | ||
46 | } | 53 | } |
47 | 54 | ||
48 | // BSActor.isActive | 55 | // BSActor.isActive |
@@ -55,6 +62,7 @@ public class BSActorLockAxis : BSActor | |||
55 | // BSActor.Dispose() | 62 | // BSActor.Dispose() |
56 | public override void Dispose() | 63 | public override void Dispose() |
57 | { | 64 | { |
65 | m_physicsScene.BeforeStep -= PhysicsScene_BeforeStep; | ||
58 | RemoveAxisLockConstraint(); | 66 | RemoveAxisLockConstraint(); |
59 | } | 67 | } |
60 | 68 | ||
@@ -63,10 +71,18 @@ public class BSActorLockAxis : BSActor | |||
63 | // BSActor.Refresh() | 71 | // BSActor.Refresh() |
64 | public override void Refresh() | 72 | public override void Refresh() |
65 | { | 73 | { |
66 | m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}", | 74 | // Since the axis logging is done with a constraint, Refresh() time is good for |
67 | m_controllingPrim.LocalID, m_controllingPrim.LockedAngularAxis, Enabled, m_controllingPrim.IsPhysicallyActive); | 75 | // changing parameters but this needs to wait until the prim/linkset is physically |
76 | // constructed. Therefore, the constraint itself is placed at pre-step time. | ||
77 | /* | ||
78 | m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedLinear={1},lockedAngular={2},enabled={3},pActive={4}", | ||
79 | m_controllingPrim.LocalID, | ||
80 | m_controllingPrim.LockedLinearAxis, | ||
81 | m_controllingPrim.LockedAngularAxis, | ||
82 | Enabled, m_controllingPrim.IsPhysicallyActive); | ||
68 | // If all the axis are free, we don't need to exist | 83 | // If all the axis are free, we don't need to exist |
69 | if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree) | 84 | if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree |
85 | && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree) | ||
70 | { | 86 | { |
71 | Enabled = false; | 87 | Enabled = false; |
72 | } | 88 | } |
@@ -74,12 +90,21 @@ public class BSActorLockAxis : BSActor | |||
74 | // If the object is physically active, add the axis locking constraint | 90 | // If the object is physically active, add the axis locking constraint |
75 | if (isActive) | 91 | if (isActive) |
76 | { | 92 | { |
93 | // Check to see if the locking parameters have changed | ||
94 | if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags | ||
95 | || m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags) | ||
96 | { | ||
97 | // The locking has changed. Remove the old constraint and build a new one | ||
98 | RemoveAxisLockConstraint(); | ||
99 | } | ||
100 | |||
77 | AddAxisLockConstraint(); | 101 | AddAxisLockConstraint(); |
78 | } | 102 | } |
79 | else | 103 | else |
80 | { | 104 | { |
81 | RemoveAxisLockConstraint(); | 105 | RemoveAxisLockConstraint(); |
82 | } | 106 | } |
107 | */ | ||
83 | } | 108 | } |
84 | 109 | ||
85 | // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...). | 110 | // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...). |
@@ -88,15 +113,35 @@ public class BSActorLockAxis : BSActor | |||
88 | // BSActor.RemoveDependencies() | 113 | // BSActor.RemoveDependencies() |
89 | public override void RemoveDependencies() | 114 | public override void RemoveDependencies() |
90 | { | 115 | { |
91 | if (LockAxisConstraint != null) | 116 | RemoveAxisLockConstraint(); |
117 | // The pre-step action will restore the constraint of needed | ||
118 | } | ||
119 | |||
120 | private void PhysicsScene_BeforeStep(float timestep) | ||
121 | { | ||
122 | // If all the axis are free, we don't need to exist | ||
123 | if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree | ||
124 | && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree) | ||
92 | { | 125 | { |
93 | // If a constraint is set up, remove it from the physical scene | 126 | Enabled = false; |
94 | RemoveAxisLockConstraint(); | 127 | } |
95 | // Schedule a call before the next simulation step to restore the constraint. | 128 | |
96 | m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate() | 129 | // If the object is physically active, add the axis locking constraint |
130 | if (isActive) | ||
131 | { | ||
132 | // Check to see if the locking parameters have changed | ||
133 | if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags | ||
134 | || m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags) | ||
97 | { | 135 | { |
98 | Refresh(); | 136 | // The locking has changed. Remove the old constraint and build a new one |
99 | }); | 137 | RemoveAxisLockConstraint(); |
138 | } | ||
139 | |||
140 | AddAxisLockConstraint(); | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | RemoveAxisLockConstraint(); | ||
100 | } | 145 | } |
101 | } | 146 | } |
102 | 147 | ||
@@ -118,56 +163,30 @@ public class BSActorLockAxis : BSActor | |||
118 | LockAxisConstraint = axisConstrainer; | 163 | LockAxisConstraint = axisConstrainer; |
119 | m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); | 164 | m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); |
120 | 165 | ||
166 | // Remember the clocking being inforced so we can notice if they have changed | ||
167 | LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis; | ||
168 | LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis; | ||
169 | |||
121 | // The constraint is tied to the world and oriented to the prim. | 170 | // The constraint is tied to the world and oriented to the prim. |
122 | 171 | ||
123 | // Free to move linearly in the region | 172 | if (!axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh)) |
124 | // OMV.Vector3 linearLow = OMV.Vector3.Zero; | ||
125 | // OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize; | ||
126 | OMV.Vector3 linearLow = new OMV.Vector3(-10000f, -10000f, -10000f); | ||
127 | OMV.Vector3 linearHigh = new OMV.Vector3(10000f, 10000f, 10000f); | ||
128 | if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis) | ||
129 | { | ||
130 | linearLow.X = m_controllingPrim.RawPosition.X; | ||
131 | linearHigh.X = m_controllingPrim.RawPosition.X; | ||
132 | } | ||
133 | if (m_controllingPrim.LockedLinearAxis.Y != BSPhysObject.FreeAxis) | ||
134 | { | 173 | { |
135 | linearLow.Y = m_controllingPrim.RawPosition.Y; | 174 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits", |
136 | linearHigh.Y = m_controllingPrim.RawPosition.Y; | 175 | m_controllingPrim.LocalID); |
137 | } | 176 | } |
138 | if (m_controllingPrim.LockedLinearAxis.Z != BSPhysObject.FreeAxis) | ||
139 | { | ||
140 | linearLow.Z = m_controllingPrim.RawPosition.Z; | ||
141 | linearHigh.Z = m_controllingPrim.RawPosition.Z; | ||
142 | } | ||
143 | axisConstrainer.SetLinearLimits(linearLow, linearHigh); | ||
144 | 177 | ||
145 | // Angular with some axis locked | 178 | if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh)) |
146 | float fPI = (float)Math.PI; | ||
147 | OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI); | ||
148 | OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI); | ||
149 | if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis) | ||
150 | { | ||
151 | angularLow.X = 0f; | ||
152 | angularHigh.X = 0f; | ||
153 | } | ||
154 | if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis) | ||
155 | { | ||
156 | angularLow.Y = 0f; | ||
157 | angularHigh.Y = 0f; | ||
158 | } | ||
159 | if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis) | ||
160 | { | ||
161 | angularLow.Z = 0f; | ||
162 | angularHigh.Z = 0f; | ||
163 | } | ||
164 | if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh)) | ||
165 | { | 179 | { |
166 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID); | 180 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", |
181 | m_controllingPrim.LocalID); | ||
167 | } | 182 | } |
168 | 183 | ||
169 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", | 184 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", |
170 | m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh); | 185 | m_controllingPrim.LocalID, |
186 | m_controllingPrim.LockedLinearAxisLow, | ||
187 | m_controllingPrim.LockedLinearAxisHigh, | ||
188 | m_controllingPrim.LockedAngularAxisLow, | ||
189 | m_controllingPrim.LockedAngularAxisHigh); | ||
171 | 190 | ||
172 | // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. | 191 | // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. |
173 | axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); | 192 | axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index b444446..22b3f3f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -201,7 +201,10 @@ public sealed class BSLinksetCompound : BSLinkset | |||
201 | if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) | 201 | if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) |
202 | { | 202 | { |
203 | // Find the physical instance of the child | 203 | // Find the physical instance of the child |
204 | if (LinksetRoot.PhysShape.HasPhysicalShape && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo)) | 204 | if (!RebuildScheduled // if rebuilding, let the rebuild do it |
205 | && !LinksetRoot.IsIncomplete // if waiting for assets or whatever, don't change | ||
206 | && LinksetRoot.PhysShape.HasPhysicalShape // there must be a physical shape assigned | ||
207 | && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo)) | ||
205 | { | 208 | { |
206 | // It is possible that the linkset is still under construction and the child is not yet | 209 | // It is possible that the linkset is still under construction and the child is not yet |
207 | // inserted into the compound shape. A rebuild of the linkset in a pre-step action will | 210 | // inserted into the compound shape. A rebuild of the linkset in a pre-step action will |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 2b744a0..d20d094 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -309,11 +309,20 @@ public abstract class BSPhysObject : PhysicsActor | |||
309 | // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass. | 309 | // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass. |
310 | public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; } | 310 | public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; } |
311 | 311 | ||
312 | public OMV.Vector3 LockedLinearAxis { get; set; } // zero means locked. one means free. | 312 | public OMV.Vector3 LockedLinearAxis; // zero means locked. one means free. |
313 | public OMV.Vector3 LockedAngularAxis { get; set; } // zero means locked. one means free. | 313 | public OMV.Vector3 LockedAngularAxis; // zero means locked. one means free. |
314 | public const float FreeAxis = 1f; | 314 | public const float FreeAxis = 1f; |
315 | public const float LockedAxis = 0f; | ||
315 | public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free | 316 | public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free |
316 | 317 | ||
318 | // If an axis is locked (flagged above) then the limits of that axis are specified here. | ||
319 | // Linear axis limits are relative to the object's starting coordinates. | ||
320 | // Angular limits are limited to -PI to +PI | ||
321 | public OMV.Vector3 LockedLinearAxisLow; | ||
322 | public OMV.Vector3 LockedLinearAxisHigh; | ||
323 | public OMV.Vector3 LockedAngularAxisLow; | ||
324 | public OMV.Vector3 LockedAngularAxisHigh; | ||
325 | |||
317 | // Enable physical actions. Bullet will keep sleeping non-moving physical objects so | 326 | // Enable physical actions. Bullet will keep sleeping non-moving physical objects so |
318 | // they need waking up when parameters are changed. | 327 | // they need waking up when parameters are changed. |
319 | // Called in taint-time!! | 328 | // Called in taint-time!! |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c88a5c2..5d359e8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -34,6 +34,7 @@ using OMV = OpenMetaverse; | |||
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Physics.Manager; | 35 | using OpenSim.Region.Physics.Manager; |
36 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 36 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
37 | using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics | ||
37 | 38 | ||
38 | namespace OpenSim.Region.Physics.BulletSPlugin | 39 | namespace OpenSim.Region.Physics.BulletSPlugin |
39 | { | 40 | { |
@@ -95,11 +96,9 @@ public class BSPrim : BSPhysObject | |||
95 | _isPhysical = pisPhysical; | 96 | _isPhysical = pisPhysical; |
96 | _isVolumeDetect = false; | 97 | _isVolumeDetect = false; |
97 | 98 | ||
98 | // Add a dynamic vehicle to our set of actors that can move this prim. | ||
99 | // PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysScene, this, VehicleActorName)); | ||
100 | |||
101 | _mass = CalculateMass(); | 99 | _mass = CalculateMass(); |
102 | 100 | ||
101 | DetailLog("{0},BSPrim.constructor,pbs={1}", LocalID, BSScene.PrimitiveBaseShapeToString(pbs)); | ||
103 | // DetailLog("{0},BSPrim.constructor,call", LocalID); | 102 | // DetailLog("{0},BSPrim.constructor,call", LocalID); |
104 | // do the actual object creation at taint time | 103 | // do the actual object creation at taint time |
105 | PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate() | 104 | PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate() |
@@ -167,6 +166,7 @@ public class BSPrim : BSPhysObject | |||
167 | public override PrimitiveBaseShape Shape { | 166 | public override PrimitiveBaseShape Shape { |
168 | set { | 167 | set { |
169 | BaseShape = value; | 168 | BaseShape = value; |
169 | DetailLog("{0},BSPrim.changeShape,pbs={1}", LocalID, BSScene.PrimitiveBaseShapeToString(BaseShape)); | ||
170 | PrimAssetState = PrimAssetCondition.Unknown; | 170 | PrimAssetState = PrimAssetCondition.Unknown; |
171 | ForceBodyShapeRebuild(false); | 171 | ForceBodyShapeRebuild(false); |
172 | } | 172 | } |
@@ -285,23 +285,21 @@ public class BSPrim : BSPhysObject | |||
285 | { | 285 | { |
286 | DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); | 286 | DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); |
287 | 287 | ||
288 | // "1" means free, "0" means locked | 288 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f); |
289 | OMV.Vector3 locking = LockedAxisFree; | 289 | if (axis.X != 1) |
290 | if (axis.X != 1) locking.X = 0f; | ||
291 | if (axis.Y != 1) locking.Y = 0f; | ||
292 | if (axis.Z != 1) locking.Z = 0f; | ||
293 | LockedAngularAxis = locking; | ||
294 | |||
295 | EnableActor(LockedAngularAxis != LockedAxisFree, LockedAxisActorName, delegate() | ||
296 | { | 290 | { |
297 | return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); | 291 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f); |
298 | }); | 292 | } |
299 | 293 | if (axis.Y != 1) | |
300 | // Update parameters so the new actor's Refresh() action is called at the right time. | ||
301 | PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate() | ||
302 | { | 294 | { |
303 | UpdatePhysicalParameters(); | 295 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f); |
304 | }); | 296 | } |
297 | if (axis.Z != 1) | ||
298 | { | ||
299 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f); | ||
300 | } | ||
301 | |||
302 | InitializeAxisActor(); | ||
305 | 303 | ||
306 | return; | 304 | return; |
307 | } | 305 | } |
@@ -533,6 +531,12 @@ public class BSPrim : BSPhysObject | |||
533 | { | 531 | { |
534 | return new BSActorSetForce(PhysScene, this, SetForceActorName); | 532 | return new BSActorSetForce(PhysScene, this, SetForceActorName); |
535 | }); | 533 | }); |
534 | |||
535 | // Call update so actor Refresh() is called to start things off | ||
536 | PhysScene.TaintedObject(LocalID, "BSPrim.setForce", delegate() | ||
537 | { | ||
538 | UpdatePhysicalParameters(); | ||
539 | }); | ||
536 | } | 540 | } |
537 | } | 541 | } |
538 | 542 | ||
@@ -766,6 +770,12 @@ public class BSPrim : BSPhysObject | |||
766 | return new BSActorSetTorque(PhysScene, this, SetTorqueActorName); | 770 | return new BSActorSetTorque(PhysScene, this, SetTorqueActorName); |
767 | }); | 771 | }); |
768 | DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque); | 772 | DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque); |
773 | |||
774 | // Call update so actor Refresh() is called to start things off | ||
775 | PhysScene.TaintedObject(LocalID, "BSPrim.setTorque", delegate() | ||
776 | { | ||
777 | UpdatePhysicalParameters(); | ||
778 | }); | ||
769 | } | 779 | } |
770 | } | 780 | } |
771 | public override OMV.Vector3 Acceleration { | 781 | public override OMV.Vector3 Acceleration { |
@@ -1138,6 +1148,12 @@ public class BSPrim : BSPhysObject | |||
1138 | { | 1148 | { |
1139 | return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName); | 1149 | return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName); |
1140 | }); | 1150 | }); |
1151 | |||
1152 | // Call update so actor Refresh() is called to start things off | ||
1153 | PhysScene.TaintedObject(LocalID, "BSPrim.PIDActive", delegate() | ||
1154 | { | ||
1155 | UpdatePhysicalParameters(); | ||
1156 | }); | ||
1141 | } | 1157 | } |
1142 | } | 1158 | } |
1143 | 1159 | ||
@@ -1164,6 +1180,12 @@ public class BSPrim : BSPhysObject | |||
1164 | { | 1180 | { |
1165 | return new BSActorHover(PhysScene, this, HoverActorName); | 1181 | return new BSActorHover(PhysScene, this, HoverActorName); |
1166 | }); | 1182 | }); |
1183 | |||
1184 | // Call update so actor Refresh() is called to start things off | ||
1185 | PhysScene.TaintedObject(LocalID, "BSPrim.PIDHoverActive", delegate() | ||
1186 | { | ||
1187 | UpdatePhysicalParameters(); | ||
1188 | }); | ||
1167 | } | 1189 | } |
1168 | } | 1190 | } |
1169 | 1191 | ||
@@ -1601,12 +1623,293 @@ public class BSPrim : BSPhysObject | |||
1601 | object ret = null; | 1623 | object ret = null; |
1602 | switch (pFunct) | 1624 | switch (pFunct) |
1603 | { | 1625 | { |
1626 | case ExtendedPhysics.PhysFunctAxisLockLimits: | ||
1627 | ret = SetAxisLockLimitsExtension(pParams); | ||
1628 | break; | ||
1604 | default: | 1629 | default: |
1605 | ret = base.Extension(pFunct, pParams); | 1630 | ret = base.Extension(pFunct, pParams); |
1606 | break; | 1631 | break; |
1607 | } | 1632 | } |
1608 | return ret; | 1633 | return ret; |
1609 | } | 1634 | } |
1635 | |||
1636 | private void InitializeAxisActor() | ||
1637 | { | ||
1638 | EnableActor(LockedAngularAxis != LockedAxisFree || LockedLinearAxis != LockedAxisFree, | ||
1639 | LockedAxisActorName, delegate() | ||
1640 | { | ||
1641 | return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); | ||
1642 | }); | ||
1643 | |||
1644 | // Update parameters so the new actor's Refresh() action is called at the right time. | ||
1645 | PhysScene.TaintedObject(LocalID, "BSPrim.LockAxis", delegate() | ||
1646 | { | ||
1647 | UpdatePhysicalParameters(); | ||
1648 | }); | ||
1649 | } | ||
1650 | |||
1651 | // Passed an array of an array of parameters, set the axis locking. | ||
1652 | // This expects an int (PHYS_AXIS_*) followed by none or two limit floats | ||
1653 | // followed by another int and floats, etc. | ||
1654 | private object SetAxisLockLimitsExtension(object[] pParams) | ||
1655 | { | ||
1656 | DetailLog("{0} SetAxisLockLimitsExtension. parmlen={1}", LocalID, pParams.GetLength(0)); | ||
1657 | object ret = null; | ||
1658 | try | ||
1659 | { | ||
1660 | if (pParams.GetLength(0) > 1) | ||
1661 | { | ||
1662 | int index = 2; | ||
1663 | while (index < pParams.GetLength(0)) | ||
1664 | { | ||
1665 | var funct = pParams[index]; | ||
1666 | DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index); | ||
1667 | if (funct is Int32 || funct is Int64) | ||
1668 | { | ||
1669 | switch ((int)funct) | ||
1670 | { | ||
1671 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR: | ||
1672 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR, 0f, 0f); | ||
1673 | index += 1; | ||
1674 | break; | ||
1675 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X: | ||
1676 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X, 0f, 0f); | ||
1677 | index += 1; | ||
1678 | break; | ||
1679 | case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X: | ||
1680 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X, (float)pParams[index + 1], (float)pParams[index + 2]); | ||
1681 | index += 3; | ||
1682 | break; | ||
1683 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y: | ||
1684 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y, 0f, 0f); | ||
1685 | index += 1; | ||
1686 | break; | ||
1687 | case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y: | ||
1688 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]); | ||
1689 | index += 3; | ||
1690 | break; | ||
1691 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z: | ||
1692 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z, 0f, 0f); | ||
1693 | index += 1; | ||
1694 | break; | ||
1695 | case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z: | ||
1696 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]); | ||
1697 | index += 3; | ||
1698 | break; | ||
1699 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR: | ||
1700 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR, 0f, 0f); | ||
1701 | index += 1; | ||
1702 | break; | ||
1703 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X: | ||
1704 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f); | ||
1705 | index += 1; | ||
1706 | break; | ||
1707 | case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X: | ||
1708 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X, (float)pParams[index + 1], (float)pParams[index + 2]); | ||
1709 | index += 3; | ||
1710 | break; | ||
1711 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y: | ||
1712 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f); | ||
1713 | index += 1; | ||
1714 | break; | ||
1715 | case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y: | ||
1716 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]); | ||
1717 | index += 3; | ||
1718 | break; | ||
1719 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z: | ||
1720 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f); | ||
1721 | index += 1; | ||
1722 | break; | ||
1723 | case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z: | ||
1724 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]); | ||
1725 | index += 3; | ||
1726 | break; | ||
1727 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR: | ||
1728 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f); | ||
1729 | index += 1; | ||
1730 | break; | ||
1731 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X: | ||
1732 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X, 0f, 0f); | ||
1733 | index += 1; | ||
1734 | break; | ||
1735 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y: | ||
1736 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y, 0f, 0f); | ||
1737 | index += 1; | ||
1738 | break; | ||
1739 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z: | ||
1740 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z, 0f, 0f); | ||
1741 | index += 1; | ||
1742 | break; | ||
1743 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR: | ||
1744 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f); | ||
1745 | index += 1; | ||
1746 | break; | ||
1747 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X: | ||
1748 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X, 0f, 0f); | ||
1749 | index += 1; | ||
1750 | break; | ||
1751 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y: | ||
1752 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y, 0f, 0f); | ||
1753 | index += 1; | ||
1754 | break; | ||
1755 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z: | ||
1756 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z, 0f, 0f); | ||
1757 | index += 1; | ||
1758 | break; | ||
1759 | case ExtendedPhysics.PHYS_AXIS_UNLOCK: | ||
1760 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK, 0f, 0f); | ||
1761 | index += 1; | ||
1762 | break; | ||
1763 | default: | ||
1764 | m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct); | ||
1765 | index += 1; | ||
1766 | break; | ||
1767 | } | ||
1768 | } | ||
1769 | } | ||
1770 | InitializeAxisActor(); | ||
1771 | ret = (object)index; | ||
1772 | } | ||
1773 | } | ||
1774 | catch (Exception e) | ||
1775 | { | ||
1776 | m_log.WarnFormat("{0} SetSxisLockLimitsExtension exception in object {1}: {2}", LogHeader, this.Name, e); | ||
1777 | ret = null; | ||
1778 | } | ||
1779 | return ret; // not implemented yet | ||
1780 | } | ||
1781 | |||
1782 | // Set the locking parameters. | ||
1783 | // If an axis is locked, the limits for the axis are set to zero, | ||
1784 | // If the axis is being constrained, the high and low value are passed and set. | ||
1785 | // When done here, LockedXXXAxis flags are set and LockedXXXAxixLow/High are set to the range. | ||
1786 | protected void ApplyAxisLimits(int funct, float low, float high) | ||
1787 | { | ||
1788 | DetailLog("{0} ApplyAxisLimits. op={1}, low={2}, high={3}", LocalID, funct, low, high); | ||
1789 | float linearMax = 23000f; | ||
1790 | float angularMax = (float)Math.PI; | ||
1791 | |||
1792 | switch ((int)funct) | ||
1793 | { | ||
1794 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR: | ||
1795 | this.LockedLinearAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis); | ||
1796 | this.LockedLinearAxisLow = OMV.Vector3.Zero; | ||
1797 | this.LockedLinearAxisHigh = OMV.Vector3.Zero; | ||
1798 | break; | ||
1799 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X: | ||
1800 | this.LockedLinearAxis.X = LockedAxis; | ||
1801 | this.LockedLinearAxisLow.X = 0f; | ||
1802 | this.LockedLinearAxisHigh.X = 0f; | ||
1803 | break; | ||
1804 | case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X: | ||
1805 | this.LockedLinearAxis.X = LockedAxis; | ||
1806 | this.LockedLinearAxisLow.X = Util.Clip(low, -linearMax, linearMax); | ||
1807 | this.LockedLinearAxisHigh.X = Util.Clip(high, -linearMax, linearMax); | ||
1808 | break; | ||
1809 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y: | ||
1810 | this.LockedLinearAxis.Y = LockedAxis; | ||
1811 | this.LockedLinearAxisLow.Y = 0f; | ||
1812 | this.LockedLinearAxisHigh.Y = 0f; | ||
1813 | break; | ||
1814 | case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y: | ||
1815 | this.LockedLinearAxis.Y = LockedAxis; | ||
1816 | this.LockedLinearAxisLow.Y = Util.Clip(low, -linearMax, linearMax); | ||
1817 | this.LockedLinearAxisHigh.Y = Util.Clip(high, -linearMax, linearMax); | ||
1818 | break; | ||
1819 | case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z: | ||
1820 | this.LockedLinearAxis.Z = LockedAxis; | ||
1821 | this.LockedLinearAxisLow.Z = 0f; | ||
1822 | this.LockedLinearAxisHigh.Z = 0f; | ||
1823 | break; | ||
1824 | case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z: | ||
1825 | this.LockedLinearAxis.Z = LockedAxis; | ||
1826 | this.LockedLinearAxisLow.Z = Util.Clip(low, -linearMax, linearMax); | ||
1827 | this.LockedLinearAxisHigh.Z = Util.Clip(high, -linearMax, linearMax); | ||
1828 | break; | ||
1829 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR: | ||
1830 | this.LockedAngularAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis); | ||
1831 | this.LockedAngularAxisLow = OMV.Vector3.Zero; | ||
1832 | this.LockedAngularAxisHigh = OMV.Vector3.Zero; | ||
1833 | break; | ||
1834 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X: | ||
1835 | this.LockedAngularAxis.X = LockedAxis; | ||
1836 | this.LockedAngularAxisLow.X = 0; | ||
1837 | this.LockedAngularAxisHigh.X = 0; | ||
1838 | break; | ||
1839 | case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X: | ||
1840 | this.LockedAngularAxis.X = LockedAxis; | ||
1841 | this.LockedAngularAxisLow.X = Util.Clip(low, -angularMax, angularMax); | ||
1842 | this.LockedAngularAxisHigh.X = Util.Clip(high, -angularMax, angularMax); | ||
1843 | break; | ||
1844 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y: | ||
1845 | this.LockedAngularAxis.Y = LockedAxis; | ||
1846 | this.LockedAngularAxisLow.Y = 0; | ||
1847 | this.LockedAngularAxisHigh.Y = 0; | ||
1848 | break; | ||
1849 | case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y: | ||
1850 | this.LockedAngularAxis.Y = LockedAxis; | ||
1851 | this.LockedAngularAxisLow.Y = Util.Clip(low, -angularMax, angularMax); | ||
1852 | this.LockedAngularAxisHigh.Y = Util.Clip(high, -angularMax, angularMax); | ||
1853 | break; | ||
1854 | case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z: | ||
1855 | this.LockedAngularAxis.Z = LockedAxis; | ||
1856 | this.LockedAngularAxisLow.Z = 0; | ||
1857 | this.LockedAngularAxisHigh.Z = 0; | ||
1858 | break; | ||
1859 | case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z: | ||
1860 | this.LockedAngularAxis.Z = LockedAxis; | ||
1861 | this.LockedAngularAxisLow.Z = Util.Clip(low, -angularMax, angularMax); | ||
1862 | this.LockedAngularAxisHigh.Z = Util.Clip(high, -angularMax, angularMax); | ||
1863 | break; | ||
1864 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR: | ||
1865 | this.LockedLinearAxis = LockedAxisFree; | ||
1866 | this.LockedLinearAxisLow = new OMV.Vector3(-linearMax, -linearMax, -linearMax); | ||
1867 | this.LockedLinearAxisHigh = new OMV.Vector3(linearMax, linearMax, linearMax); | ||
1868 | break; | ||
1869 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X: | ||
1870 | this.LockedLinearAxis.X = FreeAxis; | ||
1871 | this.LockedLinearAxisLow.X = -linearMax; | ||
1872 | this.LockedLinearAxisHigh.X = linearMax; | ||
1873 | break; | ||
1874 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y: | ||
1875 | this.LockedLinearAxis.Y = FreeAxis; | ||
1876 | this.LockedLinearAxisLow.Y = -linearMax; | ||
1877 | this.LockedLinearAxisHigh.Y = linearMax; | ||
1878 | break; | ||
1879 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z: | ||
1880 | this.LockedLinearAxis.Z = FreeAxis; | ||
1881 | this.LockedLinearAxisLow.Z = -linearMax; | ||
1882 | this.LockedLinearAxisHigh.Z = linearMax; | ||
1883 | break; | ||
1884 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR: | ||
1885 | this.LockedAngularAxis = LockedAxisFree; | ||
1886 | this.LockedAngularAxisLow = new OMV.Vector3(-angularMax, -angularMax, -angularMax); | ||
1887 | this.LockedAngularAxisHigh = new OMV.Vector3(angularMax, angularMax, angularMax); | ||
1888 | break; | ||
1889 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X: | ||
1890 | this.LockedAngularAxis.X = FreeAxis; | ||
1891 | this.LockedAngularAxisLow.X = -angularMax; | ||
1892 | this.LockedAngularAxisHigh.X = angularMax; | ||
1893 | break; | ||
1894 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y: | ||
1895 | this.LockedAngularAxis.Y = FreeAxis; | ||
1896 | this.LockedAngularAxisLow.Y = -angularMax; | ||
1897 | this.LockedAngularAxisHigh.Y = angularMax; | ||
1898 | break; | ||
1899 | case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z: | ||
1900 | this.LockedAngularAxis.Z = FreeAxis; | ||
1901 | this.LockedAngularAxisLow.Z = -angularMax; | ||
1902 | this.LockedAngularAxisHigh.Z = angularMax; | ||
1903 | break; | ||
1904 | case ExtendedPhysics.PHYS_AXIS_UNLOCK: | ||
1905 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f); | ||
1906 | ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f); | ||
1907 | break; | ||
1908 | default: | ||
1909 | break; | ||
1910 | } | ||
1911 | return; | ||
1912 | } | ||
1610 | #endregion // Extension | 1913 | #endregion // Extension |
1611 | 1914 | ||
1612 | // The physics engine says that properties have updated. Update same and inform | 1915 | // The physics engine says that properties have updated. Update same and inform |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 414bc92..238fcc2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -947,6 +947,73 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
947 | } | 947 | } |
948 | #endregion // Extensions | 948 | #endregion // Extensions |
949 | 949 | ||
950 | public static string PrimitiveBaseShapeToString(PrimitiveBaseShape pbs) | ||
951 | { | ||
952 | float pathShearX = pbs.PathShearX < 128 ? (float)pbs.PathShearX * 0.01f : (float)(pbs.PathShearX - 256) * 0.01f; | ||
953 | float pathShearY = pbs.PathShearY < 128 ? (float)pbs.PathShearY * 0.01f : (float)(pbs.PathShearY - 256) * 0.01f; | ||
954 | float pathBegin = (float)pbs.PathBegin * 2.0e-5f; | ||
955 | float pathEnd = 1.0f - (float)pbs.PathEnd * 2.0e-5f; | ||
956 | float pathScaleX = (float)(pbs.PathScaleX - 100) * 0.01f; | ||
957 | float pathScaleY = (float)(pbs.PathScaleY - 100) * 0.01f; | ||
958 | |||
959 | float profileBegin = (float)pbs.ProfileBegin * 2.0e-5f; | ||
960 | float profileEnd = 1.0f - (float)pbs.ProfileEnd * 2.0e-5f; | ||
961 | float profileHollow = (float)pbs.ProfileHollow * 2.0e-5f; | ||
962 | if (profileHollow > 0.95f) | ||
963 | profileHollow = 0.95f; | ||
964 | |||
965 | StringBuilder buff = new StringBuilder(); | ||
966 | buff.Append("shape="); | ||
967 | buff.Append(((ProfileShape)pbs.ProfileShape).ToString()); | ||
968 | buff.Append(","); | ||
969 | buff.Append("hollow="); | ||
970 | buff.Append(((HollowShape)pbs.HollowShape).ToString()); | ||
971 | buff.Append(","); | ||
972 | buff.Append("pathCurve="); | ||
973 | buff.Append(((Extrusion)pbs.PathCurve).ToString()); | ||
974 | buff.Append(","); | ||
975 | buff.Append("profCurve="); | ||
976 | buff.Append(((Extrusion)pbs.ProfileCurve).ToString()); | ||
977 | buff.Append(","); | ||
978 | buff.Append("profHollow="); | ||
979 | buff.Append(profileHollow.ToString()); | ||
980 | buff.Append(","); | ||
981 | buff.Append("pathBegEnd="); | ||
982 | buff.Append(pathBegin.ToString()); | ||
983 | buff.Append("/"); | ||
984 | buff.Append(pathEnd.ToString()); | ||
985 | buff.Append(","); | ||
986 | buff.Append("profileBegEnd="); | ||
987 | buff.Append(profileBegin.ToString()); | ||
988 | buff.Append("/"); | ||
989 | buff.Append(profileEnd.ToString()); | ||
990 | buff.Append(","); | ||
991 | buff.Append("scaleXY="); | ||
992 | buff.Append(pathScaleX.ToString()); | ||
993 | buff.Append("/"); | ||
994 | buff.Append(pathScaleY.ToString()); | ||
995 | buff.Append(","); | ||
996 | buff.Append("shearXY="); | ||
997 | buff.Append(pathShearX.ToString()); | ||
998 | buff.Append("/"); | ||
999 | buff.Append(pathShearY.ToString()); | ||
1000 | buff.Append(","); | ||
1001 | buff.Append("taperXY="); | ||
1002 | buff.Append(pbs.PathTaperX.ToString()); | ||
1003 | buff.Append("/"); | ||
1004 | buff.Append(pbs.PathTaperY.ToString()); | ||
1005 | buff.Append(","); | ||
1006 | buff.Append("skew="); | ||
1007 | buff.Append(pbs.PathSkew.ToString()); | ||
1008 | buff.Append(","); | ||
1009 | buff.Append("twist/Beg="); | ||
1010 | buff.Append(pbs.PathTwist.ToString()); | ||
1011 | buff.Append("/"); | ||
1012 | buff.Append(pbs.PathTwistBegin.ToString()); | ||
1013 | |||
1014 | return buff.ToString(); | ||
1015 | } | ||
1016 | |||
950 | #region Taints | 1017 | #region Taints |
951 | // The simulation execution order is: | 1018 | // The simulation execution order is: |
952 | // Simulate() | 1019 | // Simulate() |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 09f5bc4..aa04726 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -38,6 +38,76 @@ using OMV = OpenMetaverse; | |||
38 | 38 | ||
39 | namespace OpenSim.Region.Physics.BulletSPlugin | 39 | namespace OpenSim.Region.Physics.BulletSPlugin |
40 | { | 40 | { |
41 | // Information class that holds stats for the shape. Which values mean | ||
42 | // something depends on the type of shape. | ||
43 | // This information is used for debugging and stats and is not used | ||
44 | // for operational things. | ||
45 | public class ShapeInfoInfo | ||
46 | { | ||
47 | public int Vertices { get; set; } | ||
48 | private int m_hullCount; | ||
49 | private int[] m_verticesPerHull; | ||
50 | public ShapeInfoInfo() | ||
51 | { | ||
52 | Vertices = 0; | ||
53 | m_hullCount = 0; | ||
54 | m_verticesPerHull = null; | ||
55 | } | ||
56 | public int HullCount | ||
57 | { | ||
58 | set | ||
59 | { | ||
60 | m_hullCount = value; | ||
61 | m_verticesPerHull = new int[m_hullCount]; | ||
62 | Array.Clear(m_verticesPerHull, 0, m_hullCount); | ||
63 | } | ||
64 | get { return m_hullCount; } | ||
65 | } | ||
66 | public void SetVerticesPerHull(int hullNum, int vertices) | ||
67 | { | ||
68 | if (m_verticesPerHull != null && hullNum < m_verticesPerHull.Length) | ||
69 | { | ||
70 | m_verticesPerHull[hullNum] = vertices; | ||
71 | } | ||
72 | } | ||
73 | public int GetVerticesPerHull(int hullNum) | ||
74 | { | ||
75 | if (m_verticesPerHull != null && hullNum < m_verticesPerHull.Length) | ||
76 | { | ||
77 | return m_verticesPerHull[hullNum]; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | public override string ToString() | ||
82 | { | ||
83 | StringBuilder buff = new StringBuilder(); | ||
84 | // buff.Append("ShapeInfo=<"); | ||
85 | buff.Append("<"); | ||
86 | if (Vertices > 0) | ||
87 | { | ||
88 | buff.Append("verts="); | ||
89 | buff.Append(Vertices.ToString()); | ||
90 | } | ||
91 | |||
92 | if (Vertices > 0 && HullCount > 0) buff.Append(","); | ||
93 | |||
94 | if (HullCount > 0) | ||
95 | { | ||
96 | buff.Append("nHulls="); | ||
97 | buff.Append(HullCount.ToString()); | ||
98 | buff.Append(","); | ||
99 | buff.Append("hullVerts="); | ||
100 | for (int ii = 0; ii < HullCount; ii++) | ||
101 | { | ||
102 | if (ii != 0) buff.Append(","); | ||
103 | buff.Append(GetVerticesPerHull(ii).ToString()); | ||
104 | } | ||
105 | } | ||
106 | buff.Append(">"); | ||
107 | return buff.ToString(); | ||
108 | } | ||
109 | } | ||
110 | |||
41 | public abstract class BSShape | 111 | public abstract class BSShape |
42 | { | 112 | { |
43 | private static string LogHeader = "[BULLETSIM SHAPE]"; | 113 | private static string LogHeader = "[BULLETSIM SHAPE]"; |
@@ -45,18 +115,21 @@ public abstract class BSShape | |||
45 | public int referenceCount { get; set; } | 115 | public int referenceCount { get; set; } |
46 | public DateTime lastReferenced { get; set; } | 116 | public DateTime lastReferenced { get; set; } |
47 | public BulletShape physShapeInfo { get; set; } | 117 | public BulletShape physShapeInfo { get; set; } |
118 | public ShapeInfoInfo shapeInfo { get; private set; } | ||
48 | 119 | ||
49 | public BSShape() | 120 | public BSShape() |
50 | { | 121 | { |
51 | referenceCount = 1; | 122 | referenceCount = 1; |
52 | lastReferenced = DateTime.Now; | 123 | lastReferenced = DateTime.Now; |
53 | physShapeInfo = new BulletShape(); | 124 | physShapeInfo = new BulletShape(); |
125 | shapeInfo = new ShapeInfoInfo(); | ||
54 | } | 126 | } |
55 | public BSShape(BulletShape pShape) | 127 | public BSShape(BulletShape pShape) |
56 | { | 128 | { |
57 | referenceCount = 1; | 129 | referenceCount = 1; |
58 | lastReferenced = DateTime.Now; | 130 | lastReferenced = DateTime.Now; |
59 | physShapeInfo = pShape; | 131 | physShapeInfo = pShape; |
132 | shapeInfo = new ShapeInfoInfo(); | ||
60 | } | 133 | } |
61 | 134 | ||
62 | // Get another reference to this shape. | 135 | // Get another reference to this shape. |
@@ -283,6 +356,9 @@ public class BSShapeNull : BSShape | |||
283 | } | 356 | } |
284 | 357 | ||
285 | // ============================================================================================================ | 358 | // ============================================================================================================ |
359 | // BSShapeNative is a wrapper for a Bullet 'native' shape -- cube and sphere. | ||
360 | // They are odd in that they don't allocate meshes but are computated/procedural. | ||
361 | // This means allocation and freeing is different than meshes. | ||
286 | public class BSShapeNative : BSShape | 362 | public class BSShapeNative : BSShape |
287 | { | 363 | { |
288 | private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; | 364 | private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; |
@@ -361,6 +437,7 @@ public class BSShapeNative : BSShape | |||
361 | } | 437 | } |
362 | 438 | ||
363 | // ============================================================================================================ | 439 | // ============================================================================================================ |
440 | // BSShapeMesh is a simple mesh. | ||
364 | public class BSShapeMesh : BSShape | 441 | public class BSShapeMesh : BSShape |
365 | { | 442 | { |
366 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; | 443 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; |
@@ -457,7 +534,11 @@ public class BSShapeMesh : BSShape | |||
457 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 534 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
458 | { | 535 | { |
459 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | 536 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, |
460 | (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); | 537 | (w, iC, i, vC, v) => |
538 | { | ||
539 | shapeInfo.Vertices = vC; | ||
540 | return physicsScene.PE.CreateMeshShape(w, iC, i, vC, v); | ||
541 | }); | ||
461 | } | 542 | } |
462 | 543 | ||
463 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. | 544 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. |
@@ -545,6 +626,9 @@ public class BSShapeMesh : BSShape | |||
545 | } | 626 | } |
546 | 627 | ||
547 | // ============================================================================================================ | 628 | // ============================================================================================================ |
629 | // BSShapeHull is a physical shape representation htat is made up of many convex hulls. | ||
630 | // The convex hulls are either supplied with the asset or are approximated by one of the | ||
631 | // convex hull creation routines (in OpenSim or in Bullet). | ||
548 | public class BSShapeHull : BSShape | 632 | public class BSShapeHull : BSShape |
549 | { | 633 | { |
550 | #pragma warning disable 414 | 634 | #pragma warning disable 414 |
@@ -553,6 +637,7 @@ public class BSShapeHull : BSShape | |||
553 | 637 | ||
554 | public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); | 638 | public static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); |
555 | 639 | ||
640 | |||
556 | public BSShapeHull(BulletShape pShape) : base(pShape) | 641 | public BSShapeHull(BulletShape pShape) : base(pShape) |
557 | { | 642 | { |
558 | } | 643 | } |
@@ -615,6 +700,7 @@ public class BSShapeHull : BSShape | |||
615 | // TODO: schedule aging and destruction of unused meshes. | 700 | // TODO: schedule aging and destruction of unused meshes. |
616 | } | 701 | } |
617 | } | 702 | } |
703 | |||
618 | List<ConvexResult> m_hulls; | 704 | List<ConvexResult> m_hulls; |
619 | private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey, | 705 | private BulletShape CreatePhysicalHull(BSScene physicsScene, BSPhysObject prim, System.UInt64 newHullKey, |
620 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 706 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
@@ -647,6 +733,7 @@ public class BSShapeHull : BSShape | |||
647 | if (allHulls != null && BSParam.ShouldUseAssetHulls) | 733 | if (allHulls != null && BSParam.ShouldUseAssetHulls) |
648 | { | 734 | { |
649 | int hullCount = allHulls.Count; | 735 | int hullCount = allHulls.Count; |
736 | shapeInfo.HullCount = hullCount; | ||
650 | int totalVertices = 1; // include one for the count of the hulls | 737 | int totalVertices = 1; // include one for the count of the hulls |
651 | // Using the structure described for HACD hulls, create the memory sturcture | 738 | // Using the structure described for HACD hulls, create the memory sturcture |
652 | // to pass the hull data to the creater. | 739 | // to pass the hull data to the creater. |
@@ -659,6 +746,7 @@ public class BSShapeHull : BSShape | |||
659 | 746 | ||
660 | convHulls[0] = (float)hullCount; | 747 | convHulls[0] = (float)hullCount; |
661 | int jj = 1; | 748 | int jj = 1; |
749 | int hullIndex = 0; | ||
662 | foreach (List<OMV.Vector3> hullVerts in allHulls) | 750 | foreach (List<OMV.Vector3> hullVerts in allHulls) |
663 | { | 751 | { |
664 | convHulls[jj + 0] = hullVerts.Count; | 752 | convHulls[jj + 0] = hullVerts.Count; |
@@ -673,6 +761,8 @@ public class BSShapeHull : BSShape | |||
673 | convHulls[jj + 2] = oneVert.Z; | 761 | convHulls[jj + 2] = oneVert.Z; |
674 | jj += 3; | 762 | jj += 3; |
675 | } | 763 | } |
764 | shapeInfo.SetVerticesPerHull(hullIndex, hullVerts.Count); | ||
765 | hullIndex++; | ||
676 | } | 766 | } |
677 | 767 | ||
678 | // create the hull data structure in Bullet | 768 | // create the hull data structure in Bullet |
@@ -708,6 +798,10 @@ public class BSShapeHull : BSShape | |||
708 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); | 798 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); |
709 | 799 | ||
710 | // Now done with the mesh shape. | 800 | // Now done with the mesh shape. |
801 | shapeInfo.HullCount = 1; | ||
802 | BSShapeMesh maybeMesh = meshShape as BSShapeMesh; | ||
803 | if (maybeMesh != null) | ||
804 | shapeInfo.SetVerticesPerHull(0, maybeMesh.shapeInfo.Vertices); | ||
711 | meshShape.Dereference(physicsScene); | 805 | meshShape.Dereference(physicsScene); |
712 | } | 806 | } |
713 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 807 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
@@ -857,6 +951,8 @@ public class BSShapeHull : BSShape | |||
857 | } | 951 | } |
858 | 952 | ||
859 | // ============================================================================================================ | 953 | // ============================================================================================================ |
954 | // BSShapeCompound is a wrapper for the Bullet compound shape which is built from multiple, separate | ||
955 | // meshes. Used by BulletSim for complex shapes like linksets. | ||
860 | public class BSShapeCompound : BSShape | 956 | public class BSShapeCompound : BSShape |
861 | { | 957 | { |
862 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; | 958 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; |
@@ -999,6 +1095,9 @@ public class BSShapeCompound : BSShape | |||
999 | } | 1095 | } |
1000 | 1096 | ||
1001 | // ============================================================================================================ | 1097 | // ============================================================================================================ |
1098 | // BSShapeConvexHull is a wrapper for a Bullet single convex hull. A BSShapeHull contains multiple convex | ||
1099 | // hull shapes. This is used for simple prims that are convex and thus can be made into a simple | ||
1100 | // collision shape (a single hull). More complex physical shapes will be BSShapeHull's. | ||
1002 | public class BSShapeConvexHull : BSShape | 1101 | public class BSShapeConvexHull : BSShape |
1003 | { | 1102 | { |
1004 | #pragma warning disable 414 | 1103 | #pragma warning disable 414 |
@@ -1098,6 +1197,9 @@ public class BSShapeConvexHull : BSShape | |||
1098 | } | 1197 | } |
1099 | } | 1198 | } |
1100 | // ============================================================================================================ | 1199 | // ============================================================================================================ |
1200 | // BSShapeGImpact is a wrapper for the Bullet GImpact shape which is a collision mesh shape that | ||
1201 | // can handle concave as well as convex shapes. Much slower computationally but creates smoother | ||
1202 | // shapes than multiple convex hull approximations. | ||
1101 | public class BSShapeGImpact : BSShape | 1203 | public class BSShapeGImpact : BSShape |
1102 | { | 1204 | { |
1103 | #pragma warning disable 414 | 1205 | #pragma warning disable 414 |
@@ -1151,7 +1253,11 @@ public class BSShapeGImpact : BSShape | |||
1151 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 1253 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
1152 | { | 1254 | { |
1153 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | 1255 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, |
1154 | (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); | 1256 | (w, iC, i, vC, v) => |
1257 | { | ||
1258 | shapeInfo.Vertices = vC; | ||
1259 | return physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v); | ||
1260 | }); | ||
1155 | } | 1261 | } |
1156 | 1262 | ||
1157 | public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) | 1263 | public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim) |
@@ -1206,6 +1312,7 @@ public class BSShapeGImpact : BSShape | |||
1206 | } | 1312 | } |
1207 | 1313 | ||
1208 | // ============================================================================================================ | 1314 | // ============================================================================================================ |
1315 | // BSShapeAvatar is a specialized mesh shape for avatars. | ||
1209 | public class BSShapeAvatar : BSShape | 1316 | public class BSShapeAvatar : BSShape |
1210 | { | 1317 | { |
1211 | #pragma warning disable 414 | 1318 | #pragma warning disable 414 |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs index 28207a4..775bca2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs | |||
@@ -28,15 +28,16 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Linq; | ||
32 | using System.Text; | 31 | using System.Text; |
33 | 32 | ||
34 | using Nini.Config; | 33 | using Nini.Config; |
35 | 34 | ||
36 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
37 | using OpenSim.Region.Physics.BulletSPlugin; | 36 | using OpenSim.Region.Physics.Manager; |
38 | using OpenSim.Region.Physics.Meshing; | 37 | using OpenSim.Region.Physics.Meshing; |
39 | 38 | ||
39 | using OpenMetaverse; | ||
40 | |||
40 | namespace OpenSim.Region.Physics.BulletSPlugin.Tests | 41 | namespace OpenSim.Region.Physics.BulletSPlugin.Tests |
41 | { | 42 | { |
42 | // Utility functions for building up and tearing down the sample physics environments | 43 | // Utility functions for building up and tearing down the sample physics environments |
@@ -77,17 +78,21 @@ public static class BulletSimTestsUtil | |||
77 | bulletSimConfig.Set("VehicleLoggingEnabled","True"); | 78 | bulletSimConfig.Set("VehicleLoggingEnabled","True"); |
78 | } | 79 | } |
79 | 80 | ||
80 | BSPlugin bsPlugin = new BSPlugin(); | 81 | PhysicsPluginManager physicsPluginManager; |
82 | physicsPluginManager = new PhysicsPluginManager(); | ||
83 | physicsPluginManager.LoadPluginsFromAssemblies("Physics"); | ||
84 | |||
85 | Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); | ||
86 | |||
87 | PhysicsScene pScene = physicsPluginManager.GetPhysicsScene( | ||
88 | "BulletSim", "Meshmerizer", openSimINI, "BSTestRegion", regionExtent); | ||
81 | 89 | ||
82 | BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); | 90 | BSScene bsScene = pScene as BSScene; |
83 | 91 | ||
84 | // Since the asset requestor is not initialized, any mesh or sculptie will be a cube. | 92 | // Since the asset requestor is not initialized, any mesh or sculptie will be a cube. |
85 | // In the future, add a fake asset fetcher to get meshes and sculpts. | 93 | // In the future, add a fake asset fetcher to get meshes and sculpts. |
86 | // bsScene.RequestAssetMethod = ???; | 94 | // bsScene.RequestAssetMethod = ???; |
87 | 95 | ||
88 | Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI); | ||
89 | bsScene.Initialise(mesher, openSimINI); | ||
90 | |||
91 | return bsScene; | 96 | return bsScene; |
92 | } | 97 | } |
93 | 98 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs new file mode 100644 index 0000000..4bec062 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/HullCreation.cs | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | |||
33 | using NUnit.Framework; | ||
34 | using log4net; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Physics.BulletSPlugin; | ||
38 | using OpenSim.Region.Physics.Manager; | ||
39 | using OpenSim.Tests.Common; | ||
40 | |||
41 | using OpenMetaverse; | ||
42 | |||
43 | namespace OpenSim.Region.Physics.BulletSPlugin.Tests | ||
44 | { | ||
45 | [TestFixture] | ||
46 | public class HullCreation : OpenSimTestCase | ||
47 | { | ||
48 | // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 | ||
49 | // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 | ||
50 | |||
51 | BSScene PhysicsScene { get; set; } | ||
52 | Vector3 ObjectInitPosition; | ||
53 | float simulationTimeStep = 0.089f; | ||
54 | |||
55 | [TestFixtureSetUp] | ||
56 | public void Init() | ||
57 | { | ||
58 | |||
59 | } | ||
60 | |||
61 | [TestFixtureTearDown] | ||
62 | public void TearDown() | ||
63 | { | ||
64 | if (PhysicsScene != null) | ||
65 | { | ||
66 | // The Dispose() will also free any physical objects in the scene | ||
67 | PhysicsScene.Dispose(); | ||
68 | PhysicsScene = null; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | [TestCase(7, 2, 5f, 5f, 32, 0f)] /* default hull parameters */ | ||
73 | public void GeomHullConvexDecomp( int maxDepthSplit, | ||
74 | int maxDepthSplitForSimpleShapes, | ||
75 | float concavityThresholdPercent, | ||
76 | float volumeConservationThresholdPercent, | ||
77 | int maxVertices, | ||
78 | float maxSkinWidth) | ||
79 | { | ||
80 | // Setup the physics engine to use the C# version of convex decomp | ||
81 | Dictionary<string, string> engineParams = new Dictionary<string, string>(); | ||
82 | engineParams.Add("MeshSculptedPrim", "true"); // ShouldMeshSculptedPrim | ||
83 | engineParams.Add("ForceSimplePrimMeshing", "false"); // ShouldForceSimplePrimMeshing | ||
84 | engineParams.Add("UseHullsForPhysicalObjects", "true"); // ShouldUseHullsForPhysicalObjects | ||
85 | engineParams.Add("ShouldRemoveZeroWidthTriangles", "true"); | ||
86 | engineParams.Add("ShouldUseBulletHACD", "false"); | ||
87 | engineParams.Add("ShouldUseSingleConvexHullForPrims", "true"); | ||
88 | engineParams.Add("ShouldUseGImpactShapeForPrims", "false"); | ||
89 | engineParams.Add("ShouldUseAssetHulls", "true"); | ||
90 | |||
91 | engineParams.Add("CSHullMaxDepthSplit", maxDepthSplit.ToString()); | ||
92 | engineParams.Add("CSHullMaxDepthSplitForSimpleShapes", maxDepthSplitForSimpleShapes.ToString()); | ||
93 | engineParams.Add("CSHullConcavityThresholdPercent", concavityThresholdPercent.ToString()); | ||
94 | engineParams.Add("CSHullVolumeConservationThresholdPercent", volumeConservationThresholdPercent.ToString()); | ||
95 | engineParams.Add("CSHullMaxVertices", maxVertices.ToString()); | ||
96 | engineParams.Add("CSHullMaxSkinWidth", maxSkinWidth.ToString()); | ||
97 | |||
98 | PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); | ||
99 | |||
100 | PrimitiveBaseShape pbs; | ||
101 | Vector3 pos; | ||
102 | Vector3 size; | ||
103 | Quaternion rot; | ||
104 | bool isPhys; | ||
105 | |||
106 | // Cylinder | ||
107 | pbs = PrimitiveBaseShape.CreateCylinder(); | ||
108 | pos = new Vector3(100.0f, 100.0f, 0f); | ||
109 | pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f; | ||
110 | ObjectInitPosition = pos; | ||
111 | size = new Vector3(2f, 2f, 2f); | ||
112 | pbs.Scale = size; | ||
113 | rot = Quaternion.Identity; | ||
114 | isPhys = true; | ||
115 | uint cylinderLocalID = 123; | ||
116 | PhysicsScene.AddPrimShape("testCylinder", pbs, pos, size, rot, isPhys, cylinderLocalID); | ||
117 | BSPrim primTypeCylinder = (BSPrim)PhysicsScene.PhysObjects[cylinderLocalID]; | ||
118 | |||
119 | // Hollow Cylinder | ||
120 | pbs = PrimitiveBaseShape.CreateCylinder(); | ||
121 | pbs.ProfileHollow = (ushort)(0.70f * 50000); | ||
122 | pos = new Vector3(110.0f, 110.0f, 0f); | ||
123 | pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f; | ||
124 | ObjectInitPosition = pos; | ||
125 | size = new Vector3(2f, 2f, 2f); | ||
126 | pbs.Scale = size; | ||
127 | rot = Quaternion.Identity; | ||
128 | isPhys = true; | ||
129 | uint hollowCylinderLocalID = 124; | ||
130 | PhysicsScene.AddPrimShape("testHollowCylinder", pbs, pos, size, rot, isPhys, hollowCylinderLocalID); | ||
131 | BSPrim primTypeHollowCylinder = (BSPrim)PhysicsScene.PhysObjects[hollowCylinderLocalID]; | ||
132 | |||
133 | // Torus | ||
134 | // ProfileCurve = Circle, PathCurve = Curve1 | ||
135 | pbs = PrimitiveBaseShape.CreateSphere(); | ||
136 | pbs.ProfileShape = (byte)ProfileShape.Circle; | ||
137 | pbs.PathCurve = (byte)Extrusion.Curve1; | ||
138 | pos = new Vector3(120.0f, 120.0f, 0f); | ||
139 | pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 10f; | ||
140 | ObjectInitPosition = pos; | ||
141 | size = new Vector3(2f, 4f, 4f); | ||
142 | pbs.Scale = size; | ||
143 | rot = Quaternion.Identity; | ||
144 | isPhys = true; | ||
145 | uint torusLocalID = 125; | ||
146 | PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID); | ||
147 | BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID]; | ||
148 | |||
149 | // The actual prim shape creation happens at taint time | ||
150 | PhysicsScene.ProcessTaints(); | ||
151 | |||
152 | // Check out the created hull shapes and report their characteristics | ||
153 | ReportShapeGeom(primTypeCylinder); | ||
154 | ReportShapeGeom(primTypeHollowCylinder); | ||
155 | ReportShapeGeom(primTypeTorus); | ||
156 | } | ||
157 | |||
158 | [TestCase] | ||
159 | public void GeomHullBulletHACD() | ||
160 | { | ||
161 | // Cylinder | ||
162 | // Hollow Cylinder | ||
163 | // Torus | ||
164 | } | ||
165 | |||
166 | private void ReportShapeGeom(BSPrim prim) | ||
167 | { | ||
168 | if (prim != null) | ||
169 | { | ||
170 | if (prim.PhysShape.HasPhysicalShape) | ||
171 | { | ||
172 | BSShape physShape = prim.PhysShape; | ||
173 | string shapeType = physShape.GetType().ToString(); | ||
174 | switch (shapeType) | ||
175 | { | ||
176 | case "OpenSim.Region.Physics.BulletSPlugin.BSShapeNative": | ||
177 | BSShapeNative nShape = physShape as BSShapeNative; | ||
178 | prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType); | ||
179 | break; | ||
180 | case "OpenSim.Region.Physics.BulletSPlugin.BSShapeMesh": | ||
181 | BSShapeMesh mShape = physShape as BSShapeMesh; | ||
182 | prim.PhysScene.DetailLog("{0}, mesh, shapeInfo={1}", prim.Name, mShape.shapeInfo); | ||
183 | break; | ||
184 | case "OpenSim.Region.Physics.BulletSPlugin.BSShapeHull": | ||
185 | // BSShapeHull hShape = physShape as BSShapeHull; | ||
186 | // prim.PhysScene.DetailLog("{0}, hull, shapeInfo={1}", prim.Name, hShape.shapeInfo); | ||
187 | break; | ||
188 | case "OpenSim.Region.Physics.BulletSPlugin.BSShapeConvexHull": | ||
189 | BSShapeConvexHull chShape = physShape as BSShapeConvexHull; | ||
190 | prim.PhysScene.DetailLog("{0}, convexHull, shapeInfo={1}", prim.Name, chShape.shapeInfo); | ||
191 | break; | ||
192 | case "OpenSim.Region.Physics.BulletSPlugin.BSShapeCompound": | ||
193 | BSShapeCompound cShape = physShape as BSShapeCompound; | ||
194 | prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType); | ||
195 | break; | ||
196 | default: | ||
197 | prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType); | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } \ No newline at end of file | ||