aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs98
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs121
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs13
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs334
5 files changed, 474 insertions, 97 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
37public class BSActorLockAxis : BSActor 37public 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..9695fcf 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -34,6 +34,7 @@ using OMV = OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager; 35using OpenSim.Region.Physics.Manager;
36using OpenSim.Region.Physics.ConvexDecompositionDotNet; 36using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics
37 38
38namespace OpenSim.Region.Physics.BulletSPlugin 39namespace OpenSim.Region.Physics.BulletSPlugin
39{ 40{
@@ -285,23 +286,21 @@ public class BSPrim : BSPhysObject
285 { 286 {
286 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 287 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
287 288
288 // "1" means free, "0" means locked 289 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
289 OMV.Vector3 locking = LockedAxisFree; 290 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 { 291 {
297 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); 292 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
298 }); 293 }
299 294 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 { 295 {
303 UpdatePhysicalParameters(); 296 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
304 }); 297 }
298 if (axis.Z != 1)
299 {
300 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
301 }
302
303 InitializeAxisActor();
305 304
306 return; 305 return;
307 } 306 }
@@ -533,6 +532,12 @@ public class BSPrim : BSPhysObject
533 { 532 {
534 return new BSActorSetForce(PhysScene, this, SetForceActorName); 533 return new BSActorSetForce(PhysScene, this, SetForceActorName);
535 }); 534 });
535
536 // Call update so actor Refresh() is called to start things off
537 PhysScene.TaintedObject(LocalID, "BSPrim.setForce", delegate()
538 {
539 UpdatePhysicalParameters();
540 });
536 } 541 }
537 } 542 }
538 543
@@ -766,6 +771,12 @@ public class BSPrim : BSPhysObject
766 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName); 771 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName);
767 }); 772 });
768 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque); 773 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
774
775 // Call update so actor Refresh() is called to start things off
776 PhysScene.TaintedObject(LocalID, "BSPrim.setTorque", delegate()
777 {
778 UpdatePhysicalParameters();
779 });
769 } 780 }
770 } 781 }
771 public override OMV.Vector3 Acceleration { 782 public override OMV.Vector3 Acceleration {
@@ -1138,6 +1149,12 @@ public class BSPrim : BSPhysObject
1138 { 1149 {
1139 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName); 1150 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName);
1140 }); 1151 });
1152
1153 // Call update so actor Refresh() is called to start things off
1154 PhysScene.TaintedObject(LocalID, "BSPrim.PIDActive", delegate()
1155 {
1156 UpdatePhysicalParameters();
1157 });
1141 } 1158 }
1142 } 1159 }
1143 1160
@@ -1164,6 +1181,12 @@ public class BSPrim : BSPhysObject
1164 { 1181 {
1165 return new BSActorHover(PhysScene, this, HoverActorName); 1182 return new BSActorHover(PhysScene, this, HoverActorName);
1166 }); 1183 });
1184
1185 // Call update so actor Refresh() is called to start things off
1186 PhysScene.TaintedObject(LocalID, "BSPrim.PIDHoverActive", delegate()
1187 {
1188 UpdatePhysicalParameters();
1189 });
1167 } 1190 }
1168 } 1191 }
1169 1192
@@ -1601,12 +1624,293 @@ public class BSPrim : BSPhysObject
1601 object ret = null; 1624 object ret = null;
1602 switch (pFunct) 1625 switch (pFunct)
1603 { 1626 {
1627 case ExtendedPhysics.PhysFunctAxisLockLimits:
1628 ret = SetAxisLockLimitsExtension(pParams);
1629 break;
1604 default: 1630 default:
1605 ret = base.Extension(pFunct, pParams); 1631 ret = base.Extension(pFunct, pParams);
1606 break; 1632 break;
1607 } 1633 }
1608 return ret; 1634 return ret;
1609 } 1635 }
1636
1637 private void InitializeAxisActor()
1638 {
1639 EnableActor(LockedAngularAxis != LockedAxisFree || LockedLinearAxis != LockedAxisFree,
1640 LockedAxisActorName, delegate()
1641 {
1642 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName);
1643 });
1644
1645 // Update parameters so the new actor's Refresh() action is called at the right time.
1646 PhysScene.TaintedObject(LocalID, "BSPrim.LockAxis", delegate()
1647 {
1648 UpdatePhysicalParameters();
1649 });
1650 }
1651
1652 // Passed an array of an array of parameters, set the axis locking.
1653 // This expects an int (PHYS_AXIS_*) followed by none or two limit floats
1654 // followed by another int and floats, etc.
1655 private object SetAxisLockLimitsExtension(object[] pParams)
1656 {
1657 DetailLog("{0} SetAxisLockLimitsExtension. parmlen={1}", LocalID, pParams.GetLength(0));
1658 object ret = null;
1659 try
1660 {
1661 if (pParams.GetLength(0) > 1)
1662 {
1663 int index = 2;
1664 while (index < pParams.GetLength(0))
1665 {
1666 var funct = pParams[index];
1667 DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index);
1668 if (funct is Int32 || funct is Int64)
1669 {
1670 switch ((int)funct)
1671 {
1672 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
1673 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR, 0f, 0f);
1674 index += 1;
1675 break;
1676 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
1677 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X, 0f, 0f);
1678 index += 1;
1679 break;
1680 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
1681 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X, (float)pParams[index + 1], (float)pParams[index + 2]);
1682 index += 3;
1683 break;
1684 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
1685 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y, 0f, 0f);
1686 index += 1;
1687 break;
1688 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
1689 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]);
1690 index += 3;
1691 break;
1692 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
1693 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z, 0f, 0f);
1694 index += 1;
1695 break;
1696 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
1697 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]);
1698 index += 3;
1699 break;
1700 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
1701 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR, 0f, 0f);
1702 index += 1;
1703 break;
1704 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
1705 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
1706 index += 1;
1707 break;
1708 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
1709 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X, (float)pParams[index + 1], (float)pParams[index + 2]);
1710 index += 3;
1711 break;
1712 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
1713 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
1714 index += 1;
1715 break;
1716 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
1717 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]);
1718 index += 3;
1719 break;
1720 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
1721 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
1722 index += 1;
1723 break;
1724 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
1725 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]);
1726 index += 3;
1727 break;
1728 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
1729 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
1730 index += 1;
1731 break;
1732 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
1733 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X, 0f, 0f);
1734 index += 1;
1735 break;
1736 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
1737 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y, 0f, 0f);
1738 index += 1;
1739 break;
1740 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
1741 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z, 0f, 0f);
1742 index += 1;
1743 break;
1744 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
1745 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
1746 index += 1;
1747 break;
1748 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
1749 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X, 0f, 0f);
1750 index += 1;
1751 break;
1752 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
1753 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y, 0f, 0f);
1754 index += 1;
1755 break;
1756 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
1757 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z, 0f, 0f);
1758 index += 1;
1759 break;
1760 case ExtendedPhysics.PHYS_AXIS_UNLOCK:
1761 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK, 0f, 0f);
1762 index += 1;
1763 break;
1764 default:
1765 m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct);
1766 index += 1;
1767 break;
1768 }
1769 }
1770 }
1771 InitializeAxisActor();
1772 ret = (object)index;
1773 }
1774 }
1775 catch (Exception e)
1776 {
1777 m_log.WarnFormat("{0} SetSxisLockLimitsExtension exception in object {1}: {2}", LogHeader, this.Name, e);
1778 ret = null;
1779 }
1780 return ret; // not implemented yet
1781 }
1782
1783 // Set the locking parameters.
1784 // If an axis is locked, the limits for the axis are set to zero,
1785 // If the axis is being constrained, the high and low value are passed and set.
1786 // When done here, LockedXXXAxis flags are set and LockedXXXAxixLow/High are set to the range.
1787 protected void ApplyAxisLimits(int funct, float low, float high)
1788 {
1789 DetailLog("{0} ApplyAxisLimits. op={1}, low={2}, high={3}", LocalID, funct, low, high);
1790 float linearMax = 23000f;
1791 float angularMax = (float)Math.PI;
1792
1793 switch ((int)funct)
1794 {
1795 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
1796 this.LockedLinearAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
1797 this.LockedLinearAxisLow = OMV.Vector3.Zero;
1798 this.LockedLinearAxisHigh = OMV.Vector3.Zero;
1799 break;
1800 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
1801 this.LockedLinearAxis.X = LockedAxis;
1802 this.LockedLinearAxisLow.X = 0f;
1803 this.LockedLinearAxisHigh.X = 0f;
1804 break;
1805 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
1806 this.LockedLinearAxis.X = LockedAxis;
1807 this.LockedLinearAxisLow.X = Util.Clip(low, -linearMax, linearMax);
1808 this.LockedLinearAxisHigh.X = Util.Clip(high, -linearMax, linearMax);
1809 break;
1810 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
1811 this.LockedLinearAxis.Y = LockedAxis;
1812 this.LockedLinearAxisLow.Y = 0f;
1813 this.LockedLinearAxisHigh.Y = 0f;
1814 break;
1815 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
1816 this.LockedLinearAxis.Y = LockedAxis;
1817 this.LockedLinearAxisLow.Y = Util.Clip(low, -linearMax, linearMax);
1818 this.LockedLinearAxisHigh.Y = Util.Clip(high, -linearMax, linearMax);
1819 break;
1820 case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
1821 this.LockedLinearAxis.Z = LockedAxis;
1822 this.LockedLinearAxisLow.Z = 0f;
1823 this.LockedLinearAxisHigh.Z = 0f;
1824 break;
1825 case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
1826 this.LockedLinearAxis.Z = LockedAxis;
1827 this.LockedLinearAxisLow.Z = Util.Clip(low, -linearMax, linearMax);
1828 this.LockedLinearAxisHigh.Z = Util.Clip(high, -linearMax, linearMax);
1829 break;
1830 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
1831 this.LockedAngularAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
1832 this.LockedAngularAxisLow = OMV.Vector3.Zero;
1833 this.LockedAngularAxisHigh = OMV.Vector3.Zero;
1834 break;
1835 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
1836 this.LockedAngularAxis.X = LockedAxis;
1837 this.LockedAngularAxisLow.X = 0;
1838 this.LockedAngularAxisHigh.X = 0;
1839 break;
1840 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
1841 this.LockedAngularAxis.X = LockedAxis;
1842 this.LockedAngularAxisLow.X = Util.Clip(low, -angularMax, angularMax);
1843 this.LockedAngularAxisHigh.X = Util.Clip(high, -angularMax, angularMax);
1844 break;
1845 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
1846 this.LockedAngularAxis.Y = LockedAxis;
1847 this.LockedAngularAxisLow.Y = 0;
1848 this.LockedAngularAxisHigh.Y = 0;
1849 break;
1850 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
1851 this.LockedAngularAxis.Y = LockedAxis;
1852 this.LockedAngularAxisLow.Y = Util.Clip(low, -angularMax, angularMax);
1853 this.LockedAngularAxisHigh.Y = Util.Clip(high, -angularMax, angularMax);
1854 break;
1855 case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
1856 this.LockedAngularAxis.Z = LockedAxis;
1857 this.LockedAngularAxisLow.Z = 0;
1858 this.LockedAngularAxisHigh.Z = 0;
1859 break;
1860 case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
1861 this.LockedAngularAxis.Z = LockedAxis;
1862 this.LockedAngularAxisLow.Z = Util.Clip(low, -angularMax, angularMax);
1863 this.LockedAngularAxisHigh.Z = Util.Clip(high, -angularMax, angularMax);
1864 break;
1865 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
1866 this.LockedLinearAxis = LockedAxisFree;
1867 this.LockedLinearAxisLow = new OMV.Vector3(-linearMax, -linearMax, -linearMax);
1868 this.LockedLinearAxisHigh = new OMV.Vector3(linearMax, linearMax, linearMax);
1869 break;
1870 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
1871 this.LockedLinearAxis.X = FreeAxis;
1872 this.LockedLinearAxisLow.X = -linearMax;
1873 this.LockedLinearAxisHigh.X = linearMax;
1874 break;
1875 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
1876 this.LockedLinearAxis.Y = FreeAxis;
1877 this.LockedLinearAxisLow.Y = -linearMax;
1878 this.LockedLinearAxisHigh.Y = linearMax;
1879 break;
1880 case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
1881 this.LockedLinearAxis.Z = FreeAxis;
1882 this.LockedLinearAxisLow.Z = -linearMax;
1883 this.LockedLinearAxisHigh.Z = linearMax;
1884 break;
1885 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
1886 this.LockedAngularAxis = LockedAxisFree;
1887 this.LockedAngularAxisLow = new OMV.Vector3(-angularMax, -angularMax, -angularMax);
1888 this.LockedAngularAxisHigh = new OMV.Vector3(angularMax, angularMax, angularMax);
1889 break;
1890 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
1891 this.LockedAngularAxis.X = FreeAxis;
1892 this.LockedAngularAxisLow.X = -angularMax;
1893 this.LockedAngularAxisHigh.X = angularMax;
1894 break;
1895 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
1896 this.LockedAngularAxis.Y = FreeAxis;
1897 this.LockedAngularAxisLow.Y = -angularMax;
1898 this.LockedAngularAxisHigh.Y = angularMax;
1899 break;
1900 case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
1901 this.LockedAngularAxis.Z = FreeAxis;
1902 this.LockedAngularAxisLow.Z = -angularMax;
1903 this.LockedAngularAxisHigh.Z = angularMax;
1904 break;
1905 case ExtendedPhysics.PHYS_AXIS_UNLOCK:
1906 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
1907 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
1908 break;
1909 default:
1910 break;
1911 }
1912 return;
1913 }
1610 #endregion // Extension 1914 #endregion // Extension
1611 1915
1612 // The physics engine says that properties have updated. Update same and inform 1916 // The physics engine says that properties have updated. Update same and inform