Merge commit '84eb25da23765b3a4f7ae5513e8a238680bb99f2'
commit
711441f922
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
|
||||||
|
LockAxisConstraint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BSActor.isActive
|
||||||
|
public override bool isActive
|
||||||
|
{
|
||||||
|
get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release any connections and resources used by the actor.
|
||||||
|
// BSActor.Dispose()
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
RemoveAxisLockConstraint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||||
|
// Called at taint-time.
|
||||||
|
// BSActor.Refresh()
|
||||||
|
public override void Refresh()
|
||||||
|
{
|
||||||
|
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}",
|
||||||
|
m_controllingPrim.LocalID, m_controllingPrim.LockedAxis, Enabled, m_controllingPrim.IsPhysicallyActive);
|
||||||
|
// If all the axis are free, we don't need to exist
|
||||||
|
if (m_controllingPrim.LockedAxis == m_controllingPrim.LockedAxisFree)
|
||||||
|
{
|
||||||
|
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,allAxisFree,removing={1}", m_controllingPrim.LocalID, ActorName);
|
||||||
|
m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If the object is physically active, add the axis locking constraint
|
||||||
|
if (Enabled
|
||||||
|
&& m_controllingPrim.IsPhysicallyActive
|
||||||
|
&& TryExperimentalLockAxisCode
|
||||||
|
&& m_controllingPrim.LockedAxis != m_controllingPrim.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.
|
||||||
|
m_physicsScene.PostTaintObject(m_controllingPrim.LockedAxisActorName, m_controllingPrim.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(m_physicsScene.World, m_controllingPrim.PhysBody,
|
||||||
|
// OMV.Vector3.Zero, OMV.Quaternion.Identity,
|
||||||
|
OMV.Vector3.Zero, OMV.Quaternion.Inverse(m_controllingPrim.RawOrientation),
|
||||||
|
// OMV.Vector3.Zero, m_controllingPrim.RawOrientation,
|
||||||
|
false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
|
||||||
|
LockAxisConstraint = axisConstrainer;
|
||||||
|
m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
|
||||||
|
|
||||||
|
// The constraint is tied to the world and oriented to the prim.
|
||||||
|
|
||||||
|
// Free to move linearly in the region
|
||||||
|
OMV.Vector3 linearLow = OMV.Vector3.Zero;
|
||||||
|
OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
|
||||||
|
axisConstrainer.SetLinearLimits(linearLow, linearHigh);
|
||||||
|
|
||||||
|
// Angular with some axis locked
|
||||||
|
float fPI = (float)Math.PI;
|
||||||
|
OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
|
||||||
|
OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
|
||||||
|
if (m_controllingPrim.LockedAxis.X != 1f)
|
||||||
|
{
|
||||||
|
angularLow.X = 0f;
|
||||||
|
angularHigh.X = 0f;
|
||||||
|
}
|
||||||
|
if (m_controllingPrim.LockedAxis.Y != 1f)
|
||||||
|
{
|
||||||
|
angularLow.Y = 0f;
|
||||||
|
angularHigh.Y = 0f;
|
||||||
|
}
|
||||||
|
if (m_controllingPrim.LockedAxis.Z != 1f)
|
||||||
|
{
|
||||||
|
angularLow.Z = 0f;
|
||||||
|
angularHigh.Z = 0f;
|
||||||
|
}
|
||||||
|
if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
|
||||||
|
{
|
||||||
|
m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
|
||||||
|
m_controllingPrim.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(m_controllingPrim.RawMass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveAxisLockConstraint()
|
||||||
|
{
|
||||||
|
if (LockAxisConstraint != null)
|
||||||
|
{
|
||||||
|
m_physicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
|
||||||
|
LockAxisConstraint = null;
|
||||||
|
m_physicsScene.DetailLog("{0},BSActorLockAxis.RemoveAxisLockConstraint,destroyingConstraint", m_controllingPrim.LocalID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* 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.Dispose();
|
||||||
|
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.Dispose());
|
||||||
|
}
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
ForEachActor(a => a.Refresh());
|
||||||
|
}
|
||||||
|
public void RemoveBodyDependencies()
|
||||||
|
{
|
||||||
|
ForEachActor(a => a.RemoveBodyDependencies());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
/// <summary>
|
||||||
|
/// Each physical object can have 'actors' who are pushing the object around.
|
||||||
|
/// This can be used for hover, locking axis, making vehicles, etc.
|
||||||
|
/// Each physical object can have multiple actors acting on it.
|
||||||
|
///
|
||||||
|
/// An actor usually registers itself with physics scene events (pre-step action)
|
||||||
|
/// and modifies the parameters on the host physical object.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BSActor
|
||||||
|
{
|
||||||
|
protected BSScene m_physicsScene { get; private set; }
|
||||||
|
protected BSPhysObject m_controllingPrim { get; private set; }
|
||||||
|
protected bool Enabled { get; set; }
|
||||||
|
public string ActorName { get; private set; }
|
||||||
|
|
||||||
|
public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||||
|
{
|
||||||
|
m_physicsScene = physicsScene;
|
||||||
|
m_controllingPrim = 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 Dispose();
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
private OMV.Vector3 _rotationalVelocity;
|
private OMV.Vector3 _rotationalVelocity;
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
private bool _isStationaryStanding; // true is standing on a stationary object
|
||||||
|
|
||||||
private BSVMotor _velocityMotor;
|
private BSVMotor _velocityMotor;
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||||
Friction = BSParam.AvatarStandingFriction;
|
Friction = BSParam.AvatarStandingFriction;
|
||||||
Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
|
Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
|
||||||
|
_isStationaryStanding = false;
|
||||||
|
|
||||||
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
||||||
// replace with the default values.
|
// replace with the default values.
|
||||||
|
@ -208,6 +210,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
// The code below uses whether the collider is static or moving to decide whether to zero motion.
|
// The code below uses whether the collider is static or moving to decide whether to zero motion.
|
||||||
|
|
||||||
_velocityMotor.Step(timeStep);
|
_velocityMotor.Step(timeStep);
|
||||||
|
_isStationaryStanding = false;
|
||||||
|
|
||||||
// If we're not supposed to be moving, make sure things are zero.
|
// If we're not supposed to be moving, make sure things are zero.
|
||||||
if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
|
if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
|
||||||
|
@ -221,6 +224,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
if (!ColliderIsMoving)
|
if (!ColliderIsMoving)
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
|
DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
|
||||||
|
_isStationaryStanding = true;
|
||||||
ZeroMotion(true /* inTaintTime */);
|
ZeroMotion(true /* inTaintTime */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,7 +886,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
// the world that things have changed.
|
// the world that things have changed.
|
||||||
public override void UpdateProperties(EntityProperties entprop)
|
public override void UpdateProperties(EntityProperties entprop)
|
||||||
{
|
{
|
||||||
|
// Don't change position if standing on a stationary object.
|
||||||
|
if (!_isStationaryStanding)
|
||||||
_position = entprop.Position;
|
_position = entprop.Position;
|
||||||
|
|
||||||
_orientation = entprop.Rotation;
|
_orientation = entprop.Rotation;
|
||||||
|
|
||||||
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
|
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
|
||||||
|
|
|
@ -85,7 +85,9 @@ public abstract class BSConstraint : IDisposable
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
|
{
|
||||||
ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
|
ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,14 +97,14 @@ public sealed class BSConstraint6Dof : BSConstraint
|
||||||
|
|
||||||
// A 6 Dof constraint that is fixed in the world and constrained to a on-the-fly created static object
|
// A 6 Dof constraint that is fixed in the world and constrained to a on-the-fly created static object
|
||||||
public BSConstraint6Dof(BulletWorld world, BulletBody obj1, Vector3 frameInBloc, Quaternion frameInBrot,
|
public BSConstraint6Dof(BulletWorld world, BulletBody obj1, Vector3 frameInBloc, Quaternion frameInBrot,
|
||||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
bool useLinearReferenceFrameB, bool disableCollisionsBetweenLinkedBodies)
|
||||||
: base(world)
|
: base(world)
|
||||||
{
|
{
|
||||||
m_body1 = obj1;
|
m_body1 = obj1;
|
||||||
m_body2 = obj1; // Look out for confusion down the road
|
m_body2 = obj1; // Look out for confusion down the road
|
||||||
m_constraint = PhysicsScene.PE.Create6DofConstraintFixed(m_world, m_body1,
|
m_constraint = PhysicsScene.PE.Create6DofConstraintFixed(m_world, m_body1,
|
||||||
frameInBloc, frameInBrot,
|
frameInBloc, frameInBrot,
|
||||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
|
useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
|
||||||
m_enabled = true;
|
m_enabled = true;
|
||||||
world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
|
world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
|
||||||
BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString);
|
BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString);
|
||||||
|
|
|
@ -40,13 +40,14 @@ using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
public sealed class BSDynamics
|
public sealed class BSDynamics : BSActor
|
||||||
{
|
{
|
||||||
private static string LogHeader = "[BULLETSIM VEHICLE]";
|
private static string LogHeader = "[BULLETSIM VEHICLE]";
|
||||||
|
|
||||||
private BSScene PhysicsScene { get; set; }
|
|
||||||
// the prim this dynamic controller belongs to
|
// the prim this dynamic controller belongs to
|
||||||
private BSPrim Prim { get; set; }
|
private BSPrim ControllingPrim { get; set; }
|
||||||
|
|
||||||
|
private bool m_haveRegisteredForSceneEvents;
|
||||||
|
|
||||||
// mass of the vehicle fetched each time we're calles
|
// mass of the vehicle fetched each time we're calles
|
||||||
private float m_vehicleMass;
|
private float m_vehicleMass;
|
||||||
|
@ -129,11 +130,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
public bool enableAngularDeflection;
|
public bool enableAngularDeflection;
|
||||||
public bool enableAngularBanking;
|
public bool enableAngularBanking;
|
||||||
|
|
||||||
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName)
|
||||||
|
: base(myScene, myPrim, actorName)
|
||||||
{
|
{
|
||||||
PhysicsScene = myScene;
|
ControllingPrim = myPrim;
|
||||||
Prim = myPrim;
|
|
||||||
Type = Vehicle.TYPE_NONE;
|
Type = Vehicle.TYPE_NONE;
|
||||||
|
m_haveRegisteredForSceneEvents = false;
|
||||||
SetupVehicleDebugging();
|
SetupVehicleDebugging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +157,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Return 'true' if this vehicle is doing vehicle things
|
// Return 'true' if this vehicle is doing vehicle things
|
||||||
public bool IsActive
|
public bool IsActive
|
||||||
{
|
{
|
||||||
get { return (Type != Vehicle.TYPE_NONE && Prim.IsPhysicallyActive); }
|
get { return (Type != Vehicle.TYPE_NONE && ControllingPrim.IsPhysicallyActive); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 'true' if this a vehicle that should be sitting on the ground
|
// Return 'true' if this a vehicle that should be sitting on the ground
|
||||||
|
@ -167,7 +169,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
#region Vehicle parameter setting
|
#region Vehicle parameter setting
|
||||||
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||||
{
|
{
|
||||||
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
|
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
|
||||||
switch (pParam)
|
switch (pParam)
|
||||||
{
|
{
|
||||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||||
|
@ -195,7 +197,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
break;
|
break;
|
||||||
case Vehicle.BUOYANCY:
|
case Vehicle.BUOYANCY:
|
||||||
m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
|
m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
|
||||||
m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
|
m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
|
||||||
break;
|
break;
|
||||||
case Vehicle.HOVER_EFFICIENCY:
|
case Vehicle.HOVER_EFFICIENCY:
|
||||||
m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
|
m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
|
||||||
|
@ -258,7 +260,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||||
{
|
{
|
||||||
VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
|
VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
|
||||||
switch (pParam)
|
switch (pParam)
|
||||||
{
|
{
|
||||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
@ -294,7 +296,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||||
{
|
{
|
||||||
VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
|
VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", ControllingPrim.LocalID, pParam, pValue);
|
||||||
switch (pParam)
|
switch (pParam)
|
||||||
{
|
{
|
||||||
case Vehicle.REFERENCE_FRAME:
|
case Vehicle.REFERENCE_FRAME:
|
||||||
|
@ -308,7 +310,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
internal void ProcessVehicleFlags(int pParam, bool remove)
|
internal void ProcessVehicleFlags(int pParam, bool remove)
|
||||||
{
|
{
|
||||||
VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove);
|
VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", ControllingPrim.LocalID, pParam, remove);
|
||||||
VehicleFlag parm = (VehicleFlag)pParam;
|
VehicleFlag parm = (VehicleFlag)pParam;
|
||||||
if (pParam == -1)
|
if (pParam == -1)
|
||||||
m_flags = (VehicleFlag)0;
|
m_flags = (VehicleFlag)0;
|
||||||
|
@ -323,7 +325,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
public void ProcessTypeChange(Vehicle pType)
|
public void ProcessTypeChange(Vehicle pType)
|
||||||
{
|
{
|
||||||
VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType);
|
VDetailLog("{0},ProcessTypeChange,type={1}", ControllingPrim.LocalID, pType);
|
||||||
// Set Defaults For Type
|
// Set Defaults For Type
|
||||||
Type = pType;
|
Type = pType;
|
||||||
switch (pType)
|
switch (pType)
|
||||||
|
@ -563,12 +565,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
||||||
m_linearMotorDecayTimescale, m_linearFrictionTimescale,
|
m_linearMotorDecayTimescale, m_linearFrictionTimescale,
|
||||||
1f);
|
1f);
|
||||||
m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
|
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
|
||||||
m_angularMotorDecayTimescale, m_angularFrictionTimescale,
|
m_angularMotorDecayTimescale, m_angularFrictionTimescale,
|
||||||
1f);
|
1f);
|
||||||
m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
|
|
||||||
/* Not implemented
|
/* Not implemented
|
||||||
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
|
||||||
|
@ -578,13 +580,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
||||||
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (this.Type == Vehicle.TYPE_NONE)
|
||||||
|
{
|
||||||
|
UnregisterForSceneEvents();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegisterForSceneEvents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion // Vehicle parameter setting
|
#endregion // Vehicle parameter setting
|
||||||
|
|
||||||
public void Refresh()
|
// BSActor.Refresh()
|
||||||
|
public override void Refresh()
|
||||||
{
|
{
|
||||||
// If asking for a refresh, reset the physical parameters before the next simulation step.
|
// If asking for a refresh, reset the physical parameters before the next simulation step.
|
||||||
PhysicsScene.PostTaintObject("BSDynamics.Refresh", Prim.LocalID, delegate()
|
m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
|
||||||
{
|
{
|
||||||
SetPhysicalParameters();
|
SetPhysicalParameters();
|
||||||
});
|
});
|
||||||
|
@ -597,49 +609,90 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if (IsActive)
|
if (IsActive)
|
||||||
{
|
{
|
||||||
// Remember the mass so we don't have to fetch it every step
|
// Remember the mass so we don't have to fetch it every step
|
||||||
m_vehicleMass = Prim.TotalMass;
|
m_vehicleMass = ControllingPrim.TotalMass;
|
||||||
|
|
||||||
// Friction affects are handled by this vehicle code
|
// Friction affects are handled by this vehicle code
|
||||||
PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
|
m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction);
|
||||||
PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution);
|
m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution);
|
||||||
|
|
||||||
// Moderate angular movement introduced by Bullet.
|
// Moderate angular movement introduced by Bullet.
|
||||||
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
|
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
|
||||||
// Maybe compute linear and angular factor and damping from params.
|
// Maybe compute linear and angular factor and damping from params.
|
||||||
PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping);
|
m_physicsScene.PE.SetAngularDamping(ControllingPrim.PhysBody, BSParam.VehicleAngularDamping);
|
||||||
PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactor);
|
m_physicsScene.PE.SetLinearFactor(ControllingPrim.PhysBody, BSParam.VehicleLinearFactor);
|
||||||
PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactor);
|
m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor);
|
||||||
|
|
||||||
// Vehicles report collision events so we know when it's on the ground
|
// Vehicles report collision events so we know when it's on the ground
|
||||||
PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||||
|
|
||||||
Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
|
ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape, m_vehicleMass);
|
||||||
PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia);
|
m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
|
||||||
PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
|
m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
|
||||||
|
|
||||||
// Set the gravity for the vehicle depending on the buoyancy
|
// Set the gravity for the vehicle depending on the buoyancy
|
||||||
// TODO: what should be done if prim and vehicle buoyancy differ?
|
// TODO: what should be done if prim and vehicle buoyancy differ?
|
||||||
m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
|
m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy);
|
||||||
// The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
|
// The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
|
||||||
PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
|
m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
|
VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
|
||||||
Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity,
|
ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity,
|
||||||
BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
|
BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
|
||||||
BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
|
BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Prim.PhysBody.HasPhysicalBody)
|
if (ControllingPrim.PhysBody.HasPhysicalBody)
|
||||||
PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RemoveBodyDependencies(BSPhysObject prim)
|
// BSActor.RemoveBodyDependencies
|
||||||
|
public override void RemoveBodyDependencies()
|
||||||
{
|
{
|
||||||
Refresh();
|
Refresh();
|
||||||
return IsActive;
|
}
|
||||||
|
|
||||||
|
// BSActor.Release()
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
UnregisterForSceneEvents();
|
||||||
|
Type = Vehicle.TYPE_NONE;
|
||||||
|
Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterForSceneEvents()
|
||||||
|
{
|
||||||
|
if (!m_haveRegisteredForSceneEvents)
|
||||||
|
{
|
||||||
|
m_physicsScene.BeforeStep += this.Step;
|
||||||
|
m_physicsScene.AfterStep += this.PostStep;
|
||||||
|
ControllingPrim.OnPreUpdateProperty += this.PreUpdateProperty;
|
||||||
|
m_haveRegisteredForSceneEvents = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnregisterForSceneEvents()
|
||||||
|
{
|
||||||
|
if (m_haveRegisteredForSceneEvents)
|
||||||
|
{
|
||||||
|
m_physicsScene.BeforeStep -= this.Step;
|
||||||
|
m_physicsScene.AfterStep -= this.PostStep;
|
||||||
|
ControllingPrim.OnPreUpdateProperty -= this.PreUpdateProperty;
|
||||||
|
m_haveRegisteredForSceneEvents = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PreUpdateProperty(ref EntityProperties entprop)
|
||||||
|
{
|
||||||
|
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
||||||
|
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
||||||
|
if (IsActive)
|
||||||
|
{
|
||||||
|
entprop.RotationalVelocity = Vector3.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Known vehicle value functions
|
#region Known vehicle value functions
|
||||||
|
@ -686,14 +739,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if (m_knownChanged != 0)
|
if (m_knownChanged != 0)
|
||||||
{
|
{
|
||||||
if ((m_knownChanged & m_knownChangedPosition) != 0)
|
if ((m_knownChanged & m_knownChangedPosition) != 0)
|
||||||
Prim.ForcePosition = m_knownPosition;
|
ControllingPrim.ForcePosition = m_knownPosition;
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedOrientation) != 0)
|
if ((m_knownChanged & m_knownChangedOrientation) != 0)
|
||||||
Prim.ForceOrientation = m_knownOrientation;
|
ControllingPrim.ForceOrientation = m_knownOrientation;
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
if ((m_knownChanged & m_knownChangedVelocity) != 0)
|
||||||
{
|
{
|
||||||
Prim.ForceVelocity = m_knownVelocity;
|
ControllingPrim.ForceVelocity = m_knownVelocity;
|
||||||
// Fake out Bullet by making it think the velocity is the same as last time.
|
// Fake out Bullet by making it think the velocity is the same as last time.
|
||||||
// Bullet does a bunch of smoothing for changing parameters.
|
// Bullet does a bunch of smoothing for changing parameters.
|
||||||
// Since the vehicle is demanding this setting, we override Bullet's smoothing
|
// Since the vehicle is demanding this setting, we override Bullet's smoothing
|
||||||
|
@ -702,28 +755,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedForce) != 0)
|
if ((m_knownChanged & m_knownChangedForce) != 0)
|
||||||
Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
|
ControllingPrim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
|
if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
|
||||||
Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
|
ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
|
if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
|
||||||
{
|
{
|
||||||
Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
|
ControllingPrim.ForceRotationalVelocity = m_knownRotationalVelocity;
|
||||||
// PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
|
// PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
|
if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
|
||||||
Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/);
|
ControllingPrim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/);
|
||||||
|
|
||||||
if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
|
if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
|
||||||
{
|
{
|
||||||
Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
|
ControllingPrim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we set one of the values (ie, the physics engine didn't do it) we must force
|
// If we set one of the values (ie, the physics engine didn't do it) we must force
|
||||||
// an UpdateProperties event to send the changes up to the simulator.
|
// an UpdateProperties event to send the changes up to the simulator.
|
||||||
PhysicsScene.PE.PushUpdate(Prim.PhysBody);
|
m_physicsScene.PE.PushUpdate(ControllingPrim.PhysBody);
|
||||||
}
|
}
|
||||||
m_knownChanged = 0;
|
m_knownChanged = 0;
|
||||||
}
|
}
|
||||||
|
@ -736,7 +789,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
|
if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
|
||||||
{
|
{
|
||||||
lastRememberedHeightPos = pos;
|
lastRememberedHeightPos = pos;
|
||||||
m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
m_knownTerrainHeight = ControllingPrim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||||
m_knownHas |= m_knownChangedTerrainHeight;
|
m_knownHas |= m_knownChangedTerrainHeight;
|
||||||
}
|
}
|
||||||
return m_knownTerrainHeight;
|
return m_knownTerrainHeight;
|
||||||
|
@ -748,7 +801,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if ((m_knownHas & m_knownChangedWaterLevel) == 0)
|
if ((m_knownHas & m_knownChangedWaterLevel) == 0)
|
||||||
{
|
{
|
||||||
m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos);
|
m_knownWaterLevel = ControllingPrim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos);
|
||||||
m_knownHas |= m_knownChangedWaterLevel;
|
m_knownHas |= m_knownChangedWaterLevel;
|
||||||
}
|
}
|
||||||
return (float)m_knownWaterLevel;
|
return (float)m_knownWaterLevel;
|
||||||
|
@ -760,7 +813,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if ((m_knownHas & m_knownChangedPosition) == 0)
|
if ((m_knownHas & m_knownChangedPosition) == 0)
|
||||||
{
|
{
|
||||||
m_knownPosition = Prim.ForcePosition;
|
m_knownPosition = ControllingPrim.ForcePosition;
|
||||||
m_knownHas |= m_knownChangedPosition;
|
m_knownHas |= m_knownChangedPosition;
|
||||||
}
|
}
|
||||||
return m_knownPosition;
|
return m_knownPosition;
|
||||||
|
@ -779,7 +832,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if ((m_knownHas & m_knownChangedOrientation) == 0)
|
if ((m_knownHas & m_knownChangedOrientation) == 0)
|
||||||
{
|
{
|
||||||
m_knownOrientation = Prim.ForceOrientation;
|
m_knownOrientation = ControllingPrim.ForceOrientation;
|
||||||
m_knownHas |= m_knownChangedOrientation;
|
m_knownHas |= m_knownChangedOrientation;
|
||||||
}
|
}
|
||||||
return m_knownOrientation;
|
return m_knownOrientation;
|
||||||
|
@ -798,7 +851,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if ((m_knownHas & m_knownChangedVelocity) == 0)
|
if ((m_knownHas & m_knownChangedVelocity) == 0)
|
||||||
{
|
{
|
||||||
m_knownVelocity = Prim.ForceVelocity;
|
m_knownVelocity = ControllingPrim.ForceVelocity;
|
||||||
m_knownHas |= m_knownChangedVelocity;
|
m_knownHas |= m_knownChangedVelocity;
|
||||||
}
|
}
|
||||||
return m_knownVelocity;
|
return m_knownVelocity;
|
||||||
|
@ -839,7 +892,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if ((m_knownHas & m_knownChangedRotationalVelocity) == 0)
|
if ((m_knownHas & m_knownChangedRotationalVelocity) == 0)
|
||||||
{
|
{
|
||||||
m_knownRotationalVelocity = Prim.ForceRotationalVelocity;
|
m_knownRotationalVelocity = ControllingPrim.ForceRotationalVelocity;
|
||||||
m_knownHas |= m_knownChangedRotationalVelocity;
|
m_knownHas |= m_knownChangedRotationalVelocity;
|
||||||
}
|
}
|
||||||
return (Vector3)m_knownRotationalVelocity;
|
return (Vector3)m_knownRotationalVelocity;
|
||||||
|
@ -914,11 +967,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// for the physics engine to note the changes so an UpdateProperties event will happen.
|
// for the physics engine to note the changes so an UpdateProperties event will happen.
|
||||||
PushKnownChanged();
|
PushKnownChanged();
|
||||||
|
|
||||||
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
if (m_physicsScene.VehiclePhysicalLoggingEnabled)
|
||||||
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
|
||||||
|
|
||||||
VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
|
VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
|
||||||
Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
|
ControllingPrim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called after the simulation step
|
// Called after the simulation step
|
||||||
|
@ -926,8 +979,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
|
|
||||||
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
if (m_physicsScene.VehiclePhysicalLoggingEnabled)
|
||||||
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
m_physicsScene.PE.DumpRigidBody(m_physicsScene.World, ControllingPrim.PhysBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the effect of the linear motor and other linear motions (like hover and float).
|
// Apply the effect of the linear motor and other linear motions (like hover and float).
|
||||||
|
@ -967,12 +1020,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VehicleVelocity /= VehicleVelocity.Length();
|
VehicleVelocity /= VehicleVelocity.Length();
|
||||||
VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
|
VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
|
||||||
VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
|
VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
|
||||||
Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
|
ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity);
|
||||||
}
|
}
|
||||||
else if (newVelocityLengthSq < 0.001f)
|
else if (newVelocityLengthSq < 0.001f)
|
||||||
VehicleVelocity = Vector3.Zero;
|
VehicleVelocity = Vector3.Zero;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity );
|
VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.IsColliding, VehicleVelocity );
|
||||||
|
|
||||||
} // end MoveLinear()
|
} // end MoveLinear()
|
||||||
|
|
||||||
|
@ -997,7 +1050,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VehicleVelocity += linearMotorVelocityW;
|
VehicleVelocity += linearMotorVelocityW;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
|
VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
|
||||||
Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
|
ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
||||||
|
@ -1011,7 +1064,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
|
newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
|
||||||
VehiclePosition = newPosition;
|
VehiclePosition = newPosition;
|
||||||
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
|
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
|
||||||
Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
|
ControllingPrim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,7 +1103,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
pos.Z = m_VhoverTargetHeight;
|
pos.Z = m_VhoverTargetHeight;
|
||||||
VehiclePosition = pos;
|
VehiclePosition = pos;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos);
|
VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", ControllingPrim.LocalID, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1079,7 +1132,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
|
VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
|
||||||
Prim.LocalID, VehiclePosition, m_VhoverEfficiency,
|
ControllingPrim.LocalID, VehiclePosition, m_VhoverEfficiency,
|
||||||
m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
|
m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
|
||||||
verticalError, verticalCorrection);
|
verticalError, verticalCorrection);
|
||||||
}
|
}
|
||||||
|
@ -1124,7 +1177,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
VehiclePosition = pos;
|
VehiclePosition = pos;
|
||||||
VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
|
VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
|
||||||
Prim.LocalID, m_BlockingEndPoint, posChange, pos);
|
ControllingPrim.LocalID, m_BlockingEndPoint, posChange, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
|
@ -1164,7 +1217,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
// Another approach is to measure if we're going up. If going up and not colliding,
|
// Another approach is to measure if we're going up. If going up and not colliding,
|
||||||
// the vehicle is in the air. Fix that by pushing down.
|
// the vehicle is in the air. Fix that by pushing down.
|
||||||
if (!Prim.IsColliding && VehicleVelocity.Z > 0.1)
|
if (!ControllingPrim.IsColliding && VehicleVelocity.Z > 0.1)
|
||||||
{
|
{
|
||||||
// Get rid of any of the velocity vector that is pushing us up.
|
// Get rid of any of the velocity vector that is pushing us up.
|
||||||
float upVelocity = VehicleVelocity.Z;
|
float upVelocity = VehicleVelocity.Z;
|
||||||
|
@ -1186,7 +1239,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
|
VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
|
||||||
Prim.LocalID, Prim.IsColliding, upVelocity, VehicleVelocity);
|
ControllingPrim.LocalID, ControllingPrim.IsColliding, upVelocity, VehicleVelocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1196,14 +1249,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
|
Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
|
||||||
|
|
||||||
// Hack to reduce downward force if the vehicle is probably sitting on the ground
|
// Hack to reduce downward force if the vehicle is probably sitting on the ground
|
||||||
if (Prim.IsColliding && IsGroundVehicle)
|
if (ControllingPrim.IsColliding && IsGroundVehicle)
|
||||||
appliedGravity *= BSParam.VehicleGroundGravityFudge;
|
appliedGravity *= BSParam.VehicleGroundGravityFudge;
|
||||||
|
|
||||||
VehicleAddForce(appliedGravity);
|
VehicleAddForce(appliedGravity);
|
||||||
|
|
||||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
|
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
|
||||||
Prim.LocalID, m_VehicleGravity,
|
ControllingPrim.LocalID, m_VehicleGravity,
|
||||||
Prim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
|
ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
|
@ -1227,11 +1280,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
// The vehicle is not adding anything angular wise.
|
// The vehicle is not adding anything angular wise.
|
||||||
VehicleRotationalVelocity = Vector3.Zero;
|
VehicleRotationalVelocity = Vector3.Zero;
|
||||||
VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID);
|
VDetailLog("{0}, MoveAngular,done,zero", ControllingPrim.LocalID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", Prim.LocalID, VehicleRotationalVelocity);
|
VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", ControllingPrim.LocalID, VehicleRotationalVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
|
@ -1262,7 +1315,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
torqueFromOffset.Z = 0;
|
torqueFromOffset.Z = 0;
|
||||||
|
|
||||||
VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
|
VehicleAddAngularForce(torqueFromOffset * m_vehicleMass);
|
||||||
VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
|
VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", ControllingPrim.LocalID, torqueFromOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1341,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// }
|
// }
|
||||||
|
|
||||||
VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
|
VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
|
||||||
VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV);
|
VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", ControllingPrim.LocalID, angularMotorContributionV);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
// From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
|
||||||
|
@ -1334,7 +1387,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VehicleRotationalVelocity += vertContributionV;
|
VehicleRotationalVelocity += vertContributionV;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
|
VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}",
|
||||||
Prim.LocalID,
|
ControllingPrim.LocalID,
|
||||||
differenceAxis,
|
differenceAxis,
|
||||||
differenceAngle,
|
differenceAngle,
|
||||||
correctionRotation,
|
correctionRotation,
|
||||||
|
@ -1433,9 +1486,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
|
VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
|
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
|
||||||
Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
|
ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
|
||||||
VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
|
VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
|
||||||
Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
|
ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1501,7 +1554,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
|
||||||
|
|
||||||
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
|
VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
|
||||||
Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
|
ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1540,7 +1593,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if (rotq != m_rot)
|
if (rotq != m_rot)
|
||||||
{
|
{
|
||||||
VehicleOrientation = m_rot;
|
VehicleOrientation = m_rot;
|
||||||
VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot);
|
VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", ControllingPrim.LocalID, rotq, m_rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1554,8 +1607,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void VDetailLog(string msg, params Object[] args)
|
private void VDetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
if (Prim.PhysicsScene.VehicleLoggingEnabled)
|
if (ControllingPrim.PhysicsScene.VehicleLoggingEnabled)
|
||||||
Prim.PhysicsScene.DetailLog(msg, args);
|
ControllingPrim.PhysicsScene.DetailLog(msg, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,9 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
|
Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
|
||||||
TypeName = typeName;
|
TypeName = typeName;
|
||||||
|
|
||||||
|
// The collection of things that push me around
|
||||||
|
PhysicalActors = new BSActorCollection(PhysicsScene);
|
||||||
|
|
||||||
// Initialize variables kept in base.
|
// Initialize variables kept in base.
|
||||||
GravModifier = 1.0f;
|
GravModifier = 1.0f;
|
||||||
Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
|
Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
|
||||||
|
@ -109,6 +112,10 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
{
|
{
|
||||||
UnRegisterAllPreStepActions();
|
UnRegisterAllPreStepActions();
|
||||||
UnRegisterAllPostStepActions();
|
UnRegisterAllPostStepActions();
|
||||||
|
PhysicsScene.TaintedObject("BSPhysObject.Destroy", delegate()
|
||||||
|
{
|
||||||
|
PhysicalActors.Release();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public BSScene PhysicsScene { get; protected set; }
|
public BSScene PhysicsScene { get; protected set; }
|
||||||
|
@ -180,7 +187,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
Friction = matAttrib.friction;
|
Friction = matAttrib.friction;
|
||||||
Restitution = matAttrib.restitution;
|
Restitution = matAttrib.restitution;
|
||||||
Density = matAttrib.density / BSParam.DensityScaleFactor;
|
Density = matAttrib.density / BSParam.DensityScaleFactor;
|
||||||
DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density);
|
// DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop all physical motion.
|
// Stop all physical motion.
|
||||||
|
@ -230,6 +237,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
|
|
||||||
public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
|
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 OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free
|
||||||
|
public readonly String LockedAxisActorName = "BSPrim.LockedAxis";
|
||||||
|
|
||||||
#region Collisions
|
#region Collisions
|
||||||
|
|
||||||
|
@ -413,6 +421,9 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
#endregion // Collisions
|
#endregion // Collisions
|
||||||
|
|
||||||
#region Per Simulation Step actions
|
#region Per Simulation Step actions
|
||||||
|
|
||||||
|
public BSActorCollection PhysicalActors;
|
||||||
|
|
||||||
// There are some actions that must be performed for a physical object before each simulation step.
|
// 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
|
// 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.
|
// if they have anything to do, a physical object registers for an event call before the step is performed.
|
||||||
|
|
|
@ -72,7 +72,8 @@ public class BSPrim : BSPhysObject
|
||||||
|
|
||||||
private int CrossingFailures { get; set; }
|
private int CrossingFailures { get; set; }
|
||||||
|
|
||||||
public BSDynamics VehicleController { get; private set; }
|
public BSDynamics VehicleActor;
|
||||||
|
public string VehicleActorName = "BasicVehicle";
|
||||||
|
|
||||||
private BSVMotor _targetMotor;
|
private BSVMotor _targetMotor;
|
||||||
private OMV.Vector3 _PIDTarget;
|
private OMV.Vector3 _PIDTarget;
|
||||||
|
@ -100,11 +101,12 @@ public class BSPrim : BSPhysObject
|
||||||
_isPhysical = pisPhysical;
|
_isPhysical = pisPhysical;
|
||||||
_isVolumeDetect = false;
|
_isVolumeDetect = false;
|
||||||
|
|
||||||
VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
|
VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName);
|
||||||
|
PhysicalActors.Add(VehicleActorName, VehicleActor);
|
||||||
|
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
// DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||||
// do the actual object creation at taint time
|
// do the actual object creation at taint time
|
||||||
PhysicsScene.TaintedObject("BSPrim.create", delegate()
|
PhysicsScene.TaintedObject("BSPrim.create", delegate()
|
||||||
{
|
{
|
||||||
|
@ -126,7 +128,7 @@ public class BSPrim : BSPhysObject
|
||||||
// Undo any vehicle properties
|
// Undo any vehicle properties
|
||||||
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("BSPrim.destroy", delegate()
|
PhysicsScene.TaintedObject("BSPrim.Destroy", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||||
// If there are physical body and shape, release my use of same.
|
// If there are physical body and shape, release my use of same.
|
||||||
|
@ -257,98 +259,32 @@ public class BSPrim : BSPhysObject
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TryExperimentalLockAxisCode = false;
|
|
||||||
BSConstraint LockAxisConstraint = null;
|
|
||||||
public override void LockAngularMotion(OMV.Vector3 axis)
|
public override void LockAngularMotion(OMV.Vector3 axis)
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
|
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
|
||||||
|
|
||||||
// "1" means free, "0" means locked
|
// "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.X != 1) locking.X = 0f;
|
||||||
if (axis.Y != 1) locking.Y = 0f;
|
if (axis.Y != 1) locking.Y = 0f;
|
||||||
if (axis.Z != 1) locking.Z = 0f;
|
if (axis.Z != 1) locking.Z = 0f;
|
||||||
LockedAxis = locking;
|
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()
|
PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
|
||||||
{
|
{
|
||||||
CleanUpLockAxisPhysicals(true /* inTaintTime */);
|
// If there is not already an axis locker, make one
|
||||||
|
if (!PhysicalActors.HasActor(LockedAxisActorName))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
angularLow.X = 0f;
|
DetailLog("{0},BSPrim.LockAngularMotion,taint,registeringLockAxisActor", LocalID);
|
||||||
angularHigh.X = 0f;
|
PhysicalActors.Add(LockedAxisActorName, new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName));
|
||||||
}
|
}
|
||||||
if (LockedAxis.Y != 1f)
|
UpdatePhysicalParameters();
|
||||||
{
|
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Everything seems unlocked
|
|
||||||
CleanUpLockAxisPhysicals(false /* inTaintTime */);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
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
|
public override OMV.Vector3 RawPosition
|
||||||
{
|
{
|
||||||
|
@ -604,7 +540,7 @@ public class BSPrim : BSPhysObject
|
||||||
|
|
||||||
public override int VehicleType {
|
public override int VehicleType {
|
||||||
get {
|
get {
|
||||||
return (int)VehicleController.Type; // if we are a vehicle, return that type
|
return (int)VehicleActor.Type; // if we are a vehicle, return that type
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
Vehicle type = (Vehicle)value;
|
Vehicle type = (Vehicle)value;
|
||||||
|
@ -613,20 +549,8 @@ public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
// Done at taint time so we're sure the physics engine is not using the variables
|
// 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 code changes the parameters for this vehicle type.
|
||||||
VehicleController.ProcessTypeChange(type);
|
VehicleActor.ProcessTypeChange(type);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
|
|
||||||
// If an active vehicle, register the vehicle code to be called before each step
|
|
||||||
if (VehicleController.Type == Vehicle.TYPE_NONE)
|
|
||||||
{
|
|
||||||
UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
|
|
||||||
UnRegisterPostStepAction("BSPrim.Vehicle", LocalID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
|
|
||||||
RegisterPostStepAction("BSPrim.Vehicle", LocalID, VehicleController.PostStep);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -634,7 +558,7 @@ public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||||
{
|
{
|
||||||
VehicleController.ProcessFloatVehicleParam((Vehicle)param, value);
|
VehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -642,7 +566,7 @@ public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||||
{
|
{
|
||||||
VehicleController.ProcessVectorVehicleParam((Vehicle)param, value);
|
VehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -650,7 +574,7 @@ public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||||
{
|
{
|
||||||
VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
VehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -658,7 +582,7 @@ public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||||
{
|
{
|
||||||
VehicleController.ProcessVehicleFlags(param, remove);
|
VehicleActor.ProcessVehicleFlags(param, remove);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +839,8 @@ public class BSPrim : BSPhysObject
|
||||||
MakeDynamic(IsStatic);
|
MakeDynamic(IsStatic);
|
||||||
|
|
||||||
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
||||||
VehicleController.Refresh();
|
VehicleActor.Refresh();
|
||||||
|
PhysicalActors.Refresh();
|
||||||
|
|
||||||
// Arrange for collision events if the simulator wants them
|
// Arrange for collision events if the simulator wants them
|
||||||
EnableCollisions(SubscribedEvents());
|
EnableCollisions(SubscribedEvents());
|
||||||
|
@ -1721,9 +1646,9 @@ public class BSPrim : BSPhysObject
|
||||||
volume *= (profileEnd - profileBegin);
|
volume *= (profileEnd - profileBegin);
|
||||||
|
|
||||||
returnMass = Density * BSParam.DensityScaleFactor * volume;
|
returnMass = Density * BSParam.DensityScaleFactor * volume;
|
||||||
DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
|
|
||||||
|
|
||||||
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
|
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
|
||||||
|
// DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
|
||||||
|
|
||||||
return returnMass;
|
return returnMass;
|
||||||
}// end CalculateMass
|
}// end CalculateMass
|
||||||
|
@ -1752,7 +1677,8 @@ public class BSPrim : BSPhysObject
|
||||||
|
|
||||||
protected virtual void RemoveBodyDependencies()
|
protected virtual void RemoveBodyDependencies()
|
||||||
{
|
{
|
||||||
VehicleController.RemoveBodyDependencies(this);
|
VehicleActor.RemoveBodyDependencies();
|
||||||
|
PhysicalActors.RemoveBodyDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The physics engine says that properties have updated. Update same and inform
|
// The physics engine says that properties have updated. Update same and inform
|
||||||
|
@ -1761,13 +1687,6 @@ public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
TriggerPreUpdatePropertyAction(ref entprop);
|
TriggerPreUpdatePropertyAction(ref entprop);
|
||||||
|
|
||||||
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
|
||||||
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
|
||||||
if (VehicleController.IsActive)
|
|
||||||
{
|
|
||||||
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||||
|
|
||||||
// Assign directly to the local variables so the normal set actions do not happen
|
// Assign directly to the local variables so the normal set actions do not happen
|
||||||
|
|
|
@ -463,7 +463,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
if (!m_initialized) return null;
|
if (!m_initialized) return null;
|
||||||
|
|
||||||
DetailLog("{0},BSScene.AddPrimShape,call", localID);
|
// DetailLog("{0},BSScene.AddPrimShape,call", localID);
|
||||||
|
|
||||||
BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
||||||
lock (PhysObjects) PhysObjects.Add(localID, prim);
|
lock (PhysObjects) PhysObjects.Add(localID, prim);
|
||||||
|
|
|
@ -114,9 +114,9 @@ public class BasicVehicles : OpenSimTestCase
|
||||||
// Instead the appropriate values are set and calls are made just the parts of the
|
// Instead the appropriate values are set and calls are made just the parts of the
|
||||||
// controller we want to exercise. Stepping the physics engine then applies
|
// controller we want to exercise. Stepping the physics engine then applies
|
||||||
// the actions of that one feature.
|
// the actions of that one feature.
|
||||||
TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
|
TestVehicle.VehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
|
||||||
TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
|
TestVehicle.VehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
|
||||||
TestVehicle.VehicleController.enableAngularVerticalAttraction = true;
|
TestVehicle.VehicleActor.enableAngularVerticalAttraction = true;
|
||||||
|
|
||||||
TestVehicle.IsPhysical = true;
|
TestVehicle.IsPhysical = true;
|
||||||
PhysicsScene.ProcessTaints();
|
PhysicsScene.ProcessTaints();
|
||||||
|
@ -124,9 +124,9 @@ public class BasicVehicles : OpenSimTestCase
|
||||||
// Step the simulator a bunch of times and vertical attraction should orient the vehicle up
|
// Step the simulator a bunch of times and vertical attraction should orient the vehicle up
|
||||||
for (int ii = 0; ii < simSteps; ii++)
|
for (int ii = 0; ii < simSteps; ii++)
|
||||||
{
|
{
|
||||||
TestVehicle.VehicleController.ForgetKnownVehicleProperties();
|
TestVehicle.VehicleActor.ForgetKnownVehicleProperties();
|
||||||
TestVehicle.VehicleController.ComputeAngularVerticalAttraction();
|
TestVehicle.VehicleActor.ComputeAngularVerticalAttraction();
|
||||||
TestVehicle.VehicleController.PushKnownChanged();
|
TestVehicle.VehicleActor.PushKnownChanged();
|
||||||
|
|
||||||
PhysicsScene.Simulate(simulationTimeStep);
|
PhysicsScene.Simulate(simulationTimeStep);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue