BulletSim: fixes for change linkset implementation of physical linksets.

0.7.6-extended
Robert Adams 2013-08-06 10:32:56 -07:00 committed by Justin Clark-Casey (justincc)
parent a9dcdae6a2
commit 719380380a
5 changed files with 50 additions and 18 deletions

View File

@ -29,6 +29,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.CoreModules; using OpenSim.Region.CoreModules;
@ -198,7 +199,33 @@ public class ExtendedPhysics : INonSharedRegionModule
Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
if (rootPhysActor != null) if (rootPhysActor != null)
{ {
ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); if (rootPhysActor.IsPhysical)
{
// Change a physical linkset by making non-physical, waiting for one heartbeat so all
// the prim and linkset state is updated, changing the type and making the
// linkset physical again.
containingGroup.ScriptSetPhysicsStatus(false);
Thread.Sleep(150); // longer than one heartbeat tick
// A kludge for the moment.
// Since compound linksets move the children but don't generate position updates to the
// simulator, it is possible for compound linkset children to have out-of-sync simulator
// and physical positions. The following causes the simulator to push the real child positions
// down into the physics engine to get everything synced.
containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition);
containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation);
ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
Thread.Sleep(150); // longer than one heartbeat tick
containingGroup.ScriptSetPhysicsStatus(true);
}
else
{
// Non-physical linksets don't have a physical instantiation so there is no state to
// worry about being updated.
ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
}
} }
else else
{ {

View File

@ -148,7 +148,7 @@ public abstract class BSLinkset
// Returns a new linkset for the child which is a linkset of one (just the // Returns a new linkset for the child which is a linkset of one (just the
// orphened child). // orphened child).
// Called at runtime. // Called at runtime.
public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child) public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime)
{ {
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
@ -157,7 +157,7 @@ public abstract class BSLinkset
// Cannot remove the root from a linkset. // Cannot remove the root from a linkset.
return this; return this;
} }
RemoveChildFromLinkset(child); RemoveChildFromLinkset(child, inTaintTime);
LinksetMass = ComputeLinksetMass(); LinksetMass = ComputeLinksetMass();
} }
@ -255,7 +255,7 @@ public abstract class BSLinkset
// I am the root of a linkset and one of my children is being removed. // I am the root of a linkset and one of my children is being removed.
// Safe to call even if the child is not really in my linkset. // Safe to call even if the child is not really in my linkset.
protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); protected abstract void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime);
// When physical properties are changed the linkset needs to recalculate // When physical properties are changed the linkset needs to recalculate
// its internal properties. // its internal properties.

View File

@ -242,7 +242,7 @@ public sealed class BSLinksetCompound : BSLinkset
{ {
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", DetailLog("{0},BSLinksetCompound.RemoveDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child));
ScheduleRebuild(child); ScheduleRebuild(child);
@ -270,7 +270,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Remove the specified child from the linkset. // Remove the specified child from the linkset.
// Safe to call even if the child is not really in the linkset. // Safe to call even if the child is not really in the linkset.
protected override void RemoveChildFromLinkset(BSPrimLinkable child) protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
{ {
child.ClearDisplacement(); child.ClearDisplacement();
@ -282,12 +282,12 @@ public sealed class BSLinksetCompound : BSLinkset
child.LocalID, child.PhysBody.AddrString); child.LocalID, child.PhysBody.AddrString);
// Cause the child's body to be rebuilt and thus restored to normal operation // Cause the child's body to be rebuilt and thus restored to normal operation
child.ForceBodyShapeRebuild(false); child.ForceBodyShapeRebuild(inTaintTime);
if (!HasAnyChildren) if (!HasAnyChildren)
{ {
// The linkset is now empty. The root needs rebuilding. // The linkset is now empty. The root needs rebuilding.
LinksetRoot.ForceBodyShapeRebuild(false); LinksetRoot.ForceBodyShapeRebuild(inTaintTime);
} }
else else
{ {
@ -318,10 +318,10 @@ public sealed class BSLinksetCompound : BSLinkset
// being destructed and going non-physical. // being destructed and going non-physical.
LinksetRoot.ForceBodyShapeRebuild(true); LinksetRoot.ForceBodyShapeRebuild(true);
// There is no reason to build all this physical stuff for a non-physical linkset. // There is no reason to build all this physical stuff for a non-physical or empty linkset.
if (!LinksetRoot.IsPhysicallyActive) if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
{ {
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
return; // Note the 'finally' clause at the botton which will get executed. return; // Note the 'finally' clause at the botton which will get executed.
} }

View File

@ -224,7 +224,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// Remove the specified child from the linkset. // Remove the specified child from the linkset.
// Safe to call even if the child is not really in my linkset. // Safe to call even if the child is not really in my linkset.
protected override void RemoveChildFromLinkset(BSPrimLinkable child) protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
{ {
if (m_children.Remove(child)) if (m_children.Remove(child))
{ {
@ -236,7 +236,7 @@ public sealed class BSLinksetConstraints : BSLinkset
rootx.LocalID, rootx.PhysBody.AddrString, rootx.LocalID, rootx.PhysBody.AddrString,
childx.LocalID, childx.PhysBody.AddrString); childx.LocalID, childx.PhysBody.AddrString);
m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() m_physicsScene.TaintedObject(inTaintTime, "BSLinksetConstraints.RemoveChildFromLinkset", delegate()
{ {
PhysicallyUnlinkAChildFromRoot(rootx, childx); PhysicallyUnlinkAChildFromRoot(rootx, childx);
}); });
@ -382,9 +382,9 @@ public sealed class BSLinksetConstraints : BSLinkset
Rebuilding = true; Rebuilding = true;
// There is no reason to build all this physical stuff for a non-physical linkset. // There is no reason to build all this physical stuff for a non-physical linkset.
if (!LinksetRoot.IsPhysicallyActive) if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
{ {
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
return; // Note the 'finally' clause at the botton which will get executed. return; // Note the 'finally' clause at the botton which will get executed.
} }

View File

@ -66,7 +66,7 @@ public class BSPrimLinkable : BSPrimDisplaced
public override void Destroy() public override void Destroy()
{ {
Linkset = Linkset.RemoveMeFromLinkset(this); Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime */);
base.Destroy(); base.Destroy();
} }
@ -94,7 +94,7 @@ public class BSPrimLinkable : BSPrimDisplaced
BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
int childrenBefore = Linkset.NumberOfChildren; // DEBUG int childrenBefore = Linkset.NumberOfChildren; // DEBUG
Linkset = Linkset.RemoveMeFromLinkset(this); Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime*/);
DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
@ -240,6 +240,8 @@ public class BSPrimLinkable : BSPrimDisplaced
bool ret = false; bool ret = false;
if (LinksetType != newType) if (LinksetType != newType)
{ {
DetailLog("{0},BSPrimLinkset.ConvertLinkset,oldT={1},newT={2}", LocalID, LinksetType, newType);
// Set the implementation type first so the call to BSLinkset.Factory gets the new type. // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
this.LinksetType = newType; this.LinksetType = newType;
@ -263,7 +265,10 @@ public class BSPrimLinkable : BSPrimDisplaced
// Remove the children from the old linkset and add to the new (will be a new instance from the factory) // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
foreach (BSPrimLinkable child in children) foreach (BSPrimLinkable child in children)
{ {
oldLinkset.RemoveMeFromLinkset(child); oldLinkset.RemoveMeFromLinkset(child, true /*inTaintTime*/);
}
foreach (BSPrimLinkable child in children)
{
newLinkset.AddMeToLinkset(child); newLinkset.AddMeToLinkset(child);
child.Linkset = newLinkset; child.Linkset = newLinkset;
} }