BulletSim: rename some constraint variables to be consistant with other name use.
Added callbacks for shape and body changes in GetBodyAndShape() so the linkset constraints can be picked up and restored. A better design might be to have a "prim shape changed" event. Think about that. Added constraint types to general constraint class.connector_plugin
parent
7b65985047
commit
74dea4cfd5
|
@ -34,6 +34,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
public class BS6DofConstraint : BSConstraint
|
public class BS6DofConstraint : BSConstraint
|
||||||
{
|
{
|
||||||
|
private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]";
|
||||||
|
|
||||||
|
public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } }
|
||||||
|
|
||||||
// Create a btGeneric6DofConstraint
|
// Create a btGeneric6DofConstraint
|
||||||
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||||
Vector3 frame1, Quaternion frame1rot,
|
Vector3 frame1, Quaternion frame1rot,
|
||||||
|
@ -49,6 +53,9 @@ public class BS6DofConstraint : BSConstraint
|
||||||
frame2, frame2rot,
|
frame2, frame2rot,
|
||||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||||
m_enabled = true;
|
m_enabled = true;
|
||||||
|
world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
|
||||||
|
BSScene.DetailLogZero, world.worldID,
|
||||||
|
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||||
|
@ -60,12 +67,13 @@ public class BS6DofConstraint : BSConstraint
|
||||||
m_body2 = obj2;
|
m_body2 = obj2;
|
||||||
if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero)
|
if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
world.scene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
|
world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
|
||||||
"[BULLETSIM 6DOF CONSTRAINT]", world.worldID,
|
BSScene.DetailLogZero, world.worldID,
|
||||||
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
|
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
|
||||||
world.scene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
|
world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
|
||||||
"[BULLETSIM 6DOF CONSTRAINT]", world.worldID,
|
"[BULLETSIM 6DOF CONSTRAINT]", world.worldID,
|
||||||
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
|
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
|
||||||
|
m_enabled = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -73,16 +81,28 @@ public class BS6DofConstraint : BSConstraint
|
||||||
BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
|
BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
|
||||||
joinPoint,
|
joinPoint,
|
||||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||||
|
world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
|
||||||
|
BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"),
|
||||||
|
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
|
||||||
|
if (m_constraint.ptr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
|
||||||
|
LogHeader, obj1.ID, obj2.ID);
|
||||||
|
m_enabled = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
m_enabled = true;
|
m_enabled = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
|
public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetFrames2(m_constraint.Ptr, frameA, frameArot, frameB, frameBrot);
|
BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -93,9 +113,9 @@ public class BS6DofConstraint : BSConstraint
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
|
BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
|
||||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -106,7 +126,7 @@ public class BS6DofConstraint : BSConstraint
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff);
|
ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +135,7 @@ public class BS6DofConstraint : BSConstraint
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce);
|
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +143,7 @@ public class BS6DofConstraint : BSConstraint
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.Ptr, threshold);
|
ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,20 +49,23 @@ public abstract class BSConstraint : IDisposable
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.Ptr);
|
bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr);
|
||||||
m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
|
m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
|
||||||
m_constraint.Ptr = System.IntPtr.Zero;
|
m_constraint.ptr = System.IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BulletBody Body1 { get { return m_body1; } }
|
public BulletBody Body1 { get { return m_body1; } }
|
||||||
public BulletBody Body2 { get { return m_body2; } }
|
public BulletBody Body2 { get { return m_body2; } }
|
||||||
|
public BulletConstraint Constraint { get { return m_constraint; } }
|
||||||
|
public abstract ConstraintType Type { get; }
|
||||||
|
|
||||||
|
|
||||||
public virtual bool SetLinearLimits(Vector3 low, Vector3 high)
|
public virtual bool SetLinearLimits(Vector3 low, Vector3 high)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
ret = BulletSimAPI.SetLinearLimits2(m_constraint.Ptr, low, high);
|
ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +73,7 @@ public abstract class BSConstraint : IDisposable
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
ret = BulletSimAPI.SetAngularLimits2(m_constraint.Ptr, low, high);
|
ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +82,7 @@ public abstract class BSConstraint : IDisposable
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.Ptr, cnt);
|
BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -91,7 +94,7 @@ public abstract class BSConstraint : IDisposable
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
// Recompute the internal transforms
|
// Recompute the internal transforms
|
||||||
BulletSimAPI.CalculateTransforms2(m_constraint.Ptr);
|
BulletSimAPI.CalculateTransforms2(m_constraint.ptr);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -110,11 +113,11 @@ public abstract class BSConstraint : IDisposable
|
||||||
// Setting an object's mass to zero (making it static like when it's selected)
|
// Setting an object's mass to zero (making it static like when it's selected)
|
||||||
// automatically disables the constraints.
|
// automatically disables the constraints.
|
||||||
// If the link is enabled, be sure to set the constraint itself to enabled.
|
// If the link is enabled, be sure to set the constraint itself to enabled.
|
||||||
BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
|
BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, m_world.physicsScene.NumericBool(true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_world.scene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID);
|
m_world.physicsScene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -34,6 +34,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
class BSHingeConstraint : BSConstraint
|
class BSHingeConstraint : BSConstraint
|
||||||
{
|
{
|
||||||
|
public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } }
|
||||||
|
|
||||||
public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||||
Vector3 pivotInA, Vector3 pivotInB,
|
Vector3 pivotInA, Vector3 pivotInB,
|
||||||
Vector3 axisInA, Vector3 axisInB,
|
Vector3 axisInA, Vector3 axisInB,
|
||||||
|
|
|
@ -88,6 +88,7 @@ public class BSLinkset
|
||||||
// Link to a linkset where the child knows the parent.
|
// Link to a linkset where the child knows the parent.
|
||||||
// Parent changing should not happen so do some sanity checking.
|
// Parent changing should not happen so do some sanity checking.
|
||||||
// We return the parent's linkset so the child can track its membership.
|
// We return the parent's linkset so the child can track its membership.
|
||||||
|
// Called at runtime.
|
||||||
public BSLinkset AddMeToLinkset(BSPhysObject child)
|
public BSLinkset AddMeToLinkset(BSPhysObject child)
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
|
@ -102,6 +103,7 @@ public class BSLinkset
|
||||||
// Remove a child from a linkset.
|
// Remove a child from a linkset.
|
||||||
// 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.
|
||||||
public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
|
public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
|
@ -113,27 +115,6 @@ public class BSLinkset
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveChildFromLinkset(child);
|
RemoveChildFromLinkset(child);
|
||||||
|
|
||||||
/* Alternate implementation that destroys the linkset of the root is removed.
|
|
||||||
* This fails because items are added and removed from linksets to build shapes.
|
|
||||||
* Code left for reference.
|
|
||||||
if (IsRoot(child))
|
|
||||||
{
|
|
||||||
// if root of linkset, take the linkset apart
|
|
||||||
while (m_children.Count > 0)
|
|
||||||
{
|
|
||||||
// Note that we don't do a foreach because the remove routine
|
|
||||||
// takes it out of the list.
|
|
||||||
RemoveChildFromOtherLinkset(m_children[0]);
|
|
||||||
}
|
|
||||||
m_children.Clear(); // just to make sure
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Just removing a child from an existing linkset
|
|
||||||
RemoveChildFromLinkset(child);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The child is down to a linkset of just itself
|
// The child is down to a linkset of just itself
|
||||||
|
@ -169,6 +150,106 @@ public class BSLinkset
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// has not yet been fully constructed.
|
||||||
|
// Return 'true' if any properties updated on the passed object.
|
||||||
|
// Called at taint-time!
|
||||||
|
public bool MakeDynamic(BSPhysObject child)
|
||||||
|
{
|
||||||
|
// What is done for each object in BSPrim is what we want.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The object is going static (non-physical). Do any setup necessary
|
||||||
|
// for a static linkset.
|
||||||
|
// Return 'true' if any properties updated on the passed object.
|
||||||
|
// Called at taint-time!
|
||||||
|
public bool MakeStatic(BSPhysObject child)
|
||||||
|
{
|
||||||
|
// What is done for each object in BSPrim is what we want.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When physical properties are changed the linkset needs to recalculate
|
||||||
|
// its internal properties.
|
||||||
|
// Called at runtime.
|
||||||
|
public void Refresh(BSPhysObject requestor)
|
||||||
|
{
|
||||||
|
// If there are no children, there can't be any constraints to recompute
|
||||||
|
if (!HasAnyChildren)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Only the root does the recomputation
|
||||||
|
if (IsRoot(requestor))
|
||||||
|
{
|
||||||
|
PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
|
||||||
|
{
|
||||||
|
RecomputeLinksetConstraintVariables();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Routine used when rebuilding the body of the root of the linkset
|
||||||
|
// Destroy all the constraints have have been made to root.
|
||||||
|
// This is called when the root body is changing.
|
||||||
|
// Called at taint-time!!
|
||||||
|
public void RemoveBodyDependencies(BSPrim child)
|
||||||
|
{
|
||||||
|
lock (m_linksetActivityLock)
|
||||||
|
{
|
||||||
|
if (IsRoot(child))
|
||||||
|
{
|
||||||
|
// If the one with the dependency is root, must undo all children
|
||||||
|
DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},numChild={2}",
|
||||||
|
LinksetRoot.LocalID, m_children.Count);
|
||||||
|
foreach (BSPhysObject bpo in m_children)
|
||||||
|
{
|
||||||
|
PhysicallyUnlinkAChildFromRoot(LinksetRoot, LinksetRoot.BSBody, bpo, bpo.BSBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
|
||||||
|
LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
|
||||||
|
child.LocalID, child.BSBody.ptr.ToString("X"));
|
||||||
|
// Remove the dependency on the body of this one
|
||||||
|
PhysicallyUnlinkAChildFromRoot(LinksetRoot, LinksetRoot.BSBody, child, child.BSBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Routine used when rebuilding the body of the root of the linkset
|
||||||
|
// This is called after RemoveAllLinksToRoot() to restore all the constraints.
|
||||||
|
// This is called when the root body has been changed.
|
||||||
|
// Called at taint-time!!
|
||||||
|
public void RestoreBodyDependencies(BSPrim child)
|
||||||
|
{
|
||||||
|
lock (m_linksetActivityLock)
|
||||||
|
{
|
||||||
|
if (IsRoot(child))
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}",
|
||||||
|
LinksetRoot.LocalID, m_children.Count);
|
||||||
|
foreach (BSPhysObject bpo in m_children)
|
||||||
|
{
|
||||||
|
PhysicallyLinkAChildToRoot(LinksetRoot, LinksetRoot.BSBody, bpo, bpo.BSBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
|
||||||
|
LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
|
||||||
|
child.LocalID, child.BSBody.ptr.ToString("X"));
|
||||||
|
PhysicallyLinkAChildToRoot(LinksetRoot, LinksetRoot.BSBody, child, child.BSBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// Below this point is internal magic
|
||||||
|
|
||||||
private float ComputeLinksetMass()
|
private float ComputeLinksetMass()
|
||||||
{
|
{
|
||||||
float mass;
|
float mass;
|
||||||
|
@ -220,46 +301,6 @@ public class BSLinkset
|
||||||
return com;
|
return com;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
// has not yet been fully constructed.
|
|
||||||
// Return 'true' if any properties updated on the passed object.
|
|
||||||
// Called at taint-time!
|
|
||||||
public bool MakeDynamic(BSPhysObject child)
|
|
||||||
{
|
|
||||||
// What is done for each object in BSPrim is what we want.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The object is going static (non-physical). Do any setup necessary
|
|
||||||
// for a static linkset.
|
|
||||||
// Return 'true' if any properties updated on the passed object.
|
|
||||||
// Called at taint-time!
|
|
||||||
public bool MakeStatic(BSPhysObject child)
|
|
||||||
{
|
|
||||||
// What is done for each object in BSPrim is what we want.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When physical properties are changed the linkset needs to recalculate
|
|
||||||
// its internal properties.
|
|
||||||
public void Refresh(BSPhysObject requestor)
|
|
||||||
{
|
|
||||||
// If there are no children, there can't be any constraints to recompute
|
|
||||||
if (!HasAnyChildren)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Only the root does the recomputation
|
|
||||||
if (IsRoot(requestor))
|
|
||||||
{
|
|
||||||
PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
|
|
||||||
{
|
|
||||||
RecomputeLinksetConstraintVariables();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call each of the constraints that make up this linkset and recompute the
|
// Call each of the constraints that make up this linkset and recompute the
|
||||||
// various transforms and variables. Used when objects are added or removed
|
// various transforms and variables. Used when objects are added or removed
|
||||||
// from a linkset to make sure the constraints know about the new mass and
|
// from a linkset to make sure the constraints know about the new mass and
|
||||||
|
@ -327,6 +368,11 @@ public class BSLinkset
|
||||||
BSPhysObject childx = child;
|
BSPhysObject childx = child;
|
||||||
BulletBody childBodyx = child.BSBody;
|
BulletBody childBodyx = child.BSBody;
|
||||||
|
|
||||||
|
DetailLog("{0},AddChildToLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
|
||||||
|
rootx.LocalID,
|
||||||
|
rootx.LocalID, rootBodyx.ptr.ToString("X"),
|
||||||
|
childx.LocalID, childBodyx.ptr.ToString("X"));
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
|
PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
|
DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
|
||||||
|
@ -358,10 +404,14 @@ public class BSLinkset
|
||||||
BulletBody rootBodyx = LinksetRoot.BSBody;
|
BulletBody rootBodyx = LinksetRoot.BSBody;
|
||||||
BSPhysObject childx = child;
|
BSPhysObject childx = child;
|
||||||
BulletBody childBodyx = child.BSBody;
|
BulletBody childBodyx = child.BSBody;
|
||||||
|
|
||||||
|
DetailLog("{0},RemoveChildFromLinkset,call,child={1}",
|
||||||
|
rootx.LocalID,
|
||||||
|
rootx.LocalID, rootBodyx.ptr.ToString("X"),
|
||||||
|
childx.LocalID, childBodyx.ptr.ToString("X"));
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
|
PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
|
|
||||||
|
|
||||||
PhysicallyUnlinkAChildFromRoot(rootx, rootBodyx, childx, childBodyx);
|
PhysicallyUnlinkAChildFromRoot(rootx, rootBodyx, childx, childBodyx);
|
||||||
RecomputeLinksetConstraintVariables();
|
RecomputeLinksetConstraintVariables();
|
||||||
});
|
});
|
||||||
|
@ -390,14 +440,15 @@ public class BSLinkset
|
||||||
// real world coordinate of midpoint between the two objects
|
// real world coordinate of midpoint between the two objects
|
||||||
OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
|
OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
|
||||||
|
|
||||||
// create a constraint that allows no freedom of movement between the two objects
|
|
||||||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
|
||||||
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
|
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
|
||||||
rootPrim.LocalID,
|
rootPrim.LocalID,
|
||||||
rootPrim.LocalID, rootBody.ptr.ToString("X"),
|
rootPrim.LocalID, rootBody.ptr.ToString("X"),
|
||||||
childPrim.LocalID, childBody.ptr.ToString("X"),
|
childPrim.LocalID, childBody.ptr.ToString("X"),
|
||||||
rootPrim.Position, childPrim.Position, midPoint);
|
rootPrim.Position, childPrim.Position, midPoint);
|
||||||
|
|
||||||
|
// create a constraint that allows no freedom of movement between the two objects
|
||||||
|
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||||
|
|
||||||
// There is great subtlty in these paramters. Notice the check for a ptr of zero.
|
// There is great subtlty in these paramters. Notice the check for a ptr of zero.
|
||||||
// We pass the BulletBody structure into the taint in order to capture the pointer
|
// We pass the BulletBody structure into the taint in order to capture the pointer
|
||||||
// of the body at the time of constraint creation. This doesn't work for the very first
|
// of the body at the time of constraint creation. This doesn't work for the very first
|
||||||
|
@ -416,6 +467,7 @@ public class BSLinkset
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
/* NOTE: below is an attempt to build constraint with full frame computation, etc.
|
/* NOTE: below is an attempt to build constraint with full frame computation, etc.
|
||||||
* Using the midpoint is easier since it lets the Bullet code manipulate the transforms
|
* Using the midpoint is easier since it lets the Bullet code manipulate the transforms
|
||||||
* of the objects.
|
* of the objects.
|
||||||
|
|
|
@ -1111,13 +1111,21 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Undo me from any possible linkset so, if body is rebuilt, the link will get restored.
|
// Undo me from any possible linkset so, if body is rebuilt, the link will get restored.
|
||||||
// NOTE that the new linkset is not set. This saves the handle to the linkset
|
// NOTE that the new linkset is not set. This saves the handle to the linkset
|
||||||
// so we can add ourselves back when shape mangling is complete.
|
// so we can add ourselves back when shape mangling is complete.
|
||||||
Linkset.RemoveMeFromLinkset(this);
|
bool needToRestoreLinkset = false;
|
||||||
|
|
||||||
// Create the correct physical representation for this type of object.
|
// Create the correct physical representation for this type of object.
|
||||||
// Updates BSBody and BSShape with the new information.
|
// Updates BSBody and BSShape with the new information.
|
||||||
PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs);
|
PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs,
|
||||||
|
null, delegate(BulletBody dBody)
|
||||||
|
{
|
||||||
|
// Called if the current prim body is about to be destroyed.
|
||||||
|
// The problem is the constraints for Linksets which need to be updated for the new body.
|
||||||
|
Linkset.RemoveBodyDependencies(this);
|
||||||
|
needToRestoreLinkset = true;
|
||||||
|
});
|
||||||
|
|
||||||
Linkset = Linkset.AddMeToLinkset(this);
|
if (needToRestoreLinkset)
|
||||||
|
Linkset.RestoreBodyDependencies(this);
|
||||||
|
|
||||||
// Make sure the properties are set on the new object
|
// Make sure the properties are set on the new object
|
||||||
UpdatePhysicalParameters();
|
UpdatePhysicalParameters();
|
||||||
|
|
|
@ -81,12 +81,21 @@ public class BSShapeCollection : IDisposable
|
||||||
// TODO!!!!!!!!!
|
// TODO!!!!!!!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callbacks called just before either the body or shape is destroyed.
|
||||||
|
// Mostly used for changing bodies out from under Linksets.
|
||||||
|
// Useful for other cases where parameters need saving.
|
||||||
|
// Passing 'null' says no callback.
|
||||||
|
public delegate void ShapeDestructionCallback(BulletShape shape);
|
||||||
|
public delegate void BodyDestructionCallback(BulletBody body);
|
||||||
|
|
||||||
// Called to update/change the body and shape for an object.
|
// Called to update/change the body and shape for an object.
|
||||||
// First checks the shape and updates that if necessary then makes
|
// First checks the shape and updates that if necessary then makes
|
||||||
// sure the body is of the right type.
|
// sure the body is of the right type.
|
||||||
// Return 'true' if either the body or the shape changed.
|
// Return 'true' if either the body or the shape changed.
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs)
|
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPrim prim,
|
||||||
|
ShapeData shapeData, PrimitiveBaseShape pbs,
|
||||||
|
ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
@ -95,11 +104,11 @@ public class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
// Do we have the correct geometry for this type of object?
|
// Do we have the correct geometry for this type of object?
|
||||||
// Updates prim.BSShape with information/pointers to requested shape
|
// Updates prim.BSShape with information/pointers to requested shape
|
||||||
bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs);
|
bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback);
|
||||||
// If we had to select a new shape geometry for the object,
|
// If we had to select a new shape geometry for the object,
|
||||||
// rebuild the body around it.
|
// rebuild the body around it.
|
||||||
// Updates prim.BSBody with information/pointers to requested body
|
// Updates prim.BSBody with information/pointers to requested body
|
||||||
bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData);
|
bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData, bodyCallback);
|
||||||
ret = newGeom || newBody;
|
ret = newGeom || newBody;
|
||||||
}
|
}
|
||||||
DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}",
|
DetailLog("{0},BSShapeCollection.GetBodyAndShape,force={1},ret={2},body={3},shape={4}",
|
||||||
|
@ -135,7 +144,7 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Release the usage of a body.
|
// Release the usage of a body.
|
||||||
// Called when releasing use of a BSBody. BSShape is handled separately.
|
// Called when releasing use of a BSBody. BSShape is handled separately.
|
||||||
public void DereferenceBody(BulletBody shape, bool inTaintTime)
|
public void DereferenceBody(BulletBody shape, bool inTaintTime, BodyDestructionCallback bodyCallback )
|
||||||
{
|
{
|
||||||
if (shape.ptr == IntPtr.Zero)
|
if (shape.ptr == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
|
@ -244,7 +253,7 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Release the usage of a shape.
|
// Release the usage of a shape.
|
||||||
// The collisionObject is released since it is a copy of the real collision shape.
|
// The collisionObject is released since it is a copy of the real collision shape.
|
||||||
private void DereferenceShape(BulletShape shape, bool atTaintTime)
|
private void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
if (shape.ptr == IntPtr.Zero)
|
if (shape.ptr == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
|
@ -254,10 +263,10 @@ public class BSShapeCollection : IDisposable
|
||||||
switch (shape.type)
|
switch (shape.type)
|
||||||
{
|
{
|
||||||
case ShapeData.PhysicsShapeType.SHAPE_HULL:
|
case ShapeData.PhysicsShapeType.SHAPE_HULL:
|
||||||
DereferenceHull(shape);
|
DereferenceHull(shape, shapeCallback);
|
||||||
break;
|
break;
|
||||||
case ShapeData.PhysicsShapeType.SHAPE_MESH:
|
case ShapeData.PhysicsShapeType.SHAPE_MESH:
|
||||||
DereferenceMesh(shape);
|
DereferenceMesh(shape, shapeCallback);
|
||||||
break;
|
break;
|
||||||
case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN:
|
case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
|
@ -267,6 +276,7 @@ public class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
|
DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
|
||||||
BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime);
|
BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime);
|
||||||
|
if (shapeCallback != null) shapeCallback(shape);
|
||||||
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
|
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -287,13 +297,14 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Count down the reference count for a mesh shape
|
// Count down the reference count for a mesh shape
|
||||||
// Called at taint-time.
|
// Called at taint-time.
|
||||||
private void DereferenceMesh(BulletShape shape)
|
private void DereferenceMesh(BulletShape shape, ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
MeshDesc meshDesc;
|
MeshDesc meshDesc;
|
||||||
if (Meshes.TryGetValue(shape.shapeKey, out meshDesc))
|
if (Meshes.TryGetValue(shape.shapeKey, out meshDesc))
|
||||||
{
|
{
|
||||||
meshDesc.referenceCount--;
|
meshDesc.referenceCount--;
|
||||||
// TODO: release the Bullet storage
|
// TODO: release the Bullet storage
|
||||||
|
if (shapeCallback != null) shapeCallback(shape);
|
||||||
meshDesc.lastReferenced = System.DateTime.Now;
|
meshDesc.lastReferenced = System.DateTime.Now;
|
||||||
Meshes[shape.shapeKey] = meshDesc;
|
Meshes[shape.shapeKey] = meshDesc;
|
||||||
DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}",
|
DetailLog("{0},BSShapeCollection.DereferenceMesh,key={1},refCnt={2}",
|
||||||
|
@ -304,13 +315,14 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Count down the reference count for a hull shape
|
// Count down the reference count for a hull shape
|
||||||
// Called at taint-time.
|
// Called at taint-time.
|
||||||
private void DereferenceHull(BulletShape shape)
|
private void DereferenceHull(BulletShape shape, ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
HullDesc hullDesc;
|
HullDesc hullDesc;
|
||||||
if (Hulls.TryGetValue(shape.shapeKey, out hullDesc))
|
if (Hulls.TryGetValue(shape.shapeKey, out hullDesc))
|
||||||
{
|
{
|
||||||
hullDesc.referenceCount--;
|
hullDesc.referenceCount--;
|
||||||
// TODO: release the Bullet storage (aging old entries?)
|
// TODO: release the Bullet storage (aging old entries?)
|
||||||
|
if (shapeCallback != null) shapeCallback(shape);
|
||||||
hullDesc.lastReferenced = System.DateTime.Now;
|
hullDesc.lastReferenced = System.DateTime.Now;
|
||||||
Hulls[shape.shapeKey] = hullDesc;
|
Hulls[shape.shapeKey] = hullDesc;
|
||||||
DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}",
|
DetailLog("{0},BSShapeCollection.DereferenceHull,key={1},refCnt={2}",
|
||||||
|
@ -324,7 +336,8 @@ public class BSShapeCollection : IDisposable
|
||||||
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used.
|
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used.
|
||||||
// Returns 'true' if the geometry was rebuilt.
|
// Returns 'true' if the geometry was rebuilt.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
private bool CreateGeom(bool forceRebuild, BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs)
|
private bool CreateGeom(bool forceRebuild, BSPrim prim, ShapeData shapeData,
|
||||||
|
PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
bool haveShape = false;
|
bool haveShape = false;
|
||||||
|
@ -349,8 +362,8 @@ public class BSShapeCollection : IDisposable
|
||||||
|| prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
|
|| prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ret = GetReferenceToNativeShape(prim, shapeData,
|
ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
|
||||||
ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE);
|
ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
|
||||||
prim.LocalID, forceRebuild, prim.BSShape);
|
prim.LocalID, forceRebuild, prim.BSShape);
|
||||||
}
|
}
|
||||||
|
@ -363,8 +376,8 @@ public class BSShapeCollection : IDisposable
|
||||||
|| prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
|
|| prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ret = GetReferenceToNativeShape(
|
ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX,
|
||||||
prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX);
|
ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
|
||||||
prim.LocalID, forceRebuild, prim.BSShape);
|
prim.LocalID, forceRebuild, prim.BSShape);
|
||||||
}
|
}
|
||||||
|
@ -378,13 +391,13 @@ public class BSShapeCollection : IDisposable
|
||||||
if (prim.IsPhysical)
|
if (prim.IsPhysical)
|
||||||
{
|
{
|
||||||
// Update prim.BSShape to reference a hull of this shape.
|
// Update prim.BSShape to reference a hull of this shape.
|
||||||
ret = GetReferenceToHull(prim, shapeData, pbs);
|
ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
||||||
shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
|
shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = GetReferenceToMesh(prim, shapeData, pbs);
|
ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
||||||
shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
|
shapeData.ID, prim.BSShape, prim.BSShape.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
|
@ -394,7 +407,8 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Creates a native shape and assignes it to prim.BSShape
|
// Creates a native shape and assignes it to prim.BSShape
|
||||||
private bool GetReferenceToNativeShape( BSPrim prim, ShapeData shapeData,
|
private bool GetReferenceToNativeShape( BSPrim prim, ShapeData shapeData,
|
||||||
ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey)
|
ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
|
||||||
|
ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
BulletShape newShape;
|
BulletShape newShape;
|
||||||
|
|
||||||
|
@ -404,7 +418,7 @@ public class BSShapeCollection : IDisposable
|
||||||
shapeData.Scale = shapeData.Size;
|
shapeData.Scale = shapeData.Size;
|
||||||
|
|
||||||
// release any previous shape
|
// release any previous shape
|
||||||
DereferenceShape(prim.BSShape, true);
|
DereferenceShape(prim.BSShape, true, shapeCallback);
|
||||||
|
|
||||||
// Native shapes are always built independently.
|
// Native shapes are always built independently.
|
||||||
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType);
|
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType);
|
||||||
|
@ -422,7 +436,8 @@ public class BSShapeCollection : IDisposable
|
||||||
// Dereferences previous shape in BSShape and adds a reference for this new shape.
|
// Dereferences previous shape in BSShape and adds a reference for this new shape.
|
||||||
// Returns 'true' of a mesh was actually built. Otherwise .
|
// Returns 'true' of a mesh was actually built. Otherwise .
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
private bool GetReferenceToMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs)
|
private bool GetReferenceToMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs,
|
||||||
|
ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
BulletShape newShape = new BulletShape(IntPtr.Zero);
|
BulletShape newShape = new BulletShape(IntPtr.Zero);
|
||||||
|
|
||||||
|
@ -436,7 +451,7 @@ public class BSShapeCollection : IDisposable
|
||||||
prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
|
prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
|
||||||
|
|
||||||
// Since we're recreating new, get rid of the reference to the previous shape
|
// Since we're recreating new, get rid of the reference to the previous shape
|
||||||
DereferenceShape(prim.BSShape, true);
|
DereferenceShape(prim.BSShape, true, shapeCallback);
|
||||||
|
|
||||||
newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod);
|
newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod);
|
||||||
|
|
||||||
|
@ -490,7 +505,8 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// See that hull shape exists in the physical world and update prim.BSShape.
|
// See that hull shape exists in the physical world and update prim.BSShape.
|
||||||
// We could be creating the hull because scale changed or whatever.
|
// We could be creating the hull because scale changed or whatever.
|
||||||
private bool GetReferenceToHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs)
|
private bool GetReferenceToHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs,
|
||||||
|
ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
BulletShape newShape;
|
BulletShape newShape;
|
||||||
|
|
||||||
|
@ -505,7 +521,7 @@ public class BSShapeCollection : IDisposable
|
||||||
prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
|
prim.LocalID, prim.BSShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
|
||||||
|
|
||||||
// Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull.
|
// Remove usage of the previous shape. Also removes reference to underlying mesh if it is a hull.
|
||||||
DereferenceShape(prim.BSShape, true);
|
DereferenceShape(prim.BSShape, true, shapeCallback);
|
||||||
|
|
||||||
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
|
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
|
||||||
|
|
||||||
|
@ -656,7 +672,8 @@ public class BSShapeCollection : IDisposable
|
||||||
// Updates prim.BSBody with the information about the new body if one is created.
|
// Updates prim.BSBody with the information about the new body if one is created.
|
||||||
// Returns 'true' if an object was actually created.
|
// Returns 'true' if an object was actually created.
|
||||||
// Called at taint-time.
|
// Called at taint-time.
|
||||||
private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData)
|
private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape,
|
||||||
|
ShapeData shapeData, BodyDestructionCallback bodyCallback)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
@ -679,7 +696,7 @@ public class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
if (mustRebuild || forceRebuild)
|
if (mustRebuild || forceRebuild)
|
||||||
{
|
{
|
||||||
DereferenceBody(prim.BSBody, true);
|
DereferenceBody(prim.BSBody, true, bodyCallback);
|
||||||
|
|
||||||
BulletBody aBody;
|
BulletBody aBody;
|
||||||
IntPtr bodyPtr = IntPtr.Zero;
|
IntPtr bodyPtr = IntPtr.Zero;
|
||||||
|
|
|
@ -42,12 +42,12 @@ public struct BulletSim
|
||||||
{
|
{
|
||||||
ptr = xx;
|
ptr = xx;
|
||||||
worldID = worldId;
|
worldID = worldId;
|
||||||
scene = bss;
|
physicsScene = bss;
|
||||||
}
|
}
|
||||||
public IntPtr ptr;
|
public IntPtr ptr;
|
||||||
public uint worldID;
|
public uint worldID;
|
||||||
// The scene is only in here so very low level routines have a handle to print debug/error messages
|
// The scene is only in here so very low level routines have a handle to print debug/error messages
|
||||||
public BSScene scene;
|
public BSScene physicsScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An allocated Bullet btRigidBody
|
// An allocated Bullet btRigidBody
|
||||||
|
@ -120,14 +120,27 @@ public struct BulletShape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constraint type values as defined by Bullet
|
||||||
|
public enum ConstraintType : int
|
||||||
|
{
|
||||||
|
POINT2POINT_CONSTRAINT_TYPE = 3,
|
||||||
|
HINGE_CONSTRAINT_TYPE,
|
||||||
|
CONETWIST_CONSTRAINT_TYPE,
|
||||||
|
D6_CONSTRAINT_TYPE,
|
||||||
|
SLIDER_CONSTRAINT_TYPE,
|
||||||
|
CONTACT_CONSTRAINT_TYPE,
|
||||||
|
D6_SPRING_CONSTRAINT_TYPE,
|
||||||
|
MAX_CONSTRAINT_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
// An allocated Bullet btConstraint
|
// An allocated Bullet btConstraint
|
||||||
public struct BulletConstraint
|
public struct BulletConstraint
|
||||||
{
|
{
|
||||||
public BulletConstraint(IntPtr xx)
|
public BulletConstraint(IntPtr xx)
|
||||||
{
|
{
|
||||||
Ptr = xx;
|
ptr = xx;
|
||||||
}
|
}
|
||||||
public IntPtr Ptr;
|
public IntPtr ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An allocated HeightMapThing which holds various heightmap info.
|
// An allocated HeightMapThing which holds various heightmap info.
|
||||||
|
|
Loading…
Reference in New Issue