From 5ab151c2d69277b8c528b8ebe94d2b0d2312a2fc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 8 Aug 2012 13:48:49 -0700 Subject: [PATCH 1/5] BulletSim: add avatar code to keep avatars from ending up trapped under the terrain --- .../Physics/BulletSPlugin/BSCharacter.cs | 56 +++++++++---------- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 13 +++-- .../Region/Physics/BulletSPlugin/BSPrim.cs | 4 +- .../Region/Physics/BulletSPlugin/BSScene.cs | 26 ++++----- bin/OpenSimDefaults.ini | 2 +- 5 files changed, 47 insertions(+), 54 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d4f5c63309..8149a5359e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -205,6 +205,8 @@ public class BSCharacter : PhysicsActor } set { _position = value; + PositionSanityCheck(); + _scene.TaintedObject(delegate() { DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); @@ -212,6 +214,28 @@ public class BSCharacter : PhysicsActor }); } } + + // Check that the current position is sane and, if not, modify the position to make it so. + // Check for being below terrain and being out of bounds. + // Returns 'true' of the position was made sane by some action. + private bool PositionSanityCheck() + { + bool ret = false; + + // If below the ground, move the avatar up + float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); + if (_position.Z < terrainHeight) + { + DetailLog("{0},PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); + _position.Z = terrainHeight + 2.0f; + ret = true; + } + + // TODO: check for out of bounds + + return ret; + } + public override float Mass { get { return _mass; @@ -456,42 +480,12 @@ public class BSCharacter : PhysicsActor // the world that things have changed. public void UpdateProperties(EntityProperties entprop) { - /* - bool changed = false; - // we assign to the local variables so the normal set action does not happen - if (_position != entprop.Position) { - _position = entprop.Position; - changed = true; - } - if (_orientation != entprop.Rotation) { - _orientation = entprop.Rotation; - changed = true; - } - if (_velocity != entprop.Velocity) { - _velocity = entprop.Velocity; - changed = true; - } - if (_acceleration != entprop.Acceleration) { - _acceleration = entprop.Acceleration; - changed = true; - } - if (_rotationalVelocity != entprop.RotationalVelocity) { - _rotationalVelocity = entprop.RotationalVelocity; - changed = true; - } - if (changed) { - // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); - // Avatar movement is not done by generating this event. There is code in the heartbeat - // loop that updates avatars. - // base.RequestPhysicsterseUpdate(); - } - */ _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; - // Avatars don't report theirr changes the usual way. Changes are checked for in the heartbeat loop. + // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 6f8430c8cc..d19c4b8122 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -296,13 +296,13 @@ public class BSLinkset DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); BSConstraint constrain = m_scene.Constraints.CreateConstraint( m_scene.World, m_linksetRoot.Body, childPrim.Body, - // childRelativePosition, - // childRelativeRotation, + childRelativePosition, + childRelativeRotation, OMV.Vector3.Zero, - OMV.Quaternion.Identity, - OMV.Vector3.Zero, - OMV.Quaternion.Identity + -childRelativeRotation ); + + // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); @@ -339,7 +339,8 @@ public class BSLinkset // Invoke the detailed logger and output something if it's enabled. private void DebugLog(string msg, params Object[] args) { - m_scene.Logger.DebugFormat(msg, args); + if (m_scene.ShouldDebugLog) + m_scene.Logger.DebugFormat(msg, args); } // Invoke the detailed logger and output something if it's enabled. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 11868bc35e..98b69b14b1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -42,7 +42,7 @@ public sealed class BSPrim : PhysicsActor private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS PRIM]"; - private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); } + private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); } private IMesh _mesh; private PrimitiveBaseShape _pbs; @@ -1338,7 +1338,6 @@ public sealed class BSPrim : PhysicsActor base.RequestPhysicsterseUpdate(); } - /* else { // For debugging, we also report the movement of children @@ -1346,7 +1345,6 @@ public sealed class BSPrim : PhysicsActor LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } - */ } // I've collided with something diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 0e257b63b8..117086ad4b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -73,7 +73,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS SCENE]"; - public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); } + public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } public string BulletSimVersion = "?"; @@ -169,7 +169,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters ConfigurationParameters[] m_params; GCHandle m_paramsHandle; - public bool shouldDebugLog { get; private set; } + public bool ShouldDebugLog { get; private set; } private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; @@ -812,12 +812,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters private struct ParameterDefn { - public string name; - public string desc; - public float defaultValue; - public ParamUser userParam; - public ParamGet getter; - public ParamSet setter; + public string name; // string name of the parameter + public string desc; // a short description of what the parameter means + public float defaultValue; // default value if not specified anywhere else + public ParamUser userParam; // get the value from the configuration file + public ParamGet getter; // return the current value stored for this parameter + public ParamSet setter; // set the current value for this parameter public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) { name = n; @@ -834,7 +834,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // To add a new externally referencable/settable parameter, add the paramter storage // location somewhere in the program and make an entry in this table with the // getters and setters. - // To add a new variable, it is easiest to find an existing definition and copy it. + // It is easiest to find an existing definition and copy it. // Parameter values are floats. Booleans are converted to a floating value. // // A ParameterDefn() takes the following parameters: @@ -870,7 +870,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters (s) => { return (float)s.m_meshLOD; }, (s,p,l,v) => { s.m_meshLOD = (int)v; } ), new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", - 32, + 32f, (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, (s) => { return (float)s.m_sculptLOD; }, (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), @@ -1106,9 +1106,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements", ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s.shouldDebugLog); }, - (s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ), + (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); }, + (s) => { return s.NumericBool(s.ShouldDebugLog); }, + (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ), }; diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index a27e775775..dcbd90cee0 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -939,7 +939,7 @@ FixedTimeStep = .01667 MaxCollisionsPerFrame = 2048 - MaxUpdatesPerFrame = 2048 + MaxUpdatesPerFrame = 8192 [RemoteAdmin] enabled = false From 38e79b80a87d213748d55d66e8b72021999d3945 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 9 Aug 2012 15:01:05 -0700 Subject: [PATCH 2/5] BulletSim: separate out the constraints by type. The linksets use 6dof constraint but eventually others will be exposed so future features can use all the Bullet capabilities. Force children to generate a position update when unlinked. --- .../Physics/BulletSPlugin/BS6DofConstraint.cs | 80 +++++++++++++++++++ .../Physics/BulletSPlugin/BSConstraint.cs | 60 +++----------- .../BulletSPlugin/BSConstraintCollection.cs | 10 --- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 38 ++++++--- .../Region/Physics/BulletSPlugin/BSPrim.cs | 15 ++-- .../Physics/BulletSPlugin/BulletSimAPI.cs | 37 +++++---- 6 files changed, 146 insertions(+), 94 deletions(-) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs new file mode 100755 index 0000000000..72df6b9427 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs @@ -0,0 +1,80 @@ +/* + * 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.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public class BS6DofConstraint : BSConstraint +{ + // Create a btGeneric6DofConstraint + public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 frame1, Quaternion frame1rot, + Vector3 frame2, Quaternion frame2rot ) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + m_constraint = new BulletConstraint( + BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, + frame1, frame1rot, + frame2, frame2rot, + true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/)); + m_enabled = true; + } + + public bool SetCFMAndERP(float cfm, float erp) + { + bool ret = true; + BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); + BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + return ret; + } + + public bool UseFrameOffset(bool useOffset) + { + bool ret = false; + float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; + if (m_enabled) + ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff); + return ret; + } + + public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce) + { + bool ret = false; + float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; + if (m_enabled) + ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce); + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index ea3093a96b..a17efea8ea 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -32,30 +32,19 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -public class BSConstraint : IDisposable +public abstract class BSConstraint : IDisposable { - private BulletSim m_world; - private BulletBody m_body1; - private BulletBody m_body2; - private BulletConstraint m_constraint; - private bool m_enabled = false; + protected BulletSim m_world; + protected BulletBody m_body1; + protected BulletBody m_body2; + protected BulletConstraint m_constraint; + protected bool m_enabled = false; - public BSConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, - Vector3 frame1, Quaternion frame1rot, - Vector3 frame2, Quaternion frame2rot - ) + public BSConstraint() { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - m_constraint = new BulletConstraint(BulletSimAPI.CreateConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, - frame1, frame1rot, - frame2, frame2rot, - true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/)); - m_enabled = true; } - public void Dispose() + public virtual void Dispose() { if (m_enabled) { @@ -68,7 +57,7 @@ public class BSConstraint : IDisposable public BulletBody Body1 { get { return m_body1; } } public BulletBody Body2 { get { return m_body2; } } - public bool SetLinearLimits(Vector3 low, Vector3 high) + public virtual bool SetLinearLimits(Vector3 low, Vector3 high) { bool ret = false; if (m_enabled) @@ -76,7 +65,7 @@ public class BSConstraint : IDisposable return ret; } - public bool SetAngularLimits(Vector3 low, Vector3 high) + public virtual bool SetAngularLimits(Vector3 low, Vector3 high) { bool ret = false; if (m_enabled) @@ -84,34 +73,7 @@ public class BSConstraint : IDisposable return ret; } - public bool SetCFMAndERP(float cfm, float erp) - { - bool ret = true; - BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - return ret; - } - - public bool UseFrameOffset(bool useOffset) - { - bool ret = false; - float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; - if (m_enabled) - ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff); - return ret; - } - - public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce) - { - bool ret = false; - float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; - if (m_enabled) - ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce); - return ret; - } - - public bool CalculateTransforms() + public virtual bool CalculateTransforms() { bool ret = false; if (m_enabled) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs index c88e6455b9..397045a437 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -63,16 +63,6 @@ public class BSConstraintCollection : IDisposable m_constraints.Clear(); } - public BSConstraint CreateConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, - Vector3 frame1, Quaternion frame1rot, - Vector3 frame2, Quaternion frame2rot) - { - BSConstraint constrain = new BSConstraint(world, obj1, obj2, frame1, frame1rot, frame2, frame2rot); - - this.AddConstraint(constrain); - return constrain; - } - public bool AddConstraint(BSConstraint cons) { // There is only one constraint between any bodies. Remove any old just to make sure. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index d19c4b8122..e265d6dcc8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -101,7 +101,7 @@ public class BSLinkset { // Note that we don't do a foreach because the remove routine // takes it out of the list. - RemoveChildFromLinkset(m_children[0]); + RemoveChildFromOtherLinkset(m_children[0]); } m_children.Clear(); // just to make sure } @@ -124,6 +124,7 @@ public class BSLinkset lock (m_linksetActivityLock) { + // The body pointer is refetched in case anything has moved. System.IntPtr aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, m_linksetRoot.LocalID); if (aPtr == System.IntPtr.Zero) { @@ -155,7 +156,7 @@ public class BSLinkset } foreach (BSPrim bsp in toRemove) { - RemoveChildFromLinkset(bsp); + RemoveChildFromOtherLinkset(bsp); } } } @@ -208,7 +209,8 @@ public class BSLinkset com += bp.Position * bp.MassRaw; totalMass += bp.MassRaw; } - com /= totalMass; + if (totalMass != 0f) + com /= totalMass; return com; } @@ -221,7 +223,7 @@ public class BSLinkset { com += bp.Position * bp.MassRaw; } - com /= m_children.Count + 1; + com /= (m_children.Count + 1); return com; } @@ -237,13 +239,24 @@ public class BSLinkset m_scene.TaintedObject(delegate() { DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); - DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID); + DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child }); } return; } + // Forcefully removing a child from a linkset. + // This is not being called by the child so we have to make sure the child doesn't think + // it's still connected to the linkset. + // Normal OpenSimulator operation will never do this because other SceneObjectPart information + // has to be updated also (like pointer to prim's parent). + public void RemoveChildFromOtherLinkset(BSPrim pchild) + { + pchild.Linkset = new BSLinkset(m_scene, pchild); + RemoveChildFromLinkset(pchild); + } + // I am the root of a linkset and one of my children is being removed. // Safe to call even if the child is not really in my linkset. public void RemoveChildFromLinkset(BSPrim pchild) @@ -255,7 +268,7 @@ public class BSLinkset m_scene.TaintedObject(delegate() { DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); - DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID); + DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); if (m_children.Count == 0) { @@ -294,13 +307,14 @@ public class BSLinkset // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); - BSConstraint constrain = m_scene.Constraints.CreateConstraint( + BS6DofConstraint constrain = new BS6DofConstraint( m_scene.World, m_linksetRoot.Body, childPrim.Body, childRelativePosition, childRelativeRotation, OMV.Vector3.Zero, -childRelativeRotation ); + m_scene.Constraints.AddConstraint(constrain); // zero linear and angular limits makes the objects unable to move in relation to each other constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); @@ -319,11 +333,13 @@ public class BSLinkset // Called at taint time! private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim) { - DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", - LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); + // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", + // LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); - // BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID); + m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body); + // Make the child refresh its location + BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); } // Remove linkage between myself and any possible children I might have @@ -332,8 +348,8 @@ public class BSLinkset { // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID); + m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body); - // BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID); } // Invoke the detailed logger and output something if it's enabled. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 98b69b14b1..e0f6ed22c3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -224,10 +224,12 @@ public sealed class BSPrim : PhysicsActor // link me to the specified parent 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); - - _linkset = _linkset.AddMeToLinkset(this, parent); + if (parent != null) + { + DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); + DetailLog("{0},link,parent={1}", LocalID, parent.LocalID); + _linkset = _linkset.AddMeToLinkset(this, parent); + } return; } @@ -478,7 +480,6 @@ public sealed class BSPrim : PhysicsActor // 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() { // RA: remove this for the moment. @@ -982,7 +983,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) { - DetailLog("{0},CreateGeom,sphere", LocalID); + DetailLog("{0},CreateGeom,sphere (force={1}", LocalID, forceRebuild); _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; // Bullet native objects are scaled by the Bullet engine so pass the size in _scale = _size; @@ -996,7 +997,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) { - DetailLog("{0},CreateGeom,box", LocalID); + DetailLog("{0},CreateGeom,box (force={1})", LocalID, forceRebuild); _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _scale = _size; // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 86fc9d2dad..c016402057 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -363,7 +363,7 @@ public static extern IntPtr GetSimHandle2(uint worldID); public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id); +public static extern IntPtr GetBodyHandle2(IntPtr world, uint id); // =============================================================================== [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -372,40 +372,43 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, int maxUpdates, IntPtr updateArray); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UpdateParameter2(IntPtr sim, uint localID, String parm, float value); +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 sim, float[] heightmap); +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 sim, float timeStep, int maxSubSteps, float fixedTimeStep, +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); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool PushUpdate2(IntPtr obj); + /* [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateMesh2(IntPtr sim, int indicesCount, int* indices, int verticesCount, float* vertices ); +public static extern IntPtr CreateMesh2(IntPtr world, int indicesCount, int* indices, int verticesCount, float* vertices ); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool BuildHull2(IntPtr sim, IntPtr mesh); +public static extern bool BuildHull2(IntPtr world, IntPtr mesh); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool ReleaseHull2(IntPtr sim, IntPtr mesh); +public static extern bool ReleaseHull2(IntPtr world, IntPtr mesh); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DestroyMesh2(IntPtr sim, IntPtr mesh); +public static extern bool DestroyMesh2(IntPtr world, IntPtr mesh); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateObject2(IntPtr sim, ShapeData shapeData); +public static extern IntPtr CreateObject2(IntPtr world, ShapeData shapeData); */ [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateConstraint2(IntPtr sim, IntPtr obj1, IntPtr obj2, +public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, Vector3 frame1loc, Quaternion frame1rot, Vector3 frame2loc, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); @@ -429,7 +432,13 @@ public static extern bool CalculateTransforms2(IntPtr constrain); public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DestroyConstraint2(IntPtr sim, IntPtr constrain); +public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 AddObjectToWorld2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 RemoveObjectFromWorld2(IntPtr world, IntPtr obj); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern Vector3 GetPosition2(IntPtr obj); @@ -509,12 +518,6 @@ public static extern bool SetMargin2(IntPtr obj, float val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); - [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool DestroyObject2(IntPtr world, uint id); From 320982cae388814b8e7e9e9fe62724caa9621d90 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 9 Aug 2012 15:17:19 -0700 Subject: [PATCH 3/5] BulletSim: add an identifier to the TaintObject call so exceptions that happen when the taint is invoked can be debugged --- .../Physics/BulletSPlugin/BSCharacter.cs | 22 ++++----- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 4 +- .../Region/Physics/BulletSPlugin/BSPrim.cs | 49 +++++++++---------- .../Region/Physics/BulletSPlugin/BSScene.cs | 34 ++++++++----- 4 files changed, 57 insertions(+), 52 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8149a5359e..d49a578561 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -122,7 +122,7 @@ public class BSCharacter : PhysicsActor shapeData.Restitution = _scene.Params.avatarRestitution; // do actual create at taint time - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.create", delegate() { BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); @@ -138,7 +138,7 @@ public class BSCharacter : PhysicsActor public void Destroy() { // DetailLog("{0},Destroy", LocalID); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.destroy", delegate() { BulletSimAPI.DestroyObject(_scene.WorldID, _localID); }); @@ -169,7 +169,7 @@ public class BSCharacter : PhysicsActor ComputeAvatarVolumeAndMass(); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.setSize", delegate() { BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true); }); @@ -207,7 +207,7 @@ public class BSCharacter : PhysicsActor _position = value; PositionSanityCheck(); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.setPosition", delegate() { DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); @@ -246,7 +246,7 @@ public class BSCharacter : PhysicsActor set { _force = value; // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); - Scene.TaintedObject(delegate() + Scene.TaintedObject("BSCharacter.SetForce", delegate() { DetailLog("{0},setForce,taint,force={1}", LocalID, _force); BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force); @@ -273,7 +273,7 @@ public class BSCharacter : PhysicsActor set { _velocity = value; // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.setVelocity", delegate() { DetailLog("{0},setVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); @@ -299,7 +299,7 @@ public class BSCharacter : PhysicsActor set { _orientation = value; // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.setOrientation", delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); @@ -366,7 +366,7 @@ public class BSCharacter : PhysicsActor public override float Buoyancy { get { return _buoyancy; } set { _buoyancy = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() { DetailLog("{0},setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); @@ -413,7 +413,7 @@ public class BSCharacter : PhysicsActor _force.Y += force.Y; _force.Z += force.Z; // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSCharacter.AddForce", delegate() { DetailLog("{0},setAddForce,taint,addedForce={1}", LocalID, _force); BulletSimAPI.AddObjectForce2(Body.Ptr, _force); @@ -439,7 +439,7 @@ public class BSCharacter : PhysicsActor // make sure first collision happens _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; - Scene.TaintedObject(delegate() + Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate() { BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); @@ -449,7 +449,7 @@ public class BSCharacter : PhysicsActor public override void UnSubscribeEvents() { _subscribedEventsMs = 0; // Avatars get all their collision events - // Scene.TaintedObject(delegate() + // Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() // { // BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); // }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index e265d6dcc8..bf262c5316 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -236,7 +236,7 @@ public class BSLinkset { m_children.Add(child); - m_scene.TaintedObject(delegate() + m_scene.TaintedObject("AddChildToLinkset", delegate() { DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); @@ -265,7 +265,7 @@ public class BSLinkset if (m_children.Remove(child)) { - m_scene.TaintedObject(delegate() + m_scene.TaintedObject("RemoveChildFromLinkset", delegate() { DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e0f6ed22c3..988e03b9b6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -145,7 +145,7 @@ public sealed class BSPrim : PhysicsActor _vehicle = new BSDynamics(this); // add vehicleness _mass = CalculateMass(); // do the actual object creation at taint time - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.create", delegate() { RecreateGeomAndObject(); @@ -166,7 +166,7 @@ public sealed class BSPrim : PhysicsActor _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); _scene.RemoveVehiclePrim(this); // just to make sure - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.destroy", delegate() { // Undo any links between me and any other object _linkset = _linkset.RemoveMeFromLinkset(this); @@ -183,7 +183,7 @@ public sealed class BSPrim : PhysicsActor get { return _size; } set { _size = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setSize", delegate() { _mass = CalculateMass(); // changing size changes the mass BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); @@ -195,7 +195,7 @@ public sealed class BSPrim : PhysicsActor public override PrimitiveBaseShape Shape { set { _pbs = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setShape", delegate() { _mass = CalculateMass(); // changing the shape changes the mass RecreateGeomAndObject(); @@ -213,7 +213,7 @@ public sealed class BSPrim : PhysicsActor public override bool Selected { set { _isSelected = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setSelected", delegate() { SetObjectDynamic(); }); @@ -281,7 +281,7 @@ public sealed class BSPrim : PhysicsActor set { _position = value; // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); @@ -318,7 +318,7 @@ public sealed class BSPrim : PhysicsActor get { return _force; } set { _force = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setForce", delegate() { DetailLog("{0},setForce,taint,force={1}", LocalID, _force); // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); @@ -333,7 +333,7 @@ public sealed class BSPrim : PhysicsActor } set { Vehicle type = (Vehicle)value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setVehicleType", delegate() { DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type); _vehicle.ProcessTypeChange(type); @@ -343,12 +343,7 @@ public sealed class BSPrim : PhysicsActor } else { - _scene.TaintedObject(delegate() - { - // Tell the physics engine to clear state - BulletSimAPI.ClearForces2(this.Body.Ptr); - }); - + BulletSimAPI.ClearForces2(this.Body.Ptr); // make it so the scene will call us each tick to do vehicle things _scene.AddVehiclePrim(this); } @@ -358,28 +353,28 @@ public sealed class BSPrim : PhysicsActor } public override void VehicleFloatParam(int param, float value) { - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.VehicleFloatParam", delegate() { _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); }); } public override void VehicleVectorParam(int param, OMV.Vector3 value) { - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.VehicleVectorParam", delegate() { _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); }); } public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.VehicleRotationParam", delegate() { _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); }); } public override void VehicleFlags(int param, bool remove) { - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.VehicleFlags", delegate() { _vehicle.ProcessVehicleFlags(param, remove); }); @@ -397,7 +392,7 @@ public sealed class BSPrim : PhysicsActor public override void SetVolumeDetect(int param) { bool newValue = (param != 0); _isVolumeDetect = newValue; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.SetVolumeDetect", delegate() { SetObjectDynamic(); }); @@ -408,7 +403,7 @@ public sealed class BSPrim : PhysicsActor get { return _velocity; } set { _velocity = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setVelocity", delegate() { DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); @@ -442,7 +437,7 @@ public sealed class BSPrim : PhysicsActor set { _orientation = value; // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setOrientation", delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); DetailLog("{0},setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); @@ -459,7 +454,7 @@ public sealed class BSPrim : PhysicsActor get { return _isPhysical; } set { _isPhysical = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setIsPhysical", delegate() { SetObjectDynamic(); }); @@ -547,7 +542,7 @@ public sealed class BSPrim : PhysicsActor set { _rotationalVelocity = value; // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); @@ -564,7 +559,7 @@ public sealed class BSPrim : PhysicsActor get { return _buoyancy; } set { _buoyancy = value; - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.setBuoyancy", delegate() { DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); @@ -618,7 +613,7 @@ public sealed class BSPrim : PhysicsActor m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); return; } - _scene.TaintedObject(delegate() + _scene.TaintedObject("BSPrim.AddForce", delegate() { OMV.Vector3 fSum = OMV.Vector3.Zero; lock (m_accumulatedForces) @@ -648,7 +643,7 @@ public sealed class BSPrim : PhysicsActor // make sure first collision happens _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; - Scene.TaintedObject(delegate() + Scene.TaintedObject("BSPrim.SubscribeEvents", delegate() { BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); @@ -656,7 +651,7 @@ public sealed class BSPrim : PhysicsActor } public override void UnSubscribeEvents() { _subscribedEventsMs = 0; - Scene.TaintedObject(delegate() + Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate() { BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 117086ad4b..65a8014490 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -162,7 +162,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters } public delegate void TaintCallback(); - private List _taintedObjects; + private struct TaintCallbackEntry + { + public String ident; + public TaintCallback callback; + public TaintCallbackEntry(string i, TaintCallback c) + { + ident = i; + callback = c; + } + } + private List _taintedObjects; private Object _taintLock = new Object(); // A pointer to an instance if this structure is passed to the C++ code @@ -232,7 +242,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); } - _taintedObjects = new List(); + _taintedObjects = new List(); mesher = meshmerizer; // The bounding box for the simulated world @@ -535,7 +545,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters public override void SetTerrain(float[] heightMap) { m_heightMap = heightMap; - this.TaintedObject(delegate() + this.TaintedObject("BSScene.SetTerrain", delegate() { BulletSimAPI.SetHeightmap(m_worldID, m_heightMap); }); @@ -727,12 +737,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters // Calls to the PhysicsActors can't directly call into the physics engine // because it might be busy. We delay changes to a known time. // We rely on C#'s closure to save and restore the context for the delegate. - public void TaintedObject(TaintCallback callback) + public void TaintedObject(String ident, TaintCallback callback) { if (!m_initialized) return; lock (_taintLock) - _taintedObjects.Add(callback); + _taintedObjects.Add(new TaintCallbackEntry(ident, callback)); return; } @@ -744,22 +754,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process { // swizzle a new list into the list location so we can process what's there - List oldList; + List oldList; lock (_taintLock) { oldList = _taintedObjects; - _taintedObjects = new List(); + _taintedObjects = new List(); } - foreach (TaintCallback callback in oldList) + foreach (TaintCallbackEntry tcbe in oldList) { try { - callback(); + tcbe.callback(); } catch (Exception e) { - m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e); + m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e); } } oldList.Clear(); @@ -1248,7 +1258,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters List objectIDs = lIDs; string xparm = parm.ToLower(); float xval = val; - TaintedObject(delegate() { + TaintedObject("BSScene.UpdateParameterSet", delegate() { foreach (uint lID in objectIDs) { BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); @@ -1268,7 +1278,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters uint xlocalID = localID; string xparm = parm.ToLower(); float xval = val; - TaintedObject(delegate() { + TaintedObject("BSScene.TaintedUpdateParameter", delegate() { BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); }); } From 3ca770cd2c7705d53efe11bb2a2315392b1f492a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 10 Aug 2012 08:33:09 -0700 Subject: [PATCH 4/5] BulletSim: Add module names to DetailLog output. Fix some problems with linksets that were caused by checking data structures that are changed regularly from taint time code -- resulted in linksets not being unlinked properly. --- .../Physics/BulletSPlugin/BSCharacter.cs | 8 ++- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 57 ++++++++------- .../Region/Physics/BulletSPlugin/BSPrim.cs | 69 ++++++++++--------- 3 files changed, 71 insertions(+), 63 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d49a578561..4f48cfb529 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -248,7 +248,7 @@ public class BSCharacter : PhysicsActor // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); Scene.TaintedObject("BSCharacter.SetForce", delegate() { - DetailLog("{0},setForce,taint,force={1}", LocalID, _force); + DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force); }); } @@ -275,7 +275,7 @@ public class BSCharacter : PhysicsActor // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); _scene.TaintedObject("BSCharacter.setVelocity", delegate() { - DetailLog("{0},setVelocity,taint,vel={1}", LocalID, _velocity); + DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); }); } @@ -487,6 +487,10 @@ public class BSCharacter : PhysicsActor _rotationalVelocity = entprop.RotationalVelocity; // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); + + DetailLog("{0},BSCharacter.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, + entprop.Acceleration, entprop.RotationalVelocity); } // Called by the scene when a collision with this object is reported diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index bf262c5316..f68e06eb69 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -40,9 +40,12 @@ public class BSLinkset public BSPrim Root { get { return m_linksetRoot; } } private BSScene m_scene; + public BSScene Scene { get { return m_scene; } } private List m_children; + public int NumberOfChildren { get { return m_children.Count; } } + // We lock the diddling of linkset classes to prevent any badness. // This locks the modification of the instances of this class. Changes // to the physical representation is done via the tainting mechenism. @@ -113,9 +116,10 @@ public class BSLinkset } // The child is down to a linkset of just itself - return new BSLinkset(m_scene, child); + return new BSLinkset(Scene, child); } + /* DEPRECATED: this is really bad in that it trys to unlink other prims. // An existing linkset had one of its members rebuilt or something. // Go through the linkset and rebuild the pointers to the bodies of the linkset members. public BSLinkset RefreshLinkset(BSPrim requestor) @@ -163,6 +167,7 @@ public class BSLinkset return ret; } + */ // Return 'true' if the passed object is the root object of this linkset @@ -229,18 +234,19 @@ public class BSLinkset } // I am the root of a linkset and a new child is being added - public void AddChildToLinkset(BSPrim pchild) + // Called while LinkActivity is locked. + public void AddChildToLinkset(BSPrim child) { - BSPrim child = pchild; if (!HasChild(child)) { m_children.Add(child); + BSPrim root = Root; // capture the root as of now m_scene.TaintedObject("AddChildToLinkset", delegate() { DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); - DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); - PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child + DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); + PhysicallyLinkAChildToRoot(root, child); // build the physical binding between me and the child }); } return; @@ -259,26 +265,17 @@ public class BSLinkset // I am the root of a linkset and one of my children is being removed. // Safe to call even if the child is not really in my linkset. - public void RemoveChildFromLinkset(BSPrim pchild) + public void RemoveChildFromLinkset(BSPrim child) { - BSPrim child = pchild; - if (m_children.Remove(child)) { + BSPrim root = Root; // capture the root as of now m_scene.TaintedObject("RemoveChildFromLinkset", delegate() { DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); - DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, pchild.LocalID); + DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); - if (m_children.Count == 0) - { - // if the linkset is empty, make sure all linkages have been removed - PhysicallyUnlinkAllChildrenFromRoot(); - } - else - { - PhysicallyUnlinkAChildFromRoot(pchild); - } + PhysicallyUnlinkAChildFromRoot(root, child); }); } else @@ -291,14 +288,14 @@ public class BSLinkset // Create a constraint between me (root of linkset) and the passed prim (the child). // Called at taint time! - private void PhysicallyLinkAChildToRoot(BSPrim childPrim) + private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(); // relative position normalized to the root prim - OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation); - OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation; + OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); + OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; // relative rotation of the child to the parent OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; @@ -306,9 +303,9 @@ public class BSLinkset // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); - DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); + DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( - m_scene.World, m_linksetRoot.Body, childPrim.Body, + m_scene.World, rootPrim.Body, childPrim.Body, childRelativePosition, childRelativeRotation, OMV.Vector3.Zero, @@ -331,25 +328,25 @@ public class BSLinkset // Remove linkage between myself and a particular child // Called at taint time! - private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim) + private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) { // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", - // LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); - DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); + // LogHeader, rootPrim.LocalID, childPrim.LocalID); + DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); - m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body); + m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); // Make the child refresh its location BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); } // Remove linkage between myself and any possible children I might have // Called at taint time! - private void PhysicallyUnlinkAllChildrenFromRoot() + private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) { // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); - DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID); + DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); - m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body); + m_scene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); } // Invoke the detailed logger and output something if it's enabled. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 988e03b9b6..4193d22b5b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -160,16 +160,18 @@ public sealed class BSPrim : PhysicsActor public void Destroy() { // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); - // DetailLog("{0},Destroy", LocalID); + // DetailLog("{0},BSPrim.Destroy", LocalID); // Undo any vehicle properties _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); _scene.RemoveVehiclePrim(this); // just to make sure + // Undo any links between me and any other object + _linkset = _linkset.RemoveMeFromLinkset(this); + _scene.TaintedObject("BSPrim.destroy", delegate() { - // Undo any links between me and any other object - _linkset = _linkset.RemoveMeFromLinkset(this); + DetailLog("{0},BSPrim.Destroy,taint,", LocalID); // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); @@ -187,7 +189,7 @@ public sealed class BSPrim : PhysicsActor { _mass = CalculateMass(); // changing size changes the mass BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); - // DetailLog("{0}: setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); + // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); RecreateGeomAndObject(); }); } @@ -227,7 +229,7 @@ public sealed class BSPrim : PhysicsActor if (parent != null) { DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); - DetailLog("{0},link,parent={1}", LocalID, parent.LocalID); + DetailLog("{0},BSPrim.link,parent={1}", LocalID, parent.LocalID); _linkset = _linkset.AddMeToLinkset(this, parent); } return; @@ -239,9 +241,14 @@ 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, _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString()); - DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString()); - _linkset.RemoveMeFromLinkset(this); + BSPrim parentBefore = _linkset.Root; + int childrenBefore = _linkset.NumberOfChildren; + + _linkset = _linkset.RemoveMeFromLinkset(this); + + DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", + LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); return; } @@ -264,7 +271,7 @@ public sealed class BSPrim : PhysicsActor public override void LockAngularMotion(OMV.Vector3 axis) { - DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis); + DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); return; } @@ -283,7 +290,7 @@ public sealed class BSPrim : PhysicsActor // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? _scene.TaintedObject("BSPrim.setPosition", delegate() { - DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); }); } @@ -320,7 +327,7 @@ public sealed class BSPrim : PhysicsActor _force = value; _scene.TaintedObject("BSPrim.setForce", delegate() { - DetailLog("{0},setForce,taint,force={1}", LocalID, _force); + DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); BulletSimAPI.SetObjectForce2(Body.Ptr, _force); }); @@ -335,7 +342,7 @@ public sealed class BSPrim : PhysicsActor Vehicle type = (Vehicle)value; _scene.TaintedObject("BSPrim.setVehicleType", delegate() { - DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type); + DetailLog("{0},BSPrim.SetVehicleType,taint,type={1}", LocalID, type); _vehicle.ProcessTypeChange(type); if (type == Vehicle.TYPE_NONE) { @@ -405,7 +412,7 @@ public sealed class BSPrim : PhysicsActor _velocity = value; _scene.TaintedObject("BSPrim.setVelocity", delegate() { - DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity); + DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); }); } @@ -413,7 +420,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); + DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); } } public override float CollisionScore { @@ -440,7 +447,7 @@ public sealed class BSPrim : PhysicsActor _scene.TaintedObject("BSPrim.setOrientation", delegate() { // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); - DetailLog("{0},setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); }); } @@ -486,7 +493,7 @@ public sealed class BSPrim : PhysicsActor // Bullet wants static objects to have a mass of zero float mass = IsStatic ? 0f : _mass; - DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); + DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); } @@ -544,7 +551,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { - DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); + DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); }); } @@ -561,7 +568,7 @@ public sealed class BSPrim : PhysicsActor _buoyancy = value; _scene.TaintedObject("BSPrim.setBuoyancy", delegate() { - DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); + DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); }); } @@ -624,17 +631,17 @@ public sealed class BSPrim : PhysicsActor } m_accumulatedForces.Clear(); } - DetailLog("{0},AddObjectForce,taint,force={1}", LocalID, _force); + DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); }); } public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { - DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); + DetailLog("{0},BSPrim.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); + DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); } public override void SubscribeEvents(int ms) { _subscribedEventsMs = ms; @@ -978,7 +985,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) { - DetailLog("{0},CreateGeom,sphere (force={1}", LocalID, forceRebuild); + DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; // Bullet native objects are scaled by the Bullet engine so pass the size in _scale = _size; @@ -992,7 +999,7 @@ public sealed class BSPrim : PhysicsActor // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) { - DetailLog("{0},CreateGeom,box (force={1})", LocalID, forceRebuild); + DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _scale = _size; // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? @@ -1035,12 +1042,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, newMeshKey); + DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); // 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); + DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; _meshKey = 0; @@ -1070,7 +1077,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); + DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); return; } @@ -1084,17 +1091,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); + DetailLog("{0},BSPrim.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); + DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); _hullKey = 0; _hulls.Clear(); - DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); + DetailLog("{0},BSPrim.CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); _mesh = null; // the mesh cannot match either _meshKey = 0; @@ -1191,7 +1198,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); + DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); return; } @@ -1329,7 +1336,7 @@ public sealed class BSPrim : PhysicsActor // 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}", + DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); base.RequestPhysicsterseUpdate(); @@ -1337,7 +1344,7 @@ public sealed class BSPrim : PhysicsActor else { // For debugging, we also report the movement of children - DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + DetailLog("{0},BSPrim.BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } From 0c7ce4fc98d4be185d5a5d83d4cc1c596b5cb1d3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 10 Aug 2012 16:22:44 -0700 Subject: [PATCH 5/5] BulletSim: many, many detailed logging messages for physical linkset debugging. Linkset bugs fixed where accounting of children would get lost. Moved scene based vehicle tracking logic from prim to the scene. Added GetCollisionFlags2 method to BulletSimAPI. Updated DLLs and SOs. --- .../Physics/BulletSPlugin/BSCharacter.cs | 2 +- .../Physics/BulletSPlugin/BSConstraint.cs | 4 +- .../BulletSPlugin/BSConstraintCollection.cs | 8 ++- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 14 ++--- .../Region/Physics/BulletSPlugin/BSPrim.cs | 58 ++++++++++--------- .../Region/Physics/BulletSPlugin/BSScene.cs | 27 +++++++-- .../Physics/BulletSPlugin/BulletSimAPI.cs | 9 ++- 7 files changed, 78 insertions(+), 44 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 4f48cfb529..f164afeeff 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -488,7 +488,7 @@ public class BSCharacter : PhysicsActor // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); - DetailLog("{0},BSCharacter.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index a17efea8ea..da26b721ec 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -49,7 +49,9 @@ public abstract class BSConstraint : IDisposable if (m_enabled) { // BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID); - BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); + bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); + m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); + m_constraint.Ptr = System.IntPtr.Zero; m_enabled = false; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs index 397045a437..3df2ddc007 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -68,6 +68,8 @@ public class BSConstraintCollection : IDisposable // There is only one constraint between any bodies. Remove any old just to make sure. RemoveAndDestroyConstraint(cons.Body1, cons.Body2); + m_world.scene.DetailLog("{0},BSConstraintCollection.AddConstraint,call,body1={1},body2={2}", BSScene.DetailLogZero, cons.Body1.ID, cons.Body2.ID); + m_constraints.Add(cons); return true; @@ -108,6 +110,7 @@ public class BSConstraintCollection : IDisposable if (this.TryGetConstraint(body1, body2, out constrain)) { + m_world.scene.DetailLog("{0},BSConstraintCollection.RemoveAndDestroyConstraint,taint,body1={1},body2={2}", BSScene.DetailLogZero, body1.ID, body2.ID); // remove the constraint from our collection m_constraints.Remove(constrain); // tell the engine that all its structures need to be freed @@ -148,10 +151,11 @@ public class BSConstraintCollection : IDisposable public bool RecalculateAllConstraints() { - foreach (BSConstraint constrain in m_constraints) + ForEachConstraint(delegate(BSConstraint constrain) { constrain.CalculateTransforms(); - } + return false; + }); return true; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index f68e06eb69..4a71612f1a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -44,8 +44,6 @@ public class BSLinkset private List m_children; - public int NumberOfChildren { get { return m_children.Count; } } - // We lock the diddling of linkset classes to prevent any badness. // This locks the modification of the instances of this class. Changes // to the physical representation is done via the tainting mechenism. @@ -83,14 +81,14 @@ public class BSLinkset // Link to a linkset where the child knows the parent. // Parent changing should not happen so do some sanity checking. - // We return the parent's linkset so the child can track it's membership. - public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent) + // We return the parent's linkset so the child can track its membership. + public BSLinkset AddMeToLinkset(BSPrim child) { lock (m_linksetActivityLock) { - parent.Linkset.AddChildToLinkset(child); + AddChildToLinkset(child); } - return parent.Linkset; + return this; } public BSLinkset RemoveMeFromLinkset(BSPrim child) @@ -176,6 +174,8 @@ public class BSLinkset return (requestor.LocalID == m_linksetRoot.LocalID); } + public int NumberOfChildren { get { return m_children.Count; } } + // Return 'true' if this linkset has any children (more than the root member) public bool HasAnyChildren { get { return (m_children.Count > 0); } } @@ -303,7 +303,7 @@ public class BSLinkset // create a constraint that allows no freedom of movement between the two objects // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); - DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); + DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); BS6DofConstraint constrain = new BS6DofConstraint( m_scene.World, rootPrim.Body, childPrim.Body, childRelativePosition, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 4193d22b5b..05cc8227a3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -138,13 +138,14 @@ public sealed class BSPrim : PhysicsActor _isPhysical = pisPhysical; _isVolumeDetect = false; _subscribedEventsMs = 0; - _friction = _scene.Params.defaultFriction; // TODO: compute based on object material - _density = _scene.Params.defaultDensity; // TODO: compute based on object material + _friction = _scene.Params.defaultFriction; // TODO: compute based on object material + _density = _scene.Params.defaultDensity; // TODO: compute based on object material _restitution = _scene.Params.defaultRestitution; _linkset = new BSLinkset(_scene, this); // a linkset of one - _vehicle = new BSDynamics(this); // add vehicleness + _vehicle = new BSDynamics(this); // add vehicleness _mass = CalculateMass(); // do the actual object creation at taint time + DetailLog("{0},BSPrim.constructor,call", LocalID); _scene.TaintedObject("BSPrim.create", delegate() { RecreateGeomAndObject(); @@ -160,19 +161,22 @@ public sealed class BSPrim : PhysicsActor public void Destroy() { // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); - // DetailLog("{0},BSPrim.Destroy", LocalID); - - // Undo any vehicle properties - _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); - _scene.RemoveVehiclePrim(this); // just to make sure // Undo any links between me and any other object + BSPrim parentBefore = _linkset.Root; + int childrenBefore = _linkset.NumberOfChildren; + _linkset = _linkset.RemoveMeFromLinkset(this); + DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", + LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); + + // Undo any vehicle properties + this.VehicleType = (int)Vehicle.TYPE_NONE; + _scene.TaintedObject("BSPrim.destroy", delegate() { DetailLog("{0},BSPrim.Destroy,taint,", LocalID); - // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); }); @@ -229,8 +233,13 @@ public sealed class BSPrim : PhysicsActor if (parent != null) { DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); - DetailLog("{0},BSPrim.link,parent={1}", LocalID, parent.LocalID); - _linkset = _linkset.AddMeToLinkset(this, parent); + BSPrim parentBefore = _linkset.Root; + int childrenBefore = _linkset.NumberOfChildren; + + _linkset = parent.Linkset.AddMeToLinkset(this); + + DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", + LocalID, parentBefore.LocalID, childrenBefore, _linkset.Root.LocalID, _linkset.NumberOfChildren); } return; } @@ -340,21 +349,14 @@ public sealed class BSPrim : PhysicsActor } set { Vehicle type = (Vehicle)value; - _scene.TaintedObject("BSPrim.setVehicleType", delegate() + BSPrim vehiclePrim = this; + _scene.TaintedObject("setVehicleType", delegate() { - DetailLog("{0},BSPrim.SetVehicleType,taint,type={1}", LocalID, type); + // Done at taint time so we're sure the physics engine is not using the variables + // Vehicle code changes the parameters for this vehicle type. _vehicle.ProcessTypeChange(type); - if (type == Vehicle.TYPE_NONE) - { - _scene.RemoveVehiclePrim(this); - } - else - { - BulletSimAPI.ClearForces2(this.Body.Ptr); - // make it so the scene will call us each tick to do vehicle things - _scene.AddVehiclePrim(this); - } - return; + // Tell the scene about the vehicle so it will get processing each frame. + _scene.VehicleInSceneTypeChanged(this, type); }); } } @@ -493,8 +495,10 @@ public sealed class BSPrim : PhysicsActor // Bullet wants static objects to have a mass of zero float mass = IsStatic ? 0f : _mass; - DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); + + CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); + DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); } // prims don't fly @@ -1224,7 +1228,7 @@ public sealed class BSPrim : PhysicsActor bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); // the CreateObject() may have recreated the rigid body. Make sure we have the latest. - m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID); + Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); return ret; } @@ -1344,7 +1348,7 @@ public sealed class BSPrim : PhysicsActor else { // For debugging, we also report the movement of children - DetailLog("{0},BSPrim.BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 65a8014490..beaea1f32c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -255,7 +255,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters // 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, BulletSimAPI.GetSimHandle2(m_worldID)); + m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID)); m_constraintCollection = new BSConstraintCollection(World); m_initialized = true; @@ -362,6 +362,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters BSPrim bsprim = prim as BSPrim; if (bsprim != null) { + DetailLog("{0},RemovePrim,call", bsprim.LocalID); // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); try { @@ -387,6 +388,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters if (!m_initialized) return null; + 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); return prim; @@ -426,12 +429,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters { numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); - DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount); + DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, 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}", "0000000000", numSubSteps, updatedEntityCount, collidersCount); + DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); // updatedEntityCount = 0; collidersCount = 0; } @@ -777,6 +780,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters } #region Vehicles + + public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType) + { + if (newType == Vehicle.TYPE_NONE) + { + RemoveVehiclePrim(vehic); + } + else + { + // make it so the scene will call us each tick to do vehicle things + AddVehiclePrim(vehic); + } + } + // Make so the scene will call this prim for vehicle actions each tick. // Safe to call if prim is already in the vehicle list. public void AddVehiclePrim(BSPrim vehicle) @@ -1304,10 +1321,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters #endregion Runtime settable parameters // Invoke the detailed logger and output something if it's enabled. - private void DetailLog(string msg, params Object[] args) + public void DetailLog(string msg, params Object[] args) { PhysicsLogging.Write(msg, args); } + // used to fill in the LocalID when there isn't one + public const string DetailLogZero = "0000000000"; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index c016402057..6800b96977 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -35,9 +35,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Classes to allow some type checking for the API public struct BulletSim { - public BulletSim(uint id, IntPtr xx) { ID = id; Ptr = xx; } - public IntPtr Ptr; + public BulletSim(uint id, BSScene bss, IntPtr xx) { ID = id; scene = bss; Ptr = xx; } public uint ID; + // The scene is only in here so very low level routines have a handle to print debug/error messages + public BSScene scene; + public IntPtr Ptr; } public struct BulletBody @@ -491,6 +493,9 @@ public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); + [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr SetCollisionFlags2(IntPtr obj, CollisionFlags flags);