BulletSim: Make avatar capsule so it is not circular.

Simple attempt to make avatars better shaped.
Replace parameter 'avatarCapsuleRadius' with 'avatarCapsuleWidth'
and 'avatarCapsuleDepth'.
More tweeking to avatar height calculation. A little better but
short avatar's feet are above the terrain and tall avatar's feet
are a little below the ground.
connector_plugin
Robert Adams 2012-11-21 16:31:23 -08:00
parent 4a0de01704
commit cbc7e7bf85
7 changed files with 41 additions and 22 deletions

View File

@ -82,7 +82,13 @@ public sealed class BSCharacter : BSPhysObject
{ {
_physicsActorType = (int)ActorTypes.Agent; _physicsActorType = (int)ActorTypes.Agent;
_position = pos; _position = pos;
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
// replace with the default values.
_size = size; _size = size;
if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth;
if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth;
_flying = isFlying; _flying = isFlying;
_orientation = OMV.Quaternion.Identity; _orientation = OMV.Quaternion.Identity;
_velocity = OMV.Vector3.Zero; _velocity = OMV.Vector3.Zero;
@ -175,8 +181,7 @@ public sealed class BSCharacter : BSPhysObject
get get
{ {
// Avatar capsule size is kept in the scale parameter. // Avatar capsule size is kept in the scale parameter.
// return _size; return _size;
return new OMV.Vector3(Scale.X * 2f, Scale.Y * 2f, Scale.Z);
} }
set { set {
@ -614,14 +619,19 @@ public sealed class BSCharacter : BSPhysObject
// The 'size' given by the simulator is the mid-point of the avatar // The 'size' given by the simulator is the mid-point of the avatar
// and X and Y are unspecified. // and X and Y are unspecified.
OMV.Vector3 newScale = OMV.Vector3.Zero; OMV.Vector3 newScale = size;
newScale.X = PhysicsScene.Params.avatarCapsuleRadius; // newScale.X = PhysicsScene.Params.avatarCapsuleWidth;
newScale.Y = PhysicsScene.Params.avatarCapsuleRadius; // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth;
// From the total height, remove the capsule half spheres that are at each end // From the total height, remove the capsule half spheres that are at each end
// The 1.15f came from ODE. Not sure what this factors in. // The 1.15f came from ODE. Not sure what this factors in.
newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y);
Scale = newScale;
// The total scale height is the central cylindar plus the caps on the two ends.
newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f);
// Convert diameters to radii and height to half height -- the way Bullet expects it.
Scale = newScale / 2f;
} }
// set _avatarVolume and _mass based on capsule size, _density and Scale // set _avatarVolume and _mass based on capsule size, _density and Scale

View File

@ -93,7 +93,7 @@ public sealed class BSPrim : BSPhysObject
_physicsActorType = (int)ActorTypes.Prim; _physicsActorType = (int)ActorTypes.Prim;
_position = pos; _position = pos;
_size = size; _size = size;
Scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type Scale = size; // the scale will be set by CreateGeom depending on object type
_orientation = rotation; _orientation = rotation;
_buoyancy = 1f; _buoyancy = 1f;
_velocity = OMV.Vector3.Zero; _velocity = OMV.Vector3.Zero;
@ -154,6 +154,8 @@ public sealed class BSPrim : BSPhysObject
public override OMV.Vector3 Size { public override OMV.Vector3 Size {
get { return _size; } get { return _size; }
set { set {
// We presume the scale and size are the same. If scale must be changed for
// the physical shape, that is done when the geometry is built.
_size = value; _size = value;
ForceBodyShapeRebuild(false); ForceBodyShapeRebuild(false);
} }

View File

@ -1185,14 +1185,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
(s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarRestitution; }, (s) => { return s.m_params[0].avatarRestitution; },
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
0.37f, 0.6f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarCapsuleWidth = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleRadius; }, (s) => { return s.m_params[0].avatarCapsuleWidth; },
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleWidth, p, l, v); } ),
new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
0.45f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleDepth = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleDepth; },
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleDepth, p, l, v); } ),
new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
// 1.5f, 1.5f,
2.140599f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleHeight; }, (s) => { return s.m_params[0].avatarCapsuleHeight; },
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),

View File

@ -525,9 +525,6 @@ public sealed class BSShapeCollection : IDisposable
// release any previous shape // release any previous shape
DereferenceShape(prim.PhysShape, true, shapeCallback); DereferenceShape(prim.PhysShape, true, shapeCallback);
// Bullet native objects are scaled by the Bullet engine so pass the size in
prim.Scale = prim.Size;
BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
// 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.
@ -547,12 +544,13 @@ public sealed class BSShapeCollection : IDisposable
nativeShapeData.Type = shapeType; nativeShapeData.Type = shapeType;
nativeShapeData.ID = prim.LocalID; nativeShapeData.ID = prim.LocalID;
nativeShapeData.Scale = prim.Scale; nativeShapeData.Scale = prim.Scale;
nativeShapeData.Size = prim.Scale; nativeShapeData.Size = prim.Scale; // unneeded, I think.
nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.MeshKey = (ulong)shapeKey;
nativeShapeData.HullKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey;
if (shapeType == PhysicsShapeType.SHAPE_CAPSULE) if (shapeType == PhysicsShapeType.SHAPE_CAPSULE)
{ {
// The proper scale has been calculated in the prim.
newShape = new BulletShape( newShape = new BulletShape(
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
, shapeType); , shapeType);
@ -560,6 +558,9 @@ public sealed class BSShapeCollection : IDisposable
} }
else else
{ {
// Native shapes are scaled in Bullet so set the scaling to the size
prim.Scale = prim.Size;
nativeShapeData.Scale = prim.Scale;
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
} }
if (newShape.ptr == IntPtr.Zero) if (newShape.ptr == IntPtr.Zero)

View File

@ -308,7 +308,7 @@ public sealed class BSTerrainManager
{ {
PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
LogHeader, PhysicsScene.RegionName, terrainRegionBase, LogHeader, PhysicsScene.RegionName, terrainRegionBase,
PhysicsScene.Params.terrainImplementation); (BSTerrainPhys.TerrainImplementation)PhysicsScene.Params.terrainImplementation);
BSTerrainPhys newTerrainPhys = null; BSTerrainPhys newTerrainPhys = null;
switch ((int)PhysicsScene.Params.terrainImplementation) switch ((int)PhysicsScene.Params.terrainImplementation)
{ {

View File

@ -291,7 +291,8 @@ public struct ConfigurationParameters
public float avatarStandingFriction; public float avatarStandingFriction;
public float avatarDensity; public float avatarDensity;
public float avatarRestitution; public float avatarRestitution;
public float avatarCapsuleRadius; public float avatarCapsuleWidth;
public float avatarCapsuleDepth;
public float avatarCapsuleHeight; public float avatarCapsuleHeight;
public float avatarContactProcessingThreshold; public float avatarContactProcessingThreshold;

View File

@ -913,7 +913,8 @@
AvatarFriction = 0.2 AvatarFriction = 0.2
AvatarRestitution = 0.0 AvatarRestitution = 0.0
AvatarDensity = 60.0 AvatarDensity = 60.0
AvatarCapsuleRadius = 0.37 AvatarCapsuleWidth = 0.6
AvatarCapsuleDepth = 0.45
AvatarCapsuleHeight = 1.5 AvatarCapsuleHeight = 1.5
AvatarContactProcessingThreshold = 0.1 AvatarContactProcessingThreshold = 0.1