Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/ScenePresence.csavinationmerge
commit
3ab1bd0403
|
@ -2447,10 +2447,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_lastSize = Appearance.AvatarSize;
|
m_lastSize = Appearance.AvatarSize;
|
||||||
SendAvatarDataToAllAgents();
|
SendAvatarDataToAllAgents();
|
||||||
}
|
}
|
||||||
|
// Throw away duplicate or insignificant updates
|
||||||
|
else if (
|
||||||
|
// If the velocity has become zero, send it no matter what.
|
||||||
|
(Velocity != m_lastVelocity && Velocity == Vector3.Zero)
|
||||||
|
// otherwise, if things have changed reasonably, send the update
|
||||||
|
|| (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|
||||||
|
|| !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
|
||||||
|
|| !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
|
||||||
|
|
||||||
else if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
|
|
||||||
!Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
|
|
||||||
!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
|
|
||||||
{
|
{
|
||||||
SendTerseUpdateToAllClients();
|
SendTerseUpdateToAllClients();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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); } ),
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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,22 +402,45 @@ 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 (IsStatic)
|
if (PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
Inertia = OMV.Vector3.Zero;
|
if (IsStatic)
|
||||||
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
|
{
|
||||||
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
|
Inertia = OMV.Vector3.Zero;
|
||||||
}
|
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
|
||||||
else
|
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
|
||||||
{
|
}
|
||||||
Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
|
else
|
||||||
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia);
|
{
|
||||||
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
|
if (inWorld)
|
||||||
// center of mass is at the zero of the object
|
{
|
||||||
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation);
|
// Changing interesting properties doesn't change proxy and collision cache
|
||||||
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia);
|
// 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);
|
||||||
|
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia);
|
||||||
|
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
|
||||||
|
|
||||||
|
// center of mass is at the zero of the object
|
||||||
|
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation);
|
||||||
|
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,13 +975,9 @@ 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);
|
||||||
{
|
ActivateIfPhysical(false);
|
||||||
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
|
|
||||||
BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
|
|
||||||
ActivateIfPhysical(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -637,7 +637,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false);
|
meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false);
|
||||||
|
|
||||||
if (meshData != null)
|
if (meshData != null)
|
||||||
{
|
{
|
||||||
|
@ -709,7 +709,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
// Build a new hull in the physical world
|
// Build a new hull in the physical world
|
||||||
// Pass true for physicalness as this creates some sort of bounding box which we don't need
|
// Pass true for physicalness as this creates some sort of bounding box which we don't need
|
||||||
IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false);
|
IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false);
|
||||||
if (meshData != null)
|
if (meshData != 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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -585,18 +584,6 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
get { return _throttleUpdates; }
|
get { return _throttleUpdates; }
|
||||||
set { _throttleUpdates = value; }
|
set { _throttleUpdates = value; }
|
||||||
}
|
}
|
||||||
public override bool IsColliding {
|
|
||||||
get { return (CollidingStep == PhysicsScene.SimulationStep); }
|
|
||||||
set { _isColliding = value; }
|
|
||||||
}
|
|
||||||
public override bool CollidingGround {
|
|
||||||
get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
|
|
||||||
set { CollidingGround = value; }
|
|
||||||
}
|
|
||||||
public override bool CollidingObj {
|
|
||||||
get { return _collidingObj; }
|
|
||||||
set { _collidingObj = value; }
|
|
||||||
}
|
|
||||||
public override bool FloatOnWater {
|
public override bool FloatOnWater {
|
||||||
set {
|
set {
|
||||||
_floatOnWater = value;
|
_floatOnWater = value;
|
||||||
|
@ -684,22 +671,31 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
public override void AddForce(OMV.Vector3 force, bool pushforce) {
|
public override void AddForce(OMV.Vector3 force, bool pushforce) {
|
||||||
if (force.IsFinite())
|
if (force.IsFinite())
|
||||||
{
|
{
|
||||||
_force.X += force.X;
|
float magnitude = force.Length();
|
||||||
_force.Y += force.Y;
|
if (magnitude > BSParam.MaxAddForceMagnitude)
|
||||||
_force.Z += force.Z;
|
{
|
||||||
// m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
|
// Force has a limit
|
||||||
|
force = force / magnitude * BSParam.MaxAddForceMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep;
|
||||||
|
DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
|
// Bullet adds this central force to the total force for this tick
|
||||||
|
DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
|
{
|
||||||
|
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader);
|
m_log.WarnFormat("{0}: Got a NaN force applied to a character. LocalID={1}", LogHeader, LocalID);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
//m_lastUpdateSent = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||||
|
@ -761,22 +757,26 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
|
|
||||||
OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep);
|
OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep);
|
||||||
|
|
||||||
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
// Check for cases to turn off the motor.
|
||||||
if (!Flying && !IsColliding)
|
if (
|
||||||
|
// If the walking motor is all done, turn it off
|
||||||
|
(_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) )
|
||||||
{
|
{
|
||||||
stepVelocity.Z = entprop.Velocity.Z;
|
|
||||||
DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user has said stop and we've stopped applying velocity correction,
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
_velocityMotor.Enabled = false;
|
|
||||||
stepVelocity = OMV.Vector3.Zero;
|
|
||||||
ZeroMotion(true);
|
ZeroMotion(true);
|
||||||
|
stepVelocity = OMV.Vector3.Zero;
|
||||||
|
_velocityMotor.Enabled = false;
|
||||||
DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor);
|
DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the motor is not being turned off...
|
||||||
|
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
||||||
|
if (!Flying && !IsColliding)
|
||||||
|
{
|
||||||
|
stepVelocity.Z = entprop.Velocity.Z;
|
||||||
|
DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_velocity = stepVelocity;
|
_velocity = stepVelocity;
|
||||||
entprop.Velocity = _velocity;
|
entprop.Velocity = _velocity;
|
||||||
|
|
|
@ -573,6 +573,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -819,6 +822,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
|
|
||||||
|
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
||||||
|
BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr);
|
||||||
|
|
||||||
ForgetKnownVehicleProperties();
|
ForgetKnownVehicleProperties();
|
||||||
|
|
||||||
MoveLinear(pTimestep);
|
MoveLinear(pTimestep);
|
||||||
|
@ -833,6 +839,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// for the physics engine to note the changes so an UpdateProperties event will happen.
|
// for the physics engine to note the changes so an UpdateProperties event will happen.
|
||||||
PushKnownChanged();
|
PushKnownChanged();
|
||||||
|
|
||||||
|
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
||||||
|
BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||||
Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity);
|
Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclat simer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyrightD
|
* * Redistributions in binary form must reproduce the above copyrightD
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
@ -98,11 +98,12 @@ 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.ScheduleRebuild,,rebuilding={1}",
|
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2}",
|
||||||
requestor.LocalID, Rebuilding);
|
requestor.LocalID, Rebuilding, HasAnyChildren);
|
||||||
// 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 a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
|
||||||
|
if (!Rebuilding && HasAnyChildren)
|
||||||
{
|
{
|
||||||
PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
|
PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
|
||||||
{
|
{
|
||||||
|
@ -112,8 +113,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The object is going dynamic (physical). Do any setup necessary
|
// The object is going dynamic (physical). Do any setup necessary for a dynamic linkset.
|
||||||
// for a dynamic linkset.
|
|
||||||
// Only the state of the passed object can be modified. The rest of the linkset
|
// Only the state of the passed object can be modified. The rest of the linkset
|
||||||
// has not yet been fully constructed.
|
// has not yet been fully constructed.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
|
@ -124,7 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
||||||
if (IsRoot(child))
|
if (IsRoot(child))
|
||||||
{
|
{
|
||||||
// The root is going dynamic. Make sure mass is properly set.
|
// The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
|
||||||
ScheduleRebuild(LinksetRoot);
|
ScheduleRebuild(LinksetRoot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -378,7 +378,7 @@ 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.
|
||||||
LinksetMass = LinksetMass;
|
LinksetMass = ComputeLinksetMass();
|
||||||
LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
|
LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -241,8 +241,8 @@ public class BSVMotor : BSMotor
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>",
|
return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>",
|
||||||
UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale);
|
UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,18 @@ public static class BSParam
|
||||||
public static float PID_D { get; private set; } // derivative
|
public static float PID_D { get; private set; } // derivative
|
||||||
public static float PID_P { get; private set; } // proportional
|
public static float PID_P { get; private set; } // proportional
|
||||||
|
|
||||||
|
// Various constants that come from that other virtual world that shall not be named
|
||||||
|
public const float MinGravityZ = -1f;
|
||||||
|
public const float MaxGravityZ = 28f;
|
||||||
|
public const float MinFriction = 0f;
|
||||||
|
public const float MaxFriction = 255f;
|
||||||
|
public const float MinDensity = 0f;
|
||||||
|
public const float MaxDensity = 22587f;
|
||||||
|
public const float MinRestitution = 0f;
|
||||||
|
public const float MaxRestitution = 1f;
|
||||||
|
public const float MaxAddForceMagnitude = 20000f;
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
|
public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
|
||||||
public delegate float ParamGet(BSScene scene);
|
public delegate float ParamGet(BSScene scene);
|
||||||
public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
|
public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
|
||||||
|
@ -200,6 +212,11 @@ public static class BSParam
|
||||||
(s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
|
||||||
(s) => { return (float)s.m_fixedTimeStep; },
|
(s) => { return (float)s.m_fixedTimeStep; },
|
||||||
(s,p,l,v) => { s.m_fixedTimeStep = v; } ),
|
(s,p,l,v) => { s.m_fixedTimeStep = v; } ),
|
||||||
|
new ParameterDefn("NominalFrameRate", "The base frame rate we claim",
|
||||||
|
55f,
|
||||||
|
(s,cf,p,v) => { s.NominalFrameRate = cf.GetInt(p, (int)v); },
|
||||||
|
(s) => { return (float)s.NominalFrameRate; },
|
||||||
|
(s,p,l,v) => { s.NominalFrameRate = (int)v; } ),
|
||||||
new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
|
new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
|
||||||
2048f,
|
2048f,
|
||||||
(s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
|
(s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
|
||||||
|
|
|
@ -182,9 +182,40 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
protected long CollidingStep { get; set; }
|
protected long CollidingStep { get; set; }
|
||||||
// The simulation step that last had a collision with the ground
|
// The simulation step that last had a collision with the ground
|
||||||
protected long CollidingGroundStep { get; set; }
|
protected long CollidingGroundStep { get; set; }
|
||||||
|
// The simulation step that last collided with an object
|
||||||
|
protected long CollidingObjectStep { get; set; }
|
||||||
// The collision flags we think are set in Bullet
|
// The collision flags we think are set in Bullet
|
||||||
protected CollisionFlags CurrentCollisionFlags { get; set; }
|
protected CollisionFlags CurrentCollisionFlags { get; set; }
|
||||||
|
|
||||||
|
public override bool IsColliding {
|
||||||
|
get { return (CollidingStep == PhysicsScene.SimulationStep); }
|
||||||
|
set {
|
||||||
|
if (value)
|
||||||
|
CollidingStep = PhysicsScene.SimulationStep;
|
||||||
|
else
|
||||||
|
CollidingStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override bool CollidingGround {
|
||||||
|
get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
CollidingGroundStep = PhysicsScene.SimulationStep;
|
||||||
|
else
|
||||||
|
CollidingGroundStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override bool CollidingObj {
|
||||||
|
get { return (CollidingObjectStep == PhysicsScene.SimulationStep); }
|
||||||
|
set {
|
||||||
|
if (value)
|
||||||
|
CollidingObjectStep = PhysicsScene.SimulationStep;
|
||||||
|
else
|
||||||
|
CollidingObjectStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The collisions that have been collected this tick
|
// The collisions that have been collected this tick
|
||||||
protected CollisionEventUpdate CollisionCollection;
|
protected CollisionEventUpdate CollisionCollection;
|
||||||
|
|
||||||
|
@ -196,12 +227,16 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
// The following lines make IsColliding() and IsCollidingGround() work
|
// The following lines make IsColliding(), CollidingGround() and CollidingObj work
|
||||||
CollidingStep = PhysicsScene.SimulationStep;
|
CollidingStep = PhysicsScene.SimulationStep;
|
||||||
if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
|
if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
|
||||||
{
|
{
|
||||||
CollidingGroundStep = PhysicsScene.SimulationStep;
|
CollidingGroundStep = PhysicsScene.SimulationStep;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CollidingObjectStep = PhysicsScene.SimulationStep;
|
||||||
|
}
|
||||||
|
|
||||||
// prims in the same linkset cannot collide with each other
|
// prims in the same linkset cannot collide with each other
|
||||||
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
||||||
|
|
|
@ -94,7 +94,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_size = size;
|
_size = size;
|
||||||
Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
|
Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
|
||||||
_orientation = rotation;
|
_orientation = rotation;
|
||||||
_buoyancy = 1f;
|
_buoyancy = 0f;
|
||||||
_velocity = OMV.Vector3.Zero;
|
_velocity = OMV.Vector3.Zero;
|
||||||
_rotationalVelocity = OMV.Vector3.Zero;
|
_rotationalVelocity = OMV.Vector3.Zero;
|
||||||
BaseShape = pbs;
|
BaseShape = pbs;
|
||||||
|
@ -408,12 +408,15 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
if (IsStatic)
|
if (IsStatic)
|
||||||
{
|
{
|
||||||
|
BulletSimAPI.SetGravity2(PhysBody.ptr, PhysicsScene.DefaultGravity);
|
||||||
Inertia = OMV.Vector3.Zero;
|
Inertia = OMV.Vector3.Zero;
|
||||||
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
|
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
|
||||||
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
|
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
OMV.Vector3 grav = ComputeGravity();
|
||||||
|
|
||||||
if (inWorld)
|
if (inWorld)
|
||||||
{
|
{
|
||||||
// Changing interesting properties doesn't change proxy and collision cache
|
// Changing interesting properties doesn't change proxy and collision cache
|
||||||
|
@ -422,24 +425,41 @@ public sealed class BSPrim : BSPhysObject
|
||||||
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
|
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
|
// The computation of mass props requires gravity to be set on the object.
|
||||||
BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
|
BulletSimAPI.SetGravity2(PhysBody.ptr, grav);
|
||||||
|
|
||||||
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},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld);
|
||||||
|
|
||||||
if (inWorld)
|
if (inWorld)
|
||||||
{
|
{
|
||||||
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
|
AddObjectToPhysicalWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
BulletSimAPI.SetGravity2(PhysBody.ptr, grav);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return what gravity should be set to this very moment
|
||||||
|
private OMV.Vector3 ComputeGravity()
|
||||||
|
{
|
||||||
|
OMV.Vector3 ret = PhysicsScene.DefaultGravity;
|
||||||
|
|
||||||
|
if (!IsStatic)
|
||||||
|
ret *= (1f - Buoyancy);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Is this used?
|
// Is this used?
|
||||||
public override OMV.Vector3 CenterOfMass
|
public override OMV.Vector3 CenterOfMass
|
||||||
{
|
{
|
||||||
|
@ -665,7 +685,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_isPhysical = value;
|
_isPhysical = value;
|
||||||
PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
||||||
{
|
{
|
||||||
// DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
|
DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
|
||||||
SetObjectDynamic(true);
|
SetObjectDynamic(true);
|
||||||
// whether phys-to-static or static-to-phys, the object is not moving.
|
// whether phys-to-static or static-to-phys, the object is not moving.
|
||||||
ZeroMotion(true);
|
ZeroMotion(true);
|
||||||
|
@ -720,22 +740,19 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Make solid or not (do things bounce off or pass through this object).
|
// Make solid or not (do things bounce off or pass through this object).
|
||||||
MakeSolid(IsSolid);
|
MakeSolid(IsSolid);
|
||||||
|
|
||||||
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
|
AddObjectToPhysicalWorld();
|
||||||
|
|
||||||
// Rebuild its shape
|
// Rebuild its shape
|
||||||
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
|
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
|
||||||
|
|
||||||
// Collision filter can be set only when the object is in the world
|
|
||||||
PhysBody.ApplyCollisionMask();
|
|
||||||
|
|
||||||
// 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.
|
||||||
// For compound based linksets, this enables and disables interactions of the children.
|
// For compound based linksets, this enables and disables interactions of the children.
|
||||||
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},cType={6},body={7},shape={8}",
|
||||||
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape);
|
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Making dynamic" means changing to and from static.
|
// "Making dynamic" means changing to and from static.
|
||||||
|
@ -876,6 +893,28 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add me to the physical world.
|
||||||
|
// Object MUST NOT already be in the world.
|
||||||
|
// This routine exists because some assorted properties get mangled by adding to the world.
|
||||||
|
internal void AddObjectToPhysicalWorld()
|
||||||
|
{
|
||||||
|
if (PhysBody.HasPhysicalBody)
|
||||||
|
{
|
||||||
|
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
|
||||||
|
|
||||||
|
// TODO: Fix this. Total kludge because adding object to world resets its gravity to default.
|
||||||
|
// Replace this when the new AddObjectToWorld function is complete.
|
||||||
|
BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity());
|
||||||
|
|
||||||
|
// Collision filter can be set only when the object is in the world
|
||||||
|
if (!PhysBody.ApplyCollisionMask())
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID);
|
||||||
|
DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// prims don't fly
|
// prims don't fly
|
||||||
public override bool Flying {
|
public override bool Flying {
|
||||||
get { return _flying; }
|
get { return _flying; }
|
||||||
|
@ -891,18 +930,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
get { return _throttleUpdates; }
|
get { return _throttleUpdates; }
|
||||||
set { _throttleUpdates = value; }
|
set { _throttleUpdates = value; }
|
||||||
}
|
}
|
||||||
public override bool IsColliding {
|
|
||||||
get { return (CollidingStep == PhysicsScene.SimulationStep); }
|
|
||||||
set { _isColliding = value; }
|
|
||||||
}
|
|
||||||
public override bool CollidingGround {
|
|
||||||
get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
|
|
||||||
set { _collidingGround = value; }
|
|
||||||
}
|
|
||||||
public override bool CollidingObj {
|
|
||||||
get { return _collidingObj; }
|
|
||||||
set { _collidingObj = value; }
|
|
||||||
}
|
|
||||||
public bool IsPhantom {
|
public bool IsPhantom {
|
||||||
get {
|
get {
|
||||||
// SceneObjectPart removes phantom objects from the physics scene
|
// SceneObjectPart removes phantom objects from the physics scene
|
||||||
|
@ -972,6 +999,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_buoyancy = value;
|
_buoyancy = value;
|
||||||
// DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
// DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||||
// Force the recalculation of the various inertia,etc variables in the object
|
// Force the recalculation of the various inertia,etc variables in the object
|
||||||
|
DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2}", LocalID, _buoyancy, _mass);
|
||||||
UpdatePhysicalMassProperties(_mass, true);
|
UpdatePhysicalMassProperties(_mass, true);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
}
|
}
|
||||||
|
@ -981,12 +1009,12 @@ public sealed class BSPrim : BSPhysObject
|
||||||
public override OMV.Vector3 PIDTarget {
|
public override OMV.Vector3 PIDTarget {
|
||||||
set { _PIDTarget = value; }
|
set { _PIDTarget = value; }
|
||||||
}
|
}
|
||||||
public override bool PIDActive {
|
|
||||||
set { _usePID = value; }
|
|
||||||
}
|
|
||||||
public override float PIDTau {
|
public override float PIDTau {
|
||||||
set { _PIDTau = value; }
|
set { _PIDTau = value; }
|
||||||
}
|
}
|
||||||
|
public override bool PIDActive {
|
||||||
|
set { _usePID = value; }
|
||||||
|
}
|
||||||
|
|
||||||
// Used for llSetHoverHeight and maybe vehicle height
|
// Used for llSetHoverHeight and maybe vehicle height
|
||||||
// Hover Height will override MoveTo target's Z
|
// Hover Height will override MoveTo target's Z
|
||||||
|
@ -1010,7 +1038,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.
|
||||||
|
@ -1018,8 +1048,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 > BSParam.MaxAddForceMagnitude)
|
||||||
|
{
|
||||||
|
// Force has a limit
|
||||||
|
force = force / magnitude * BSParam.MaxAddForceMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -38,15 +38,6 @@ using Nini.Config;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
|
|
||||||
// Based on material, set density and friction
|
|
||||||
// More efficient memory usage when passing hull information from BSPrim to BulletSim
|
|
||||||
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
|
||||||
// Implement LockAngularMotion
|
|
||||||
// Add PID movement operations. What does ScenePresence.MoveToTarget do?
|
|
||||||
// Check terrain size. 128 or 127?
|
|
||||||
// Raycast
|
|
||||||
//
|
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
@ -83,6 +74,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
internal int m_maxSubSteps;
|
internal int m_maxSubSteps;
|
||||||
internal float m_fixedTimeStep;
|
internal float m_fixedTimeStep;
|
||||||
internal long m_simulationStep = 0;
|
internal long m_simulationStep = 0;
|
||||||
|
internal float NominalFrameRate { get; set; }
|
||||||
public long SimulationStep { get { return m_simulationStep; } }
|
public long SimulationStep { get { return m_simulationStep; } }
|
||||||
internal int m_taintsToProcessPerStep;
|
internal int m_taintsToProcessPerStep;
|
||||||
internal float LastTimeStep { get; private set; }
|
internal float LastTimeStep { get; private set; }
|
||||||
|
@ -171,6 +163,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
private string m_physicsLoggingPrefix;
|
private string m_physicsLoggingPrefix;
|
||||||
private int m_physicsLoggingFileMinutes;
|
private int m_physicsLoggingFileMinutes;
|
||||||
private bool m_physicsLoggingDoFlush;
|
private bool m_physicsLoggingDoFlush;
|
||||||
|
private bool m_physicsPhysicalDumpEnabled;
|
||||||
// 'true' of the vehicle code is to log lots of details
|
// 'true' of the vehicle code is to log lots of details
|
||||||
public bool VehicleLoggingEnabled { get; private set; }
|
public bool VehicleLoggingEnabled { get; private set; }
|
||||||
public bool VehiclePhysicalLoggingEnabled { get; private set; }
|
public bool VehiclePhysicalLoggingEnabled { get; private set; }
|
||||||
|
@ -276,11 +269,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
BSParam.SetParameterConfigurationValues(this, pConfig);
|
BSParam.SetParameterConfigurationValues(this, pConfig);
|
||||||
|
|
||||||
// Very detailed logging for physics debugging
|
// Very detailed logging for physics debugging
|
||||||
|
// TODO: the boolean values can be moved to the normal parameter processing.
|
||||||
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
|
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
|
||||||
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
|
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
|
||||||
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
|
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
|
||||||
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
|
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
|
||||||
m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false);
|
m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false);
|
||||||
|
m_physicsPhysicalDumpEnabled = pConfig.GetBoolean("PhysicsPhysicalDumpEnabled", false);
|
||||||
// Very detailed logging for vehicle debugging
|
// Very detailed logging for vehicle debugging
|
||||||
VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
|
VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
|
||||||
VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false);
|
VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false);
|
||||||
|
@ -495,6 +490,11 @@ 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.
|
||||||
|
if (m_physicsPhysicalDumpEnabled)
|
||||||
|
BulletSimAPI.DumpAllInfo2(World.ptr);
|
||||||
|
|
||||||
// step the physical world one interval
|
// step the physical world one interval
|
||||||
m_simulationStep++;
|
m_simulationStep++;
|
||||||
int numSubSteps = 0;
|
int numSubSteps = 0;
|
||||||
|
@ -592,12 +592,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
// The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
|
// 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.
|
// Only enable this in a limited test world with few objects.
|
||||||
// BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
|
if (m_physicsPhysicalDumpEnabled)
|
||||||
|
BulletSimAPI.DumpAllInfo2(World.ptr);
|
||||||
|
|
||||||
// The physics engine returns the number of milliseconds it simulated this call.
|
// The physics engine returns the number of milliseconds it simulated this call.
|
||||||
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
||||||
// Multiply by 55 to give a nominal frame rate of 55.
|
// Multiply by 55 to give a nominal frame rate of 55.
|
||||||
return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f;
|
return (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something has collided
|
// Something has collided
|
||||||
|
|
|
@ -250,20 +250,20 @@ public enum CollisionFilterGroups : uint
|
||||||
// filter/mask definition below. This way collision interactions
|
// filter/mask definition below. This way collision interactions
|
||||||
// are more easily found and debugged.
|
// are more easily found and debugged.
|
||||||
BNoneGroup = 0,
|
BNoneGroup = 0,
|
||||||
BDefaultGroup = 1 << 0,
|
BDefaultGroup = 1 << 0, // 0001
|
||||||
BStaticGroup = 1 << 1,
|
BStaticGroup = 1 << 1, // 0002
|
||||||
BKinematicGroup = 1 << 2,
|
BKinematicGroup = 1 << 2, // 0004
|
||||||
BDebrisGroup = 1 << 3,
|
BDebrisGroup = 1 << 3, // 0008
|
||||||
BSensorTrigger = 1 << 4,
|
BSensorTrigger = 1 << 4, // 0010
|
||||||
BCharacterGroup = 1 << 5,
|
BCharacterGroup = 1 << 5, // 0020
|
||||||
BAllGroup = 0xFFFFFFFF,
|
BAllGroup = 0x000FFFFF,
|
||||||
// Filter groups defined by BulletSim
|
// Filter groups defined by BulletSim
|
||||||
BGroundPlaneGroup = 1 << 10,
|
BGroundPlaneGroup = 1 << 10, // 0400
|
||||||
BTerrainGroup = 1 << 11,
|
BTerrainGroup = 1 << 11, // 0800
|
||||||
BRaycastGroup = 1 << 12,
|
BRaycastGroup = 1 << 12, // 1000
|
||||||
BSolidGroup = 1 << 13,
|
BSolidGroup = 1 << 13, // 2000
|
||||||
// BLinksetGroup = xx // a linkset proper is either static or dynamic
|
// BLinksetGroup = xx // a linkset proper is either static or dynamic
|
||||||
BLinksetChildGroup = 1 << 14,
|
BLinksetChildGroup = 1 << 14, // 4000
|
||||||
};
|
};
|
||||||
|
|
||||||
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
||||||
|
|
|
@ -72,12 +72,12 @@ public struct BulletBody
|
||||||
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
|
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
|
||||||
|
|
||||||
// Apply the specificed collision mask into the physical world
|
// Apply the specificed collision mask into the physical world
|
||||||
public void ApplyCollisionMask()
|
public bool ApplyCollisionMask()
|
||||||
{
|
{
|
||||||
// Should assert the body has been added to the physical world.
|
// Should assert the body has been added to the physical world.
|
||||||
// (The collision masks are stored in the collision proxy cache which only exists for
|
// (The collision masks are stored in the collision proxy cache which only exists for
|
||||||
// a collision body that is in the world.)
|
// a collision body that is in the world.)
|
||||||
BulletSimAPI.SetCollisionGroupMask2(ptr,
|
return BulletSimAPI.SetCollisionGroupMask2(ptr,
|
||||||
BulletSimData.CollisionTypeMasks[collisionType].group,
|
BulletSimData.CollisionTypeMasks[collisionType].group,
|
||||||
BulletSimData.CollisionTypeMasks[collisionType].mask);
|
BulletSimData.CollisionTypeMasks[collisionType].mask);
|
||||||
}
|
}
|
||||||
|
@ -207,26 +207,6 @@ public struct CollisionTypeFilterGroup
|
||||||
public uint mask;
|
public uint mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NOTE: old definitions kept for reference. Delete when things are working.
|
|
||||||
// The collsion filters and masked are defined in one place -- don't want them scattered
|
|
||||||
AvatarGroup = BCharacterGroup,
|
|
||||||
AvatarMask = BAllGroup,
|
|
||||||
ObjectGroup = BSolidGroup,
|
|
||||||
ObjectMask = BAllGroup,
|
|
||||||
StaticObjectGroup = BStaticGroup,
|
|
||||||
StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much
|
|
||||||
LinksetGroup = BLinksetGroup,
|
|
||||||
LinksetMask = BAllGroup,
|
|
||||||
LinksetChildGroup = BLinksetChildGroup,
|
|
||||||
LinksetChildMask = BNoneGroup, // Linkset children disappear from the world
|
|
||||||
VolumeDetectGroup = BSensorTrigger,
|
|
||||||
VolumeDetectMask = ~BSensorTrigger,
|
|
||||||
TerrainGroup = BTerrainGroup,
|
|
||||||
TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide
|
|
||||||
GroundPlaneGroup = BGroundPlaneGroup,
|
|
||||||
GroundPlaneMask = BAllGroup
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static class BulletSimData
|
public static class BulletSimData
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -269,8 +249,9 @@ public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeM
|
||||||
},
|
},
|
||||||
{ CollisionType.LinksetChild,
|
{ CollisionType.LinksetChild,
|
||||||
new CollisionTypeFilterGroup(CollisionType.LinksetChild,
|
new CollisionTypeFilterGroup(CollisionType.LinksetChild,
|
||||||
(uint)CollisionFilterGroups.BTerrainGroup,
|
(uint)CollisionFilterGroups.BLinksetChildGroup,
|
||||||
(uint)(CollisionFilterGroups.BNoneGroup))
|
(uint)(CollisionFilterGroups.BNoneGroup))
|
||||||
|
// (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
CURRENT PRIORITIES
|
CURRENT PRIORITIES
|
||||||
=================================================
|
=================================================
|
||||||
Smooth avatar movement with motor (DONE)
|
Redo BulletSimAPI to allow native C# implementation of Bullet option.
|
||||||
Should motor update be all at taint-time? (Yes, DONE)
|
Avatar movement
|
||||||
Fix avatar slowly sliding when standing (zero motion when stopped)
|
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle
|
||||||
llApplyImpulse()
|
walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
|
||||||
Compare mass/movement in OS and SL. Calibrate actions.
|
avatar capsule rotation completed
|
||||||
llSetBuoyancy()
|
llMoveToTarget
|
||||||
Boats float low in the water
|
|
||||||
Enable vehicle border crossings (at least as poorly as ODE)
|
Enable vehicle border crossings (at least as poorly as ODE)
|
||||||
Terrain skirts
|
Terrain skirts
|
||||||
Avatar created in previous region and not new region when crossing border
|
Avatar created in previous region and not new region when crossing border
|
||||||
Vehicle recreated in new sim at small Z value (offset from root value?) (DONE)
|
Vehicle recreated in new sim at small Z value (offset from root value?) (DONE)
|
||||||
Add material densities to the material types.
|
|
||||||
Vehicle movement on terrain smoothness
|
Vehicle movement on terrain smoothness
|
||||||
Vehicle script tuning/debugging
|
Vehicle script tuning/debugging
|
||||||
Avanti speed script
|
Avanti speed script
|
||||||
Weapon shooter script
|
Weapon shooter script
|
||||||
limitMotorUp calibration (more down?)
|
limitMotorUp calibration (more down?)
|
||||||
|
Boats float low in the water
|
||||||
|
Add material densities to the material types.
|
||||||
|
|
||||||
CRASHES
|
CRASHES
|
||||||
=================================================
|
=================================================
|
||||||
|
@ -35,6 +35,8 @@ Border crossing with linked vehicle causes crash
|
||||||
Vehicles (Move smoothly)
|
Vehicles (Move smoothly)
|
||||||
Add vehicle collisions so IsColliding is properly reported.
|
Add vehicle collisions so IsColliding is properly reported.
|
||||||
Needed for banking, limitMotorUp, movementLimiting, ...
|
Needed for banking, limitMotorUp, movementLimiting, ...
|
||||||
|
VehicleAddForce is not scaled by the simulation step but it is only
|
||||||
|
applied for one step. Should it be scaled?
|
||||||
Some vehicles should not be able to turn if no speed or off ground.
|
Some vehicles should not be able to turn if no speed or off ground.
|
||||||
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
||||||
Neb car jiggling left and right
|
Neb car jiggling left and right
|
||||||
|
@ -58,7 +60,6 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
|
||||||
|
|
||||||
BULLETSIM TODO LIST:
|
BULLETSIM TODO LIST:
|
||||||
=================================================
|
=================================================
|
||||||
In SL, perfect spheres don't seem to have rolling friction. Add special case.
|
|
||||||
Avatar density is WAY off. Compare and calibrate with what's in SL.
|
Avatar density is WAY off. Compare and calibrate with what's in SL.
|
||||||
Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
|
Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
|
||||||
Duplicating a physical prim causes old prim to jump away
|
Duplicating a physical prim causes old prim to jump away
|
||||||
|
@ -93,6 +94,9 @@ Should the different PID factors have non-equal contributions for different
|
||||||
Selecting and deselecting physical objects causes CPU processing time to jump
|
Selecting and deselecting physical objects causes CPU processing time to jump
|
||||||
http://www.youtube.com/watch?v=Hjg57fWg8yI&hd=1
|
http://www.youtube.com/watch?v=Hjg57fWg8yI&hd=1
|
||||||
put thousand physical objects, select and deselect same. CPU time will be large.
|
put thousand physical objects, select and deselect same. CPU time will be large.
|
||||||
|
Re-implement buoyancy as a separate force on the object rather than diddling gravity.
|
||||||
|
Register a pre-step event to add the force.
|
||||||
|
More efficient memory usage when passing hull information from BSPrim to BulletSim
|
||||||
|
|
||||||
LINKSETS
|
LINKSETS
|
||||||
======================================================
|
======================================================
|
||||||
|
@ -146,6 +150,8 @@ Is there are more efficient method of implementing pre and post step actions?
|
||||||
See http://www.codeproject.com/Articles/29922/Weak-Events-in-C
|
See http://www.codeproject.com/Articles/29922/Weak-Events-in-C
|
||||||
|
|
||||||
Physics Arena central pyramid: why is one side permiable?
|
Physics Arena central pyramid: why is one side permiable?
|
||||||
|
|
||||||
|
In SL, perfect spheres don't seem to have rolling friction. Add special case.
|
||||||
Enforce physical parameter min/max:
|
Enforce physical parameter min/max:
|
||||||
Gravity: [-1, 28]
|
Gravity: [-1, 28]
|
||||||
Friction: [0, 255]
|
Friction: [0, 255]
|
||||||
|
@ -188,6 +194,7 @@ Should taints check for existance or activeness of target?
|
||||||
actually gone when the taint happens. Crashes don't happen because the taint closure
|
actually gone when the taint happens. Crashes don't happen because the taint closure
|
||||||
keeps the object from being freed, but that is just an accident.
|
keeps the object from being freed, but that is just an accident.
|
||||||
Possibly have and 'active' flag that is checked by the taint processor?
|
Possibly have and 'active' flag that is checked by the taint processor?
|
||||||
|
Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones)
|
||||||
|
|
||||||
THREADING
|
THREADING
|
||||||
=================================================
|
=================================================
|
||||||
|
@ -237,3 +244,12 @@ Should vehicle angular/linear movement friction happen after all the components
|
||||||
What is expected by some vehicles (turning up friction to moderate speed))
|
What is expected by some vehicles (turning up friction to moderate speed))
|
||||||
Tune terrain/object friction to be closer to SL.
|
Tune terrain/object friction to be closer to SL.
|
||||||
(Resolution: added material type with friction and resolution)
|
(Resolution: added material type with friction and resolution)
|
||||||
|
Smooth avatar movement with motor (DONE)
|
||||||
|
Should motor update be all at taint-time? (Yes, DONE)
|
||||||
|
Fix avatar slowly sliding when standing (zero motion when stopped) (DONE)
|
||||||
|
(Resolution: added BSVMotor for avatar starting and stopping)
|
||||||
|
llApplyImpulse()
|
||||||
|
Compare mass/movement in OS and SL. Calibrate actions. (DONE)
|
||||||
|
(Resolution: tested on SL and OS. AddForce scales the force for timestep)
|
||||||
|
llSetBuoyancy() (DONE)
|
||||||
|
(Resolution: Bullet resets object gravity when added to world. Moved set gravity)
|
||||||
|
|
Loading…
Reference in New Issue