* 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;
if (rootpart != null)
{
rootpart.PhysActor.PIDTarget = new PhysicsVector(target.X, target.Y, target.Z);
rootpart.PhysActor.PIDTau = tau;
rootpart.PhysActor.PIDActive = true;
if (rootpart.PhysActor != null)
{
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
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 Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1);
public LLUUID m_sitTargetAvatar = LLUUID.Zero;
[XmlIgnore] public PhysicsVector m_rotationAxis = new PhysicsVector(1f,1f,1f);
#region Permissions
@ -1290,6 +1291,21 @@ namespace OpenSim.Region.Environment.Scenes
PhysActor.Buoyancy = fvalue;
}
}
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)
{
@ -1306,6 +1322,7 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public LLVector3 GetSitTargetPositionLL()
{

View File

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

View File

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

View File

@ -123,6 +123,8 @@ namespace OpenSim.Region.Physics.Manager
public abstract void delink();
public abstract void LockAngularMotion(PhysicsVector axis);
public virtual void RequestPhysicsterseUpdate()
{
// 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)
{

View File

@ -149,7 +149,7 @@ namespace OpenSim.Region.Physics.Manager
{
PhysicsVector diff = this - v;
float d = diff.length();
if (d < tolerance)
if (d <= tolerance)
return true;
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()
// {
// // 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
{
/// <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
{
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_taintVelocity = PhysicsVector.Zero;
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 float m_PIDTau = 0f;
@ -309,6 +316,12 @@ namespace OpenSim.Region.Physics.OdePlugin
m_collisionscore = 0;
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);
}
@ -722,7 +735,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
if (prim_geom != (IntPtr)0)
{
if (m_taintposition != _position)
if (!_position.IsIdentical(m_taintposition,0f))
changemove(timestep);
if (m_taintrot != _orientation)
@ -733,7 +746,7 @@ namespace OpenSim.Region.Physics.OdePlugin
changePhysicsStatus(timestep);
//
if (m_taintsize != _size)
if (!_size.IsIdentical(m_taintsize,0))
changesize(timestep);
//
@ -750,7 +763,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintselected != m_isSelected)
changeSelectedStatus(timestep);
if (m_taintVelocity != PhysicsVector.Zero)
if (!m_taintVelocity.IsIdentical(PhysicsVector.Zero,0))
changevelocity(timestep);
if (m_taintparent != _parent)
@ -759,6 +772,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintCollidesWater != m_collidesWater)
changefloatonwater(timestep);
if (!m_angularlock.IsIdentical(m_taintAngularLock,0))
changeAngularLock(timestep);
}
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)
{
@ -1241,6 +1285,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_isphysical && Body != (IntPtr) 0)
{
d.BodySetQuaternion(Body, ref myrot);
if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0))
createAMotor(m_angularlock);
}
resetCollisionAccounting();
@ -1880,6 +1926,17 @@ namespace OpenSim.Region.Physics.OdePlugin
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()
{
// 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 bool PIDActive { set { m_usePID = value; } }
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)
{
_acceleration = accel;
@ -706,6 +712,11 @@ namespace OpenSim.Region.Physics.POSPlugin
{
}
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override bool Selected
{
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)
{
}
@ -630,6 +635,11 @@ namespace OpenSim.Region.Physics.PhysXPlugin
{
}
public override void LockAngularMotion(PhysicsVector axis)
{
}
public override float Mass
{
get { return 0f; }

View File

@ -692,6 +692,9 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llSetStatus(int status, int value)
{
m_host.AddScriptLPS(1);
int statusrotationaxis = 0;
if ((status & BuiltIn_Commands_BaseClass.STATUS_PHYSICS) == BuiltIn_Commands_BaseClass.STATUS_PHYSICS)
{
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)
{
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)
{
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)
{
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)
{
@ -739,7 +743,11 @@ namespace OpenSim.Region.ScriptEngine.Common
{
NotImplemented("llSetStatus - STATUS_SANDBOX");
}
if (statusrotationaxis != 0)
{
m_host.SetAxisRotation(statusrotationaxis, value);
}
return;
}

Binary file not shown.