diff options
author | Robert Adams | 2012-09-27 19:57:35 -0700 |
---|---|---|
committer | Robert Adams | 2012-09-27 22:02:08 -0700 |
commit | 74dea4cfd52be75b4dd6277260c3ada80b939fbb (patch) | |
tree | 5781a9b2cb58bf27cb58d6189c535b33ca4af439 /OpenSim/Region | |
parent | BulletSim: remove the trailing spaces from lines to make git happier (diff) | |
download | opensim-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')
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 | ||
35 | public class BS6DofConstraint : BSConstraint | 35 | public 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 | ||
35 | class BSHingeConstraint : BSConstraint | 35 | class 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 | ||
124 | public 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 |
124 | public struct BulletConstraint | 137 | public 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. |