From 7b6987ce83d16871f6070f3cc7d56280ad3d5dbe Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 24 Aug 2012 12:58:42 -0700 Subject: BulletSim: unify physical objects under BSPhysObjects. Now BSScene and BSLinkset only know of BSPhysObject's and there is only one list to search in BSScene. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 137 +++++++++++------------- 1 file changed, 61 insertions(+), 76 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 56924aa..ce64b9b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -78,14 +78,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters public string BulletSimVersion = "?"; - private Dictionary m_avatars = new Dictionary(); - public Dictionary Characters { get { return m_avatars; } } - - private Dictionary m_prims = new Dictionary(); - public Dictionary Prims { get { return m_prims; } } + public Dictionary PhysObjects = new Dictionary(); + private HashSet m_objectsWithCollisions = new HashSet(); + // Following is a kludge and can be removed when avatar animation updating is + // moved to a better place. private HashSet m_avatarsWithCollisions = new HashSet(); - private HashSet m_primsWithCollisions = new HashSet(); private List m_vehicles = new List(); @@ -235,7 +233,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // BulletSimVersion = BulletSimAPI.GetVersion(); // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); - // if Debug, enable logging from the unmanaged code + // If Debug logging level, enable logging from the unmanaged code if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) { m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); @@ -243,13 +241,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters 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 + // The handle is saved in a variable to make sure it doesn't get freed after this call BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); } _taintedObjects = new List(); mesher = meshmerizer; + // The bounding box for the simulated world Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); @@ -337,7 +336,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (!m_initialized) return null; BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); - lock (m_avatars) m_avatars.Add(localID, actor); + lock (PhysObjects) PhysObjects.Add(localID, actor); + + // Remove kludge someday + lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor); + return actor; } @@ -352,7 +355,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters { try { - lock (m_avatars) m_avatars.Remove(actor.LocalID); + lock (PhysObjects) PhysObjects.Remove(actor.LocalID); + // Remove kludge someday + lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor); } catch (Exception e) { @@ -374,7 +379,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); try { - lock (m_prims) m_prims.Remove(bsprim.LocalID); + lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID); } catch (Exception e) { @@ -399,7 +404,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters DetailLog("{0},AddPrimShape,call", localID); BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); - lock (m_prims) m_prims.Add(localID, prim); + lock (PhysObjects) PhysObjects.Add(localID, prim); return prim; } @@ -470,19 +475,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters // The above SendCollision's batch up the collisions on the objects. // Now push the collisions into the simulator. - foreach (BSPrim bsp in m_primsWithCollisions) + foreach (BSPhysObject bsp in m_objectsWithCollisions) bsp.SendCollisions(); - m_primsWithCollisions.Clear(); + m_objectsWithCollisions.Clear(); // This is a kludge to get avatar movement updated. - // Don't send collisions only if there were collisions -- send everytime. // ODE sends collisions even if there are none and this is used to update // avatar animations and stuff. - // foreach (BSCharacter bsc in m_avatarsWithCollisions) - // bsc.SendCollisions(); - foreach (KeyValuePair kvp in m_avatars) - kvp.Value.SendCollisions(); - m_avatarsWithCollisions.Clear(); + foreach (BSPhysObject bpo in m_avatarsWithCollisions) + bpo.SendCollisions(); + // m_avatarsWithCollisions.Clear(); // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) @@ -490,16 +492,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters for (int ii = 0; ii < updatedEntityCount; ii++) { EntityProperties entprop = m_updateArray[ii]; - BSPrim prim; - if (m_prims.TryGetValue(entprop.ID, out prim)) - { - prim.UpdateProperties(entprop); - continue; - } - BSCharacter actor; - if (m_avatars.TryGetValue(entprop.ID, out actor)) + BSPhysObject pobj; + if (PhysObjects.TryGetValue(entprop.ID, out pobj)) { - actor.UpdateProperties(entprop); + pobj.UpdateProperties(entprop); continue; } } @@ -529,33 +525,36 @@ public class BSScene : PhysicsScene, IPhysicsParameters } // Something has collided - private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration) + private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration) { if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) { return; // don't send collisions to the terrain } + BSPhysObject collider = PhysObjects[localID]; + // TODO: as of this code, terrain was not in the physical object list. + // When BSTerrain is created and it will be in the list, we can remove + // the possibility that it's not there and just fetch the collidee. + BSPhysObject collidee = null; + ActorTypes type = ActorTypes.Prim; if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) + { type = ActorTypes.Ground; - else if (m_avatars.ContainsKey(collidingWith)) - type = ActorTypes.Agent; + } + else + { + collidee = PhysObjects[collidingWith]; + if (collidee is BSCharacter) + type = ActorTypes.Agent; + } // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); - BSPrim prim; - if (m_prims.TryGetValue(localID, out prim)) { - prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); - m_primsWithCollisions.Add(prim); - return; - } - BSCharacter actor; - if (m_avatars.TryGetValue(localID, out actor)) { - actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration); - m_avatarsWithCollisions.Add(actor); - return; - } + collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration); + m_objectsWithCollisions.Add(collider); + return; } @@ -605,17 +604,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters // make sure no stepping happens while we're deleting stuff m_initialized = false; - foreach (KeyValuePair kvp in m_avatars) - { - kvp.Value.Destroy(); - } - m_avatars.Clear(); - - foreach (KeyValuePair kvp in m_prims) + foreach (KeyValuePair kvp in PhysObjects) { kvp.Value.Destroy(); } - m_prims.Clear(); + PhysObjects.Clear(); // Now that the prims are all cleaned up, there should be no constraints left if (m_constraintCollection != null) @@ -996,42 +989,42 @@ public class BSScene : PhysicsScene, IPhysicsParameters 0f, (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linearDamping; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ), new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 0f, (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].angularDamping; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ), new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 0.2f, (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].deactivationTime; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ), new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 0.8f, (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].linearSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1.0f, (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].angularSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 0f, // set to zero to disable (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdMotionThreshold; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 0f, (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].ccdSweptSphereRadius; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 0.1f, (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].contactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 0.5f, @@ -1052,32 +1045,32 @@ public class BSScene : PhysicsScene, IPhysicsParameters 0.5f, (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarFriction; }, - (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", 60f, (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarDensity; }, - (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ), new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 0f, (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarRestitution; }, - (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ), new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", 0.37f, (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarCapsuleRadius; }, - (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 1.5f, (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarCapsuleHeight; }, - (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 0.1f, (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), + (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", @@ -1264,18 +1257,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters } // check to see if we are updating a parameter for a particular or all of the prims - protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) - { - List operateOn; - lock (m_prims) operateOn = new List(m_prims.Keys); - UpdateParameterSet(operateOn, ref loc, parm, localID, val); - } - - // check to see if we are updating a parameter for a particular or all of the avatars - protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val) + protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val) { List operateOn; - lock (m_avatars) operateOn = new List(m_avatars.Keys); + lock (PhysObjects) operateOn = new List(PhysObjects.Keys); UpdateParameterSet(operateOn, ref loc, parm, localID, val); } -- cgit v1.1 From 7c140570db3b01eb83efc0d42a47715d3047e376 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 25 Aug 2012 23:18:46 -0700 Subject: BulletSim: Changes to terrain storage and management so mega-regions work. Moved all terrain code out of BSScene and into new BSTerrainManager. Added logic to manage multiple terrains for mega-regions. Added new functions to BulletSimAPI to match the library. Moved all of the terrain creation and setup logic from C++ code to C# code. The unused code has not yet been removed from either place. Soon. Moved checks for avatar above ground and in bounds into BSCharacter. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 245 +++++++++++++----------- 1 file changed, 137 insertions(+), 108 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index ce64b9b..f80304d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -39,8 +39,6 @@ using log4net; using OpenMetaverse; // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Debug linkset -// Test with multiple regions in one simulator // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) // Test sculpties // Compute physics FPS reasonably @@ -54,10 +52,8 @@ using OpenMetaverse; // 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 -// 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) // Does NeedsMeshing() really need to exclude all the different shapes? @@ -85,18 +81,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters // moved to a better place. private HashSet m_avatarsWithCollisions = new HashSet(); - private List m_vehicles = new List(); - - private float[] m_heightMap; - private float m_waterLevel; - private uint m_worldID; - public uint WorldID { get { return m_worldID; } } + // List of all the objects that have vehicle properties and should be called + // to update each physics step. + private List m_vehicles = new List(); // let my minuions use my logger public ILog Logger { get { return m_log; } } - private bool m_initialized = false; - + // If non-zero, the number of simulation steps between calls to the physics + // engine to output detailed physics stats. Debug logging level must be on also. private int m_detailedStatsStep = 0; public IMesher mesher; @@ -106,29 +99,31 @@ public class BSScene : PhysicsScene, IPhysicsParameters public float MeshMegaPrimThreshold { get; private set; } public float SculptLOD { get; private set; } - private BulletSim m_worldSim; - public BulletSim World - { - get { return m_worldSim; } - } - private BSConstraintCollection m_constraintCollection; - public BSConstraintCollection Constraints - { - get { return m_constraintCollection; } - } + public uint WorldID { get; private set; } + public BulletSim World { get; private set; } + + // All the constraints that have been allocated in this instance. + public BSConstraintCollection Constraints { get; private set; } + // Simulation parameters private int m_maxSubSteps; private float m_fixedTimeStep; private long m_simulationStep = 0; public long SimulationStep { get { return m_simulationStep; } } + // The length of the last timestep we were asked to simulate. + // This is used by the vehicle code. Since the vehicle code is called + // once per simulation step, its constants need to be scaled by this. public float LastSimulatedTimestep { get; private set; } // 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 - private int m_simulationNowTime; - public int SimulationNowTime { get { return m_simulationNowTime; } } + // Set to 'now' just before all the prims and actors are called for collisions and updates + public int SimulationNowTime { get; private set; } + + // True if initialized and ready to do simulation steps + private bool m_initialized = false; + // Pinned memory used to pass step information between managed and unmanaged private int m_maxCollisionsPerFrame; private CollisionDesc[] m_collisionArray; private GCHandle m_collisionArrayPinnedHandle; @@ -145,6 +140,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 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 BSTerrainManager TerrainManager { get; private set; } public ConfigurationParameters Params { @@ -155,12 +154,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters get { return new Vector3(0f, 0f, Params.gravity); } } - private float m_maximumObjectMass; - public float MaximumObjectMass - { - get { return m_maximumObjectMass; } - } + public float MaximumObjectMass { get; private set; } + // When functions in the unmanaged code must be called, it is only + // done at a known time just before the simulation step. The taint + // system saves all these function calls and executes them in + // order before the simulation. public delegate void TaintCallback(); private struct TaintCallbackEntry { @@ -176,6 +175,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters private Object _taintLock = new Object(); // A pointer to an instance if this structure is passed to the C++ code + // Used to pass basic configuration values to the unmanaged code. ConfigurationParameters[] m_params; GCHandle m_paramsHandle; @@ -189,11 +189,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters private bool m_physicsLoggingEnabled; private string m_physicsLoggingDir; private string m_physicsLoggingPrefix; - private int m_physicsLoggingFileMinutes; - - private bool m_vehicleLoggingEnabled; - public bool VehicleLoggingEnabled { get { return m_vehicleLoggingEnabled; } } + private int m_physicsLoggingFileMinutes; + // 'true' of the vehicle code is to log lots of details + public bool VehicleLoggingEnabled { get; private set; } + #region Construction and Initialization public BSScene(string identifier) { m_initialized = false; @@ -216,6 +216,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + mesher = meshmerizer; + _taintedObjects = new List(); + // Enable very detailed logging. // By creating an empty logger when not logging, the log message invocation code // can be left in and every call doesn't have to check for null. @@ -228,11 +231,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters PhysicsLogging = new Logging.LogWriter(); } - // Get the version of the DLL - // TODO: this doesn't work yet. Something wrong with marshaling the returned string. - // BulletSimVersion = BulletSimAPI.GetVersion(); - // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); - // If Debug logging level, enable logging from the unmanaged code if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) { @@ -245,22 +243,32 @@ public class BSScene : PhysicsScene, IPhysicsParameters BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); } - _taintedObjects = new List(); - - mesher = meshmerizer; + // Get the version of the DLL + // TODO: this doesn't work yet. Something wrong with marshaling the returned string. + // BulletSimVersion = BulletSimAPI.GetVersion(); + // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); - // The bounding box for the simulated world + // The bounding box for the simulated world. The origin is 0,0,0 unless we're + // a child in a mega-region. + // Turns out that Bullet really doesn't care about the extents of the simulated + // area. It tracks active objects no matter where they are. Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), + WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); // Initialization to support the transition to a new API which puts most of the logic // into the C# code so it is easier to modify and add to. - m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID)); - m_constraintCollection = new BSConstraintCollection(World); + World = new BulletSim(WorldID, this, BulletSimAPI.GetSimHandle2(WorldID)); + + Constraints = new BSConstraintCollection(World); + + // Note: choose one of the two following lines + // BulletSimAPI.CreateInitialGroundPlaneAndTerrain(WorldID); + TerrainManager = new BSTerrainManager(this); + TerrainManager.CreateInitialGroundPlaneAndTerrain(); m_initialized = true; } @@ -288,7 +296,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); // Very detailed logging for vehicle debugging - m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); + VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); // Do any replacements in the parameters m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); @@ -323,6 +331,38 @@ public class BSScene : PhysicsScene, IPhysicsParameters PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); } + public override void Dispose() + { + // m_log.DebugFormat("{0}: Dispose()", LogHeader); + + // make sure no stepping happens while we're deleting stuff + m_initialized = false; + + TerrainManager.ReleaseGroundPlaneAndTerrain(); + + foreach (KeyValuePair kvp in PhysObjects) + { + kvp.Value.Destroy(); + } + PhysObjects.Clear(); + + // Now that the prims are all cleaned up, there should be no constraints left + if (Constraints != null) + { + Constraints.Dispose(); + Constraints = null; + } + + // Anything left in the unmanaged code should be cleaned out + BulletSimAPI.Shutdown(WorldID); + + // Not logging any more + PhysicsLogging.Close(); + } + #endregion // Construction and Initialization + + #region Prim and Avatar addition and removal + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) { m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); @@ -413,6 +453,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters // information call is not needed. public override void AddPhysicsActorTaint(PhysicsActor prim) { } + #endregion // Prim and Avatar addition and removal + + #region Simulation // Simulate one timestep public override float Simulate(float timeStep) { @@ -428,7 +471,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters int simulateStartTime = Util.EnvironmentTickCount(); - // update the prim states while we know the physics engine is not busy + // update the prim states while we know the physics engine is not busy + int numTaints = _taintedObjects.Count; ProcessTaints(); // Some of the prims operate with special vehicle properties @@ -440,14 +484,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters int numSubSteps = 0; try { - numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, + numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); - DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); + DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}", + DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); } catch (Exception e) { - m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); - // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); + m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", + LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); + DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}", + DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); updatedEntityCount = 0; collidersCount = 0; } @@ -456,7 +503,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // 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 - m_simulationNowTime = Util.EnvironmentTickCount(); + SimulationNowTime = Util.EnvironmentTickCount(); // If there were collisions, process them by sending the event to the prim. // Collisions must be processed before updates. @@ -527,7 +574,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // Something has collided private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration) { - if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) + if (localID <= TerrainManager.HighestTerrainID) { return; // don't send collisions to the terrain } @@ -539,7 +586,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters BSPhysObject collidee = null; ActorTypes type = ActorTypes.Prim; - if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) + if (collidingWith <= TerrainManager.HighestTerrainID) { type = ActorTypes.Ground; } @@ -558,28 +605,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters return; } + #endregion // Simulation + public override void GetResults() { } - public override void SetTerrain(float[] heightMap) { - m_heightMap = heightMap; - this.TaintedObject("BSScene.SetTerrain", delegate() - { - BulletSimAPI.SetHeightmap(m_worldID, m_heightMap); - }); - } + #region Terrain - // Someday we will have complex terrain with caves and tunnels - // For the moment, it's flat and convex - public float GetTerrainHeightAtXYZ(Vector3 loc) - { - return GetTerrainHeightAtXY(loc.X, loc.Y); - } - - public float GetTerrainHeightAtXY(float tX, float tY) - { - if (tX < 0 || tX >= Constants.RegionSize || tY < 0 || tY >= Constants.RegionSize) - return 30; - return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)]; + public override void SetTerrain(float[] heightMap) { + TerrainManager.SetTerrain(heightMap); } public override void SetWaterLevel(float baseheight) @@ -595,35 +628,29 @@ public class BSScene : PhysicsScene, IPhysicsParameters public override void DeleteTerrain() { // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); + } + + // Although no one seems to check this, I do support combining. + public override bool SupportsCombining() + { + return TerrainManager.SupportsCombining(); } - - public override void Dispose() - { - // m_log.DebugFormat("{0}: Dispose()", LogHeader); - - // make sure no stepping happens while we're deleting stuff - m_initialized = false; - - foreach (KeyValuePair kvp in PhysObjects) - { - kvp.Value.Destroy(); - } - PhysObjects.Clear(); - - // Now that the prims are all cleaned up, there should be no constraints left - if (m_constraintCollection != null) - { - m_constraintCollection.Dispose(); - m_constraintCollection = null; - } - - // Anything left in the unmanaged code should be cleaned out - BulletSimAPI.Shutdown(WorldID); - - // Not logging any more - PhysicsLogging.Close(); + // This call says I am a child to region zero in a mega-region. 'pScene' is that + // of region zero, 'offset' is my offset from regions zero's origin, and + // 'extents' is the largest XY that is handled in my region. + public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) + { + TerrainManager.Combine(pScene, offset, extents); + } + + // Unhook all the combining that I know about. + public override void UnCombine(PhysicsScene pScene) + { + TerrainManager.UnCombine(pScene); } + #endregion // Terrain + public override Dictionary GetTopColliders() { return new Dictionary(); @@ -833,14 +860,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters // no locking because only called when physics engine is not busy private void ProcessVehicles(float timeStep) { - foreach (BSPrim prim in m_vehicles) + foreach (BSPhysObject pobj in m_vehicles) { - prim.StepVehicle(timeStep); + pobj.StepVehicle(timeStep); } } #endregion Vehicles - #region Parameters + #region INI and command line parameter processing delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); delegate float ParamGet(BSScene scene); @@ -943,9 +970,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", 10000.01f, - (s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)s.m_maximumObjectMass; }, - (s,p,l,v) => { s.m_maximumObjectMass = v; } ), + (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)s.MaximumObjectMass; }, + (s,p,l,v) => { s.MaximumObjectMass = v; } ), new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 2200f, @@ -1207,6 +1234,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; + // This creates an array in the correct format for returning the list of + // parameters. This is used by the 'list' option of the 'physics' command. private void BuildParameterTable() { if (SettableParameters.Length < ParameterDefinitions.Length) @@ -1283,7 +1312,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters TaintedObject("BSScene.UpdateParameterSet", delegate() { foreach (uint lID in objectIDs) { - BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); + BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval); } }); break; @@ -1301,7 +1330,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters string xparm = parm.ToLower(); float xval = val; TaintedObject("BSScene.TaintedUpdateParameter", delegate() { - BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); + BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval); }); } -- cgit v1.1 From d3adf9b2b3bd8e0e76168cd6eb6414f3123c5f02 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 25 Aug 2012 23:25:29 -0700 Subject: BulletSim: fix line endings. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index f80304d..7b4802e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -102,7 +102,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters public uint WorldID { get; private set; } public BulletSim World { get; private set; } - // All the constraints that have been allocated in this instance. + // All the constraints that have been allocated in this instance. public BSConstraintCollection Constraints { get; private set; } // Simulation parameters @@ -117,7 +117,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters public float LastSimulatedTimestep { get; private set; } // 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 + // Set to 'now' just before all the prims and actors are called for collisions and updates public int SimulationNowTime { get; private set; } // True if initialized and ready to do simulation steps @@ -140,8 +140,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero public const uint GROUNDPLANE_ID = 1; - public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here - + public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here + private float m_waterLevel; public BSTerrainManager TerrainManager { get; private set; } @@ -189,8 +189,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters private bool m_physicsLoggingEnabled; private string m_physicsLoggingDir; private string m_physicsLoggingPrefix; - private int m_physicsLoggingFileMinutes; - // 'true' of the vehicle code is to log lots of details + private int m_physicsLoggingFileMinutes; + // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } #region Construction and Initialization @@ -266,7 +266,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters Constraints = new BSConstraintCollection(World); // Note: choose one of the two following lines - // BulletSimAPI.CreateInitialGroundPlaneAndTerrain(WorldID); + // BulletSimAPI.CreateInitialGroundPlaneAndTerrain(WorldID); TerrainManager = new BSTerrainManager(this); TerrainManager.CreateInitialGroundPlaneAndTerrain(); @@ -471,7 +471,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters int simulateStartTime = Util.EnvironmentTickCount(); - // update the prim states while we know the physics engine is not busy + // update the prim states while we know the physics engine is not busy int numTaints = _taintedObjects.Count; ProcessTaints(); @@ -611,7 +611,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters #region Terrain - public override void SetTerrain(float[] heightMap) { + public override void SetTerrain(float[] heightMap) { TerrainManager.SetTerrain(heightMap); } @@ -628,25 +628,25 @@ public class BSScene : PhysicsScene, IPhysicsParameters public override void DeleteTerrain() { // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); - } - - // Although no one seems to check this, I do support combining. - public override bool SupportsCombining() - { - return TerrainManager.SupportsCombining(); + } + + // Although no one seems to check this, I do support combining. + public override bool SupportsCombining() + { + return TerrainManager.SupportsCombining(); } // This call says I am a child to region zero in a mega-region. 'pScene' is that // of region zero, 'offset' is my offset from regions zero's origin, and // 'extents' is the largest XY that is handled in my region. public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) - { + { TerrainManager.Combine(pScene, offset, extents); - } - - // Unhook all the combining that I know about. - public override void UnCombine(PhysicsScene pScene) - { - TerrainManager.UnCombine(pScene); + } + + // Unhook all the combining that I know about. + public override void UnCombine(PhysicsScene pScene) + { + TerrainManager.UnCombine(pScene); } #endregion // Terrain -- cgit v1.1 From ae852bb8738c7bce60c8fee9fbf6038288bd9363 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 29 Aug 2012 09:20:09 -0700 Subject: BulletSim: clean up some variable naming for consistancy. Update DLL API for new terrain and shape/body pattern methods. Terrain creation and modification uses new shape/body pattern. Move debug logging callback set to initialization call so logging is per physics engine. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7b4802e..2f55ba4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -232,15 +232,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters } // If Debug logging level, enable logging from the unmanaged code + m_DebugLogCallbackHandle = null; if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) { m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); if (PhysicsLogging.Enabled) + // The handle is saved in a variable to make sure it doesn't get freed after this call 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); } // Get the version of the DLL @@ -257,7 +257,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), - m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); + m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(), + m_DebugLogCallbackHandle); // Initialization to support the transition to a new API which puts most of the logic // into the C# code so it is easier to modify and add to. @@ -265,8 +266,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters Constraints = new BSConstraintCollection(World); - // Note: choose one of the two following lines - // BulletSimAPI.CreateInitialGroundPlaneAndTerrain(WorldID); TerrainManager = new BSTerrainManager(this); TerrainManager.CreateInitialGroundPlaneAndTerrain(); @@ -378,7 +377,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); lock (PhysObjects) PhysObjects.Add(localID, actor); - // Remove kludge someday + // TODO: Remove kludge someday. + // We must generate a collision for avatars whether they collide or not. + // This is required by OpenSim to update avatar animations, etc. lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor); return actor; -- cgit v1.1 From ffdc7987207de279116a077e2042ed3a1f381a5f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 31 Aug 2012 11:33:36 -0700 Subject: BulletSim: Update BulletSimAPI to match the DLL interface. Major rework of terrain management which finally makes mega-regions work. Update heightmap of terrain by rebuilding the terrain's body and shape. There is a problem with just replacing the shape so this workaround will do for the moment but it will need to be resolved for mesh and hull switching. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 2f55ba4..4a468af 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1070,7 +1070,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].terrainRestitution; }, (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ), new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", - 0.5f, + 0.2f, (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarFriction; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), -- cgit v1.1