BulletSim: add shape and linkset rebuild scheduled flags. Add BSPrim.Incomplete flag based on rebuild flags to say when an object is being rebuilt.

mb-throttle-test
Robert Adams 2014-10-02 18:45:36 -07:00
parent 981fff95cd
commit cf85ade81e
7 changed files with 101 additions and 19 deletions

View File

@ -73,8 +73,12 @@ public sealed class BSCharacter : BSPhysObject
// base.RawVelocity = value; }
// }
// Avatars are always complete (in the physics engine sense)
public override bool IsIncomplete { get { return false; } }
public BSCharacter(
uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying)
: base(parent_scene, localID, avName, "BSCharacter")
{
_physicsActorType = (int)ActorTypes.Agent;

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -128,6 +128,7 @@ public abstract class BSLinkset
m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>();
LinksetMass = parent.RawMass;
Rebuilding = false;
RebuildScheduled = false;
parent.ClearDisplacement();
}
@ -297,8 +298,16 @@ public abstract class BSLinkset
// Flag denoting the linkset is in the process of being rebuilt.
// Used to know not the schedule a rebuild in the middle of a rebuild.
// Because of potential update calls that could want to schedule another rebuild.
protected bool Rebuilding { get; set; }
// Flag saying a linkset rebuild has been scheduled.
// This is turned on when the rebuild is requested and turned off when
// the rebuild is complete. Used to limit modifications to the
// linkset parameters while the linkset is in an intermediate state.
// Protected by a "lock(this)" on the BSLinkset object
public bool RebuildScheduled { get; protected set; }
// The object is going dynamic (physical). Do any setup necessary
// for a dynamic linkset.
// Only the state of the passed object can be modified. The rest of the linkset

View File

@ -106,13 +106,21 @@ public sealed class BSLinksetCompound : BSLinkset
// When rebuilding, it is possible to set properties that would normally require a rebuild.
// If already rebuilding, don't request another rebuild.
// If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
if (!Rebuilding && HasAnyChildren)
lock (this)
{
m_physicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
if (!RebuildScheduled)
{
if (HasAnyChildren)
RecomputeLinksetCompound();
});
if (!Rebuilding && HasAnyChildren)
{
RebuildScheduled = true;
m_physicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
{
if (HasAnyChildren)
RecomputeLinksetCompound();
RebuildScheduled = false;
});
}
}
}
}

View File

@ -212,20 +212,28 @@ public sealed class BSLinksetConstraints : BSLinkset
// When rebuilding, it is possible to set properties that would normally require a rebuild.
// If already rebuilding, don't request another rebuild.
// If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
if (!Rebuilding && HasAnyChildren)
lock (this)
{
// Queue to happen after all the other taint processing
m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
if (!RebuildScheduled)
{
if (HasAnyChildren)
if (!Rebuilding && HasAnyChildren)
{
// Constraints that have not been changed are not rebuild but make sure
// the constraint of the requestor is rebuilt.
PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
// Rebuild the linkset and all its constraints.
RecomputeLinksetConstraints();
RebuildScheduled = true;
// Queue to happen after all the other taint processing
m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
{
if (HasAnyChildren)
{
// Constraints that have not been changed are not rebuild but make sure
// the constraint of the requestor is rebuilt.
PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
// Rebuild the linkset and all its constraints.
RecomputeLinksetConstraints();
}
RebuildScheduled = false;
});
}
});
}
}
}

View File

@ -136,6 +136,15 @@ public abstract class BSPhysObject : PhysicsActor
// This mostly prevents property updates and collisions until the object is completely here.
public bool IsInitialized { get; protected set; }
// Set to 'true' if an object (mesh/linkset/sculpty) is not completely constructed.
// This test is used to prevent some updates to the object when it only partially exists.
// There are several reasons and object might be incomplete:
// Its underlying mesh/sculpty is an asset which must be fetched from the asset store
// It is a linkset who is being added to or removed from
// It is changing state (static to physical, for instance) which requires rebuilding
// This is a computed value based on the underlying physical object construction
abstract public bool IsIncomplete { get; }
// Return the object mass without calculating it or having side effects
public abstract float RawMass { get; }
// Set the raw mass but also update physical mass properties (inertia, ...)

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -141,6 +141,18 @@ public class BSPrim : BSPhysObject
public override bool Stopped {
get { return false; }
}
public override bool IsIncomplete {
get {
return ShapeRebuildScheduled;
}
}
// 'true' if this object's shape is in need of a rebuild and a rebuild has been queued.
// The prim is still available but its underlying shape will change soon.
// This is protected by a 'lock(this)'.
public bool ShapeRebuildScheduled { get; protected set; }
public override OMV.Vector3 Size {
get { return _size; }
set {
@ -159,13 +171,37 @@ public class BSPrim : BSPhysObject
ForceBodyShapeRebuild(false);
}
}
// Cause the body and shape of the prim to be rebuilt if necessary.
// If there are no changes required, this is quick and does not make changes to the prim.
// If rebuilding is necessary (like changing from static to physical), that will happen.
// The 'ShapeRebuildScheduled' tells any checker that the body/shape may change shortly.
// The return parameter is not used by anyone.
public override bool ForceBodyShapeRebuild(bool inTaintTime)
{
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ForceBodyShapeRebuild", delegate()
if (inTaintTime)
{
// If called in taint time, do the operation immediately
_mass = CalculateMass(); // changing the shape changes the mass
CreateGeomAndObject(true);
});
}
else
{
lock (this)
{
// If a rebuild is not already in the queue
if (!ShapeRebuildScheduled)
{
// Remember that a rebuild is queued -- this is used to flag an incomplete object
ShapeRebuildScheduled = true;
PhysScene.TaintedObject(LocalID, "BSPrim.ForceBodyShapeRebuild", delegate()
{
_mass = CalculateMass(); // changing the shape changes the mass
CreateGeomAndObject(true);
ShapeRebuildScheduled = false;
});
}
}
}
return true;
}
public override bool Grabbed {

View File

@ -54,6 +54,14 @@ public class BSPrimLinkable : BSPrimDisplaced
public BSLinkset.LinksetImplementation LinksetType { get; set; }
public override bool IsIncomplete
{
get
{
return base.IsIncomplete || Linkset.RebuildScheduled ;
}
}
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
: base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)