aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs104
1 files changed, 55 insertions, 49 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 0df4310..4ece1eb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -32,6 +32,15 @@ using OMV = OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35
36// A BSPrim can get individual information about its linkedness attached
37// to it through an instance of a subclass of LinksetInfo.
38// Each type of linkset will define the information needed for its type.
39public abstract class BSLinksetInfo
40{
41 public virtual void Clear() { }
42}
43
35public abstract class BSLinkset 44public abstract class BSLinkset
36{ 45{
37 // private static string LogHeader = "[BULLETSIM LINKSET]"; 46 // private static string LogHeader = "[BULLETSIM LINKSET]";
@@ -43,11 +52,11 @@ public abstract class BSLinkset
43 Manual = 2 // linkset tied together manually (code moves all the pieces) 52 Manual = 2 // linkset tied together manually (code moves all the pieces)
44 } 53 }
45 // Create the correct type of linkset for this child 54 // Create the correct type of linkset for this child
46 public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) 55 public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent)
47 { 56 {
48 BSLinkset ret = null; 57 BSLinkset ret = null;
49 58
50 switch ((int)physScene.Params.linksetImplementation) 59 switch ((int)BSParam.LinksetImplementation)
51 { 60 {
52 case (int)LinksetImplementation.Constraint: 61 case (int)LinksetImplementation.Constraint:
53 ret = new BSLinksetConstraints(physScene, parent); 62 ret = new BSLinksetConstraints(physScene, parent);
@@ -62,10 +71,14 @@ public abstract class BSLinkset
62 ret = new BSLinksetCompound(physScene, parent); 71 ret = new BSLinksetCompound(physScene, parent);
63 break; 72 break;
64 } 73 }
74 if (ret == null)
75 {
76 physScene.Logger.ErrorFormat("[BULLETSIM LINKSET] Factory could not create linkset. Parent name={1}, ID={2}", parent.Name, parent.LocalID);
77 }
65 return ret; 78 return ret;
66 } 79 }
67 80
68 public BSPhysObject LinksetRoot { get; protected set; } 81 public BSPrimLinkable LinksetRoot { get; protected set; }
69 82
70 public BSScene PhysicsScene { get; private set; } 83 public BSScene PhysicsScene { get; private set; }
71 84
@@ -73,7 +86,7 @@ public abstract class BSLinkset
73 public int LinksetID { get; private set; } 86 public int LinksetID { get; private set; }
74 87
75 // The children under the root in this linkset. 88 // The children under the root in this linkset.
76 protected HashSet<BSPhysObject> m_children; 89 protected HashSet<BSPrimLinkable> m_children;
77 90
78 // We lock the diddling of linkset classes to prevent any badness. 91 // We lock the diddling of linkset classes to prevent any badness.
79 // This locks the modification of the instances of this class. Changes 92 // This locks the modification of the instances of this class. Changes
@@ -82,27 +95,13 @@ public abstract class BSLinkset
82 95
83 // Some linksets have a preferred physical shape. 96 // Some linksets have a preferred physical shape.
84 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. 97 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
85 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) 98 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
86 { 99 {
87 return BSPhysicsShapeType.SHAPE_UNKNOWN; 100 return BSPhysicsShapeType.SHAPE_UNKNOWN;
88 } 101 }
89 102
90 // Linksets move around the children so the linkset might need to compute the child position
91 public virtual OMV.Vector3 Position(BSPhysObject member)
92 { return member.RawPosition; }
93 public virtual OMV.Quaternion Orientation(BSPhysObject member)
94 { return member.RawOrientation; }
95 // TODO: does this need to be done for Velocity and RotationalVelocityy?
96
97 // We keep the prim's mass in the linkset structure since it could be dependent on other prims 103 // We keep the prim's mass in the linkset structure since it could be dependent on other prims
98 protected float m_mass; 104 public float LinksetMass { get; protected set; }
99 public float LinksetMass
100 {
101 get
102 {
103 return m_mass;
104 }
105 }
106 105
107 public virtual bool LinksetIsColliding { get { return false; } } 106 public virtual bool LinksetIsColliding { get { return false; } }
108 107
@@ -116,7 +115,7 @@ public abstract class BSLinkset
116 get { return ComputeLinksetGeometricCenter(); } 115 get { return ComputeLinksetGeometricCenter(); }
117 } 116 }
118 117
119 protected void Initialize(BSScene scene, BSPhysObject parent) 118 protected BSLinkset(BSScene scene, BSPrimLinkable parent)
120 { 119 {
121 // A simple linkset of one (no children) 120 // A simple linkset of one (no children)
122 LinksetID = m_nextLinksetID++; 121 LinksetID = m_nextLinksetID++;
@@ -125,22 +124,25 @@ public abstract class BSLinkset
125 m_nextLinksetID = 1; 124 m_nextLinksetID = 1;
126 PhysicsScene = scene; 125 PhysicsScene = scene;
127 LinksetRoot = parent; 126 LinksetRoot = parent;
128 m_children = new HashSet<BSPhysObject>(); 127 m_children = new HashSet<BSPrimLinkable>();
129 m_mass = parent.RawMass; 128 LinksetMass = parent.RawMass;
129 Rebuilding = false;
130
131 parent.ClearDisplacement();
130 } 132 }
131 133
132 // Link to a linkset where the child knows the parent. 134 // Link to a linkset where the child knows the parent.
133 // Parent changing should not happen so do some sanity checking. 135 // Parent changing should not happen so do some sanity checking.
134 // We return the parent's linkset so the child can track its membership. 136 // We return the parent's linkset so the child can track its membership.
135 // Called at runtime. 137 // Called at runtime.
136 public BSLinkset AddMeToLinkset(BSPhysObject child) 138 public BSLinkset AddMeToLinkset(BSPrimLinkable child)
137 { 139 {
138 lock (m_linksetActivityLock) 140 lock (m_linksetActivityLock)
139 { 141 {
140 // Don't add the root to its own linkset 142 // Don't add the root to its own linkset
141 if (!IsRoot(child)) 143 if (!IsRoot(child))
142 AddChildToLinkset(child); 144 AddChildToLinkset(child);
143 m_mass = ComputeLinksetMass(); 145 LinksetMass = ComputeLinksetMass();
144 } 146 }
145 return this; 147 return this;
146 } 148 }
@@ -149,7 +151,7 @@ public abstract class BSLinkset
149 // Returns a new linkset for the child which is a linkset of one (just the 151 // Returns a new linkset for the child which is a linkset of one (just the
150 // orphened child). 152 // orphened child).
151 // Called at runtime. 153 // Called at runtime.
152 public BSLinkset RemoveMeFromLinkset(BSPhysObject child) 154 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
153 { 155 {
154 lock (m_linksetActivityLock) 156 lock (m_linksetActivityLock)
155 { 157 {
@@ -159,7 +161,7 @@ public abstract class BSLinkset
159 return this; 161 return this;
160 } 162 }
161 RemoveChildFromLinkset(child); 163 RemoveChildFromLinkset(child);
162 m_mass = ComputeLinksetMass(); 164 LinksetMass = ComputeLinksetMass();
163 } 165 }
164 166
165 // The child is down to a linkset of just itself 167 // The child is down to a linkset of just itself
@@ -167,7 +169,7 @@ public abstract class BSLinkset
167 } 169 }
168 170
169 // Return 'true' if the passed object is the root object of this linkset 171 // Return 'true' if the passed object is the root object of this linkset
170 public bool IsRoot(BSPhysObject requestor) 172 public bool IsRoot(BSPrimLinkable requestor)
171 { 173 {
172 return (requestor.LocalID == LinksetRoot.LocalID); 174 return (requestor.LocalID == LinksetRoot.LocalID);
173 } 175 }
@@ -178,14 +180,14 @@ public abstract class BSLinkset
178 public bool HasAnyChildren { get { return (m_children.Count > 0); } } 180 public bool HasAnyChildren { get { return (m_children.Count > 0); } }
179 181
180 // Return 'true' if this child is in this linkset 182 // Return 'true' if this child is in this linkset
181 public bool HasChild(BSPhysObject child) 183 public bool HasChild(BSPrimLinkable child)
182 { 184 {
183 bool ret = false; 185 bool ret = false;
184 lock (m_linksetActivityLock) 186 lock (m_linksetActivityLock)
185 { 187 {
186 ret = m_children.Contains(child); 188 ret = m_children.Contains(child);
187 /* Safer version but the above should work 189 /* Safer version but the above should work
188 foreach (BSPhysObject bp in m_children) 190 foreach (BSPrimLinkable bp in m_children)
189 { 191 {
190 if (child.LocalID == bp.LocalID) 192 if (child.LocalID == bp.LocalID)
191 { 193 {
@@ -200,14 +202,14 @@ public abstract class BSLinkset
200 202
201 // Perform an action on each member of the linkset including root prim. 203 // Perform an action on each member of the linkset including root prim.
202 // Depends on the action on whether this should be done at taint time. 204 // Depends on the action on whether this should be done at taint time.
203 public delegate bool ForEachMemberAction(BSPhysObject obj); 205 public delegate bool ForEachMemberAction(BSPrimLinkable obj);
204 public virtual bool ForEachMember(ForEachMemberAction action) 206 public virtual bool ForEachMember(ForEachMemberAction action)
205 { 207 {
206 bool ret = false; 208 bool ret = false;
207 lock (m_linksetActivityLock) 209 lock (m_linksetActivityLock)
208 { 210 {
209 action(LinksetRoot); 211 action(LinksetRoot);
210 foreach (BSPhysObject po in m_children) 212 foreach (BSPrimLinkable po in m_children)
211 { 213 {
212 if (action(po)) 214 if (action(po))
213 break; 215 break;
@@ -218,16 +220,23 @@ public abstract class BSLinkset
218 220
219 // I am the root of a linkset and a new child is being added 221 // I am the root of a linkset and a new child is being added
220 // Called while LinkActivity is locked. 222 // Called while LinkActivity is locked.
221 protected abstract void AddChildToLinkset(BSPhysObject child); 223 protected abstract void AddChildToLinkset(BSPrimLinkable child);
222 224
223 // I am the root of a linkset and one of my children is being removed. 225 // I am the root of a linkset and one of my children is being removed.
224 // Safe to call even if the child is not really in my linkset. 226 // Safe to call even if the child is not really in my linkset.
225 protected abstract void RemoveChildFromLinkset(BSPhysObject child); 227 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
226 228
227 // When physical properties are changed the linkset needs to recalculate 229 // When physical properties are changed the linkset needs to recalculate
228 // its internal properties. 230 // its internal properties.
229 // May be called at runtime or taint-time. 231 // May be called at runtime or taint-time.
230 public abstract void Refresh(BSPhysObject requestor); 232 public virtual void Refresh(BSPrimLinkable requestor)
233 {
234 LinksetMass = ComputeLinksetMass();
235 }
236
237 // Flag denoting the linkset is in the process of being rebuilt.
238 // Used to know not the schedule a rebuild in the middle of a rebuild.
239 protected bool Rebuilding { get; set; }
231 240
232 // The object is going dynamic (physical). Do any setup necessary 241 // The object is going dynamic (physical). Do any setup necessary
233 // for a dynamic linkset. 242 // for a dynamic linkset.
@@ -235,30 +244,26 @@ public abstract class BSLinkset
235 // has not yet been fully constructed. 244 // has not yet been fully constructed.
236 // Return 'true' if any properties updated on the passed object. 245 // Return 'true' if any properties updated on the passed object.
237 // Called at taint-time! 246 // Called at taint-time!
238 public abstract bool MakeDynamic(BSPhysObject child); 247 public abstract bool MakeDynamic(BSPrimLinkable child);
239 248
240 // The object is going static (non-physical). Do any setup necessary 249 // The object is going static (non-physical). Do any setup necessary
241 // for a static linkset. 250 // for a static linkset.
242 // Return 'true' if any properties updated on the passed object. 251 // Return 'true' if any properties updated on the passed object.
243 // Called at taint-time! 252 // Called at taint-time!
244 public abstract bool MakeStatic(BSPhysObject child); 253 public abstract bool MakeStatic(BSPrimLinkable child);
245 254
246 // Called when a parameter update comes from the physics engine for any object 255 // Called when a parameter update comes from the physics engine for any object
247 // of the linkset is received. 256 // of the linkset is received.
257 // Passed flag is update came from physics engine (true) or the user (false).
248 // Called at taint-time!! 258 // Called at taint-time!!
249 public abstract void UpdateProperties(BSPhysObject physObject); 259 public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable physObject);
250 260
251 // Routine used when rebuilding the body of the root of the linkset 261 // Routine used when rebuilding the body of the root of the linkset
252 // Destroy all the constraints have have been made to root. 262 // Destroy all the constraints have have been made to root.
253 // This is called when the root body is changing. 263 // This is called when the root body is changing.
254 // Returns 'true' of something was actually removed and would need restoring 264 // Returns 'true' of something was actually removed and would need restoring
255 // Called at taint-time!! 265 // Called at taint-time!!
256 public abstract bool RemoveBodyDependencies(BSPrim child); 266 public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
257
258 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
259 // this routine will restore the removed constraints.
260 // Called at taint-time!!
261 public abstract void RestoreBodyDependencies(BSPrim child);
262 267
263 // ================================================================ 268 // ================================================================
264 protected virtual float ComputeLinksetMass() 269 protected virtual float ComputeLinksetMass()
@@ -268,7 +273,7 @@ public abstract class BSLinkset
268 { 273 {
269 lock (m_linksetActivityLock) 274 lock (m_linksetActivityLock)
270 { 275 {
271 foreach (BSPhysObject bp in m_children) 276 foreach (BSPrimLinkable bp in m_children)
272 { 277 {
273 mass += bp.RawMass; 278 mass += bp.RawMass;
274 } 279 }
@@ -277,6 +282,7 @@ public abstract class BSLinkset
277 return mass; 282 return mass;
278 } 283 }
279 284
285 // Computes linkset's center of mass in world coordinates.
280 protected virtual OMV.Vector3 ComputeLinksetCenterOfMass() 286 protected virtual OMV.Vector3 ComputeLinksetCenterOfMass()
281 { 287 {
282 OMV.Vector3 com; 288 OMV.Vector3 com;
@@ -285,7 +291,7 @@ public abstract class BSLinkset
285 com = LinksetRoot.Position * LinksetRoot.RawMass; 291 com = LinksetRoot.Position * LinksetRoot.RawMass;
286 float totalMass = LinksetRoot.RawMass; 292 float totalMass = LinksetRoot.RawMass;
287 293
288 foreach (BSPhysObject bp in m_children) 294 foreach (BSPrimLinkable bp in m_children)
289 { 295 {
290 com += bp.Position * bp.RawMass; 296 com += bp.Position * bp.RawMass;
291 totalMass += bp.RawMass; 297 totalMass += bp.RawMass;
@@ -304,9 +310,9 @@ public abstract class BSLinkset
304 { 310 {
305 com = LinksetRoot.Position; 311 com = LinksetRoot.Position;
306 312
307 foreach (BSPhysObject bp in m_children) 313 foreach (BSPrimLinkable bp in m_children)
308 { 314 {
309 com += bp.Position * bp.RawMass; 315 com += bp.Position;
310 } 316 }
311 com /= (m_children.Count + 1); 317 com /= (m_children.Count + 1);
312 } 318 }