From 5685b33071c683c41643fcb78d6f8a28d98db468 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 26 Nov 2012 10:47:34 -0800 Subject: BulletSim: increase vehicle stability by suppressing Bullet's update to angular velocity. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 21 +++++---- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 50 +++------------------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 12 +++--- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 2 +- 4 files changed, 26 insertions(+), 59 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 95a4134..6ff8a48 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -805,6 +805,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_angularFrictionTimescale // body angular velocity decay rate // m_lastAngularVelocity // what was last applied to body + /* if (m_angularMotorDirection.LengthSquared() > 0.0001) { Vector3 origVel = m_angularMotorVelocity; @@ -823,6 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_angularMotorVelocity = Vector3.Zero; } + */ Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); @@ -842,15 +844,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // verticalError.X and .Y are the World error amounts. They are 0 when there is no // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall - // and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be + // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be // modulated to prevent a stable inverted body. // Error is 0 (no error) to +/- 2 (max error) - if (verticalError.Z < 0.0f) - { - verticalError.X = 2.0f - verticalError.X; - verticalError.Y = 2.0f - verticalError.Y; - } + verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f)); + verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f)); + // scale it by VAservo (timestep and timescale) verticalError = verticalError * VAservo; @@ -1013,10 +1013,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Also remove any motion that is on the object so added motion is only from vehicle. Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity); + // Unscale the force by the angular factor so it overwhelmes the Bullet additions. Prim.ForceRotationalVelocity = applyAngularForce; - VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}", - Prim.LocalID, applyAngularForce, m_lastAngularVelocity); + VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + applyAngularForce, m_lastAngularVelocity + ); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index caa6c46..c62c79a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1380,54 +1380,16 @@ public sealed class BSPrim : BSPhysObject public override void UpdateProperties(EntityProperties entprop) { - /* - UpdatedProperties changed = 0; - // assign to the local variables so the normal set action does not happen - // if (_position != entprop.Position) - if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE)) - { - _position = entprop.Position; - changed |= UpdatedProperties.Position; - } - // if (_orientation != entprop.Rotation) - if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE)) - { - _orientation = entprop.Rotation; - changed |= UpdatedProperties.Rotation; - } - // if (_velocity != entprop.Velocity) - if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE)) - { - _velocity = entprop.Velocity; - changed |= UpdatedProperties.Velocity; - } - // if (_acceleration != entprop.Acceleration) - if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE)) - { - _acceleration = entprop.Acceleration; - changed |= UpdatedProperties.Acceleration; - } - // if (_rotationalVelocity != entprop.RotationalVelocity) - if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE)) - { - _rotationalVelocity = entprop.RotationalVelocity; - changed |= UpdatedProperties.RotationalVel; - } - if (changed != 0) + // Updates only for individual prims and for the root object of a linkset. + if (Linkset.IsRoot(this)) { - // Only update the position of single objects and linkset roots - if (Linkset.IsRoot(this)) + // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet + // TODO: handle physics introduced by Bullet with computed vehicle physics. + if (_vehicle.IsActive) { - base.RequestPhysicsterseUpdate(); + entprop.RotationalVelocity = OMV.Vector3.Zero; } - } - */ - - // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. - // Updates only for individual prims and for the root object of a linkset. - if (Linkset.IsRoot(this)) - { // Assign directly to the local variables so the normal set action does not happen _position = entprop.Position; _orientation = entprop.Rotation; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 805e670..09b1423 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -515,9 +515,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters collidersCount = 0; } - // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in + // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in. - // Get a value for 'now' so all the collision and update routines don't have to get their own + // Get a value for 'now' so all the collision and update routines don't have to get their own. SimulationNowTime = Util.EnvironmentTickCount(); // If there were collisions, process them by sending the event to the prim. @@ -563,6 +563,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ObjectsWithCollisions.Remove(po); ObjectsWithNoMoreCollisions.Clear(); } + // Done with collisions. // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) @@ -586,9 +587,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // 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. - // We multiply by 55 to give a recognizable running rate (55 or less). - return numSubSteps * m_fixedTimeStep * 1000 * 55; - // return timeStep * 1000 * 55; + // Multiply by 55 to give a nominal frame rate of 55. + return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f; } // Something has collided @@ -1172,7 +1172,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].avatarFriction; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 0.99f, + 10.0f, (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarStandingFriction; }, (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 12baee9..1e003e6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -357,7 +357,7 @@ public enum CollisionFlags : uint CF_CHARACTER_OBJECT = 1 << 4, CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, - // Following used by BulletSim to control collisions + // Following used by BulletSim to control collisions and updates BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, BS_FLOATS_ON_WATER = 1 << 11, BS_NONE = 0, -- cgit v1.1 From 16e4019eca0bec8802e9bd7d2e7bd228025b701a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 26 Nov 2012 22:25:36 +0000 Subject: Fix database service unit test failures by temporarily reverting BasicDataServiceTest extending OpenSimTestCase. Mono 2.4.3 doesn't like this when running nunit, with nunit throwing AssetTests`2 : System.MemberAccessException : Cannot create an instance of OpenSim.Data.Tests.AssetTests`2[TConn,TAssetData] because Type.ContainsGenericParameters is true. and similar. Mono 2.10.8.1 does not have this issue. So will wait until min version of mono bumps before restoring. --- OpenSim/Data/Tests/BasicDataServiceTest.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/Tests/BasicDataServiceTest.cs b/OpenSim/Data/Tests/BasicDataServiceTest.cs index d8019ba..69b79bf 100644 --- a/OpenSim/Data/Tests/BasicDataServiceTest.cs +++ b/OpenSim/Data/Tests/BasicDataServiceTest.cs @@ -44,9 +44,15 @@ namespace OpenSim.Data.Tests /// This is a base class for testing any Data service for any DBMS. /// Requires NUnit 2.5 or better (to support the generics). /// + /// + /// FIXME: Should extend OpenSimTestCase but compile on mono 2.4.3 currently fails with + /// AssetTests`2 : System.MemberAccessException : Cannot create an instance of OpenSim.Data.Tests.AssetTests`2[TConn,TAssetData] because Type.ContainsGenericParameters is true. + /// and similar on EstateTests, InventoryTests and RegionTests. + /// Runs fine with mono 2.10.8.1, so easiest thing is to wait until min Mono version uplifts. + /// /// /// - public class BasicDataServiceTest : OpenSimTestCase + public class BasicDataServiceTest where TConn : DbConnection, new() where TService : class, new() { -- cgit v1.1 From 9e0db36c82da303a0d9c709b84b1c35879a39e86 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:23:50 -0800 Subject: BulletSim: add 'infinite' timescale that does not reduce motor target or friction. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 480da2c..e91bfa8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -7,6 +7,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public abstract class BSMotor { + // Timescales and other things can be turned off by setting them to 'infinite'. + public const float Infinite = 10000f; + public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); + public BSMotor(string useName) { UseName = useName; @@ -46,8 +50,9 @@ public class BSVMotor : BSMotor public BSVMotor(string useName) : base(useName) { - TimeScale = TargetValueDecayTimeScale = Efficiency = 1f; - FrictionTimescale = Vector3.Zero; + TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; + Efficiency = 1f; + FrictionTimescale = BSMotor.InfiniteVector; CurrentValue = TargetValue = Vector3.Zero; } public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) @@ -78,23 +83,35 @@ public class BSVMotor : BSMotor // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; CurrentValue += addAmount; + returnCurrent = CurrentValue; - // The desired value reduces to zero when also reduces the difference with current. - float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; - TargetValue *= (1f - decayFactor); + // The desired value reduces to zero which also reduces the difference with current. + // If the decay time is infinite, don't decay at all. + float decayFactor = 0f; + if (TargetValueDecayTimeScale != BSMotor.Infinite) + { + decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; + TargetValue *= (1f - decayFactor); + } Vector3 frictionFactor = Vector3.Zero; - frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; - CurrentValue *= (Vector3.One - frictionFactor); + if (FrictionTimescale != BSMotor.InfiniteVector) + { + // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; + frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; + frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; + CurrentValue *= (Vector3.One - frictionFactor); + } - MDetailLog("{0},BSVMotor.Step,nonZero,{1},origTarget={2},origCurr={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", - BSScene.DetailLogZero, UseName, origTarget, origCurrVal, + MDetailLog("{0},BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, TimeScale, addAmount, TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor); MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", - BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, + BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, addAmount, decayFactor, frictionFactor, returnCurrent); } else -- cgit v1.1 From 59554758b155c7965dc414a16e8b35c115ad3f64 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:24:29 -0800 Subject: BulletSim: implementation of vertical attraction motor. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 103 +++++++++++++-------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 6ff8a48..d94abf4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,6 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. //Attractor properties + private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. @@ -197,9 +198,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); + m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; break; case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); + m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; break; // These are vector properties but the engine lets you use a single float value to @@ -530,12 +533,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, - m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); + m_linearMotorDecayTimescale, m_linearFrictionTimescale, + 1f); m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, - m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f); + m_angularMotorDecayTimescale, m_angularFrictionTimescale, + 1f); m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, + BSMotor.Infinite, BSMotor.InfiniteVector, + m_verticalAttractionEfficiency); + // Z goes away and we keep X and Y + m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); + m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + // m_bankingMotor = new BSVMotor("BankingMotor", ...); } @@ -829,46 +842,63 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== + // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + { + angularMotorContribution.X = 0f; + angularMotorContribution.Y = 0f; + VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + } + + // ================================================================== Vector3 verticalAttractionContribution = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... - if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) + if (m_verticalAttractionTimescale < 500) { - float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; - if (Prim.IsColliding) - VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale; + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); + m_verticalAttractionMotor.SetCurrent(verticalError); + m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); + verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); + /* + // Take a vector pointing up and convert it from world to vehicle relative coords. + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); - VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) + // is now leaning to one side (rotated around the X axis) and the Y value will + // go from zero (nearly straight up) to one (completely to the side) or leaning + // front-to-back (rotated around the Y axis) and the value of X will be between + // zero and one. + // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. - // Create a vector of the vehicle "up" in world coordinates - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; - // verticalError.X and .Y are the World error amounts. They are 0 when there is no - // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its - // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall - // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be - // modulated to prevent a stable inverted body. - - // Error is 0 (no error) to +/- 2 (max error) - verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f)); - verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f)); - - // scale it by VAservo (timestep and timescale) - verticalError = verticalError * VAservo; - - // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y - // then .X increases, so change Body angular velocity X based on Y, and Y based on X. - // Z is not changed. + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. + if (verticalError.Z < 0f) + { + verticalError.X = 2f - verticalError.X; + verticalError.Y = 2f - verticalError.Y; + } + + // Y error means needed rotation around X axis and visa versa. verticalAttractionContribution.X = verticalError.Y; verticalAttractionContribution.Y = - verticalError.X; verticalAttractionContribution.Z = 0f; - // scaling appears better usingsquare-law - Vector3 angularVelocity = Prim.ForceRotationalVelocity; - float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - verticalAttractionContribution.X += bounce * angularVelocity.X; - verticalAttractionContribution.Y += bounce * angularVelocity.Y; + // scale by the time scale and timestep + Vector3 unscaledContrib = verticalAttractionContribution; + verticalAttractionContribution /= m_verticalAttractionTimescale; + verticalAttractionContribution *= pTimestep; - VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", - Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution); + // apply efficiency + Vector3 preEfficiencyContrib = verticalAttractionContribution; + float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; + verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + + VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", + Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, + m_verticalAttractionEfficiency, efficencySquared, + verticalAttractionContribution); + */ } @@ -989,15 +1019,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // ================================================================== - // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement - if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - { - m_lastAngularVelocity.X = 0; - m_lastAngularVelocity.Y = 0; - VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); - } - - // ================================================================== if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. -- cgit v1.1 From 68fe7dff20fb38480a1c760f1347dafac43899c5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:37:06 -0800 Subject: BulletSim: reorganize angular movement routine into separate subroutines enabling external calibration routines and unit testing. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 209 +++++++++++---------- 1 file changed, 114 insertions(+), 95 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index d94abf4..eb4d06a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -317,7 +317,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_VhoverEfficiency = 0; m_VhoverTimescale = 0; m_VehicleBuoyancy = 0; - + m_linearDeflectionEfficiency = 1; m_linearDeflectionTimescale = 1; @@ -366,8 +366,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingMix = 1; m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP @@ -575,7 +575,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); - VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", + VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); } } @@ -759,13 +759,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. - VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", + VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, limitMotorUpContribution); } // ================================================================== - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + hoverContribution + limitMotorUpContribution; @@ -801,7 +801,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, newVelocity, Prim.Velocity, totalDownForce); } // end MoveLinear() @@ -850,8 +850,84 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } + Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); + + Vector3 deflectionContribution = ComputeAngularDeflection(pTimestep); + + Vector3 bankingContribution = ComputeAngularBanking(pTimestep); + + // ================================================================== + m_lastVertAttractor = verticalAttractionContribution; + + // Sum velocities + m_lastAngularVelocity = angularMotorContribution + + verticalAttractionContribution + + bankingContribution + + deflectionContribution; + + // ================================================================== + //Offset section + if (m_linearMotorOffset != Vector3.Zero) + { + //Offset of linear velocity doesn't change the linear velocity, + // but causes a torque to be applied, for example... + // + // IIIII >>> IIIII + // IIIII >>> IIIII + // IIIII >>> IIIII + // ^ + // | Applying a force at the arrow will cause the object to move forward, but also rotate + // + // + // The torque created is the linear velocity crossed with the offset + + // TODO: this computation should be in the linear section + // because that is where we know the impulse being applied. + Vector3 torqueFromOffset = Vector3.Zero; + // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); + if (float.IsNaN(torqueFromOffset.X)) + torqueFromOffset.X = 0; + if (float.IsNaN(torqueFromOffset.Y)) + torqueFromOffset.Y = 0; + if (float.IsNaN(torqueFromOffset.Z)) + torqueFromOffset.Z = 0; + torqueFromOffset *= m_vehicleMass; + Prim.ApplyTorqueImpulse(torqueFromOffset, true); + VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); + } + // ================================================================== - Vector3 verticalAttractionContribution = Vector3.Zero; + if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. + Prim.ZeroAngularMotion(true); + VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + } + else + { + // Apply to the body. + // The above calculates the absolute angular velocity needed. Angular velocity is massless. + // Since we are stuffing the angular velocity directly into the object, the computed + // velocity needs to be scaled by the timestep. + // Also remove any motion that is on the object so added motion is only from vehicle. + Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) + - Prim.ForceRotationalVelocity); + // Unscale the force by the angular factor so it overwhelmes the Bullet additions. + Prim.ForceRotationalVelocity = applyAngularForce; + + VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + applyAngularForce, m_lastAngularVelocity + ); + } + } + + public Vector3 ComputeAngularVerticalAttraction(float pTimestep) + { + Vector3 ret = Vector3.Zero; + // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { @@ -859,7 +935,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin verticalError.Normalize(); m_verticalAttractionMotor.SetCurrent(verticalError); m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); - verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); + ret = m_verticalAttractionMotor.Step(pTimestep); /* // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; @@ -895,15 +971,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", - Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, + Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, verticalAttractionContribution); */ } + return ret; + } + + public Vector3 ComputeAngularDeflection(float pTimestep) + { + Vector3 ret = Vector3.Zero; - // ================================================================== - Vector3 deflectionContribution = Vector3.Zero; if (m_angularDeflectionEfficiency != 0) { // Compute a scaled vector that points in the preferred axis (X direction) @@ -914,24 +994,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); // Scale by efficiency and timescale - deflectionContribution = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + + VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); - VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", - Prim.LocalID, preferredAxisOfMotion, deflectionContribution); // This deflection computation is not correct. - deflectionContribution = Vector3.Zero; + ret = Vector3.Zero; } + return ret; + } + + public Vector3 ComputeAngularBanking(float pTimestep) + { + Vector3 ret = Vector3.Zero; - // ================================================================== - Vector3 bankingContribution = Vector3.Zero; if (m_bankingEfficiency != 0) { Vector3 dir = Vector3.One * Prim.ForceOrientation; - float mult = (m_bankingMix*m_bankingMix)*-1*(m_bankingMix < 0 ? -1 : 1); - //Changes which way it banks in and out of turns + float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); + //Changes which way it banks in and out of turns //Use the square of the efficiency, as it looks much more how SL banking works - float effSquared = (m_bankingEfficiency*m_bankingEfficiency); + float effSquared = (m_bankingEfficiency * m_bankingEfficiency); if (m_bankingEfficiency < 0) effSquared *= -1; //Keep the negative! @@ -953,99 +1037,34 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; + ret.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; } //If they are colliding, we probably shouldn't shove the prim around... probably if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) { - float angVelZ = m_angularMotorVelocity.X*-1; + float angVelZ = m_angularMotorVelocity.X * -1; /*if(angVelZ > mix) angVelZ = mix; else if(angVelZ < -mix) angVelZ = -mix;*/ //This controls how fast and how far the banking occurs - Vector3 bankingRot = new Vector3(angVelZ*(effSquared*mult), 0, 0); + Vector3 bankingRot = new Vector3(angVelZ * (effSquared * mult), 0, 0); if (bankingRot.X > 3) bankingRot.X = 3; else if (bankingRot.X < -3) bankingRot.X = -3; bankingRot *= Prim.ForceOrientation; - bankingContribution += bankingRot; + ret += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution); - } - - // ================================================================== - m_lastVertAttractor = verticalAttractionContribution; - - // Sum velocities - m_lastAngularVelocity = angularMotorContribution - + verticalAttractionContribution - + bankingContribution - + deflectionContribution; - - // ================================================================== - //Offset section - if (m_linearMotorOffset != Vector3.Zero) - { - //Offset of linear velocity doesn't change the linear velocity, - // but causes a torque to be applied, for example... - // - // IIIII >>> IIIII - // IIIII >>> IIIII - // IIIII >>> IIIII - // ^ - // | Applying a force at the arrow will cause the object to move forward, but also rotate - // - // - // The torque created is the linear velocity crossed with the offset - - // TODO: this computation should be in the linear section - // because that is where we know the impulse being applied. - Vector3 torqueFromOffset = Vector3.Zero; - // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); - if (float.IsNaN(torqueFromOffset.X)) - torqueFromOffset.X = 0; - if (float.IsNaN(torqueFromOffset.Y)) - torqueFromOffset.Y = 0; - if (float.IsNaN(torqueFromOffset.Z)) - torqueFromOffset.Z = 0; - torqueFromOffset *= m_vehicleMass; - Prim.ApplyTorqueImpulse(torqueFromOffset, true); - VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); - } - - // ================================================================== - if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) - { - m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. - Prim.ZeroAngularMotion(true); - VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); - } - else - { - // Apply to the body. - // The above calculates the absolute angular velocity needed. Angular velocity is massless. - // Since we are stuffing the angular velocity directly into the object, the computed - // velocity needs to be scaled by the timestep. - // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - - Prim.ForceRotationalVelocity); - // Unscale the force by the angular factor so it overwhelmes the Bullet additions. - Prim.ForceRotationalVelocity = applyAngularForce; - - VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", - Prim.LocalID, - angularMotorContribution, verticalAttractionContribution, - bankingContribution, deflectionContribution, - applyAngularForce, m_lastAngularVelocity - ); + VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", + Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); } + return ret; } + // This is from previous instantiations of XXXDynamics.cs. // Applies roll reference frame. // TODO: is this the right way to separate the code to do this operation? -- cgit v1.1 From a5100cafee7e1e79f911c1e33fb1742075ca7283 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 10:01:25 -0800 Subject: BulletSim: fix terrain mesh generation for problem with regions that have unequal edge heights. Thanks UBit. --- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index d7afdeb..5f6675d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -88,9 +88,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", + ID, indicesCount, indices.Length, verticesCount, vertices.Length); m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indicesCount, indices, verticesCount, vertices), + indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); if (m_terrainShape.ptr == IntPtr.Zero) { @@ -122,10 +124,10 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Static objects are not very massive. BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); - // Return the new terrain to the world of physical objects + // Put the new terrain to the world of physical objects BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); - // redo its bounding box now that it is in the world + // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, @@ -188,6 +190,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Simple mesh creation which assumes magnification == 1. // TODO: do a more general solution that scales, adds new vertices and smoothes the result. + // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop + // from zero to <= sizeX). The triangle indices are then generated as two triangles + // per heightmap point. There are sizeX by sizeY of these squares. The extra row and + // column of vertices are used to complete the triangles of the last row and column + // of the heightmap. try { // One vertice per heightmap value plus the vertices off the top and bottom edge. @@ -200,16 +207,18 @@ public sealed class BSTerrainMesh : BSTerrainPhys float magY = (float)sizeY / extentY; physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); + float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. for (int yy = 0; yy <= sizeY; yy++) { - for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times + for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times { int offset = yy * sizeX + xx; - // Extend the height from the height from the last row or column + // Extend the height with the height from the last row or column if (yy == sizeY) offset -= sizeX; if (xx == sizeX) offset -= 1; float height = heightMap[offset]; + minHeight = Math.Min(minHeight, height); vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; @@ -222,7 +231,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys { for (int xx = 0; xx < sizeX; xx++) { - int offset = yy * sizeX + xx; + int offset = yy * (sizeX + 1) + xx; // Each vertices is presumed to be the upper left corner of a box of two triangles indices[indicesCount + 0] = offset; indices[indicesCount + 1] = offset + 1; @@ -233,6 +242,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys indicesCount += 6; } } + ret = true; } catch (Exception e) -- cgit v1.1 From 8e459a03467ffa45145f90ea764854deaf2615ed Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 10:02:29 -0800 Subject: BulletSim: reorganize linear movement routine into separate subroutines enabling external calibration routines and unit tests. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 137 ++++++++++++--------- 1 file changed, 79 insertions(+), 58 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index eb4d06a..74eb9ab 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -630,13 +630,64 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - // Current vehicle position Vector3 pos = Prim.ForcePosition; + float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); + + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep, ref pos, terrainHeight); + + Vector3 hoverContribution = ComputeLinearHover(pTimestep, ref pos, terrainHeight); + + ComputeLinearBlockingEndPoint(pTimestep, ref pos); + + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep, pos, terrainHeight); + + // ================================================================== + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + + hoverContribution + + limitMotorUpContribution; + + // If not changing some axis, reduce out velocity + if ((m_flags & (VehicleFlag.NO_X)) != 0) + newVelocity.X = 0; + if ((m_flags & (VehicleFlag.NO_Y)) != 0) + newVelocity.Y = 0; + if ((m_flags & (VehicleFlag.NO_Z)) != 0) + newVelocity.Z = 0; + + // ================================================================== + // Clamp REALLY high or low velocities + float newVelocityLengthSq = newVelocity.LengthSquared(); + if (newVelocityLengthSq > 1e6f) + { + newVelocity /= newVelocity.Length(); + newVelocity *= 1000f; + } + else if (newVelocityLengthSq < 1e-6f) + newVelocity = Vector3.Zero; // ================================================================== - Vector3 terrainHeightContribution = Vector3.Zero; + // Stuff new linear velocity into the vehicle + Prim.ForceVelocity = newVelocity; + // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG + + // Other linear forces are applied as forces. + Vector3 totalDownForce = grav * m_vehicleMass; + if (totalDownForce != Vector3.Zero) + { + Prim.AddForce(totalDownForce, false); + } + + VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, + newVelocity, Prim.Velocity, totalDownForce); + + } // end MoveLinear() + + public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep, ref Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. - float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; @@ -648,10 +699,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.ForcePosition = pos; VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); } + return ret; + } + + public Vector3 ComputeLinearHover(float pTimestep, ref Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; - // ================================================================== - Vector3 hoverContribution = Vector3.Zero; - // Check if hovering // m_VhoverEfficiency: 0=bouncy, 1=totally damped // m_VhoverTimescale: time to achieve height if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) @@ -692,24 +746,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Replace Vertical speed with correction figure if significant if (verticalError > 0.01f) { - hoverContribution = new Vector3(0f, 0f, verticalCorrectionVelocity); + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); //KF: m_VhoverEfficiency is not yet implemented } else if (verticalError < -0.01) { - hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity); + ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); } } VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", - Prim.LocalID, pos, hoverContribution, m_VhoverHeight, m_VhoverTargetHeight); + Prim.LocalID, pos, ret, m_VhoverHeight, m_VhoverTargetHeight); } - // ================================================================== + return ret; + } + + public bool ComputeLinearBlockingEndPoint(float pTimestep, ref Vector3 pos) + { + bool changed = false; + Vector3 posChange = pos - m_lastPositionVector; if (m_BlockingEndPoint != Vector3.Zero) { - bool changed = false; if (pos.X >= (m_BlockingEndPoint.X - (float)1)) { pos.X -= posChange.X + 1; @@ -742,9 +801,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.LocalID, m_BlockingEndPoint, posChange, pos); } } + return changed; + } - // ================================================================== - Vector3 limitMotorUpContribution = Vector3.Zero; + public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. @@ -753,58 +815,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - limitMotorUpContribution = new Vector3(0, 0, -distanceAboveGround); + ret = new Vector3(0, 0, -distanceAboveGround); } // TODO: this calculation is all wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", - Prim.LocalID, distanceAboveGround, limitMotorUpContribution); + Prim.LocalID, distanceAboveGround, ret); } - - // ================================================================== - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution - + hoverContribution - + limitMotorUpContribution; - - // If not changing some axis, reduce out velocity - if ((m_flags & (VehicleFlag.NO_X)) != 0) - newVelocity.X = 0; - if ((m_flags & (VehicleFlag.NO_Y)) != 0) - newVelocity.Y = 0; - if ((m_flags & (VehicleFlag.NO_Z)) != 0) - newVelocity.Z = 0; - - // ================================================================== - // Clamp REALLY high or low velocities - float newVelocityLengthSq = newVelocity.LengthSquared(); - if (newVelocityLengthSq > 1e6f) - { - newVelocity /= newVelocity.Length(); - newVelocity *= 1000f; - } - else if (newVelocityLengthSq < 1e-6f) - newVelocity = Vector3.Zero; - - // ================================================================== - // Stuff new linear velocity into the vehicle - Prim.ForceVelocity = newVelocity; - // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG - - // Other linear forces are applied as forces. - Vector3 totalDownForce = grav * m_vehicleMass; - if (totalDownForce != Vector3.Zero) - { - Prim.AddForce(totalDownForce, false); - } - - VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, - newVelocity, Prim.Velocity, totalDownForce); - - } // end MoveLinear() + return ret; + } // ======================================================================= // ======================================================================= -- cgit v1.1 From 2cd88787af52213e1f0b2d863b75e35ca83e8032 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Nov 2012 14:42:28 -0800 Subject: Prevent the core Groups module from being enabled when its name doesn't match the "default" ini choice --- OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index af54c1a..b735c61 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -81,7 +81,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups } if (groupsConfig.GetString("Module", "Default") != "Default") + { + m_Enabled = false; return; + } } } -- cgit v1.1 From c17ea2049b3027abb5bc5446a8c5b0d4985953b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Nov 2012 01:42:58 +0000 Subject: Show many more primitive properties on console command "show part name/id/pos" --- .../World/Objects/Commands/ObjectCommandsModule.cs | 60 ++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index ab8f143..7b235ae 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -365,7 +365,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part id [--full] "); + //m_console.OutputFormat("Usage: show part id [--full] "); + m_console.OutputFormat("Usage: show part id "); return; } @@ -405,6 +406,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 5) { + //m_console.OutputFormat("Usage: show part pos to "); m_console.OutputFormat("Usage: show part pos [--full] to "); return; } @@ -445,7 +447,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part name [--full] [--regex] "); + m_console.OutputFormat("Usage: show part name [--regex] "); + //m_console.OutputFormat("Usage: show part name [--full] [--regex] "); return; } @@ -577,6 +580,58 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands cdl.AddRow("Link number", sop.LinkNum); cdl.AddRow("Flags", sop.Flags); + if (showFull) + { + PrimitiveBaseShape s = sop.Shape; + cdl.AddRow("FlexiDrag", s.FlexiDrag); + cdl.AddRow("FlexiEntry", s.FlexiEntry); + cdl.AddRow("FlexiForce", string.Format("<{0},{1},{2}>", s.FlexiForceX, s.FlexiForceY, s.FlexiForceZ)); + cdl.AddRow("FlexiGravity", s.FlexiGravity); + cdl.AddRow("FlexiSoftness", s.FlexiSoftness); + cdl.AddRow("HollowShape", s.HollowShape); + cdl.AddRow( + "LightColor", + string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA)); + cdl.AddRow("FlexiDrag", s.LightCutoff); + cdl.AddRow("FlexiDrag", s.LightEntry); + cdl.AddRow("FlexiDrag", s.LightFalloff); + cdl.AddRow("FlexiDrag", s.LightIntensity); + cdl.AddRow("FlexiDrag", s.LightRadius); + cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); + cdl.AddRow("PathBegin", s.PathBegin); + cdl.AddRow("PathEnd", s.PathEnd); + cdl.AddRow("PathCurve", s.PathCurve); + cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset); + cdl.AddRow("PathRevolutions", s.PathRevolutions); + cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY)); + cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY)); + cdl.AddRow("FlexiDrag", s.PathSkew); + cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY)); + cdl.AddRow("PathTwist", s.PathTwist); + cdl.AddRow("PathTwistBegin", s.PathTwistBegin); + cdl.AddRow("PCode", s.PCode); + cdl.AddRow("ProfileBegin", s.ProfileBegin); + cdl.AddRow("ProfileEnd", s.ProfileEnd); + cdl.AddRow("ProfileHollow", s.ProfileHollow); + cdl.AddRow("ProfileShape", s.ProfileShape); + cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance); + cdl.AddRow("ProjectionEntry", s.ProjectionEntry); + cdl.AddRow("ProjectionFocus", s.ProjectionFocus); + cdl.AddRow("ProjectionFOV", s.ProjectionFOV); + cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); + cdl.AddRow("Scale", s.Scale); + cdl.AddRow( + "SculptData", + string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a")); + cdl.AddRow("SculptEntry", s.SculptEntry); + cdl.AddRow("SculptTexture", s.SculptTexture); + cdl.AddRow("SculptType", s.SculptType); + cdl.AddRow("State", s.State); + + // TODO, unpack and display texture entries + //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures. + } + object itemsOutput; if (showFull) { @@ -588,7 +643,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands itemsOutput = sop.Inventory.Count; } - cdl.AddRow("Items", itemsOutput); return sb.Append(cdl.ToString()); -- cgit v1.1 From aae76f7be4f62db230bf4750496b913b6d013eb8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Nov 2012 02:01:04 +0000 Subject: Stop logging spurious asset data for {0} is zero length error for sculpts/mesh ODEPrim, for instance, always hits this code path twice at the moment Firstly before any sculpt data has been loaded (hence the spurious message) Secondly when any sculpt data has been loaded or failed to load (when the message would be valid). Hence comment this out and rely on the message in ODEPrim.MeshAssetReceived() instead (though this is not ideal since it requires all physics plugins to copy/paste similar code). --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 5 ++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 3bd15ce..6fa91ab 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -321,7 +321,10 @@ namespace OpenSim.Region.Physics.Meshing if (primShape.SculptData.Length <= 0) { - m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); + // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this + // method twice - once before it has loaded sculpt data from the asset service and once afterwards. + // The first time will always call with unloaded SculptData if this needs to be uploaded. +// m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); return false; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 5a0b8d1..0d66496 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -3361,6 +3361,11 @@ Console.WriteLine(" JointCreateFixed"); _pbs.SculptData = new byte[asset.Data.Length]; asset.Data.CopyTo(_pbs.SculptData, 0); // m_assetFailed = false; + +// m_log.DebugFormat( +// "[ODE PRIM]: Received mesh/sculpt data asset {0} with {1} bytes for {2} at {3} in {4}", +// _pbs.SculptTexture, _pbs.SculptData.Length, Name, _position, _parent_scene.Name); + m_taintshape = true; _parent_scene.AddPhysicsActorTaint(this); } -- cgit v1.1 From 92a766e8cb38ed0cf2f778d95e192275cd4e3100 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Nov 2012 21:10:58 -0800 Subject: Bug fix in Offline IM for inventory transfers. The items were being placed twice in the receiver's inventory. --- .../Avatar/InstantMessage/OfflineMessageModule.cs | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 4aaf1fe..41364d7 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -186,17 +186,21 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage foreach (GridInstantMessage im in msglist) { - // client.SendInstantMessage(im); - - // Send through scene event manager so all modules get a chance - // to look at this message before it gets delivered. - // - // Needed for proper state management for stored group - // invitations - // - Scene s = FindScene(client.AgentId); - if (s != null) - s.EventManager.TriggerIncomingInstantMessage(im); + if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) + // send it directly or else the item will be given twice + client.SendInstantMessage(im); + else + { + // Send through scene event manager so all modules get a chance + // to look at this message before it gets delivered. + // + // Needed for proper state management for stored group + // invitations + // + Scene s = FindScene(client.AgentId); + if (s != null) + s.EventManager.TriggerIncomingInstantMessage(im); + } } } } -- cgit v1.1 From 0a66317fa6414dff9a7a4ab5bae10802e1e6693f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 28 Nov 2012 08:05:01 -0800 Subject: BulletSim: move GetWaterLevelAtXYZ from BSScene to BSPhysTerrain. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 10 ++++--- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 7 +++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 17 +++++------ .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 8 +++++- .../Physics/BulletSPlugin/BSTerrainManager.cs | 33 ++++++++++++++++++++-- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 8 +++++- 7 files changed, 63 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 4c195e1..1dfc420 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -307,7 +307,7 @@ public sealed class BSCharacter : BSPhysObject } if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { - float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); if (Position.Z < waterHeight) { _position.Z = waterHeight; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 74eb9ab..b6e3594 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -713,7 +713,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; + m_VhoverTargetHeight = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { @@ -730,6 +730,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; } + if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) { if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) @@ -883,8 +884,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Sum velocities m_lastAngularVelocity = angularMotorContribution + verticalAttractionContribution - + bankingContribution - + deflectionContribution; + + deflectionContribution + + bankingContribution; // ================================================================== //Offset section @@ -921,8 +922,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. - Prim.ZeroAngularMotion(true); + // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + Prim.ZeroAngularMotion(true); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c62c79a..3fb0300 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -253,8 +253,9 @@ public sealed class BSPrim : BSPhysObject // Zero some other properties in the physics engine PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); + BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); }); } @@ -329,7 +330,7 @@ public sealed class BSPrim : BSPhysObject if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { - float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); // TODO: a floating motor so object will bob in the water if (Math.Abs(Position.Z - waterHeight) > 0.1f) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 09b1423..0c80611 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -127,7 +127,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public const uint GROUNDPLANE_ID = 1; public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here - private float m_waterLevel; + public float SimpleWaterLevel { get; set; } public BSTerrainManager TerrainManager { get; private set; } public ConfigurationParameters Params @@ -182,6 +182,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private string m_physicsLoggingDir; private string m_physicsLoggingPrefix; private int m_physicsLoggingFileMinutes; + private bool m_physicsLoggingDoFlush; // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } @@ -290,6 +291,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); + m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); // Very detailed logging for vehicle debugging VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); @@ -494,7 +496,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters try { - if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -503,7 +505,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); - if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { @@ -634,12 +636,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public override void SetWaterLevel(float baseheight) { - m_waterLevel = baseheight; - } - // Someday.... - public float GetWaterLevelAtXYZ(Vector3 loc) - { - return m_waterLevel; + SimpleWaterLevel = baseheight; } public override void DeleteTerrain() @@ -1493,7 +1490,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { PhysicsLogging.Write(msg, args); // Add the Flush() if debugging crashes. Gets all the messages written out. - // PhysicsLogging.Flush(); + if (m_physicsLoggingDoFlush) PhysicsLogging.Flush(); } // Used to fill in the LocalID when there isn't one. It's the correct number of characters. public const string DetailLogZero = "0000000000"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 1450f66..0cb151e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -148,7 +148,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys } // The passed position is relative to the base of the region. - public override float GetHeightAtXYZ(Vector3 pos) + public override float GetTerrainHeightAtXYZ(Vector3 pos) { float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; @@ -166,5 +166,11 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys } return ret; } + + // The passed position is relative to the base of the region. + public override float GetWaterLevelAtXYZ(Vector3 pos) + { + return PhysicsScene.SimpleWaterLevel; + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index cd623f1..17d9536 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -62,7 +62,8 @@ public abstract class BSTerrainPhys : IDisposable ID = id; } public abstract void Dispose(); - public abstract float GetHeightAtXYZ(Vector3 pos); + public abstract float GetTerrainHeightAtXYZ(Vector3 pos); + public abstract float GetWaterLevelAtXYZ(Vector3 pos); } // ========================================================================================== @@ -75,6 +76,7 @@ public sealed class BSTerrainManager public const float HEIGHT_INITIALIZATION = 24.987f; public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f; public const float HEIGHT_GETHEIGHT_RET = 24.765f; + public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f; // If the min and max height are equal, we reduce the min by this // amount to make sure that a bounding box is built for the terrain. @@ -358,7 +360,7 @@ public sealed class BSTerrainManager BSTerrainPhys physTerrain; if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) { - ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); + ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ); } else { @@ -370,6 +372,33 @@ public sealed class BSTerrainManager return ret; } + public float GetWaterLevelAtXYZ(Vector3 pos) + { + float ret = WATER_HEIGHT_GETHEIGHT_RET; + + float tX = pos.X; + float tY = pos.Y; + + Vector3 terrainBaseXYZ = Vector3.Zero; + terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; + terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + + lock (m_terrains) + { + BSTerrainPhys physTerrain; + if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) + { + ret = physTerrain.GetWaterLevelAtXYZ(pos); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: region={1}, x={2}, y={3}", + LogHeader, PhysicsScene.RegionName, tX, tY); + } + } + return ret; + } + // Although no one seems to check this, I do support combining. public bool SupportsCombining() { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 5f6675d..7e93ab4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -148,7 +148,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys } } - public override float GetHeightAtXYZ(Vector3 pos) + public override float GetTerrainHeightAtXYZ(Vector3 pos) { // For the moment use the saved heightmap to get the terrain height. // TODO: raycast downward to find the true terrain below the position. @@ -169,6 +169,12 @@ public sealed class BSTerrainMesh : BSTerrainPhys return ret; } + // The passed position is relative to the base of the region. + public override float GetWaterLevelAtXYZ(Vector3 pos) + { + return PhysicsScene.SimpleWaterLevel; + } + // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). // Return 'true' if successfully created. public static bool ConvertHeightmapToMesh( -- cgit v1.1 From 24b3b4df2e1ef57c386583860e851a3e278c54cf Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 28 Nov 2012 08:10:32 -0800 Subject: BulletSim: update DLLs and SOs to remove simulator crash when calling SetInterpolationAngularVelocity. --- bin/lib32/BulletSim.dll | Bin 551424 -> 551424 bytes bin/lib32/libBulletSim.so | Bin 1707625 -> 1707601 bytes bin/lib64/BulletSim.dll | Bin 699904 -> 699904 bytes bin/lib64/libBulletSim.so | Bin 1844588 -> 1844572 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 38b11cd..3f5011a 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index f59ec97..46d40fe 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 1861d6d..27a807c 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index e9b8845..1e82b3d 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 2ccd4c130234ff16a6c31845958476c759f72245 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 28 Nov 2012 09:46:05 -0800 Subject: BulletSim: fix boats floating low by removing LIMIT_MOTOR_UP flag from TYPE_BOAT definition. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index b6e3594..3a73fba 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -445,9 +445,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_WATER_ONLY); break; case Vehicle.TYPE_AIRPLANE: @@ -805,6 +805,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin return changed; } + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // Prevent ground vehicles from motoring into the sky.This flag has a subtle effect when + // used with conjunction with banking: the strength of the banking will decay when the + // vehicle no longer experiences collisions. The decay timescale is the same as + // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering + // when they are in mid jump. + // TODO: this code is wrong. Also, what should it do for boats? public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) { Vector3 ret = Vector3.Zero; @@ -818,10 +825,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); ret = new Vector3(0, 0, -distanceAboveGround); } - // TODO: this calculation is all wrong. From the description at + // TODO: this calculation is wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. + // TODO: add interaction with banking. VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, ret); } @@ -864,7 +872,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== - // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // This flag prevents linear deflection parallel to world z-axis. This is useful + // for preventing ground vehicles with large linear deflection, like bumper cars, + // from climbing their linear deflection into the sky. + // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { angularMotorContribution.X = 0f; -- cgit v1.1 From b8a7cbb9e916f0fe47e56a35a1bf3a6001ed02d0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 08:03:30 -0800 Subject: BulletSim: reverse direction of hover correction. Removes problem with vehicles being orbited. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 3a73fba..a398b74 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -742,22 +742,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin else { float verticalError = pos.Z - m_VhoverTargetHeight; - // RA: where does the 50 come from? - float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); - // Replace Vertical speed with correction figure if significant + float verticalCorrectionVelocity = pTimestep * (verticalError / m_VhoverTimescale); + + // TODO: implement m_VhoverEfficiency if (verticalError > 0.01f) { - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); - //KF: m_VhoverEfficiency is not yet implemented + // If error is positive (we're above the target height), push down + ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); } else if (verticalError < -0.01) { - ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); } } - VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", - Prim.LocalID, pos, ret, m_VhoverHeight, m_VhoverTargetHeight); + VDetailLog("{0},MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", + Prim.LocalID, pos, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); } return ret; -- cgit v1.1 From 0cd99c74a70ddfd42c3e8325716f56bf35d4474c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 09:24:53 -0800 Subject: BulletSim: add expanded call to IMesher/Meshmerizer which enables/disables mesh caching. Since BulletSim caches and tracks the unmanaged memory version of meshes, the Meshmerizer itself does not need to cache built meshes once BulletSim has made the physical proxy mesh. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 7 +++---- OpenSim/Region/Physics/Manager/IMesher.cs | 1 + OpenSim/Region/Physics/Manager/ZeroMesher.cs | 7 ++++++- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 21 ++++++++++++++++----- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 892c34b..b94dcf6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -620,8 +620,7 @@ public sealed class BSShapeCollection : IDisposable } else { - // Pass false for physicalness as this creates some sort of bounding box which we don't need - meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, false); + meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); if (meshData != null) { @@ -694,8 +693,8 @@ public sealed class BSShapeCollection : IDisposable else { // Build a new hull in the physical world - // Pass false for physicalness as this creates some sort of bounding box which we don't need - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, false); + // Pass true for physicalness as this creates some sort of bounding box which we don't need + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); if (meshData != null) { diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 3a9ca1b..10c4bd3 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -36,6 +36,7 @@ namespace OpenSim.Region.Physics.Manager { IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); + IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache); } // Values for level of detail to be passed to the mesher. diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs index ba19db6..270d2ec 100644 --- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs +++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs @@ -64,11 +64,16 @@ namespace OpenSim.Region.Physics.Manager { public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false); + return CreateMesh(primName, primShape, size, lod, false, false); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { + return CreateMesh(primName, primShape, size, lod, false, false); + } + + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) + { // Remove the reference to the encoded JPEG2000 data so it can be GCed primShape.SculptData = OpenMetaverse.Utils.EmptyBytes; diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 6fa91ab..8145d61 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -702,11 +702,16 @@ namespace OpenSim.Region.Physics.Meshing public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false); + return CreateMesh(primName, primShape, size, lod, false, true); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { + return CreateMesh(primName, primShape, size, lod, isPhysical, true); + } + + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) + { #if SPAM m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); #endif @@ -716,9 +721,12 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - key = primShape.GetMeshKey(size, lod); - if (m_uniqueMeshes.TryGetValue(key, out mesh)) - return mesh; + if (shouldCache) + { + key = primShape.GetMeshKey(size, lod); + if (m_uniqueMeshes.TryGetValue(key, out mesh)) + return mesh; + } if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; @@ -741,7 +749,10 @@ namespace OpenSim.Region.Physics.Meshing // trim the vertex and triangle lists to free up memory mesh.TrimExcess(); - m_uniqueMeshes.Add(key, mesh); + if (shouldCache) + { + m_uniqueMeshes.Add(key, mesh); + } } return mesh; -- cgit v1.1 From 0bda35e18fdba53998d752b7ce7ef5b0580a642e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 09:53:59 -0800 Subject: BulletSim: add copyright header where it is missing. Remove some unnecessary 'using' requirements so testing framework is less complicated. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 -- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 32 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a398b74..fcee1de 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -45,9 +45,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; -using log4net; using OpenMetaverse; -using OpenSim.Framework; using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Physics.BulletSPlugin diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index e91bfa8..eca1452 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -1,3 +1,30 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * 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. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ using System; using System.Collections.Generic; using System.Text; @@ -8,7 +35,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public abstract class BSMotor { // Timescales and other things can be turned off by setting them to 'infinite'. - public const float Infinite = 10000f; + public const float Infinite = 12345f; public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); public BSMotor(string useName) @@ -19,7 +46,9 @@ public abstract class BSMotor public virtual void Reset() { } public virtual void Zero() { } + // A name passed at motor creation for easily identifyable debugging messages. public string UseName { get; private set; } + // Used only for outputting debug information. Might not be set so check for null. public BSScene PhysicsScene { get; set; } protected void MDetailLog(string msg, params Object[] parms) @@ -99,6 +128,7 @@ public class BSVMotor : BSMotor if (FrictionTimescale != BSMotor.InfiniteVector) { // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + // Individual friction components can be 'infinite' so compute each separately. frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; -- cgit v1.1 From ec63e4ff29f9983b65d76232018156605762ccc0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 22:21:45 -0800 Subject: BulletSim: remove time scaling of computed vehicle absolute velocity since Bullet will scale the movement by the time slice. Restore LIMIT_MOTOR_UP to definitition of BOAT simce some vehicle engines use it even for land vehicles. Push vehicle parameter updates through the regular property update to solve vehicles floating off when they should be stopped. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 98 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 8 ++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 15 +--- 3 files changed, 73 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fcee1de..fcc1224 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -127,6 +127,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + // Local + private float m_knownTerrainHeight; + private float m_knownWaterLevel; + public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -443,9 +447,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_WATER_ONLY); break; case Vehicle.TYPE_AIRPLANE: @@ -596,11 +600,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); } + // Since the computation of terrain height can be a little involved, this routine + // is used ot fetch the height only once for each vehicle simulation step. + private float GetTerrainHeight(Vector3 pos) + { + if (m_knownTerrainHeight == float.MinValue) + m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); + return m_knownTerrainHeight; + } + + // Since the computation of water level can be a little involved, this routine + // is used ot fetch the level only once for each vehicle simulation step. + private float GetWaterLevel(Vector3 pos) + { + if (m_knownWaterLevel == float.MinValue) + m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); + return m_knownWaterLevel; + } + // One step of the vehicle properties for the next 'pTimestep' seconds. internal void Step(float pTimestep) { if (!IsActive) return; + // zap values so they will be fetched when needed + m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; + MoveLinear(pTimestep); MoveAngular(pTimestep); @@ -609,6 +634,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; + // Force the physics engine to decide whether values have updated. + // TODO: this is only necessary if pos, velocity, ... were updated. Is it quicker + // to check for changes here or just push the update? + BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); } @@ -629,15 +659,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); Vector3 pos = Prim.ForcePosition; - float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep, ref pos, terrainHeight); + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); - Vector3 hoverContribution = ComputeLinearHover(pTimestep, ref pos, terrainHeight); + Vector3 hoverContribution = ComputeLinearHover(ref pos); - ComputeLinearBlockingEndPoint(pTimestep, ref pos); + ComputeLinearBlockingEndPoint(ref pos); - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep, pos, terrainHeight); + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pos); // ================================================================== Vector3 newVelocity = linearMotorContribution @@ -665,42 +694,40 @@ namespace OpenSim.Region.Physics.BulletSPlugin newVelocity = Vector3.Zero; // ================================================================== - // Stuff new linear velocity into the vehicle + // Stuff new linear velocity into the vehicle. + // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. Prim.ForceVelocity = newVelocity; - // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG // Other linear forces are applied as forces. - Vector3 totalDownForce = grav * m_vehicleMass; + Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; if (totalDownForce != Vector3.Zero) { Prim.AddForce(totalDownForce, false); } - VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, - newVelocity, Prim.Velocity, totalDownForce); + VDetailLog("{0},MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", + Prim.LocalID, newVelocity, totalDownForce, + linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution + ); } // end MoveLinear() - public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep, ref Vector3 pos, float terrainHeight) + public Vector3 ComputeLinearTerrainHeightCorrection(ref Vector3 pos) { Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. - // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. - // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. - // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; - // if (rotatedSize.Z < terrainHeight) - if (pos.Z < terrainHeight) + // TODO: Consider taking the rotated size of the object or possibly casting a ray. + if (pos.Z < GetTerrainHeight(pos)) { // TODO: correct position by applying force rather than forcing position. - pos.Z = terrainHeight + 2; + pos.Z = GetTerrainHeight(pos) + 2; Prim.ForcePosition = pos; - VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); + VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); } return ret; } - public Vector3 ComputeLinearHover(float pTimestep, ref Vector3 pos, float terrainHeight) + public Vector3 ComputeLinearHover(ref Vector3 pos) { Vector3 ret = Vector3.Zero; @@ -711,11 +738,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; + m_VhoverTargetHeight = GetWaterLevel(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { - m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; + m_VhoverTargetHeight = GetTerrainHeight(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) { @@ -739,16 +766,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - float verticalError = pos.Z - m_VhoverTargetHeight; - float verticalCorrectionVelocity = pTimestep * (verticalError / m_VhoverTimescale); + // Error is positive if below the target and negative if above. + float verticalError = m_VhoverTargetHeight - pos.Z; + float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; - // TODO: implement m_VhoverEfficiency - if (verticalError > 0.01f) - { - // If error is positive (we're above the target height), push down - ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); - } - else if (verticalError < -0.01) + // TODO: implement m_VhoverEfficiency correctly + if (Math.Abs(verticalError) > m_VhoverEfficiency) { ret = new Vector3(0f, 0f, verticalCorrectionVelocity); } @@ -761,7 +784,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin return ret; } - public bool ComputeLinearBlockingEndPoint(float pTimestep, ref Vector3 pos) + public bool ComputeLinearBlockingEndPoint(ref Vector3 pos) { bool changed = false; @@ -810,13 +833,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering // when they are in mid jump. // TODO: this code is wrong. Also, what should it do for boats? - public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) + public Vector3 ComputeLinearMotorUp(Vector3 pos) { Vector3 ret = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. - float distanceAboveGround = pos.Z - terrainHeight; + // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); + float distanceAboveGround = pos.Z - GetTerrainHeight(pos); if (distanceAboveGround > 1f) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); @@ -933,7 +957,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); Prim.ZeroAngularMotion(true); } else @@ -948,7 +972,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Unscale the force by the angular factor so it overwhelmes the Bullet additions. Prim.ForceRotationalVelocity = applyAngularForce; - VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index eca1452..b256887 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -101,6 +101,14 @@ public class BSVMotor : BSMotor { TargetValue = target; } + + // A form of stepping that does not take the time quantum into account. + // The caller must do the right thing later. + public Vector3 Step() + { + return Step(1f); + } + public Vector3 Step(float timeStep) { Vector3 returnCurrent = Vector3.Zero; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 3fb0300..54b4167 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -348,7 +348,9 @@ public sealed class BSPrim : BSPhysObject if (ret) { // Apply upforce and overcome gravity. - AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime); + OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; + DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); + AddForce(correctionForce, false, inTaintTime); } return ret; } @@ -839,15 +841,6 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 RotationalVelocity { get { - /* - OMV.Vector3 pv = OMV.Vector3.Zero; - // if close to zero, report zero - // This is copied from ODE but I'm not sure why it returns zero but doesn't - // zero the property in the physics engine. - if (_rotationalVelocity.ApproxEquals(pv, 0.2f)) - return pv; - */ - return _rotationalVelocity; } set { @@ -1409,7 +1402,7 @@ public sealed class BSPrim : BSPhysObject LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; + OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); -- cgit v1.1 From b124aae05e6aeca02f692a7a5d96569b804612bd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 1 Dec 2012 15:39:13 -0800 Subject: BulletSim: Add DumpActivationInfo2 function. Change static objects from DISABLE_SIMULATION to ISLAND_SLEEPING. Update DLLs and SOs to add DumpActivationInfo2 function. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 ++++++------ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 ++ .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 7 +++++-- bin/lib32/BulletSim.dll | Bin 551424 -> 551936 bytes bin/lib32/libBulletSim.so | Bin 1707601 -> 1708712 bytes bin/lib64/BulletSim.dll | Bin 699904 -> 700928 bytes bin/lib64/libBulletSim.so | Bin 1844572 -> 1846041 bytes 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fcc1224..15a40fe 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -623,7 +623,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; - // zap values so they will be fetched when needed + // Zap values so they will be fetched if needed m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; MoveLinear(pTimestep); @@ -634,8 +634,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; - // Force the physics engine to decide whether values have updated. - // TODO: this is only necessary if pos, velocity, ... were updated. Is it quicker + // Force the physics engine to decide whether values were updated. + // TODO: this is only necessary if pos, velocity, etc were updated. Is it quicker // to check for changes here or just push the update? BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); @@ -643,13 +643,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); } - // Apply the effect of the linear motor. - // Also does hover and float. + // Apply the effect of the linear motor and other linear motions (like hover and float). private void MoveLinear(float pTimestep) { Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); - // Rotate new object velocity from vehicle relative to world coordinates + // The movement computed in the linear motor is relative to the vehicle + // coordinates. Rotate the movement to world coordinates. linearMotorContribution *= Prim.ForceOrientation; // ================================================================== diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 54b4167..42a362f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -687,9 +687,9 @@ public sealed class BSPrim : BSPhysObject // There can be special things needed for implementing linksets Linkset.MakeStatic(this); // The activation state is 'disabled' so Bullet will not try to act on it. - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); // Start it out sleeping and physical actions could wake it up. - // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 0c80611..5e70a23 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -971,6 +971,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Should handle fetching the right type from the ini file and converting it. // -- a delegate for getting the value as a float // -- a delegate for setting the value from a float + // -- an optional delegate to update the value in the world. Most often used to + // push the new value to an in-world object. // // The single letter parameters for the delegates are: // s = BSScene diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 1e003e6..21bc6a3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -1007,13 +1007,16 @@ public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpAllInfo2(IntPtr sim); +public static extern void DumpActivationInfo2(IntPtr sim); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); +public static extern void DumpAllInfo2(IntPtr sim); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DumpPhysicsStatistics2(IntPtr sim); diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 3f5011a..c3dde8e 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 46d40fe..98bd655 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 27a807c..9c90924 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 1e82b3d..4301d34 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 20c3ec7d9277997d9510f5d08df6a0523faaa31e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 1 Dec 2012 18:03:32 -0800 Subject: BulletSim: localize vehicle property setting so the vehicle prim is only updated at the end of the vehicle simulation step and the push of the physics property update event only happens if the properties are actually changed. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 161 ++++++++++++++++----- 1 file changed, 128 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 15a40fe..9749429 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -127,10 +127,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. - // Local - private float m_knownTerrainHeight; - private float m_knownWaterLevel; - public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -560,9 +556,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (IsActive) { + // Remember the mass so we don't have to fetch it every step m_vehicleMass = Prim.Linkset.LinksetMass; - // Friction effects are handled by this vehicle code + // Friction affects are handled by this vehicle code float friction = 0f; BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); @@ -600,31 +597,130 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); } + #region Known vehicle value functions + private int m_knownChanged; + private float? m_knownTerrainHeight; + private float? m_knownWaterLevel; + + private Vector3? m_knownPosition; + private Vector3? m_knownVelocity; + private Quaternion? m_knownOrientation; + private Vector3? m_knownRotationalVelocity; + + private const int m_knownChangedPosition = 1 << 0; + private const int m_knownChangedVelocity = 1 << 1; + private const int m_knownChangedOrientation = 1 << 2; + private const int m_knownChangedRotationalVelocity = 1 << 3; + + private void ForgetKnownVehicleProperties() + { + m_knownTerrainHeight = null; + m_knownWaterLevel = null; + m_knownPosition = null; + m_knownVelocity = null; + m_knownOrientation = null; + m_knownRotationalVelocity = null; + m_knownChanged = 0; + } + private void PushKnownChanged() + { + if (m_knownChanged != 0) + { + if ((m_knownChanged & m_knownChangedPosition) != 0) Prim.ForcePosition = VehiclePosition; + if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation; + if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity; + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + // If we set one of the values (ie, the physics engine doesn't do it) we must make sure there + // is an UpdateProperties event to send the changes up to the simulator. + BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + } + } + // Since the computation of terrain height can be a little involved, this routine // is used ot fetch the height only once for each vehicle simulation step. private float GetTerrainHeight(Vector3 pos) { - if (m_knownTerrainHeight == float.MinValue) + if (m_knownTerrainHeight == null) m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - return m_knownTerrainHeight; + return (float)m_knownTerrainHeight; } // Since the computation of water level can be a little involved, this routine // is used ot fetch the level only once for each vehicle simulation step. private float GetWaterLevel(Vector3 pos) { - if (m_knownWaterLevel == float.MinValue) + if (m_knownWaterLevel == null) m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); - return m_knownWaterLevel; + return (float)m_knownWaterLevel; + } + + private Vector3 VehiclePosition + { + get + { + if (m_knownPosition == null) + m_knownPosition = Prim.ForcePosition; + return (Vector3)m_knownPosition; + } + set + { + m_knownPosition = value; + m_knownChanged |= m_knownChangedPosition; + } + } + + private Quaternion VehicleOrientation + { + get + { + if (m_knownOrientation == null) + m_knownOrientation = Prim.ForceOrientation; + return (Quaternion)m_knownOrientation; + } + set + { + m_knownOrientation = value; + m_knownChanged |= m_knownChangedOrientation; + } + } + + private Vector3 VehicleVelocity + { + get + { + if (m_knownVelocity == null) + m_knownVelocity = Prim.ForceVelocity; + return (Vector3)m_knownVelocity; + } + set + { + m_knownVelocity = value; + m_knownChanged |= m_knownChangedVelocity; + } + } + + private Vector3 VehicleRotationalVelocity + { + get + { + if (m_knownRotationalVelocity == null) + m_knownRotationalVelocity = Prim.ForceRotationalVelocity; + return (Vector3)m_knownRotationalVelocity; + } + set + { + m_knownRotationalVelocity = value; + m_knownChanged |= m_knownChangedRotationalVelocity; + } } + #endregion // Known vehicle value functions // One step of the vehicle properties for the next 'pTimestep' seconds. internal void Step(float pTimestep) { if (!IsActive) return; - // Zap values so they will be fetched if needed - m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; + ForgetKnownVehicleProperties(); MoveLinear(pTimestep); MoveAngular(pTimestep); @@ -632,15 +728,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin LimitRotation(pTimestep); // remember the position so next step we can limit absolute movement effects - m_lastPositionVector = Prim.ForcePosition; + m_lastPositionVector = VehiclePosition; - // Force the physics engine to decide whether values were updated. - // TODO: this is only necessary if pos, velocity, etc were updated. Is it quicker - // to check for changes here or just push the update? - BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + // If we forced the changing of some vehicle parameters, update the values and + // for the physics engine to note the changes so an UpdateProperties event will happen. + PushKnownChanged(); VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", - Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); + Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); } // Apply the effect of the linear motor and other linear motions (like hover and float). @@ -650,7 +745,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The movement computed in the linear motor is relative to the vehicle // coordinates. Rotate the movement to world coordinates. - linearMotorContribution *= Prim.ForceOrientation; + linearMotorContribution *= VehicleOrientation; // ================================================================== // Gravity and Buoyancy @@ -658,7 +753,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - Vector3 pos = Prim.ForcePosition; + Vector3 pos = VehiclePosition; Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); @@ -696,7 +791,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Stuff new linear velocity into the vehicle. // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. - Prim.ForceVelocity = newVelocity; + VehicleVelocity = newVelocity; // Other linear forces are applied as forces. Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; @@ -721,7 +816,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // TODO: correct position by applying force rather than forcing position. pos.Z = GetTerrainHeight(pos) + 2; - Prim.ForcePosition = pos; + VehiclePosition = pos; VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); } return ret; @@ -761,7 +856,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) { pos.Z = m_VhoverTargetHeight; - Prim.ForcePosition = pos; + VehiclePosition = pos; } } else @@ -818,7 +913,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } if (changed) { - Prim.ForcePosition = pos; + VehiclePosition = pos; VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", Prim.LocalID, m_BlockingEndPoint, posChange, pos); } @@ -958,6 +1053,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VehicleRotationalVelocity = Vector3.Zero; Prim.ZeroAngularMotion(true); } else @@ -967,10 +1063,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since we are stuffing the angular velocity directly into the object, the computed // velocity needs to be scaled by the timestep. // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - - Prim.ForceRotationalVelocity); + Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); // Unscale the force by the angular factor so it overwhelmes the Bullet additions. - Prim.ForceRotationalVelocity = applyAngularForce; + VehicleRotationalVelocity = applyAngularForce; VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", Prim.LocalID, @@ -988,14 +1083,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); m_verticalAttractionMotor.SetCurrent(verticalError); m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); ret = m_verticalAttractionMotor.Step(pTimestep); /* // Take a vector pointing up and convert it from world to vehicle relative coords. - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) @@ -1048,7 +1143,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. - Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); + Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(VehicleOrientation, m_referenceFrame); // Scale by efficiency and timescale ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; @@ -1067,7 +1162,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (m_bankingEfficiency != 0) { - Vector3 dir = Vector3.One * Prim.ForceOrientation; + Vector3 dir = Vector3.One * VehicleOrientation; float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); //Changes which way it banks in and out of turns @@ -1111,7 +1206,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin bankingRot.X = 3; else if (bankingRot.X < -3) bankingRot.X = -3; - bankingRot *= Prim.ForceOrientation; + bankingRot *= VehicleOrientation; ret += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; @@ -1128,7 +1223,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Should this be in MoveAngular()? internal void LimitRotation(float timestep) { - Quaternion rotq = Prim.ForceOrientation; + Quaternion rotq = VehicleOrientation; Quaternion m_rot = rotq; if (m_RollreferenceFrame != Quaternion.Identity) { @@ -1156,7 +1251,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } if (rotq != m_rot) { - Prim.ForceOrientation = m_rot; + VehicleOrientation = m_rot; VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); } -- cgit v1.1 From f9fed421fed75d2494fe55c6b153f59232e2c796 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 1 Dec 2012 18:06:39 -0800 Subject: BulletSim: format vehicle detail logging messages so vehicle changs are grouped better in the log output. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 28 +++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 6 ++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 9749429..cbad3bf 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -800,7 +800,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.AddForce(totalDownForce, false); } - VDetailLog("{0},MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", Prim.LocalID, newVelocity, totalDownForce, linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution ); @@ -817,7 +817,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: correct position by applying force rather than forcing position. pos.Z = GetTerrainHeight(pos) + 2; VehiclePosition = pos; - VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); } return ret; } @@ -872,7 +872,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - VDetailLog("{0},MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", + VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", Prim.LocalID, pos, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); } @@ -914,7 +914,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (changed) { VehiclePosition = pos; - VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", + VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", Prim.LocalID, m_BlockingEndPoint, posChange, pos); } } @@ -947,7 +947,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // has a decay factor. This says this force should // be computed with a motor. // TODO: add interaction with banking. - VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, ret); } return ret; @@ -977,7 +977,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // decay requested direction m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); - VDetailLog("{0},MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", + VDetailLog("{0}, MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); } else @@ -998,7 +998,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { angularMotorContribution.X = 0f; angularMotorContribution.Y = 0f; - VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); @@ -1044,7 +1044,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin torqueFromOffset.Z = 0; torqueFromOffset *= m_vehicleMass; Prim.ApplyTorqueImpulse(torqueFromOffset, true); - VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); + VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } // ================================================================== @@ -1052,7 +1052,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VDetailLog("{0}, MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); VehicleRotationalVelocity = Vector3.Zero; Prim.ZeroAngularMotion(true); } @@ -1067,7 +1067,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Unscale the force by the angular factor so it overwhelmes the Bullet additions. VehicleRotationalVelocity = applyAngularForce; - VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + VDetailLog("{0}, MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, @@ -1122,7 +1122,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, verticalAttractionContribution); @@ -1148,7 +1148,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Scale by efficiency and timescale ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; - VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); + VDetailLog("{0}, MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); // This deflection computation is not correct. ret = Vector3.Zero; @@ -1210,7 +1210,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin ret += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", + VDetailLog("{0}, MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); } return ret; @@ -1252,7 +1252,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (rotq != m_rot) { VehicleOrientation = m_rot; - VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); + VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index b256887..e9f1549 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -143,12 +143,12 @@ public class BSVMotor : BSMotor CurrentValue *= (Vector3.One - frictionFactor); } - MDetailLog("{0},BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, TimeScale, addAmount, TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor); - MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, addAmount, decayFactor, frictionFactor, returnCurrent); } @@ -158,7 +158,7 @@ public class BSVMotor : BSMotor CurrentValue = Vector3.Zero; TargetValue = Vector3.Zero; - MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", + MDetailLog("{0}, BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); } -- cgit v1.1 From 10fcc70b36aa1b38cd92e9c4d9c441e4c0eeb5f6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 20:07:05 -0800 Subject: BulletSim: revert angular vertical attraction from motor to code. The motor code did not return the restoring difference but the current value. Remove unused commented out code. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 66 +++++++--------------- 1 file changed, 19 insertions(+), 47 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index cbad3bf..4d067cf 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,7 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin //Attractor properties private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); private float m_verticalAttractionEfficiency = 1.0f; // damped - private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + private float m_verticalAttractionTimescale = 600f; // Timescale > 500 means no vert attractor. public BSDynamics(BSScene myScene, BSPrim myPrim) { @@ -573,6 +573,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Vector3 localInertia = new Vector3(1f, 1f, 1f); Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); + BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); @@ -958,34 +959,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Apply the effect of the angular motor. private void MoveAngular(float pTimestep) { - // m_angularMotorDirection // angular velocity requested by LSL motor - // m_angularMotorVelocity // current angular motor velocity (ramps up and down) - // m_angularMotorTimescale // motor angular velocity ramp up time - // m_angularMotorDecayTimescale // motor angular velocity decay rate - // m_angularFrictionTimescale // body angular velocity decay rate - // m_lastAngularVelocity // what was last applied to body - - /* - if (m_angularMotorDirection.LengthSquared() > 0.0001) - { - Vector3 origVel = m_angularMotorVelocity; - Vector3 origDir = m_angularMotorDirection; - - // new velocity += error / ( time to get there / step interval) - // requested direction - current vehicle direction - m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); - // decay requested direction - m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); - - VDetailLog("{0}, MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", - Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); - } - else - { - m_angularMotorVelocity = Vector3.Zero; - } - */ - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== @@ -1050,9 +1023,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { - m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0}, MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); VehicleRotationalVelocity = Vector3.Zero; Prim.ZeroAngularMotion(true); } @@ -1063,15 +1035,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since we are stuffing the angular velocity directly into the object, the computed // velocity needs to be scaled by the timestep. // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); - // Unscale the force by the angular factor so it overwhelmes the Bullet additions. - VehicleRotationalVelocity = applyAngularForce; + Vector3 setAngularVelocity = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); + VehicleRotationalVelocity = setAngularVelocity; - VDetailLog("{0}, MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},setAngVelocity={6}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, - applyAngularForce, m_lastAngularVelocity + m_lastAngularVelocity, setAngularVelocity ); } } @@ -1083,12 +1054,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { + /* Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); m_verticalAttractionMotor.SetCurrent(verticalError); m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); ret = m_verticalAttractionMotor.Step(pTimestep); - /* + */ // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); @@ -1108,25 +1080,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // Y error means needed rotation around X axis and visa versa. - verticalAttractionContribution.X = verticalError.Y; - verticalAttractionContribution.Y = - verticalError.X; - verticalAttractionContribution.Z = 0f; + ret.X = verticalError.Y; + ret.Y = - verticalError.X; + ret.Z = 0f; // scale by the time scale and timestep - Vector3 unscaledContrib = verticalAttractionContribution; - verticalAttractionContribution /= m_verticalAttractionTimescale; - verticalAttractionContribution *= pTimestep; + Vector3 unscaledContrib = ret; + ret /= m_verticalAttractionTimescale; + ret *= pTimestep; // apply efficiency - Vector3 preEfficiencyContrib = verticalAttractionContribution; + Vector3 preEfficiencyContrib = ret; + // Effenciency squared seems to give a more realistic effect float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + ret *= efficencySquared; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, - verticalAttractionContribution); - */ + ret); } return ret; -- cgit v1.1 From dc0497c1b831b3bb8fe021d48520bbff7305ce2e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 20:08:11 -0800 Subject: BulletSim: begin tracking a TODO list. There just are so many things to remember to do. --- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt new file mode 100755 index 0000000..cf112fb --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -0,0 +1,112 @@ +CRASHES +================================================= +20121129.1411: editting/moving phys object across region boundries causes crash + getPos-> btRigidBody::upcast -> getBodyType -> BOOM +20121128.1600: mesh object not rezzing (no physics mesh). + Causes many errors. Doesn't stop after first error with box shape. + Eventually crashes when deleting the object. + +BULLETSIM TODO LIST: +================================================= +Neb car jiggling left and right +Vehicles (Move smoothly) +Light cycle falling over when driving +Light cycle not banking +Do single prim vehicles don't seem to properly vehiclize. +Gun sending shooter flying +Collision margin (gap between physical objects lying on each other) +Boundry checking (crashes related to crossing boundry) + Add check for border edge position for avatars and objects. + Verify the events are created for border crossings. +Avatar rotation (check out changes to ScenePresence for physical rotation) +Avatar running (what does phys engine need to do?) +Small physical objects do not interact correctly + Create chain of .5x.5x.1 torui and make all but top physical so to hang. + The chain will fall apart and pairs will dance around on ground + Chains of 1x1x.2 will stay connected but will dance. + Chains above 2x2x.4 are move stable and get stablier as torui get larger. +Add material type linkage and input all the material property definitions. + Skeleton classes and table are in the sources but are not filled or used. + +After getting off a vehicle, the root prim is phantom (can be walked through) + Need to force a position update for the root prim after compound shape destruction +Find/remove avatar collision with ID=0. +Test avatar walking up stairs. How does compare with SL. + Radius of the capsule affects ability to climb edges. +Tune terrain/object friction to be closer to SL. +Debounce avatar contact so legs don't keep folding up when standing. +Implement LSL physics controls. Like STATUS_ROTATE_X. +Add border extensions to terrain to help region crossings and objects leaving region. +Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) + +Speed up creation of large physical linksets + For instance, sitting in Neb's car (130 prims) takes several seconds to become physical +Performance test with lots of avatars. Can BulletSim support a thousand? +Optimize collisions in C++: only send up to the object subscribed to collisions. + Use collision subscription and remove the collsion(A,B) and collision(B,A) +Check wheter SimMotionState needs large if statement (see TODO). + +Implement 'top colliders' info. +Avatar jump +Implement meshes or just verify that they work. +Do prim hash codes work for sculpties and meshes? +Performance measurement and changes to make quicker. +Implement detailed physics stats (GetStats()). + +Eliminate collisions between objects in a linkset. (LinksetConstraint) + Have UserPointer point to struct with localID and linksetID? + Objects in original linkset still collide with each other? + +Measure performance improvement from hulls +Test not using ghost objects for volume detect implementation. +Performance of closures and delegates for taint processing + Are there faster ways? + Is any slowdown introduced by the existing implementation significant? +Is there are more efficient method of implementing pre and post step actions? + See http://www.codeproject.com/Articles/29922/Weak-Events-in-C + +Package Bullet source mods for Bullet internal stats output + +Physics Arena central pyramid: why is one side permiable? + +INTERNAL IMPROVEMENT/CLEANUP +================================================= +Remove unused fields from ShapeData (not used in API2) +Breakout code for mesh/hull/compound/native into separate BSShape* classes + Standardize access to building and reference code. + The skeleton classes are in the sources but are not complete or linked in. +Generalize Dynamics and PID with standardized motors. +Generalize Linkset and vehicles into PropertyManagers + Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies + Possibly generalized a 'per step action' registration. +Implement linkset by setting position of children when root updated. (LinksetManual) +LinkablePrim class? Would that simplify/centralize the linkset logic? +Linkset implementation using manual prim movement. +Linkset implementation using compound shapes. + Compound shapes will need the LocalID in the shapes and collision + processing to get it from there. +BSScene.UpdateParameterSet() is broken. How to set params on objects? +Remove HeightmapInfo from terrain specification. + Since C++ code does not need terrain height, this structure et al are not needed. +Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will + bob at the water level. BSPrim.PositionSanityCheck(). + +DONE DONE DONE DONE +================================================= +Cleanup code in BSDynamics by using motors. +Consider implementing terrain with a mesh rather than heightmap. + Would have better and adjustable resolution. +NOTDONE: Build terrain mesh so heighmap is height of the center of the square meter. + SL and ODE define meter square as being at one corner with one diagional. +Terrain as mesh. +How are static linksets seen by the physics engine? + A: they are not linked in physics. When moved, all the children are repositioned. +Remember to remove BSScene.DetailLog Refresh call. +Convert BSCharacter to use all API2 +Avatar pushing difficult (too heavy?) +Use asset service passed to BulletSim to get sculptie bodies, etc. +Vehicles (fix bouncing on terrain) +Remove old code in DLL (all non-API2 stuff). +Measurements of mega-physical prim performance (with graph) +Debug Bullet internal stats output (why is timing all wrong?) + Bullet stats logging only works with a single instance of Bullet (one region). \ No newline at end of file -- cgit v1.1 From 2586bab2dde141c4d01c81c54291394ba07b1ee7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 20:45:46 -0800 Subject: BulletSim: add stubs for generalization of preStep actions. Will eventually replace the specialized vehicle processing with preStep event processing. Add TODO comments about this feature. Redo line endings in TODO file to be all Linux. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 19 +++++++++++++++++-- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 6 +++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 5e70a23..17cc7b4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -96,6 +96,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public long SimulationStep { get { return m_simulationStep; } } private int m_taintsToProcessPerStep; + public delegate void PreStepAction(float timeStep); + public event PreStepAction BeforeStep; + // A value of the time now so all the collision and update routines do not have to get their own // Set to 'now' just before all the prims and actors are called for collisions and updates public int SimulationNowTime { get; private set; } @@ -487,8 +490,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessTaints(); // Some of the prims operate with special vehicle properties - ProcessVehicles(timeStep); - ProcessTaints(); // the vehicles might have added taints + DoPreStepActions(timeStep); + + // the prestep actions might have added taints + ProcessTaints(); // step the physical world one interval m_simulationStep++; @@ -907,6 +912,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } + private void DoPreStepActions(float timeStep) + { + ProcessVehicles(timeStep); + + PreStepAction actions = BeforeStep; + if (actions != null) + actions(timeStep); + + } + // Some prims have extra vehicle actions // Called at taint time! private void ProcessVehicles(float timeStep) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index cf112fb..ca71313 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -27,6 +27,7 @@ Small physical objects do not interact correctly Chains above 2x2x.4 are move stable and get stablier as torui get larger. Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. +Add PID motor for avatar movement (slow to stop, ...) After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction @@ -78,7 +79,10 @@ Breakout code for mesh/hull/compound/native into separate BSShape* classes Generalize Dynamics and PID with standardized motors. Generalize Linkset and vehicles into PropertyManagers Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies - Possibly generalized a 'per step action' registration. + Possibly generalized a 'pre step action' registration. +Complete implemention of preStepActions + Replace vehicle step call with prestep event. + Is there a need for postStepActions? postStepTaints? Implement linkset by setting position of children when root updated. (LinksetManual) LinkablePrim class? Would that simplify/centralize the linkset logic? Linkset implementation using manual prim movement. -- cgit v1.1 From 41f1c5b7f712ed9c093ce421b39460c7711aece4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 23:39:17 -0800 Subject: BulletSim: rework angular corrections to remove any hybrid code and compute absolute collections. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 204 ++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 17 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 1 + 4 files changed, 115 insertions(+), 111 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 4d067cf..525aac4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate - private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + private Vector3 m_lastAngularCorrection = Vector3.Zero; private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body //Deflection properties @@ -111,6 +111,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_bankingEfficiency = 0; private float m_bankingMix = 0; private float m_bankingTimescale = 0; + private Vector3 m_lastBanking = Vector3.Zero; //Hover and Buoyancy properties private float m_VhoverHeight = 0f; @@ -152,7 +153,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - m_angularMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); + m_angularMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; break; case Vehicle.ANGULAR_MOTOR_TIMESCALE: @@ -240,9 +241,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.ANGULAR_MOTOR_DIRECTION: // Limit requested angular speed to 2 rps= 4 pi rads/sec - pValue.X = Math.Max(-12.56f, Math.Min(pValue.X, 12.56f)); - pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); - pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); + pValue.X = ClampInRange(-12.56f, pValue.X, 12.56f); + pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); + pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); m_angularMotor.SetTarget(m_angularMotorDirection); break; @@ -328,6 +329,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 1000; m_bankingMix = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags = (VehicleFlag)0; @@ -362,6 +364,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 10; m_bankingMix = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -400,6 +403,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.2f; m_bankingMix = 1; m_bankingTimescale = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -438,6 +442,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.3f; m_bankingMix = 0.8f; m_bankingTimescale = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY @@ -476,6 +481,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 1; m_bankingMix = 0.7f; m_bankingTimescale = 2; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -514,6 +520,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingMix = 0.7f; m_bankingTimescale = 5; + m_lastBanking = Vector3.Zero; + m_referenceFrame = Quaternion.Identity; m_referenceFrame = Quaternion.Identity; @@ -627,12 +635,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (m_knownChanged != 0) { - if ((m_knownChanged & m_knownChangedPosition) != 0) Prim.ForcePosition = VehiclePosition; - if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation; - if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity; - if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) Prim.ForceRotationalVelocity = VehicleRotationalVelocity; - // If we set one of the values (ie, the physics engine doesn't do it) we must make sure there - // is an UpdateProperties event to send the changes up to the simulator. + if ((m_knownChanged & m_knownChangedPosition) != 0) + Prim.ForcePosition = VehiclePosition; + if ((m_knownChanged & m_knownChangedOrientation) != 0) + Prim.ForceOrientation = VehicleOrientation; + if ((m_knownChanged & m_knownChangedVelocity) != 0) + Prim.ForceVelocity = VehicleVelocity; + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) + Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + // If we set one of the values (ie, the physics engine didn't do it) we must force + // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); } } @@ -957,9 +969,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. + // The 'contribution' is how much angular correction each function wants. + // All the contributions are added together and the orientation of the vehicle + // is changed by all the contributed corrections. private void MoveAngular(float pTimestep) { - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + Vector3 angularMotorContribution = m_angularMotor.Step(); // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -974,22 +989,41 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } - Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); + Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(); - Vector3 deflectionContribution = ComputeAngularDeflection(pTimestep); + Vector3 deflectionContribution = ComputeAngularDeflection(); - Vector3 bankingContribution = ComputeAngularBanking(pTimestep); + Vector3 bankingContribution = ComputeAngularBanking(angularMotorContribution.Z); // ================================================================== m_lastVertAttractor = verticalAttractionContribution; - // Sum velocities - m_lastAngularVelocity = angularMotorContribution + // Sum corrections + m_lastAngularCorrection = angularMotorContribution + verticalAttractionContribution + deflectionContribution + bankingContribution; // ================================================================== + // The correction is applied to the current orientation. + // Any angular velocity on the vehicle is not us so zero the current value. + VehicleRotationalVelocity = Vector3.Zero; + if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) + { + Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; + Quaternion quatCorrection = Quaternion.CreateFromEulers(scaledCorrection); + + VehicleOrientation = Quaternion.Add(VehicleOrientation, quatCorrection); + + VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + m_lastAngularCorrection, scaledCorrection + ); + } + + // ================================================================== //Offset section if (m_linearMotorOffset != Vector3.Zero) { @@ -1020,50 +1054,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } - // ================================================================== - if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) - { - // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); - VehicleRotationalVelocity = Vector3.Zero; - Prim.ZeroAngularMotion(true); - } - else - { - // Apply to the body. - // The above calculates the absolute angular velocity needed. Angular velocity is massless. - // Since we are stuffing the angular velocity directly into the object, the computed - // velocity needs to be scaled by the timestep. - // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 setAngularVelocity = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); - VehicleRotationalVelocity = setAngularVelocity; - - VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},setAngVelocity={6}", - Prim.LocalID, - angularMotorContribution, verticalAttractionContribution, - bankingContribution, deflectionContribution, - m_lastAngularVelocity, setAngularVelocity - ); - } } - public Vector3 ComputeAngularVerticalAttraction(float pTimestep) + public Vector3 ComputeAngularVerticalAttraction() { Vector3 ret = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { - /* - Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - verticalError.Normalize(); - m_verticalAttractionMotor.SetCurrent(verticalError); - m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); - ret = m_verticalAttractionMotor.Step(pTimestep); - */ // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - verticalError.Normalize(); + // verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) // is now leaning to one side (rotated around the X axis) and the Y value will @@ -1087,56 +1089,63 @@ namespace OpenSim.Region.Physics.BulletSPlugin // scale by the time scale and timestep Vector3 unscaledContrib = ret; ret /= m_verticalAttractionTimescale; - ret *= pTimestep; + // This returns the angular correction desired. Timestep is added later. + // ret *= pTimestep; // apply efficiency Vector3 preEfficiencyContrib = ret; + // TODO: implement efficiency. // Effenciency squared seems to give a more realistic effect float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - ret *= efficencySquared; + // ret *= efficencySquared; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, ret); - } return ret; } - public Vector3 ComputeAngularDeflection(float pTimestep) + // Return the angular correction to correct the direction the vehicle is pointing to be + // the direction is should want to be pointing. + public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; if (m_angularDeflectionEfficiency != 0) { - // Compute a scaled vector that points in the preferred axis (X direction) - Vector3 scaledDefaultDirection = - new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); - // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. - // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. - Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(VehicleOrientation, m_referenceFrame); + // Where the vehicle should want to point relative to the vehicle + Vector3 preferredDirection = Vector3.UnitX * m_referenceFrame; + + // Where the vehicle is pointing relative to the vehicle. + Vector3 currentDirection = Vector3.UnitX * Quaternion.Add(VehicleOrientation, m_referenceFrame); - // Scale by efficiency and timescale - ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + // Difference between where vehicle is pointing and where it should wish to point + Vector3 directionCorrection = preferredDirection - currentDirection; - VDetailLog("{0}, MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); + // Scale the correction by recovery timescale and efficiency + ret = directionCorrection * m_angularDeflectionEfficiency / m_angularDeflectionTimescale; - // This deflection computation is not correct. - ret = Vector3.Zero; + VDetailLog("{0}, MoveAngular,Deflection,perfDir={1},currentDir={2},dirCorrection={3},ret={4}", + Prim.LocalID, preferredDirection, currentDirection, directionCorrection, ret); } return ret; } - public Vector3 ComputeAngularBanking(float pTimestep) + // Return an angular change to tip the vehicle (around X axis) when turning (turned around Z). + // Remembers the last banking value calculated and returns the difference needed this tick. + // TurningFactor is rate going left or right (pos=left, neg=right, scale=0..1). + public Vector3 ComputeAngularBanking(float turningFactor) { Vector3 ret = Vector3.Zero; + Vector3 computedBanking = Vector3.Zero; if (m_bankingEfficiency != 0) { - Vector3 dir = Vector3.One * VehicleOrientation; + Vector3 currentDirection = Vector3.UnitX * VehicleOrientation; + float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); - //Changes which way it banks in and out of turns //Use the square of the efficiency, as it looks much more how SL banking works float effSquared = (m_bankingEfficiency * m_bankingEfficiency); @@ -1144,51 +1153,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin effSquared *= -1; //Keep the negative! float mix = Math.Abs(m_bankingMix); - if (m_angularMotorVelocity.X == 0) - { - // The vehicle is stopped - /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) - { - Vector3 axisAngle; - float angle; - parent.Orientation.GetAxisAngle(out axisAngle, out angle); - Vector3 rotatedVel = parent.Velocity * parent.Orientation; - if ((rotatedVel.X < 0 && axisAngle.Y > 0) || (rotatedVel.X > 0 && axisAngle.Y < 0)) - m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (1f) * 10; - else - m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (-1f) * 10; - }*/ - } - else - { - ret.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; - } + // TODO: Must include reference frame. + float forwardSpeed = VehicleVelocity.X; - //If they are colliding, we probably shouldn't shove the prim around... probably - if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) + if (!Prim.IsColliding && forwardSpeed > mix) { - float angVelZ = m_angularMotorVelocity.X * -1; - /*if(angVelZ > mix) - angVelZ = mix; - else if(angVelZ < -mix) - angVelZ = -mix;*/ - //This controls how fast and how far the banking occurs - Vector3 bankingRot = new Vector3(angVelZ * (effSquared * mult), 0, 0); - if (bankingRot.X > 3) - bankingRot.X = 3; - else if (bankingRot.X < -3) - bankingRot.X = -3; - bankingRot *= VehicleOrientation; - ret += bankingRot; + computedBanking.X = ClampInRange(-3f, turningFactor * (effSquared * mult), 3f); } - m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0}, MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); + + // 'computedBanking' is now how much banking that should be happening. + ret = computedBanking - m_lastBanking; + + // Scale the correction by timescale and efficiency + ret /= m_bankingTimescale * m_bankingEfficiency; + + VDetailLog("{0}, MoveAngular,Banking,computedB={1},lastB={2},bEff={3},effSq={4},mult={5},mix={6},banking={7}", + Prim.LocalID, computedBanking, m_lastBanking, m_bankingEfficiency, effSquared, mult, mix, ret); } + m_lastBanking = computedBanking; return ret; } - // This is from previous instantiations of XXXDynamics.cs. // Applies roll reference frame. // TODO: is this the right way to separate the code to do this operation? @@ -1229,6 +1214,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin } + private float ClampInRange(float low, float val, float high) + { + return Math.Max(low, Math.Min(val, high)); + } + // Invoke the detailed logger and output something if it's enabled. private void VDetailLog(string msg, params Object[] args) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index e9f1549..851d508 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -63,10 +63,23 @@ public abstract class BSMotor } } // Can all the incremental stepping be replaced with motor classes? + +// Motor which moves CurrentValue to TargetValue over TimeScale seconds. +// The TargetValue is decays in TargetValueDecayTimeScale and +// the CurrentValue will be held back by FrictionTimeScale. +// TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay. + +// For instance, if something is moving at speed X and the desired speed is Y, +// CurrentValue is X and TargetValue is Y. As the motor is stepped, new +// values of CurrentValue are returned that approach the TargetValue. +// The feature of decaying TargetValue is so vehicles will eventually +// come to a stop rather than run forever. This can be disabled by +// setting TargetValueDecayTimescale to 'infinite'. +// The change from CurrentValue to TargetValue is linear over TimeScale seconds. public class BSVMotor : BSMotor { - public Vector3 FrameOfReference { get; set; } - public Vector3 Offset { get; set; } + // public Vector3 FrameOfReference { get; set; } + // public Vector3 Offset { get; set; } public float TimeScale { get; set; } public float TargetValueDecayTimeScale { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 17cc7b4..f72bd74 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -501,7 +501,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters try { - // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -510,7 +510,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); - // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index ca71313..68f25fc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -28,6 +28,7 @@ Small physical objects do not interact correctly Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. Add PID motor for avatar movement (slow to stop, ...) +Implement function efficiency for lineaar and angular motion. After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction -- cgit v1.1 From 787636b97ac242c3a903664a2fe1f26ea8c0130a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 3 Dec 2012 16:25:51 -0800 Subject: BulletSim: Reduce idle region physics overhead where there are MANY static objects by more restrictive selection of objects that collide with static objects. Rename collision mask fuctions from 'filter' to 'group' so it is clear what is being set. Rename BulletSimAPI.SetCollisionFilterMask() to SetCollisionGroupMask to match above. Restore passing of time step to linear and angular motion component routines. Use buffering vehicle physical parameter get/set routines consistantly. Make range enforcement clearer by using ClampInRange() function for parameter setting. Remove commented out experimental vehicle calculations. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 81 ++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 14 ++-- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 4 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 4 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 4 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 64 ++++++++-------- bin/lib32/BulletSim.dll | Bin 551936 -> 551936 bytes bin/lib32/libBulletSim.so | Bin 1708712 -> 1708731 bytes bin/lib64/BulletSim.dll | Bin 700928 -> 700928 bytes bin/lib64/libBulletSim.so | Bin 1846041 -> 1846064 bytes 11 files changed, 95 insertions(+), 80 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 1dfc420..21aa9be 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -165,8 +165,8 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Do this after the object has been added to the world - BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, - (uint)CollisionFilterGroups.AvatarFilter, + BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, + (uint)CollisionFilterGroups.AvatarGroup, (uint)CollisionFilterGroups.AvatarMask); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 525aac4..be8a502 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -161,7 +161,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularMotor.TimeScale = m_angularMotorTimescale; break; case Vehicle.BANKING_EFFICIENCY: - m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); + m_bankingEfficiency = ClampInRange(-1f, pValue, 1f); break; case Vehicle.BANKING_MIX: m_bankingMix = Math.Max(pValue, 0.01f); @@ -170,10 +170,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.BUOYANCY: - m_VehicleBuoyancy = Math.Max(-1f, Math.Min(pValue, 1f)); + m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); break; case Vehicle.HOVER_EFFICIENCY: - m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f)); + m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); break; case Vehicle.HOVER_HEIGHT: m_VhoverHeight = pValue; @@ -188,7 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - m_linearMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); + m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; break; case Vehicle.LINEAR_MOTOR_TIMESCALE: @@ -196,7 +196,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearMotor.TimeScale = m_linearMotorTimescale; break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: - m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); + m_verticalAttractionEfficiency = ClampInRange(0.1f, pValue, 1f); m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; break; case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: @@ -607,10 +607,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin } #region Known vehicle value functions + // Vehicle physical parameters that we buffer from constant getting and setting. + // The "m_known*" variables are initialized to 'null', fetched only if referenced + // and stored back into the physics engine only if updated. + // This does two things: 1) saves continuious calls into unmanaged code, and + // 2) signals when a physics property update must happen back to the simulator + // to update values modified for the vehicle. private int m_knownChanged; private float? m_knownTerrainHeight; private float? m_knownWaterLevel; - private Vector3? m_knownPosition; private Vector3? m_knownVelocity; private Quaternion? m_knownOrientation; @@ -642,7 +647,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity; if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) + { Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity); + } // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); @@ -766,15 +774,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - Vector3 pos = VehiclePosition; - - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); - Vector3 hoverContribution = ComputeLinearHover(ref pos); + Vector3 hoverContribution = ComputeLinearHover(pTimestep); - ComputeLinearBlockingEndPoint(ref pos); + ComputeLinearBlockingEndPoint(pTimestep); - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pos); + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); // ================================================================== Vector3 newVelocity = linearMotorContribution @@ -820,22 +826,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // end MoveLinear() - public Vector3 ComputeLinearTerrainHeightCorrection(ref Vector3 pos) + public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) { Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. // TODO: Consider taking the rotated size of the object or possibly casting a ray. - if (pos.Z < GetTerrainHeight(pos)) + if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) { // TODO: correct position by applying force rather than forcing position. - pos.Z = GetTerrainHeight(pos) + 2; - VehiclePosition = pos; - VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); + VehiclePosition += new Vector3(0f, 0f, GetTerrainHeight(VehiclePosition) + 2f); + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); } return ret; } - public Vector3 ComputeLinearHover(ref Vector3 pos) + public Vector3 ComputeLinearHover(float pTimestep) { Vector3 ret = Vector3.Zero; @@ -846,11 +851,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = GetWaterLevel(pos) + m_VhoverHeight; + m_VhoverTargetHeight = GetWaterLevel(VehiclePosition) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { - m_VhoverTargetHeight = GetTerrainHeight(pos) + m_VhoverHeight; + m_VhoverTargetHeight = GetTerrainHeight(VehiclePosition) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) { @@ -860,14 +865,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) { // If body is already heigher, use its height as target height - if (pos.Z > m_VhoverTargetHeight) - m_VhoverTargetHeight = pos.Z; + if (VehiclePosition.Z > m_VhoverTargetHeight) + m_VhoverTargetHeight = VehiclePosition.Z; } if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) { - if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) + if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) { + Vector3 pos = VehiclePosition; pos.Z = m_VhoverTargetHeight; VehiclePosition = pos; } @@ -875,7 +881,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin else { // Error is positive if below the target and negative if above. - float verticalError = m_VhoverTargetHeight - pos.Z; + float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly @@ -886,16 +892,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin } VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", - Prim.LocalID, pos, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); + Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); } return ret; } - public bool ComputeLinearBlockingEndPoint(ref Vector3 pos) + public bool ComputeLinearBlockingEndPoint(float pTimestep) { bool changed = false; + Vector3 pos = VehiclePosition; Vector3 posChange = pos - m_lastPositionVector; if (m_BlockingEndPoint != Vector3.Zero) { @@ -941,14 +948,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering // when they are in mid jump. // TODO: this code is wrong. Also, what should it do for boats? - public Vector3 ComputeLinearMotorUp(Vector3 pos) + public Vector3 ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); - float distanceAboveGround = pos.Z - GetTerrainHeight(pos); + float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition); if (distanceAboveGround > 1f) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); @@ -969,12 +976,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. - // The 'contribution' is how much angular correction each function wants. + // The 'contribution' is how much angular correction velocity each function wants. // All the contributions are added together and the orientation of the vehicle // is changed by all the contributed corrections. private void MoveAngular(float pTimestep) { - Vector3 angularMotorContribution = m_angularMotor.Step(); + // The user wants how many radians per second angular change? + Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -1006,14 +1014,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // The correction is applied to the current orientation. - // Any angular velocity on the vehicle is not us so zero the current value. - VehicleRotationalVelocity = Vector3.Zero; if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) { Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; - Quaternion quatCorrection = Quaternion.CreateFromEulers(scaledCorrection); - VehicleOrientation = Quaternion.Add(VehicleOrientation, quatCorrection); + VehicleRotationalVelocity = scaledCorrection; VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", Prim.LocalID, @@ -1022,6 +1027,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_lastAngularCorrection, scaledCorrection ); } + else + { + // The vehicle is not adding anything velocity wise. + VehicleRotationalVelocity = Vector3.Zero; + VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); + } // ================================================================== //Offset section @@ -1065,7 +1076,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - // verticalError.Normalize(); + verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) // is now leaning to one side (rotated around the X axis) and the Y value will diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 42a362f..ea1f71a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -646,9 +646,13 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Collision filter can be set only when the object is in the world - if (PhysBody.collisionFilter != 0 || PhysBody.collisionMask != 0) + if (PhysBody.collisionGroup != 0 || PhysBody.collisionMask != 0) { - BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, (uint)PhysBody.collisionFilter, (uint)PhysBody.collisionMask); + if (!BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, (uint)PhysBody.collisionGroup, (uint)PhysBody.collisionMask)) + { + PhysicsScene.Logger.ErrorFormat("{0} Failure setting prim collision mask. localID={1}, grp={2:X}, mask={3:X}", + LogHeader, LocalID, PhysBody.collisionGroup, PhysBody.collisionMask); + } } // Recompute any linkset parameters. @@ -691,7 +695,7 @@ public sealed class BSPrim : BSPhysObject // Start it out sleeping and physical actions could wake it up. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); - PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; + PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup; PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; } else @@ -737,7 +741,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); // BulletSimAPI.Activate2(BSBody.ptr, true); - PhysBody.collisionFilter = CollisionFilterGroups.ObjectFilter; + PhysBody.collisionGroup = CollisionFilterGroups.ObjectGroup; PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; } } @@ -765,7 +769,7 @@ public sealed class BSPrim : BSPhysObject m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); } CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - PhysBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; + PhysBody.collisionGroup = CollisionFilterGroups.VolumeDetectGroup; PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 0cb151e..83b9c37 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -121,8 +121,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, + BulletSimAPI.SetCollisionGroupMask2(m_mapInfo.terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainGroup, (uint)CollisionFilterGroups.TerrainMask); // Make it so the terrain will not move or be considered for movement. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 17d9536..83df360 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -140,8 +140,8 @@ public sealed class BSTerrainManager // Ground plane does not move BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); // Everything collides with the ground plane. - BulletSimAPI.SetCollisionFilterMask2(m_groundPlane.ptr, - (uint)CollisionFilterGroups.GroundPlaneFilter, (uint)CollisionFilterGroups.GroundPlaneMask); + BulletSimAPI.SetCollisionGroupMask2(m_groundPlane.ptr, + (uint)CollisionFilterGroups.GroundPlaneGroup, (uint)CollisionFilterGroups.GroundPlaneMask); // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 7e93ab4..6ce767d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -130,8 +130,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); - BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, + BulletSimAPI.SetCollisionGroupMask2(m_terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainGroup, (uint)CollisionFilterGroups.TerrainMask); // Make it so the terrain will not move or be considered for movement. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 21bc6a3..a5acfd1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -57,12 +57,12 @@ public struct BulletBody { ID = id; ptr = xx; - collisionFilter = 0; + collisionGroup = 0; collisionMask = 0; } public IntPtr ptr; public uint ID; - public CollisionFilterGroups collisionFilter; + public CollisionFilterGroups collisionGroup; public CollisionFilterGroups collisionMask; public override string ToString() { @@ -71,10 +71,10 @@ public struct BulletBody buff.Append(ID.ToString()); buff.Append(",p="); buff.Append(ptr.ToString("X")); - if (collisionFilter != 0 || collisionMask != 0) + if (collisionGroup != 0 || collisionMask != 0) { - buff.Append(",f="); - buff.Append(collisionFilter.ToString("X")); + buff.Append(",g="); + buff.Append(collisionGroup.ToString("X")); buff.Append(",m="); buff.Append(collisionMask.ToString("X")); } @@ -376,36 +376,36 @@ public enum CollisionFilterGroups : uint // Don't use the bit definitions!! Define the use in a // filter/mask definition below. This way collision interactions // are more easily debugged. - BNoneFilter = 0, - BDefaultFilter = 1 << 0, - BStaticFilter = 1 << 1, - BKinematicFilter = 1 << 2, - BDebrisFilter = 1 << 3, - BSensorTrigger = 1 << 4, - BCharacterFilter = 1 << 5, - BAllFilter = 0xFFFFFFFF, + BNoneGroup = 0, + BDefaultGroup = 1 << 0, + BStaticGroup = 1 << 1, + BKinematicGroup = 1 << 2, + BDebrisGroup = 1 << 3, + BSensorTrigger = 1 << 4, + BCharacterGroup = 1 << 5, + BAllGroup = 0xFFFFFFFF, // Filter groups defined by BulletSim - BGroundPlaneFilter = 1 << 10, - BTerrainFilter = 1 << 11, - BRaycastFilter = 1 << 12, - BSolidFilter = 1 << 13, - BLinksetFilter = 1 << 14, + BGroundPlaneGroup = 1 << 10, + BTerrainGroup = 1 << 11, + BRaycastGroup = 1 << 12, + BSolidGroup = 1 << 13, + BLinksetGroup = 1 << 14, // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarFilter = BCharacterFilter, - AvatarMask = BAllFilter, - ObjectFilter = BSolidFilter, - ObjectMask = BAllFilter, - StaticObjectFilter = BStaticFilter, - StaticObjectMask = BAllFilter & ~BStaticFilter, // static objects don't collide with each other - LinksetFilter = BLinksetFilter, - LinksetMask = BAllFilter & ~BLinksetFilter, // linkset objects don't collide with each other - VolumeDetectFilter = BSensorTrigger, + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetGroup, + LinksetMask = BAllGroup & ~BLinksetGroup, // linkset objects don't collide with each other + VolumeDetectGroup = BSensorTrigger, VolumeDetectMask = ~BSensorTrigger, - TerrainFilter = BTerrainFilter, - TerrainMask = BAllFilter & ~BStaticFilter, // static objects on the ground don't collide - GroundPlaneFilter = BGroundPlaneFilter, - GroundPlaneMask = BAllFilter + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup }; @@ -945,7 +945,7 @@ public static extern IntPtr GetConstraintRef2(IntPtr obj, int index); public static extern int GetNumConstraintRefs2(IntPtr obj); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCollisionFilterMask2(IntPtr body, uint filter, uint mask); +public static extern bool SetCollisionGroupMask2(IntPtr body, uint filter, uint mask); // ===================================================================================== // btCollisionShape entries diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index c3dde8e..75d5bc3 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 98bd655..b648da1 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 9c90924..fc0fdca 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 4301d34..a1b099c 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From ac65085cc36bb4820482bf769b4be44e1c8d58ce Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 3 Dec 2012 20:09:54 -0500 Subject: XmlRpcGridRouter Flesh out XmlRpcGridRouter to reap unused channels from gateway when scripts or objects are removed, or when the llCloseRemoteDataChannel is called. See: http://http://forge.opensimulator.org/gf/project/xmlrpcrouter/ or https://github.com/BlueWall/XmlRpcRouter for php gateway and test code. --- .../Region/Framework/Interfaces/IXmlRpcRouter.cs | 1 + .../XmlRpcRouterModule/XmlRpcGridRouterModule.cs | 82 +++++++++++++++++----- .../XmlRpcRouterModule/XmlRpcRouterModule.cs | 6 ++ .../Shared/Api/Implementation/LSL_Api.cs | 7 ++ 4 files changed, 77 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs b/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs index 6db6674..093d3f0 100644 --- a/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs +++ b/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs @@ -34,5 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces void RegisterNewReceiver(IScriptModule scriptEngine, UUID channelID, UUID objectID, UUID itemID, string url); void ScriptRemoved(UUID itemID); void ObjectRemoved(UUID objectID); + void UnRegisterReceiver(string channelID, UUID itemID); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index 6120a81..709d389 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs @@ -46,6 +46,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule { public class XmlRpcInfo { + public UUID item; public UUID channel; public string uri; } @@ -88,6 +89,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule return; scene.RegisterModuleInterface(this); + + IScriptModule scriptEngine = scene.RequestModuleInterface(); + if ( scriptEngine != null ) + { + scriptEngine.OnScriptRemoved += this.ScriptRemoved; + scriptEngine.OnObjectRemoved += this.ObjectRemoved; + + } } public void RegionLoaded(Scene scene) @@ -120,22 +129,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { - if (!m_Channels.ContainsKey(itemID)) - { - XmlRpcInfo info = new XmlRpcInfo(); - info.channel = channel; - info.uri = uri; + if (!m_Enabled) + return; - bool success = SynchronousRestObjectRequester.MakeRequest( - "POST", m_ServerURI+"/RegisterChannel/", info); + m_log.InfoFormat("[XMLRPC GRID ROUTER]: New receiver Obj: {0} Ch: {1} ID: {2} URI: {3}", + objectID.ToString(), channel.ToString(), itemID.ToString(), uri); - if (!success) - { - m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); - } + XmlRpcInfo info = new XmlRpcInfo(); + info.channel = channel; + info.uri = uri; + info.item = itemID; + + bool success = SynchronousRestObjectRequester.MakeRequest( + "POST", m_ServerURI+"/RegisterChannel/", info); - m_Channels[itemID] = channel; + if (!success) + { + m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); } + + m_Channels[itemID] = channel; + + } + + public void UnRegisterReceiver(string channelID, UUID itemID) + { + if (!m_Enabled) + return; + + RemoveChannel(itemID); + } public void ScriptRemoved(UUID itemID) @@ -143,10 +166,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule if (!m_Enabled) return; - if (m_Channels.ContainsKey(itemID)) + RemoveChannel(itemID); + + } + + public void ObjectRemoved(UUID objectID) + { + // m_log.InfoFormat("[XMLRPC GRID ROUTER]: Object Removed {0}",objectID.ToString()); + } + + private bool RemoveChannel(UUID itemID) + { + if(!m_Channels.ContainsKey(itemID)) + { + m_log.InfoFormat("[XMLRPC GRID ROUTER]: Attempted to unregister non-existing Item: {0}", itemID.ToString()); + return false; + } + + XmlRpcInfo info = new XmlRpcInfo(); + + info.channel = m_Channels[itemID]; + info.item = itemID; + info.uri = "http://0.0.0.0:00"; + + if (info != null) { - bool success = SynchronousRestObjectRequester.MakeRequest( - "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]); + bool success = SynchronousRestObjectRequester.MakeRequest( + "POST", m_ServerURI+"/RemoveChannel/", info); if (!success) { @@ -154,11 +200,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule } m_Channels.Remove(itemID); + return true; } - } - - public void ObjectRemoved(UUID objectID) - { + return false; } } } diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index 4783f4c..ad0b83d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -101,12 +101,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] {uri}); } + public void UnRegisterReceiver(string channelID, UUID itemID) + { + } + public void ScriptRemoved(UUID itemID) { + System.Console.WriteLine("TEST Script Removed!"); } public void ObjectRemoved(UUID objectID) { + System.Console.WriteLine("TEST Obj Removed!"); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index acf4d8c..4108588 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6856,6 +6856,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llCloseRemoteDataChannel(string channel) { m_host.AddScriptLPS(1); + + IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); + if (xmlRpcRouter != null) + { + xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID); + } + IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); xmlrpcMod.CloseXMLRPCChannel((UUID)channel); ScriptSleep(1000); -- cgit v1.1 From dc80c2afb338570f8f7d79491fd731bebaf643f4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 4 Dec 2012 08:08:34 -0800 Subject: Improvement in HGInstantMessageService: account for the existence of an offline IM service. --- .../HypergridService/HGInstantMessageService.cs | 35 +++++-- OpenSim/Services/Interfaces/IOfflineIMService.cs | 115 +++++++++++++++++++++ 2 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 OpenSim/Services/Interfaces/IOfflineIMService.cs diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 0c9cfd3..e8d7cca 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -61,13 +61,13 @@ namespace OpenSim.Services.HypergridService protected static IGridService m_GridService; protected static IPresenceService m_PresenceService; protected static IUserAgentService m_UserAgentService; + protected static IOfflineIMService m_OfflineIMService; protected static IInstantMessageSimConnector m_IMSimConnector; protected static Dictionary m_UserLocationMap = new Dictionary(); private static ExpiringCache m_RegionCache; - private static string m_RestURL; private static bool m_ForwardOfflineGroupMessages; private static bool m_InGatekeeper; @@ -111,9 +111,14 @@ namespace OpenSim.Services.HypergridService return; } - m_RestURL = cnf.GetString("OfflineMessageURL", string.Empty); m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", false); + if (m_InGatekeeper) + { + string offlineIMService = cnf.GetString("OfflineIMService", string.Empty); + if (offlineIMService != string.Empty) + m_OfflineIMService = ServerUtils.LoadPlugin(offlineIMService, args); + } } } @@ -329,18 +334,28 @@ namespace OpenSim.Services.HypergridService private bool UndeliveredMessage(GridInstantMessage im) { - if (m_RestURL != string.Empty && (im.offline != 0) - && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) - { -// m_log.DebugFormat("[HG IM SERVICE]: Message saved"); + if (m_OfflineIMService == null) + return false; - return SynchronousRestObjectRequester.MakeRequest( - "POST", m_RestURL + "/SaveMessage/", im); - } - else + if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && + im.dialog != (byte)InstantMessageDialog.MessageFromAgent && + im.dialog != (byte)InstantMessageDialog.GroupNotice && + im.dialog != (byte)InstantMessageDialog.GroupInvitation && + im.dialog != (byte)InstantMessageDialog.InventoryOffered) { return false; } + + if (!m_ForwardOfflineGroupMessages) + { + if (im.dialog == (byte)InstantMessageDialog.GroupNotice || + im.dialog == (byte)InstantMessageDialog.GroupInvitation) + return false; + } + +// m_log.DebugFormat("[HG IM SERVICE]: Message saved"); + string reason = string.Empty; + return m_OfflineIMService.StoreMessage(im, out reason); } } } \ No newline at end of file diff --git a/OpenSim/Services/Interfaces/IOfflineIMService.cs b/OpenSim/Services/Interfaces/IOfflineIMService.cs new file mode 100644 index 0000000..2848967 --- /dev/null +++ b/OpenSim/Services/Interfaces/IOfflineIMService.cs @@ -0,0 +1,115 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * 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. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; + +using OpenSim.Framework; +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IOfflineIMService + { + List GetMessages(UUID principalID); + bool StoreMessage(GridInstantMessage im, out string reason); + } + + public class OfflineIMDataUtils + { + public static GridInstantMessage GridInstantMessage(Dictionary dict) + { + GridInstantMessage im = new GridInstantMessage(); + + if (dict.ContainsKey("BinaryBucket") && dict["BinaryBucket"] != null) + im.binaryBucket = OpenMetaverse.Utils.HexStringToBytes(dict["BinaryBucket"].ToString(), true); + + if (dict.ContainsKey("Dialog") && dict["Dialog"] != null) + im.dialog = byte.Parse(dict["Dialog"].ToString()); + + if (dict.ContainsKey("FromAgentID") && dict["FromAgentID"] != null) + im.fromAgentID = new Guid(dict["FromAgentID"].ToString()); + + if (dict.ContainsKey("FromAgentName") && dict["FromAgentName"] != null) + im.fromAgentName = dict["FromAgentName"].ToString(); + else + im.fromAgentName = string.Empty; + + if (dict.ContainsKey("FromGroup") && dict["FromGroup"] != null) + im.fromGroup = bool.Parse(dict["FromGroup"].ToString()); + + if (dict.ContainsKey("SessionID") && dict["SessionID"] != null) + im.imSessionID = new Guid(dict["SessionID"].ToString()); + + if (dict.ContainsKey("Message") && dict["Message"] != null) + im.message = dict["Message"].ToString(); + else + im.message = string.Empty; + + if (dict.ContainsKey("Offline") && dict["Offline"] != null) + im.offline = byte.Parse(dict["Offline"].ToString()); + + if (dict.ContainsKey("EstateID") && dict["EstateID"] != null) + im.ParentEstateID = UInt32.Parse(dict["EstateID"].ToString()); + + if (dict.ContainsKey("Position") && dict["Position"] != null) + im.Position = Vector3.Parse(dict["Position"].ToString()); + + if (dict.ContainsKey("RegionID") && dict["RegionID"] != null) + im.RegionID = new Guid(dict["RegionID"].ToString()); + + if (dict.ContainsKey("Timestamp") && dict["Timestamp"] != null) + im.timestamp = UInt32.Parse(dict["Timestamp"].ToString()); + + if (dict.ContainsKey("ToAgentID") && dict["ToAgentID"] != null) + im.toAgentID = new Guid(dict["ToAgentID"].ToString()); + + return im; + } + + public static Dictionary GridInstantMessage(GridInstantMessage im) + { + Dictionary dict = new Dictionary(); + + dict["BinaryBucket"] = OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, im.binaryBucket.Length, null); + dict["Dialog"] = im.dialog.ToString(); + dict["FromAgentID"] = im.fromAgentID.ToString(); + dict["FromAgentName"] = im.fromAgentName == null ? string.Empty : im.fromAgentName; + dict["FromGroup"] = im.fromGroup.ToString(); + dict["SessionID"] = im.imSessionID.ToString(); + dict["Message"] = im.message == null ? string.Empty : im.message; + dict["Offline"] = im.offline.ToString(); + dict["EstateID"] = im.ParentEstateID.ToString(); + dict["Position"] = im.Position.ToString(); + dict["RegionID"] = im.RegionID.ToString(); + dict["Timestamp"] = im.timestamp.ToString(); + dict["ToAgentID"] = im.toAgentID.ToString(); + + return dict; + } + + } +} -- cgit v1.1 From 583e44103c8eb552c437468cba84771c94592ae9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 4 Dec 2012 08:36:54 -0800 Subject: Bug fix in OfflineMessageModule. Mantis #6446 --- .../Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 41364d7..7d763fa 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -219,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (!m_ForwardOfflineGroupMessages) { if (im.dialog == (byte)InstantMessageDialog.GroupNotice || - im.dialog != (byte)InstantMessageDialog.GroupInvitation) + im.dialog == (byte)InstantMessageDialog.GroupInvitation) return; } -- cgit v1.1 From 7fdc2517749cba6fb88c6c7bf11539413d130901 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 22:24:51 +0000 Subject: Add path references for Mono.Addins where they were missing for DataSnapshot and UserStatistics. Should address http://opensimulator.org/mantis/view.php?id=6444 Appears that nant doesn't need these paths but building directly in monodevelop does. --- prebuild.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prebuild.xml b/prebuild.xml index 0612c10..17db573 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2045,7 +2045,7 @@ - + @@ -2453,7 +2453,7 @@ - + -- cgit v1.1 From fb26d32a5c1320e97c9288326ebe402658a0a1c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 22:33:25 +0000 Subject: minor: Put Scene.PhysicsRequestAsset() into standard C# xml format. --- OpenSim/Region/Framework/Scenes/Scene.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1ad5edd..cca295c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5638,10 +5638,17 @@ namespace OpenSim.Region.Framework.Scenes return m_SpawnPoint - 1; } - // Wrappers to get physics modules retrieve assets. Has to be done this way - // because we can't assign the asset service to physics directly - at the - // time physics are instantiated it's not registered but it will be by - // the time the first prim exists. + /// + /// Wrappers to get physics modules retrieve assets. + /// + /// + /// Has to be done this way + /// because we can't assign the asset service to physics directly - at the + /// time physics are instantiated it's not registered but it will be by + /// the time the first prim exists. + /// + /// + /// public void PhysicsRequestAsset(UUID assetID, AssetReceivedDelegate callback) { AssetService.Get(assetID.ToString(), callback, PhysicsAssetReceived); -- cgit v1.1 From 0d4047e641bac2d7fa554097ad23cec930082e33 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 23:06:02 +0000 Subject: minor: Comment out "Delivering IM to..." messages for now. --- .../CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 3983369..a169748 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (sp != null && !sp.IsChildAgent) { // Local message - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); sp.ControllingClient.SendInstantMessage(im); @@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (sp != null) { // Local message - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); sp.ControllingClient.SendInstantMessage(im); @@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); SendGridInstantMessageViaXMLRPC(im, result); } -- cgit v1.1 From 1b5f21f761ae12be34d80a41d23c5b97cc10f4a9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 23:07:26 +0000 Subject: minor: also comment out the debug log message which reports searching for child agents in simulator scenes for now. --- .../Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index a169748..fa935cd 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -159,8 +159,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // try child avatar second foreach (Scene scene in m_Scenes) { - m_log.DebugFormat( - "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); ScenePresence sp = scene.GetScenePresence(toAgentID); if (sp != null) -- cgit v1.1 From d97440c7cf307ec701cc5351a0075239ece44727 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 21:37:41 +0000 Subject: On XEngine.ProcessEventHandler(), instead of creating a new CultureInfo on every call use the single one set by Culture.SetCurrentCulture() This is slightly different in that SetCurrentCulture() does not use overridden settings if the system culture matches en-US but some settings there have been changed. This is what we want - we do not want to use any system overriden settings. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 0460f22..1dab51e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1415,8 +1415,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine /// private object ProcessEventHandler(object parms) { - CultureInfo USCulture = new CultureInfo("en-US"); - Thread.CurrentThread.CurrentCulture = USCulture; + Culture.SetCurrentCulture(); IScriptInstance instance = (ScriptInstance) parms; -- cgit v1.1 From ea786414c283ed04a32905b177afd342c88a7471 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 21:51:08 +0000 Subject: In XEngine.DoOnRezScript() use Culture.SetCurrentCulture() instead of constructing a new CultureInfo separately --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1dab51e..d9d4494 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1018,8 +1018,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine string assembly = ""; - CultureInfo USCulture = new CultureInfo("en-US"); - Thread.CurrentThread.CurrentCulture = USCulture; + Culture.SetCurrentCulture(); Dictionary, KeyValuePair> linemap; -- cgit v1.1 From fdf8876e20e519e2c69f0bd0fed4aea7ff4bab8d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 21:52:10 +0000 Subject: In BaseHttpServer.HandleRequest(), use Culture.SetCurrentCulture() rather than creating a new CultureInfo separately --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 2cd626f..8a0340f 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -436,7 +436,7 @@ namespace OpenSim.Framework.Servers.HttpServer // reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]); //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); - Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); + Culture.SetCurrentCulture(); // // This is the REST agent interface. We require an agent to properly identify // // itself. If the REST handler recognizes the prefix it will attempt to -- cgit v1.1 From 2342d20a7e249bc3006e47e85e03de6d532a7d2d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 21:53:25 +0000 Subject: minor: tidy up spacing at bottom of MundaneFrameworkTests --- OpenSim/Framework/Tests/MundaneFrameworkTests.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index 47fe599..1dc8053 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs @@ -303,10 +303,6 @@ namespace OpenSim.Framework.Tests Culture.SetCurrentCulture(); Assert.That(Thread.CurrentThread.CurrentCulture.Name == ci.Name, "SetCurrentCulture failed to set thread culture to en-US"); - } - - - + } } -} - +} \ No newline at end of file -- cgit v1.1 From b60c6bc3f8936f3a152e0609daa1081216d34768 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 22:01:47 +0000 Subject: Don't pointlessly set ExtraParams = byte[1] in PrimitiveBaseShape since this is ignored by the ExtraParams properly anyway --- OpenSim/Framework/PrimitiveBaseShape.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 76dcfca..3dbdd0f 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -193,7 +193,6 @@ namespace OpenSim.Framework public PrimitiveBaseShape() { PCode = (byte) PCodeEnum.Primitive; - ExtraParams = new byte[1]; m_textureEntry = DEFAULT_TEXTURE; } @@ -203,7 +202,6 @@ namespace OpenSim.Framework return; PCode = (byte)PCodeEnum.Primitive; - ExtraParams = new byte[1]; m_textureEntry = DEFAULT_TEXTURE; } @@ -216,7 +214,6 @@ namespace OpenSim.Framework // m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: Creating from {0}", prim.ID); PCode = (byte)prim.PrimData.PCode; - ExtraParams = new byte[1]; State = prim.PrimData.State; PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); -- cgit v1.1 From 0f3ebe09713cf67110ff24bf6cd10b9add5cc8c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 22:12:45 +0000 Subject: Remove very probably unused PrimitiveBaseShape(bool) constructor to reduce code complexity --- OpenSim/Framework/PrimitiveBaseShape.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 3dbdd0f..4c36819 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -192,15 +192,6 @@ namespace OpenSim.Framework public PrimitiveBaseShape() { - PCode = (byte) PCodeEnum.Primitive; - m_textureEntry = DEFAULT_TEXTURE; - } - - public PrimitiveBaseShape(bool noShape) - { - if (noShape) - return; - PCode = (byte)PCodeEnum.Primitive; m_textureEntry = DEFAULT_TEXTURE; } @@ -245,7 +236,10 @@ namespace OpenSim.Framework SculptTexture = prim.Sculpt.SculptTexture; SculptType = (byte)prim.Sculpt.Type; } - else SculptType = (byte)OpenMetaverse.SculptType.None; + else + { + SculptType = (byte)OpenMetaverse.SculptType.None; + } } [XmlIgnore] @@ -337,9 +331,9 @@ namespace OpenSim.Framework _scale = new Vector3(side, side, side); } - public void SetHeigth(float heigth) + public void SetHeigth(float height) { - _scale.Z = heigth; + _scale.Z = height; } public void SetRadius(float radius) -- cgit v1.1 From e8df0f1b4c3194c7f5c1a354b5d5d2f67d6a250c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 22:33:28 +0000 Subject: Add IScriptInstance.EventsProcessed stat so that we can record this information and display in "show scripts" for debug purposes --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 5 +++++ OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 ++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1 + 3 files changed, 10 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index b04f6b6..f3abd96 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -114,6 +114,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces UUID AssetID { get; } Queue EventQueue { get; } + /// + /// Number of events processed by this script instance. + /// + long EventsProcessed { get; } + void ClearQueue(); int StartParam { get; set; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5793cc9..5bfe97a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -173,6 +173,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public Queue EventQueue { get; private set; } + public long EventsProcessed { get; private set; } + public int StartParam { get; set; } public TaskInventoryItem ScriptTask { get; private set; } @@ -808,6 +810,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // script engine to run the next event. lock (EventQueue) { + EventsProcessed++; + if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d9d4494..2136fe8 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -512,6 +512,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine lock (eq) sb.AppendFormat("Queued events : {0}\n", eq.Count); + sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); -- cgit v1.1 From 652f4bcb425646aab2096da99aa00016dfe639fd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:27:50 +0000 Subject: For now, sort "show scripts" output in descending order sorted by events processed. For debug purposes - should later add options to allow different sorting or show only highest 10, etc. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 2136fe8..394826e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Reflection; using System.Security; using System.Security.Policy; @@ -377,9 +378,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine /// /// /// - /// true if we're okay to proceed, false if not. + /// Basis on which to sort output. Can be null if no sort needs to take place private void HandleScriptsAction(string[] cmdparams, Action action) { + HandleScriptsAction(cmdparams, action, null); + } + + /// + /// Parse the raw item id into a script instance from the command params if it's present. + /// + /// + /// + /// Basis on which to sort output. Can be null if no sort needs to take place + private void HandleScriptsAction( + string[] cmdparams, Action action, Func keySelector) + { if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) return; @@ -390,7 +403,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (cmdparams.Length == 2) { - foreach (IScriptInstance instance in m_Scripts.Values) + IEnumerable scripts = m_Scripts.Values; + + if (keySelector != null) + scripts = scripts.OrderBy(keySelector); + + foreach (IScriptInstance instance in scripts) action(instance); return; @@ -478,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - HandleScriptsAction(cmdparams, HandleShowScript); + HandleScriptsAction(cmdparams, HandleShowScript, si => si.EventsProcessed); } private void HandleShowScript(IScriptInstance instance) -- cgit v1.1 From 5ba99cbf554d965a6b11114a602c5317ca8f5ebd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:33:48 +0000 Subject: Add IScriptInstance.EventsQueued to match EventsProcessed instead of asking callers to lock and directly inspect the EventQueue --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 5 +++++ OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 9 +++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 +---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index f3abd96..0cef550 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -115,6 +115,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces Queue EventQueue { get; } /// + /// Number of events queued for processing. + /// + long EventsQueued { get; } + + /// /// Number of events processed by this script instance. /// long EventsProcessed { get; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5bfe97a..8e81e9f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -173,6 +173,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public Queue EventQueue { get; private set; } + public long EventsQueued + { + get + { + lock (EventQueue) + return EventQueue.Count; + } + } + public long EventsProcessed { get; private set; } public int StartParam { get; set; } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 394826e..aeb807c 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -526,10 +526,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine sb.AppendFormat("Script name : {0}\n", instance.ScriptName); sb.AppendFormat("Status : {0}\n", status); - - lock (eq) - sb.AppendFormat("Queued events : {0}\n", eq.Count); - + sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued); sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); -- cgit v1.1 From 66982c8a599eeeaf63f9e3c5bfdae743deab5528 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:36:15 +0000 Subject: Remove some mono warnings in script tests, chiefly where SetUp() wasn't properly calling to OpenSimTestCase.SetUp() --- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 4 +--- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index 2c9d9e8..cb7291a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -57,8 +57,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 57f19b9..d9b17d7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -62,8 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index 182b07b..98017d8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs @@ -51,8 +51,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests private LSL_Api m_lslApi; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 213f33f..1381d2b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -57,8 +57,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index b49bcc2..d6c82f1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -127,12 +127,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests OSSL_Api osslApi = new OSSL_Api(); osslApi.Initialize(m_engine, so.RootPart, null); - string npcRaw; bool gotExpectedException = false; try { - npcRaw - = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); + osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); } catch (ScriptException) { -- cgit v1.1 From ec765de7e55893c24792c95c1356bfad67e02034 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:41:50 +0000 Subject: Add engine-wide events queued and events processed numbers to output of "xengine status" console command. For debugging purposes. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index aeb807c..965101a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -455,9 +455,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine StringBuilder sb = new StringBuilder(); sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); + long scriptsLoaded, eventsQueued = 0, eventsProcessed = 0; + lock (m_Scripts) - sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count); + { + scriptsLoaded = m_Scripts.Count; + + foreach (IScriptInstance si in m_Scripts.Values) + { + eventsQueued += si.EventsQueued; + eventsProcessed += si.EventsProcessed; + } + } + sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded); sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); @@ -466,6 +477,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); + sb.AppendFormat("Events queued : {0}\n", eventsQueued); + sb.AppendFormat("Events processed : {0}\n", eventsProcessed); SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); -- cgit v1.1 From e60fe958df1709d1443abaa44faa4736f515f977 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:44:12 +0000 Subject: minor: Fix more compiler warnings in CoreModules tests by properly overriding OpenSimTestCase.SetUp() --- OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | 4 +++- .../Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | 4 +++- .../ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs | 5 ++++- OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs | 4 +++- OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs | 4 +++- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 0872cc8..fd02b08 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs @@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Asset.Tests protected FlotsamAssetCache m_cache; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index b768257..ac25a93 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -57,8 +57,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests protected TestClient m_tc; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_iam = new BasicInventoryAccessModule(); IConfigSource config = new IniConfigSource(); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs index 7e365ca..69bac82 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs @@ -46,8 +46,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests public class PresenceConnectorsTests : OpenSimTestCase { LocalPresenceServicesConnector m_LocalConnector; - private void SetUp() + + public override void SetUp() { + base.SetUp(); + IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.AddConfig("PresenceService"); diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index 14eca42..0945b43 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -60,8 +60,10 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests protected ILandObject m_lo2; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_pcm = new PrimCountModule(); LandManagementModule lmm = new LandManagementModule(); m_scene = new SceneHelpers().SetupScene(); diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index ba4b041..03a96a4 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -50,8 +50,10 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests protected MoapModule m_module; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_module = new MoapModule(); m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, m_module); -- cgit v1.1 From 1c9ecc55d3ae52548f974c4c19cc1f8ed6fb7d88 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Dec 2012 00:22:52 +0000 Subject: Instead of printing script errors out to console, put to debug log so that we also get timestamps. This commit also adds script name, part name, uuid, etc. for later identification. This information has been sent to console since 2009 but may be turned down if it proves too noisy. However, I still currently need it to investigate some region problems probably triggered by scripting. --- .../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 8e81e9f..5ad6eeb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -785,6 +785,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); + + + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", + ScriptName, + PrimName, + part.UUID, + part.AbsolutePosition, + part.ParentGroup.Scene.Name, + text.Replace("\n", "\\n"), + e.InnerException); } catch (Exception) { @@ -1026,7 +1037,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance "({0}): {1}", scriptLine - 1, e.InnerException.Message); - System.Console.WriteLine(e.ToString()+"\n"); return message; } } -- cgit v1.1 From acc01bb85d5c5f15a3943a908433b7fe08075c93 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Dec 2012 01:12:12 +0000 Subject: Allow GetTexture calls with no second value in the range header (e.g. just 5333-) It looks like the latest Kokua is doing this. As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, leaving off the second value is legal This indicates the caller wants the rest of the entity. --- .../Handlers/GetTexture/GetTextureHandler.cs | 35 +++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 04cc33a..6e9094a 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -246,6 +246,11 @@ namespace OpenSim.Capabilities.Handlers } else { + // Handle the case where no second range value was given. This is equivalent to requesting + // the rest of the entity. + if (end == -1) + end = int.MaxValue; + end = Utils.Clamp(end, 0, texture.Data.Length - 1); start = Utils.Clamp(start, 0, end); int len = end - start + 1; @@ -299,15 +304,43 @@ namespace OpenSim.Capabilities.Handlers // texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length); } + /// + /// Parse a range header. + /// + /// + /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, + /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-). + /// Where there is no value, -1 is returned. + /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1 + /// for start. + /// + /// + /// Undefined if the parse fails. + /// Undefined if the parse fails. private bool TryParseRange(string header, out int start, out int end) { + start = end = 0; + if (header.StartsWith("bytes=")) { string[] rangeValues = header.Substring(6).Split('-'); + if (rangeValues.Length == 2) { - if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) + if (!Int32.TryParse(rangeValues[0], out start)) + return false; + + string rawEnd = rangeValues[1]; + + if (rawEnd == "") + { + end = -1; + return true; + } + else if (Int32.TryParse(rawEnd, out end)) + { return true; + } } } -- cgit v1.1 From 68daeee4342757340177a015a30b78c54674fafc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Dec 2012 01:36:30 +0000 Subject: minor: change method doc on GetTextureHandler.TryParseRange(), mainly to trigger another build --- OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 6e9094a..b497fde 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -315,8 +315,8 @@ namespace OpenSim.Capabilities.Handlers /// for start. /// /// - /// Undefined if the parse fails. - /// Undefined if the parse fails. + /// Start of the range. Undefined if this was not a number. + /// End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number. private bool TryParseRange(string header, out int start, out int end) { start = end = 0; -- cgit v1.1 From f1d4e8f792f6f5ad5181226337a6467cc5f948b9 Mon Sep 17 00:00:00 2001 From: nebadon Date: Thu, 6 Dec 2012 09:52:18 -0700 Subject: fix openjpeg on 64 bit OSX we were pointing to a file taht did not exist. --- bin/OpenMetaverse.dll.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/OpenMetaverse.dll.config b/bin/OpenMetaverse.dll.config index b67da5f..f5423b2 100644 --- a/bin/OpenMetaverse.dll.config +++ b/bin/OpenMetaverse.dll.config @@ -1,5 +1,5 @@ - + -- cgit v1.1 From e599a8b2421ab51860c65e49bdfd38fa064fa9b8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 5 Dec 2012 09:27:38 -0800 Subject: BulletSim: Vehicle angular vertical attraction works. Other vehicle angular forces commented out for the moment for debugging. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 55 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 3 ++ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index be8a502..a83d966 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -620,11 +620,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3? m_knownVelocity; private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; + private Vector3? m_knownRotationalForce; private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; private const int m_knownChangedOrientation = 1 << 2; private const int m_knownChangedRotationalVelocity = 1 << 3; + private const int m_knownChangedRotationalForce = 1 << 4; private void ForgetKnownVehicleProperties() { @@ -634,6 +636,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownVelocity = null; m_knownOrientation = null; m_knownRotationalVelocity = null; + m_knownRotationalForce = null; m_knownChanged = 0; } private void PushKnownChanged() @@ -645,12 +648,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation; if ((m_knownChanged & m_knownChangedVelocity) != 0) + { Prim.ForceVelocity = VehicleVelocity; + BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); + } if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + // Fake out Bullet by making it think the velocity is the same as last time. BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity); } + if ((m_knownChanged & m_knownChangedRotationalForce) != 0) + Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); @@ -734,6 +744,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownChanged |= m_knownChangedRotationalVelocity; } } + private void VehicleAddAngularForce(Vector3 aForce) + { + m_knownRotationalForce += aForce; + m_knownChanged |= m_knownChangedRotationalForce; + } #endregion // Known vehicle value functions // One step of the vehicle properties for the next 'pTimestep' seconds. @@ -1013,11 +1028,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin + bankingContribution; // ================================================================== - // The correction is applied to the current orientation. + // Apply the correction velocity. + // TODO: Should this be applied as an angular force (torque)? if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) { Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; - VehicleRotationalVelocity = scaledCorrection; VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", @@ -1029,7 +1044,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - // The vehicle is not adding anything velocity wise. + // The vehicle is not adding anything angular wise. VehicleRotationalVelocity = Vector3.Zero; VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); } @@ -1060,8 +1075,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin torqueFromOffset.Y = 0; if (float.IsNaN(torqueFromOffset.Z)) torqueFromOffset.Z = 0; - torqueFromOffset *= m_vehicleMass; - Prim.ApplyTorqueImpulse(torqueFromOffset, true); + + VehicleAddAngularForce(torqueFromOffset * m_vehicleMass); VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } @@ -1097,23 +1112,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin ret.Y = - verticalError.X; ret.Z = 0f; - // scale by the time scale and timestep + // Scale the correction force by how far we're off from vertical. + // Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over. + // float clampedZError = ClampInRange(0.1f, Math.Abs(verticalError.Z), 1f); + float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f); + // float vertForce = 1f / clampedSqrZError * m_verticalAttractionEfficiency; + float vertForce = 1f / clampedSqrZError; + + ret *= vertForce; + + // Correction happens over a number of seconds. Vector3 unscaledContrib = ret; ret /= m_verticalAttractionTimescale; - // This returns the angular correction desired. Timestep is added later. - // ret *= pTimestep; - - // apply efficiency - Vector3 preEfficiencyContrib = ret; - // TODO: implement efficiency. - // Effenciency squared seems to give a more realistic effect - float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - // ret *= efficencySquared; - - VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", - Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, - m_verticalAttractionEfficiency, efficencySquared, - ret); + + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},vertForce={3},eff={4},vertAttr={5}", + Prim.LocalID, verticalError, unscaledContrib, vertForce, m_verticalAttractionEfficiency, ret); } return ret; } @@ -1123,6 +1136,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; + return ret; // DEBUG DEBUG DEBUG debug the other contributors first if (m_angularDeflectionEfficiency != 0) { @@ -1151,6 +1165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 ret = Vector3.Zero; Vector3 computedBanking = Vector3.Zero; + return ret; // DEBUG DEBUG DEBUG debug the other contributors first if (m_bankingEfficiency != 0) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index ea1f71a..e392078 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1010,6 +1010,9 @@ public sealed class BSPrim : BSPhysObject }); } // A torque impulse. + // ApplyTorqueImpulse adds torque directly to the angularVelocity. + // AddAngularForce accumulates the force and applied it to the angular velocity all at once. + // Computed as: angularVelocity += impulse * inertia; public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) { OMV.Vector3 applyImpulse = impulse; -- cgit v1.1 From 6d7f66f78192c686f2f9666bbb4c4517310c30a7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 5 Dec 2012 09:45:33 -0800 Subject: BulletSim: Don't add gravity to down force -- let Bullet do that. Add VehicleAddForce to set of managed vehicle prim properties. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 42 ++++++++++++++-------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a83d966..09aee17 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -618,15 +618,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float? m_knownWaterLevel; private Vector3? m_knownPosition; private Vector3? m_knownVelocity; + private Vector3? m_knownForce; private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; private Vector3? m_knownRotationalForce; private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; - private const int m_knownChangedOrientation = 1 << 2; - private const int m_knownChangedRotationalVelocity = 1 << 3; - private const int m_knownChangedRotationalForce = 1 << 4; + private const int m_knownChangedForce = 1 << 2; + private const int m_knownChangedOrientation = 1 << 3; + private const int m_knownChangedRotationalVelocity = 1 << 4; + private const int m_knownChangedRotationalForce = 1 << 5; private void ForgetKnownVehicleProperties() { @@ -634,6 +636,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownWaterLevel = null; m_knownPosition = null; m_knownVelocity = null; + m_knownForce = null; m_knownOrientation = null; m_knownRotationalVelocity = null; m_knownRotationalForce = null; @@ -652,6 +655,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.ForceVelocity = VehicleVelocity; BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); } + if ((m_knownChanged & m_knownChangedForce) != 0) + Prim.AddForce((Vector3)m_knownForce, false, true); + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = VehicleRotationalVelocity; @@ -730,6 +736,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } + private void VehicleAddForce(Vector3 aForce) + { + m_knownForce += aForce; + m_knownChanged |= m_knownChangedForce; + } + private Vector3 VehicleRotationalVelocity { get @@ -784,10 +796,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin linearMotorContribution *= VehicleOrientation; // ================================================================== - // Gravity and Buoyancy - // There is some gravity, make a gravity force vector that is applied after object velocity. + // Buoyancy: force to overcome gravity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); + Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * (m_VehicleBuoyancy - 1f); Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); @@ -812,14 +823,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin newVelocity.Z = 0; // ================================================================== - // Clamp REALLY high or low velocities + // Clamp high or low velocities float newVelocityLengthSq = newVelocity.LengthSquared(); - if (newVelocityLengthSq > 1e6f) + // if (newVelocityLengthSq > 1e6f) + if (newVelocityLengthSq > 1000f) { newVelocity /= newVelocity.Length(); newVelocity *= 1000f; } - else if (newVelocityLengthSq < 1e-6f) + // else if (newVelocityLengthSq < 1e-6f) + else if (newVelocityLengthSq < 0.001f) newVelocity = Vector3.Zero; // ================================================================== @@ -828,15 +841,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleVelocity = newVelocity; // Other linear forces are applied as forces. - Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; - if (totalDownForce != Vector3.Zero) + Vector3 totalDownForce = buoyancyContribution * m_vehicleMass; + if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) { - Prim.AddForce(totalDownForce, false); + VehicleAddForce(totalDownForce); } - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6},buoyContrib={7}", Prim.LocalID, newVelocity, totalDownForce, - linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution + linearMotorContribution, terrainHeightContribution, hoverContribution, + limitMotorUpContribution, buoyancyContribution ); } // end MoveLinear() -- cgit v1.1 From 2ecd8e6720ebc9668aa30a8276c8b15a8650b8fe Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 06:45:51 -0800 Subject: BulletSim: add values for material friction and restitution. Fix line endings in material definition file. --- .../Region/Physics/BulletSPlugin/BSMaterials.cs | 376 ++++++++++----------- 1 file changed, 185 insertions(+), 191 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs index 663b6f4..390c2f9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs @@ -1,191 +1,185 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * 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. - * * 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. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using System.Reflection; -using Nini.Config; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - -public struct MaterialAttributes -{ - // Material type values that correspond with definitions for LSL - public enum Material : int - { - Stone = 0, - Metal, - Glass, - Wood, - Flesh, - Plastic, - Rubber, - Light, - // Hereafter are BulletSim additions - Avatar, - NumberOfTypes // the count of types in the enum. - } - // Names must be in the order of the above enum. - public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", - "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; - public static string[] MaterialAttribs = { "Density", "Friction", "Restitution", - "ccdMotionThreshold", "ccdSweptSphereRadius" }; - - public MaterialAttributes(string t, float d, float f, float r, float ccdM, float ccdS) - { - type = t; - density = d; - friction = f; - restitution = r; - ccdMotionThreshold = ccdM; - ccdSweptSphereRadius = ccdS; - } - public string type; - public float density; - public float friction; - public float restitution; - public float ccdMotionThreshold; - public float ccdSweptSphereRadius; -} - -public static class BSMaterials -{ - public static MaterialAttributes[] Attributes; - - static BSMaterials() - { - // Attribute sets for both the non-physical and physical instances of materials. - Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; - } - - // This is where all the default material attributes are defined. - public static void InitializeFromDefaults(ConfigurationParameters parms) - { - // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", - // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; - float dFriction = parms.defaultFriction; - float dRestitution = parms.defaultRestitution; - float dDensity = parms.defaultDensity; - float dCcdM = parms.ccdMotionThreshold; - float dCcdS = parms.ccdSweptSphereRadius; - Attributes[(int)MaterialAttributes.Material.Stone] = - new MaterialAttributes("stone",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Metal] = - new MaterialAttributes("metal",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Glass] = - new MaterialAttributes("glass",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Wood] = - new MaterialAttributes("wood",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Flesh] = - new MaterialAttributes("flesh",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Plastic] = - new MaterialAttributes("plastic",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Rubber] = - new MaterialAttributes("rubber",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Light] = - new MaterialAttributes("light",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Avatar] = - new MaterialAttributes("avatar",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - - Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("stonePhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("metalPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("glassPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("woodPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("fleshPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("plasticPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("rubberPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("lightPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("avatarPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - } - - // Under the [BulletSim] section, one can change the individual material - // attribute values. The format of the configuration parameter is: - // ["Physical"] = floatValue - // For instance: - // [BulletSim] - // StoneFriction = 0.2 - // FleshRestitutionPhysical = 0.8 - // Materials can have different parameters for their static and - // physical instantiations. When setting the non-physical value, - // both values are changed. Setting the physical value only changes - // the physical value. - public static void InitializefromParameters(IConfig pConfig) - { - int matType = 0; - foreach (string matName in MaterialAttributes.MaterialNames) - { - foreach (string attribName in MaterialAttributes.MaterialAttribs) - { - string paramName = matName + attribName; - if (pConfig.Contains(paramName)) - { - float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue(matType, attribName, paramValue); - // set the physical value also - SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); - } - paramName += "Physical"; - if (pConfig.Contains(paramName)) - { - float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); - } - } - matType++; - } - } - - private static void SetAttributeValue(int matType, string attribName, float val) - { - MaterialAttributes thisAttrib = Attributes[matType]; - FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); - if (fieldInfo != null) - { - fieldInfo.SetValue(thisAttrib, val); - Attributes[matType] = thisAttrib; - } - } - - public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) - { - int ind = (int)type; - if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; - return Attributes[ind]; - } - -} -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * 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. + * * 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. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public struct MaterialAttributes +{ + // Material type values that correspond with definitions for LSL + public enum Material : int + { + Stone = 0, + Metal, + Glass, + Wood, + Flesh, + Plastic, + Rubber, + Light, + // Hereafter are BulletSim additions + Avatar, + NumberOfTypes // the count of types in the enum. + } + // Names must be in the order of the above enum. + public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", + "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + public static string[] MaterialAttribs = { "Density", "Friction", "Restitution"}; + + public MaterialAttributes(string t, float d, float f, float r) + { + type = t; + density = d; + friction = f; + restitution = r; + } + public string type; + public float density; + public float friction; + public float restitution; +} + +public static class BSMaterials +{ + public static MaterialAttributes[] Attributes; + + static BSMaterials() + { + // Attribute sets for both the non-physical and physical instances of materials. + Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; + } + + // This is where all the default material attributes are defined. + public static void InitializeFromDefaults(ConfigurationParameters parms) + { + // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL + // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", + // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + float dFriction = parms.defaultFriction; + float dRestitution = parms.defaultRestitution; + float dDensity = parms.defaultDensity; + Attributes[(int)MaterialAttributes.Material.Stone] = + new MaterialAttributes("stone",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Metal] = + new MaterialAttributes("metal",dDensity, 0.3f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Glass] = + new MaterialAttributes("glass",dDensity, 0.2f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Wood] = + new MaterialAttributes("wood",dDensity, 0.6f, 0.5f); + Attributes[(int)MaterialAttributes.Material.Flesh] = + new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f); + Attributes[(int)MaterialAttributes.Material.Plastic] = + new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Rubber] = + new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f); + Attributes[(int)MaterialAttributes.Material.Light] = + new MaterialAttributes("light",dDensity, dFriction, dRestitution); + Attributes[(int)MaterialAttributes.Material.Avatar] = + new MaterialAttributes("avatar",60f, 0.2f, 0f); + + Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); + Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); + Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); + Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); + Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); + } + + // Under the [BulletSim] section, one can change the individual material + // attribute values. The format of the configuration parameter is: + // ["Physical"] = floatValue + // For instance: + // [BulletSim] + // StoneFriction = 0.2 + // FleshRestitutionPhysical = 0.8 + // Materials can have different parameters for their static and + // physical instantiations. When setting the non-physical value, + // both values are changed. Setting the physical value only changes + // the physical value. + public static void InitializefromParameters(IConfig pConfig) + { + int matType = 0; + foreach (string matName in MaterialAttributes.MaterialNames) + { + foreach (string attribName in MaterialAttributes.MaterialAttribs) + { + string paramName = matName + attribName; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue(matType, attribName, paramValue); + // set the physical value also + SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + paramName += "Physical"; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + } + matType++; + } + } + + private static void SetAttributeValue(int matType, string attribName, float val) + { + MaterialAttributes thisAttrib = Attributes[matType]; + FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); + if (fieldInfo != null) + { + fieldInfo.SetValue(thisAttrib, val); + Attributes[matType] = thisAttrib; + } + } + + public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) + { + int ind = (int)type; + if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; + return Attributes[ind]; + } + +} +} -- cgit v1.1 From cc59e3cbdf2d660422bc8707816d7d30d7c72b92 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:21:04 -0800 Subject: BulletSim: only check position sanity if the prim is physical -- the user can do anything dumb they wish. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e392078..62aaf80 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1399,7 +1399,7 @@ public sealed class BSPrim : BSPhysObject _rotationalVelocity = entprop.RotationalVelocity; // The sanity check can change the velocity and/or position. - if (PositionSanityCheck(true)) + if (IsPhysical && PositionSanityCheck(true)) { entprop.Position = _position; entprop.Velocity = _velocity; @@ -1413,8 +1413,6 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); - // BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG - base.RequestPhysicsterseUpdate(); } /* -- cgit v1.1 From 18fe35906dd07ecfe8f8b439f5648982262aa17f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:22:29 -0800 Subject: BulletSim: add detail logging detail flag so I don't have to comment and uncomment the detail logging when changing the depth of logged info. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 61 ++++++++++++---------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index b94dcf6..e77b6ba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -65,9 +65,16 @@ public sealed class BSShapeCollection : IDisposable private Dictionary Meshes = new Dictionary(); private Dictionary Hulls = new Dictionary(); + private bool DDetail = false; + public BSShapeCollection(BSScene physScene) { PhysicsScene = physScene; + // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) + // While detailed debugging is still active, this is better than commenting out all the + // DetailLog statements. When debugging slows down, this and the protected logging + // statements can be commented/removed. + DDetail = true; } public void Dispose() @@ -126,13 +133,13 @@ public sealed class BSShapeCollection : IDisposable { lock (m_collectionActivityLock) { - DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() { if (!BulletSimAPI.IsInWorld2(body.ptr)) { BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); - DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); } }); } @@ -149,7 +156,7 @@ public sealed class BSShapeCollection : IDisposable { PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() { - DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", body.ID, body, inTaintTime); // If the caller needs to know the old body is going away, pass the event up. if (bodyCallback != null) bodyCallback(body); @@ -157,7 +164,7 @@ public sealed class BSShapeCollection : IDisposable if (BulletSimAPI.IsInWorld2(body.ptr)) { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); - DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); } // Zero any reference to the shape so it is not freed when the body is deleted. @@ -184,7 +191,7 @@ public sealed class BSShapeCollection : IDisposable { // There is an existing instance of this mesh. meshDesc.referenceCount++; - DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); } else @@ -194,7 +201,7 @@ public sealed class BSShapeCollection : IDisposable meshDesc.shapeKey = shape.shapeKey; // We keep a reference to the underlying IMesh data so a hull can be built meshDesc.referenceCount = 1; - DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); ret = true; } @@ -207,7 +214,7 @@ public sealed class BSShapeCollection : IDisposable { // There is an existing instance of this hull. hullDesc.referenceCount++; - DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); } else @@ -216,7 +223,7 @@ public sealed class BSShapeCollection : IDisposable hullDesc.ptr = shape.ptr; hullDesc.shapeKey = shape.shapeKey; hullDesc.referenceCount = 1; - DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); ret = true; @@ -246,7 +253,7 @@ public sealed class BSShapeCollection : IDisposable if (shape.isNativeShape) { // Native shapes are not tracked and are released immediately - DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); if (shapeCallback != null) shapeCallback(shape); BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); @@ -286,7 +293,7 @@ public sealed class BSShapeCollection : IDisposable if (shapeCallback != null) shapeCallback(shape); meshDesc.lastReferenced = System.DateTime.Now; Meshes[shape.shapeKey] = meshDesc; - DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", BSScene.DetailLogZero, shape, meshDesc.referenceCount); } @@ -307,7 +314,7 @@ public sealed class BSShapeCollection : IDisposable hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; - DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", BSScene.DetailLogZero, shape, hullDesc.referenceCount); } } @@ -325,13 +332,13 @@ public sealed class BSShapeCollection : IDisposable // Failed the sanity check!! PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", LogHeader, shape.type, shape.ptr.ToString("X")); - DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); return; } int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); - DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); for (int ii = numChildren - 1; ii >= 0; ii--) { @@ -379,7 +386,7 @@ public sealed class BSShapeCollection : IDisposable } } - DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) { @@ -410,7 +417,7 @@ public sealed class BSShapeCollection : IDisposable // an avatar capsule is close to a native shape (it is not shared) ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; haveShape = true; } @@ -420,7 +427,7 @@ public sealed class BSShapeCollection : IDisposable if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) { ret = GetReferenceToCompoundShape(prim, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); haveShape = true; } @@ -465,7 +472,7 @@ public sealed class BSShapeCollection : IDisposable { ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_SPHERE, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); } } @@ -479,7 +486,7 @@ public sealed class BSShapeCollection : IDisposable { ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); } } @@ -504,13 +511,13 @@ public sealed class BSShapeCollection : IDisposable { // Update prim.BSShape to reference a hull of this shape. ret = GetReferenceToHull(prim,shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } else { ret = GetReferenceToMesh(prim, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } return ret; @@ -528,7 +535,7 @@ public sealed class BSShapeCollection : IDisposable BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. - DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", prim.LocalID, newShape, prim.Scale); prim.PhysShape = newShape; @@ -554,7 +561,7 @@ public sealed class BSShapeCollection : IDisposable newShape = new BulletShape( BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) , shapeType); - DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); + if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { @@ -589,7 +596,7 @@ public sealed class BSShapeCollection : IDisposable if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) return false; - DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); // Since we're recreating new, get rid of the reference to the previous shape @@ -662,7 +669,7 @@ public sealed class BSShapeCollection : IDisposable if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) return false; - DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); // Remove usage of the previous shape. @@ -808,7 +815,7 @@ public sealed class BSShapeCollection : IDisposable // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. CreateGeomMeshOrHull(prim, shapeCallback); BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); - DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", prim.LocalID, cShape, prim.PhysShape); prim.PhysShape = cShape; @@ -935,13 +942,13 @@ public sealed class BSShapeCollection : IDisposable { bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); - DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } else { bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); - DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } aBody = new BulletBody(prim.LocalID, bodyPtr); -- cgit v1.1 From edd1b353a5b683b7d9b22e80d97e15e05f34611c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:23:20 -0800 Subject: BulletSim: update and add to the TODO list. --- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 87 ++++++++++++++-------- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 68f25fc..d51003c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -6,14 +6,34 @@ CRASHES Causes many errors. Doesn't stop after first error with box shape. Eventually crashes when deleting the object. -BULLETSIM TODO LIST: +VEHICLES TODO LIST: ================================================= Neb car jiggling left and right + Happens on terrain and any other mesh object. Flat cubes are much smoother. Vehicles (Move smoothly) -Light cycle falling over when driving -Light cycle not banking -Do single prim vehicles don't seem to properly vehiclize. -Gun sending shooter flying +Add vehicle collisions so IsColliding is properly reported. + Needed for banking, limitMotorUp, movementLimiting, ... +Some vehicles should not be able to turn if no speed or off ground. +For limitMotorUp, use raycast down to find if vehicle is in the air. +Implement function efficiency for lineaar and angular motion. +Should vehicle angular/linear movement friction happen after all the components + or does it only apply to the basic movement? +After getting off a vehicle, the root prim is phantom (can be walked through) + Need to force a position update for the root prim after compound shape destruction +Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) +Implement referenceFrame for all the motion routines. +Cannot edit/move a vehicle being ridden: it jumps back to the origional position. + +BULLETSIM TODO LIST: +================================================= +Disable activity of passive linkset children. + Since the linkset is a compound object, the old prims are left lying + around and need to be phantomized so they don't collide, ... +Scenes with hundred of thousands of static objects take a lot of physics CPU time. +BSPrim.Force should set a continious force on the prim. The force should be + applied each tick. Some limits? +Single prim vehicles don't seem to properly vehiclize. +Gun sending shooter flying. Collision margin (gap between physical objects lying on each other) Boundry checking (crashes related to crossing boundry) Add check for border edge position for avatars and objects. @@ -28,10 +48,11 @@ Small physical objects do not interact correctly Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. Add PID motor for avatar movement (slow to stop, ...) -Implement function efficiency for lineaar and angular motion. +setForce should set a constant force. Different than AddImpulse. +Implement raycast. +Implement ShapeCollection.Dispose() +Implement water as a plain so raycasting and collisions can happen with same. -After getting off a vehicle, the root prim is phantom (can be walked through) - Need to force a position update for the root prim after compound shape destruction Find/remove avatar collision with ID=0. Test avatar walking up stairs. How does compare with SL. Radius of the capsule affects ability to climb edges. @@ -39,19 +60,16 @@ Tune terrain/object friction to be closer to SL. Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. -Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) Speed up creation of large physical linksets For instance, sitting in Neb's car (130 prims) takes several seconds to become physical Performance test with lots of avatars. Can BulletSim support a thousand? Optimize collisions in C++: only send up to the object subscribed to collisions. Use collision subscription and remove the collsion(A,B) and collision(B,A) -Check wheter SimMotionState needs large if statement (see TODO). +Check whether SimMotionState needs large if statement (see TODO). Implement 'top colliders' info. Avatar jump -Implement meshes or just verify that they work. -Do prim hash codes work for sculpties and meshes? Performance measurement and changes to make quicker. Implement detailed physics stats (GetStats()). @@ -67,8 +85,6 @@ Performance of closures and delegates for taint processing Is there are more efficient method of implementing pre and post step actions? See http://www.codeproject.com/Articles/29922/Weak-Events-in-C -Package Bullet source mods for Bullet internal stats output - Physics Arena central pyramid: why is one side permiable? INTERNAL IMPROVEMENT/CLEANUP @@ -85,33 +101,42 @@ Complete implemention of preStepActions Replace vehicle step call with prestep event. Is there a need for postStepActions? postStepTaints? Implement linkset by setting position of children when root updated. (LinksetManual) + Linkset implementation using manual prim movement. LinkablePrim class? Would that simplify/centralize the linkset logic? -Linkset implementation using manual prim movement. -Linkset implementation using compound shapes. - Compound shapes will need the LocalID in the shapes and collision - processing to get it from there. BSScene.UpdateParameterSet() is broken. How to set params on objects? Remove HeightmapInfo from terrain specification. Since C++ code does not need terrain height, this structure et al are not needed. Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will bob at the water level. BSPrim.PositionSanityCheck(). +THREADING +================================================= +Do taint action immediately if not actually executing Bullet. + Add lock around Bullet execution and just do taint actions if simulation is not happening. + DONE DONE DONE DONE ================================================= -Cleanup code in BSDynamics by using motors. -Consider implementing terrain with a mesh rather than heightmap. +Cleanup code in BSDynamics by using motors. (Resolution: started) +Consider implementing terrain with a mesh rather than heightmap. (Resolution: done) Would have better and adjustable resolution. -NOTDONE: Build terrain mesh so heighmap is height of the center of the square meter. - SL and ODE define meter square as being at one corner with one diagional. -Terrain as mesh. +Build terrain mesh so heighmap is height of the center of the square meter. + Resolution: NOT DONE: SL and ODE define meter square as being at one corner with one diagional. +Terrain as mesh. (Resolution: done) How are static linksets seen by the physics engine? - A: they are not linked in physics. When moved, all the children are repositioned. -Remember to remove BSScene.DetailLog Refresh call. -Convert BSCharacter to use all API2 + Resolution: they are not linked in physics. When moved, all the children are repositioned. +Convert BSCharacter to use all API2 (Resolution: done) Avatar pushing difficult (too heavy?) -Use asset service passed to BulletSim to get sculptie bodies, etc. -Vehicles (fix bouncing on terrain) -Remove old code in DLL (all non-API2 stuff). -Measurements of mega-physical prim performance (with graph) +Use asset service passed to BulletSim to get sculptie bodies, etc. (Resolution: done) +Remove old code in DLL (all non-API2 stuff). (Resolution: done) +Measurements of mega-physical prim performance (with graph) (Resolution: done, email) Debug Bullet internal stats output (why is timing all wrong?) - Bullet stats logging only works with a single instance of Bullet (one region). \ No newline at end of file + Resolution: Bullet stats logging only works with a single instance of Bullet (one region). +Implement meshes or just verify that they work. (Resolution: they do!) +Do prim hash codes work for sculpties and meshes? (Resolution: yes) +Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound) + Compound shapes will need the LocalID in the shapes and collision + processing to get it from there. +Light cycle falling over when driving (Resolution: implemented VerticalAttractor) +Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) +Package Bullet source mods for Bullet internal stats output + (Resolution: move code into WorldData.h rather than relying on patches) \ No newline at end of file -- cgit v1.1 From 7fd8202ae3fbe5627396f34dfc03e3571f4f9fe4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:24:24 -0800 Subject: BulletSim: rewrite and improve vehicle angularDeflection, verticalAttraction, linearMotorUp and related vehicle forces. Fixed problems with downward vehicle position correction forces being too large. Add vehicle collision flag so can sense whether vehicle is on the ground. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 212 +++++++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 1 + 2 files changed, 130 insertions(+), 83 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 09aee17..fa3110c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -24,21 +24,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - -/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to - * call the BulletSim system. - */ -/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. + * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial + * are Copyright (c) 2009 Linden Research, Inc and are used under their license + * of Creative Commons Attribution-Share Alike 3.0 + * (http://creativecommons.org/licenses/by-sa/3.0/). */ using System; @@ -111,7 +100,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_bankingEfficiency = 0; private float m_bankingMix = 0; private float m_bankingTimescale = 0; - private Vector3 m_lastBanking = Vector3.Zero; //Hover and Buoyancy properties private float m_VhoverHeight = 0f; @@ -125,8 +113,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin //Attractor properties private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); - private float m_verticalAttractionEfficiency = 1.0f; // damped - private float m_verticalAttractionTimescale = 600f; // Timescale > 500 means no vert attractor. + private float m_verticalAttractionEfficiency = 1.0f; // damped + private float m_verticalAttractionCutoff = 500f; // per the documentation + // Timescale > cutoff means no vert attractor. + private float m_verticalAttractionTimescale = 510f; public BSDynamics(BSScene myScene, BSPrim myPrim) { @@ -329,7 +319,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 1000; m_bankingMix = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags = (VehicleFlag)0; @@ -364,7 +353,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 10; m_bankingMix = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -374,6 +362,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + break; case Vehicle.TYPE_CAR: m_linearMotorDirection = Vector3.Zero; @@ -403,7 +392,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.2f; m_bankingMix = 1; m_bankingTimescale = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -442,7 +430,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.3f; m_bankingMix = 0.8f; m_bankingTimescale = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY @@ -481,7 +468,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 1; m_bankingMix = 0.7f; m_bankingTimescale = 2; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -520,7 +506,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingMix = 0.7f; m_bankingTimescale = 5; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; @@ -554,8 +539,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Z goes away and we keep X and Y m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) - - // m_bankingMotor = new BSVMotor("BankingMotor", ...); } // Some of the properties of this prim may have changed. @@ -577,15 +560,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin float angularDamping = PhysicsScene.Params.vehicleAngularDamping; BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + // Vehicles report collision events so we know when it's on the ground + BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + // DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet // Vector3 localInertia = new Vector3(1f, 1f, 1f); - Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); + // Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); + Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); } + else + { + BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + } } public bool RemoveBodyDependencies(BSPhysObject prim) @@ -618,10 +609,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float? m_knownWaterLevel; private Vector3? m_knownPosition; private Vector3? m_knownVelocity; - private Vector3? m_knownForce; + private Vector3 m_knownForce; private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; - private Vector3? m_knownRotationalForce; + private Vector3 m_knownRotationalForce; + private float? m_knownForwardSpeed; private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; @@ -636,10 +628,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownWaterLevel = null; m_knownPosition = null; m_knownVelocity = null; - m_knownForce = null; + m_knownForce = Vector3.Zero; m_knownOrientation = null; m_knownRotationalVelocity = null; - m_knownRotationalForce = null; + m_knownRotationalForce = Vector3.Zero; + m_knownForwardSpeed = null; m_knownChanged = 0; } private void PushKnownChanged() @@ -761,6 +754,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownRotationalForce += aForce; m_knownChanged |= m_knownChangedRotationalForce; } + private float VehicleForwardSpeed + { + get + { + if (m_knownForwardSpeed == null) + m_knownForwardSpeed = (VehicleVelocity * Quaternion.Inverse(VehicleOrientation)).X; + return (float)m_knownForwardSpeed; + } + } + #endregion // Known vehicle value functions // One step of the vehicle properties for the next 'pTimestep' seconds. @@ -798,7 +801,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Buoyancy: force to overcome gravity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * (m_VehicleBuoyancy - 1f); + // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. + Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); @@ -847,8 +851,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleAddForce(totalDownForce); } - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6},buoyContrib={7}", - Prim.LocalID, newVelocity, totalDownForce, + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", + Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); + VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", + Prim.LocalID, linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution, buoyancyContribution ); @@ -971,21 +977,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : - // Prevent ground vehicles from motoring into the sky.This flag has a subtle effect when + // Prevent ground vehicles from motoring into the sky. This flag has a subtle effect when // used with conjunction with banking: the strength of the banking will decay when the // vehicle no longer experiences collisions. The decay timescale is the same as // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering // when they are in mid jump. - // TODO: this code is wrong. Also, what should it do for boats? + // TODO: this code is wrong. Also, what should it do for boats (height from water)? + // This is just using the ground and a general collision check. Should really be using + // a downward raycast to find what is below. public Vector3 ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; + if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. - // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition); - if (distanceAboveGround > 1f) + // Not colliding if the vehicle is off the ground + if (!Prim.IsColliding) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); @@ -1006,8 +1015,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ======================================================================= // Apply the effect of the angular motor. // The 'contribution' is how much angular correction velocity each function wants. - // All the contributions are added together and the orientation of the vehicle - // is changed by all the contributed corrections. + // All the contributions are added together and the resulting velocity is + // set directly on the vehicle. private void MoveAngular(float pTimestep) { // The user wants how many radians per second angular change? @@ -1030,7 +1039,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 deflectionContribution = ComputeAngularDeflection(); - Vector3 bankingContribution = ComputeAngularBanking(angularMotorContribution.Z); + Vector3 bankingContribution = ComputeAngularBanking(); // ================================================================== m_lastVertAttractor = verticalAttractionContribution; @@ -1095,13 +1104,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: + // Some vehicles, like boats, should always keep their up-side up. This can be done by + // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to + // the world z-axis (a.k.a. "up"). To take advantage of this feature you would set the + // VEHICLE_VERTICAL_ATTRACTION_TIMESCALE to control the period of the spring frequency, + // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An + // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an + // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. public Vector3 ComputeAngularVerticalAttraction() { Vector3 ret = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... - if (m_verticalAttractionTimescale < 500) + if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1128,9 +1144,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Scale the correction force by how far we're off from vertical. // Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over. - // float clampedZError = ClampInRange(0.1f, Math.Abs(verticalError.Z), 1f); float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f); - // float vertForce = 1f / clampedSqrZError * m_verticalAttractionEfficiency; float vertForce = 1f / clampedSqrZError; ret *= vertForce; @@ -1147,70 +1161,102 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Return the angular correction to correct the direction the vehicle is pointing to be // the direction is should want to be pointing. + // The vehicle is moving in some direction and correct its orientation to it is pointing + // in that direction. + // TODO: implement reference frame. public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG debug the other contributors first + return ret; // DEBUG DEBUG DEBUG debug one force at a time if (m_angularDeflectionEfficiency != 0) { - // Where the vehicle should want to point relative to the vehicle - Vector3 preferredDirection = Vector3.UnitX * m_referenceFrame; + // The direction the vehicle is moving + Vector3 movingDirection = VehicleVelocity; + movingDirection.Normalize(); - // Where the vehicle is pointing relative to the vehicle. - Vector3 currentDirection = Vector3.UnitX * Quaternion.Add(VehicleOrientation, m_referenceFrame); + // The direction the vehicle is pointing + Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; + pointingDirection.Normalize(); - // Difference between where vehicle is pointing and where it should wish to point - Vector3 directionCorrection = preferredDirection - currentDirection; + // The difference between what is and what should be + Vector3 deflectionError = movingDirection - pointingDirection; // Scale the correction by recovery timescale and efficiency - ret = directionCorrection * m_angularDeflectionEfficiency / m_angularDeflectionTimescale; + ret = (-deflectionError * VehicleForwardSpeed) * m_angularDeflectionEfficiency; + ret /= m_angularDeflectionTimescale; - VDetailLog("{0}, MoveAngular,Deflection,perfDir={1},currentDir={2},dirCorrection={3},ret={4}", - Prim.LocalID, preferredDirection, currentDirection, directionCorrection, ret); + VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", + Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); } return ret; } - // Return an angular change to tip the vehicle (around X axis) when turning (turned around Z). - // Remembers the last banking value calculated and returns the difference needed this tick. - // TurningFactor is rate going left or right (pos=left, neg=right, scale=0..1). - public Vector3 ComputeAngularBanking(float turningFactor) + // Return an angular change to rotate the vehicle around the Z axis when the vehicle + // is tipped around the X axis. + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: + // The vertical attractor feature must be enabled in order for the banking behavior to + // function. The way banking works is this: a rotation around the vehicle's roll-axis will + // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude + // of the yaw effect will be proportional to the + // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's + // velocity along its preferred axis of motion. + // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any + // positive rotation (by the right-hand rule) about the roll-axis will effect a + // (negative) torque around the yaw-axis, making it turn to the right--that is the + // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. + // Negating the banking coefficient will make it so that the vehicle leans to the + // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). + // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making + // banking vehicles do what you want rather than what the laws of physics allow. + // For example, consider a real motorcycle...it must be moving forward in order for + // it to turn while banking, however video-game motorcycles are often configured + // to turn in place when at a dead stop--because they are often easier to control + // that way using the limited interface of the keyboard or game controller. The + // VEHICLE_BANKING_MIX enables combinations of both realistic and non-realistic + // banking by functioning as a slider between a banking that is correspondingly + // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the + // banking effect depends only on the vehicle's rotation about its roll-axis compared + // to "dynamic" where the banking is also proportional to its velocity along its + // roll-axis. Finding the best value of the "mixture" will probably require trial and error. + // The time it takes for the banking behavior to defeat a preexisting angular velocity about the + // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to + // bank quickly then give it a banking timescale of about a second or less, otherwise you can + // make a sluggish vehicle by giving it a timescale of several seconds. + public Vector3 ComputeAngularBanking() { Vector3 ret = Vector3.Zero; - Vector3 computedBanking = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG debug the other contributors first - if (m_bankingEfficiency != 0) + if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { - Vector3 currentDirection = Vector3.UnitX * VehicleOrientation; - - float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); + // This works by rotating a unit vector to the orientation of the vehicle. The + // roll (tilt) will be Y component of a tilting Z vector (zero for no tilt + // up to one for full over). + Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; - //Use the square of the efficiency, as it looks much more how SL banking works - float effSquared = (m_bankingEfficiency * m_bankingEfficiency); - if (m_bankingEfficiency < 0) - effSquared *= -1; //Keep the negative! + // Figure out the yaw value for this much roll. + float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency; + // Keep the sign + if (rollComponents.Y < 0f) + turnComponent = -turnComponent; - float mix = Math.Abs(m_bankingMix); - // TODO: Must include reference frame. - float forwardSpeed = VehicleVelocity.X; + // TODO: there must be a better computation of the banking force. + float bankingTurnForce = turnComponent; - if (!Prim.IsColliding && forwardSpeed > mix) - { - computedBanking.X = ClampInRange(-3f, turningFactor * (effSquared * mult), 3f); - } + // actual error = static turn error + dynamic turn error + float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed; + // TODO: the banking effect should not go to infinity but what to limit it to? + mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f); - // 'computedBanking' is now how much banking that should be happening. - ret = computedBanking - m_lastBanking; + // Build the force vector to change rotation from what it is to what it should be + ret.Z = -mixedBankingError; - // Scale the correction by timescale and efficiency - ret /= m_bankingTimescale * m_bankingEfficiency; + // Don't do it all at once. + ret /= m_bankingTimescale; - VDetailLog("{0}, MoveAngular,Banking,computedB={1},lastB={2},bEff={3},effSq={4},mult={5},mix={6},banking={7}", - Prim.LocalID, computedBanking, m_lastBanking, m_bankingEfficiency, effSquared, mult, mix, ret); + VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}", + Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret); } - m_lastBanking = computedBanking; return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index a5acfd1..2671995 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -360,6 +360,7 @@ public enum CollisionFlags : uint // Following used by BulletSim to control collisions and updates BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, BS_FLOATS_ON_WATER = 1 << 11, + BS_VEHICLE_COLLISIONS = 1 << 12, BS_NONE = 0, BS_ALL = 0xFFFFFFFF, -- cgit v1.1 From 707e186aa32cb65b8ad396b7f03d8902eeac71c7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:34:30 -0800 Subject: BulletSim: update DLLs and SOs with vehicle collision event check --- bin/lib32/BulletSim.dll | Bin 551936 -> 552960 bytes bin/lib32/libBulletSim.so | Bin 1708731 -> 1720874 bytes bin/lib64/BulletSim.dll | Bin 700928 -> 702464 bytes bin/lib64/libBulletSim.so | Bin 1846064 -> 1859487 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 75d5bc3..9834faa 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index b648da1..3c8e034 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index fc0fdca..75999f0 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index a1b099c..a8a4720 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- cgit v1.1 From 0568c76a8801408665730702c97717d3c05cfe4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 7 Dec 2012 00:47:04 +0000 Subject: Use a thread abort safe version of OpenMetaverse.DoubleDictionary with the aim of avoiding OpenSimulator problems due to script thread aborts. When an object is removed, its scripts are stopped and then the thread running them is aborted if stop takes too long. However, it appears that aborting a thread at just the wrong moment when it is obtaining a ReaderWriterLockSlim lock can leave this lock in an inconsistent state. One symptom of this is that mono leaps to 100% cpu and a vm thread dump reveals lots of threads waiting for a ReaderWriterLockSlim lock without any thread actually holding it. This is probably the same problem as encountered originally in commit 12cebb12 This commit looks to plaster this problem by putting lock obtaining methods inside finally blocks which should be uninterruptible by thread aborts. --- .../Framework/DoubleDictionaryThreadAbortSafe.cs | 508 +++++++++++++++++++++ OpenSim/Region/Framework/Scenes/EntityManager.cs | 4 +- 2 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs diff --git a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs new file mode 100644 index 0000000..9056548 --- /dev/null +++ b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2008, openmetaverse.org, http://opensimulator.org/ + * All rights reserved. + * + * - 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. + * - Neither the name of the openmetaverse.org nor the names + * of its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Threading; +using System.Collections.Generic; + +namespace OpenSim.Framework +{ + /// + /// A double dictionary that is thread abort safe. + /// + /// + /// This adapts OpenMetaverse.DoubleDictionary to be thread-abort safe by acquiring ReaderWriterLockSlim within + /// a finally section (which can't be interrupted by Thread.Abort()). + /// + public class DoubleDictionaryThreadAbortSafe + { + Dictionary Dictionary1; + Dictionary Dictionary2; + ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); + + public DoubleDictionaryThreadAbortSafe() + { + Dictionary1 = new Dictionary(); + Dictionary2 = new Dictionary(); + } + + public DoubleDictionaryThreadAbortSafe(int capacity) + { + Dictionary1 = new Dictionary(capacity); + Dictionary2 = new Dictionary(capacity); + } + + public void Add(TKey1 key1, TKey2 key2, TValue value) + { + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterWriteLock(); + gotLock = true; + } + + if (Dictionary1.ContainsKey(key1)) + { + if (!Dictionary2.ContainsKey(key2)) + throw new ArgumentException("key1 exists in the dictionary but not key2"); + } + else if (Dictionary2.ContainsKey(key2)) + { + if (!Dictionary1.ContainsKey(key1)) + throw new ArgumentException("key2 exists in the dictionary but not key1"); + } + + Dictionary1[key1] = value; + Dictionary2[key2] = value; + } + finally + { + if (gotLock) + rwLock.ExitWriteLock(); + } + } + + public bool Remove(TKey1 key1, TKey2 key2) + { + bool success; + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterWriteLock(); + gotLock = true; + } + + Dictionary1.Remove(key1); + success = Dictionary2.Remove(key2); + } + finally + { + if (gotLock) + rwLock.ExitWriteLock(); + } + + return success; + } + + public bool Remove(TKey1 key1) + { + bool found = false; + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterWriteLock(); + gotLock = true; + } + + // This is an O(n) operation! + TValue value; + if (Dictionary1.TryGetValue(key1, out value)) + { + foreach (KeyValuePair kvp in Dictionary2) + { + if (kvp.Value.Equals(value)) + { + Dictionary1.Remove(key1); + Dictionary2.Remove(kvp.Key); + found = true; + break; + } + } + } + } + finally + { + if (gotLock) + rwLock.ExitWriteLock(); + } + + return found; + } + + public bool Remove(TKey2 key2) + { + bool found = false; + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterWriteLock(); + gotLock = true; + } + + // This is an O(n) operation! + TValue value; + if (Dictionary2.TryGetValue(key2, out value)) + { + foreach (KeyValuePair kvp in Dictionary1) + { + if (kvp.Value.Equals(value)) + { + Dictionary2.Remove(key2); + Dictionary1.Remove(kvp.Key); + found = true; + break; + } + } + } + } + finally + { + if (gotLock) + rwLock.ExitWriteLock(); + } + + return found; + } + + public void Clear() + { + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterWriteLock(); + gotLock = true; + } + + Dictionary1.Clear(); + Dictionary2.Clear(); + } + finally + { + if (gotLock) + rwLock.ExitWriteLock(); + } + } + + public int Count + { + get { return Dictionary1.Count; } + } + + public bool ContainsKey(TKey1 key) + { + return Dictionary1.ContainsKey(key); + } + + public bool ContainsKey(TKey2 key) + { + return Dictionary2.ContainsKey(key); + } + + public bool TryGetValue(TKey1 key, out TValue value) + { + bool success; + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + success = Dictionary1.TryGetValue(key, out value); + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + + return success; + } + + public bool TryGetValue(TKey2 key, out TValue value) + { + bool success; + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + success = Dictionary2.TryGetValue(key, out value); + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + + return success; + } + + public void ForEach(Action action) + { + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + foreach (TValue value in Dictionary1.Values) + action(value); + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + } + + public void ForEach(Action> action) + { + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + foreach (KeyValuePair entry in Dictionary1) + action(entry); + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + } + + public void ForEach(Action> action) + { + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + foreach (KeyValuePair entry in Dictionary2) + action(entry); + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + } + + public TValue FindValue(Predicate predicate) + { + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + foreach (TValue value in Dictionary1.Values) + { + if (predicate(value)) + return value; + } + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + + return default(TValue); + } + + public IList FindAll(Predicate predicate) + { + IList list = new List(); + bool gotLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterReadLock(); + gotLock = true; + } + + foreach (TValue value in Dictionary1.Values) + { + if (predicate(value)) + list.Add(value); + } + } + finally + { + if (gotLock) + rwLock.ExitReadLock(); + } + + return list; + } + + public int RemoveAll(Predicate predicate) + { + IList list = new List(); + bool gotUpgradeableLock = false; + + try + { + // Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing + // the acquision inside the main try. The inner finally block is needed because thread aborts cannot + // interrupt code in these blocks (hence gotLock is guaranteed to be set correctly). + try {} + finally + { + rwLock.EnterUpgradeableReadLock(); + gotUpgradeableLock = true; + } + + foreach (KeyValuePair kvp in Dictionary1) + { + if (predicate(kvp.Value)) + list.Add(kvp.Key); + } + + IList list2 = new List(list.Count); + foreach (KeyValuePair kvp in Dictionary2) + { + if (predicate(kvp.Value)) + list2.Add(kvp.Key); + } + + bool gotWriteLock = false; + + try + { + try {} + finally + { + rwLock.EnterUpgradeableReadLock(); + gotWriteLock = true; + } + + for (int i = 0; i < list.Count; i++) + Dictionary1.Remove(list[i]); + + for (int i = 0; i < list2.Count; i++) + Dictionary2.Remove(list2[i]); + } + finally + { + if (gotWriteLock) + rwLock.ExitWriteLock(); + } + } + finally + { + if (gotUpgradeableLock) + rwLock.ExitUpgradeableReadLock(); + } + + return list.Count; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index b788a3c..7181313 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Reflection; using log4net; using OpenMetaverse; +using OpenSim.Framework; namespace OpenSim.Region.Framework.Scenes { @@ -38,7 +39,8 @@ namespace OpenSim.Region.Framework.Scenes { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly DoubleDictionary m_entities = new DoubleDictionary(); + private readonly DoubleDictionaryThreadAbortSafe m_entities + = new DoubleDictionaryThreadAbortSafe(); public int Count { -- cgit v1.1 From 8b29db98bde4e052c441f5099b5e56ffa85c53dd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 6 Dec 2012 20:04:32 -0800 Subject: Trying to prevent old route of sending attachments, simulator version unknown maybe due to timeout. mantis #6450 --- OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 95c4f87..57f2ffa 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -314,7 +314,7 @@ namespace OpenSim.Services.Connectors.Simulation try { - OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000, false); + OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 30000, false); bool success = result["success"].AsBoolean(); if (result.ContainsKey("_Result")) { -- cgit v1.1