* Adds llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z,TF)

* Currently if you apply that to only one or two axis you get unpredictable and sometimes explosive results.
* Three axis works well enough to play with it anyway.   More work is needed here.
* Fixed an incorrectly named method in ODE.NET
0.6.0-stable
Teravus Ovares 2008-04-23 15:32:19 +00:00
parent d52fc2dc1a
commit 2a3bdde0fa
12 changed files with 252 additions and 12 deletions

View File

@ -1179,9 +1179,12 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectPart rootpart = m_rootPart; SceneObjectPart rootpart = m_rootPart;
if (rootpart != null) if (rootpart != null)
{ {
rootpart.PhysActor.PIDTarget = new PhysicsVector(target.X, target.Y, target.Z); if (rootpart.PhysActor != null)
rootpart.PhysActor.PIDTau = tau; {
rootpart.PhysActor.PIDActive = true; rootpart.PhysActor.PIDTarget = new PhysicsVector(target.X, target.Y, target.Z);
rootpart.PhysActor.PIDTau = tau;
rootpart.PhysActor.PIDActive = true;
}
} }
} }
@ -2229,5 +2232,38 @@ namespace OpenSim.Region.Environment.Scenes
} }
#endregion #endregion
internal void SetAxisRotation(int axis, int rotate10)
{
bool setX = false;
bool setY = false;
bool setZ = false;
int xaxis = 2;
int yaxis = 4;
int zaxis = 8;
if (m_rootPart != null)
{
setX = ((axis & xaxis) != 0) ? true : false;
setY = ((axis & yaxis) != 0) ? true : false;
setZ = ((axis & zaxis) != 0) ? true : false;
float setval = (rotate10 > 0) ? 1f : 0f;
if (setX)
m_rootPart.m_rotationAxis.X = setval;
if (setY)
m_rootPart.m_rotationAxis.Y = setval;
if (setZ)
m_rootPart.m_rotationAxis.Z = setval;
if (setX || setY || setZ)
{
m_rootPart.SetPhysicsAxisRotation();
}
}
}
} }
} }

View File

@ -104,6 +104,7 @@ namespace OpenSim.Region.Environment.Scenes
private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0); private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0);
private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1); private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1);
public LLUUID m_sitTargetAvatar = LLUUID.Zero; public LLUUID m_sitTargetAvatar = LLUUID.Zero;
[XmlIgnore] public PhysicsVector m_rotationAxis = new PhysicsVector(1f,1f,1f);
#region Permissions #region Permissions
@ -1291,6 +1292,21 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
public void SetAxisRotation(int axis, int rotate)
{
if (m_parentGroup != null)
{
m_parentGroup.SetAxisRotation(axis, rotate);
}
}
public void SetPhysicsAxisRotation()
{
PhysActor.LockAngularMotion(m_rotationAxis);
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
}
public void SetFloatOnWater(int floatYN) public void SetFloatOnWater(int floatYN)
{ {
if (PhysActor != null) if (PhysActor != null)
@ -1307,6 +1323,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
public LLVector3 GetSitTargetPositionLL() public LLVector3 GetSitTargetPositionLL()
{ {
return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z); return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z);

View File

@ -374,6 +374,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
{ {
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public void SetAcceleration(PhysicsVector accel) public void SetAcceleration(PhysicsVector accel)
{ {
_acceleration = accel; _acceleration = accel;

View File

@ -809,6 +809,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin
{ {
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override float Mass public override float Mass
{ {
get { return ActorMass; } get { return ActorMass; }

View File

@ -123,6 +123,8 @@ namespace OpenSim.Region.Physics.Manager
public abstract void delink(); public abstract void delink();
public abstract void LockAngularMotion(PhysicsVector axis);
public virtual void RequestPhysicsterseUpdate() public virtual void RequestPhysicsterseUpdate()
{ {
// Make a temporary copy of the event to avoid possibility of // Make a temporary copy of the event to avoid possibility of
@ -347,6 +349,9 @@ namespace OpenSim.Region.Physics.Manager
{ {
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override void AddForce(PhysicsVector force) public override void AddForce(PhysicsVector force)
{ {

View File

@ -149,7 +149,7 @@ namespace OpenSim.Region.Physics.Manager
{ {
PhysicsVector diff = this - v; PhysicsVector diff = this - v;
float d = diff.length(); float d = diff.length();
if (d < tolerance) if (d <= tolerance)
return true; return true;
return false; return false;

View File

@ -505,7 +505,14 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
// TODO: unused: public override void LockAngularMotion(PhysicsVector axis)
{
}
// This code is very useful. Written by DanX0r. We're just not using it right now.
// Commented out to prevent a warning.
//
// private void standupStraight() // private void standupStraight()
// { // {
// // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air. // // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air.

View File

@ -38,6 +38,10 @@ using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.OdePlugin namespace OpenSim.Region.Physics.OdePlugin
{ {
/// <summary>
/// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves.
/// </summary>
public class OdePrim : PhysicsActor public class OdePrim : PhysicsActor
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -55,6 +59,9 @@ namespace OpenSim.Region.Physics.OdePlugin
private PhysicsVector m_taintsize; private PhysicsVector m_taintsize;
private PhysicsVector m_taintVelocity = PhysicsVector.Zero; private PhysicsVector m_taintVelocity = PhysicsVector.Zero;
private Quaternion m_taintrot; private Quaternion m_taintrot;
private PhysicsVector m_angularlock = new PhysicsVector(1f, 1f, 1f);
private PhysicsVector m_taintAngularLock = new PhysicsVector(1f, 1f, 1f);
private IntPtr Amotor = IntPtr.Zero;
private PhysicsVector m_PIDTarget = new PhysicsVector(0, 0, 0); private PhysicsVector m_PIDTarget = new PhysicsVector(0, 0, 0);
private float m_PIDTau = 0f; private float m_PIDTau = 0f;
@ -309,6 +316,12 @@ namespace OpenSim.Region.Physics.OdePlugin
m_collisionscore = 0; m_collisionscore = 0;
m_disabled = false; m_disabled = false;
// The body doesn't already have a finite rotation mode set here
if ((!m_angularlock.IsIdentical(PhysicsVector.Zero, 0)) && _parent == null)
{
createAMotor(m_angularlock);
}
_parent_scene.addActivePrim(this); _parent_scene.addActivePrim(this);
} }
@ -722,7 +735,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
if (prim_geom != (IntPtr)0) if (prim_geom != (IntPtr)0)
{ {
if (m_taintposition != _position) if (!_position.IsIdentical(m_taintposition,0f))
changemove(timestep); changemove(timestep);
if (m_taintrot != _orientation) if (m_taintrot != _orientation)
@ -733,7 +746,7 @@ namespace OpenSim.Region.Physics.OdePlugin
changePhysicsStatus(timestep); changePhysicsStatus(timestep);
// //
if (m_taintsize != _size) if (!_size.IsIdentical(m_taintsize,0))
changesize(timestep); changesize(timestep);
// //
@ -750,7 +763,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintselected != m_isSelected) if (m_taintselected != m_isSelected)
changeSelectedStatus(timestep); changeSelectedStatus(timestep);
if (m_taintVelocity != PhysicsVector.Zero) if (!m_taintVelocity.IsIdentical(PhysicsVector.Zero,0))
changevelocity(timestep); changevelocity(timestep);
if (m_taintparent != _parent) if (m_taintparent != _parent)
@ -759,6 +772,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintCollidesWater != m_collidesWater) if (m_taintCollidesWater != m_collidesWater)
changefloatonwater(timestep); changefloatonwater(timestep);
if (!m_angularlock.IsIdentical(m_taintAngularLock,0))
changeAngularLock(timestep);
} }
else else
@ -767,6 +782,35 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
private void changeAngularLock(float timestep)
{
// do we have a Physical object?
if (Body != IntPtr.Zero)
{
//Check that we have a Parent
//If we have a parent then we're not authorative here
if (_parent == null)
{
if (!m_taintAngularLock.IsIdentical(new PhysicsVector(1f,1f,1f), 0))
{
//d.BodySetFiniteRotationMode(Body, 0);
//d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z);
createAMotor(m_taintAngularLock);
}
else
{
if (Amotor != IntPtr.Zero)
{
d.JointDestroy(Amotor);
Amotor = (IntPtr)0;
}
}
}
}
// Store this for later in case we get turned into a separate body
m_angularlock = new PhysicsVector(m_taintAngularLock.X,m_angularlock.Y,m_angularlock.Z);
}
private void changelink(float timestep) private void changelink(float timestep)
{ {
@ -1241,6 +1285,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_isphysical && Body != (IntPtr) 0) if (m_isphysical && Body != (IntPtr) 0)
{ {
d.BodySetQuaternion(Body, ref myrot); d.BodySetQuaternion(Body, ref myrot);
if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0))
createAMotor(m_angularlock);
} }
resetCollisionAccounting(); resetCollisionAccounting();
@ -1880,6 +1926,17 @@ namespace OpenSim.Region.Physics.OdePlugin
m_taintparent = null; m_taintparent = null;
} }
public override void LockAngularMotion(PhysicsVector axis)
{
// reverse the zero/non zero values for ODE.
axis.X = (axis.X > 0) ? 1f : 0f;
axis.Y = (axis.Y > 0) ? 1f : 0f;
axis.Z = (axis.Z > 0) ? 1f : 0f;
m_taintAngularLock = new PhysicsVector(axis.X, axis.Y, axis.Z); ;
}
public void UpdatePositionAndVelocity() public void UpdatePositionAndVelocity()
{ {
// no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
@ -2078,5 +2135,83 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } } public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } }
public override bool PIDActive { set { m_usePID = value; } } public override bool PIDActive { set { m_usePID = value; } }
public override float PIDTau { set { m_PIDTau = (value * 0.6f); } } public override float PIDTau { set { m_PIDTau = (value * 0.6f); } }
private void createAMotor(PhysicsVector axis)
{
if (Body == IntPtr.Zero)
return;
if (Amotor != IntPtr.Zero)
{
d.JointDestroy(Amotor);
Amotor = IntPtr.Zero;
}
float m_tensor = 0f;
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
m_tensor = 2f;
}
else
{
m_tensor = 5f;
}
float axisnum = 3;
axisnum = (axisnum - (axis.X + axis.Y + axis.Z));
if (axisnum <= 0)
return;
int dAMotorEuler = 1;
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
d.JointAttach(Amotor, Body, IntPtr.Zero);
d.JointSetAMotorMode(Amotor, dAMotorEuler);
d.JointSetAMotorNumAxes(Amotor,(int)axisnum);
int i = 0;
if (axis.X == 0)
{
d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0);
i++;
}
if (axis.Y == 0)
{
d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0);
i++;
}
if (axis.Z == 0)
{
d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1);
i++;
}
for (int j = 0; j < (int)axisnum; j++)
{
//d.JointSetAMotorAngle(Amotor, j, 0);
}
//
//d.JointSetAMotorAngle(Amotor, 1, 0);
//d.JointSetAMotorAngle(Amotor, 2, 0);
// These lowstops and high stops are effectively (no wiggle room)
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, m_tensor);
}
} }
} }

View File

@ -502,6 +502,12 @@ namespace OpenSim.Region.Physics.POSPlugin
{ {
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public void SetAcceleration(PhysicsVector accel) public void SetAcceleration(PhysicsVector accel)
{ {
_acceleration = accel; _acceleration = accel;
@ -706,6 +712,11 @@ namespace OpenSim.Region.Physics.POSPlugin
{ {
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override bool Selected public override bool Selected
{ {
set { return; } set { return; }

View File

@ -392,6 +392,11 @@ namespace OpenSim.Region.Physics.PhysXPlugin
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override void SetMomentum(PhysicsVector momentum) public override void SetMomentum(PhysicsVector momentum)
{ {
} }
@ -630,6 +635,11 @@ namespace OpenSim.Region.Physics.PhysXPlugin
{ {
} }
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override float Mass public override float Mass
{ {
get { return 0f; } get { return 0f; }

View File

@ -692,6 +692,9 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llSetStatus(int status, int value) public void llSetStatus(int status, int value)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
int statusrotationaxis = 0;
if ((status & BuiltIn_Commands_BaseClass.STATUS_PHYSICS) == BuiltIn_Commands_BaseClass.STATUS_PHYSICS) if ((status & BuiltIn_Commands_BaseClass.STATUS_PHYSICS) == BuiltIn_Commands_BaseClass.STATUS_PHYSICS)
{ {
if (value == 1) if (value == 1)
@ -713,15 +716,16 @@ namespace OpenSim.Region.ScriptEngine.Common
} }
if ((status & BuiltIn_Commands_BaseClass.STATUS_ROTATE_X) == BuiltIn_Commands_BaseClass.STATUS_ROTATE_X) if ((status & BuiltIn_Commands_BaseClass.STATUS_ROTATE_X) == BuiltIn_Commands_BaseClass.STATUS_ROTATE_X)
{ {
NotImplemented("llSetStatus - STATUS_ROTATE_X"); statusrotationaxis |= BuiltIn_Commands_BaseClass.STATUS_ROTATE_X;
} }
if ((status & BuiltIn_Commands_BaseClass.STATUS_ROTATE_Y) == BuiltIn_Commands_BaseClass.STATUS_ROTATE_Y) if ((status & BuiltIn_Commands_BaseClass.STATUS_ROTATE_Y) == BuiltIn_Commands_BaseClass.STATUS_ROTATE_Y)
{ {
NotImplemented("llSetStatus - STATUS_ROTATE_Y"); statusrotationaxis |= BuiltIn_Commands_BaseClass.STATUS_ROTATE_Y;
} }
if ((status & BuiltIn_Commands_BaseClass.STATUS_ROTATE_Z) == BuiltIn_Commands_BaseClass.STATUS_ROTATE_Z) if ((status & BuiltIn_Commands_BaseClass.STATUS_ROTATE_Z) == BuiltIn_Commands_BaseClass.STATUS_ROTATE_Z)
{ {
NotImplemented("llSetStatus - STATUS_ROTATE_Z"); statusrotationaxis |= BuiltIn_Commands_BaseClass.STATUS_ROTATE_Z;
} }
if ((status & BuiltIn_Commands_BaseClass.STATUS_BLOCK_GRAB) == BuiltIn_Commands_BaseClass.STATUS_BLOCK_GRAB) if ((status & BuiltIn_Commands_BaseClass.STATUS_BLOCK_GRAB) == BuiltIn_Commands_BaseClass.STATUS_BLOCK_GRAB)
{ {
@ -739,7 +743,11 @@ namespace OpenSim.Region.ScriptEngine.Common
{ {
NotImplemented("llSetStatus - STATUS_SANDBOX"); NotImplemented("llSetStatus - STATUS_SANDBOX");
} }
if (statusrotationaxis != 0)
{
m_host.SetAxisRotation(statusrotationaxis, value);
}
return; return;
} }

Binary file not shown.