From ace1f1e9314d2e5b3cf45426225ca485649bbf96 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 14 Dec 2012 17:03:59 -0800 Subject: [PATCH 1/9] BulletSim: rip out old code for linkset child position fetching. BulletSim doesn't need to do that bookkeeping because SOG/SOP already does it. --- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 8 +---- .../BulletSPlugin/BSLinksetCompound.cs | 24 +++++++-------- .../BulletSPlugin/BSLinksetConstraints.cs | 12 -------- .../Region/Physics/BulletSPlugin/BSPrim.cs | 29 +++++++++++-------- .../Physics/BulletSPlugin/BulletSimTODO.txt | 3 ++ 5 files changed, 31 insertions(+), 45 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index ce0fbe6c91..2486be59ba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -38,6 +38,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Each type of linkset will define the information needed for its type. public abstract class BSLinksetInfo { + public virtual void Clear() { } } public abstract class BSLinkset @@ -95,13 +96,6 @@ public abstract class BSLinkset return BSPhysicsShapeType.SHAPE_UNKNOWN; } - // Linksets move around the children so the linkset might need to compute the child position - public virtual OMV.Vector3 Position(BSPhysObject member) - { return member.RawPosition; } - public virtual OMV.Quaternion Orientation(BSPhysObject member) - { return member.RawOrientation; } - // TODO: does this need to be done for Velocity and RotationalVelocityy? - // We keep the prim's mass in the linkset structure since it could be dependent on other prims protected float m_mass; public float LinksetMass diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 2189468e17..8359607284 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -45,6 +45,11 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo OffsetPos = p; OffsetRot = r; } + public override void Clear() + { + OffsetPos = OMV.Vector3.Zero; + OffsetRot = OMV.Quaternion.Identity; + } public override string ToString() { StringBuilder buff = new StringBuilder(); @@ -82,8 +87,11 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { - // External request for Refresh (from BSPrim) doesn't need to do anything - // InternalRefresh(requestor); + if (!IsRoot(requestor)) + { + } + // Something changed so do the rebuilding thing + InternalRefresh(requestor); } // Schedule a refresh to happen after all the other taint processing. @@ -170,18 +178,6 @@ public sealed class BSLinksetCompound : BSLinkset // Nothing to do for compound linksets on property updates } - // The children move around in relationship to the root. - // Just grab the current values of wherever it is right now. - public override OMV.Vector3 Position(BSPhysObject member) - { - return BulletSimAPI.GetPosition2(member.PhysBody.ptr); - } - - public override OMV.Quaternion Orientation(BSPhysObject member) - { - return BulletSimAPI.GetOrientation2(member.PhysBody.ptr); - } - // Routine called when rebuilding the body of some member of the linkset. // Since we don't keep in world relationships, do nothing unless it's a child changing. // Returns 'true' of something was actually removed and would need restoring diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 732c0848b7..7076ab4c6c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -83,18 +83,6 @@ public sealed class BSLinksetConstraints : BSLinkset // Nothing to do for constraints on property updates } - // The children of the linkset are moved around by the constraints. - // Just grab the current values of wherever it is right now. - public override OMV.Vector3 Position(BSPhysObject member) - { - return BulletSimAPI.GetPosition2(member.PhysBody.ptr); - } - - public override OMV.Quaternion Orientation(BSPhysObject member) - { - return BulletSimAPI.GetOrientation2(member.PhysBody.ptr); - } - // Routine called when rebuilding the body of some member of the linkset. // Destroy all the constraints have have been made to root and set // up to rebuild the constraints before the next simulation step. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c9c9c2cc10..53be2e3a11 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -279,9 +279,12 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 Position { get { + /* NOTE: this refetch is not necessary. The simulator knows about linkset children + * and does not fetch this position info for children. Thus this is commented out. // child prims move around based on their parent. Need to get the latest location if (!Linkset.IsRoot(this)) - _position = Linkset.Position(this); + _position = Linkset.PositionGet(this); + */ // don't do the GetObjectPosition for root elements because this function is called a zillion times. // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); @@ -289,21 +292,18 @@ public sealed class BSPrim : BSPhysObject } set { // If the position must be forced into the physics engine, use ForcePosition. + // All positions are given in world positions. if (_position == value) { + DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); return; } _position = value; - // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? PositionSanityCheck(false); PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { - // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - ActivateIfPhysical(false); - } + DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + ForcePosition = _position; }); } } @@ -314,9 +314,11 @@ public sealed class BSPrim : BSPhysObject } set { _position = value; - // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better. - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - ActivateIfPhysical(false); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + ActivateIfPhysical(false); + } } } @@ -551,11 +553,14 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Quaternion Orientation { get { + /* NOTE: this refetch is not necessary. The simulator knows about linkset children + * and does not fetch this position info for children. Thus this is commented out. // Children move around because tied to parent. Get a fresh value. if (!Linkset.IsRoot(this)) { - _orientation = Linkset.Orientation(this); + _orientation = Linkset.OrientationGet(this); } + */ return _orientation; } set { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7d6ace8b08..9b89f0b0fa 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -37,6 +37,7 @@ Border crossing with linked vehicle causes crash BULLETSIM TODO LIST: ================================================= +Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Avatar height off after unsitting (floats off ground) Editting appearance then moving restores. Must not be initializing height when recreating capsule after unsit. @@ -64,6 +65,8 @@ Implement ShapeCollection.Dispose() Implement water as a plain so raycasting and collisions can happen with same. Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE Also osGetPhysicsEngineVerion() maybe. +Linkset.Position and Linkset.Orientation requre rewrite to properly return + child position. LinksetConstraint acts like it's at taint time!! LINKSETS ====================================================== From f3b1efd889e2e87f89c8e8da6a08089596c878f6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 15 Dec 2012 11:31:26 -0800 Subject: [PATCH 2/9] BulletSim: remove some errors on shutdown by moving terrain destruction until after physical object destruction. TerrainManager also made disposable and that feature used. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 9 +++++++-- .../Region/Physics/BulletSPlugin/BSTerrainManager.cs | 10 +++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index cf5bb57c17..ac99777ad0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -349,8 +349,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // make sure no stepping happens while we're deleting stuff m_initialized = false; - TerrainManager.ReleaseGroundPlaneAndTerrain(); - foreach (KeyValuePair kvp in PhysObjects) { kvp.Value.Destroy(); @@ -370,6 +368,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters Shapes = null; } + if (TerrainManager != null) + { + TerrainManager.ReleaseGroundPlaneAndTerrain(); + TerrainManager.Dispose(); + TerrainManager = null; + } + // Anything left in the unmanaged code should be cleaned out BulletSimAPI.Shutdown2(World.ptr); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 5dbd8ce6cf..c68fd69911 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -67,7 +67,7 @@ public abstract class BSTerrainPhys : IDisposable } // ========================================================================================== -public sealed class BSTerrainManager +public sealed class BSTerrainManager : IDisposable { static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; @@ -122,6 +122,11 @@ public sealed class BSTerrainManager MegaRegionParentPhysicsScene = null; } + public void Dispose() + { + ReleaseGroundPlaneAndTerrain(); + } + // Create the initial instance of terrain and the underlying ground plane. // This is called from the initialization routine so we presume it is // safe to call Bullet in real time. We hope no one is moving prims around yet. @@ -366,6 +371,9 @@ public sealed class BSTerrainManager { PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", LogHeader, PhysicsScene.RegionName, tX, tY); + DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,loc={1},base={2}", + BSScene.DetailLogZero, loc, terrainBaseXYZ); + Util.PrintCallStack(); // DEBUG DEBUG DEBUG } } lastHeight = ret; From 21dc5f4a1ada6fa7538627a81907054c619c0ebb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 17:53:44 -0800 Subject: [PATCH 3/9] Add stack dump function that takes an alternate printer outter. I've found that log4net can be slowish so, if one is generating A LOT of debug output, alternate printers are better --- OpenSim/Framework/Util.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index a0c54a027e..0c657c51eb 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1854,6 +1854,12 @@ namespace OpenSim.Framework /// Prints the call stack at any given point. Useful for debugging. /// public static void PrintCallStack() + { + PrintCallStack(m_log.DebugFormat); + } + + public delegate void DebugPrinter(string msg, params Object[] parm); + public static void PrintCallStack(DebugPrinter printer) { StackTrace stackTrace = new StackTrace(true); // get call stack StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) @@ -1862,7 +1868,7 @@ namespace OpenSim.Framework foreach (StackFrame stackFrame in stackFrames) { MethodBase mb = stackFrame.GetMethod(); - m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name + printer("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name } } From 8a95953bb7c35ec1f2b6d97520c56178778ef729 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:12:01 -0800 Subject: [PATCH 4/9] BulletSim: experimentally remove unit displacement from prim border crossing test. This seems to cause border crossing to be sensed either a little early or a little late depending on which directin the object is moving. If border crossings become totally borked or someone remembers why this was displacement was done, revert this change. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1fa6a759e3..64a581120b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -430,8 +430,19 @@ namespace OpenSim.Region.Framework.Scenes if (Scene != null) { - if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) - || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) + if ( + // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) + // || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) + // || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) + // || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) + // Experimental change for better border crossings. + // The commented out original lines above would, it seems, trigger + // a border crossing a little early or late depending on which + // direction the object was moving. + (Scene.TestBorderCross(val, Cardinals.E) + || Scene.TestBorderCross(val, Cardinals.W) + || Scene.TestBorderCross(val, Cardinals.N) + || Scene.TestBorderCross(val, Cardinals.S)) && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) { m_scene.CrossPrimGroupIntoNewRegion(val, this, true); From 4cbc5082ffc5aa4818471cedf906c78038a7b0f9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:14:48 -0800 Subject: [PATCH 5/9] BulletSim: refactor to combine common terrain height testing code. Add function to test if a position is over known terrain. --- .../Physics/BulletSPlugin/BSTerrainManager.cs | 90 ++++++++++--------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c68fd69911..3428b9c0fa 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -332,6 +332,13 @@ public sealed class BSTerrainManager : IDisposable return newTerrainPhys; } + // Return 'true' of this position is somewhere in known physical terrain space + public bool IsWithinKnownTerrain(Vector3 pos) + { + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); + } // Given an X and Y, find the height of the terrain. // Since we could be handling multiple terrains for a mega-region, @@ -342,13 +349,13 @@ public sealed class BSTerrainManager : IDisposable private float lastHeightTX = 999999f; private float lastHeightTY = 999999f; private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; - public float GetTerrainHeightAtXYZ(Vector3 loc) + public float GetTerrainHeightAtXYZ(Vector3 pos) { - float tX = loc.X; - float tY = loc.Y; + float tX = pos.X; + float tY = pos.Y; // You'd be surprized at the number of times this routine is called // with the same parameters as last time. - if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) + if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY)) return lastHeight; m_terrainModified = false; @@ -356,26 +363,20 @@ public sealed class BSTerrainManager : IDisposable lastHeightTY = tY; float ret = HEIGHT_GETHEIGHT_RET; - int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; - int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; - Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); - - lock (m_terrains) + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) { - BSTerrainPhys physTerrain; - if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) - { - ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", - LogHeader, PhysicsScene.RegionName, tX, tY); - DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,loc={1},base={2}", - BSScene.DetailLogZero, loc, terrainBaseXYZ); - Util.PrintCallStack(); // DEBUG DEBUG DEBUG - } + ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ); } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", + LogHeader, PhysicsScene.RegionName, tX, tY); + DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", + BSScene.DetailLogZero, pos, terrainBaseXYZ); + } + lastHeight = ret; return ret; } @@ -384,29 +385,38 @@ public sealed class BSTerrainManager : IDisposable { 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) + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) { - 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); - } + ret = physTerrain.GetWaterLevelAtXYZ(pos); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}", + LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret); } return ret; } + // Given an address, return 'true' of there is a description of that terrain and output + // the descriptor class and the 'base' fo the addresses therein. + private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) + { + int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; + int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); + + BSTerrainPhys physTerrain = null; + lock (m_terrains) + { + m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); + } + outTerrainBase = terrainBaseXYZ; + outPhysTerrain = physTerrain; + return (physTerrain != null); + } + // Although no one seems to check this, I do support combining. public bool SupportsCombining() { From 7ed860d3ac8307b2f404fea1c40471ee488cf70e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:15:49 -0800 Subject: [PATCH 6/9] BulletSim: add check for border crossing in character position sanity check. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 0defb24f76..4dd6264339 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -311,6 +311,15 @@ public sealed class BSCharacter : BSPhysObject { bool ret = false; + // TODO: check for out of bounds + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + { + // The character is out of the known/simulated area. + // Upper levels of code will handle the transition to other areas so, for + // the time, we just ignore the position. + return ret; + } + // If below the ground, move the avatar up float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); if (Position.Z < terrainHeight) @@ -329,7 +338,6 @@ public sealed class BSCharacter : BSPhysObject } } - // TODO: check for out of bounds return ret; } @@ -700,7 +708,7 @@ public sealed class BSCharacter : BSPhysObject } // Tell the linkset about value changes - Linkset.UpdateProperties(this); + Linkset.UpdateProperties(this, true); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); From 3f2aaffd4d32ec7569cc2e5faae76c5faa9e9da4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:16:40 -0800 Subject: [PATCH 7/9] BulletSim: add even more to the TODO list. --- .../Physics/BulletSPlugin/BulletSimTODO.txt | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 9b89f0b0fa..31dd790ff3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,3 +1,16 @@ +CURRENT PRIORITIES +================================================= +Eliminate all crashes (DONEish) + Editing/deleting physical linkset (DONE) + Border crossing of physical linkset (DONE) +Enable vehicle border crossings (at least as poorly as ODE) + Avatar created in previous region and not new region when crossing border + Vehicle recreated in new sim at small Z value (offset from root value?) +Calibrate turning radius +limitMotorUp calibration (more down?) +study PID motors (include 'efficiency' implementation + Add to avatar movement + CRASHES ================================================= 20121129.1411: editting/moving phys object across region boundries causes crash @@ -11,16 +24,18 @@ CRASHES VEHICLES TODO LIST: ================================================= +Border crossing with linked vehicle causes crash Neb vehicle taking > 25ms of physics time!! Vehicles (Move smoothly) 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. +Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. Light cycle falling over when driving -For limitMotorUp, use raycast down to find if vehicle is in the air. +Implement referenceFrame for all the motion routines. Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. Verify llGetVel() is returning a smooth and good value for vehicle movement. @@ -31,9 +46,9 @@ Should vehicle angular/linear movement friction happen after all the components 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. -Border crossing with linked vehicle causes crash +For limitMotorUp, use raycast down to find if vehicle is in the air. +Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). + A kludge that isn't fixing the real problem of Bullet adding extra motion. BULLETSIM TODO LIST: ================================================= @@ -72,6 +87,9 @@ LINKSETS ====================================================== Linksets should allow collisions to individual children Add LocalID to children shapes in LinksetCompound and create events for individuals +LinksetCompound: when one of the children changes orientation (like tires + turning on a vehicle, the whole compound object is rebuilt. Optimize this + so orientation/position of individual children can change without a rebuild. Verify/think through scripts in children of linksets. What do they reference and return when getting position, velocity, ... Confirm constraint linksets still work after making all the changes for compound linksets. @@ -143,6 +161,11 @@ 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(). +Should taints check for existance or activeness of target? + When destroying linksets/etc, taints can be generated for objects that are + actually gone when the taint happens. Crashes don't happen because the taint closure + keeps the object from being freed, but that is just an accident. + Possibly have and 'active' flag that is checked by the taint processor? THREADING ================================================= From 2b8efa24dd816fda23fe3aed5822af1d50febf5d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:18:32 -0800 Subject: [PATCH 8/9] BulletSim: add parameter to UpdateProperties call into the linkset so changes from the physics engine can be differentiated from changes made by the user. This eliminates a linkset rebuild loop. Also add logic to not rebuild or freak out when the object/linkset crosses a terrain boundry. --- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 3 +- .../BulletSPlugin/BSLinksetCompound.cs | 48 +++++++++++-------- .../BulletSPlugin/BSLinksetConstraints.cs | 2 +- .../Physics/BulletSPlugin/BSPhysObject.cs | 9 ++-- .../Region/Physics/BulletSPlugin/BSPrim.cs | 29 +++++++---- .../Region/Physics/BulletSPlugin/BSScene.cs | 10 ++-- 6 files changed, 65 insertions(+), 36 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 2486be59ba..2017fa5656 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -252,8 +252,9 @@ public abstract class BSLinkset // Called when a parameter update comes from the physics engine for any object // of the linkset is received. + // Passed flag is update came from physics engine (true) or the user (false). // Called at taint-time!! - public abstract void UpdateProperties(BSPhysObject physObject); + public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate); // Routine used when rebuilding the body of the root of the linkset // Destroy all the constraints have have been made to root. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8359607284..4d4f7123bc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -28,6 +28,8 @@ using System; using System.Collections.Generic; using System.Text; +using OpenSim.Framework; + using OMV = OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin @@ -87,25 +89,22 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { - if (!IsRoot(requestor)) - { - } // Something changed so do the rebuilding thing - InternalRefresh(requestor); + // ScheduleRebuild(); } // Schedule a refresh to happen after all the other taint processing. - private void InternalRefresh(BSPhysObject requestor) + private void ScheduleRebuild() { - DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}", - LinksetRoot.LocalID, requestor.LocalID, Rebuilding); + DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", + LinksetRoot.LocalID, Rebuilding); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. if (!Rebuilding) { - PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() + PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() { - if (IsRoot(requestor) && HasAnyChildren) + if (HasAnyChildren) RecomputeLinksetCompound(); }); } @@ -125,8 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset { // The root is going dynamic. Make sure mass is properly set. m_mass = ComputeLinksetMass(); - if (HasAnyChildren) - InternalRefresh(LinksetRoot); + ScheduleRebuild(); } else { @@ -155,8 +153,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); if (IsRoot(child)) { - if (HasAnyChildren) - InternalRefresh(LinksetRoot); + ScheduleRebuild(); } else { @@ -172,10 +169,21 @@ public sealed class BSLinksetCompound : BSLinkset return ret; } - // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated) + public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) { - // Nothing to do for compound linksets on property updates + // The user moving a child around requires the rebuilding of the linkset compound shape + // One problem is this happens when a border is crossed -- the simulator implementation + // is to store the position into the group which causes the move of the object + // but it also means all the child positions get updated. + // What would cause an unnecessary rebuild so we make sure the linkset is in a + // region before bothering to do a rebuild. + if (!IsRoot(updated) + && !physicalUpdate + && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) + { + updated.LinksetInfo = null; + ScheduleRebuild(); + } } // Routine called when rebuilding the body of some member of the linkset. @@ -257,8 +265,8 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); - // Cause constraints and assorted properties to be recomputed before the next simulation step. - InternalRefresh(LinksetRoot); + // Rebuild the compound shape with the new child shape included + ScheduleRebuild(); } return; } @@ -285,8 +293,8 @@ public sealed class BSLinksetCompound : BSLinkset } else { - // Schedule a rebuild of the linkset before the next simulation tick. - InternalRefresh(LinksetRoot); + // Rebuild the compound shape with the child removed + ScheduleRebuild(); } } return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 7076ab4c6c..8c36c3153a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -78,7 +78,7 @@ public sealed class BSLinksetConstraints : BSLinkset } // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated) + public override void UpdateProperties(BSPhysObject updated, bool inTaintTime) { // Nothing to do for constraints on property updates } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 6539b43156..92a5f2f054 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -214,7 +214,7 @@ public abstract class BSPhysObject : PhysicsActor { bool ret = true; // If the 'no collision' call, force it to happen right now so quick collision_end - bool force = CollisionCollection.Count == 0; + bool force = (CollisionCollection.Count == 0); // throttle the collisions to the number of milliseconds specified in the subscription if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) @@ -232,8 +232,10 @@ public abstract class BSPhysObject : PhysicsActor // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); - // The collisionCollection structure is passed around in the simulator. + // The CollisionCollection instance is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. + // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, + // a race condition is created for the other users of this instance. CollisionCollection = new CollisionEventUpdate(); } return ret; @@ -251,7 +253,8 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + if (PhysBody.HasPhysicalBody) + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } else diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 53be2e3a11..758d92bd0f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -300,6 +300,10 @@ public sealed class BSPrim : BSPhysObject } _position = value; PositionSanityCheck(false); + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(this, false); + PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); @@ -329,6 +333,14 @@ public sealed class BSPrim : BSPhysObject { bool ret = false; + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + { + // The physical object is out of the known/simulated area. + // Upper levels of code will handle the transition to other areas so, for + // the time, we just ignore the position. + return ret; + } + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); OMV.Vector3 upForce = OMV.Vector3.Zero; if (RawPosition.Z < terrainHeight) @@ -352,8 +364,6 @@ public sealed class BSPrim : BSPhysObject } } - // TODO: check for out of bounds - // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. // TODO: This should be intergrated with a geneal physics action mechanism. // TODO: This should be moderated with PID'ness. @@ -567,7 +577,10 @@ public sealed class BSPrim : BSPhysObject if (_orientation == value) return; _orientation = value; - // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(this, false); + PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { if (PhysBody.HasPhysicalBody) @@ -1432,14 +1445,14 @@ public sealed class BSPrim : BSPhysObject entprop.Velocity = _velocity; } - // remember the current and last set values - LastEntityProperties = CurrentEntityProperties; - CurrentEntityProperties = entprop; - 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); + // remember the current and last set values + LastEntityProperties = CurrentEntityProperties; + CurrentEntityProperties = entprop; + base.RequestPhysicsterseUpdate(); } /* @@ -1453,7 +1466,7 @@ public sealed class BSPrim : BSPhysObject */ // The linkset implimentation might want to know about this. - Linkset.UpdateProperties(this); + Linkset.UpdateProperties(this, true); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index ac99777ad0..7b44574c69 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -517,8 +517,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 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); + DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", + DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, + updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) @@ -573,6 +574,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Objects that are done colliding are removed from the ObjectsWithCollisions list. // Not done above because it is inside an iteration of ObjectWithCollisions. + // This complex collision processing is required to create an empty collision + // event call after all collisions have happened on an object. This enables + // the simulator to generate the 'collision end' event. if (ObjectsWithNoMoreCollisions.Count > 0) { foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) @@ -597,7 +601,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessPostStepTaints(); - // This causes the unmanaged code to output ALL the values found in ALL the objects in the world. + // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG From 021623a17d8371147eefe9290d780048e24812c6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 22:31:22 -0800 Subject: [PATCH 9/9] BulletSim: fix vehicles being shot in the air at border crossings because of mis-application of correction to postion for below groundness. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 82e829e700..ef68471a29 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -871,8 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) { // TODO: correct position by applying force rather than forcing position. - VehiclePosition += new Vector3(0f, 0f, GetTerrainHeight(VehiclePosition) + 2f); - VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); + Vector3 newPosition = VehiclePosition; + newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; + VehiclePosition = newPosition; + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", + Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); } return ret; }