diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 4c195e1cfc..1dfc4204dd 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 74eb9ab408..3a73fba7b8 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: @@ -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) @@ -804,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; @@ -817,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); } @@ -863,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; @@ -883,8 +896,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Sum velocities m_lastAngularVelocity = angularMotorContribution + verticalAttractionContribution - + bankingContribution - + deflectionContribution; + + deflectionContribution + + bankingContribution; // ================================================================== //Offset section @@ -921,8 +934,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 c62c79a11f..3fb0300cfc 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 09b1423586..0c806118cc 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 1450f66491..0cb151e285 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 cd623f1398..17d9536c42 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 5f6675d526..7e93ab4623 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( diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 38b11cd9f1..3f5011a928 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 f59ec978fc..46d40feb89 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 1861d6d21b..27a807cd50 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 e9b8845729..1e82b3d37e 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ