OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
BSConstraintCollection.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 using System;
28 using System.Collections.Generic;
29 using System.Text;
30 using log4net;
31 using OpenMetaverse;
32 
33 namespace OpenSim.Region.PhysicsModule.BulletS
34 {
35 
36 public sealed class BSConstraintCollection : IDisposable
37 {
38  // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
39  // private static readonly string LogHeader = "[CONSTRAINT COLLECTION]";
40 
41  delegate bool ConstraintAction(BSConstraint constrain);
42 
43  private List<BSConstraint> m_constraints;
44  private BulletWorld m_world;
45 
47  {
48  m_world = world;
49  m_constraints = new List<BSConstraint>();
50  }
51 
52  public void Dispose()
53  {
54  this.Clear();
55  }
56 
57  public void Clear()
58  {
59  lock (m_constraints)
60  {
61  foreach (BSConstraint cons in m_constraints)
62  {
63  cons.Dispose();
64  }
65  m_constraints.Clear();
66  }
67  }
68 
69  public bool AddConstraint(BSConstraint cons)
70  {
71  lock (m_constraints)
72  {
73  // There is only one constraint between any bodies. Remove any old just to make sure.
74  RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
75 
76  m_constraints.Add(cons);
77  }
78 
79  return true;
80  }
81 
82  // Get the constraint between two bodies. There can be only one.
83  // Return 'true' if a constraint was found.
84  public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint)
85  {
86  bool found = false;
87  BSConstraint foundConstraint = null;
88 
89  uint lookingID1 = body1.ID;
90  uint lookingID2 = body2.ID;
91  lock (m_constraints)
92  {
93  foreach (BSConstraint constrain in m_constraints)
94  {
95  if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
96  || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
97  {
98  foundConstraint = constrain;
99  found = true;
100  break;
101  }
102  }
103  }
104  returnConstraint = foundConstraint;
105  return found;
106  }
107 
108  // Remove any constraint between the passed bodies.
109  // Presumed there is only one such constraint possible.
110  // Return 'true' if a constraint was found and destroyed.
112  {
113  bool ret = false;
114  lock (m_constraints)
115  {
116  BSConstraint constrain;
117  if (this.TryGetConstraint(body1, body2, out constrain))
118  {
119  // remove the constraint from our collection
120  ret = RemoveAndDestroyConstraint(constrain);
121  }
122  }
123 
124  return ret;
125  }
126 
127  // The constraint MUST exist in the collection
128  // Could be called if the constraint was previously removed.
129  // Return 'true' if the constraint was actually removed and disposed.
131  {
132  bool removed = false;
133  lock (m_constraints)
134  {
135  // remove the constraint from our collection
136  removed = m_constraints.Remove(constrain);
137  }
138  // Dispose() is safe to call multiple times
139  constrain.Dispose();
140  return removed;
141  }
142 
143  // Remove all constraints that reference the passed body.
144  // Return 'true' if any constraints were destroyed.
146  {
147  List<BSConstraint> toRemove = new List<BSConstraint>();
148  uint lookingID = body1.ID;
149  lock (m_constraints)
150  {
151  foreach (BSConstraint constrain in m_constraints)
152  {
153  if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
154  {
155  toRemove.Add(constrain);
156  }
157  }
158  foreach (BSConstraint constrain in toRemove)
159  {
160  m_constraints.Remove(constrain);
161  constrain.Dispose();
162  }
163  }
164  return (toRemove.Count > 0);
165  }
166 
168  {
169  bool ret = false;
170  lock (m_constraints)
171  {
172  foreach (BSConstraint constrain in m_constraints)
173  {
174  constrain.CalculateTransforms();
175  ret = true;
176  }
177  }
178  return ret;
179  }
180 }
181 }
bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint)
bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)