aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorRobert Adams2012-09-27 19:57:35 -0700
committerRobert Adams2012-09-27 22:02:08 -0700
commit74dea4cfd52be75b4dd6277260c3ada80b939fbb (patch)
tree5781a9b2cb58bf27cb58d6189c535b33ca4af439 /OpenSim/Region/Physics
parentBulletSim: remove the trailing spaces from lines to make git happier (diff)
downloadopensim-SC-74dea4cfd52be75b4dd6277260c3ada80b939fbb.zip
opensim-SC-74dea4cfd52be75b4dd6277260c3ada80b939fbb.tar.gz
opensim-SC-74dea4cfd52be75b4dd6277260c3ada80b939fbb.tar.bz2
opensim-SC-74dea4cfd52be75b4dd6277260c3ada80b939fbb.tar.xz
BulletSim: rename some constraint variables to be consistant with other name use.
Added callbacks for shape and body changes in GetBodyAndShape() so the linkset constraints can be picked up and restored. A better design might be to have a "prim shape changed" event. Think about that. Added constraint types to general constraint class.
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs42
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs21
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs182
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs14
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs65
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs21
7 files changed, 231 insertions, 116 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs
index 39a3421..3306a97 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs
@@ -34,6 +34,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
34 34
35public class BS6DofConstraint : BSConstraint 35public class BS6DofConstraint : BSConstraint
36{ 36{
37 private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]";
38
39 public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } }
40
37 // Create a btGeneric6DofConstraint 41 // Create a btGeneric6DofConstraint
38 public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, 42 public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
39 Vector3 frame1, Quaternion frame1rot, 43 Vector3 frame1, Quaternion frame1rot,
@@ -49,6 +53,9 @@ public class BS6DofConstraint : BSConstraint
49 frame2, frame2rot, 53 frame2, frame2rot,
50 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); 54 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
51 m_enabled = true; 55 m_enabled = true;
56 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
57 BSScene.DetailLogZero, world.worldID,
58 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
52 } 59 }
53 60
54 public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, 61 public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
@@ -60,12 +67,13 @@ public class BS6DofConstraint : BSConstraint
60 m_body2 = obj2; 67 m_body2 = obj2;
61 if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero) 68 if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero)
62 { 69 {
63 world.scene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", 70 world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
64 "[BULLETSIM 6DOF CONSTRAINT]", world.worldID, 71 BSScene.DetailLogZero, world.worldID,
65 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); 72 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
66 world.scene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", 73 world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
67 "[BULLETSIM 6DOF CONSTRAINT]", world.worldID, 74 "[BULLETSIM 6DOF CONSTRAINT]", world.worldID,
68 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); 75 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
76 m_enabled = false;
69 } 77 }
70 else 78 else
71 { 79 {
@@ -73,8 +81,20 @@ public class BS6DofConstraint : BSConstraint
73 BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, 81 BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
74 joinPoint, 82 joinPoint,
75 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); 83 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
84 world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
85 BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"),
86 obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
87 if (m_constraint.ptr == IntPtr.Zero)
88 {
89 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
90 LogHeader, obj1.ID, obj2.ID);
91 m_enabled = false;
92 }
93 else
94 {
95 m_enabled = true;
96 }
76 } 97 }
77 m_enabled = true;
78 } 98 }
79 99
80 public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) 100 public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
@@ -82,7 +102,7 @@ public class BS6DofConstraint : BSConstraint
82 bool ret = false; 102 bool ret = false;
83 if (m_enabled) 103 if (m_enabled)
84 { 104 {
85 BulletSimAPI.SetFrames2(m_constraint.Ptr, frameA, frameArot, frameB, frameBrot); 105 BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot);
86 ret = true; 106 ret = true;
87 } 107 }
88 return ret; 108 return ret;
@@ -93,9 +113,9 @@ public class BS6DofConstraint : BSConstraint
93 bool ret = false; 113 bool ret = false;
94 if (m_enabled) 114 if (m_enabled)
95 { 115 {
96 BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); 116 BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
97 BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); 117 BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
98 BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); 118 BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
99 ret = true; 119 ret = true;
100 } 120 }
101 return ret; 121 return ret;
@@ -106,7 +126,7 @@ public class BS6DofConstraint : BSConstraint
106 bool ret = false; 126 bool ret = false;
107 float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; 127 float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
108 if (m_enabled) 128 if (m_enabled)
109 ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff); 129 ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff);
110 return ret; 130 return ret;
111 } 131 }
112 132
@@ -115,7 +135,7 @@ public class BS6DofConstraint : BSConstraint
115 bool ret = false; 135 bool ret = false;
116 float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; 136 float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
117 if (m_enabled) 137 if (m_enabled)
118 ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce); 138 ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce);
119 return ret; 139 return ret;
120 } 140 }
121 141
@@ -123,7 +143,7 @@ public class BS6DofConstraint : BSConstraint
123 { 143 {
124 bool ret = false; 144 bool ret = false;
125 if (m_enabled) 145 if (m_enabled)
126 ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.Ptr, threshold); 146 ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold);
127 return ret; 147 return ret;
128 } 148 }
129} 149}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index c21252b..63a4127 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -49,20 +49,23 @@ public abstract class BSConstraint : IDisposable
49 if (m_enabled) 49 if (m_enabled)
50 { 50 {
51 m_enabled = false; 51 m_enabled = false;
52 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.Ptr); 52 bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr);
53 m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); 53 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
54 m_constraint.Ptr = System.IntPtr.Zero; 54 m_constraint.ptr = System.IntPtr.Zero;
55 } 55 }
56 } 56 }
57 57
58 public BulletBody Body1 { get { return m_body1; } } 58 public BulletBody Body1 { get { return m_body1; } }
59 public BulletBody Body2 { get { return m_body2; } } 59 public BulletBody Body2 { get { return m_body2; } }
60 public BulletConstraint Constraint { get { return m_constraint; } }
61 public abstract ConstraintType Type { get; }
62
60 63
61 public virtual bool SetLinearLimits(Vector3 low, Vector3 high) 64 public virtual bool SetLinearLimits(Vector3 low, Vector3 high)
62 { 65 {
63 bool ret = false; 66 bool ret = false;
64 if (m_enabled) 67 if (m_enabled)
65 ret = BulletSimAPI.SetLinearLimits2(m_constraint.Ptr, low, high); 68 ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high);
66 return ret; 69 return ret;
67 } 70 }
68 71
@@ -70,7 +73,7 @@ public abstract class BSConstraint : IDisposable
70 { 73 {
71 bool ret = false; 74 bool ret = false;
72 if (m_enabled) 75 if (m_enabled)
73 ret = BulletSimAPI.SetAngularLimits2(m_constraint.Ptr, low, high); 76 ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high);
74 return ret; 77 return ret;
75 } 78 }
76 79
@@ -79,7 +82,7 @@ public abstract class BSConstraint : IDisposable
79 bool ret = false; 82 bool ret = false;
80 if (m_enabled) 83 if (m_enabled)
81 { 84 {
82 BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.Ptr, cnt); 85 BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt);
83 ret = true; 86 ret = true;
84 } 87 }
85 return ret; 88 return ret;
@@ -91,7 +94,7 @@ public abstract class BSConstraint : IDisposable
91 if (m_enabled) 94 if (m_enabled)
92 { 95 {
93 // Recompute the internal transforms 96 // Recompute the internal transforms
94 BulletSimAPI.CalculateTransforms2(m_constraint.Ptr); 97 BulletSimAPI.CalculateTransforms2(m_constraint.ptr);
95 ret = true; 98 ret = true;
96 } 99 }
97 return ret; 100 return ret;
@@ -110,11 +113,11 @@ public abstract class BSConstraint : IDisposable
110 // Setting an object's mass to zero (making it static like when it's selected) 113 // Setting an object's mass to zero (making it static like when it's selected)
111 // automatically disables the constraints. 114 // automatically disables the constraints.
112 // If the link is enabled, be sure to set the constraint itself to enabled. 115 // If the link is enabled, be sure to set the constraint itself to enabled.
113 BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true)); 116 BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, m_world.physicsScene.NumericBool(true));
114 } 117 }
115 else 118 else
116 { 119 {
117 m_world.scene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID); 120 m_world.physicsScene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID);
118 } 121 }
119 } 122 }
120 return ret; 123 return ret;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs
index a6e4235..7c8a215 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs
@@ -34,6 +34,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
34 34
35class BSHingeConstraint : BSConstraint 35class BSHingeConstraint : BSConstraint
36{ 36{
37 public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } }
38
37 public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, 39 public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
38 Vector3 pivotInA, Vector3 pivotInB, 40 Vector3 pivotInA, Vector3 pivotInB,
39 Vector3 axisInA, Vector3 axisInB, 41 Vector3 axisInA, Vector3 axisInB,
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index b0cc63c..dff71af 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -88,6 +88,7 @@ public class BSLinkset
88 // Link to a linkset where the child knows the parent. 88 // Link to a linkset where the child knows the parent.
89 // Parent changing should not happen so do some sanity checking. 89 // Parent changing should not happen so do some sanity checking.
90 // We return the parent's linkset so the child can track its membership. 90 // We return the parent's linkset so the child can track its membership.
91 // Called at runtime.
91 public BSLinkset AddMeToLinkset(BSPhysObject child) 92 public BSLinkset AddMeToLinkset(BSPhysObject child)
92 { 93 {
93 lock (m_linksetActivityLock) 94 lock (m_linksetActivityLock)
@@ -102,6 +103,7 @@ public class BSLinkset
102 // Remove a child from a linkset. 103 // Remove a child from a linkset.
103 // Returns a new linkset for the child which is a linkset of one (just the 104 // Returns a new linkset for the child which is a linkset of one (just the
104 // orphened child). 105 // orphened child).
106 // Called at runtime.
105 public BSLinkset RemoveMeFromLinkset(BSPhysObject child) 107 public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
106 { 108 {
107 lock (m_linksetActivityLock) 109 lock (m_linksetActivityLock)
@@ -113,27 +115,6 @@ public class BSLinkset
113 } 115 }
114 116
115 RemoveChildFromLinkset(child); 117 RemoveChildFromLinkset(child);
116
117 /* Alternate implementation that destroys the linkset of the root is removed.
118 * This fails because items are added and removed from linksets to build shapes.
119 * Code left for reference.
120 if (IsRoot(child))
121 {
122 // if root of linkset, take the linkset apart
123 while (m_children.Count > 0)
124 {
125 // Note that we don't do a foreach because the remove routine
126 // takes it out of the list.
127 RemoveChildFromOtherLinkset(m_children[0]);
128 }
129 m_children.Clear(); // just to make sure
130 }
131 else
132 {
133 // Just removing a child from an existing linkset
134 RemoveChildFromLinkset(child);
135 }
136 */
137 } 118 }
138 119
139 // The child is down to a linkset of just itself 120 // The child is down to a linkset of just itself
@@ -169,6 +150,106 @@ public class BSLinkset
169 return ret; 150 return ret;
170 } 151 }
171 152
153 // The object is going dynamic (physical). Do any setup necessary
154 // for a dynamic linkset.
155 // Only the state of the passed object can be modified. The rest of the linkset
156 // has not yet been fully constructed.
157 // Return 'true' if any properties updated on the passed object.
158 // Called at taint-time!
159 public bool MakeDynamic(BSPhysObject child)
160 {
161 // What is done for each object in BSPrim is what we want.
162 return false;
163 }
164
165 // The object is going static (non-physical). Do any setup necessary
166 // for a static linkset.
167 // Return 'true' if any properties updated on the passed object.
168 // Called at taint-time!
169 public bool MakeStatic(BSPhysObject child)
170 {
171 // What is done for each object in BSPrim is what we want.
172 return false;
173 }
174
175 // When physical properties are changed the linkset needs to recalculate
176 // its internal properties.
177 // Called at runtime.
178 public void Refresh(BSPhysObject requestor)
179 {
180 // If there are no children, there can't be any constraints to recompute
181 if (!HasAnyChildren)
182 return;
183
184 // Only the root does the recomputation
185 if (IsRoot(requestor))
186 {
187 PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
188 {
189 RecomputeLinksetConstraintVariables();
190 });
191 }
192 }
193
194 // Routine used when rebuilding the body of the root of the linkset
195 // Destroy all the constraints have have been made to root.
196 // This is called when the root body is changing.
197 // Called at taint-time!!
198 public void RemoveBodyDependencies(BSPrim child)
199 {
200 lock (m_linksetActivityLock)
201 {
202 if (IsRoot(child))
203 {
204 // If the one with the dependency is root, must undo all children
205 DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},numChild={2}",
206 LinksetRoot.LocalID, m_children.Count);
207 foreach (BSPhysObject bpo in m_children)
208 {
209 PhysicallyUnlinkAChildFromRoot(LinksetRoot, LinksetRoot.BSBody, bpo, bpo.BSBody);
210 }
211 }
212 else
213 {
214 DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
215 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
216 child.LocalID, child.BSBody.ptr.ToString("X"));
217 // Remove the dependency on the body of this one
218 PhysicallyUnlinkAChildFromRoot(LinksetRoot, LinksetRoot.BSBody, child, child.BSBody);
219 }
220 }
221 }
222
223 // Routine used when rebuilding the body of the root of the linkset
224 // This is called after RemoveAllLinksToRoot() to restore all the constraints.
225 // This is called when the root body has been changed.
226 // Called at taint-time!!
227 public void RestoreBodyDependencies(BSPrim child)
228 {
229 lock (m_linksetActivityLock)
230 {
231 if (IsRoot(child))
232 {
233 DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}",
234 LinksetRoot.LocalID, m_children.Count);
235 foreach (BSPhysObject bpo in m_children)
236 {
237 PhysicallyLinkAChildToRoot(LinksetRoot, LinksetRoot.BSBody, bpo, bpo.BSBody);
238 }
239 }
240 else
241 {
242 DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
243 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
244 child.LocalID, child.BSBody.ptr.ToString("X"));
245 PhysicallyLinkAChildToRoot(LinksetRoot, LinksetRoot.BSBody, child, child.BSBody);
246 }
247 }
248 }
249
250 // ================================================================
251 // Below this point is internal magic
252
172 private float ComputeLinksetMass() 253 private float ComputeLinksetMass()
173 { 254 {
174 float mass; 255 float mass;
@@ -220,46 +301,6 @@ public class BSLinkset
220 return com; 301 return com;
221 } 302 }
222 303
223 // The object is going dynamic (physical). Do any setup necessary
224 // for a dynamic linkset.
225 // Only the state of the passed object can be modified. The rest of the linkset
226 // has not yet been fully constructed.
227 // Return 'true' if any properties updated on the passed object.
228 // Called at taint-time!
229 public bool MakeDynamic(BSPhysObject child)
230 {
231 // What is done for each object in BSPrim is what we want.
232 return false;
233 }
234
235 // The object is going static (non-physical). Do any setup necessary
236 // for a static linkset.
237 // Return 'true' if any properties updated on the passed object.
238 // Called at taint-time!
239 public bool MakeStatic(BSPhysObject child)
240 {
241 // What is done for each object in BSPrim is what we want.
242 return false;
243 }
244
245 // When physical properties are changed the linkset needs to recalculate
246 // its internal properties.
247 public void Refresh(BSPhysObject requestor)
248 {
249 // If there are no children, there can't be any constraints to recompute
250 if (!HasAnyChildren)
251 return;
252
253 // Only the root does the recomputation
254 if (IsRoot(requestor))
255 {
256 PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
257 {
258 RecomputeLinksetConstraintVariables();
259 });
260 }
261 }
262
263 // Call each of the constraints that make up this linkset and recompute the 304 // Call each of the constraints that make up this linkset and recompute the
264 // various transforms and variables. Used when objects are added or removed 305 // various transforms and variables. Used when objects are added or removed
265 // from a linkset to make sure the constraints know about the new mass and 306 // from a linkset to make sure the constraints know about the new mass and
@@ -327,6 +368,11 @@ public class BSLinkset
327 BSPhysObject childx = child; 368 BSPhysObject childx = child;
328 BulletBody childBodyx = child.BSBody; 369 BulletBody childBodyx = child.BSBody;
329 370
371 DetailLog("{0},AddChildToLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
372 rootx.LocalID,
373 rootx.LocalID, rootBodyx.ptr.ToString("X"),
374 childx.LocalID, childBodyx.ptr.ToString("X"));
375
330 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 376 PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
331 { 377 {
332 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID); 378 DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
@@ -358,10 +404,14 @@ public class BSLinkset
358 BulletBody rootBodyx = LinksetRoot.BSBody; 404 BulletBody rootBodyx = LinksetRoot.BSBody;
359 BSPhysObject childx = child; 405 BSPhysObject childx = child;
360 BulletBody childBodyx = child.BSBody; 406 BulletBody childBodyx = child.BSBody;
407
408 DetailLog("{0},RemoveChildFromLinkset,call,child={1}",
409 rootx.LocalID,
410 rootx.LocalID, rootBodyx.ptr.ToString("X"),
411 childx.LocalID, childBodyx.ptr.ToString("X"));
412
361 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 413 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
362 { 414 {
363 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
364
365 PhysicallyUnlinkAChildFromRoot(rootx, rootBodyx, childx, childBodyx); 415 PhysicallyUnlinkAChildFromRoot(rootx, rootBodyx, childx, childBodyx);
366 RecomputeLinksetConstraintVariables(); 416 RecomputeLinksetConstraintVariables();
367 }); 417 });
@@ -390,14 +440,15 @@ public class BSLinkset
390 // real world coordinate of midpoint between the two objects 440 // real world coordinate of midpoint between the two objects
391 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 441 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
392 442
393 // create a constraint that allows no freedom of movement between the two objects
394 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
395 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 443 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
396 rootPrim.LocalID, 444 rootPrim.LocalID,
397 rootPrim.LocalID, rootBody.ptr.ToString("X"), 445 rootPrim.LocalID, rootBody.ptr.ToString("X"),
398 childPrim.LocalID, childBody.ptr.ToString("X"), 446 childPrim.LocalID, childBody.ptr.ToString("X"),
399 rootPrim.Position, childPrim.Position, midPoint); 447 rootPrim.Position, childPrim.Position, midPoint);
400 448
449 // create a constraint that allows no freedom of movement between the two objects
450 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
451
401 // There is great subtlty in these paramters. Notice the check for a ptr of zero. 452 // There is great subtlty in these paramters. Notice the check for a ptr of zero.
402 // We pass the BulletBody structure into the taint in order to capture the pointer 453 // We pass the BulletBody structure into the taint in order to capture the pointer
403 // of the body at the time of constraint creation. This doesn't work for the very first 454 // of the body at the time of constraint creation. This doesn't work for the very first
@@ -416,6 +467,7 @@ public class BSLinkset
416 true, 467 true,
417 true 468 true
418 ); 469 );
470
419 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 471 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
420 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms 472 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
421 * of the objects. 473 * of the objects.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 8688485..c879143 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1111,13 +1111,21 @@ public sealed class BSPrim : BSPhysObject
1111 // Undo me from any possible linkset so, if body is rebuilt, the link will get restored. 1111 // Undo me from any possible linkset so, if body is rebuilt, the link will get restored.
1112 // NOTE that the new linkset is not set. This saves the handle to the linkset 1112 // NOTE that the new linkset is not set. This saves the handle to the linkset
1113 // so we can add ourselves back when shape mangling is complete. 1113 // so we can add ourselves back when shape mangling is complete.
1114 Linkset.RemoveMeFromLinkset(this); 1114 bool needToRestoreLinkset = false;
1115 1115
1116 // Create the correct physical representation for this type of object. 1116 // Create the correct physical representation for this type of object.
1117 // Updates BSBody and BSShape with the new information. 1117 // Updates BSBody and BSShape with the new information.
1118 PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs); 1118 PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs,
1119 null, delegate(BulletBody dBody)
1120 {
1121 // Called if the current prim body is about to be destroyed.
1122 // The problem is the constraints for Linksets which need to be updated for the new body.
1123 Linkset.RemoveBodyDependencies(this);
1124 needToRestoreLinkset = true;
1125 });
1119 1126
1120 Linkset = Linkset.AddMeToLinkset(this); 1127 if (needToRestoreLinkset)
1128 Linkset.RestoreBodyDependencies(this);
1121 1129
1122 // Make sure the properties are set on the new object 1130 // Make sure the properties are set on the new object
1123 UpdatePhysicalParameters(); 1131 UpdatePhysicalParameters();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index b428ba3..2618971 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -81,12 +81,21 @@ public class BSShapeCollection : IDisposable
81 // TODO!!!!!!!!! 81 // TODO!!!!!!!!!
82 } 82 }
83 83
84 // Callbacks called just before either the body or shape is destroyed.
85 // Mostly used for changing bodies out from under Linksets.
86 // Useful for other cases where parameters need saving.
87 // Passing 'null' says no callback.
88 public delegate void ShapeDestructionCallback(BulletShape shape);
89 public delegate void BodyDestructionCallback(BulletBody body);
90
84 // Called to update/change the body and shape for an object. 91 // Called to update/change the body and shape for an object.
85 // First checks the shape and updates that if necessary then makes 92 // First checks the shape and updates that if necessary then makes
86 // sure the body is of the right type. 93 // sure the body is of the right type.
87 // Return 'true' if either the body or the shape changed. 94 // Return 'true' if either the body or the shape changed.
88 // Called at taint-time!! 95 // Called at taint-time!!
89 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) 96 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPrim prim,
97 ShapeData shapeData, PrimitiveBaseShape pbs,
98 ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
90 { 99 {
91 bool ret = false; 100 bool ret = false;
92 101
@@ -95,11 +104,11 @@ public class BSShapeCollection : IDisposable
95 { 104 {
96 // Do we have the correct geometry for this type of object? 105 // Do we have the correct geometry for this type of object?
97 // Updates prim.BSShape with information/pointers to requested shape 106 // Updates prim.BSShape with information/pointers to requested shape
98 bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs); 107 bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback);
99 // If we had to select a new shape geometry for the object, 108 // If we had to select a new shape geometry for the object,
100 // rebuild the body around it. 109 // rebuild the body around it.
101 // Updates prim.BSBody with information/pointers to requested body 110 // Updates prim.BSBody with information/pointers to requested body
102 bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData); 111 bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData, bodyCallback);
103 ret = newGeom || newBody; 112 ret = newGeom || newBody;
104 } 113 }
105 DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}", 114 DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}",
@@ -135,7 +144,7 @@ public class BSShapeCollection : IDisposable
135 144
136 // Release the usage of a body. 145 // Release the usage of a body.
137 // Called when releasing use of a BSBody. BSShape is handled separately. 146 // Called when releasing use of a BSBody. BSShape is handled separately.
138 public void DereferenceBody(BulletBody shape, bool inTaintTime) 147 public void DereferenceBody(BulletBody shape, bool inTaintTime, BodyDestructionCallback bodyCallback )
139 { 148 {
140 if (shape.ptr == IntPtr.Zero) 149 if (shape.ptr == IntPtr.Zero)
141 return; 150 return;
@@ -244,7 +253,7 @@ public class BSShapeCollection : IDisposable
244 253
245 // Release the usage of a shape. 254 // Release the usage of a shape.
246 // The collisionObject is released since it is a copy of the real collision shape. 255 // The collisionObject is released since it is a copy of the real collision shape.
247 private void DereferenceShape(BulletShape shape, bool atTaintTime) 256 private void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback)
248 { 257 {
249 if (shape.ptr == IntPtr.Zero) 258 if (shape.ptr == IntPtr.Zero)
250 return; 259 return;
@@ -254,10 +263,10 @@ public class BSShapeCollection : IDisposable
254 switch (shape.type) 263 switch (shape.type)
255 { 264 {
256 case ShapeData.PhysicsShapeType.SHAPE_HULL: 265 case ShapeData.PhysicsShapeType.SHAPE_HULL:
257 DereferenceHull(shape); 266 DereferenceHull(shape, shapeCallback);
258 break; 267 break;
259 case ShapeData.PhysicsShapeType.SHAPE_MESH: 268 case ShapeData.PhysicsShapeType.SHAPE_MESH:
260 DereferenceMesh(shape); 269 DereferenceMesh(shape, shapeCallback);
261 break; 270 break;
262 case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: 271 case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN:
263 break; 272 break;
@@ -267,6 +276,7 @@ public class BSShapeCollection : IDisposable
267 { 276 {
268 DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", 277 DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
269 BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime); 278 BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime);
279 if (shapeCallback != null) shapeCallback(shape);
270 BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); 280 BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
271 } 281 }
272 break; 282 break;
@@ -287,13 +297,14 @@ public class BSShapeCollection : IDisposable
287 297
288 // Count down the reference count for a mesh shape 298 // Count down the reference count for a mesh shape
289 // Called at taint-time. 299 // Called at taint-time.
290 private void DereferenceMesh(BulletShape shape) 300 private void DereferenceMesh(BulletShape shape, ShapeDestructionCallback shapeCallback)
291 { 301 {
292 MeshDesc meshDesc; 302 MeshDesc meshDesc;
293 if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) 303 if (Meshes.TryGetValue(shape.shapeKey, out meshDesc))
294 { 304 {
295 meshDesc.referenceCount--; 305 meshDesc.referenceCount--;
296 // TODO: release the Bullet storage 306 // TODO: release the Bullet storage
307 if (shapeCallback != null) shapeCallback(shape);
297 meshDesc.lastReferenced = System.DateTime.Now; 308 meshDesc.lastReferenced = System.DateTime.Now;
298 Meshes[shape.shapeKey] = meshDesc; 309 Meshes[shape.shapeKey] = meshDesc;
299 DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}", 310 DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}",
@@ -304,13 +315,14 @@ public class BSShapeCollection : IDisposable
304 315
305 // Count down the reference count for a hull shape 316 // Count down the reference count for a hull shape
306 // Called at taint-time. 317 // Called at taint-time.
307 private void DereferenceHull(BulletShape shape) 318 private void DereferenceHull(BulletShape shape, ShapeDestructionCallback shapeCallback)
308 { 319 {
309 HullDesc hullDesc; 320 HullDesc hullDesc;
310 if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) 321 if (Hulls.TryGetValue(shape.shapeKey, out hullDesc))
311 { 322 {
312 hullDesc.referenceCount--; 323 hullDesc.referenceCount--;
313 // TODO: release the Bullet storage (aging old entries?) 324 // TODO: release the Bullet storage (aging old entries?)
325 if (shapeCallback != null) shapeCallback(shape);
314 hullDesc.lastReferenced = System.DateTime.Now; 326 hullDesc.lastReferenced = System.DateTime.Now;
315 Hulls[shape.shapeKey] = hullDesc; 327 Hulls[shape.shapeKey] = hullDesc;
316 DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}", 328 DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}",
@@ -324,7 +336,8 @@ public class BSShapeCollection : IDisposable
324 // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used. 336 // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used.
325 // Returns 'true' if the geometry was rebuilt. 337 // Returns 'true' if the geometry was rebuilt.
326 // Called at taint-time! 338 // Called at taint-time!
327 private bool CreateGeom(bool forceRebuild, BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) 339 private bool CreateGeom(bool forceRebuild, BSPrim prim, ShapeData shapeData,
340 PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback)
328 { 341 {
329 bool ret = false; 342 bool ret = false;
330 bool haveShape = false; 343 bool haveShape = false;
@@ -349,8 +362,8 @@ public class BSShapeCollection : IDisposable
349 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE 362 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
350 ) 363 )
351 { 364 {
352 ret = GetReferenceToNativeShape(prim, shapeData, 365 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
353 ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE); 366 ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
354 DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", 367 DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
355 prim.LocalID, forceRebuild, prim.BSShape); 368 prim.LocalID, forceRebuild, prim.BSShape);
356 } 369 }
@@ -363,8 +376,8 @@ public class BSShapeCollection : IDisposable
363 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX 376 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
364 ) 377 )
365 { 378 {
366 ret = GetReferenceToNativeShape( 379 ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX,
367 prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); 380 ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
368 DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", 381 DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
369 prim.LocalID, forceRebuild, prim.BSShape); 382 prim.LocalID, forceRebuild, prim.BSShape);
370 } 383 }
@@ -378,13 +391,13 @@ public class BSShapeCollection : IDisposable
378 if (prim.IsPhysical) 391 if (prim.IsPhysical)
379 { 392 {
380 // Update prim.BSShape to reference a hull of this shape. 393 // Update prim.BSShape to reference a hull of this shape.
381 ret = GetReferenceToHull(prim, shapeData, pbs); 394 ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback);
382 DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", 395 DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
383 shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); 396 shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
384 } 397 }
385 else 398 else
386 { 399 {
387 ret = GetReferenceToMesh(prim, shapeData, pbs); 400 ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback);
388 DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", 401 DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
389 shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X")); 402 shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
390 } 403 }
@@ -394,7 +407,8 @@ public class BSShapeCollection : IDisposable
394 407
395 // Creates a native shape and assignes it to prim.BSShape 408 // Creates a native shape and assignes it to prim.BSShape
396 private bool GetReferenceToNativeShape( BSPrim prim, ShapeData shapeData, 409 private bool GetReferenceToNativeShape( BSPrim prim, ShapeData shapeData,
397 ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey) 410 ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
411 ShapeDestructionCallback shapeCallback)
398 { 412 {
399 BulletShape newShape; 413 BulletShape newShape;
400 414
@@ -404,7 +418,7 @@ public class BSShapeCollection : IDisposable
404 shapeData.Scale = shapeData.Size; 418 shapeData.Scale = shapeData.Size;
405 419
406 // release any previous shape 420 // release any previous shape
407 DereferenceShape(prim.BSShape, true); 421 DereferenceShape(prim.BSShape, true, shapeCallback);
408 422
409 // Native shapes are always built independently. 423 // Native shapes are always built independently.
410 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); 424 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType);
@@ -422,7 +436,8 @@ public class BSShapeCollection : IDisposable
422 // Dereferences previous shape in BSShape and adds a reference for this new shape. 436 // Dereferences previous shape in BSShape and adds a reference for this new shape.
423 // Returns 'true' of a mesh was actually built. Otherwise . 437 // Returns 'true' of a mesh was actually built. Otherwise .
424 // Called at taint-time! 438 // Called at taint-time!
425 private bool GetReferenceToMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) 439 private bool GetReferenceToMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs,
440 ShapeDestructionCallback shapeCallback)
426 { 441 {
427 BulletShape newShape = new BulletShape(IntPtr.Zero); 442 BulletShape newShape = new BulletShape(IntPtr.Zero);
428 443
@@ -436,7 +451,7 @@ public class BSShapeCollection : IDisposable
436 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); 451 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
437 452
438 // Since we're recreating new, get rid of the reference to the previous shape 453 // Since we're recreating new, get rid of the reference to the previous shape
439 DereferenceShape(prim.BSShape, true); 454 DereferenceShape(prim.BSShape, true, shapeCallback);
440 455
441 newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod); 456 newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod);
442 457
@@ -490,7 +505,8 @@ public class BSShapeCollection : IDisposable
490 505
491 // See that hull shape exists in the physical world and update prim.BSShape. 506 // See that hull shape exists in the physical world and update prim.BSShape.
492 // We could be creating the hull because scale changed or whatever. 507 // We could be creating the hull because scale changed or whatever.
493 private bool GetReferenceToHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) 508 private bool GetReferenceToHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs,
509 ShapeDestructionCallback shapeCallback)
494 { 510 {
495 BulletShape newShape; 511 BulletShape newShape;
496 512
@@ -505,7 +521,7 @@ public class BSShapeCollection : IDisposable
505 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X")); 521 prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
506 522
507 // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull. 523 // Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull.
508 DereferenceShape(prim.BSShape, true); 524 DereferenceShape(prim.BSShape, true, shapeCallback);
509 525
510 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); 526 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
511 527
@@ -656,7 +672,8 @@ public class BSShapeCollection : IDisposable
656 // Updates prim.BSBody with the information about the new body if one is created. 672 // Updates prim.BSBody with the information about the new body if one is created.
657 // Returns 'true' if an object was actually created. 673 // Returns 'true' if an object was actually created.
658 // Called at taint-time. 674 // Called at taint-time.
659 private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData) 675 private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape,
676 ShapeData shapeData, BodyDestructionCallback bodyCallback)
660 { 677 {
661 bool ret = false; 678 bool ret = false;
662 679
@@ -679,7 +696,7 @@ public class BSShapeCollection : IDisposable
679 696
680 if (mustRebuild || forceRebuild) 697 if (mustRebuild || forceRebuild)
681 { 698 {
682 DereferenceBody(prim.BSBody, true); 699 DereferenceBody(prim.BSBody, true, bodyCallback);
683 700
684 BulletBody aBody; 701 BulletBody aBody;
685 IntPtr bodyPtr = IntPtr.Zero; 702 IntPtr bodyPtr = IntPtr.Zero;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 544c53d..1125d7e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -42,12 +42,12 @@ public struct BulletSim
42 { 42 {
43 ptr = xx; 43 ptr = xx;
44 worldID = worldId; 44 worldID = worldId;
45 scene = bss; 45 physicsScene = bss;
46 } 46 }
47 public IntPtr ptr; 47 public IntPtr ptr;
48 public uint worldID; 48 public uint worldID;
49 // The scene is only in here so very low level routines have a handle to print debug/error messages 49 // The scene is only in here so very low level routines have a handle to print debug/error messages
50 public BSScene scene; 50 public BSScene physicsScene;
51} 51}
52 52
53// An allocated Bullet btRigidBody 53// An allocated Bullet btRigidBody
@@ -120,14 +120,27 @@ public struct BulletShape
120 } 120 }
121} 121}
122 122
123 // Constraint type values as defined by Bullet
124public enum ConstraintType : int
125{
126 POINT2POINT_CONSTRAINT_TYPE = 3,
127 HINGE_CONSTRAINT_TYPE,
128 CONETWIST_CONSTRAINT_TYPE,
129 D6_CONSTRAINT_TYPE,
130 SLIDER_CONSTRAINT_TYPE,
131 CONTACT_CONSTRAINT_TYPE,
132 D6_SPRING_CONSTRAINT_TYPE,
133 MAX_CONSTRAINT_TYPE
134}
135
123// An allocated Bullet btConstraint 136// An allocated Bullet btConstraint
124public struct BulletConstraint 137public struct BulletConstraint
125{ 138{
126 public BulletConstraint(IntPtr xx) 139 public BulletConstraint(IntPtr xx)
127 { 140 {
128 Ptr = xx; 141 ptr = xx;
129 } 142 }
130 public IntPtr Ptr; 143 public IntPtr ptr;
131} 144}
132 145
133// An allocated HeightMapThing which holds various heightmap info. 146// An allocated HeightMapThing which holds various heightmap info.