OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
BSActorLockAxis.cs
Go to the documentation of this file.
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.PhysicsModule.BulletS
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 }
OpenMetaverse OMV
Each physical object can have 'actors' who are pushing the object around. This can be used for hover...
Definition: BSActors.cs:118
BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)