diff options
5 files changed, 50 insertions, 18 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index d1d318c..4455df4 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs | |||
@@ -29,6 +29,7 @@ using System.Collections.Generic; | |||
29 | using System.Linq; | 29 | using System.Linq; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Threading; | ||
32 | 33 | ||
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
34 | using OpenSim.Region.CoreModules; | 35 | using OpenSim.Region.CoreModules; |
@@ -198,7 +199,33 @@ public class ExtendedPhysics : INonSharedRegionModule | |||
198 | Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; | 199 | Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; |
199 | if (rootPhysActor != null) | 200 | if (rootPhysActor != null) |
200 | { | 201 | { |
201 | ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); | 202 | if (rootPhysActor.IsPhysical) |
203 | { | ||
204 | // Change a physical linkset by making non-physical, waiting for one heartbeat so all | ||
205 | // the prim and linkset state is updated, changing the type and making the | ||
206 | // linkset physical again. | ||
207 | containingGroup.ScriptSetPhysicsStatus(false); | ||
208 | Thread.Sleep(150); // longer than one heartbeat tick | ||
209 | |||
210 | // A kludge for the moment. | ||
211 | // Since compound linksets move the children but don't generate position updates to the | ||
212 | // simulator, it is possible for compound linkset children to have out-of-sync simulator | ||
213 | // and physical positions. The following causes the simulator to push the real child positions | ||
214 | // down into the physics engine to get everything synced. | ||
215 | containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition); | ||
216 | containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation); | ||
217 | |||
218 | ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); | ||
219 | Thread.Sleep(150); // longer than one heartbeat tick | ||
220 | |||
221 | containingGroup.ScriptSetPhysicsStatus(true); | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | // Non-physical linksets don't have a physical instantiation so there is no state to | ||
226 | // worry about being updated. | ||
227 | ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); | ||
228 | } | ||
202 | } | 229 | } |
203 | else | 230 | else |
204 | { | 231 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 3afd52e..a051002 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -148,7 +148,7 @@ public abstract class BSLinkset | |||
148 | // Returns a new linkset for the child which is a linkset of one (just the | 148 | // Returns a new linkset for the child which is a linkset of one (just the |
149 | // orphened child). | 149 | // orphened child). |
150 | // Called at runtime. | 150 | // Called at runtime. |
151 | public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child) | 151 | public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime) |
152 | { | 152 | { |
153 | lock (m_linksetActivityLock) | 153 | lock (m_linksetActivityLock) |
154 | { | 154 | { |
@@ -157,7 +157,7 @@ public abstract class BSLinkset | |||
157 | // Cannot remove the root from a linkset. | 157 | // Cannot remove the root from a linkset. |
158 | return this; | 158 | return this; |
159 | } | 159 | } |
160 | RemoveChildFromLinkset(child); | 160 | RemoveChildFromLinkset(child, inTaintTime); |
161 | LinksetMass = ComputeLinksetMass(); | 161 | LinksetMass = ComputeLinksetMass(); |
162 | } | 162 | } |
163 | 163 | ||
@@ -255,7 +255,7 @@ public abstract class BSLinkset | |||
255 | 255 | ||
256 | // I am the root of a linkset and one of my children is being removed. | 256 | // I am the root of a linkset and one of my children is being removed. |
257 | // Safe to call even if the child is not really in my linkset. | 257 | // Safe to call even if the child is not really in my linkset. |
258 | protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); | 258 | protected abstract void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime); |
259 | 259 | ||
260 | // When physical properties are changed the linkset needs to recalculate | 260 | // When physical properties are changed the linkset needs to recalculate |
261 | // its internal properties. | 261 | // its internal properties. |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 085d195..47ab842 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -242,7 +242,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
242 | { | 242 | { |
243 | bool ret = false; | 243 | bool ret = false; |
244 | 244 | ||
245 | DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", | 245 | DetailLog("{0},BSLinksetCompound.RemoveDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", |
246 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); | 246 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); |
247 | 247 | ||
248 | ScheduleRebuild(child); | 248 | ScheduleRebuild(child); |
@@ -270,7 +270,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
270 | 270 | ||
271 | // Remove the specified child from the linkset. | 271 | // Remove the specified child from the linkset. |
272 | // Safe to call even if the child is not really in the linkset. | 272 | // Safe to call even if the child is not really in the linkset. |
273 | protected override void RemoveChildFromLinkset(BSPrimLinkable child) | 273 | protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime) |
274 | { | 274 | { |
275 | child.ClearDisplacement(); | 275 | child.ClearDisplacement(); |
276 | 276 | ||
@@ -282,12 +282,12 @@ public sealed class BSLinksetCompound : BSLinkset | |||
282 | child.LocalID, child.PhysBody.AddrString); | 282 | child.LocalID, child.PhysBody.AddrString); |
283 | 283 | ||
284 | // Cause the child's body to be rebuilt and thus restored to normal operation | 284 | // Cause the child's body to be rebuilt and thus restored to normal operation |
285 | child.ForceBodyShapeRebuild(false); | 285 | child.ForceBodyShapeRebuild(inTaintTime); |
286 | 286 | ||
287 | if (!HasAnyChildren) | 287 | if (!HasAnyChildren) |
288 | { | 288 | { |
289 | // The linkset is now empty. The root needs rebuilding. | 289 | // The linkset is now empty. The root needs rebuilding. |
290 | LinksetRoot.ForceBodyShapeRebuild(false); | 290 | LinksetRoot.ForceBodyShapeRebuild(inTaintTime); |
291 | } | 291 | } |
292 | else | 292 | else |
293 | { | 293 | { |
@@ -318,10 +318,10 @@ public sealed class BSLinksetCompound : BSLinkset | |||
318 | // being destructed and going non-physical. | 318 | // being destructed and going non-physical. |
319 | LinksetRoot.ForceBodyShapeRebuild(true); | 319 | LinksetRoot.ForceBodyShapeRebuild(true); |
320 | 320 | ||
321 | // There is no reason to build all this physical stuff for a non-physical linkset. | 321 | // There is no reason to build all this physical stuff for a non-physical or empty linkset. |
322 | if (!LinksetRoot.IsPhysicallyActive) | 322 | if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren) |
323 | { | 323 | { |
324 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); | 324 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID); |
325 | return; // Note the 'finally' clause at the botton which will get executed. | 325 | return; // Note the 'finally' clause at the botton which will get executed. |
326 | } | 326 | } |
327 | 327 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 4bac222..d4ee27d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | |||
@@ -224,7 +224,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
224 | 224 | ||
225 | // Remove the specified child from the linkset. | 225 | // Remove the specified child from the linkset. |
226 | // 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. |
227 | protected override void RemoveChildFromLinkset(BSPrimLinkable child) | 227 | protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime) |
228 | { | 228 | { |
229 | if (m_children.Remove(child)) | 229 | if (m_children.Remove(child)) |
230 | { | 230 | { |
@@ -236,7 +236,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
236 | rootx.LocalID, rootx.PhysBody.AddrString, | 236 | rootx.LocalID, rootx.PhysBody.AddrString, |
237 | childx.LocalID, childx.PhysBody.AddrString); | 237 | childx.LocalID, childx.PhysBody.AddrString); |
238 | 238 | ||
239 | m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() | 239 | m_physicsScene.TaintedObject(inTaintTime, "BSLinksetConstraints.RemoveChildFromLinkset", delegate() |
240 | { | 240 | { |
241 | PhysicallyUnlinkAChildFromRoot(rootx, childx); | 241 | PhysicallyUnlinkAChildFromRoot(rootx, childx); |
242 | }); | 242 | }); |
@@ -382,9 +382,9 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
382 | Rebuilding = true; | 382 | Rebuilding = true; |
383 | 383 | ||
384 | // There is no reason to build all this physical stuff for a non-physical linkset. | 384 | // There is no reason to build all this physical stuff for a non-physical linkset. |
385 | if (!LinksetRoot.IsPhysicallyActive) | 385 | if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren) |
386 | { | 386 | { |
387 | DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); | 387 | DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID); |
388 | return; // Note the 'finally' clause at the botton which will get executed. | 388 | return; // Note the 'finally' clause at the botton which will get executed. |
389 | } | 389 | } |
390 | 390 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 7179a6d..38d1f88 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs | |||
@@ -66,7 +66,7 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
66 | 66 | ||
67 | public override void Destroy() | 67 | public override void Destroy() |
68 | { | 68 | { |
69 | Linkset = Linkset.RemoveMeFromLinkset(this); | 69 | Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime */); |
70 | base.Destroy(); | 70 | base.Destroy(); |
71 | } | 71 | } |
72 | 72 | ||
@@ -94,7 +94,7 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
94 | BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG | 94 | BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG |
95 | int childrenBefore = Linkset.NumberOfChildren; // DEBUG | 95 | int childrenBefore = Linkset.NumberOfChildren; // DEBUG |
96 | 96 | ||
97 | Linkset = Linkset.RemoveMeFromLinkset(this); | 97 | Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime*/); |
98 | 98 | ||
99 | DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", | 99 | DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", |
100 | LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); | 100 | LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); |
@@ -240,6 +240,8 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
240 | bool ret = false; | 240 | bool ret = false; |
241 | if (LinksetType != newType) | 241 | if (LinksetType != newType) |
242 | { | 242 | { |
243 | DetailLog("{0},BSPrimLinkset.ConvertLinkset,oldT={1},newT={2}", LocalID, LinksetType, newType); | ||
244 | |||
243 | // Set the implementation type first so the call to BSLinkset.Factory gets the new type. | 245 | // Set the implementation type first so the call to BSLinkset.Factory gets the new type. |
244 | this.LinksetType = newType; | 246 | this.LinksetType = newType; |
245 | 247 | ||
@@ -263,7 +265,10 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
263 | // Remove the children from the old linkset and add to the new (will be a new instance from the factory) | 265 | // Remove the children from the old linkset and add to the new (will be a new instance from the factory) |
264 | foreach (BSPrimLinkable child in children) | 266 | foreach (BSPrimLinkable child in children) |
265 | { | 267 | { |
266 | oldLinkset.RemoveMeFromLinkset(child); | 268 | oldLinkset.RemoveMeFromLinkset(child, true /*inTaintTime*/); |
269 | } | ||
270 | foreach (BSPrimLinkable child in children) | ||
271 | { | ||
267 | newLinkset.AddMeToLinkset(child); | 272 | newLinkset.AddMeToLinkset(child); |
268 | child.Linkset = newLinkset; | 273 | child.Linkset = newLinkset; |
269 | } | 274 | } |