BulletSim: fixes for change linkset implementation of physical linksets.
parent
a9dcdae6a2
commit
719380380a
|
@ -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)
|
||||||
{
|
{
|
||||||
|
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);
|
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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue