diff options
Diffstat (limited to 'OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs')
-rwxr-xr-x | OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs new file mode 100755 index 0000000..3b3c161 --- /dev/null +++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs | |||
@@ -0,0 +1,219 @@ | |||
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 copyrightD | ||
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 OMV = OpenMetaverse; | ||
34 | |||
35 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
36 | { | ||
37 | public class BSActorLockAxis : BSActor | ||
38 | { | ||
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; | ||
46 | |||
47 | public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) | ||
48 | : base(physicsScene, pObj, actorName) | ||
49 | { | ||
50 | m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); | ||
51 | LockAxisConstraint = null; | ||
52 | HaveRegisteredForBeforeStepCallback = false; | ||
53 | } | ||
54 | |||
55 | // BSActor.isActive | ||
56 | public override bool isActive | ||
57 | { | ||
58 | get { return Enabled && m_controllingPrim.IsPhysicallyActive; } | ||
59 | } | ||
60 | |||
61 | // Release any connections and resources used by the actor. | ||
62 | // BSActor.Dispose() | ||
63 | public override void Dispose() | ||
64 | { | ||
65 | Enabled = false; | ||
66 | UnRegisterForBeforeStepCallback(); | ||
67 | RemoveAxisLockConstraint(); | ||
68 | } | ||
69 | |||
70 | // Called when physical parameters (properties set in Bullet) need to be re-applied. | ||
71 | // Called at taint-time. | ||
72 | // BSActor.Refresh() | ||
73 | public override void Refresh() | ||
74 | { | ||
75 | // Since the axis logging is done with a constraint, Refresh() time is good for | ||
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 | |||
79 | // If all the axis are free, we don't need to exist | ||
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) | ||
85 | { | ||
86 | Enabled = false; | ||
87 | } | ||
88 | |||
89 | if (isActive) | ||
90 | { | ||
91 | RegisterForBeforeStepCallback(); | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | RemoveDependencies(); | ||
96 | UnRegisterForBeforeStepCallback(); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...). | ||
101 | // Register a prestep action to restore physical requirements before the next simulation step. | ||
102 | // Called at taint-time. | ||
103 | // BSActor.RemoveDependencies() | ||
104 | public override void RemoveDependencies() | ||
105 | { | ||
106 | RemoveAxisLockConstraint(); | ||
107 | } | ||
108 | |||
109 | private void RegisterForBeforeStepCallback() | ||
110 | { | ||
111 | if (!HaveRegisteredForBeforeStepCallback) | ||
112 | { | ||
113 | m_physicsScene.BeforeStep += PhysicsScene_BeforeStep; | ||
114 | HaveRegisteredForBeforeStepCallback = true; | ||
115 | } | ||
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) | ||
142 | { | ||
143 | // The locking has changed. Remove the old constraint and build a new one | ||
144 | RemoveAxisLockConstraint(); | ||
145 | } | ||
146 | |||
147 | AddAxisLockConstraint(); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | RemoveAxisLockConstraint(); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | // Note that this relies on being called at TaintTime | ||
156 | private void AddAxisLockConstraint() | ||
157 | { | ||
158 | if (LockAxisConstraint == null) | ||
159 | { | ||
160 | // Lock that axis by creating a 6DOF constraint that has one end in the world and | ||
161 | // the other in the object. | ||
162 | // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817 | ||
163 | // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380 | ||
164 | |||
165 | // Remove any existing axis constraint (just to be sure) | ||
166 | RemoveAxisLockConstraint(); | ||
167 | |||
168 | BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(m_physicsScene.World, m_controllingPrim.PhysBody, | ||
169 | OMV.Vector3.Zero, OMV.Quaternion.Identity, | ||
170 | false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */); | ||
171 | LockAxisConstraint = axisConstrainer; | ||
172 | m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); | ||
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 | |||
178 | // The constraint is tied to the world and oriented to the prim. | ||
179 | |||
180 | if (!axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh)) | ||
181 | { | ||
182 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits", | ||
183 | m_controllingPrim.LocalID); | ||
184 | } | ||
185 | |||
186 | if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh)) | ||
187 | { | ||
188 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", | ||
189 | m_controllingPrim.LocalID); | ||
190 | } | ||
191 | |||
192 | m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", | ||
193 | m_controllingPrim.LocalID, | ||
194 | m_controllingPrim.LockedLinearAxisLow, | ||
195 | m_controllingPrim.LockedLinearAxisHigh, | ||
196 | m_controllingPrim.LockedAngularAxisLow, | ||
197 | m_controllingPrim.LockedAngularAxisHigh); | ||
198 | |||
199 | // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. | ||
200 | axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); | ||
201 | |||
202 | axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass); | ||
203 | |||
204 | RegisterForBeforeStepCallback(); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | private void RemoveAxisLockConstraint() | ||
209 | { | ||
210 | UnRegisterForBeforeStepCallback(); | ||
211 | if (LockAxisConstraint != null) | ||
212 | { | ||
213 | m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); | ||
214 | LockAxisConstraint = null; | ||
215 | m_physicsScene.DetailLog("{0},BSActorLockAxis.RemoveAxisLockConstraint,destroyingConstraint", m_controllingPrim.LocalID); | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | } | ||