From ca3b6b1f90f89ab3be4a43863da81f9df0993e2f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 20 Jul 2012 14:08:29 -0700 Subject: [PATCH] BulletSim: more detail logging for vehicle and general physics debugging. Physical linksets are fully functional. Tweeking of the vehicle code to make it semi-work. Utilize the new API2 for some setting operations. Add GetOrientation() API call for proper reporting of children of linksets. Changes the interface between C# and C++ code so old DLLs won't work! --- .../Physics/BulletSPlugin/BSDynamics.cs | 52 ++++-- .../Region/Physics/BulletSPlugin/BSPrim.cs | 168 ++++++++++++++---- .../Region/Physics/BulletSPlugin/BSScene.cs | 48 +++-- .../Physics/BulletSPlugin/BulletSimAPI.cs | 51 ++++++ 4 files changed, 244 insertions(+), 75 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 4c5bc8565e..c197e61ee8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -613,23 +613,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin MoveAngular(pTimestep); LimitRotation(pTimestep); - DetailLog("{0},step,done,pos={1},force={2},velocity={3},angvel={4}", + DetailLog("{0},Dynamics,done,pos={1},force={2},velocity={3},angvel={4}", m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); }// end Step private void MoveLinear(float pTimestep) { - if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant + // requested m_linearMotorDirection is significant + // if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) + if (m_linearMotorDirection.LengthSquared() > 0.0001f) { Vector3 origDir = m_linearMotorDirection; Vector3 origVel = m_lastLinearVelocityVector; // add drive to body - Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); - m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? + // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); + Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale); + // lastLinearVelocityVector is the current body velocity vector? + // RA: Not sure what the *10 is for. A correction for pTimestep? + // m_lastLinearVelocityVector += (addAmount*10); + m_lastLinearVelocityVector += addAmount; // This will work temporarily, but we really need to compare speed on an axis // KF: Limit body velocity to applied velocity? + // Limit the velocity vector to less than the last set linear motor direction if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) @@ -641,19 +648,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; + /* + Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale; + m_lastLinearVelocityVector += addAmount; + + float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale); + m_linearMotorDirection *= decayfraction; + + */ + DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); } else - { // requested is not significant - // if what remains of applied is small, zero it. - if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) - m_lastLinearVelocityVector = Vector3.Zero; + { + // if what remains of applied is small, zero it. + // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) + // m_lastLinearVelocityVector = Vector3.Zero; + m_linearMotorDirection = Vector3.Zero; + m_lastLinearVelocityVector = Vector3.Zero; } // convert requested object velocity to world-referenced vector - m_dir = m_lastLinearVelocityVector; - m_dir *= m_prim.Orientation; + Quaternion rotq = m_prim.Orientation; + m_dir = m_lastLinearVelocityVector * rotq; // Add the various forces into m_dir which will be our new direction vector (velocity) @@ -708,9 +726,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_prim.LocalID, m_BlockingEndPoint, posChange, pos); } } - if (pos.Z < m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y)) + + // If below the terrain, move us above the ground a little. + if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos)) { - pos.Z = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2; + pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; m_prim.Position = pos; DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); } @@ -816,8 +836,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Apply velocity m_prim.Velocity = m_dir; // apply gravity force - m_prim.Force = grav; - + // Why is this set here? The physics engine already does gravity. + // m_prim.AddForce(grav, false); + // m_prim.Force = grav; // Apply friction Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); @@ -990,7 +1011,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Invoke the detailed logger and output something if it's enabled. private void DetailLog(string msg, params Object[] args) { - m_prim.Scene.VehicleLogging.Write(msg, args); + if (m_prim.Scene.VehicleLoggingEnabled) + m_prim.Scene.PhysicsLogging.Write(msg, args); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 5911897234..71a430391e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -148,6 +148,7 @@ public sealed class BSPrim : PhysicsActor public void Destroy() { // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); + // DetailLog("{0},Destroy", LocalID); // Undo any vehicle properties _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); _scene.RemoveVehiclePrim(this); // just to make sure @@ -215,6 +216,7 @@ public sealed class BSPrim : PhysicsActor public override void link(PhysicsActor obj) { BSPrim parent = obj as BSPrim; DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); + DetailLog("{0},link,parent={1}", LocalID, obj.LocalID); // TODO: decide if this parent checking needs to happen at taint time if (_parentPrim == null) { @@ -250,6 +252,7 @@ public sealed class BSPrim : PhysicsActor // Race condition here: if link() and delink() in same simulation tick, the delink will not happen DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, (_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString())); + DetailLog("{0},delink,parent={1}", LocalID, (_parentPrim==null ? "NULL" : _parentPrim.LocalID.ToString())); if (_parentPrim != null) { _parentPrim.RemoveChildFromLinkset(this); @@ -266,6 +269,7 @@ public sealed class BSPrim : PhysicsActor if (!_childrenPrims.Contains(child)) { DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID); + DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID); _childrenPrims.Add(child); child._parentPrim = this; // the child has gained a parent RecreateGeomAndObject(); // rebuild my shape with the new child added @@ -284,6 +288,7 @@ public sealed class BSPrim : PhysicsActor if (_childrenPrims.Contains(child)) { DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); + DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID); if (!BulletSimAPI.RemoveConstraintByID(_scene.WorldID, child.LocalID)) { m_log.ErrorFormat("{0}: RemoveChildFromLinkset: Failed remove constraint for {1}", LogHeader, child.LocalID); @@ -317,20 +322,28 @@ public sealed class BSPrim : PhysicsActor base.RequestPhysicsterseUpdate(); } - public override void LockAngularMotion(OMV.Vector3 axis) { return; } + public override void LockAngularMotion(OMV.Vector3 axis) + { + DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis); + return; + } public override OMV.Vector3 Position { get { - // don't do the following GetObjectPosition because this function is called a zillion times + // child prims move around based on their parent. Need to get the latest location + if (_parentPrim != null) + _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + // don't do the GetObjectPosition for root elements because this function is called a zillion times // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); return _position; } set { _position = value; + // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? _scene.TaintedObject(delegate() { + DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); - // m_log.DebugFormat("{0}: setPosition: id={1}, position={2}", LogHeader, _localID, _position); }); } } @@ -343,6 +356,7 @@ public sealed class BSPrim : PhysicsActor _force = value; _scene.TaintedObject(delegate() { + DetailLog("{0},SetForce,taint,force={1}", LocalID, _force); BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); }); } @@ -354,15 +368,23 @@ public sealed class BSPrim : PhysicsActor } set { Vehicle type = (Vehicle)value; - _vehicle.ProcessTypeChange(type); _scene.TaintedObject(delegate() { + DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type); + _vehicle.ProcessTypeChange(type); if (type == Vehicle.TYPE_NONE) { _scene.RemoveVehiclePrim(this); } else { + _scene.TaintedObject(delegate() + { + // Tell the physics engine to clear state + IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID); + BulletSimAPI.ClearForces2(obj); + }); + // make it so the scene will call us each tick to do vehicle things _scene.AddVehiclePrim(this); } @@ -372,21 +394,39 @@ public sealed class BSPrim : PhysicsActor } public override void VehicleFloatParam(int param, float value) { - _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); + m_log.DebugFormat("{0} VehicleFloatParam. {1} <= {2}", LogHeader, param, value); + _scene.TaintedObject(delegate() + { + _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); + }); } public override void VehicleVectorParam(int param, OMV.Vector3 value) { - _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); + m_log.DebugFormat("{0} VehicleVectorParam. {1} <= {2}", LogHeader, param, value); + _scene.TaintedObject(delegate() + { + _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); + }); } public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { - _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + m_log.DebugFormat("{0} VehicleRotationParam. {1} <= {2}", LogHeader, param, rotation); + _scene.TaintedObject(delegate() + { + _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + }); } public override void VehicleFlags(int param, bool remove) { - _vehicle.ProcessVehicleFlags(param, remove); + m_log.DebugFormat("{0} VehicleFlags. {1}. Remove={2}", LogHeader, param, remove); + _scene.TaintedObject(delegate() + { + _vehicle.ProcessVehicleFlags(param, remove); + }); } - // Called each simulation step to advance vehicle characteristics + + // Called each simulation step to advance vehicle characteristics. + // Called from Scene when doing simulation step so we're in taint processing time. public void StepVehicle(float timeStep) { _vehicle.Step(timeStep); @@ -395,14 +435,11 @@ public sealed class BSPrim : PhysicsActor // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more public override void SetVolumeDetect(int param) { bool newValue = (param != 0); - if (_isVolumeDetect != newValue) + _isVolumeDetect = newValue; + _scene.TaintedObject(delegate() { - _isVolumeDetect = newValue; - _scene.TaintedObject(delegate() - { - SetObjectDynamic(); - }); - } + SetObjectDynamic(); + }); return; } @@ -410,9 +447,11 @@ public sealed class BSPrim : PhysicsActor public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } public override OMV.Vector3 Velocity { get { return _velocity; } - set { _velocity = value; + set { + _velocity = value; _scene.TaintedObject(delegate() { + DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); }); } @@ -420,6 +459,7 @@ public sealed class BSPrim : PhysicsActor public override OMV.Vector3 Torque { get { return _torque; } set { _torque = value; + DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque); } } public override float CollisionScore { @@ -432,13 +472,21 @@ public sealed class BSPrim : PhysicsActor set { _acceleration = value; } } public override OMV.Quaternion Orientation { - get { return _orientation; } + get { + if (_parentPrim != null) + { + // children move around because tied to parent. Get a fresh value. + _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); + } + return _orientation; + } set { _orientation = value; - // m_log.DebugFormat("{0}: set orientation: id={1}, ori={2}", LogHeader, LocalID, _orientation); + // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? _scene.TaintedObject(delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); + DetailLog("{0},SetOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); }); } @@ -471,8 +519,9 @@ public sealed class BSPrim : PhysicsActor get { return !IsPhantom && !_isVolumeDetect; } } - // make gravity work if the object is physical and not selected - // no locking here because only called when it is safe + // Make gravity work if the object is physical and not selected + // No locking here because only called when it is safe + // Only called at taint time so it is save to call into Bullet. private void SetObjectDynamic() { // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); @@ -489,6 +538,7 @@ public sealed class BSPrim : PhysicsActor RecreateGeomAndObject(); } + DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, _mass); BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); } @@ -529,11 +579,24 @@ public sealed class BSPrim : PhysicsActor set { _floatOnWater = value; } } public override OMV.Vector3 RotationalVelocity { - get { return _rotationalVelocity; } - set { _rotationalVelocity = value; + 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 { + _rotationalVelocity = value; // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); _scene.TaintedObject(delegate() { + DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); }); } @@ -546,11 +609,13 @@ public sealed class BSPrim : PhysicsActor } public override float Buoyancy { get { return _buoyancy; } - set { _buoyancy = value; - _scene.TaintedObject(delegate() - { - BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); - }); + set { + _buoyancy = value; + _scene.TaintedObject(delegate() + { + DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); + BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); + }); } } @@ -586,27 +651,45 @@ public sealed class BSPrim : PhysicsActor public override float APIDStrength { set { return; } } public override float APIDDamping { set { return; } } + private List m_accumulatedForces = new List(); public override void AddForce(OMV.Vector3 force, bool pushforce) { if (force.IsFinite()) { - _force.X += force.X; - _force.Y += force.Y; - _force.Z += force.Z; + // _force += force; + lock (m_accumulatedForces) + m_accumulatedForces.Add(new OMV.Vector3(force)); } else { m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); + return; } _scene.TaintedObject(delegate() { - BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); + lock (m_accumulatedForces) + { + if (m_accumulatedForces.Count > 0) + { + OMV.Vector3 fSum = OMV.Vector3.Zero; + foreach (OMV.Vector3 v in m_accumulatedForces) + { + fSum += v; + } + m_accumulatedForces.Clear(); + + DetailLog("{0},SetObjectForce,taint,force={1}", LocalID, fSum); + BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, fSum); + } + } }); } public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { + DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); } public override void SetMomentum(OMV.Vector3 momentum) { + DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum); } public override void SubscribeEvents(int ms) { _subscribedEventsMs = ms; @@ -931,6 +1014,7 @@ public sealed class BSPrim : PhysicsActor { // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; + DetailLog("{0},CreateGeom,sphere", LocalID); // Bullet native objects are scaled by the Bullet engine so pass the size in _scale = _size; } @@ -938,6 +1022,7 @@ public sealed class BSPrim : PhysicsActor else { // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); + DetailLog("{0},CreateGeom,box", LocalID); _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _scale = _size; } @@ -974,10 +1059,12 @@ public sealed class BSPrim : PhysicsActor // if this new shape is the same as last time, don't recreate the mesh if (_meshKey == newMeshKey) return; + DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, _meshKey); // Since we're recreating new, get rid of any previously generated shape if (_meshKey != 0) { // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); + DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; _meshKey = 0; @@ -1007,6 +1094,7 @@ public sealed class BSPrim : PhysicsActor _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); + DetailLog("{0},CreateGeomMesh,done", LocalID); return; } @@ -1020,13 +1108,17 @@ public sealed class BSPrim : PhysicsActor // if the hull hasn't changed, don't rebuild it if (newHullKey == _hullKey) return; + DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey); + // Since we're recreating new, get rid of any previously generated shape if (_hullKey != 0) { // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); + DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); _hullKey = 0; _hulls.Clear(); + DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; // the mesh cannot match either _meshKey = 0; @@ -1123,6 +1215,7 @@ public sealed class BSPrim : PhysicsActor _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; // meshes are already scaled by the meshmerizer _scale = new OMV.Vector3(1f, 1f, 1f); + DetailLog("{0},CreateGeomHull,done", LocalID); return; } @@ -1310,6 +1403,7 @@ public sealed class BSPrim : PhysicsActor */ // 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 (this._parentPrim == null) { @@ -1319,8 +1413,12 @@ public sealed class BSPrim : PhysicsActor _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; + // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); + DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); + base.RequestPhysicsterseUpdate(); } } @@ -1361,5 +1459,11 @@ public sealed class BSPrim : PhysicsActor collisionCollection.Clear(); } } + + // Invoke the detailed logger and output something if it's enabled. + private void DetailLog(string msg, params Object[] args) + { + Scene.PhysicsLogging.Write(msg, args); + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index c4b4332e75..9d41ce8937 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -30,9 +30,9 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading; using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.Statistics.Logging; using OpenSim.Region.Framework; using OpenSim.Region.Physics.Manager; +using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging; using Nini.Config; using log4net; using OpenMetaverse; @@ -45,15 +45,17 @@ using OpenMetaverse; // Compute physics FPS reasonably // Based on material, set density and friction // More efficient memory usage when passing hull information from BSPrim to BulletSim +// Move all logic out of the C++ code and into the C# code for easier future modifications. // Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? // In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) // At the moment, physical and phantom causes object to drop through the terrain // Physical phantom objects and related typing (collision options ) +// Use collision masks for collision with terrain and phantom objects // Check out llVolumeDetect. Must do something for that. // Should prim.link() and prim.delink() membership checking happen at taint time? +// changing the position and orientation of a linked prim must rebuild the constraint with the root. // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect -// Use collision masks for collision with terrain and phantom objects // Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions) // Implement LockAngularMotion // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) @@ -61,9 +63,6 @@ using OpenMetaverse; // Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet. // Add PID movement operations. What does ScenePresence.MoveToTarget do? // Check terrain size. 128 or 127? -// Multiple contact points on collision? -// See code in ode::near... calls to collision_accounting_events() -// (This might not be a problem. ODE collects all the collisions with one object in one tick.) // Raycast // namespace OpenSim.Region.Physics.BulletSPlugin @@ -160,17 +159,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; // Sometimes you just have to log everything. - public LogWriter PhysicsLogging; + public Logging.LogWriter PhysicsLogging; private bool m_physicsLoggingEnabled; private string m_physicsLoggingDir; private string m_physicsLoggingPrefix; private int m_physicsLoggingFileMinutes; - public LogWriter VehicleLogging; private bool m_vehicleLoggingEnabled; - private string m_vehicleLoggingDir; - private string m_vehicleLoggingPrefix; - private int m_vehicleLoggingFileMinutes; + public bool VehicleLoggingEnabled { get { return m_vehicleLoggingEnabled; } } public BSScene(string identifier) { @@ -197,19 +193,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters // can be left in and every call doesn't have to check for null. if (m_physicsLoggingEnabled) { - PhysicsLogging = new LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); + PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); } else { - PhysicsLogging = new LogWriter(); - } - if (m_vehicleLoggingEnabled) - { - VehicleLogging = new LogWriter(m_vehicleLoggingDir, m_vehicleLoggingPrefix, m_vehicleLoggingFileMinutes); - } - else - { - VehicleLogging = new LogWriter(); + PhysicsLogging = new Logging.LogWriter(); } // Get the version of the DLL @@ -218,11 +206,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); // if Debug, enable logging from the unmanaged code - if (m_log.IsDebugEnabled) + if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) { m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); - // the handle is saved to it doesn't get freed after this call - m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); + if (PhysicsLogging.Enabled) + m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); + else + m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); + // the handle is saved in a variable to make sure it doesn't get freed after this call BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); } @@ -363,9 +354,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); // Very detailed logging for vehicle debugging m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); - m_vehicleLoggingDir = pConfig.GetString("VehicleLoggingDir", "."); - m_vehicleLoggingPrefix = pConfig.GetString("VehicleLoggingPrefix", "vehicle-"); - m_vehicleLoggingFileMinutes = pConfig.GetInt("VehicleLoggingFileMinutes", 5); } } m_params[0] = parms; @@ -386,12 +374,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters return ret; } - // Called directly from unmanaged code so don't do much private void BulletLogger(string msg) { m_log.Debug("[BULLETS UNMANAGED]:" + msg); } + + // Called directly from unmanaged code so don't do much + private void BulletLoggerPhysLog(string msg) + { + PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); + } public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) { @@ -532,7 +525,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters for (int ii = 0; ii < updatedEntityCount; ii++) { EntityProperties entprop = m_updateArray[ii]; - // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); BSPrim prim; if (m_prims.TryGetValue(entprop.ID, out prim)) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 086f0dc9d7..babb707b75 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -146,6 +146,22 @@ public struct ConfigurationParameters public const float numericFalse = 0f; } +// Values used by Bullet and BulletSim to control collisions +public enum CollisionFlags : uint +{ + STATIC_OBJECT = 1 << 0, + KINEMATIC_OBJECT = 1 << 1, + NO_CONTACT_RESPONSE = 1 << 2, + CUSTOM_MATERIAL_CALLBACK = 1 << 3, + CHARACTER_OBJECT = 1 << 4, + DISABLE_VISUALIZE_OBJECT = 1 << 5, + DISABLE_SPU_COLLISION_PROCESS = 1 << 6, + // Following used by BulletSim to control collisions + VOLUME_DETECT_OBJECT = 1 << 10, + PHANTOM_OBJECT = 1 << 11, + PHYSICAL_OBJECT = 1 << 12, +}; + static class BulletSimAPI { [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -213,6 +229,9 @@ public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern Vector3 GetObjectPosition(uint WorldID, uint id); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Quaternion GetObjectOrientation(uint WorldID, uint id); + [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool SetObjectTranslation(uint worldID, uint id, Vector3 position, Quaternion rotation); @@ -268,5 +287,37 @@ public static extern void DumpBulletStatistics(); public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void SetDebugLogCallback(DebugLogCallback callback); + +// =============================================================================== +// =============================================================================== +// =============================================================================== +// A new version of the API that moves all the logic out of the C++ code and into +// the C# code. This will make modifications easier for the next person. +// This interface passes the actual pointers to the objects in the unmanaged +// address space. All the management (calls for creation/destruction/lookup) +// is done in the C# code. +// The names have a 2 tacked on. This will be removed as the code gets rebuilt +// and the old code is removed from the C# code. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetSimHandle2(uint worldID); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr ClearForces2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr SetCollisionFlags2(IntPtr obj, uint flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr AddToCollisionFlags2(IntPtr obj, uint flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, uint flags); + } }