diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index bf262c5..f68e06e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -40,9 +40,12 @@ public class BSLinkset | |||
40 | public BSPrim Root { get { return m_linksetRoot; } } | 40 | public BSPrim Root { get { return m_linksetRoot; } } |
41 | 41 | ||
42 | private BSScene m_scene; | 42 | private BSScene m_scene; |
43 | public BSScene Scene { get { return m_scene; } } | ||
43 | 44 | ||
44 | private List<BSPrim> m_children; | 45 | private List<BSPrim> m_children; |
45 | 46 | ||
47 | public int NumberOfChildren { get { return m_children.Count; } } | ||
48 | |||
46 | // We lock the diddling of linkset classes to prevent any badness. | 49 | // We lock the diddling of linkset classes to prevent any badness. |
47 | // This locks the modification of the instances of this class. Changes | 50 | // This locks the modification of the instances of this class. Changes |
48 | // to the physical representation is done via the tainting mechenism. | 51 | // to the physical representation is done via the tainting mechenism. |
@@ -113,9 +116,10 @@ public class BSLinkset | |||
113 | } | 116 | } |
114 | 117 | ||
115 | // The child is down to a linkset of just itself | 118 | // The child is down to a linkset of just itself |
116 | return new BSLinkset(m_scene, child); | 119 | return new BSLinkset(Scene, child); |
117 | } | 120 | } |
118 | 121 | ||
122 | /* DEPRECATED: this is really bad in that it trys to unlink other prims. | ||
119 | // An existing linkset had one of its members rebuilt or something. | 123 | // An existing linkset had one of its members rebuilt or something. |
120 | // Go through the linkset and rebuild the pointers to the bodies of the linkset members. | 124 | // Go through the linkset and rebuild the pointers to the bodies of the linkset members. |
121 | public BSLinkset RefreshLinkset(BSPrim requestor) | 125 | public BSLinkset RefreshLinkset(BSPrim requestor) |
@@ -163,6 +167,7 @@ public class BSLinkset | |||
163 | 167 | ||
164 | return ret; | 168 | return ret; |
165 | } | 169 | } |
170 | */ | ||
166 | 171 | ||
167 | 172 | ||
168 | // Return 'true' if the passed object is the root object of this linkset | 173 | // Return 'true' if the passed object is the root object of this linkset |
@@ -229,18 +234,19 @@ public class BSLinkset | |||
229 | } | 234 | } |
230 | 235 | ||
231 | // I am the root of a linkset and a new child is being added | 236 | // I am the root of a linkset and a new child is being added |
232 | public void AddChildToLinkset(BSPrim pchild) | 237 | // Called while LinkActivity is locked. |
238 | public void AddChildToLinkset(BSPrim child) | ||
233 | { | 239 | { |
234 | BSPrim child = pchild; | ||
235 | if (!HasChild(child)) | 240 | if (!HasChild(child)) |
236 | { | 241 | { |
237 | m_children.Add(child); | 242 | m_children.Add(child); |
238 | 243 | ||
244 | BSPrim root = Root; // capture the root as of now | ||
239 | m_scene.TaintedObject("AddChildToLinkset", delegate() | 245 | m_scene.TaintedObject("AddChildToLinkset", delegate() |
240 | { | 246 | { |
241 | DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); | 247 | DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); |
242 | DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); | 248 | DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); |
243 | PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child | 249 | PhysicallyLinkAChildToRoot(root, child); // build the physical binding between me and the child |
244 | }); | 250 | }); |
245 | } | 251 | } |
246 | return; | 252 | return; |
@@ -259,26 +265,17 @@ public class BSLinkset | |||
259 | 265 | ||
260 | // I am the root of a linkset and one of my children is being removed. | 266 | // I am the root of a linkset and one of my children is being removed. |
261 | // Safe to call even if the child is not really in my linkset. | 267 | // Safe to call even if the child is not really in my linkset. |
262 | public void RemoveChildFromLinkset(BSPrim pchild) | 268 | public void RemoveChildFromLinkset(BSPrim child) |
263 | { | 269 | { |
264 | BSPrim child = pchild; | ||
265 | |||
266 | if (m_children.Remove(child)) | 270 | if (m_children.Remove(child)) |
267 | { | 271 | { |
272 | BSPrim root = Root; // capture the root as of now | ||
268 | m_scene.TaintedObject("RemoveChildFromLinkset", delegate() | 273 | m_scene.TaintedObject("RemoveChildFromLinkset", delegate() |
269 | { | 274 | { |
270 | DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); | 275 | DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); |
271 | DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); | 276 | DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); |
272 | 277 | ||
273 | if (m_children.Count == 0) | 278 | PhysicallyUnlinkAChildFromRoot(root, child); |
274 | { | ||
275 | // if the linkset is empty, make sure all linkages have been removed | ||
276 | PhysicallyUnlinkAllChildrenFromRoot(); | ||
277 | } | ||
278 | else | ||
279 | { | ||
280 | PhysicallyUnlinkAChildFromRoot(pchild); | ||
281 | } | ||
282 | }); | 279 | }); |
283 | } | 280 | } |
284 | else | 281 | else |
@@ -291,14 +288,14 @@ public class BSLinkset | |||
291 | 288 | ||
292 | // Create a constraint between me (root of linkset) and the passed prim (the child). | 289 | // Create a constraint between me (root of linkset) and the passed prim (the child). |
293 | // Called at taint time! | 290 | // Called at taint time! |
294 | private void PhysicallyLinkAChildToRoot(BSPrim childPrim) | 291 | private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim) |
295 | { | 292 | { |
296 | // Zero motion for children so they don't interpolate | 293 | // Zero motion for children so they don't interpolate |
297 | childPrim.ZeroMotion(); | 294 | childPrim.ZeroMotion(); |
298 | 295 | ||
299 | // relative position normalized to the root prim | 296 | // relative position normalized to the root prim |
300 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation); | 297 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); |
301 | OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation; | 298 | OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; |
302 | 299 | ||
303 | // relative rotation of the child to the parent | 300 | // relative rotation of the child to the parent |
304 | OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; | 301 | OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; |
@@ -306,9 +303,9 @@ public class BSLinkset | |||
306 | // create a constraint that allows no freedom of movement between the two objects | 303 | // create a constraint that allows no freedom of movement between the two objects |
307 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | 304 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 |
308 | // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); | 305 | // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); |
309 | DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); | 306 | DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); |
310 | BS6DofConstraint constrain = new BS6DofConstraint( | 307 | BS6DofConstraint constrain = new BS6DofConstraint( |
311 | m_scene.World, m_linksetRoot.Body, childPrim.Body, | 308 | m_scene.World, rootPrim.Body, childPrim.Body, |
312 | childRelativePosition, | 309 | childRelativePosition, |
313 | childRelativeRotation, | 310 | childRelativeRotation, |
314 | OMV.Vector3.Zero, | 311 | OMV.Vector3.Zero, |
@@ -331,25 +328,25 @@ public class BSLinkset | |||
331 | 328 | ||
332 | // Remove linkage between myself and a particular child | 329 | // Remove linkage between myself and a particular child |
333 | // Called at taint time! | 330 | // Called at taint time! |
334 | private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim) | 331 | private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) |
335 | { | 332 | { |
336 | // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", | 333 | // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", |
337 | // LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); | 334 | // LogHeader, rootPrim.LocalID, childPrim.LocalID); |
338 | DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); | 335 | DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); |
339 | 336 | ||
340 | m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body); | 337 | m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); |
341 | // Make the child refresh its location | 338 | // Make the child refresh its location |
342 | BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); | 339 | BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); |
343 | } | 340 | } |
344 | 341 | ||
345 | // Remove linkage between myself and any possible children I might have | 342 | // Remove linkage between myself and any possible children I might have |
346 | // Called at taint time! | 343 | // Called at taint time! |
347 | private void PhysicallyUnlinkAllChildrenFromRoot() | 344 | private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) |
348 | { | 345 | { |
349 | // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); | 346 | // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); |
350 | DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID); | 347 | DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); |
351 | 348 | ||
352 | m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body); | 349 | m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); |
353 | } | 350 | } |
354 | 351 | ||
355 | // Invoke the detailed logger and output something if it's enabled. | 352 | // Invoke the detailed logger and output something if it's enabled. |