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