From feb058f5c53b76ab0dab1680d2b0dd15fd2bfa6d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 6 Mar 2016 11:30:25 -0800 Subject: BulletSim: Send out avatar position update if velocity is now zero and it wasn't zero last tick. This will prevent some avatar creeping. Adjust BulletSim default avatar velocity zeroing so the avatar stops sooner. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 +++ OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b281e5f..e4c9de1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3571,6 +3571,9 @@ namespace OpenSim.Region.Framework.Scenes !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !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 ) ) ) { diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index 389a441..e34e3a9 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs @@ -633,7 +633,7 @@ public static class BSParam new ParameterDefn("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines", 0.315f ), new ParameterDefn("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped", - 0.4f, + 0.45f, (s) => { return (float)AvatarStopZeroThreshold; }, (s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ), new ParameterDefn("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", -- cgit v1.1 From b65a18ef3fbd567114d85d9e30a110b7dda7b835 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 6 Mar 2016 14:16:46 -0800 Subject: Remove unused parameter ShouldUseFireAndForgetForCollisions. It was used a while ago for testing but the execution code was removed. --- OpenSim/Region/Framework/Scenes/Scene.cs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ec74297..058b6f6 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -418,17 +418,6 @@ namespace OpenSim.Region.Framework.Scenes private float terrainMS; 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; - /// /// Tick at which the last frame was processed. /// @@ -1147,10 +1136,6 @@ namespace OpenSim.Region.Framework.Scenes m_update_terrain = startupConfig.GetInt("UpdateTerrainEveryNFrames", m_update_terrain); m_update_temp_cleaning = startupConfig.GetInt("UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning); - if (startupConfig.Contains("ShouldUseFireAndForgetForCollisions")) - { - ShouldUseFireAndForgetForCollisions = startupConfig.GetBoolean("ShouldUseFireAndForgetForCollisions", false); - } } -- cgit v1.1 From be43fc2234731c452842b6fd7c08a33ba568b3eb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 6 Mar 2016 14:23:06 -0800 Subject: BulletSim: use the new 'setAvatarSize' physics call introduced in 0.9. This disables all the avatar size fudge numbers previously used by BulletSim. If you have your region tuned to the old way, set "[BulletSim]AvatarUseBefore09SizeComputation=true" in your INI files. --- .../Region/PhysicsModules/BulletS/BSCharacter.cs | 213 ++++++++++++--------- OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | 3 + OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | 4 +- 3 files changed, 129 insertions(+), 91 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs index 6d5589f..5ad2136 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs @@ -40,7 +40,6 @@ public sealed class BSCharacter : BSPhysObject private static readonly string LogHeader = "[BULLETS CHAR]"; // private bool _stopped; - private OMV.Vector3 _size; private bool _grabbed; private bool _selected; private float _mass; @@ -57,6 +56,9 @@ public sealed class BSCharacter : BSPhysObject private bool _kinematic; private float _buoyancy; + private OMV.Vector3 _size; + private float _footOffset; + private BSActorAvatarMove m_moveActor; private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; @@ -76,7 +78,7 @@ public sealed class BSCharacter : BSPhysObject public override bool IsIncomplete { get { return false; } } 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") { @@ -91,21 +93,13 @@ public sealed class BSCharacter : BSPhysObject Density = BSParam.AvatarDensity; _isPhysical = true; - // Old versions of ScenePresence passed only the height. If width and/or depth are zero, - // replace with the default values. - _size = size; - 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(); + // Adjustments for zero X and Y made in Size() + // This also computes avatar scale, volume, and mass + SetAvatarSize(size, footOffset, true /* initializing */); DetailLog( "{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 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() @@ -209,45 +203,68 @@ public sealed class BSCharacter : BSPhysObject public override OMV.Vector3 Size { get { - // Avatar capsule size is kept in the scale parameter. return _size; } set { - // This is how much the avatar size is changing. Positive means getting bigger. - // The avatar altitude must be adjusted for this change. - float heightChange = value.Z - _size.Z; + setAvatarSize(value, _footOffset); + } + } - _size = value; + // 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 (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; - if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; + if (newSize.X == 0f) newSize.X = BSParam.AvatarCapsuleDepth; + if (newSize.Y == 0f) newSize.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); + 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); + } - PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate() - { - if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) - { - PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale); - UpdatePhysicalMassProperties(RawMass, true); + // 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; - // 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); + _size = newSize; - // Make sure this change appears as a property update event - PhysScene.PE.PushUpdate(PhysBody); - } - }); + 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 + public override PrimitiveBaseShape Shape { set { BaseShape = value; } } @@ -702,60 +719,71 @@ public sealed class BSCharacter : BSPhysObject 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) { OMV.Vector3 newScale = size; - // Bullet's capsule total height is the "passed height + radius * 2"; - // 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. + if (BSParam.AvatarUseBefore09SizeComputation) + { - // Scale is multiplier of radius with one of "0.5" + // Bullet's capsule total height is the "passed height + radius * 2"; + // 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. - 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 - 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) + // 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 - heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge; + const float AVATAR_LOW = 1.1f; + 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 { - // Large avatar. Add the adjustment based on the distance from midheight - heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge; + newScale.Z = size.Z + heightAdjust; } - } - 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; + // 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.ComputeAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}", + LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale); } 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; } @@ -763,17 +791,24 @@ public sealed class BSCharacter : BSPhysObject // set _avatarVolume and _mass based on capsule size, _density and Scale private void ComputeAvatarVolumeAndMass() { - _avatarVolume = (float)( - Math.PI - * Size.X / 2f - * Size.Y / 2f // the area of capsule cylinder - * Size.Z // times height of capsule cylinder - + 1.33333333f - * Math.PI - * Size.X / 2f - * Math.Min(Size.X, Size.Y) / 2 - * Size.Y / 2f // plus the volume of the capsule end caps - ); + if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule) + { + _avatarVolume = (float)( + Math.PI + * Size.X / 2f + * Size.Y / 2f // the area of capsule cylinder + * Size.Z // times height of capsule cylinder + + 1.33333333f + * Math.PI + * 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; } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index e34e3a9..28df2d9 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs @@ -142,6 +142,7 @@ public static class BSParam public static float AvatarCapsuleWidth { get; private set; } public static float AvatarCapsuleDepth { 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 AvatarHeightMidFudge { get; private set; } public static float AvatarHeightHighFudge { get; private set; } @@ -616,6 +617,8 @@ public static class BSParam 0.45f ), new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 1.5f ), + new ParameterDefn("AvatarUseBefore09SizeComputation", "Use the old fudge method of computing avatar capsule size", + true ), new ParameterDefn("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 0f ), new ParameterDefn("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs index 747bad5..bd9f325 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs @@ -523,13 +523,13 @@ namespace OpenSim.Region.PhysicsModule.BulletS 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); 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) PhysObjects.Add(localID, actor); -- cgit v1.1