BulletSim: reorder avatar collision checking to eliminate double collision_end.

Various tweekings to avatar shape/mass/inertia/etc.
Remove change from avatar radius to diameter. But still the avatar sinks.
Collision_end now happens immediately rather than at the next subscription time.
connector_plugin
Robert Adams 2012-10-19 10:48:45 -07:00
parent e87a179c89
commit f422b9b388
6 changed files with 44 additions and 36 deletions

View File

@ -141,10 +141,6 @@ public class BSCharacter : BSPhysObject
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr);
ZeroMotion(); ZeroMotion();
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw);
BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
ForcePosition = _position; ForcePosition = _position;
// Set the velocity and compute the proper friction // Set the velocity and compute the proper friction
ForceVelocity = _velocity; ForceVelocity = _velocity;
@ -157,6 +153,9 @@ public class BSCharacter : BSPhysObject
BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
} }
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw);
BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT);
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr);
@ -583,14 +582,16 @@ public class BSCharacter : BSPhysObject
private void ComputeAvatarScale(OMV.Vector3 size) private void ComputeAvatarScale(OMV.Vector3 size)
{ {
OMV.Vector3 newScale = OMV.Vector3.Zero; // The 'size' given by the simulator is the mid-point of the avatar
// Scale wants the diameter so mult radius by two // and X and Y are unspecified.
newScale.X = PhysicsScene.Params.avatarCapsuleRadius * 2f;
newScale.Y = PhysicsScene.Params.avatarCapsuleRadius * 2f;
// From the total height, add the capsule half spheres that are at each end OMV.Vector3 newScale = OMV.Vector3.Zero;
// newScale.Z = (size.Z) - Math.Min(newScale.X, newScale.Y); newScale.X = PhysicsScene.Params.avatarCapsuleRadius;
newScale.Z = (size.Z * 2f); newScale.Y = PhysicsScene.Params.avatarCapsuleRadius;
// From the total height, remote the capsule half spheres that are at each end
newScale.Z = (size.Z * 2f) - Math.Min(newScale.X, newScale.Y);
// newScale.Z = (size.Z * 2f);
Scale = newScale; Scale = newScale;
} }
@ -599,14 +600,14 @@ public class BSCharacter : BSPhysObject
{ {
_avatarVolume = (float)( _avatarVolume = (float)(
Math.PI Math.PI
* (Scale.X / 2f) * Scale.X
* (Scale.Y / 2f) // the area of capsule cylinder * Scale.Y // the area of capsule cylinder
* Scale.Z // times height of capsule cylinder * Scale.Z // times height of capsule cylinder
+ 1.33333333f + 1.33333333f
* Math.PI * Math.PI
* (Scale.X / 2f) * Scale.X
* (Math.Min(Scale.X, Scale.Y) / 2f) * Math.Min(Scale.X, Scale.Y)
* (Scale.Y / 2f) // plus the volume of the capsule end caps * Scale.Y // plus the volume of the capsule end caps
); );
_mass = _avatarDensity * _avatarVolume; _mass = _avatarDensity * _avatarVolume;
} }

View File

@ -156,9 +156,11 @@ public abstract class BSPhysObject : PhysicsActor
public virtual bool SendCollisions() public virtual bool SendCollisions()
{ {
bool ret = true; bool ret = true;
// If the 'no collision' call, force it to happen right now so quick collision_end
bool force = CollisionCollection.Count == 0;
// throttle the collisions to the number of milliseconds specified in the subscription // throttle the collisions to the number of milliseconds specified in the subscription
if (PhysicsScene.SimulationNowTime >= NextCollisionOkTime) if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
{ {
NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs; NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs;

View File

@ -532,26 +532,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
} }
// This is a kludge to get avatar movement updates.
// The simulator expects collisions for avatars even if there are have been no collisions. This updates
// avatar animations and stuff.
// If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
foreach (BSPhysObject bsp in m_avatars)
bsp.SendCollisions();
// The above SendCollision's batch up the collisions on the objects. // The above SendCollision's batch up the collisions on the objects.
// Now push the collisions into the simulator. // Now push the collisions into the simulator.
if (ObjectsWithCollisions.Count > 0) if (ObjectsWithCollisions.Count > 0)
{ {
foreach (BSPhysObject bsp in ObjectsWithCollisions) foreach (BSPhysObject bsp in ObjectsWithCollisions)
if (!m_avatars.Contains(bsp)) // don't call avatars twice if (!bsp.SendCollisions())
if (!bsp.SendCollisions()) {
{ // If the object is done colliding, see that it's removed from the colliding list
// If the object is done colliding, see that it's removed from the colliding list ObjectsWithNoMoreCollisions.Add(bsp);
ObjectsWithNoMoreCollisions.Add(bsp); }
}
} }
// This is a kludge to get avatar movement updates.
// The simulator expects collisions for avatars even if there are have been no collisions.
// The event updates avatar animations and stuff.
// If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
foreach (BSPhysObject bsp in m_avatars)
if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice
bsp.SendCollisions();
// Objects that are done colliding are removed from the ObjectsWithCollisions list. // Objects that are done colliding are removed from the ObjectsWithCollisions list.
// Not done above because it is inside an iteration of ObjectWithCollisions. // Not done above because it is inside an iteration of ObjectWithCollisions.
if (ObjectsWithNoMoreCollisions.Count > 0) if (ObjectsWithNoMoreCollisions.Count > 0)
@ -575,6 +575,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
} }
// This 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
// 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.
// We multiply by 55 to give a recognizable running rate (55 or less). // We multiply by 55 to give a recognizable running rate (55 or less).

View File

@ -417,10 +417,9 @@ public class BSShapeCollection : IDisposable
if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
{ {
// The radius is scaled by 1/2 because we scale by the diameter.
newShape = new BulletShape( newShape = new BulletShape(
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 0.5f, 1.0f, shapeData.Scale), BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1.0f, 1.0f, shapeData.Scale),
shapeType); shapeType);
newShape.shapeKey = (System.UInt64)shapeKey; newShape.shapeKey = (System.UInt64)shapeKey;
newShape.isNativeShape = true; newShape.isNativeShape = true;
} }
@ -432,7 +431,8 @@ public class BSShapeCollection : IDisposable
} }
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared. // Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
// DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1}", shapeData.ID, newShape); DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
shapeData.ID, newShape, shapeData.Scale);
prim.BSShape = newShape; prim.BSShape = newShape;
return true; return true;

View File

@ -114,6 +114,7 @@ public class BSTerrainManager
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);
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);
// Everything collides with the ground plane. // Everything collides with the ground plane.

View File

@ -390,7 +390,7 @@ public enum CollisionFilterGroups : uint
VolumeDetectMask = ~BSensorTrigger, VolumeDetectMask = ~BSensorTrigger,
TerrainFilter = BTerrainFilter, TerrainFilter = BTerrainFilter,
TerrainMask = BAllFilter & ~BStaticFilter, TerrainMask = BAllFilter & ~BStaticFilter,
GroundPlaneFilter = BAllFilter, GroundPlaneFilter = BGroundPlaneFilter,
GroundPlaneMask = BAllFilter GroundPlaneMask = BAllFilter
}; };