* Merges BulletSim Updates to BulletSimN(BulletSNPlugin)

0.7.5-pf-bulletsim
teravus 2012-12-18 15:00:10 -05:00
parent 225b564573
commit 29cdf0f3dd
19 changed files with 116 additions and 79 deletions

View File

@ -174,7 +174,7 @@ public sealed class BSCharacter : BSPhysObject
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
} }
UpdatePhysicalMassProperties(RawMass); UpdatePhysicalMassProperties(RawMass, false);
// Make so capsule does not fall over // Make so capsule does not fall over
BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero);
@ -224,7 +224,7 @@ public sealed class BSCharacter : BSPhysObject
if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape)
{ {
BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale);
UpdatePhysicalMassProperties(RawMass); UpdatePhysicalMassProperties(RawMass, true);
// Make sure this change appears as a property update event // Make sure this change appears as a property update event
BulletSimAPI.PushUpdate2(PhysBody.ptr); BulletSimAPI.PushUpdate2(PhysBody.ptr);
} }
@ -260,7 +260,6 @@ public sealed class BSCharacter : BSPhysObject
public override void ZeroMotion(bool inTaintTime) public override void ZeroMotion(bool inTaintTime)
{ {
_velocity = OMV.Vector3.Zero; _velocity = OMV.Vector3.Zero;
_velocityMotor.Zero();
_acceleration = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
@ -390,7 +389,7 @@ public sealed class BSCharacter : BSPhysObject
public override float RawMass { public override float RawMass {
get {return _mass; } get {return _mass; }
} }
public override void UpdatePhysicalMassProperties(float physMass) public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
{ {
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia);
@ -787,6 +786,7 @@ public sealed class BSCharacter : BSPhysObject
// the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer.
if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero)
{ {
ZeroMotion(true);
stepVelocity = OMV.Vector3.Zero; stepVelocity = OMV.Vector3.Zero;
_velocityMotor.Enabled = false; _velocityMotor.Enabled = false;
DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor);

View File

@ -36,7 +36,7 @@ public abstract class BSConstraint : IDisposable
{ {
private static string LogHeader = "[BULLETSIM CONSTRAINT]"; private static string LogHeader = "[BULLETSIM CONSTRAINT]";
protected BulletSim m_world; protected BulletWorld m_world;
protected BulletBody m_body1; protected BulletBody m_body1;
protected BulletBody m_body2; protected BulletBody m_body2;
protected BulletConstraint m_constraint; protected BulletConstraint m_constraint;

View File

@ -39,7 +39,7 @@ public sealed class BSConstraint6Dof : BSConstraint
public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } }
// Create a btGeneric6DofConstraint // Create a btGeneric6DofConstraint
public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 frame1, Quaternion frame1rot, Vector3 frame1, Quaternion frame1rot,
Vector3 frame2, Quaternion frame2rot, Vector3 frame2, Quaternion frame2rot,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
@ -58,7 +58,7 @@ public sealed class BSConstraint6Dof : BSConstraint
obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString());
} }
public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 joinPoint, Vector3 joinPoint,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
{ {

View File

@ -41,9 +41,9 @@ public sealed class BSConstraintCollection : IDisposable
delegate bool ConstraintAction(BSConstraint constrain); delegate bool ConstraintAction(BSConstraint constrain);
private List<BSConstraint> m_constraints; private List<BSConstraint> m_constraints;
private BulletSim m_world; private BulletWorld m_world;
public BSConstraintCollection(BulletSim world) public BSConstraintCollection(BulletWorld world)
{ {
m_world = world; m_world = world;
m_constraints = new List<BSConstraint>(); m_constraints = new List<BSConstraint>();

View File

@ -36,7 +36,7 @@ public sealed class BSConstraintHinge : BSConstraint
{ {
public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } }
public BSConstraintHinge(BulletSim world, BulletBody obj1, BulletBody obj2, public BSConstraintHinge(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 pivotInA, Vector3 pivotInB, Vector3 pivotInA, Vector3 pivotInB,
Vector3 axisInA, Vector3 axisInB, Vector3 axisInA, Vector3 axisInB,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)

View File

@ -573,6 +573,9 @@ namespace OpenSim.Region.Physics.BulletSNPlugin
BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia);
BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr);
Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy);
BulletSimAPI.SetGravity2(Prim.PhysBody.ptr, grav);
VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}",
Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping);
} }

View File

@ -97,14 +97,7 @@ public abstract class BSLinkset
} }
// We keep the prim's mass in the linkset structure since it could be dependent on other prims // We keep the prim's mass in the linkset structure since it could be dependent on other prims
protected float m_mass; public float LinksetMass { get; protected set; }
public float LinksetMass
{
get
{
return m_mass;
}
}
public virtual bool LinksetIsColliding { get { return false; } } public virtual bool LinksetIsColliding { get { return false; } }
@ -128,7 +121,7 @@ public abstract class BSLinkset
PhysicsScene = scene; PhysicsScene = scene;
LinksetRoot = parent; LinksetRoot = parent;
m_children = new HashSet<BSPhysObject>(); m_children = new HashSet<BSPhysObject>();
m_mass = parent.RawMass; LinksetMass = parent.RawMass;
Rebuilding = false; Rebuilding = false;
} }
@ -143,7 +136,7 @@ public abstract class BSLinkset
// Don't add the root to its own linkset // Don't add the root to its own linkset
if (!IsRoot(child)) if (!IsRoot(child))
AddChildToLinkset(child); AddChildToLinkset(child);
m_mass = ComputeLinksetMass(); LinksetMass = ComputeLinksetMass();
} }
return this; return this;
} }
@ -162,7 +155,7 @@ public abstract class BSLinkset
return this; return this;
} }
RemoveChildFromLinkset(child); RemoveChildFromLinkset(child);
m_mass = ComputeLinksetMass(); LinksetMass = ComputeLinksetMass();
} }
// The child is down to a linkset of just itself // The child is down to a linkset of just itself
@ -230,7 +223,10 @@ public abstract class BSLinkset
// When physical properties are changed the linkset needs to recalculate // When physical properties are changed the linkset needs to recalculate
// its internal properties. // its internal properties.
// May be called at runtime or taint-time. // May be called at runtime or taint-time.
public abstract void Refresh(BSPhysObject requestor); public virtual void Refresh(BSPhysObject requestor)
{
LinksetMass = ComputeLinksetMass();
}
// Flag denoting the linkset is in the process of being rebuilt. // 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. // Used to know not the schedule a rebuild in the middle of a rebuild.

View File

@ -89,6 +89,8 @@ public sealed class BSLinksetCompound : BSLinkset
// its internal properties. // its internal properties.
public override void Refresh(BSPhysObject requestor) public override void Refresh(BSPhysObject requestor)
{ {
base.Refresh(requestor);
// Something changed so do the rebuilding thing // Something changed so do the rebuilding thing
// ScheduleRebuild(); // ScheduleRebuild();
} }
@ -96,13 +98,13 @@ public sealed class BSLinksetCompound : BSLinkset
// Schedule a refresh to happen after all the other taint processing. // Schedule a refresh to happen after all the other taint processing.
private void ScheduleRebuild(BSPhysObject requestor) private void ScheduleRebuild(BSPhysObject requestor)
{ {
DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}",
requestor.LocalID, Rebuilding); requestor.LocalID, Rebuilding);
// When rebuilding, it is possible to set properties that would normally require a rebuild. // When rebuilding, it is possible to set properties that would normally require a rebuild.
// If already rebuilding, don't request another rebuild. // If already rebuilding, don't request another rebuild.
if (!Rebuilding) if (!Rebuilding)
{ {
PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
{ {
if (HasAnyChildren) if (HasAnyChildren)
RecomputeLinksetCompound(); RecomputeLinksetCompound();
@ -123,7 +125,6 @@ public sealed class BSLinksetCompound : BSLinkset
if (IsRoot(child)) if (IsRoot(child))
{ {
// The root is going dynamic. Make sure mass is properly set. // The root is going dynamic. Make sure mass is properly set.
m_mass = ComputeLinksetMass();
ScheduleRebuild(LinksetRoot); ScheduleRebuild(LinksetRoot);
} }
else else
@ -377,8 +378,8 @@ public sealed class BSLinksetCompound : BSLinkset
}); });
// With all of the linkset packed into the root prim, it has the mass of everyone. // With all of the linkset packed into the root prim, it has the mass of everyone.
float linksetMass = LinksetMass; LinksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass); LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
} }
finally finally
{ {

View File

@ -46,6 +46,8 @@ public sealed class BSLinksetConstraints : BSLinkset
// refresh will happen once after all the other taints are applied. // refresh will happen once after all the other taints are applied.
public override void Refresh(BSPhysObject requestor) public override void Refresh(BSPhysObject requestor)
{ {
base.Refresh(requestor);
// Queue to happen after all the other taint processing // Queue to happen after all the other taint processing
PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
{ {
@ -279,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset
private void RecomputeLinksetConstraints() private void RecomputeLinksetConstraints()
{ {
float linksetMass = LinksetMass; float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass); LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true);
// DEBUG: see of inter-linkset collisions are causing problems // DEBUG: see of inter-linkset collisions are causing problems
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
@ -292,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// A child in the linkset physically shows the mass of the whole linkset. // A child in the linkset physically shows the mass of the whole linkset.
// This allows Bullet to apply enough force on the child to move the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset.
// (Also do the mass stuff before recomputing the constraint so mass is not zero.) // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
child.UpdatePhysicalMassProperties(linksetMass); child.UpdatePhysicalMassProperties(linksetMass, true);
BSConstraint constrain; BSConstraint constrain;
if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))

View File

@ -119,26 +119,26 @@ public static class BSMaterials
Attributes[(int)MaterialAttributes.Material.Light] = Attributes[(int)MaterialAttributes.Material.Light] =
new MaterialAttributes("light",dDensity, dFriction, dRestitution); new MaterialAttributes("light",dDensity, dFriction, dRestitution);
Attributes[(int)MaterialAttributes.Material.Avatar] = Attributes[(int)MaterialAttributes.Material.Avatar] =
new MaterialAttributes("avatar",60f, 0.2f, 0f); new MaterialAttributes("avatar",3.5f, 0.2f, 0f);
Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f);
Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); new MaterialAttributes("metalPhysical",dDensity, 0.3f, 0.4f);
Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); new MaterialAttributes("glassPhysical",dDensity, 0.2f, 0.7f);
Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); new MaterialAttributes("woodPhysical",dDensity, 0.6f, 0.5f);
Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); new MaterialAttributes("fleshPhysical",dDensity, 0.9f, 0.3f);
Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); new MaterialAttributes("plasticPhysical",dDensity, 0.4f, 0.7f);
Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); new MaterialAttributes("rubberPhysical",dDensity, 0.9f, 0.9f);
Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution);
Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] =
new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); new MaterialAttributes("avatarPhysical",3.5f, 0.2f, 0f);
} }
// Under the [BulletSim] section, one can change the individual material // Under the [BulletSim] section, one can change the individual material

View File

@ -351,7 +351,7 @@ public static class BSParam
(s) => { return AvatarStandingFriction; }, (s) => { return AvatarStandingFriction; },
(s,p,l,v) => { AvatarStandingFriction = v; } ), (s,p,l,v) => { AvatarStandingFriction = v; } ),
new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
60f, 3.5f,
(s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
(s) => { return AvatarDensity; }, (s) => { return AvatarDensity; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ),

View File

@ -96,7 +96,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 RawMass { get; } public abstract float RawMass { get; }
// Set the raw mass but also update physical mass properties (inertia, ...) // Set the raw mass but also update physical mass properties (inertia, ...)
public abstract void UpdatePhysicalMassProperties(float mass); // 'inWorld' true if the object has already been added to the dynamic world.
public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
// The last value calculated for the prim's inertia // The last value calculated for the prim's inertia
public OMV.Vector3 Inertia { get; set; } public OMV.Vector3 Inertia { get; set; }

View File

@ -115,6 +115,8 @@ public sealed class BSPrim : BSPhysObject
PhysBody = new BulletBody(LocalID); PhysBody = new BulletBody(LocalID);
PhysShape = new BulletShape(); PhysShape = new BulletShape();
Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID); DetailLog("{0},BSPrim.constructor,call", LocalID);
// do the actual object creation at taint time // do the actual object creation at taint time
PhysicsScene.TaintedObject("BSPrim.create", delegate() PhysicsScene.TaintedObject("BSPrim.create", delegate()
@ -384,13 +386,13 @@ public sealed class BSPrim : BSPhysObject
} }
// Return the effective mass of the object. // Return the effective mass of the object.
// If there are multiple items in the linkset, add them together for the root // The definition of this call is to return the mass of the prim.
// If the simulator cares about the mass of the linkset, it will sum it itself.
public override float Mass public override float Mass
{ {
get get
{ {
return Linkset.LinksetMass; return _mass;
// return _mass;
} }
} }
@ -400,7 +402,9 @@ public sealed class BSPrim : BSPhysObject
} }
// Set the physical mass to the passed mass. // Set the physical mass to the passed mass.
// Note that this does not change _mass! // Note that this does not change _mass!
public override void UpdatePhysicalMassProperties(float physMass) public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
{
if (PhysBody.HasPhysicalBody)
{ {
if (IsStatic) if (IsStatic)
{ {
@ -410,12 +414,33 @@ public sealed class BSPrim : BSPhysObject
} }
else else
{ {
if (inWorld)
{
// Changing interesting properties doesn't change proxy and collision cache
// information. The Bullet solution is to re-add the object to the world
// after parameters are changed.
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
}
Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
// center of mass is at the zero of the object // center of mass is at the zero of the object
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation);
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},inWorld={3}", LocalID, physMass, Inertia, inWorld);
if (inWorld)
{
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr,_position,_orientation);
}
// Must set gravity after it has been added to the world because, for unknown reasons,
// adding the object resets the object's gravity to world gravity
OMV.Vector3 grav = PhysicsScene.DefaultGravity * (1f - Buoyancy);
BulletSimAPI.SetGravity2(PhysBody.ptr, grav);
}
} }
} }
@ -714,7 +739,7 @@ public sealed class BSPrim : BSPhysObject
Linkset.Refresh(this); Linkset.Refresh(this);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}",
LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape);
} }
// "Making dynamic" means changing to and from static. // "Making dynamic" means changing to and from static.
@ -737,7 +762,7 @@ public sealed class BSPrim : BSPhysObject
BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
// Mass is zero which disables a bunch of physics stuff in Bullet // Mass is zero which disables a bunch of physics stuff in Bullet
UpdatePhysicalMassProperties(0f); UpdatePhysicalMassProperties(0f, false);
// Set collision detection parameters // Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f) if (BSParam.CcdMotionThreshold > 0f)
{ {
@ -777,7 +802,7 @@ public sealed class BSPrim : BSPhysObject
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
// A dynamic object has mass // A dynamic object has mass
UpdatePhysicalMassProperties(RawMass); UpdatePhysicalMassProperties(RawMass, false);
// Set collision detection parameters // Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f) if (BSParam.CcdMotionThreshold > 0f)
@ -950,15 +975,11 @@ public sealed class BSPrim : BSPhysObject
set { set {
_buoyancy = value; _buoyancy = value;
// DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
// Buoyancy is faked by changing the gravity applied to the object // Force the recalculation of the various inertia,etc variables in the object
if (PhysBody.HasPhysicalBody) UpdatePhysicalMassProperties(_mass, true);
{
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
}
// Used for MoveTo // Used for MoveTo
public override OMV.Vector3 PIDTarget { public override OMV.Vector3 PIDTarget {
@ -993,7 +1014,9 @@ public sealed class BSPrim : BSPhysObject
public override float APIDDamping { set { return; } } public override float APIDDamping { set { return; } }
public override void AddForce(OMV.Vector3 force, bool pushforce) { public override void AddForce(OMV.Vector3 force, bool pushforce) {
AddForce(force, pushforce, false); // Since this force is being applied in only one step, make this a force per second.
OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
AddForce(addForce, pushforce, false);
} }
// Applying a force just adds this to the total force on the object. // Applying a force just adds this to the total force on the object.
// This added force will only last the next simulation tick. // This added force will only last the next simulation tick.
@ -1001,8 +1024,16 @@ public sealed class BSPrim : BSPhysObject
// for an object, doesn't matter if force is a pushforce or not // for an object, doesn't matter if force is a pushforce or not
if (force.IsFinite()) if (force.IsFinite())
{ {
float magnitude = force.Length();
if (magnitude > 20000f)
{
// Force has a limit
force = force / magnitude * 20000f;
}
OMV.Vector3 addForce = force; OMV.Vector3 addForce = force;
DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
{ {
// Bullet adds this central force to the total force for this tick // Bullet adds this central force to the total force for this tick

View File

@ -74,7 +74,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public IMesher mesher; public IMesher mesher;
public uint WorldID { get; private set; } public uint WorldID { get; private set; }
public BulletSim World { get; private set; } public BulletWorld World { get; private set; }
// All the constraints that have been allocated in this instance. // All the constraints that have been allocated in this instance.
public BSConstraintCollection Constraints { get; private set; } public BSConstraintCollection Constraints { get; private set; }
@ -244,7 +244,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
World = new BulletSim(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams, World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams,
m_maxCollisionsPerFrame, ref m_collisionArray, m_maxCollisionsPerFrame, ref m_collisionArray,
m_maxUpdatesPerFrame,ref m_updateArray, m_maxUpdatesPerFrame,ref m_updateArray,
m_DebugLogCallbackHandle)); m_DebugLogCallbackHandle));
@ -497,13 +497,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
InTaintTime = false; // Only used for debugging so locking is not necessary. InTaintTime = false; // Only used for debugging so locking is not necessary.
// The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
// Only enable this in a limited test world with few objects.
// BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
// step the physical world one interval // step the physical world one interval
m_simulationStep++; m_simulationStep++;
int numSubSteps = 0; int numSubSteps = 0;
try try
{ {
//if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
@ -833,7 +836,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
{ {
DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
Util.PrintCallStack(); // Prints the stack into the DEBUG log file. Util.PrintCallStack(DetailLog);
} }
return InTaintTime; return InTaintTime;
} }

View File

@ -98,7 +98,7 @@ public sealed class BSShapeCollection : IDisposable
// higher level dependencies on the shape or body. Mostly used for LinkSets to // higher level dependencies on the shape or body. Mostly used for LinkSets to
// remove the physical constraints before the body is destroyed. // remove the physical constraints before the body is destroyed.
// Called at taint-time!! // Called at taint-time!!
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim,
ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
{ {
PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape");
@ -126,7 +126,7 @@ public sealed class BSShapeCollection : IDisposable
return ret; return ret;
} }
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim) public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim)
{ {
return GetBodyAndShape(forceRebuild, sim, prim, null, null); return GetBodyAndShape(forceRebuild, sim, prim, null, null);
} }
@ -918,7 +918,7 @@ public sealed 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, BSPhysObject prim, BulletSim sim, BulletShape shape, private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape,
BodyDestructionCallback bodyCallback) BodyDestructionCallback bodyCallback)
{ {
bool ret = false; bool ret = false;

View File

@ -103,7 +103,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
Vector3 centerPos; Vector3 centerPos;
centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f);
centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f + 0.5f); centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f - 0.5f);
m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr,

View File

@ -140,7 +140,7 @@ public sealed class BSTerrainManager : IDisposable
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
Vector3.Zero, Quaternion.Identity)); Vector3.Zero, Quaternion.Identity));
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr, Vector3.Zero, Quaternion.Identity);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr);
// Ground plane does not move // Ground plane does not move
BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION);
@ -376,6 +376,7 @@ public sealed class BSTerrainManager : IDisposable
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}",
BSScene.DetailLogZero, pos, terrainBaseXYZ); BSScene.DetailLogZero, pos, terrainBaseXYZ);
} }
lastHeight = ret; lastHeight = ret;
return ret; return ret;
} }

View File

@ -58,7 +58,6 @@ public enum ConstraintType : int
MAX_CONSTRAINT_TYPE MAX_CONSTRAINT_TYPE
} }
// =============================================================================== // ===============================================================================
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct ConvexHull public struct ConvexHull

View File

@ -35,9 +35,9 @@ namespace OpenSim.Region.Physics.BulletSNPlugin
// These hold pointers to allocated objects in the unmanaged space. // These hold pointers to allocated objects in the unmanaged space.
// The physics engine controller class created at initialization // The physics engine controller class created at initialization
public struct BulletSim public struct BulletWorld
{ {
public BulletSim(uint worldId, BSScene bss, object xx) public BulletWorld(uint worldId, BSScene bss, object xx)
{ {
ptr = xx; ptr = xx;
worldID = worldId; worldID = worldId;