aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs113
1 files changed, 45 insertions, 68 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index c855fda..6d252ca 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -36,23 +36,27 @@ public sealed class BSLinksetConstraints : BSLinkset
36{ 36{
37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; 37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
38 38
39 public BSLinksetConstraints(BSScene scene, BSPhysObject parent) 39 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
40 { 40 {
41 base.Initialize(scene, parent);
42 } 41 }
43 42
44 // When physical properties are changed the linkset needs to recalculate 43 // When physical properties are changed the linkset needs to recalculate
45 // its internal properties. 44 // its internal properties.
46 // This is queued in the 'post taint' queue so the 45 // This is queued in the 'post taint' queue so the
47 // refresh will happen once after all the other taints are applied. 46 // refresh will happen once after all the other taints are applied.
48 public override void Refresh(BSPhysObject requestor) 47 public override void Refresh(BSPrimLinkable requestor)
49 { 48 {
50 // Queue to happen after all the other taint processing 49 base.Refresh(requestor);
51 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() 50
52 { 51 if (HasAnyChildren && IsRoot(requestor))
53 if (HasAnyChildren && IsRoot(requestor)) 52 {
54 RecomputeLinksetConstraints(); 53 // Queue to happen after all the other taint processing
55 }); 54 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
55 {
56 if (HasAnyChildren && IsRoot(requestor))
57 RecomputeLinksetConstraints();
58 });
59 }
56 } 60 }
57 61
58 // The object is going dynamic (physical). Do any setup necessary 62 // The object is going dynamic (physical). Do any setup necessary
@@ -61,7 +65,7 @@ public sealed class BSLinksetConstraints : BSLinkset
61 // has not yet been fully constructed. 65 // has not yet been fully constructed.
62 // Return 'true' if any properties updated on the passed object. 66 // Return 'true' if any properties updated on the passed object.
63 // Called at taint-time! 67 // Called at taint-time!
64 public override bool MakeDynamic(BSPhysObject child) 68 public override bool MakeDynamic(BSPrimLinkable child)
65 { 69 {
66 // What is done for each object in BSPrim is what we want. 70 // What is done for each object in BSPrim is what we want.
67 return false; 71 return false;
@@ -72,41 +76,29 @@ public sealed class BSLinksetConstraints : BSLinkset
72 // This doesn't normally happen -- OpenSim removes the objects from the physical 76 // This doesn't normally happen -- OpenSim removes the objects from the physical
73 // world if it is a static linkset. 77 // world if it is a static linkset.
74 // Called at taint-time! 78 // Called at taint-time!
75 public override bool MakeStatic(BSPhysObject child) 79 public override bool MakeStatic(BSPrimLinkable child)
76 { 80 {
77 // What is done for each object in BSPrim is what we want. 81 // What is done for each object in BSPrim is what we want.
78 return false; 82 return false;
79 } 83 }
80 84
81 // Called at taint-time!! 85 // Called at taint-time!!
82 public override void UpdateProperties(BSPhysObject updated) 86 public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable pObj)
83 { 87 {
84 // Nothing to do for constraints on property updates 88 // Nothing to do for constraints on property updates
85 } 89 }
86 90
87 // The children of the linkset are moved around by the constraints.
88 // Just grab the current values of wherever it is right now.
89 public override OMV.Vector3 Position(BSPhysObject member)
90 {
91 return BulletSimAPI.GetPosition2(member.PhysBody.ptr);
92 }
93
94 public override OMV.Quaternion Orientation(BSPhysObject member)
95 {
96 return BulletSimAPI.GetOrientation2(member.PhysBody.ptr);
97 }
98
99 // Routine called when rebuilding the body of some member of the linkset. 91 // Routine called when rebuilding the body of some member of the linkset.
100 // Destroy all the constraints have have been made to root and set 92 // Destroy all the constraints have have been made to root and set
101 // up to rebuild the constraints before the next simulation step. 93 // up to rebuild the constraints before the next simulation step.
102 // Returns 'true' of something was actually removed and would need restoring 94 // Returns 'true' of something was actually removed and would need restoring
103 // Called at taint-time!! 95 // Called at taint-time!!
104 public override bool RemoveBodyDependencies(BSPrim child) 96 public override bool RemoveBodyDependencies(BSPrimLinkable child)
105 { 97 {
106 bool ret = false; 98 bool ret = false;
107 99
108 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", 100 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
109 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); 101 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString);
110 102
111 lock (m_linksetActivityLock) 103 lock (m_linksetActivityLock)
112 { 104 {
@@ -118,19 +110,11 @@ public sealed class BSLinksetConstraints : BSLinkset
118 return ret; 110 return ret;
119 } 111 }
120 112
121 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
122 // this routine will restore the removed constraints.
123 // Called at taint-time!!
124 public override void RestoreBodyDependencies(BSPrim child)
125 {
126 // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
127 }
128
129 // ================================================================ 113 // ================================================================
130 114
131 // Add a new child to the linkset. 115 // Add a new child to the linkset.
132 // Called while LinkActivity is locked. 116 // Called while LinkActivity is locked.
133 protected override void AddChildToLinkset(BSPhysObject child) 117 protected override void AddChildToLinkset(BSPrimLinkable child)
134 { 118 {
135 if (!HasChild(child)) 119 if (!HasChild(child))
136 { 120 {
@@ -146,17 +130,17 @@ public sealed class BSLinksetConstraints : BSLinkset
146 130
147 // Remove the specified child from the linkset. 131 // Remove the specified child from the linkset.
148 // Safe to call even if the child is not really in my linkset. 132 // Safe to call even if the child is not really in my linkset.
149 protected override void RemoveChildFromLinkset(BSPhysObject child) 133 protected override void RemoveChildFromLinkset(BSPrimLinkable child)
150 { 134 {
151 if (m_children.Remove(child)) 135 if (m_children.Remove(child))
152 { 136 {
153 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now 137 BSPrimLinkable rootx = LinksetRoot; // capture the root and body as of now
154 BSPhysObject childx = child; 138 BSPrimLinkable childx = child;
155 139
156 DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", 140 DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
157 childx.LocalID, 141 childx.LocalID,
158 rootx.LocalID, rootx.PhysBody.ptr.ToString("X"), 142 rootx.LocalID, rootx.PhysBody.AddrString,
159 childx.LocalID, childx.PhysBody.ptr.ToString("X")); 143 childx.LocalID, childx.PhysBody.AddrString);
160 144
161 PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() 145 PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
162 { 146 {
@@ -175,13 +159,13 @@ public sealed class BSLinksetConstraints : BSLinkset
175 159
176 // Create a constraint between me (root of linkset) and the passed prim (the child). 160 // Create a constraint between me (root of linkset) and the passed prim (the child).
177 // Called at taint time! 161 // Called at taint time!
178 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 162 private void PhysicallyLinkAChildToRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
179 { 163 {
180 // Don't build the constraint when asked. Put it off until just before the simulation step. 164 // Don't build the constraint when asked. Put it off until just before the simulation step.
181 Refresh(rootPrim); 165 Refresh(rootPrim);
182 } 166 }
183 167
184 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) 168 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
185 { 169 {
186 // Zero motion for children so they don't interpolate 170 // Zero motion for children so they don't interpolate
187 childPrim.ZeroMotion(true); 171 childPrim.ZeroMotion(true);
@@ -195,8 +179,8 @@ public sealed class BSLinksetConstraints : BSLinkset
195 179
196 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 180 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
197 rootPrim.LocalID, 181 rootPrim.LocalID,
198 rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), 182 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
199 childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"), 183 childPrim.LocalID, childPrim.PhysBody.AddrString,
200 rootPrim.Position, childPrim.Position, midPoint); 184 rootPrim.Position, childPrim.Position, midPoint);
201 185
202 // create a constraint that allows no freedom of movement between the two objects 186 // create a constraint that allows no freedom of movement between the two objects
@@ -239,14 +223,14 @@ public sealed class BSLinksetConstraints : BSLinkset
239 constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); 223 constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
240 224
241 // tweek the constraint to increase stability 225 // tweek the constraint to increase stability
242 constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset)); 226 constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset);
243 constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor), 227 constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor,
244 PhysicsScene.Params.linkConstraintTransMotorMaxVel, 228 BSParam.LinkConstraintTransMotorMaxVel,
245 PhysicsScene.Params.linkConstraintTransMotorMaxForce); 229 BSParam.LinkConstraintTransMotorMaxForce);
246 constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); 230 constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP);
247 if (PhysicsScene.Params.linkConstraintSolverIterations != 0f) 231 if (BSParam.LinkConstraintSolverIterations != 0f)
248 { 232 {
249 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); 233 constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations);
250 } 234 }
251 return constrain; 235 return constrain;
252 } 236 }
@@ -255,19 +239,19 @@ public sealed class BSLinksetConstraints : BSLinkset
255 // The root and child bodies are passed in because we need to remove the constraint between 239 // The root and child bodies are passed in because we need to remove the constraint between
256 // the bodies that were present at unlink time. 240 // the bodies that were present at unlink time.
257 // Called at taint time! 241 // Called at taint time!
258 private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 242 private bool PhysicallyUnlinkAChildFromRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
259 { 243 {
260 bool ret = false; 244 bool ret = false;
261 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", 245 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
262 rootPrim.LocalID, 246 rootPrim.LocalID,
263 rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), 247 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
264 childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X")); 248 childPrim.LocalID, childPrim.PhysBody.AddrString);
265 249
266 // Find the constraint for this link and get rid of it from the overall collection and from my list 250 // Find the constraint for this link and get rid of it from the overall collection and from my list
267 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) 251 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
268 { 252 {
269 // Make the child refresh its location 253 // Make the child refresh its location
270 BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr); 254 PhysicsScene.PE.PushUpdate(childPrim.PhysBody);
271 ret = true; 255 ret = true;
272 } 256 }
273 257
@@ -277,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
277 // Remove linkage between myself and any possible children I might have. 261 // Remove linkage between myself and any possible children I might have.
278 // Returns 'true' of any constraints were destroyed. 262 // Returns 'true' of any constraints were destroyed.
279 // Called at taint time! 263 // Called at taint time!
280 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) 264 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPrimLinkable rootPrim)
281 { 265 {
282 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 266 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
283 267
@@ -292,20 +276,17 @@ public sealed class BSLinksetConstraints : BSLinkset
292 private void RecomputeLinksetConstraints() 276 private void RecomputeLinksetConstraints()
293 { 277 {
294 float linksetMass = LinksetMass; 278 float linksetMass = LinksetMass;
295 LinksetRoot.UpdatePhysicalMassProperties(linksetMass); 279 LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true);
296 280
297 // DEBUG: see of inter-linkset collisions are causing problems
298 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
299 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
300 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", 281 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
301 LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); 282 LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
302 283
303 foreach (BSPhysObject child in m_children) 284 foreach (BSPrimLinkable child in m_children)
304 { 285 {
305 // A child in the linkset physically shows the mass of the whole linkset. 286 // A child in the linkset physically shows the mass of the whole linkset.
306 // This allows Bullet to apply enough force on the child to move the whole linkset. 287 // This allows Bullet to apply enough force on the child to move the whole linkset.
307 // (Also do the mass stuff before recomputing the constraint so mass is not zero.) 288 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
308 child.UpdatePhysicalMassProperties(linksetMass); 289 child.UpdatePhysicalMassProperties(linksetMass, true);
309 290
310 BSConstraint constrain; 291 BSConstraint constrain;
311 if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) 292 if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
@@ -315,11 +296,7 @@ public sealed class BSLinksetConstraints : BSLinkset
315 } 296 }
316 constrain.RecomputeConstraintVariables(linksetMass); 297 constrain.RecomputeConstraintVariables(linksetMass);
317 298
318 // DEBUG: see of inter-linkset collisions are causing problems 299 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
319 // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
320 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
321
322 // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG
323 } 300 }
324 301
325 } 302 }