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.Reflection;
using System.Text;
using System.Threading;
using OpenSim.Framework;
using OpenSim.Region.CoreModules;
@ -198,7 +199,33 @@ public class ExtendedPhysics : INonSharedRegionModule
Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
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
{

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
// orphened child).
// Called at runtime.
public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime)
{
lock (m_linksetActivityLock)
{
@ -157,7 +157,7 @@ public abstract class BSLinkset
// Cannot remove the root from a linkset.
return this;
}
RemoveChildFromLinkset(child);
RemoveChildFromLinkset(child, inTaintTime);
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.
// 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
// its internal properties.

View File

@ -242,7 +242,7 @@ public sealed class BSLinksetCompound : BSLinkset
{
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));
ScheduleRebuild(child);
@ -270,7 +270,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Remove the specified child from 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();
@ -282,12 +282,12 @@ public sealed class BSLinksetCompound : BSLinkset
child.LocalID, child.PhysBody.AddrString);
// Cause the child's body to be rebuilt and thus restored to normal operation
child.ForceBodyShapeRebuild(false);
child.ForceBodyShapeRebuild(inTaintTime);
if (!HasAnyChildren)
{
// The linkset is now empty. The root needs rebuilding.
LinksetRoot.ForceBodyShapeRebuild(false);
LinksetRoot.ForceBodyShapeRebuild(inTaintTime);
}
else
{
@ -318,10 +318,10 @@ public sealed class BSLinksetCompound : BSLinkset
// being destructed and going non-physical.
LinksetRoot.ForceBodyShapeRebuild(true);
// There is no reason to build all this physical stuff for a non-physical linkset.
if (!LinksetRoot.IsPhysicallyActive)
// There is no reason to build all this physical stuff for a non-physical or empty linkset.
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.
}

View File

@ -224,7 +224,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// Remove the specified child from the 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))
{
@ -236,7 +236,7 @@ public sealed class BSLinksetConstraints : BSLinkset
rootx.LocalID, rootx.PhysBody.AddrString,
childx.LocalID, childx.PhysBody.AddrString);
m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
m_physicsScene.TaintedObject(inTaintTime, "BSLinksetConstraints.RemoveChildFromLinkset", delegate()
{
PhysicallyUnlinkAChildFromRoot(rootx, childx);
});
@ -382,9 +382,9 @@ public sealed class BSLinksetConstraints : BSLinkset
Rebuilding = true;
// 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.
}

View File

@ -66,7 +66,7 @@ public class BSPrimLinkable : BSPrimDisplaced
public override void Destroy()
{
Linkset = Linkset.RemoveMeFromLinkset(this);
Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime */);
base.Destroy();
}
@ -94,7 +94,7 @@ public class BSPrimLinkable : BSPrimDisplaced
BSPhysObject parentBefore = Linkset.LinksetRoot; // 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}, ",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
@ -240,6 +240,8 @@ public class BSPrimLinkable : BSPrimDisplaced
bool ret = false;
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.
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)
foreach (BSPrimLinkable child in children)
{
oldLinkset.RemoveMeFromLinkset(child);
oldLinkset.RemoveMeFromLinkset(child, true /*inTaintTime*/);
}
foreach (BSPrimLinkable child in children)
{
newLinkset.AddMeToLinkset(child);
child.Linkset = newLinkset;
}