UbitODE: replace 'taints' by 'changes' for avatars also. This provides better time order with changes in prims.

avinationmerge
UbitUmarov 2012-02-11 17:35:38 +00:00
parent d4e28ed113
commit 022ae33ed5
3 changed files with 396 additions and 268 deletions

View File

@ -26,7 +26,7 @@
*/ */
// Revision by Ubit 2011 // Revision by Ubit 2011/12
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -95,21 +95,12 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_iscollidingObj = false; private bool m_iscollidingObj = false;
private bool m_alwaysRun = false; private bool m_alwaysRun = false;
private int m_requestedUpdateFrequency = 0; private int m_requestedUpdateFrequency = 0;
private Vector3 m_taintPosition = Vector3.Zero;
private bool m_hasTaintPosition = false;
public uint m_localID = 0; public uint m_localID = 0;
public bool m_returnCollisions = false; public bool m_returnCollisions = false;
// taints and their non-tainted counterparts // taints and their non-tainted counterparts
public bool m_isPhysical = false; // the current physical status public bool m_isPhysical = false; // the current physical status
public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
public float MinimumGroundFlightOffset = 3f; public float MinimumGroundFlightOffset = 3f;
private Vector3 m_taintForce;
private bool m_hasTaintForce;
private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
private float m_buoyancy = 0f; private float m_buoyancy = 0f;
// private CollisionLocker ode; // private CollisionLocker ode;
@ -151,15 +142,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_uuid = UUID.Random(); m_uuid = UUID.Random();
m_hasTaintPosition = false;
if (pos.IsFinite()) if (pos.IsFinite())
{ {
if (pos.Z > 9999999f) if (pos.Z > 99999f)
{ {
pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
} }
if (pos.Z < -90000f) if (pos.Z < -100f) // shouldn't this be 0 ?
{ {
pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
} }
@ -187,15 +176,12 @@ namespace OpenSim.Region.Physics.OdePlugin
CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f; CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f;
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
m_isPhysical = false; // current status: no ODE information exists m_isPhysical = false; // current status: no ODE information exists
m_tainted_isPhysical = true; // new tainted status: need to create ODE information
m_hasTaintForce = false;
_parent_scene.AddPhysicsActorTaint(this);
m_name = avName; m_name = avName;
AddChange(changes.Add, null);
} }
public override int PhysicsActorType public override int PhysicsActorType
@ -402,16 +388,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
} }
if (value.Z < -90000f) if (value.Z < -100f)
{ {
value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
} }
AddChange(changes.Position, value);
m_taintPosition.X = value.X;
m_taintPosition.Y = value.Y;
m_taintPosition.Z = value.Z;
m_hasTaintPosition = true;
_parent_scene.AddPhysicsActorTaint(this);
} }
else else
{ {
@ -440,11 +421,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (value.IsFinite()) if (value.IsFinite())
{ {
m_pidControllerActive = true; AddChange(changes.Size, value);
Vector3 SetSize = value;
m_tainted_CAPSULE_LENGTH = SetSize.Z *1.15f - CAPSULE_RADIUS * 2.0f;
_parent_scene.AddPhysicsActorTaint(this);
} }
else else
{ {
@ -460,129 +437,6 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="npositionY"></param> /// <param name="npositionY"></param>
/// <param name="npositionZ"></param> /// <param name="npositionZ"></param>
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
// place that is safe to call this routine AvatarGeomAndBodyCreation.
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
{
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
if (CAPSULE_LENGTH <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_LENGTH = 0.01f;
}
if (CAPSULE_RADIUS <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_RADIUS = 0.01f;
}
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
m_mass = ShellMass.mass; // update mass
// rescale PID parameters
PID_D = _parent_scene.avPIDD;
PID_P = _parent_scene.avPIDP;
// rescale PID parameters so that this aren't affected by mass
// and so don't get unstable for some masses
// also scale by ode time step so you don't need to refix them
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
PID_P /= 50 * 80;
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
Body = d.BodyCreate(_parent_scene.world);
d.BodySetAutoDisableFlag(Body, false);
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
_position.X = npositionX;
_position.Y = npositionY;
_position.Z = npositionZ;
m_hasTaintPosition = false;
d.BodySetMass(Body, ref ShellMass);
d.GeomSetBody(Shell, Body);
// The purpose of the AMotor here is to keep the avatar's physical
// surrogate from rotating while moving
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
d.JointAttach(Amotor, Body, IntPtr.Zero);
d.JointSetAMotorMode(Amotor, 0);
d.JointSetAMotorNumAxes(Amotor, 3);
d.JointSetAMotorAxis(Amotor, 0, 0 , 1, 0, 0);
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
d.JointSetAMotorAngle(Amotor, 0, 0);
d.JointSetAMotorAngle(Amotor, 1, 0);
d.JointSetAMotorAngle(Amotor, 2, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
// These lowstops and high stops are effectively (no wiggle room)
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f);
}
/// <summary>
/// Destroys the avatar body and geom
private void AvatarGeomAndBodyDestroy()
{
// Kill the Amotor
if (Amotor != IntPtr.Zero)
{
d.JointDestroy(Amotor);
Amotor = IntPtr.Zero;
}
if (Body != IntPtr.Zero)
{
//kill the body
d.BodyDestroy(Body);
Body = IntPtr.Zero;
}
//kill the Geometry
if (Shell != IntPtr.Zero)
{
_parent_scene.geom_name_map.Remove(Shell);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
d.GeomDestroy(Shell);
_parent_scene.geom_name_map.Remove(Shell);
Shell = IntPtr.Zero;
}
}
// //
/// <summary> /// <summary>
/// Uses the capped cyllinder volume formula to calculate the avatar's mass. /// Uses the capped cyllinder volume formula to calculate the avatar's mass.
@ -705,8 +559,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (value.IsFinite()) if (value.IsFinite())
{ {
m_pidControllerActive = true; AddChange(changes.Velocity, value);
_target_velocity = value;
} }
else else
{ {
@ -738,9 +591,6 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return Quaternion.Identity; } get { return Quaternion.Identity; }
set set
{ {
//Matrix3 or = Orientation.ToRotationMatrix();
//d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22);
//d.BodySetRotation(Body, ref ord);
} }
} }
@ -767,18 +617,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (pushforce) if (pushforce)
{ {
m_pidControllerActive = false; AddChange(changes.Force, force * m_density / _parent_scene.ODE_STEPSIZE / 28f);
// scale with odetime step and density
m_taintForce = force * m_density / _parent_scene.ODE_STEPSIZE / 28f;
m_hasTaintForce = true;
_parent_scene.AddPhysicsActorTaint(this);
} }
else else
{ {
m_pidControllerActive = true; AddChange(changes.Velocity, force);
_target_velocity.X += force.X;
_target_velocity.Y += force.Y;
_target_velocity.Z += force.Z;
} }
} }
else else
@ -798,6 +641,128 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
// place that is safe to call this routine AvatarGeomAndBodyCreation.
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
{
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
if (CAPSULE_LENGTH <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_LENGTH = 0.01f;
}
if (CAPSULE_RADIUS <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_RADIUS = 0.01f;
}
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
m_mass = ShellMass.mass; // update mass
// rescale PID parameters
PID_D = _parent_scene.avPIDD;
PID_P = _parent_scene.avPIDP;
// rescale PID parameters so that this aren't affected by mass
// and so don't get unstable for some masses
// also scale by ode time step so you don't need to refix them
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
PID_P /= 50 * 80;
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
Body = d.BodyCreate(_parent_scene.world);
d.BodySetAutoDisableFlag(Body, false);
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
_position.X = npositionX;
_position.Y = npositionY;
_position.Z = npositionZ;
d.BodySetMass(Body, ref ShellMass);
d.GeomSetBody(Shell, Body);
// The purpose of the AMotor here is to keep the avatar's physical
// surrogate from rotating while moving
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
d.JointAttach(Amotor, Body, IntPtr.Zero);
d.JointSetAMotorMode(Amotor, 0);
d.JointSetAMotorNumAxes(Amotor, 3);
d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
d.JointSetAMotorAngle(Amotor, 0, 0);
d.JointSetAMotorAngle(Amotor, 1, 0);
d.JointSetAMotorAngle(Amotor, 2, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
// These lowstops and high stops are effectively (no wiggle room)
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f);
}
/// <summary>
/// Destroys the avatar body and geom
private void AvatarGeomAndBodyDestroy()
{
// Kill the Amotor
if (Amotor != IntPtr.Zero)
{
d.JointDestroy(Amotor);
Amotor = IntPtr.Zero;
}
if (Body != IntPtr.Zero)
{
//kill the body
d.BodyDestroy(Body);
Body = IntPtr.Zero;
}
//kill the Geometry
if (Shell != IntPtr.Zero)
{
_parent_scene.geom_name_map.Remove(Shell);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
d.GeomDestroy(Shell);
_parent_scene.geom_name_map.Remove(Shell);
Shell = IntPtr.Zero;
}
}
/// <summary> /// <summary>
/// Called from Simulate /// Called from Simulate
/// This is the avatar's movement control + PID Controller /// This is the avatar's movement control + PID Controller
@ -1136,8 +1101,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// </summary> /// </summary>
public void Destroy() public void Destroy()
{ {
m_tainted_isPhysical = false; AddChange(changes.Remove, null);
_parent_scene.AddPhysicsActorTaint(this);
} }
public override void CrossingFailure() public override void CrossingFailure()
@ -1207,12 +1171,11 @@ namespace OpenSim.Region.Physics.OdePlugin
return m_haseventsubscription; return m_haseventsubscription;
} }
public void ProcessTaints(float timestep) private void changePhysicsStatus(bool NewStatus)
{ {
if (NewStatus != m_isPhysical)
if (m_tainted_isPhysical != m_isPhysical)
{ {
if (m_tainted_isPhysical) if (NewStatus)
{ {
// Create avatar capsule and related ODE data // Create avatar capsule and related ODE data
if ((Shell != IntPtr.Zero)) if ((Shell != IntPtr.Zero))
@ -1237,19 +1200,40 @@ namespace OpenSim.Region.Physics.OdePlugin
AvatarGeomAndBodyDestroy(); AvatarGeomAndBodyDestroy();
} }
m_isPhysical = m_tainted_isPhysical; m_isPhysical = NewStatus;
}
} }
if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) private void changeAdd()
{
changePhysicsStatus(true);
}
private void changeRemove()
{
changePhysicsStatus(false);
}
private void changeShape(PrimitiveBaseShape arg)
{
}
private void changeSize(Vector3 Size)
{
if (Size.IsFinite())
{
float caplen = Size.Z;
caplen = caplen * 1.15f - CAPSULE_RADIUS * 2.0f;
if (caplen != CAPSULE_LENGTH)
{ {
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
{ {
AvatarGeomAndBodyDestroy(); AvatarGeomAndBodyDestroy();
m_pidControllerActive = true;
float prevCapsule = CAPSULE_LENGTH; float prevCapsule = CAPSULE_LENGTH;
CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; CAPSULE_LENGTH = caplen;
AvatarGeomAndBodyCreation(_position.X, _position.Y, AvatarGeomAndBodyCreation(_position.X, _position.Y,
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2)); _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2));
@ -1268,29 +1252,194 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
if (m_hasTaintPosition) m_pidControllerActive = true;
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
}
}
private void changePosition( Vector3 newPos)
{ {
if (Body != IntPtr.Zero) if (Body != IntPtr.Zero)
d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z);
_position = newPos;
_position.X = m_taintPosition.X;
_position.Y = m_taintPosition.Y;
_position.Z = m_taintPosition.Z;
m_hasTaintPosition = false;
} }
if (m_hasTaintForce) private void changeOrientation(Quaternion newOri)
{ {
}
private void changeVelocity(Vector3 newVel)
{
m_pidControllerActive = true;
_target_velocity = newVel;
}
private void changeSetTorque(Vector3 newTorque)
{
}
private void changeAddForce(Vector3 newForce)
{
}
private void changeAddAngularForce(Vector3 arg)
{
}
private void changeAngularLock(Vector3 arg)
{
}
private void changeFloatOnWater(bool arg)
{
}
private void changeVolumedetetion(bool arg)
{
}
private void changeSelectedStatus(bool arg)
{
}
private void changeDisable(bool arg)
{
}
private void changeBuilding(bool arg)
{
}
private void changeForce(Vector3 newForce)
{
m_pidControllerActive = false;
if (Body != IntPtr.Zero) if (Body != IntPtr.Zero)
{ {
if(m_taintForce.X !=0f || m_taintForce.Y !=0f || m_taintForce.Z !=0) if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0)
d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z); d.BodyAddForce(Body, newForce.X, newForce.Y, newForce.Z);
m_hasTaintForce = false;
} }
} }
private void donullchange()
{
} }
public bool DoAChange(changes what, object arg)
{
if (Shell == IntPtr.Zero && what != changes.Add && what != changes.Remove)
{
return false;
}
// nasty switch
switch (what)
{
case changes.Add:
changeAdd();
break;
case changes.Remove:
changeRemove();
break;
case changes.Position:
changePosition((Vector3)arg);
break;
case changes.Orientation:
changeOrientation((Quaternion)arg);
break;
case changes.PosOffset:
donullchange();
break;
case changes.OriOffset:
donullchange();
break;
case changes.Velocity:
changeVelocity((Vector3)arg);
break;
// case changes.Acceleration:
// changeacceleration((Vector3)arg);
// break;
// case changes.AngVelocity:
// changeangvelocity((Vector3)arg);
// break;
case changes.Force:
changeForce((Vector3)arg);
break;
case changes.Torque:
changeSetTorque((Vector3)arg);
break;
case changes.AddForce:
changeAddForce((Vector3)arg);
break;
case changes.AddAngForce:
changeAddAngularForce((Vector3)arg);
break;
case changes.AngLock:
changeAngularLock((Vector3)arg);
break;
case changes.Size:
changeSize((Vector3)arg);
break;
/* not in use for now
case changes.Shape:
changeShape((PrimitiveBaseShape)arg);
break;
case changes.CollidesWater:
changeFloatOnWater((bool)arg);
break;
case changes.VolumeDtc:
changeVolumedetetion((bool)arg);
break;
case changes.Physical:
changePhysicsStatus((bool)arg);
break;
case changes.Selected:
changeSelectedStatus((bool)arg);
break;
case changes.disabled:
changeDisable((bool)arg);
break;
case changes.building:
changeBuilding((bool)arg);
break;
*/
case changes.Null:
donullchange();
break;
default:
donullchange();
break;
}
return false;
}
public void AddChange(changes what, object arg)
{
_parent_scene.AddChange((PhysicsActor)this, what, arg);
}
internal void AddCollisionFrameTime(int p) internal void AddCollisionFrameTime(int p)
{ {
// protect it from overflow crashing // protect it from overflow crashing

View File

@ -668,13 +668,14 @@ namespace OpenSim.Region.Physics.OdePlugin
AddChange(changes.VehicleVectorParam, fp); AddChange(changes.VehicleVectorParam, fp);
} }
public override void VehicleFlags(int param, bool remove) public override void VehicleFlags(int param, bool value)
{ {
if (m_vehicle == null) if (m_vehicle == null)
return; return;
m_vehicle.ProcessVehicleFlags(param, remove); strVehicleBoolParam bp = new strVehicleBoolParam();
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) bp.param = param;
d.BodyEnable(Body); bp.value = value;
AddChange(changes.VehicleFlags, bp);
} }
public void SetAcceleration(Vector3 accel) public void SetAcceleration(Vector3 accel)
@ -2376,6 +2377,7 @@ namespace OpenSim.Region.Physics.OdePlugin
else else
*/ */
DestroyBody(); DestroyBody();
Stop();
} }
} }
} }
@ -3287,7 +3289,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void AddChange(changes what, object arg) public void AddChange(changes what, object arg)
{ {
_parent_scene.AddChange(this, what, arg); _parent_scene.AddChange((PhysicsActor) this, what, arg);
} }

View File

@ -147,7 +147,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public struct ODEchangeitem public struct ODEchangeitem
{ {
public OdePrim prim; public PhysicsActor actor;
public OdeCharacter character; public OdeCharacter character;
public changes what; public changes what;
public Object arg; public Object arg;
@ -187,7 +187,6 @@ namespace OpenSim.Region.Physics.OdePlugin
public float gravityy = 0f; public float gravityy = 0f;
public float gravityz = -9.8f; public float gravityz = -9.8f;
private float waterlevel = 0f; private float waterlevel = 0f;
private int framecount = 0; private int framecount = 0;
@ -1558,23 +1557,15 @@ namespace OpenSim.Region.Physics.OdePlugin
return true; return true;
} }
public void AddChange(OdePrim prim, changes what, Object arg)
{
ODEchangeitem item = new ODEchangeitem();
item.prim = prim;
item.what = what;
item.arg = arg;
ChangesQueue.Enqueue(item);
}
/// <summary> /// <summary>
/// Called to queue a change to a prim /// Called to queue a change to a actor
/// to use in place of old taint mechanism so changes do have a time sequence /// to use in place of old taint mechanism so changes do have a time sequence
/// </summary> /// </summary>
public void AddChange(OdeCharacter character, changes what, Object arg)
public void AddChange(PhysicsActor actor, changes what, Object arg)
{ {
ODEchangeitem item = new ODEchangeitem(); ODEchangeitem item = new ODEchangeitem();
item.character = character; item.actor = actor;
item.what = what; item.what = what;
item.arg = arg; item.arg = arg;
ChangesQueue.Enqueue(item); ChangesQueue.Enqueue(item);
@ -1687,25 +1678,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// clear pointer/counter to contacts to pass into joints // clear pointer/counter to contacts to pass into joints
m_global_contactcount = 0; m_global_contactcount = 0;
// do characters requested changes
OdeCharacter character;
int numtaints;
lock (_taintedCharacterLock)
{
numtaints = _taintedCharacterQ.Count;
// if (numtaints > 50)
// numtaints = 50;
while (numtaints > 0)
{
character = _taintedCharacterQ.Dequeue();
character.ProcessTaints(ODE_STEPSIZE);
_taintedCharacterH.Remove(character);
numtaints--;
}
}
// do other objects requested changes
ODEchangeitem item; ODEchangeitem item;
if(ChangesQueue.Count >0) if(ChangesQueue.Count >0)
@ -1716,14 +1688,19 @@ namespace OpenSim.Region.Physics.OdePlugin
while(ChangesQueue.Dequeue(out item)) while(ChangesQueue.Dequeue(out item))
{ {
if (item.prim != null) if (item.actor != null)
{ {
try try
{ {
if (item.prim.DoAChange(item.what, item.arg)) if (item.actor is OdeCharacter)
RemovePrimThreadLocked(item.prim); ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
RemovePrimThreadLocked((OdePrim)item.actor);
} }
catch { }; catch
{
m_log.Warn("[PHYSICS]: doChange failed for a actor");
};
} }
ttmp = Util.EnvironmentTickCountSubtract(ttmpstart); ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
if (ttmp > 20) if (ttmp > 20)