diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs | 140 |
1 files changed, 86 insertions, 54 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs index 8b0fdeb..3b3c161 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -36,13 +36,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
36 | { | 36 | { |
37 | public class BSActorLockAxis : BSActor | 37 | public class BSActorLockAxis : BSActor |
38 | { | 38 | { |
39 | BSConstraint LockAxisConstraint = null; | 39 | private BSConstraint LockAxisConstraint = null; |
40 | private bool HaveRegisteredForBeforeStepCallback = false; | ||
41 | |||
42 | // The lock access flags (which axises were locked) when the contraint was built. | ||
43 | // Used to see if locking has changed since when the constraint was built. | ||
44 | OMV.Vector3 LockAxisLinearFlags; | ||
45 | OMV.Vector3 LockAxisAngularFlags; | ||
40 | 46 | ||
41 | public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) | 47 | public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) |
42 | : base(physicsScene, pObj, actorName) | 48 | : base(physicsScene, pObj, actorName) |
43 | { | 49 | { |
44 | m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); | 50 | m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); |
45 | LockAxisConstraint = null; | 51 | LockAxisConstraint = null; |
52 | HaveRegisteredForBeforeStepCallback = false; | ||
46 | } | 53 | } |
47 | 54 | ||
48 | // BSActor.isActive | 55 | // BSActor.isActive |
@@ -55,6 +62,8 @@ public class BSActorLockAxis : BSActor | |||
55 | // BSActor.Dispose() | 62 | // BSActor.Dispose() |
56 | public override void Dispose() | 63 | public override void Dispose() |
57 | { | 64 | { |
65 | Enabled = false; | ||
66 | UnRegisterForBeforeStepCallback(); | ||
58 | RemoveAxisLockConstraint(); | 67 | RemoveAxisLockConstraint(); |
59 | } | 68 | } |
60 | 69 | ||
@@ -63,22 +72,28 @@ public class BSActorLockAxis : BSActor | |||
63 | // BSActor.Refresh() | 72 | // BSActor.Refresh() |
64 | public override void Refresh() | 73 | public override void Refresh() |
65 | { | 74 | { |
66 | m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}", | 75 | // 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); | 76 | // changing parameters but this needs to wait until the prim/linkset is physically |
77 | // constructed. Therefore, the constraint itself is placed at pre-step time. | ||
78 | |||
68 | // If all the axis are free, we don't need to exist | 79 | // If all the axis are free, we don't need to exist |
69 | if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree) | 80 | // Refresh() only turns off. Enabling is done by InitializeAxisActor() |
81 | // whenever parameters are changed. | ||
82 | // This leaves 'enable' free to turn off an actor when it is not wanted to run. | ||
83 | if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree | ||
84 | && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree) | ||
70 | { | 85 | { |
71 | Enabled = false; | 86 | Enabled = false; |
72 | } | 87 | } |
73 | 88 | ||
74 | // If the object is physically active, add the axis locking constraint | ||
75 | if (isActive) | 89 | if (isActive) |
76 | { | 90 | { |
77 | AddAxisLockConstraint(); | 91 | RegisterForBeforeStepCallback(); |
78 | } | 92 | } |
79 | else | 93 | else |
80 | { | 94 | { |
81 | RemoveAxisLockConstraint(); | 95 | RemoveDependencies(); |
96 | UnRegisterForBeforeStepCallback(); | ||
82 | } | 97 | } |
83 | } | 98 | } |
84 | 99 | ||
@@ -88,18 +103,56 @@ public class BSActorLockAxis : BSActor | |||
88 | // BSActor.RemoveDependencies() | 103 | // BSActor.RemoveDependencies() |
89 | public override void RemoveDependencies() | 104 | public override void RemoveDependencies() |
90 | { | 105 | { |
91 | if (LockAxisConstraint != null) | 106 | RemoveAxisLockConstraint(); |
107 | } | ||
108 | |||
109 | private void RegisterForBeforeStepCallback() | ||
110 | { | ||
111 | if (!HaveRegisteredForBeforeStepCallback) | ||
92 | { | 112 | { |
93 | // If a constraint is set up, remove it from the physical scene | 113 | m_physicsScene.BeforeStep += PhysicsScene_BeforeStep; |
94 | RemoveAxisLockConstraint(); | 114 | HaveRegisteredForBeforeStepCallback = true; |
95 | // Schedule a call before the next simulation step to restore the constraint. | 115 | } |
96 | m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate() | 116 | } |
117 | |||
118 | private void UnRegisterForBeforeStepCallback() | ||
119 | { | ||
120 | if (HaveRegisteredForBeforeStepCallback) | ||
121 | { | ||
122 | m_physicsScene.BeforeStep -= PhysicsScene_BeforeStep; | ||
123 | HaveRegisteredForBeforeStepCallback = false; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | private void PhysicsScene_BeforeStep(float timestep) | ||
128 | { | ||
129 | // If all the axis are free, we don't need to exist | ||
130 | if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree | ||
131 | && m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree) | ||
132 | { | ||
133 | Enabled = false; | ||
134 | } | ||
135 | |||
136 | // If the object is physically active, add the axis locking constraint | ||
137 | if (isActive) | ||
138 | { | ||
139 | // Check to see if the locking parameters have changed | ||
140 | if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags | ||
141 | || m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags) | ||
97 | { | 142 | { |
98 | Refresh(); | 143 | // The locking has changed. Remove the old constraint and build a new one |
99 | }); | 144 | RemoveAxisLockConstraint(); |
145 | } | ||
146 | |||
147 | AddAxisLockConstraint(); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | RemoveAxisLockConstraint(); | ||
100 | } | 152 | } |
101 | } | 153 | } |
102 | 154 | ||
155 | // Note that this relies on being called at TaintTime | ||
103 | private void AddAxisLockConstraint() | 156 | private void AddAxisLockConstraint() |
104 | { | 157 | { |
105 | if (LockAxisConstraint == null) | 158 | if (LockAxisConstraint == null) |
@@ -118,64 +171,43 @@ public class BSActorLockAxis : BSActor | |||
118 | LockAxisConstraint = axisConstrainer; | 171 | LockAxisConstraint = axisConstrainer; |
119 | m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); | 172 | m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); |
120 | 173 | ||
174 | // Remember the clocking being inforced so we can notice if they have changed | ||
175 | LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis; | ||
176 | LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis; | ||
177 | |||
121 | // The constraint is tied to the world and oriented to the prim. | 178 | // The constraint is tied to the world and oriented to the prim. |
122 | 179 | ||
123 | // Free to move linearly in the region | 180 | 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 | if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis) | ||
127 | { | 181 | { |
128 | linearLow.X = m_controllingPrim.RawPosition.X; | 182 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits", |
129 | linearHigh.X = m_controllingPrim.RawPosition.X; | 183 | m_controllingPrim.LocalID); |
130 | } | 184 | } |
131 | if (m_controllingPrim.LockedLinearAxis.Y != BSPhysObject.FreeAxis) | ||
132 | { | ||
133 | linearLow.Y = m_controllingPrim.RawPosition.Y; | ||
134 | linearHigh.Y = m_controllingPrim.RawPosition.Y; | ||
135 | } | ||
136 | if (m_controllingPrim.LockedLinearAxis.Z != BSPhysObject.FreeAxis) | ||
137 | { | ||
138 | linearLow.Z = m_controllingPrim.RawPosition.Z; | ||
139 | linearHigh.Z = m_controllingPrim.RawPosition.Z; | ||
140 | } | ||
141 | axisConstrainer.SetLinearLimits(linearLow, linearHigh); | ||
142 | 185 | ||
143 | // Angular with some axis locked | 186 | if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh)) |
144 | float fPI = (float)Math.PI; | ||
145 | OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI); | ||
146 | OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI); | ||
147 | if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis) | ||
148 | { | ||
149 | angularLow.X = 0f; | ||
150 | angularHigh.X = 0f; | ||
151 | } | ||
152 | if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis) | ||
153 | { | 187 | { |
154 | angularLow.Y = 0f; | 188 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", |
155 | angularHigh.Y = 0f; | 189 | m_controllingPrim.LocalID); |
156 | } | ||
157 | if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis) | ||
158 | { | ||
159 | angularLow.Z = 0f; | ||
160 | angularHigh.Z = 0f; | ||
161 | } | ||
162 | if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh)) | ||
163 | { | ||
164 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID); | ||
165 | } | 190 | } |
166 | 191 | ||
167 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", | 192 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", |
168 | m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh); | 193 | m_controllingPrim.LocalID, |
194 | m_controllingPrim.LockedLinearAxisLow, | ||
195 | m_controllingPrim.LockedLinearAxisHigh, | ||
196 | m_controllingPrim.LockedAngularAxisLow, | ||
197 | m_controllingPrim.LockedAngularAxisHigh); | ||
169 | 198 | ||
170 | // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. | 199 | // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. |
171 | axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); | 200 | axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); |
172 | 201 | ||
173 | axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass); | 202 | axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass); |
203 | |||
204 | RegisterForBeforeStepCallback(); | ||
174 | } | 205 | } |
175 | } | 206 | } |
176 | 207 | ||
177 | private void RemoveAxisLockConstraint() | 208 | private void RemoveAxisLockConstraint() |
178 | { | 209 | { |
210 | UnRegisterForBeforeStepCallback(); | ||
179 | if (LockAxisConstraint != null) | 211 | if (LockAxisConstraint != null) |
180 | { | 212 | { |
181 | m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); | 213 | m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); |