BulletSim: massive refactor of shape classes. Removed shape specific code from BSShapeCollection. Using BSShape* classes to hold references to shape. Simplified shape dependency callbacks. Remove 'PreferredShape' methods and have each class specify shape type. Disable compound shape linkset for a later commit that will simplify linkset implementation.
parent
890cb6a293
commit
e5582939fd
|
@ -79,7 +79,7 @@ private sealed class BulletShapeUnman : BulletShape
|
|||
: base()
|
||||
{
|
||||
ptr = xx;
|
||||
type = typ;
|
||||
shapeType = typ;
|
||||
}
|
||||
public override bool HasPhysicalShape
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ private sealed class BulletShapeUnman : BulletShape
|
|||
}
|
||||
public override BulletShape Clone()
|
||||
{
|
||||
return new BulletShapeUnman(ptr, type);
|
||||
return new BulletShapeUnman(ptr, shapeType);
|
||||
}
|
||||
public override bool ReferenceSame(BulletShape other)
|
||||
{
|
||||
|
@ -375,7 +375,7 @@ public override BulletShape DuplicateCollisionShape(BulletWorld world, BulletSha
|
|||
{
|
||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||
BulletShapeUnman srcShapeu = srcShape as BulletShapeUnman;
|
||||
return new BulletShapeUnman(BSAPICPP.DuplicateCollisionShape2(worldu.ptr, srcShapeu.ptr, id), srcShape.type);
|
||||
return new BulletShapeUnman(BSAPICPP.DuplicateCollisionShape2(worldu.ptr, srcShapeu.ptr, id), srcShape.shapeType);
|
||||
}
|
||||
|
||||
public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape)
|
||||
|
|
|
@ -85,7 +85,7 @@ private sealed class BulletShapeXNA : BulletShape
|
|||
: base()
|
||||
{
|
||||
shape = xx;
|
||||
type = typ;
|
||||
shapeType = typ;
|
||||
}
|
||||
public override bool HasPhysicalShape
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ private sealed class BulletShapeXNA : BulletShape
|
|||
}
|
||||
public override BulletShape Clone()
|
||||
{
|
||||
return new BulletShapeXNA(shape, type);
|
||||
return new BulletShapeXNA(shape, shapeType);
|
||||
}
|
||||
public override bool ReferenceSame(BulletShape other)
|
||||
{
|
||||
|
|
|
@ -87,8 +87,8 @@ public class BSActorAvatarMove : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@ public class BSActorHover : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -85,8 +85,8 @@ public class BSActorLockAxis : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
|
|
|
@ -88,8 +88,8 @@ public class BSActorMoveToTarget : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the moveToTarget since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ public class BSActorSetForce : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ public class BSActorSetTorque : BSActor
|
|||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
// BSActor.RemoveDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
|
|
@ -106,9 +106,9 @@ public class BSActorCollection
|
|||
{
|
||||
ForEachActor(a => a.Refresh());
|
||||
}
|
||||
public void RemoveBodyDependencies()
|
||||
public void RemoveDependencies()
|
||||
{
|
||||
ForEachActor(a => a.RemoveBodyDependencies());
|
||||
ForEachActor(a => a.RemoveDependencies());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ public abstract class BSActor
|
|||
public abstract void Refresh();
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
public abstract void RemoveBodyDependencies();
|
||||
public abstract void RemoveDependencies();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,8 +123,8 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, null /* bodyCallback */);
|
||||
PhysShape.Clear();
|
||||
PhysShape.Dereference(PhysicsScene);
|
||||
PhysShape = new BSShapeNull();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -146,8 +146,8 @@ public sealed class BSCharacter : BSPhysObject
|
|||
Flying = _flying;
|
||||
|
||||
PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution);
|
||||
PhysicsScene.PE.SetMargin(PhysShape, PhysicsScene.Params.collisionMargin);
|
||||
PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
|
||||
PhysicsScene.PE.SetMargin(PhysShape.physShapeInfo, PhysicsScene.Params.collisionMargin);
|
||||
PhysicsScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
|
||||
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
|
||||
if (BSParam.CcdMotionThreshold > 0f)
|
||||
{
|
||||
|
@ -205,9 +205,9 @@ public sealed class BSCharacter : BSPhysObject
|
|||
|
||||
PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
|
||||
{
|
||||
if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape)
|
||||
if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
|
||||
{
|
||||
PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
|
||||
PhysicsScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
|
||||
UpdatePhysicalMassProperties(RawMass, true);
|
||||
// Make sure this change appears as a property update event
|
||||
PhysicsScene.PE.PushUpdate(PhysBody);
|
||||
|
@ -221,11 +221,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
set { BaseShape = value; }
|
||||
}
|
||||
// I want the physics engine to make an avatar capsule
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||
{
|
||||
get {return BSPhysicsShapeType.SHAPE_CAPSULE; }
|
||||
}
|
||||
|
||||
public override bool Grabbed {
|
||||
set { _grabbed = value; }
|
||||
|
@ -381,7 +376,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
}
|
||||
public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
|
||||
{
|
||||
OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
|
||||
OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
|
||||
PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia);
|
||||
}
|
||||
|
||||
|
|
|
@ -625,7 +625,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Vehicles report collision events so we know when it's on the ground
|
||||
m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
|
||||
ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape, m_vehicleMass);
|
||||
ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
|
||||
m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
|
||||
m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
|
||||
|
||||
|
@ -649,7 +649,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
|
||||
// BSActor.RemoveBodyDependencies
|
||||
public override void RemoveBodyDependencies()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
|
|
@ -93,13 +93,6 @@ public abstract class BSLinkset
|
|||
// to the physical representation is done via the tainting mechenism.
|
||||
protected object m_linksetActivityLock = new Object();
|
||||
|
||||
// Some linksets have a preferred physical shape.
|
||||
// Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
|
||||
public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
|
||||
{
|
||||
return BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
}
|
||||
|
||||
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
|
||||
public float LinksetMass { get; protected set; }
|
||||
|
||||
|
@ -263,7 +256,7 @@ public abstract class BSLinkset
|
|||
// This is called when the root body is changing.
|
||||
// Returns 'true' of something was actually removed and would need restoring
|
||||
// Called at taint-time!!
|
||||
public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
|
||||
public abstract bool RemoveDependencies(BSPrimLinkable child);
|
||||
|
||||
// ================================================================
|
||||
protected virtual float ComputeLinksetMass()
|
||||
|
|
|
@ -98,19 +98,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
{
|
||||
}
|
||||
|
||||
// For compound implimented linksets, if there are children, use compound shape for the root.
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
|
||||
{
|
||||
// Returning 'unknown' means we don't have a preference.
|
||||
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
if (IsRoot(requestor) && HasAnyChildren)
|
||||
{
|
||||
ret = BSPhysicsShapeType.SHAPE_COMPOUND;
|
||||
}
|
||||
// DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// When physical properties are changed the linkset needs to recalculate
|
||||
// its internal properties.
|
||||
public override void Refresh(BSPrimLinkable requestor)
|
||||
|
@ -218,22 +205,22 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// and that is caused by us updating the object.
|
||||
if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
|
||||
{
|
||||
// Find the physical instance of the child
|
||||
if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
|
||||
// Find the physical instance of the child
|
||||
if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo))
|
||||
{
|
||||
// It is possible that the linkset is still under construction and the child is not yet
|
||||
// inserted into the compound shape. A rebuild of the linkset in a pre-step action will
|
||||
// build the whole thing with the new position or rotation.
|
||||
// The index must be checked because Bullet references the child array but does no validity
|
||||
// checking of the child index passed.
|
||||
int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape);
|
||||
int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape.physShapeInfo);
|
||||
if (updated.LinksetChildIndex < numLinksetChildren)
|
||||
{
|
||||
BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, updated.LinksetChildIndex);
|
||||
BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex);
|
||||
if (linksetChildShape.HasPhysicalShape)
|
||||
{
|
||||
// Found the child shape within the compound shape
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, updated.LinksetChildIndex,
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape.physShapeInfo, updated.LinksetChildIndex,
|
||||
updated.RawPosition - LinksetRoot.RawPosition,
|
||||
updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation),
|
||||
true /* shouldRecalculateLocalAabb */);
|
||||
|
@ -278,7 +265,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// Since we don't keep in world relationships, do nothing unless it's a child changing.
|
||||
// Returns 'true' of something was actually removed and would need restoring
|
||||
// Called at taint-time!!
|
||||
public override bool RemoveBodyDependencies(BSPrimLinkable child)
|
||||
public override bool RemoveDependencies(BSPrimLinkable child)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
|
@ -404,11 +391,12 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
{
|
||||
try
|
||||
{
|
||||
/*
|
||||
// Suppress rebuilding while rebuilding. (We know rebuilding is on only one thread.)
|
||||
Rebuilding = true;
|
||||
|
||||
// Cause the root shape to be rebuilt as a compound object with just the root in it
|
||||
LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime */);
|
||||
LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime );
|
||||
|
||||
// The center of mass for the linkset is the geometric center of the group.
|
||||
// Compute a displacement for each component so it is relative to the center-of-mass.
|
||||
|
@ -430,10 +418,10 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
|
||||
|
||||
// Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0 /* childIndex */,
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape.physShapeInfo, 0 /* childIndex ,
|
||||
-centerDisplacement,
|
||||
OMV.Quaternion.Identity, // LinksetRoot.RawOrientation,
|
||||
false /* shouldRecalculateLocalAabb (is done later after linkset built) */);
|
||||
false /* shouldRecalculateLocalAabb (is done later after linkset built) );
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
|
||||
LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement);
|
||||
|
@ -501,6 +489,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
|
||||
// Enable the physical position updator to return the position and rotation of the root shape
|
||||
PhysicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
|
||||
*/
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -508,7 +497,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
}
|
||||
|
||||
// See that the Aabb surrounds the new shape
|
||||
PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
|
||||
PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape.physShapeInfo);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -93,11 +93,11 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
// up to rebuild the constraints before the next simulation step.
|
||||
// Returns 'true' of something was actually removed and would need restoring
|
||||
// Called at taint-time!!
|
||||
public override bool RemoveBodyDependencies(BSPrimLinkable child)
|
||||
public override bool RemoveDependencies(BSPrimLinkable child)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
|
||||
DetailLog("{0},BSLinksetConstraint.RemoveDependencies,removeChildrenForRoot,rID={1},rBody={2}",
|
||||
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString);
|
||||
|
||||
lock (m_linksetActivityLock)
|
||||
|
|
|
@ -88,7 +88,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
// We don't have any physical representation yet.
|
||||
PhysBody = new BulletBody(localID);
|
||||
PhysShape = new BulletShape();
|
||||
PhysShape = new BSShapeNull();
|
||||
|
||||
PrimAssetState = PrimAssetCondition.Unknown;
|
||||
|
||||
|
@ -138,7 +138,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// Reference to the physical body (btCollisionObject) of this object
|
||||
public BulletBody PhysBody;
|
||||
// Reference to the physical shape (btCollisionShape) of this object
|
||||
public BulletShape PhysShape;
|
||||
public BSShape PhysShape;
|
||||
|
||||
// The physical representation of the prim might require an asset fetch.
|
||||
// The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'.
|
||||
|
@ -151,13 +151,6 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// The objects base shape information. Null if not a prim type shape.
|
||||
public PrimitiveBaseShape BaseShape { get; protected set; }
|
||||
|
||||
// Some types of objects have preferred physical representations.
|
||||
// Returns SHAPE_UNKNOWN if there is no preference.
|
||||
public virtual BSPhysicsShapeType PreferredPhysicalShape
|
||||
{
|
||||
get { return BSPhysicsShapeType.SHAPE_UNKNOWN; }
|
||||
}
|
||||
|
||||
// When the physical properties are updated, an EntityProperty holds the update values.
|
||||
// Keep the current and last EntityProperties to enable computation of differences
|
||||
// between the current update and the previous values.
|
||||
|
|
|
@ -134,8 +134,8 @@ public class BSPrim : BSPhysObject
|
|||
// If there are physical body and shape, release my use of same.
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, null);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, null);
|
||||
PhysShape.Clear();
|
||||
PhysShape.Dereference(PhysicsScene);
|
||||
PhysShape = new BSShapeNull();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -161,25 +161,13 @@ public class BSPrim : BSPhysObject
|
|||
ForceBodyShapeRebuild(false);
|
||||
}
|
||||
}
|
||||
// 'unknown' says to choose the best type
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||
{ get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } }
|
||||
|
||||
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
||||
{
|
||||
if (inTaintTime)
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
CreateGeomAndObject(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
CreateGeomAndObject(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
public override bool Grabbed {
|
||||
|
@ -462,7 +450,7 @@ public class BSPrim : BSPhysObject
|
|||
Gravity = ComputeGravity(Buoyancy);
|
||||
PhysicsScene.PE.SetGravity(PhysBody, Gravity);
|
||||
|
||||
Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
|
||||
Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
|
||||
PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia);
|
||||
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
|
||||
|
||||
|
@ -805,7 +793,8 @@ public class BSPrim : BSPhysObject
|
|||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
|
||||
|
||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
|
||||
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
||||
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(),
|
||||
CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
||||
}
|
||||
|
||||
// "Making dynamic" means changing to and from static.
|
||||
|
@ -1463,12 +1452,13 @@ public class BSPrim : BSPhysObject
|
|||
// Create the correct physical representation for this type of object.
|
||||
// Updates base.PhysBody and base.PhysShape with the new information.
|
||||
// Ignore 'forceRebuild'. 'GetBodyAndShape' makes the right choices and changes of necessary.
|
||||
PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, null, delegate(BulletBody dBody)
|
||||
PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, delegate(BulletBody pBody, BulletShape pShape)
|
||||
{
|
||||
// Called if the current prim body is about to be destroyed.
|
||||
// Remove all the physical dependencies on the old body.
|
||||
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
||||
RemoveBodyDependencies();
|
||||
// Note: this virtual function is overloaded by BSPrimLinkable to remove linkset constraints.
|
||||
RemoveDependencies();
|
||||
});
|
||||
|
||||
// Make sure the properties are set on the new object
|
||||
|
@ -1477,9 +1467,9 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
|
||||
// Called at taint-time
|
||||
protected virtual void RemoveBodyDependencies()
|
||||
protected virtual void RemoveDependencies()
|
||||
{
|
||||
PhysicalActors.RemoveBodyDependencies();
|
||||
PhysicalActors.RemoveDependencies();
|
||||
}
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
|
|
|
@ -61,9 +61,6 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
base.Destroy();
|
||||
}
|
||||
|
||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||
{ get { return Linkset.PreferredPhysicalShape(this); } }
|
||||
|
||||
public override void link(Manager.PhysicsActor obj)
|
||||
{
|
||||
BSPrimLinkable parent = obj as BSPrimLinkable;
|
||||
|
@ -149,10 +146,10 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
}
|
||||
|
||||
// Body is being taken apart. Remove physical dependencies and schedule a rebuild.
|
||||
protected override void RemoveBodyDependencies()
|
||||
protected override void RemoveDependencies()
|
||||
{
|
||||
Linkset.RemoveBodyDependencies(this);
|
||||
base.RemoveBodyDependencies();
|
||||
Linkset.RemoveDependencies(this);
|
||||
base.RemoveDependencies();
|
||||
}
|
||||
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,6 +39,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
public abstract class BSShape
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM SHAPE]";
|
||||
|
||||
public int referenceCount { get; set; }
|
||||
public DateTime lastReferenced { get; set; }
|
||||
public BulletShape physShapeInfo { get; set; }
|
||||
|
@ -56,49 +58,6 @@ public abstract class BSShape
|
|||
physShapeInfo = pShape;
|
||||
}
|
||||
|
||||
// Get a reference to a physical shape. Create if it doesn't exist
|
||||
public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
BSShape ret = null;
|
||||
|
||||
if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
|
||||
{
|
||||
// an avatar capsule is close to a native shape (it is not shared)
|
||||
ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE,
|
||||
FixedShapeKey.KEY_CAPSULE);
|
||||
physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret);
|
||||
}
|
||||
|
||||
// Compound shapes are handled special as they are rebuilt from scratch.
|
||||
// This isn't too great a hardship since most of the child shapes will have already been created.
|
||||
if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
|
||||
{
|
||||
// Getting a reference to a compound shape gets you the compound shape with the root prim shape added
|
||||
ret = BSShapeCompound.GetReference(physicsScene, prim);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
|
||||
}
|
||||
|
||||
// Avatars have their own unique shape
|
||||
if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR)
|
||||
{
|
||||
// Getting a reference to a compound shape gets you the compound shape with the root prim shape added
|
||||
ret = BSShapeAvatar.GetReference(prim);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret);
|
||||
}
|
||||
|
||||
if (ret == null)
|
||||
ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
|
||||
|
||||
return ret;
|
||||
}
|
||||
private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
// TODO: work needed here!!
|
||||
BSShapeMesh.GetReference(physicsScene, forceRebuild, prim);
|
||||
BSShapeHull.GetReference(physicsScene, forceRebuild, prim);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Called when this shape is being used again.
|
||||
public virtual void IncrementReference()
|
||||
{
|
||||
|
@ -116,6 +75,27 @@ public abstract class BSShape
|
|||
// Release the use of a physical shape.
|
||||
public abstract void Dereference(BSScene physicsScene);
|
||||
|
||||
// Return 'true' if there is an allocated physics physical shape under this class instance.
|
||||
public virtual bool HasPhysicalShape
|
||||
{
|
||||
get
|
||||
{
|
||||
if (physShapeInfo != null)
|
||||
return physShapeInfo.HasPhysicalShape;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public virtual BSPhysicsShapeType ShapeType
|
||||
{
|
||||
get
|
||||
{
|
||||
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
if (physShapeInfo != null && physShapeInfo.HasPhysicalShape)
|
||||
ret = physShapeInfo.shapeType;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a string for debugging that uniquily identifies the memory used by this instance
|
||||
public virtual string AddrString
|
||||
{
|
||||
|
@ -132,6 +112,119 @@ public abstract class BSShape
|
|||
buff.Append(">");
|
||||
return buff.ToString();
|
||||
}
|
||||
|
||||
// Create a hash of all the shape parameters to be used as a key for this particular shape.
|
||||
public static System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
|
||||
{
|
||||
// level of detail based on size and type of the object
|
||||
float lod = BSParam.MeshLOD;
|
||||
if (pbs.SculptEntry)
|
||||
lod = BSParam.SculptLOD;
|
||||
|
||||
// Mega prims usually get more detail because one can interact with shape approximations at this size.
|
||||
float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
|
||||
if (maxAxis > BSParam.MeshMegaPrimThreshold)
|
||||
lod = BSParam.MeshMegaPrimLOD;
|
||||
|
||||
retLod = lod;
|
||||
return pbs.GetMeshKey(size, lod);
|
||||
}
|
||||
|
||||
// The creation of a mesh or hull can fail if an underlying asset is not available.
|
||||
// There are two cases: 1) the asset is not in the cache and it needs to be fetched;
|
||||
// and 2) the asset cannot be converted (like failed decompression of JPEG2000s).
|
||||
// The first case causes the asset to be fetched. The second case requires
|
||||
// us to not loop forever.
|
||||
// Called after creating a physical mesh or hull. If the physical shape was created,
|
||||
// just return.
|
||||
public static BulletShape VerifyMeshCreated(BSScene physicsScene, BulletShape newShape, BSPhysObject prim)
|
||||
{
|
||||
// If the shape was successfully created, nothing more to do
|
||||
if (newShape.HasPhysicalShape)
|
||||
return newShape;
|
||||
|
||||
// VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been
|
||||
// fetched but we end up here again, the meshing of the asset must have failed.
|
||||
// Prevent trying to keep fetching the mesh by declaring failure.
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||
{
|
||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
|
||||
physicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}",
|
||||
LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
|
||||
if (prim.BaseShape.SculptEntry
|
||||
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed
|
||||
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
|
||||
&& prim.BaseShape.SculptTexture != OMV.UUID.Zero
|
||||
)
|
||||
{
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID);
|
||||
// Multiple requestors will know we're waiting for this asset
|
||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
|
||||
|
||||
BSPhysObject xprim = prim;
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod;
|
||||
if (assetProvider != null)
|
||||
{
|
||||
BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
|
||||
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
|
||||
{
|
||||
bool assetFound = false;
|
||||
string mismatchIDs = String.Empty; // DEBUG DEBUG
|
||||
if (asset != null && yprim.BaseShape.SculptEntry)
|
||||
{
|
||||
if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
|
||||
{
|
||||
yprim.BaseShape.SculptData = asset.Data;
|
||||
// This will cause the prim to see that the filler shape is not the right
|
||||
// one and try again to build the object.
|
||||
// No race condition with the normal shape setting since the rebuild is at taint time.
|
||||
yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
|
||||
assetFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
|
||||
}
|
||||
}
|
||||
if (assetFound)
|
||||
yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
|
||||
else
|
||||
yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
|
||||
physicsScene.DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
|
||||
yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
|
||||
physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
|
||||
LogHeader, physicsScene.Name);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
|
||||
{
|
||||
physicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}",
|
||||
LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// While we wait for the mesh defining asset to be loaded, stick in a simple box for the object.
|
||||
BSShape fillShape = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID);
|
||||
|
||||
return fillShape.physShapeInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
|
@ -199,7 +292,7 @@ public class BSShapeNative : BSShape
|
|||
physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
|
||||
LogHeader, prim.LocalID, shapeType);
|
||||
}
|
||||
newShape.type = shapeType;
|
||||
newShape.shapeType = shapeType;
|
||||
newShape.isNativeShape = true;
|
||||
newShape.shapeKey = (UInt64)shapeKey;
|
||||
return newShape;
|
||||
|
@ -219,10 +312,11 @@ public class BSShapeMesh : BSShape
|
|||
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
float lod;
|
||||
System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeMesh,getReference,oldKey={1},newKey={2},size={3},lod={4}",
|
||||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod);
|
||||
prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"),
|
||||
newMeshKey.ToString("X"), prim.Size, lod);
|
||||
|
||||
BSShapeMesh retMesh = new BSShapeMesh(new BulletShape());
|
||||
lock (Meshes)
|
||||
|
@ -238,8 +332,8 @@ public class BSShapeMesh : BSShape
|
|||
BulletShape newShape = retMesh.CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||
|
||||
// Check to see if mesh was created (might require an asset).
|
||||
newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
if (newShape.type == BSPhysicsShapeType.SHAPE_MESH)
|
||||
newShape = VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
if (newShape.shapeType == BSPhysicsShapeType.SHAPE_MESH)
|
||||
{
|
||||
// If a mesh was what was created, remember the built shape for later sharing.
|
||||
Meshes.Add(newMeshKey, retMesh);
|
||||
|
@ -360,10 +454,10 @@ public class BSShapeHull : BSShape
|
|||
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||
{
|
||||
float lod;
|
||||
System.UInt64 newHullKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||
|
||||
physicsScene.DetailLog("{0},BSShapeHull,getReference,oldKey={1},newKey={2},size={3},lod={4}",
|
||||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod);
|
||||
prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod);
|
||||
|
||||
BSShapeHull retHull = new BSShapeHull(new BulletShape());
|
||||
lock (Hulls)
|
||||
|
@ -379,8 +473,8 @@ public class BSShapeHull : BSShape
|
|||
BulletShape newShape = retHull.CreatePhysicalHull(physicsScene, prim, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||
|
||||
// Check to see if mesh was created (might require an asset).
|
||||
newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
if (newShape.type == BSPhysicsShapeType.SHAPE_MESH)
|
||||
newShape = VerifyMeshCreated(physicsScene, newShape, prim);
|
||||
if (newShape.shapeType == BSPhysicsShapeType.SHAPE_MESH)
|
||||
{
|
||||
// If a mesh was what was created, remember the built shape for later sharing.
|
||||
Hulls.Add(newHullKey, retHull);
|
||||
|
@ -569,7 +663,6 @@ public class BSShapeHull : BSShape
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================================================
|
||||
public class BSShapeCompound : BSShape
|
||||
{
|
||||
|
@ -589,9 +682,9 @@ public class BSShapeCompound : BSShape
|
|||
{
|
||||
// Failed the sanity check!!
|
||||
physicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
|
||||
LogHeader, physShapeInfo.type, physShapeInfo.AddrString);
|
||||
LogHeader, physShapeInfo.shapeType, physShapeInfo.AddrString);
|
||||
physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
|
||||
BSScene.DetailLogZero, physShapeInfo.type, physShapeInfo.AddrString);
|
||||
BSScene.DetailLogZero, physShapeInfo.shapeType, physShapeInfo.AddrString);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,11 +104,11 @@ public class BulletShape
|
|||
{
|
||||
public BulletShape()
|
||||
{
|
||||
type = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
shapeType = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||
shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE;
|
||||
isNativeShape = false;
|
||||
}
|
||||
public BSPhysicsShapeType type;
|
||||
public BSPhysicsShapeType shapeType;
|
||||
public System.UInt64 shapeKey;
|
||||
public bool isNativeShape;
|
||||
|
||||
|
@ -133,7 +133,7 @@ public class BulletShape
|
|||
buff.Append("<p=");
|
||||
buff.Append(AddrString);
|
||||
buff.Append(",s=");
|
||||
buff.Append(type.ToString());
|
||||
buff.Append(shapeType.ToString());
|
||||
buff.Append(",k=");
|
||||
buff.Append(shapeKey.ToString("X"));
|
||||
buff.Append(",n=");
|
||||
|
|
Loading…
Reference in New Issue