BulletSim: centralize mass/inertia computation with UpdatePhysicalMassProperties() function. Didn't add setMassRaw because assignment with side effect is dirty.

integration
Robert Adams 2012-10-29 11:30:47 -07:00
parent 7af28724ac
commit e20bad12cc
3 changed files with 38 additions and 18 deletions

View File

@ -155,8 +155,7 @@ public sealed class BSCharacter : BSPhysObject
BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); BulletSimAPI.SetCcdSweptSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
} }
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); UpdatePhysicalMassProperties(MassRaw);
BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
// Make so capsule does not fall over // Make so capsule does not fall over
BulletSimAPI.SetAngularFactorV2(BSBody.ptr, OMV.Vector3.Zero); BulletSimAPI.SetAngularFactorV2(BSBody.ptr, OMV.Vector3.Zero);
@ -201,8 +200,7 @@ public sealed class BSCharacter : BSPhysObject
PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
{ {
BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale);
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); UpdatePhysicalMassProperties(MassRaw);
BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
}); });
} }
@ -329,7 +327,14 @@ public sealed class BSCharacter : BSPhysObject
public override float Mass { get { return _mass; } } public override float Mass { get { return _mass; } }
// used when we only want this prim's mass and not the linkset thing // used when we only want this prim's mass and not the linkset thing
public override float MassRaw { get {return _mass; } } public override float MassRaw {
get {return _mass; }
}
public override void UpdatePhysicalMassProperties(float physMass)
{
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass);
BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia);
}
public override OMV.Vector3 Force { public override OMV.Vector3 Force {
get { return _force; } get { return _force; }

View File

@ -64,6 +64,8 @@ public abstract class BSPhysObject : PhysicsActor
// Return the object mass without calculating it or having side effects // Return the object mass without calculating it or having side effects
public abstract float MassRaw { get; } public abstract float MassRaw { get; }
// Set the raw mass but also update physical mass properties (inertia, ...)
public abstract void UpdatePhysicalMassProperties(float mass);
// Reference to the physical body (btCollisionObject) of this object // Reference to the physical body (btCollisionObject) of this object
public BulletBody BSBody; public BulletBody BSBody;

View File

@ -356,13 +356,32 @@ public sealed class BSPrim : BSPhysObject
{ {
get get
{ {
// return Linkset.LinksetMass; return Linkset.LinksetMass;
return _mass; // return _mass;
} }
} }
// used when we only want this prim's mass and not the linkset thing // used when we only want this prim's mass and not the linkset thing
public override float MassRaw { get { return _mass; } } public override float MassRaw {
get { return _mass; }
}
// Set the physical mass to the passed mass.
// Note that this does not change _mass!
public override void UpdatePhysicalMassProperties(float physMass)
{
if (IsStatic)
{
BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero);
BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
}
else
{
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, physMass);
BulletSimAPI.SetMassProps2(BSBody.ptr, physMass, localInertia);
BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, localInertia);
}
}
// Is this used? // Is this used?
public override OMV.Vector3 CenterOfMass public override OMV.Vector3 CenterOfMass
@ -613,7 +632,7 @@ public sealed class BSPrim : BSPhysObject
// Recompute any linkset parameters. // Recompute any linkset parameters.
// When going from non-physical to physical, this re-enables the constraints that // When going from non-physical to physical, this re-enables the constraints that
// had been automatically disabled when the mass was set to zero. // had been automatically disabled when the mass was set to zero.
Linkset.Refresh(this, true); Linkset.Refresh(this);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}",
LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape);
@ -635,9 +654,7 @@ public sealed class BSPrim : BSPhysObject
// Center of mass is at the center of the object // Center of mass is at the center of the object
BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation); BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation);
// Mass is zero which disables a bunch of physics stuff in Bullet // Mass is zero which disables a bunch of physics stuff in Bullet
BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); UpdatePhysicalMassProperties(0f);
// There is no inertia in a static object
BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
// Set collision detection parameters // Set collision detection parameters
if (PhysicsScene.Params.ccdMotionThreshold > 0f) if (PhysicsScene.Params.ccdMotionThreshold > 0f)
{ {
@ -671,9 +688,7 @@ public sealed class BSPrim : BSPhysObject
BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation);
// A dynamic object has mass // A dynamic object has mass
OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, Mass); UpdatePhysicalMassProperties(MassRaw);
BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia);
BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr);
// Set collision detection parameters // Set collision detection parameters
if (PhysicsScene.Params.ccdMotionThreshold > 0f) if (PhysicsScene.Params.ccdMotionThreshold > 0f)
@ -1247,9 +1262,7 @@ public sealed class BSPrim : BSPhysObject
returnMass = _density * volume; returnMass = _density * volume;
/* /* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
* This change means each object keeps its own mass and the Mass property
* will return the sum if we're part of a linkset.
if (IsRootOfLinkset) if (IsRootOfLinkset)
{ {
foreach (BSPrim prim in _childrenPrims) foreach (BSPrim prim in _childrenPrims)