From 2d05e16f7e934fc7a986696605950dd9a618d044 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 25 Jul 2012 10:34:51 -0700 Subject: [PATCH] BulletSim: Add C# classes for storing and tracking constraints. --- .../Physics/BulletSPlugin/BSConstraint.cs | 123 ++++++++++++ .../BulletSPlugin/BSConstraintCollection.cs | 178 ++++++++++++++++++ 2 files changed, 301 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs new file mode 100755 index 0000000000..ced8565436 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -0,0 +1,123 @@ +/* + * 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 BSConstraint : IDisposable +{ + private BulletSim m_world; + private BulletBody m_body1; + private BulletBody m_body2; + private BulletConstraint m_constraint; + private bool m_enabled = false; + + public BSConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 frame1, Quaternion frame1rot, + Vector3 frame2, Quaternion frame2rot + ) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + /* + BulletSimAPI.AddConstraint(world.ID, m_body1.ID, m_body2.ID, + frame1, frame1rot, + frame2, frame2rot, + linearLow, linearHigh, + angularLow, angularHigh + ); + */ + m_constraint = new BulletConstraint(BulletSimAPI.CreateConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, + frame1, frame1rot, + frame2, frame2rot)); + m_enabled = true; + } + + public void Dispose() + { + if (m_enabled) + { + // BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID); + BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); + m_enabled = false; + } + } + + public BulletBody Body1 { get { return m_body1; } } + public BulletBody Body2 { get { return m_body2; } } + + public bool SetLinearLimits(Vector3 low, Vector3 high) + { + bool ret = false; + if (m_enabled) + ret = BulletSimAPI.SetLinearLimits2(m_constraint.Ptr, low, high); + return ret; + } + + public bool SetAngularLimits(Vector3 low, Vector3 high) + { + bool ret = false; + if (m_enabled) + ret = BulletSimAPI.SetAngularLimits2(m_constraint.Ptr, low, high); + 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() + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.CalculateTransforms2(m_constraint.Ptr); + ret = true; + } + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs new file mode 100755 index 0000000000..6c66c5c9d0 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -0,0 +1,178 @@ +/* + * 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 log4net; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public class BSConstraintCollection : IDisposable +{ + // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + // private static readonly string LogHeader = "[CONSTRAINT COLLECTION]"; + + delegate bool ConstraintAction(BSConstraint constrain); + + private List m_constraints; + private BulletSim m_world; + + public BSConstraintCollection(BulletSim world) + { + m_world = world; + m_constraints = new List(); + } + + public void Dispose() + { + this.Clear(); + } + + public void Clear() + { + foreach (BSConstraint cons in m_constraints) + { + cons.Dispose(); + } + 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. + RemoveAndDestroyConstraint(cons.Body1, cons.Body2); + + m_constraints.Add(cons); + + return true; + } + + // Get the constraint between two bodies. There can be only one the way we're using them. + public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint) + { + bool found = false; + BSConstraint foundConstraint = null; + + uint lookingID1 = body1.ID; + uint lookingID2 = body2.ID; + ForEachConstraint(delegate(BSConstraint constrain) + { + if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) + || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) + { + foundConstraint = constrain; + found = true; + } + return found; + }); + returnConstraint = foundConstraint; + return found; + } + + public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2) + { + // return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID); + + bool ret = false; + BSConstraint constrain; + + if (this.TryGetConstraint(body1, body2, out constrain)) + { + // remove the constraint from our collection + m_constraints.Remove(constrain); + // tell the engine that all its structures need to be freed + constrain.Dispose(); + // we destroyed something + ret = true; + } + + return ret; + } + + public bool RemoveAndDestroyConstraint(BulletBody body1) + { + // return BulletSimAPI.RemoveConstraintByID(m_world.ID, obj.ID); + + List toRemove = new List(); + uint lookingID = body1.ID; + ForEachConstraint(delegate(BSConstraint constrain) + { + if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) + { + toRemove.Add(constrain); + } + return false; + }); + lock (m_constraints) + { + foreach (BSConstraint constrain in toRemove) + { + m_constraints.Remove(constrain); + constrain.Dispose(); + } + } + return (toRemove.Count > 0); + } + + public bool RecalculateAllConstraints() + { + foreach (BSConstraint constrain in m_constraints) + { + constrain.CalculateTransforms(); + } + return true; + } + + // Lock the constraint list and loop through it. + // The constraint action returns 'true' if it wants the loop aborted. + private void ForEachConstraint(ConstraintAction action) + { + lock (m_constraints) + { + foreach (BSConstraint constrain in m_constraints) + { + if (action(constrain)) + break; + } + } + } + + +} +}