BulletSim: Add physical 'actors' that operate on the physical object.
Add first 'actor' for locked axis.user_profiles
parent
9b83e53b28
commit
2c581cae2a
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyrightD
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorLockAxis : BSActor
|
||||
{
|
||||
bool TryExperimentalLockAxisCode = false;
|
||||
BSConstraint LockAxisConstraint = null;
|
||||
|
||||
public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj,actorName)
|
||||
{
|
||||
LockAxisConstraint = null;
|
||||
}
|
||||
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled && Prim.IsPhysicallyActive; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
// BSActor.Release()
|
||||
public override void Release()
|
||||
{
|
||||
RemoveAxisLockConstraint();
|
||||
}
|
||||
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
// Called at taint-time.
|
||||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
// If all the axis are free, we don't need to exist
|
||||
if (Prim.LockedAxis == Prim.LockedAxisFree)
|
||||
{
|
||||
Prim.PhysicalActors.RemoveAndRelease(ActorName);
|
||||
return;
|
||||
}
|
||||
// If the object is physically active, add the axis locking constraint
|
||||
if (Enabled
|
||||
&& Prim.IsPhysicallyActive
|
||||
&& TryExperimentalLockAxisCode
|
||||
&& Prim.LockedAxis != Prim.LockedAxisFree)
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
AddAxisLockConstraint();
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveAxisLockConstraint();
|
||||
}
|
||||
}
|
||||
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
// If a constraint is set up, remove it from the physical scene
|
||||
RemoveAxisLockConstraint();
|
||||
// Schedule a call before the next simulation step to restore the constraint.
|
||||
PhysicsScene.PostTaintObject(Prim.LockedAxisActorName, Prim.LocalID, delegate()
|
||||
{
|
||||
Refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAxisLockConstraint()
|
||||
{
|
||||
// Lock that axis by creating a 6DOF constraint that has one end in the world and
|
||||
// the other in the object.
|
||||
// http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
|
||||
// http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
|
||||
|
||||
// Remove any existing axis constraint (just to be sure)
|
||||
RemoveAxisLockConstraint();
|
||||
|
||||
BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, Prim.PhysBody,
|
||||
OMV.Vector3.Zero, OMV.Quaternion.Inverse(Prim.RawOrientation),
|
||||
true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
|
||||
LockAxisConstraint = axisConstrainer;
|
||||
PhysicsScene.Constraints.AddConstraint(LockAxisConstraint);
|
||||
|
||||
// The constraint is tied to the world and oriented to the prim.
|
||||
|
||||
// Free to move linearly
|
||||
OMV.Vector3 linearLow = OMV.Vector3.Zero;
|
||||
OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize;
|
||||
axisConstrainer.SetLinearLimits(linearLow, linearHigh);
|
||||
|
||||
// Angular with some axis locked
|
||||
float f2PI = (float)Math.PI * 2f;
|
||||
OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI);
|
||||
OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI);
|
||||
if (Prim.LockedAxis.X != 1f)
|
||||
{
|
||||
angularLow.X = 0f;
|
||||
angularHigh.X = 0f;
|
||||
}
|
||||
if (Prim.LockedAxis.Y != 1f)
|
||||
{
|
||||
angularLow.Y = 0f;
|
||||
angularHigh.Y = 0f;
|
||||
}
|
||||
if (Prim.LockedAxis.Z != 1f)
|
||||
{
|
||||
angularLow.Z = 0f;
|
||||
angularHigh.Z = 0f;
|
||||
}
|
||||
axisConstrainer.SetAngularLimits(angularLow, angularHigh);
|
||||
|
||||
PhysicsScene.DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}",
|
||||
Prim.LocalID, linearLow, linearHigh, angularLow, angularHigh);
|
||||
|
||||
// Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
|
||||
axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
|
||||
|
||||
axisConstrainer.RecomputeConstraintVariables(Prim.RawMass);
|
||||
}
|
||||
|
||||
private void RemoveAxisLockConstraint()
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
PhysicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
|
||||
LockAxisConstraint = null;
|
||||
PhysicsScene.DetailLog("{0},BSPrim.CleanUpLockAxisPhysicals,destroyingConstraint", Prim.LocalID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorCollection
|
||||
{
|
||||
private BSScene PhysicsScene { get; set; }
|
||||
private Dictionary<string, BSActor> m_actors;
|
||||
|
||||
public BSActorCollection(BSScene physicsScene)
|
||||
{
|
||||
PhysicsScene = physicsScene;
|
||||
m_actors = new Dictionary<string, BSActor>();
|
||||
}
|
||||
public void Add(string name, BSActor actor)
|
||||
{
|
||||
m_actors[name] = actor;
|
||||
}
|
||||
public bool RemoveAndRelease(string name)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_actors.ContainsKey(name))
|
||||
{
|
||||
BSActor beingRemoved = m_actors[name];
|
||||
beingRemoved.Release();
|
||||
m_actors.Remove(name);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
Release();
|
||||
m_actors.Clear();
|
||||
}
|
||||
public bool HasActor(string name)
|
||||
{
|
||||
return m_actors.ContainsKey(name);
|
||||
}
|
||||
public void ForEachActor(Action<BSActor> act)
|
||||
{
|
||||
foreach (KeyValuePair<string, BSActor> kvp in m_actors)
|
||||
act(kvp.Value);
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
ForEachActor(a => a.Release());
|
||||
}
|
||||
public void Refresh()
|
||||
{
|
||||
ForEachActor(a => a.Refresh());
|
||||
}
|
||||
public void RemoveBodyDependencies()
|
||||
{
|
||||
ForEachActor(a => a.RemoveBodyDependencies());
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
public abstract class BSActor
|
||||
{
|
||||
protected BSScene PhysicsScene { get; private set; }
|
||||
protected BSPhysObject Prim { get; private set; }
|
||||
protected bool Enabled { get; set; }
|
||||
public string ActorName { get; private set; }
|
||||
|
||||
public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
{
|
||||
PhysicsScene = physicsScene;
|
||||
Prim = pObj;
|
||||
ActorName = actorName;
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
// Return 'true' if activily updating the prim
|
||||
public virtual bool isActive
|
||||
{
|
||||
get { return Enabled; }
|
||||
}
|
||||
// Turn the actor on an off.
|
||||
public virtual void Enable(bool setEnabled)
|
||||
{
|
||||
Enabled = setEnabled;
|
||||
}
|
||||
// Release any connections and resources used by the actor.
|
||||
public abstract void Release();
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
public abstract void Refresh();
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
public abstract void RemoveBodyDependencies();
|
||||
|
||||
}
|
||||
}
|
|
@ -78,6 +78,9 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
|
||||
TypeName = typeName;
|
||||
|
||||
// The collection of things that push me around
|
||||
PhysicalActors = new BSActorCollection(PhysicsScene);
|
||||
|
||||
// Initialize variables kept in base.
|
||||
GravModifier = 1.0f;
|
||||
Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
|
||||
|
@ -109,6 +112,10 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
{
|
||||
UnRegisterAllPreStepActions();
|
||||
UnRegisterAllPostStepActions();
|
||||
PhysicsScene.TaintedObject("BSPhysObject.Destroy", delegate()
|
||||
{
|
||||
PhysicalActors.Release();
|
||||
});
|
||||
}
|
||||
|
||||
public BSScene PhysicsScene { get; protected set; }
|
||||
|
@ -230,6 +237,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
|
||||
public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free
|
||||
public readonly String LockedAxisActorName = "BSPrim.LockedAxis";
|
||||
|
||||
#region Collisions
|
||||
|
||||
|
@ -413,6 +421,9 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
#endregion // Collisions
|
||||
|
||||
#region Per Simulation Step actions
|
||||
|
||||
public BSActorCollection PhysicalActors;
|
||||
|
||||
// There are some actions that must be performed for a physical object before each simulation step.
|
||||
// These actions are optional so, rather than scanning all the physical objects and asking them
|
||||
// if they have anything to do, a physical object registers for an event call before the step is performed.
|
||||
|
|
|
@ -126,7 +126,7 @@ public class BSPrim : BSPhysObject
|
|||
// Undo any vehicle properties
|
||||
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||
|
||||
PhysicsScene.TaintedObject("BSPrim.destroy", delegate()
|
||||
PhysicsScene.TaintedObject("BSPrim.Destroy", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||
// If there are physical body and shape, release my use of same.
|
||||
|
@ -257,98 +257,31 @@ public class BSPrim : BSPhysObject
|
|||
});
|
||||
}
|
||||
|
||||
bool TryExperimentalLockAxisCode = false;
|
||||
BSConstraint LockAxisConstraint = null;
|
||||
public override void LockAngularMotion(OMV.Vector3 axis)
|
||||
{
|
||||
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
|
||||
|
||||
// "1" means free, "0" means locked
|
||||
OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f);
|
||||
OMV.Vector3 locking = LockedAxisFree;
|
||||
if (axis.X != 1) locking.X = 0f;
|
||||
if (axis.Y != 1) locking.Y = 0f;
|
||||
if (axis.Z != 1) locking.Z = 0f;
|
||||
LockedAxis = locking;
|
||||
|
||||
if (TryExperimentalLockAxisCode && LockedAxis != LockedAxisFree)
|
||||
if (LockedAxis != LockedAxisFree)
|
||||
{
|
||||
// Lock that axis by creating a 6DOF constraint that has one end in the world and
|
||||
// the other in the object.
|
||||
// http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
|
||||
// http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
|
||||
|
||||
PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
|
||||
{
|
||||
CleanUpLockAxisPhysicals(true /* inTaintTime */);
|
||||
|
||||
BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, PhysBody,
|
||||
OMV.Vector3.Zero, OMV.Quaternion.Inverse(RawOrientation),
|
||||
true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
|
||||
LockAxisConstraint = axisConstrainer;
|
||||
PhysicsScene.Constraints.AddConstraint(LockAxisConstraint);
|
||||
|
||||
// The constraint is tied to the world and oriented to the prim.
|
||||
|
||||
// Free to move linearly
|
||||
OMV.Vector3 linearLow = OMV.Vector3.Zero;
|
||||
OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize;
|
||||
axisConstrainer.SetLinearLimits(linearLow, linearHigh);
|
||||
|
||||
// Angular with some axis locked
|
||||
float f2PI = (float)Math.PI * 2f;
|
||||
OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI);
|
||||
OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI);
|
||||
if (LockedAxis.X != 1f)
|
||||
// If there is not already an axis locker, make one
|
||||
if (!PhysicalActors.HasActor(LockedAxisActorName))
|
||||
{
|
||||
angularLow.X = 0f;
|
||||
angularHigh.X = 0f;
|
||||
PhysicalActors.Add(LockedAxisActorName, new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName));
|
||||
}
|
||||
if (LockedAxis.Y != 1f)
|
||||
{
|
||||
angularLow.Y = 0f;
|
||||
angularHigh.Y = 0f;
|
||||
}
|
||||
if (LockedAxis.Z != 1f)
|
||||
{
|
||||
angularLow.Z = 0f;
|
||||
angularHigh.Z = 0f;
|
||||
}
|
||||
axisConstrainer.SetAngularLimits(angularLow, angularHigh);
|
||||
|
||||
DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}",
|
||||
LocalID, linearLow, linearHigh, angularLow, angularHigh);
|
||||
|
||||
// Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
|
||||
axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
|
||||
|
||||
axisConstrainer.RecomputeConstraintVariables(RawMass);
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything seems unlocked
|
||||
CleanUpLockAxisPhysicals(false /* inTaintTime */);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// Get rid of any constraint built for LockAxis
|
||||
// Most often the constraint is removed when the constraint collection is cleaned for this prim.
|
||||
private void CleanUpLockAxisPhysicals(bool inTaintTime)
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CleanUpLockAxisPhysicals", delegate()
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
PhysicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
|
||||
LockAxisConstraint = null;
|
||||
DetailLog("{0},BSPrim.CleanUpLockAxisPhysicals,destroyingConstraint", LocalID);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override OMV.Vector3 RawPosition
|
||||
{
|
||||
|
@ -916,6 +849,7 @@ public class BSPrim : BSPhysObject
|
|||
|
||||
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
||||
VehicleController.Refresh();
|
||||
PhysicalActors.Refresh();
|
||||
|
||||
// Arrange for collision events if the simulator wants them
|
||||
EnableCollisions(SubscribedEvents());
|
||||
|
@ -1753,6 +1687,7 @@ public class BSPrim : BSPhysObject
|
|||
protected virtual void RemoveBodyDependencies()
|
||||
{
|
||||
VehicleController.RemoveBodyDependencies(this);
|
||||
PhysicalActors.RemoveBodyDependencies();
|
||||
}
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
|
|
Loading…
Reference in New Issue