Merge branch 'master' of opensimulator.org:/var/git/opensim

LSLKeyTest
Melanie Thielker 2016-03-09 02:53:06 +01:00
commit 07b78a68fc
5 changed files with 141 additions and 115 deletions

View File

@ -418,17 +418,6 @@ namespace OpenSim.Region.Framework.Scenes
private float terrainMS; private float terrainMS;
private float landMS; private float landMS;
// A temporary configuration flag to enable using FireAndForget to process
// collisions from the physics engine. There is a problem with collisions
// stopping sometimes and MB's suspicion is some race condition passing
// collisions from the physics engine callback to the script engine.
// This causes the collision events to be passed with a FireAndForget
// call which should eliminate that linkage. Testers can turn this on
// and see if collisions stop. If they don't, the problem is somewhere else.
// This feature defaults to 'off' so, by default, the simulator operation
// is not changed.
public bool ShouldUseFireAndForgetForCollisions = false;
/// <summary> /// <summary>
/// Tick at which the last frame was processed. /// Tick at which the last frame was processed.
/// </summary> /// </summary>
@ -1147,10 +1136,6 @@ namespace OpenSim.Region.Framework.Scenes
m_update_terrain = startupConfig.GetInt("UpdateTerrainEveryNFrames", m_update_terrain); m_update_terrain = startupConfig.GetInt("UpdateTerrainEveryNFrames", m_update_terrain);
m_update_temp_cleaning = startupConfig.GetInt("UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning); m_update_temp_cleaning = startupConfig.GetInt("UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning);
if (startupConfig.Contains("ShouldUseFireAndForgetForCollisions"))
{
ShouldUseFireAndForgetForCollisions = startupConfig.GetBoolean("ShouldUseFireAndForgetForCollisions", false);
}
} }

View File

@ -3571,6 +3571,9 @@ namespace OpenSim.Region.Framework.Scenes
!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|| !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
|| !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE) || !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE)
// if velocity is zero and it wasn't zero last time, send the update
|| (Velocity == Vector3.Zero && m_lastVelocity != Vector3.Zero)
// if position has moved just a little and velocity is very low, send the update
|| (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ ) || (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ )
) ) ) )
{ {

View File

@ -40,7 +40,6 @@ public sealed class BSCharacter : BSPhysObject
private static readonly string LogHeader = "[BULLETS CHAR]"; private static readonly string LogHeader = "[BULLETS CHAR]";
// private bool _stopped; // private bool _stopped;
private OMV.Vector3 _size;
private bool _grabbed; private bool _grabbed;
private bool _selected; private bool _selected;
private float _mass; private float _mass;
@ -57,6 +56,9 @@ public sealed class BSCharacter : BSPhysObject
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
private OMV.Vector3 _size;
private float _footOffset;
private BSActorAvatarMove m_moveActor; private BSActorAvatarMove m_moveActor;
private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
@ -76,7 +78,7 @@ public sealed class BSCharacter : BSPhysObject
public override bool IsIncomplete { get { return false; } } public override bool IsIncomplete { get { return false; } }
public BSCharacter( public BSCharacter(
uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying) uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, float footOffset, bool isFlying)
: base(parent_scene, localID, avName, "BSCharacter") : base(parent_scene, localID, avName, "BSCharacter")
{ {
@ -91,21 +93,13 @@ public sealed class BSCharacter : BSPhysObject
Density = BSParam.AvatarDensity; Density = BSParam.AvatarDensity;
_isPhysical = true; _isPhysical = true;
// Old versions of ScenePresence passed only the height. If width and/or depth are zero, // Adjustments for zero X and Y made in Size()
// replace with the default values. // This also computes avatar scale, volume, and mass
_size = size; SetAvatarSize(size, footOffset, true /* initializing */);
if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
// The dimensions of the physical capsule are kept in the scale.
// Physics creates a unit capsule which is scaled by the physics engine.
Scale = ComputeAvatarScale(_size);
// set _avatarVolume and _mass based on capsule size, _density and Scale
ComputeAvatarVolumeAndMass();
DetailLog( DetailLog(
"{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}", "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}",
LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel); LocalID, Size, Scale, Density, _avatarVolume, RawMass, pos, vel);
// do actual creation in taint time // do actual creation in taint time
PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
@ -209,45 +203,68 @@ public sealed class BSCharacter : BSPhysObject
public override OMV.Vector3 Size { public override OMV.Vector3 Size {
get get
{ {
// Avatar capsule size is kept in the scale parameter.
return _size; return _size;
} }
set { set {
// This is how much the avatar size is changing. Positive means getting bigger. setAvatarSize(value, _footOffset);
// The avatar altitude must be adjusted for this change.
float heightChange = value.Z - _size.Z;
_size = value;
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
// replace with the default values.
if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
Scale = ComputeAvatarScale(_size);
ComputeAvatarVolumeAndMass();
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
{
if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
{
PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
UpdatePhysicalMassProperties(RawMass, true);
// Adjust the avatar's position to account for the increase/decrease in size
ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
// Make sure this change appears as a property update event
PhysScene.PE.PushUpdate(PhysBody);
}
});
} }
} }
public override PrimitiveBaseShape Shape // OpenSim 0.9 introduces a common avatar size computation
public override void setAvatarSize(OMV.Vector3 size, float feetOffset)
{
SetAvatarSize(size, feetOffset, false /* initializing */);
}
// Internal version that, if initializing, doesn't do all the updating of the physics engine
public void SetAvatarSize(OMV.Vector3 size, float feetOffset, bool initializing)
{
OMV.Vector3 newSize = size;
if (newSize.IsFinite())
{
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
// replace with the default values.
if (newSize.X == 0f) newSize.X = BSParam.AvatarCapsuleDepth;
if (newSize.Y == 0f) newSize.Y = BSParam.AvatarCapsuleWidth;
if (newSize.X < 0.01f) newSize.X = 0.01f;
if (newSize.Y < 0.01f) newSize.Y = 0.01f;
if (newSize.Z < 0.01f) newSize.Z = BSParam.AvatarCapsuleHeight;
}
else
{
newSize = new OMV.Vector3(BSParam.AvatarCapsuleDepth, BSParam.AvatarCapsuleWidth, BSParam.AvatarCapsuleHeight);
}
// This is how much the avatar size is changing. Positive means getting bigger.
// The avatar altitude must be adjusted for this change.
float heightChange = newSize.Z - Size.Z;
_size = newSize;
Scale = ComputeAvatarScale(Size);
ComputeAvatarVolumeAndMass();
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
{
if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
{
PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
UpdatePhysicalMassProperties(RawMass, true);
// Adjust the avatar's position to account for the increase/decrease in size
ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
// Make sure this change appears as a property update event
PhysScene.PE.PushUpdate(PhysBody);
}
});
}
public override PrimitiveBaseShape Shape
{ {
set { BaseShape = value; } set { BaseShape = value; }
} }
@ -702,60 +719,71 @@ public sealed class BSCharacter : BSPhysObject
public override void SetMomentum(OMV.Vector3 momentum) { public override void SetMomentum(OMV.Vector3 momentum) {
} }
// The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets
// the scale of that unit shape to create the avatars full size.
private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
{ {
OMV.Vector3 newScale = size; OMV.Vector3 newScale = size;
// Bullet's capsule total height is the "passed height + radius * 2"; if (BSParam.AvatarUseBefore09SizeComputation)
// The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
// The number we pass in for 'scaling' is the multiplier to get that base
// shape to be the size desired.
// So, when creating the scale for the avatar height, we take the passed height
// (size.Z) and remove the caps.
// An oddity of the Bullet capsule implementation is that it presumes the Y
// dimension is the radius of the capsule. Even though some of the code allows
// for a asymmetrical capsule, other parts of the code presume it is cylindrical.
// Scale is multiplier of radius with one of "0.5"
float heightAdjust = BSParam.AvatarHeightMidFudge;
if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
{ {
const float AVATAR_LOW = 1.1f;
const float AVATAR_MID = 1.775f; // 1.87f // Bullet's capsule total height is the "passed height + radius * 2";
const float AVATAR_HI = 2.45f; // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
// An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m. // The number we pass in for 'scaling' is the multiplier to get that base
float midHeightOffset = size.Z - AVATAR_MID; // shape to be the size desired.
if (midHeightOffset < 0f) // So, when creating the scale for the avatar height, we take the passed height
// (size.Z) and remove the caps.
// An oddity of the Bullet capsule implementation is that it presumes the Y
// dimension is the radius of the capsule. Even though some of the code allows
// for a asymmetrical capsule, other parts of the code presume it is cylindrical.
// Scale is multiplier of radius with one of "0.5"
float heightAdjust = BSParam.AvatarHeightMidFudge;
if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
{ {
// Small avatar. Add the adjustment based on the distance from midheight const float AVATAR_LOW = 1.1f;
heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge; const float AVATAR_MID = 1.775f; // 1.87f
const float AVATAR_HI = 2.45f;
// An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
float midHeightOffset = size.Z - AVATAR_MID;
if (midHeightOffset < 0f)
{
// Small avatar. Add the adjustment based on the distance from midheight
heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
}
else
{
// Large avatar. Add the adjustment based on the distance from midheight
heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
}
}
if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
{
newScale.X = size.X / 2f;
newScale.Y = size.Y / 2f;
// 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) * 2) + heightAdjust) / 2f;
} }
else else
{ {
// Large avatar. Add the adjustment based on the distance from midheight newScale.Z = size.Z + heightAdjust;
heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
} }
} // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
{ // If smaller than the endcaps, just fake like we're almost that small
newScale.X = size.X / 2f; if (newScale.Z < 0)
newScale.Y = size.Y / 2f; newScale.Z = 0.1f;
// 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) * 2) + heightAdjust) / 2f; DetailLog("{0},BSCharacter.ComputeAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
} }
else else
{ {
newScale.Z = size.Z + heightAdjust; newScale.Z = size.Z + _footOffset;
DetailLog("{0},BSCharacter.ComputeAvatarScale,using newScale={1}, footOffset={2}", LocalID, newScale, _footOffset);
} }
// m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
// If smaller than the endcaps, just fake like we're almost that small
if (newScale.Z < 0)
newScale.Z = 0.1f;
DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
return newScale; return newScale;
} }
@ -763,17 +791,24 @@ public sealed class BSCharacter : BSPhysObject
// set _avatarVolume and _mass based on capsule size, _density and Scale // set _avatarVolume and _mass based on capsule size, _density and Scale
private void ComputeAvatarVolumeAndMass() private void ComputeAvatarVolumeAndMass()
{ {
_avatarVolume = (float)( if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
Math.PI {
* Size.X / 2f _avatarVolume = (float)(
* Size.Y / 2f // the area of capsule cylinder Math.PI
* Size.Z // times height of capsule cylinder * Size.X / 2f
+ 1.33333333f * Size.Y / 2f // the area of capsule cylinder
* Math.PI * Size.Z // times height of capsule cylinder
* Size.X / 2f + 1.33333333f
* Math.Min(Size.X, Size.Y) / 2 * Math.PI
* Size.Y / 2f // plus the volume of the capsule end caps * Size.X / 2f
); * Math.Min(Size.X, Size.Y) / 2
* Size.Y / 2f // plus the volume of the capsule end caps
);
}
else
{
_avatarVolume = Size.X * Size.Y * Size.Z;
}
_mass = Density * BSParam.DensityScaleFactor * _avatarVolume; _mass = Density * BSParam.DensityScaleFactor * _avatarVolume;
} }

View File

@ -142,6 +142,7 @@ public static class BSParam
public static float AvatarCapsuleWidth { get; private set; } public static float AvatarCapsuleWidth { get; private set; }
public static float AvatarCapsuleDepth { get; private set; } public static float AvatarCapsuleDepth { get; private set; }
public static float AvatarCapsuleHeight { get; private set; } public static float AvatarCapsuleHeight { get; private set; }
public static bool AvatarUseBefore09SizeComputation { get; private set; }
public static float AvatarHeightLowFudge { get; private set; } public static float AvatarHeightLowFudge { get; private set; }
public static float AvatarHeightMidFudge { get; private set; } public static float AvatarHeightMidFudge { get; private set; }
public static float AvatarHeightHighFudge { get; private set; } public static float AvatarHeightHighFudge { get; private set; }
@ -616,6 +617,8 @@ public static class BSParam
0.45f ), 0.45f ),
new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar", new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar",
1.5f ), 1.5f ),
new ParameterDefn<bool>("AvatarUseBefore09SizeComputation", "Use the old fudge method of computing avatar capsule size",
true ),
new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
0f ), 0f ),
new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
@ -633,7 +636,7 @@ public static class BSParam
new ParameterDefn<float>("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines", new ParameterDefn<float>("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines",
0.315f ), 0.315f ),
new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped", new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
0.4f, 0.45f,
(s) => { return (float)AvatarStopZeroThreshold; }, (s) => { return (float)AvatarStopZeroThreshold; },
(s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ), (s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ),
new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",

View File

@ -523,13 +523,13 @@ namespace OpenSim.Region.PhysicsModule.BulletS
return null; return null;
} }
public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float footOffset, bool isFlying)
{ {
// m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
if (!m_initialized) return null; if (!m_initialized) return null;
BSCharacter actor = new BSCharacter(localID, avName, this, position, velocity, size, isFlying); BSCharacter actor = new BSCharacter(localID, avName, this, position, Vector3.Zero, size, footOffset, isFlying);
lock (PhysObjects) lock (PhysObjects)
PhysObjects.Add(localID, actor); PhysObjects.Add(localID, actor);