From 3d0fc708647ceb734385f90e2f22be9774e2171e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 31 Dec 2012 16:22:45 -0800 Subject: BulletSim: complete movement of BulletSimAPI functions to BSAPITemplate. Update BulletSim DLLs and SOs with simplier step function interface. --- OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs | 4 - OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 217 +++++++++++++++------ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 78 ++++---- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 43 ++-- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 127 ++++++------ .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 12 +- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 8 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 10 +- .../Region/Physics/Manager/PhysicsPluginManager.cs | 2 +- 10 files changed, 311 insertions(+), 194 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs index 9c4ba30..aadb5b2 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs @@ -111,10 +111,6 @@ public sealed class BSPrim : BSPhysObject _mass = CalculateMass(); - // No body or shape yet - PhysBody = new BulletBody(LocalID); - PhysShape = new BulletShape(); - Linkset.Refresh(this); DetailLog("{0},BSPrim.constructor,call", LocalID); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 6e68053..0355b94 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -36,31 +37,102 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public sealed class BSAPIUnman : BSAPITemplate { - /* + +// We pin the memory passed between the managed and unmanaged code. +GCHandle m_paramsHandle; +private GCHandle m_collisionArrayPinnedHandle; +private GCHandle m_updateArrayPinnedHandle; + +// Handle to the callback used by the unmanaged code to call into the managed code. +// Used for debug logging. +// Need to store the handle in a persistant variable so it won't be freed. +private BSAPICPP.DebugLogCallback m_DebugLogCallbackHandle; + +private BSScene PhysicsScene { get; set; } + +public override string BulletEngineName { get { return "BulletUnmanaged"; } } +public override string BulletEngineVersion { get; protected set; } + +public BSAPIUnman(string paramName, BSScene physScene) +{ + PhysicsScene = physScene; + // Do something fancy with the paramName to get the right DLL implementation + // like "Bullet-2.80-OpenCL-Intel" loading the version for Intel based OpenCL implementation, etc. +} + // Initialization and simulation -public BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray - ); +public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, + int maxCollisions, ref CollisionDesc[] collisionArray, + int maxUpdates, ref EntityProperties[] updateArray + ) +{ + // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code + m_paramsHandle = GCHandle.Alloc(parms, GCHandleType.Pinned); + m_collisionArrayPinnedHandle = GCHandle.Alloc(collisionArray, GCHandleType.Pinned); + m_updateArrayPinnedHandle = GCHandle.Alloc(updateArray, GCHandleType.Pinned); -public bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); + // If Debug logging level, enable logging from the unmanaged code + m_DebugLogCallbackHandle = null; + if (BSScene.m_log.IsDebugEnabled || PhysicsScene.PhysicsLogging.Enabled) + { + BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); + if (PhysicsScene.PhysicsLogging.Enabled) + // The handle is saved in a variable to make sure it doesn't get freed after this call + m_DebugLogCallbackHandle = new BSAPICPP.DebugLogCallback(BulletLoggerPhysLog); + else + m_DebugLogCallbackHandle = new BSAPICPP.DebugLogCallback(BulletLogger); + } -public void SetHeightMap(BulletWorld world, float[] heightmap); + // Get the version of the DLL + // TODO: this doesn't work yet. Something wrong with marshaling the returned string. + // BulletEngineVersion = BulletSimAPI.GetVersion2(); + BulletEngineVersion = ""; + + // Call the unmanaged code with the buffers and other information + return new BulletWorld(0, PhysicsScene, BSAPICPP.Initialize2(maxPosition, m_paramsHandle.AddrOfPinnedObject(), + maxCollisions, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), + maxUpdates, m_updateArrayPinnedHandle.AddrOfPinnedObject(), + m_DebugLogCallbackHandle)); -public void Shutdown(BulletWorld sim); +} -public int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); +// Called directly from unmanaged code so don't do much +private void BulletLogger(string msg) +{ + BSScene.m_log.Debug("[BULLETS UNMANAGED]:" + msg); +} + +// Called directly from unmanaged code so don't do much +private void BulletLoggerPhysLog(string msg) +{ + PhysicsScene.DetailLog("[BULLETS UNMANAGED]:" + msg); +} + + /* +public void SetHeightMap(BulletWorld world, float[] heightmap); */ +public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, out int collidersCount) +{ + return BSAPICPP.PhysicsStep2(world.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); +} + +public override void Shutdown(BulletWorld sim) +{ + BSAPICPP.Shutdown2(sim.ptr); +} + public override bool PushUpdate(BulletBody obj) { return BSAPICPP.PushUpdate2(obj.ptr); } +public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) +{ + return BSAPICPP.UpdateParameter2(world.ptr, localID, parm, value); +} + // ===================================================================================== // Mesh, hull, shape and body creation helper routines public override BulletShape CreateMeshShape(BulletWorld world, @@ -893,11 +965,81 @@ public override float GetMargin(BulletShape shape) return BSAPICPP.GetMargin2(shape.ptr); } +// ===================================================================================== +// Debugging +public override void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) +{ + BSAPICPP.DumpRigidBody2(sim.ptr, collisionObject.ptr); +} + +public override void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) +{ + BSAPICPP.DumpCollisionShape2(sim.ptr, collisionShape.ptr); +} + +public override void DumpMapInfo(BulletWorld sim, BulletHMapInfo mapInfo) +{ + BSAPICPP.DumpMapInfo2(sim.ptr, mapInfo.ptr); +} + +public override void DumpConstraint(BulletWorld sim, BulletConstraint constrain) +{ + BSAPICPP.DumpConstraint2(sim.ptr, constrain.ptr); +} + +public override void DumpActivationInfo(BulletWorld sim) +{ + BSAPICPP.DumpActivationInfo2(sim.ptr); +} + +public override void DumpAllInfo(BulletWorld sim) +{ + BSAPICPP.DumpAllInfo2(sim.ptr); +} + +public override void DumpPhysicsStatistics(BulletWorld sim) +{ + BSAPICPP.DumpPhysicsStatistics2(sim.ptr); +} + + +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// The actual interface to the unmanaged code static class BSAPICPP { +// =============================================================================== +// Link back to the managed code for outputting log messages +[UnmanagedFunctionPointer(CallingConvention.Cdecl)] +public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); + +// =============================================================================== +// Initialization and simulation +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray, + DebugLogCallback logRoutine); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHeightMap2(IntPtr world, float[] heightmap); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, out int collidersCount); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Shutdown2(IntPtr sim); + [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool PushUpdate2(IntPtr obj); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); + // ===================================================================================== // Mesh, hull, shape and body creation helper routines [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -1431,52 +1573,6 @@ public static extern void SetMargin2(IntPtr shape, float val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern float GetMargin2(IntPtr shape); -} -} - -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -static class BulletSimAPI { -// =============================================================================== -// Link back to the managed code for outputting log messages -[UnmanagedFunctionPointer(CallingConvention.Cdecl)] -public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); - -// =============================================================================== -// Initialization and simulation -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray, - DebugLogCallback logRoutine); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHeightMap2(IntPtr world, float[] heightmap); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Shutdown2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); - // ===================================================================================== // Debugging [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -1501,4 +1597,7 @@ public static extern void DumpAllInfo2(IntPtr sim); public static extern void DumpPhysicsStatistics2(IntPtr sim); } + +} + } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index a56a817..8ed791e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1,39 +1,39 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - /* -public sealed class BSAPIXNA : BulletSimAPITemplate -{ -} - */ -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + /* +public sealed class BSAPIXNA : BSAPITemplate +{ +} + */ +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index fbf362d..64a886b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -292,26 +292,27 @@ public enum ConstraintParamAxis : int public abstract class BSAPITemplate { - /* +// Returns the name of the underlying Bullet engine +public abstract string BulletEngineName { get; } +public abstract string BulletEngineVersion { get; protected set;} + // Initialization and simulation -public abstract BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray +public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, + int maxCollisions, ref CollisionDesc[] collisionArray, + int maxUpdates, ref EntityProperties[] updateArray ); -public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); - + /* public abstract void SetHeightMap(BulletWorld world, float[] heightmap); -public abstract void Shutdown(BulletWorld sim); - + */ public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); + out int updatedEntityCount, out int collidersCount); + +public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); + +public abstract void Shutdown(BulletWorld sim); - */ public abstract bool PushUpdate(BulletBody obj); // ===================================================================================== @@ -660,5 +661,21 @@ public abstract void SetMargin(BulletShape shape, float val); public abstract float GetMargin(BulletShape shape); +// ===================================================================================== +// Debugging +public abstract void DumpRigidBody(BulletWorld sim, BulletBody collisionObject); + +public abstract void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape); + +public abstract void DumpMapInfo(BulletWorld sim, BulletHMapInfo mapInfo); + +public abstract void DumpConstraint(BulletWorld sim, BulletConstraint constrain); + +public abstract void DumpActivationInfo(BulletWorld sim); + +public abstract void DumpAllInfo(BulletWorld sim); + +public abstract void DumpPhysicsStatistics(BulletWorld sim); + }; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index e4e3edc..13c2539 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -823,7 +823,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (!IsActive) return; if (PhysicsScene.VehiclePhysicalLoggingEnabled) - BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); + PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); ForgetKnownVehicleProperties(); @@ -840,7 +840,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin PushKnownChanged(); if (PhysicsScene.VehiclePhysicalLoggingEnabled) - BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); + PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 28c6680..258b72f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -42,8 +43,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public sealed class BSScene : PhysicsScene, IPhysicsParameters { - private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private static readonly string LogHeader = "[BULLETS SCENE]"; + internal static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + internal static readonly string LogHeader = "[BULLETS SCENE]"; // The name of the region we're working for. public string RegionName { get; private set; } @@ -51,6 +52,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public string BulletSimVersion = "?"; // The handle to the underlying managed or unmanaged version of Bullet being used. + public string BulletEngineName { get; private set; } public BSAPITemplate PE; public Dictionary PhysObjects; @@ -102,11 +104,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Pinned memory used to pass step information between managed and unmanaged internal int m_maxCollisionsPerFrame; internal CollisionDesc[] m_collisionArray; - internal GCHandle m_collisionArrayPinnedHandle; internal int m_maxUpdatesPerFrame; internal EntityProperties[] m_updateArray; - internal GCHandle m_updateArrayPinnedHandle; public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero public const uint GROUNDPLANE_ID = 1; @@ -152,12 +152,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // A pointer to an instance if this structure is passed to the C++ code // Used to pass basic configuration values to the unmanaged code. internal ConfigurationParameters[] UnmanagedParams; - GCHandle m_paramsHandle; - - // Handle to the callback used by the unmanaged code to call into the managed code. - // Used for debug logging. - // Need to store the handle in a persistant variable so it won't be freed. - private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; // Sometimes you just have to log everything. public Logging.LogWriter PhysicsLogging; @@ -194,15 +188,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Set default values for physics parameters plus any overrides from the ini file GetInitialParameterValues(config); - // For the moment, only one version of the interface - PE = new BSAPIUnman(); - - // Allocate more pinned memory. Do this early to try and get all pinned memory close together. - m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); - m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; - m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); - m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; - m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + // Get the connection to the physics engine (could be native or one of many DLLs) + PE = SelectUnderlyingBulletEngine(BulletEngineName); // Enable very detailed logging. // By creating an empty logger when not logging, the log message invocation code @@ -217,22 +204,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters PhysicsLogging = new Logging.LogWriter(); } - // 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); - } - - // 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); + // Allocate memory for returning of the updates and collisions from the physics engine + m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; + m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; // The bounding box for the simulated world. The origin is 0,0,0 unless we're // a child in a mega-region. @@ -240,11 +214,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // area. It tracks active objects no matter where they are. Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); - // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, m_paramsHandle.AddrOfPinnedObject(), - m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), - m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(), - m_DebugLogCallbackHandle)); + World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray); Constraints = new BSConstraintCollection(World); @@ -274,6 +244,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { BSParam.SetParameterConfigurationValues(this, pConfig); + // There are two Bullet implementations to choose from + BulletEngineName = pConfig.GetString("BulletEngine", "BulletUnmanaged"); + // Very detailed logging for physics debugging // TODO: the boolean values can be moved to the normal parameter processing. m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); @@ -315,16 +288,41 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters return ret; } - // Called directly from unmanaged code so don't do much - private void BulletLogger(string msg) + // Select the connection to the actual Bullet implementation. + // The main engine selection is the engineName up to the first hypen. + // So "Bullet-2.80-OpenCL-Intel" specifies the 'bullet' class here and the whole name + // is passed to the engine to do its special selection, etc. + private BSAPITemplate SelectUnderlyingBulletEngine(string engineName) { - m_log.Debug("[BULLETS UNMANAGED]:" + msg); - } + // For the moment, do a simple switch statement. + // Someday do fancyness with looking up the interfaces in the assembly. + BSAPITemplate ret = null; - // Called directly from unmanaged code so don't do much - private void BulletLoggerPhysLog(string msg) - { - DetailLog("[BULLETS UNMANAGED]:" + msg); + string selectionName = engineName.ToLower(); + int hyphenIndex = engineName.IndexOf("-"); + if (hyphenIndex > 0) + selectionName = engineName.ToLower().Substring(0, hyphenIndex - 1); + + switch (selectionName) + { + case "bulletunmanaged": + ret = new BSAPIUnman(engineName, this); + break; + case "bulletxna": + // ret = new BSAPIXNA(engineName, this); + break; + } + + if (ret == null) + { + m_log.ErrorFormat("{0) COULD NOT SELECT BULLET ENGINE: '[BulletSim]PhysicsEngine' must be either 'BulletUnmanaged-*' or 'BulletXNA-*'", LogHeader); + } + else + { + m_log.WarnFormat("{0} Selected bullet engine {1} -> {2}/{3}", LogHeader, engineName, ret.BulletEngineName, ret.BulletEngineVersion); + } + + return ret; } public override void Dispose() @@ -361,7 +359,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } // Anything left in the unmanaged code should be cleaned out - BulletSimAPI.Shutdown2(World.ptr); + PE.Shutdown(World); // Not logging any more PhysicsLogging.Close(); @@ -474,9 +472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters LastTimeStep = timeStep; int updatedEntityCount = 0; - IntPtr updatedEntitiesPtr; int collidersCount = 0; - IntPtr collidersPtr; int beforeTime = 0; int simTime = 0; @@ -492,6 +488,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters TriggerPreStepEvent(timeStep); // the prestep actions might have added taints + numTaints += _taintOperations.Count; ProcessTaints(); InTaintTime = false; // Only used for debugging so locking is not necessary. @@ -499,23 +496,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // 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. if (m_physicsPhysicalDumpEnabled) - BulletSimAPI.DumpAllInfo2(World.ptr); + PE.DumpAllInfo(World); // step the physical world one interval m_simulationStep++; int numSubSteps = 0; - try { - if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); + if (PhysicsLogging.Enabled) + beforeTime = Util.EnvironmentTickCount(); - numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, - out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); + numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount); - if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); - 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 (PhysicsLogging.Enabled) + { + simTime = Util.EnvironmentTickCountSubtract(beforeTime); + 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); + } } catch (Exception e) { @@ -527,8 +526,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters collidersCount = 0; } - // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in. - // Get a value for 'now' so all the collision and update routines don't have to get their own. SimulationNowTime = Util.EnvironmentTickCount(); @@ -570,7 +567,7 @@ 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 + // event call after all real collisions have happened on an object. This enables // the simulator to generate the 'collision end' event. if (ObjectsWithNoMoreCollisions.Count > 0) { @@ -599,11 +596,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // 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. if (m_physicsPhysicalDumpEnabled) - BulletSimAPI.DumpAllInfo2(World.ptr); + PE.DumpAllInfo(World); // The physics engine returns the number of milliseconds it simulated this call. // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. - // Multiply by 55 to give a nominal frame rate of 55. + // Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55). return (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index cc28344..0802b3a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -44,7 +44,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; - BulletHeightMapInfo m_mapInfo = null; + BulletHMapInfo m_mapInfo = null; // Constructor to build a default, flat heightmap terrain. public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) @@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; } - m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo = new BulletHMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.terrainRegionBase = TerrainBase; @@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys Vector3 minCoords, Vector3 maxCoords) : base(physicsScene, regionBase, id) { - m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo = new BulletHMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo.minCoords = minCoords; m_mapInfo.maxCoords = maxCoords; m_mapInfo.minZ = minCoords.Z; @@ -91,12 +91,12 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // Using the information in m_mapInfo, create the physical representation of the heightmap. private void BuildHeightmapTerrain() { - m_mapInfo.Ptr = PhysicsScene.PE.CreateHeightMapInfo(PhysicsScene.World, m_mapInfo.ID, + m_mapInfo.ptr = PhysicsScene.PE.CreateHeightMapInfo(PhysicsScene.World, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape(m_mapInfo.Ptr); + m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape(m_mapInfo.ptr); // The terrain object initial position is at the center of the object Vector3 centerPos; @@ -138,7 +138,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_mapInfo.terrainBody); // Frees both the body and the shape. PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody); - PhysicsScene.PE.ReleaseHeightMapInfo(m_mapInfo.Ptr); + PhysicsScene.PE.ReleaseHeightMapInfo(m_mapInfo.ptr); } } m_mapInfo = null; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index a040928..c8f4602 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -187,11 +187,11 @@ public class BulletConstraint // Made a class rather than a struct so there would be only one // instance of this and C# will pass around pointers rather // than making copies. -public class BulletHeightMapInfo +public class BulletHMapInfo { - public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { + public BulletHMapInfo(uint id, float[] hm, IntPtr xx) { ID = id; - Ptr = xx; + ptr = xx; heightMap = hm; terrainRegionBase = OMV.Vector3.Zero; minCoords = new OMV.Vector3(100f, 100f, 25f); @@ -200,7 +200,7 @@ public class BulletHeightMapInfo sizeX = sizeY = 256f; } public uint ID; - public IntPtr Ptr; + public IntPtr ptr; public float[] heightMap; public OMV.Vector3 terrainRegionBase; public OMV.Vector3 minCoords; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 4cb8e6d..a8a4ff5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -61,7 +61,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl BULLETSIM TODO LIST: ================================================= -Avatar density is WAY off. Compare and calibrate with what's in SL. +Implement an avatar mesh shape. The Bullet capsule is way too limited. + Consider just hand creating a vertex/index array in a new BSShapeAvatar. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. @@ -170,6 +171,9 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179 INTERNAL IMPROVEMENT/CLEANUP ================================================= +Create the physical wrapper classes (BulletBody, BulletShape) by methods on + BSAPITemplate and make their actual implementation Bullet engine specific. + For the short term, just call the existing functions in ShapeCollection. Consider moving prim/character body and shape destruction in destroy() to postTimeTime rather than protecting all the potential sets that might have been queued up. @@ -204,6 +208,8 @@ Should taints check for existance or activeness of target? Possibly have and 'active' flag that is checked by the taint processor? Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? +There are TOO MANY interfaces from BulletSim core to Bullet itself + Think of something to eliminate one or more of the layers THREADING ================================================= @@ -262,3 +268,5 @@ llApplyImpulse() (Resolution: tested on SL and OS. AddForce scales the force for timestep) llSetBuoyancy() (DONE) (Resolution: Bullet resets object gravity when added to world. Moved set gravity) +Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE) + (Resolution: set default density to 3.5 (from 60) which is closer to SL) diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs index 8587a2b..8ccfda5 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using Nini.Config; -using log4net; +using log4net; using OpenSim.Framework; namespace OpenSim.Region.Physics.Manager -- cgit v1.1