BulletSim: Fix single physical prim reporting its mass as zero.

Properly return root mass as mass of just the root prim rather
than the mass of the linkset. SOG has the logic to add the masses
together to get the linkset mass.
Update TODO list.
0.7.5-pf-bulletsim
Robert Adams 2012-12-24 08:56:02 -08:00
parent 9318870607
commit 80cee1b85a
7 changed files with 83 additions and 54 deletions

View File

@ -174,7 +174,7 @@ public sealed class BSCharacter : BSPhysObject
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
}
UpdatePhysicalMassProperties(RawMass);
UpdatePhysicalMassProperties(RawMass, false);
// Make so capsule does not fall over
BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero);
@ -224,7 +224,7 @@ public sealed class BSCharacter : BSPhysObject
if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape)
{
BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale);
UpdatePhysicalMassProperties(RawMass);
UpdatePhysicalMassProperties(RawMass, true);
// Make sure this change appears as a property update event
BulletSimAPI.PushUpdate2(PhysBody.ptr);
}
@ -390,7 +390,7 @@ public sealed class BSCharacter : BSPhysObject
public override float RawMass {
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);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia);
@ -772,8 +772,9 @@ 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.
if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero)
{
stepVelocity = OMV.Vector3.Zero;
_velocityMotor.Enabled = false;
stepVelocity = OMV.Vector3.Zero;
ZeroMotion(true);
DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor);
}

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
protected float m_mass;
public float LinksetMass
{
get
{
return m_mass;
}
}
public float LinksetMass { get; protected set; }
public virtual bool LinksetIsColliding { get { return false; } }
@ -128,7 +121,7 @@ public abstract class BSLinkset
PhysicsScene = scene;
LinksetRoot = parent;
m_children = new HashSet<BSPhysObject>();
m_mass = parent.RawMass;
LinksetMass = parent.RawMass;
Rebuilding = false;
}
@ -143,7 +136,7 @@ public abstract class BSLinkset
// Don't add the root to its own linkset
if (!IsRoot(child))
AddChildToLinkset(child);
m_mass = ComputeLinksetMass();
LinksetMass = ComputeLinksetMass();
}
return this;
}
@ -162,7 +155,7 @@ public abstract class BSLinkset
return this;
}
RemoveChildFromLinkset(child);
m_mass = ComputeLinksetMass();
LinksetMass = ComputeLinksetMass();
}
// 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
// its internal properties.
// 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.
// Used to know not the schedule a rebuild in the middle of a rebuild.

View File

@ -5,7 +5,7 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclat simer.
* * Redistributions in binary form must reproduce the above copyrightD
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
@ -89,6 +89,8 @@ public sealed class BSLinksetCompound : BSLinkset
// its internal properties.
public override void Refresh(BSPhysObject requestor)
{
base.Refresh(requestor);
// Something changed so do the rebuilding thing
// ScheduleRebuild();
}
@ -96,13 +98,13 @@ public sealed class BSLinksetCompound : BSLinkset
// Schedule a refresh to happen after all the other taint processing.
private void ScheduleRebuild(BSPhysObject requestor)
{
DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}",
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}",
requestor.LocalID, Rebuilding);
// When rebuilding, it is possible to set properties that would normally require a rebuild.
// If already rebuilding, don't request another rebuild.
if (!Rebuilding)
{
PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate()
PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate()
{
if (HasAnyChildren)
RecomputeLinksetCompound();
@ -123,7 +125,6 @@ public sealed class BSLinksetCompound : BSLinkset
if (IsRoot(child))
{
// The root is going dynamic. Make sure mass is properly set.
m_mass = ComputeLinksetMass();
ScheduleRebuild(LinksetRoot);
}
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.
float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
LinksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
}
finally
{

View File

@ -46,6 +46,8 @@ public sealed class BSLinksetConstraints : BSLinkset
// refresh will happen once after all the other taints are applied.
public override void Refresh(BSPhysObject requestor)
{
base.Refresh(requestor);
// Queue to happen after all the other taint processing
PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
{
@ -279,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset
private void RecomputeLinksetConstraints()
{
float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true);
// DEBUG: see of inter-linkset collisions are causing problems
// 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.
// 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.)
child.UpdatePhysicalMassProperties(linksetMass);
child.UpdatePhysicalMassProperties(linksetMass, true);
BSConstraint constrain;
if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))

View File

@ -96,7 +96,8 @@ public abstract class BSPhysObject : PhysicsActor
// Return the object mass without calculating it or having side effects
public abstract float RawMass { get; }
// 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
public OMV.Vector3 Inertia { get; set; }

View File

@ -115,6 +115,8 @@ public sealed class BSPrim : BSPhysObject
PhysBody = new BulletBody(LocalID);
PhysShape = new BulletShape();
Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID);
// do the actual object creation at taint time
PhysicsScene.TaintedObject("BSPrim.create", delegate()
@ -384,13 +386,13 @@ public sealed class BSPrim : BSPhysObject
}
// 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
{
get
{
return Linkset.LinksetMass;
// return _mass;
return _mass;
}
}
@ -400,22 +402,41 @@ public sealed class BSPrim : BSPhysObject
}
// Set the physical mass to the passed 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;
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
}
else
{
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}", LocalID, physMass, Inertia);
if (IsStatic)
{
Inertia = OMV.Vector3.Zero;
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
}
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);
}
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
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}", LocalID, physMass, Inertia);
if (inWorld)
{
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
}
}
}
}
@ -714,7 +735,7 @@ public sealed class BSPrim : BSPhysObject
Linkset.Refresh(this);
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.
@ -737,7 +758,7 @@ public sealed class BSPrim : BSPhysObject
BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
// Mass is zero which disables a bunch of physics stuff in Bullet
UpdatePhysicalMassProperties(0f);
UpdatePhysicalMassProperties(0f, false);
// Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f)
{
@ -777,7 +798,7 @@ public sealed class BSPrim : BSPhysObject
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
// A dynamic object has mass
UpdatePhysicalMassProperties(RawMass);
UpdatePhysicalMassProperties(RawMass, false);
// Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f)
@ -950,13 +971,9 @@ public sealed class BSPrim : BSPhysObject
set {
_buoyancy = value;
// DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
// Buoyancy is faked by changing the gravity applied to the object
if (PhysBody.HasPhysicalBody)
{
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
ActivateIfPhysical(false);
}
// Force the recalculation of the various inertia,etc variables in the object
UpdatePhysicalMassProperties(_mass, true);
ActivateIfPhysical(false);
}
}

View File

@ -1,11 +1,17 @@
CURRENT PRIORITIES
=================================================
Smooth avatar movement with motor
Should motor update be all at taint-time?
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)
llApplyImpulse()
Compare mass/movement in OS and SL. Calibrate actions.
llSetBuoyancy()
Boats float low in the water
Enable vehicle border crossings (at least as poorly as ODE)
Terrain skirts
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)
Add material densities to the material types.
Vehicle movement on terrain smoothness
Vehicle script tuning/debugging
Avanti speed script
@ -52,6 +58,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
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.
Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
Duplicating a physical prim causes old prim to jump away
Dup a phys prim and the original become unselected and thus interacts w/ selected prim.
@ -82,6 +90,9 @@ Linkset.Position and Linkset.Orientation requre rewrite to properly return
Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F)
Should the different PID factors have non-equal contributions for different
values of Efficiency?
Selecting and deselecting physical objects causes CPU processing time to jump
http://www.youtube.com/watch?v=Hjg57fWg8yI&hd=1
put thousand physical objects, select and deselect same. CPU time will be large.
LINKSETS
======================================================