diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 36d46b8ee5..cf68ff4273 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -149,27 +149,47 @@ namespace OpenSim.Region.Framework.Scenes
///
public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
{
+ /*
+ SceneObjectPart part = GetSceneObjectPart(primLocalID);
+
+ if (null == part)
+ return;
+
+ if (part.IsRoot)
+ {
+ SceneObjectGroup sog = part.ParentGroup;
+ sog.SendPropertiesToClient(remoteClient);
+
+ // A prim is only tainted if it's allowed to be edited by the person clicking it.
+ if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
+ || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
+ {
+ sog.IsSelected = true;
+ EventManager.TriggerParcelPrimCountTainted();
+ }
+ }
+ else
+ {
+ part.SendPropertiesToClient(remoteClient);
+ }
+ */
SceneObjectPart part = GetSceneObjectPart(primLocalID);
if (null == part)
return;
- if (part.IsRoot)
- {
- SceneObjectGroup sog = part.ParentGroup;
- sog.SendPropertiesToClient(remoteClient);
+ SceneObjectGroup sog = part.ParentGroup;
+ if (sog == null)
+ return;
- // A prim is only tainted if it's allowed to be edited by the person clicking it.
- if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
- || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
- {
- sog.IsSelected = true;
- EventManager.TriggerParcelPrimCountTainted();
- }
- }
- else
+ part.SendPropertiesToClient(remoteClient);
+
+ // A prim is only tainted if it's allowed to be edited by the person clicking it.
+ if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
+ || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
{
- part.SendPropertiesToClient(remoteClient);
+ part.IsSelected = true;
+ EventManager.TriggerParcelPrimCountTainted();
}
}
@@ -222,7 +242,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart part = GetSceneObjectPart(primLocalID);
if (part == null)
return;
-
+ /*
// A deselect packet contains all the local prims being deselected. However, since selection is still
// group based we only want the root prim to trigger a full update - otherwise on objects with many prims
// we end up sending many duplicate ObjectUpdates
@@ -257,6 +277,22 @@ namespace OpenSim.Region.Framework.Scenes
part.UUID, remoteClient.AgentId))
EventManager.TriggerParcelPrimCountTainted();
}
+ */
+
+ bool oldgprSelect = part.ParentGroup.IsSelected;
+
+ // This is wrong, wrong, wrong. Selection should not be
+ // handled by group, but by prim. Legacy cruft.
+ // TODO: Make selection flagging per prim!
+ //
+ if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)
+ || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId))
+ {
+ part.IsSelected = false;
+ if (!part.ParentGroup.IsAttachment && oldgprSelect != part.ParentGroup.IsSelected)
+ EventManager.TriggerParcelPrimCountTainted();
+ }
+
}
public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount,
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 8717ed1af2..c47db97229 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -726,6 +726,11 @@ namespace OpenSim.Region.Framework.Scenes
m_isSelected = value;
// Tell physics engine that group is selected
+ // this is not right
+ // but ode engines should only really need to know about root part
+ // so they can put entire object simulation on hold and not colliding
+ // keep as was for now
+
PhysicsActor pa = m_rootPart.PhysActor;
if (pa != null)
{
@@ -747,6 +752,40 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public void PartSelectChanged(bool partSelect)
+ {
+ // any part selected makes group selected
+ if (m_isSelected == partSelect)
+ return;
+
+ if (partSelect)
+ {
+ IsSelected = partSelect;
+// if (!IsAttachment)
+// ScheduleGroupForFullUpdate();
+ }
+ else
+ {
+ // bad bad bad 2 heavy for large linksets
+ // since viewer does send lot of (un)selects
+ // this needs to be replaced by a specific list or count ?
+ // but that will require extra code in several places
+
+ SceneObjectPart[] parts = m_parts.GetArray();
+ for (int i = 0; i < parts.Length; i++)
+ {
+ SceneObjectPart part = parts[i];
+ if (part.IsSelected)
+ return;
+ }
+ IsSelected = partSelect;
+ if (!IsAttachment)
+ {
+ ScheduleGroupForFullUpdate();
+ }
+ }
+ }
+
private SceneObjectPart m_PlaySoundMasterPrim = null;
public SceneObjectPart PlaySoundMasterPrim
{
@@ -3161,14 +3200,6 @@ namespace OpenSim.Region.Framework.Scenes
}
}
-/*
- RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
- for (int i = 0; i < parts.Length; i++)
- {
- if (parts[i] != RootPart)
- parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
- }
-*/
if (parts.Length > 1)
{
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
@@ -3185,7 +3216,6 @@ namespace OpenSim.Region.Framework.Scenes
}
else
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
-
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 0f7959d825..37b555426d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -304,6 +304,9 @@ namespace OpenSim.Region.Framework.Scenes
protected float m_friction = 0.6f; // wood
protected float m_bounce = 0.5f; // wood
+
+ protected bool m_isSelected = false;
+
///
/// Stores media texture data
///
@@ -577,6 +580,16 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public bool IsSelected
+ {
+ get { return m_isSelected; }
+ set
+ {
+ m_isSelected = value;
+ if (ParentGroup != null)
+ ParentGroup.PartSelectChanged(value);
+ }
+ }
public Dictionary CollisionFilter
@@ -1907,6 +1920,7 @@ namespace OpenSim.Region.Framework.Scenes
dupe.m_rezzed = m_rezzed;
dupe.m_UndoRedo = null;
+ dupe.m_isSelected = false;
dupe.IgnoreUndoUpdate = false;
dupe.Undoing = false;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ac791ae6e2..f3f03f5440 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -753,9 +753,10 @@ namespace OpenSim.Region.Framework.Scenes
if (m_movementAnimationUpdateCounter >= 2)
{
m_movementAnimationUpdateCounter = 0;
- if (Animator != null && ParentID == 0) // skip it if sitting
+ if (Animator != null)
{
- Animator.UpdateMovementAnimations();
+ if(ParentID == 0) // skip it if sitting
+ Animator.UpdateMovementAnimations();
}
else
{
@@ -1400,6 +1401,7 @@ namespace OpenSim.Region.Framework.Scenes
{
// Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
// m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
+
Vector3 posAdjusted = AbsolutePosition + HEAD_ADJUSTMENT;
Vector3 distTocam = CameraPosition - posAdjusted;
float distTocamlen = distTocam.Length();
@@ -1408,6 +1410,7 @@ namespace OpenSim.Region.Framework.Scenes
distTocam *= 1.0f / distTocamlen;
m_scene.PhysicsScene.RaycastWorld(posAdjusted, distTocam, distTocamlen + 0.3f, RayCastCameraCallback);
}
+
}
}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index ec4be58361..6ffcb9e145 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -686,6 +686,9 @@ namespace OpenSim.Region.Physics.OdePlugin
Body = d.BodyCreate(_parent_scene.world);
+ _zeroFlag = false;
+ m_pidControllerActive = true;
+
d.BodySetAutoDisableFlag(Body, false);
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
@@ -862,12 +865,12 @@ namespace OpenSim.Region.Physics.OdePlugin
float depth = terrainheight - chrminZ;
if (!flying)
{
- vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 60;
+ vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 50;
}
else
- vec.Z = depth * PID_P * 60;
+ vec.Z = depth * PID_P * 50;
- if (depth < 0.2f)
+ if (depth < 0.1f)
{
m_iscolliding = true;
m_colliderfilter = 2;
@@ -1009,9 +1012,17 @@ namespace OpenSim.Region.Physics.OdePlugin
// update our local ideia of position velocity and aceleration
_position = localpos;
- _acceleration = _velocity; // previus velocity
- _velocity = vel;
- _acceleration = (vel - _acceleration) / timeStep;
+ if (_zeroFlag)
+ {
+ _velocity = Vector3.Zero;
+ _acceleration = Vector3.Zero;
+ }
+ else
+ {
+ _acceleration = _velocity; // previus velocity
+ _velocity = vel;
+ _acceleration = (vel - _acceleration) / timeStep;
+ }
}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 5467b9f85e..dc6c18d220 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -68,9 +68,17 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_fakeisphysical;
private bool m_isphantom;
private bool m_fakeisphantom;
+ internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
+ private bool m_fakeisVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
protected bool m_building;
protected bool m_forcePosOrRotation;
+ private bool m_iscolliding;
+
+ internal bool m_isSelected;
+ private bool m_delaySelect;
+ private bool m_lastdoneSelected;
+ internal bool m_outbounds;
private Quaternion m_lastorientation = new Quaternion();
private Quaternion _orientation;
@@ -90,10 +98,12 @@ namespace OpenSim.Region.Physics.OdePlugin
private Vector3 m_forceacc;
private Vector3 m_angularForceacc;
+ private float m_invTimeStep = 50.0f;
+ private float m_timeStep = .02f;
+
+
private Vector3 m_PIDTarget;
private float m_PIDTau;
- private float PID_D = 35f;
- private float PID_G = 25f;
private bool m_usePID;
// KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
@@ -153,14 +163,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private List childrenPrim = new List();
- private bool m_iscolliding;
-
- public bool m_isSelected;
- private bool m_delaySelect;
- private bool m_lastdoneSelected;
- public bool m_outbounds;
-
- internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
private bool m_throttleUpdates;
private int throttleCounter;
@@ -223,9 +225,12 @@ namespace OpenSim.Region.Physics.OdePlugin
public override bool IsVolumeDtc
{
- set { return; }
- get { return m_isVolumeDetect; }
-
+ get { return m_fakeisVolumeDetect; }
+ set
+ {
+ m_fakeisVolumeDetect = value;
+ AddChange(changes.VolumeDtc, value);
+ }
}
@@ -234,10 +239,7 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return m_fakeisphantom; }
set
{
- m_fakeisphantom = value; // we show imediatly to outside that we changed physical
- // and also to stop imediatly some updates
- // but real change will only happen in taintprocessing
-
+ m_fakeisphantom = value;
AddChange(changes.Phantom, value);
}
}
@@ -427,7 +429,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SetVolumeDetect(int param)
{
- AddChange(changes.VolumeDtc, (param != 0));
+ m_fakeisVolumeDetect = (param != 0);
+ AddChange(changes.VolumeDtc, m_fakeisVolumeDetect);
}
public override Vector3 GeometricCenter
@@ -631,7 +634,6 @@ namespace OpenSim.Region.Physics.OdePlugin
Vector3 pv = Vector3.Zero;
if (_zeroFlag)
return pv;
- m_lastUpdateSent = false;
if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f))
return pv;
@@ -685,12 +687,50 @@ namespace OpenSim.Region.Physics.OdePlugin
}
public override bool PIDActive { set { m_usePID = value; } }
- public override float PIDTau { set { m_PIDTau = value; } }
+ public override float PIDTau
+ {
+ set
+ {
+ if (value <= 0)
+ m_PIDTau = 0;
+ else
+ {
+ float mint = (0.05f > m_timeStep ? 0.05f : m_timeStep);
+ if (value < mint)
+ m_PIDTau = mint;
+ else
+ m_PIDTau = value;
+ }
+ }
+ }
- public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
+ public override float PIDHoverHeight
+ {
+ set
+ {
+ m_PIDHoverHeight = value;
+ if (value == 0)
+ m_useHoverPID = false;
+ }
+ }
public override bool PIDHoverActive { set { m_useHoverPID = value; } }
public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
- public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
+ public override float PIDHoverTau
+ {
+ set
+ {
+ if (value <= 0)
+ m_PIDHoverTau = 0;
+ else
+ {
+ float mint = (0.05f > m_timeStep ? 0.05f : m_timeStep);
+ if (value < mint)
+ m_PIDHoverTau = mint;
+ else
+ m_PIDHoverTau = value;
+ }
+ }
+ }
public override Quaternion APIDTarget { set { return; } }
@@ -761,7 +801,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (force.IsFinite())
{
- AddChange(changes.AddForce, force / _parent_scene.ODE_STEPSIZE);
+ AddChange(changes.AddForce, force * m_invTimeStep);
}
else
{
@@ -774,7 +814,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (force.IsFinite())
{
- AddChange(changes.AddAngForce, force / _parent_scene.ODE_STEPSIZE);
+ AddChange(changes.AddAngForce, force * m_invTimeStep);
}
else
{
@@ -911,8 +951,9 @@ namespace OpenSim.Region.Physics.OdePlugin
_position = pos;
givefakepos = 0;
- PID_D = parent_scene.bodyPIDD;
- PID_G = parent_scene.bodyPIDG;
+ m_timeStep = parent_scene.ODE_STEPSIZE;
+ m_invTimeStep = 1f / m_timeStep;
+
m_density = parent_scene.geomDefaultDensity;
// m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
@@ -958,6 +999,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_fakeisphysical = m_isphysical;
m_isVolumeDetect = false;
+ m_fakeisVolumeDetect = false;
m_force = Vector3.Zero;
@@ -1066,7 +1108,7 @@ namespace OpenSim.Region.Physics.OdePlugin
prm.m_collisionCategories = CollisionCategories.Selected;
prm.m_collisionFlags = 0;
}
- else if (prm.IsVolumeDtc)
+ else if (prm.m_isVolumeDetect)
{
prm.m_collisionCategories = CollisionCategories.VolumeDtc;
if (m_isphysical)
@@ -1445,14 +1487,14 @@ namespace OpenSim.Region.Physics.OdePlugin
hasOOBoffsetFromMesh = false;
CalcPrimBodyData();
}
-
+/*
private void ChildSetGeom(OdePrim odePrim)
{
// well..
DestroyBody();
MakeBody();
}
-
+*/
//sets non physical prim m_targetSpace to right space in spaces grid for static prims
// should only be called for non physical prims unless they are becoming non physical
private void SetInStaticSpace(OdePrim prim)
@@ -2650,6 +2692,31 @@ namespace OpenSim.Region.Physics.OdePlugin
ApplyCollisionCatFlags();
}
+/* not in use
+ internal void ChildSelectedChange(bool childSelect)
+ {
+ if(childPrim)
+ return;
+
+ if (childSelect == m_isSelected)
+ return;
+
+ if (childSelect)
+ {
+ DoSelectedStatus(true);
+ }
+
+ else
+ {
+ foreach (OdePrim prm in childrenPrim)
+ {
+ if (prm.m_isSelected)
+ return;
+ }
+ DoSelectedStatus(false);
+ }
+ }
+*/
private void changeSelectedStatus(bool newval)
{
if (m_lastdoneSelected == newval)
@@ -2706,6 +2773,9 @@ namespace OpenSim.Region.Physics.OdePlugin
prm.m_delaySelect = false;
}
}
+// else if (_parent != null)
+// ((OdePrim)_parent).ChildSelectedChange(true);
+
if (prim_geom != null)
{
@@ -2741,8 +2811,13 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- if (!childPrim && Body != IntPtr.Zero && !m_disabled)
- d.BodyEnable(Body);
+ if (!childPrim)
+ {
+ if (Body != IntPtr.Zero && !m_disabled)
+ d.BodyEnable(Body);
+ }
+// else if (_parent != null)
+// ((OdePrim)_parent).ChildSelectedChange(false);
UpdateCollisionCatFlags();
ApplyCollisionCatFlags();
@@ -2929,7 +3004,6 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakeori--;
if (givefakeori < 0)
givefakeori = 0;
-
resetCollisionAccounting();
}
@@ -3084,9 +3158,10 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodyEnable(Body);
}
- private void changeAddForce(Vector3 force)
+
+ private void changeAddImpulse(Vector3 impulse)
{
- m_forceacc += force;
+ m_forceacc += impulse * m_invTimeStep;
if (!m_isSelected)
{
lock (this)
@@ -3105,9 +3180,10 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
- private void changeAddAngularForce(Vector3 aforce)
+ // actually angular impulse
+ private void changeAddAngularImpulse(Vector3 aimpulse)
{
- m_angularForceacc += aforce;
+ m_angularForceacc += aimpulse * m_invTimeStep;
if (!m_isSelected)
{
lock (this)
@@ -3145,6 +3221,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private void changeVolumedetetion(bool newVolDtc)
{
m_isVolumeDetect = newVolDtc;
+ m_fakeisVolumeDetect = newVolDtc;
UpdateCollisionCatFlags();
ApplyCollisionCatFlags();
}
@@ -3229,315 +3306,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
!m_disabled && !m_isSelected && !m_building && !m_outbounds)
{
- if (d.BodyIsEnabled(Body))
- {
- float timestep = _parent_scene.ODE_STEPSIZE;
-
- // check outside region
- d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator
-
- if (lpos.Z < -100 || lpos.Z > 100000f)
- {
- m_outbounds = true;
-
- lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
- _acceleration.X = 0;
- _acceleration.Y = 0;
- _acceleration.Z = 0;
-
- _velocity.X = 0;
- _velocity.Y = 0;
- _velocity.Z = 0;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
-
- d.BodySetLinearVel(Body, 0, 0, 0); // stop it
- d.BodySetAngularVel(Body, 0, 0, 0); // stop it
- d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
- m_lastposition = _position;
- m_lastorientation = _orientation;
-
- base.RequestPhysicsterseUpdate();
-
- m_throttleUpdates = false;
- throttleCounter = 0;
- _zeroFlag = true;
-
- disableBodySoft(); // disable it and colisions
- base.RaiseOutOfBounds(_position);
- return;
- }
-
- if (lpos.X < 0f)
- {
- _position.X = Util.Clip(lpos.X, -2f, -0.1f);
- m_outbounds = true;
- }
- else if (lpos.X > _parent_scene.WorldExtents.X)
- {
- _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
- m_outbounds = true;
- }
- if (lpos.Y < 0f)
- {
- _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
- m_outbounds = true;
- }
- else if (lpos.Y > _parent_scene.WorldExtents.Y)
- {
- _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
- m_outbounds = true;
- }
-
- if (m_outbounds)
- {
- m_lastposition = _position;
- m_lastorientation = _orientation;
-
- d.Vector3 dtmp = d.BodyGetAngularVel(Body);
- m_rotationalVelocity.X = dtmp.X;
- m_rotationalVelocity.Y = dtmp.Y;
- m_rotationalVelocity.Z = dtmp.Z;
-
- dtmp = d.BodyGetLinearVel(Body);
- _velocity.X = dtmp.X;
- _velocity.Y = dtmp.Y;
- _velocity.Z = dtmp.Z;
-
- d.BodySetLinearVel(Body, 0, 0, 0); // stop it
- d.BodySetAngularVel(Body, 0, 0, 0);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- disableBodySoft(); // stop collisions
- base.RequestPhysicsterseUpdate();
- return;
- }
-
- if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
- {
- // 'VEHICLES' are dealt with in ODEDynamics.cs
- m_vehicle.Step();
- }
- else
- {
- float fx = 0;
- float fy = 0;
- float fz = 0;
-
- float m_mass = _mass;
-
- // fz = 0f;
- //m_log.Info(m_collisionFlags.ToString());
- if (m_usePID)
- {
-
- // If the PID Controller isn't active then we set our force
- // calculating base velocity to the current position
-
- if ((m_PIDTau < 1) && (m_PIDTau != 0))
- {
- //PID_G = PID_G / m_PIDTau;
- m_PIDTau = 1;
- }
-
- if ((PID_G - m_PIDTau) <= 0)
- {
- PID_G = m_PIDTau + 1;
- }
-
- d.Vector3 vel = d.BodyGetLinearVel(Body);
- d.Vector3 pos = d.BodyGetPosition(Body);
- _target_velocity =
- new Vector3(
- (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
- (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
- (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
- );
-
- // if velocity is zero, use position control; otherwise, velocity control
-
- if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
- {
- // keep track of where we stopped. No more slippin' & slidin'
-
- // We only want to deactivate the PID Controller if we think we want to have our surrogate
- // react to the physics scene by moving it's position.
- // Avatar to Avatar collisions
- // Prim to avatar collisions
-
- //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
- //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
- //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
- d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
- d.BodySetLinearVel(Body, 0, 0, 0);
- d.BodyAddForce(Body, 0, 0, fz);
- return;
- }
- else
- {
- _zeroFlag = false;
-
- // We're flying and colliding with something
- fx = ((_target_velocity.X) - vel.X) * (PID_D);
- fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
-
- // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
-
- fz = ((_target_velocity.Z - vel.Z) * (PID_D));
- }
- } // end if (m_usePID)
-
- // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller
- else if (m_useHoverPID)
- {
- //Console.WriteLine("Hover " + Name);
-
- // If we're using the PID controller, then we have no gravity
-
- // no lock; for now it's only called from within Simulate()
-
- // If the PID Controller isn't active then we set our force
- // calculating base velocity to the current position
-
- if ((m_PIDTau < 1))
- {
- PID_G = PID_G / m_PIDTau;
- }
-
- if ((PID_G - m_PIDTau) <= 0)
- {
- PID_G = m_PIDTau + 1;
- }
-
- // Where are we, and where are we headed?
- d.Vector3 pos = d.BodyGetPosition(Body);
- d.Vector3 vel = d.BodyGetLinearVel(Body);
-
- // Non-Vehicles have a limited set of Hover options.
- // determine what our target height really is based on HoverType
- switch (m_PIDHoverType)
- {
- case PIDHoverType.Ground:
- m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
- m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
- break;
- case PIDHoverType.GroundAndWater:
- m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
- m_waterHeight = _parent_scene.GetWaterLevel();
- if (m_groundHeight > m_waterHeight)
- {
- m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
- }
- else
- {
- m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
- }
- break;
-
- } // end switch (m_PIDHoverType)
-
-
- _target_velocity =
- new Vector3(0.0f, 0.0f,
- (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep)
- );
-
- // if velocity is zero, use position control; otherwise, velocity control
-
- if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
- {
- // keep track of where we stopped. No more slippin' & slidin'
-
- // We only want to deactivate the PID Controller if we think we want to have our surrogate
- // react to the physics scene by moving it's position.
- // Avatar to Avatar collisions
- // Prim to avatar collisions
-
- d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
- d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
- // ? d.BodyAddForce(Body, 0, 0, fz);
- return;
- }
- else
- {
- _zeroFlag = false;
-
- // We're flying and colliding with something
- fz = ((_target_velocity.Z - vel.Z) * (PID_D));
- }
- }
- else
- {
- float b = (1.0f - m_buoyancy);
- fx = _parent_scene.gravityx * b;
- fy = _parent_scene.gravityy * b;
- fz = _parent_scene.gravityz * b;
- }
-
- fx *= m_mass;
- fy *= m_mass;
- fz *= m_mass;
-
- // constant force
- fx += m_force.X;
- fy += m_force.Y;
- fz += m_force.Z;
-
- fx += m_forceacc.X;
- fy += m_forceacc.Y;
- fz += m_forceacc.Z;
-
- m_forceacc = Vector3.Zero;
-
- //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
- if (fx != 0 || fy != 0 || fz != 0)
- {
- d.BodyAddForce(Body, fx, fy, fz);
- //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz);
- }
-
- Vector3 trq;
-
- trq = _torque;
- trq += m_angularForceacc;
- m_angularForceacc = Vector3.Zero;
- if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
- {
- d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
- }
- }
-
- // update our ideia of velocities and acelerations
- d.Quaternion ori;
- d.Vector3 dtmpu;
-
- _position.X = lpos.X;
- _position.Y = lpos.Y;
- _position.Z = lpos.Z;
-
- d.GeomCopyQuaternion(prim_geom, out ori);
- _orientation.X = ori.X;
- _orientation.Y = ori.Y;
- _orientation.Z = ori.Z;
- _orientation.W = ori.W;
-
- _acceleration = _velocity;
-
- dtmpu = d.BodyGetLinearVel(Body);
- _velocity.X = dtmpu.X;
- _velocity.Y = dtmpu.Y;
- _velocity.Z = dtmpu.Z;
-
- float invts = 1 / timestep;
- _acceleration = (_velocity - _acceleration) * invts;
-
- dtmpu = d.BodyGetAngularVel(Body);
- m_rotationalVelocity.X = dtmpu.X;
- m_rotationalVelocity.Y = dtmpu.Y;
- m_rotationalVelocity.Z = dtmpu.Z;
- }
-
- else // body disabled/sleeping
+ if (!d.BodyIsEnabled(Body))
{
// let vehicles sleep
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
@@ -3548,8 +3317,236 @@ namespace OpenSim.Region.Physics.OdePlugin
bodydisablecontrol = 0;
d.BodyEnable(Body);
+ }
+
+ // check outside region
+ d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator
+
+ if (lpos.Z < -100 || lpos.Z > 100000f)
+ {
+ m_outbounds = true;
+
+ lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
+ _acceleration.X = 0;
+ _acceleration.Y = 0;
+ _acceleration.Z = 0;
+
+ _velocity.X = 0;
+ _velocity.Y = 0;
+ _velocity.Z = 0;
+ m_rotationalVelocity.X = 0;
+ m_rotationalVelocity.Y = 0;
+ m_rotationalVelocity.Z = 0;
+
+ d.BodySetLinearVel(Body, 0, 0, 0); // stop it
+ d.BodySetAngularVel(Body, 0, 0, 0); // stop it
+ d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
+ m_lastposition = _position;
+ m_lastorientation = _orientation;
+
+ base.RequestPhysicsterseUpdate();
+
+ throttleCounter = 0;
+ _zeroFlag = true;
+
+ disableBodySoft(); // disable it and colisions
+ base.RaiseOutOfBounds(_position);
return;
}
+
+ if (lpos.X < 0f)
+ {
+ _position.X = Util.Clip(lpos.X, -2f, -0.1f);
+ m_outbounds = true;
+ }
+ else if (lpos.X > _parent_scene.WorldExtents.X)
+ {
+ _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
+ m_outbounds = true;
+ }
+ if (lpos.Y < 0f)
+ {
+ _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
+ m_outbounds = true;
+ }
+ else if (lpos.Y > _parent_scene.WorldExtents.Y)
+ {
+ _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
+ m_outbounds = true;
+ }
+
+ if (m_outbounds)
+ {
+ m_lastposition = _position;
+ m_lastorientation = _orientation;
+
+ d.Vector3 dtmp = d.BodyGetAngularVel(Body);
+ m_rotationalVelocity.X = dtmp.X;
+ m_rotationalVelocity.Y = dtmp.Y;
+ m_rotationalVelocity.Z = dtmp.Z;
+
+ dtmp = d.BodyGetLinearVel(Body);
+ _velocity.X = dtmp.X;
+ _velocity.Y = dtmp.Y;
+ _velocity.Z = dtmp.Z;
+
+ d.BodySetLinearVel(Body, 0, 0, 0); // stop it
+ d.BodySetAngularVel(Body, 0, 0, 0);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ disableBodySoft(); // stop collisions
+ base.RequestPhysicsterseUpdate();
+ return;
+ }
+
+ if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
+ {
+ // 'VEHICLES' are dealt with in ODEDynamics.cs
+ m_vehicle.Step();
+ return;
+ }
+
+ float fx = 0;
+ float fy = 0;
+ float fz = 0;
+
+ float m_mass = _mass;
+
+ if (m_usePID && m_PIDTau > 0)
+ {
+ // for now position error
+ _target_velocity =
+ new Vector3(
+ (m_PIDTarget.X - lpos.X),
+ (m_PIDTarget.Y - lpos.Y),
+ (m_PIDTarget.Z - lpos.Z)
+ );
+
+ if (_target_velocity.ApproxEquals(Vector3.Zero, 0.02f))
+ {
+ d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
+ d.BodySetLinearVel(Body, 0, 0, 0);
+ return;
+ }
+ else
+ {
+ _zeroFlag = false;
+
+ float tmp = 1 / m_PIDTau;
+ _target_velocity *= tmp;
+
+ // apply limits
+ tmp = _target_velocity.Length();
+ if (tmp > 50.0f)
+ {
+ tmp = 50 / tmp;
+ _target_velocity *= tmp;
+ }
+ else if (tmp < 0.05f)
+ {
+ tmp = 0.05f / tmp;
+ _target_velocity *= tmp;
+ }
+
+ d.Vector3 vel = d.BodyGetLinearVel(Body);
+ fx = (_target_velocity.X - vel.X) * m_invTimeStep;
+ fy = (_target_velocity.Y - vel.Y) * m_invTimeStep;
+ fz = (_target_velocity.Z - vel.Z) * m_invTimeStep;
+ }
+ } // end if (m_usePID)
+
+ // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller
+ else if (m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0)
+ {
+
+ // Non-Vehicles have a limited set of Hover options.
+ // determine what our target height really is based on HoverType
+
+ m_groundHeight = _parent_scene.GetTerrainHeightAtXY(lpos.X, lpos.Y);
+
+ switch (m_PIDHoverType)
+ {
+ case PIDHoverType.Ground:
+ m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
+ break;
+
+ case PIDHoverType.GroundAndWater:
+ m_waterHeight = _parent_scene.GetWaterLevel();
+ if (m_groundHeight > m_waterHeight)
+ m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
+ else
+ m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
+ break;
+ } // end switch (m_PIDHoverType)
+
+ // don't go underground unless volumedetector
+
+ if (m_targetHoverHeight > m_groundHeight || m_isVolumeDetect)
+ {
+ d.Vector3 vel = d.BodyGetLinearVel(Body);
+
+ fz = (m_targetHoverHeight - lpos.Z);
+
+ // if error is zero, use position control; otherwise, velocity control
+ if (Math.Abs(fz) < 0.01f)
+ {
+ d.BodySetPosition(Body, lpos.X, lpos.Y, m_targetHoverHeight);
+ d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
+ return;
+ }
+ else
+ {
+ _zeroFlag = false;
+ fz /= m_PIDHoverTau;
+
+ float tmp = Math.Abs(fz);
+ if (tmp > 50)
+ fz = 50 * Math.Sign(fz);
+ else if (tmp < 0.1)
+ fz = 0.1f * Math.Sign(fz);
+
+ fz = ((fz - vel.Z) * m_invTimeStep);
+ }
+ }
+ }
+ else
+ {
+ float b = (1.0f - m_buoyancy);
+ fx = _parent_scene.gravityx * b;
+ fy = _parent_scene.gravityy * b;
+ fz = _parent_scene.gravityz * b;
+ }
+
+ fx *= m_mass;
+ fy *= m_mass;
+ fz *= m_mass;
+
+ // constant force
+ fx += m_force.X;
+ fy += m_force.Y;
+ fz += m_force.Z;
+
+ fx += m_forceacc.X;
+ fy += m_forceacc.Y;
+ fz += m_forceacc.Z;
+
+ m_forceacc = Vector3.Zero;
+
+ //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
+ if (fx != 0 || fy != 0 || fz != 0)
+ {
+ d.BodyAddForce(Body, fx, fy, fz);
+ //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz);
+ }
+
+ Vector3 trq;
+
+ trq = _torque;
+ trq += m_angularForceacc;
+ m_angularForceacc = Vector3.Zero;
+ if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
+ {
+ d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
+ }
}
else
{ // is not physical, or is not a body or is selected
@@ -3560,92 +3557,113 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
-
- public void UpdatePositionAndVelocity(float simulatedtime)
+ public void UpdatePositionAndVelocity()
{
- // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
- if (_parent == null && !m_disabled && !m_building && !m_outbounds)
+ if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero)
{
- if (Body != IntPtr.Zero)
+ if (d.BodyIsEnabled(Body) || !_zeroFlag)
{
bool lastZeroFlag = _zeroFlag;
- if ((Math.Abs(m_lastposition.X - _position.X) < 0.01)
- && (Math.Abs(m_lastposition.Y - _position.Y) < 0.01)
- && (Math.Abs(m_lastposition.Z - _position.Z) < 0.01)
- && (Math.Abs(m_lastorientation.X - _orientation.X) < 0.0001)
- && (Math.Abs(m_lastorientation.Y - _orientation.Y) < 0.0001)
- && (Math.Abs(m_lastorientation.Z - _orientation.Z) < 0.0001)
+ d.Vector3 lpos;
+ d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
+
+ d.Quaternion ori;
+ d.GeomCopyQuaternion(prim_geom, out ori);
+
+ // decide if moving
+ // use positions since this are integrated quantities
+ // tolerance values depende a lot on simulation noise...
+ // use simple math.abs since we dont need to be exact
+
+ if (
+ (Math.Abs(_position.X - lpos.X) < 0.001f)
+ && (Math.Abs(_position.Y - lpos.Y) < 0.001f)
+ && (Math.Abs(_position.Z - lpos.Z) < 0.001f)
+ && (Math.Abs(_orientation.X - ori.X) < 0.0001f)
+ && (Math.Abs(_orientation.Y - ori.Y) < 0.0001f)
+ && (Math.Abs(_orientation.Z - ori.Z) < 0.0001f) // ignore W
)
{
_zeroFlag = true;
- m_throttleUpdates = false;
}
else
- {
_zeroFlag = false;
- m_lastUpdateSent = false;
+
+ // update velocities and aceleration
+ if (!(_zeroFlag && lastZeroFlag))
+ {
+ d.Vector3 vel = d.BodyGetLinearVel(Body);
+
+ _acceleration = _velocity;
+
+ if ((Math.Abs(vel.X) < 0.001f) &&
+ (Math.Abs(vel.Y) < 0.001f) &&
+ (Math.Abs(vel.Z) < 0.001f))
+ {
+ _velocity = Vector3.Zero;
+ float t = -m_invTimeStep;
+ _acceleration = _acceleration * t;
+ }
+ else
+ {
+ _velocity.X = vel.X;
+ _velocity.Y = vel.Y;
+ _velocity.Z = vel.Z;
+ _acceleration = (_velocity - _acceleration) * m_invTimeStep;
+ }
+
+ if ((Math.Abs(_acceleration.X) < 0.01f) &&
+ (Math.Abs(_acceleration.Y) < 0.01f) &&
+ (Math.Abs(_acceleration.Z) < 0.01f))
+ {
+ _acceleration = Vector3.Zero;
+ }
+
+ if ((Math.Abs(_orientation.X - ori.X) < 0.0001) &&
+ (Math.Abs(_orientation.Y - ori.Y) < 0.0001) &&
+ (Math.Abs(_orientation.Z - ori.Z) < 0.0001)
+ )
+ {
+ m_rotationalVelocity = Vector3.Zero;
+ }
+ else
+ {
+ vel = d.BodyGetAngularVel(Body);
+ m_rotationalVelocity.X = vel.X;
+ m_rotationalVelocity.Y = vel.Y;
+ m_rotationalVelocity.Z = vel.Z;
+ }
}
if (_zeroFlag)
{
- m_lastposition = _position;
- m_lastorientation = _orientation;
-
- _velocity = Vector3.Zero;
- _acceleration = Vector3.Zero;
- m_rotationalVelocity = Vector3.Zero;
+ if (lastZeroFlag)
+ {
+ _velocity = Vector3.Zero;
+ _acceleration = Vector3.Zero;
+ m_rotationalVelocity = Vector3.Zero;
+ }
if (!m_lastUpdateSent)
{
- m_throttleUpdates = false;
- throttleCounter = 0;
-
base.RequestPhysicsterseUpdate();
-
- m_lastUpdateSent = true;
+ if (lastZeroFlag)
+ m_lastUpdateSent = true;
}
+ return;
}
- else
- {
- if (lastZeroFlag != _zeroFlag)
- {
- base.RequestPhysicsterseUpdate();
- }
- m_lastUpdateSent = false;
- if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate)
- {
- m_lastposition = _position;
- m_lastorientation = _orientation;
- m_lastVelocity = _velocity;
- base.RequestPhysicsterseUpdate();
- }
- else
- {
- throttleCounter++;
- }
- }
- }
- else if (!m_lastUpdateSent || !_zeroFlag)
- {
- // Not a body.. so Make sure the client isn't interpolating
- _velocity = Vector3.Zero;
- _acceleration = Vector3.Zero;
- m_rotationalVelocity = Vector3.Zero;
- m_lastVelocity = Vector3.Zero;
+ _position.X = lpos.X;
+ _position.Y = lpos.Y;
+ _position.Z = lpos.Z;
- _zeroFlag = true;
-
- if (!m_lastUpdateSent)
- {
- m_throttleUpdates = false;
- throttleCounter = 0;
-
- base.RequestPhysicsterseUpdate();
-
- m_lastUpdateSent = true;
- }
+ _orientation.X = ori.X;
+ _orientation.Y = ori.Y;
+ _orientation.Z = ori.Z;
+ _orientation.W = ori.W;
+ base.RequestPhysicsterseUpdate();
+ m_lastUpdateSent = false;
}
}
}
@@ -3803,11 +3821,11 @@ namespace OpenSim.Region.Physics.OdePlugin
break;
case changes.AddForce:
- changeAddForce((Vector3)arg);
+ changeAddImpulse((Vector3)arg);
break;
case changes.AddAngForce:
- changeAddAngularForce((Vector3)arg);
+ changeAddAngularImpulse((Vector3)arg);
break;
case changes.AngLock:
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 9ca2d3f29b..cf74f14a60 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -189,9 +189,12 @@ namespace OpenSim.Region.Physics.OdePlugin
private const uint m_regionHeight = Constants.RegionSize;
public float ODE_STEPSIZE = 0.020f;
+ public float HalfOdeStep = 0.01f;
private float metersInSpace = 25.6f;
private float m_timeDilation = 1.0f;
+ DateTime m_lastframe;
+
public float gravityx = 0f;
public float gravityy = 0f;
public float gravityz = -9.8f;
@@ -485,6 +488,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ HalfOdeStep = ODE_STEPSIZE * 0.5f;
+
ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf);
@@ -521,7 +526,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldSetAngularDamping(world, 0.001f);
d.WorldSetAngularDampingThreshold(world, 0f);
d.WorldSetLinearDampingThreshold(world, 0f);
- d.WorldSetMaxAngularSpeed(world, 256f);
+ d.WorldSetMaxAngularSpeed(world, 100f);
d.WorldSetCFM(world,1e-6f); // a bit harder than default
//d.WorldSetCFM(world, 1e-4f); // a bit harder than default
@@ -564,6 +569,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// let this now be real maximum values
spaceGridMaxX--;
spaceGridMaxY--;
+ m_lastframe = DateTime.UtcNow;
}
internal void waitForSpaceUnlock(IntPtr space)
@@ -1685,35 +1691,30 @@ namespace OpenSim.Region.Physics.OdePlugin
///
public override float Simulate(float timeStep)
{
- int statstart;
- int statchanges = 0;
- int statchmove = 0;
- int statactmove = 0;
- int statray = 0;
- int statcol = 0;
- int statstep = 0;
- int statmovchar = 0;
- int statmovprim;
- int totjcontact = 0;
+ DateTime now = DateTime.UtcNow;
+ TimeSpan SinceLastFrame = now - m_lastframe;
+ m_lastframe = now;
+ timeStep = (float)SinceLastFrame.TotalSeconds;
+
// acumulate time so we can reduce error
step_time += timeStep;
- if (step_time < ODE_STEPSIZE)
+ if (step_time < HalfOdeStep)
return 0;
- if (framecount >= int.MaxValue)
+ if (framecount < 0)
framecount = 0;
framecount++;
- int curphysiteractions = m_physicsiterations;
+ int curphysiteractions;
+ // if in trouble reduce step resolution
if (step_time >= m_SkipFramesAtms)
- {
- // if in trouble reduce step resolution
- curphysiteractions /= 2;
- }
+ curphysiteractions = m_physicsiterations / 2;
+ else
+ curphysiteractions = m_physicsiterations;
int nodeframes = 0;
@@ -1733,13 +1734,10 @@ namespace OpenSim.Region.Physics.OdePlugin
base.TriggerPhysicsBasedRestart();
}
-
- while (step_time >= ODE_STEPSIZE && nodeframes < 10) //limit number of steps so we don't say here for ever
+ while (step_time >= HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
{
try
{
- statstart = Util.EnvironmentTickCount();
-
// clear pointer/counter to contacts to pass into joints
m_global_contactcount = 0;
@@ -1778,17 +1776,39 @@ namespace OpenSim.Region.Physics.OdePlugin
}
- statchanges += Util.EnvironmentTickCountSubtract(statstart);
+ // Move characters
+ lock (_characters)
+ {
+ List defects = new List();
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ actor.Move(ODE_STEPSIZE, defects);
+ }
+ if (defects.Count != 0)
+ {
+ foreach (OdeCharacter defect in defects)
+ {
+ RemoveCharacter(defect);
+ }
+ }
+ }
+
+ // Move other active objects
+ lock (_activegroups)
+ {
+ foreach (OdePrim aprim in _activegroups)
+ {
+ aprim.Move();
+ }
+ }
- statactmove += Util.EnvironmentTickCountSubtract(statstart);
//if ((framecount % m_randomizeWater) == 0)
// randomizeWater(waterlevel);
m_rayCastManager.ProcessQueuedRequests();
- statray += Util.EnvironmentTickCountSubtract(statstart);
collision_optimized();
- statcol += Util.EnvironmentTickCountSubtract(statstart);
lock (_collisionEventPrim)
{
@@ -1813,38 +1833,39 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ // do a ode simulation step
d.WorldQuickStep(world, ODE_STEPSIZE);
- statstep += Util.EnvironmentTickCountSubtract(statstart);
+ d.JointGroupEmpty(contactgroup);
- // Move characters
- lock (_characters)
+ // update managed ideia of physical data and do updates to core
+ /*
+ lock (_characters)
+ {
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ {
+ if (actor.bad)
+ m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
+
+ actor.UpdatePositionAndVelocity();
+ }
+ }
+ }
+ */
+
+ lock (_activegroups)
{
- List defects = new List();
- foreach (OdeCharacter actor in _characters)
{
- if (actor != null)
- actor.Move(ODE_STEPSIZE, defects);
- }
- if (defects.Count != 0)
- {
- foreach (OdeCharacter defect in defects)
+ foreach (OdePrim actor in _activegroups)
{
- RemoveCharacter(defect);
+ if (actor.IsPhysical)
+ {
+ actor.UpdatePositionAndVelocity();
+ }
}
}
}
- statchmove += Util.EnvironmentTickCountSubtract(statstart);
-
- // Move other active objects
- lock (_activegroups)
- {
- foreach (OdePrim aprim in _activegroups)
- {
- aprim.Move();
- }
- }
-
- //ode.dunlock(world);
}
catch (Exception e)
{
@@ -1852,32 +1873,11 @@ namespace OpenSim.Region.Physics.OdePlugin
// ode.dunlock(world);
}
- d.JointGroupEmpty(contactgroup);
- totjcontact += m_global_contactcount;
step_time -= ODE_STEPSIZE;
nodeframes++;
}
- statstart = Util.EnvironmentTickCount();
-
-/*
-// now included in characters move() and done at ode rate
-// maybe be needed later if we need to do any extra work at hearbeat rate
- lock (_characters)
- {
- foreach (OdeCharacter actor in _characters)
- {
- if (actor != null)
- {
- if (actor.bad)
- m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
-
- actor.UpdatePositionAndVelocity();
- }
- }
- }
-*/
lock (_badCharacter)
{
if (_badCharacter.Count > 0)
@@ -1890,22 +1890,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_badCharacter.Clear();
}
}
- statmovchar = Util.EnvironmentTickCountSubtract(statstart);
-
- lock (_activegroups)
- {
- {
- foreach (OdePrim actor in _activegroups)
- {
- if (actor.IsPhysical)
- {
- actor.UpdatePositionAndVelocity((float)nodeframes * ODE_STEPSIZE);
- }
- }
- }
- }
-
- statmovprim = Util.EnvironmentTickCountSubtract(statstart);
int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
@@ -1932,15 +1916,17 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
}
- // think time dilation is not a physics issue alone.. but ok let's fake something
- if (step_time < ODE_STEPSIZE) // we did the required loops
+ // think time dilation as to do with dinamic step size that we dont' have
+ // even so tell something to world
+ if (nodeframes < 10) // we did the requested loops
m_timeDilation = 1.0f;
- else
- { // we didn't forget the lost ones and let user know something
- m_timeDilation = 1 - step_time / timeStep;
- if (m_timeDilation < 0)
- m_timeDilation = 0;
- step_time = 0;
+ else if (step_time > 0)
+ {
+ m_timeDilation = timeStep / step_time;
+ if (m_timeDilation > 1)
+ m_timeDilation = 1;
+ if (step_time > m_SkipFramesAtms)
+ step_time = 0;
}
}
@@ -2007,7 +1993,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else // out world use external height
{
- ix = regsize - 1;
+ ix = regsize - 2;
dx = 0;
}
if (y < regsize - 1)
@@ -2017,7 +2003,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- iy = regsize - 1;
+ iy = regsize - 2;
dy = 0;
}
}
@@ -2034,7 +2020,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else // out world use external height
{
- iy = regsize - 1;
+ iy = regsize - 2;
dy = 0;
}
if (y < regsize - 1)
@@ -2044,7 +2030,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- ix = regsize - 1;
+ ix = regsize - 2;
dx = 0;
}
}
@@ -2057,18 +2043,35 @@ namespace OpenSim.Region.Physics.OdePlugin
iy += ix; // all indexes have iy + ix
float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
+ /*
+ if ((dx + dy) <= 1.0f)
+ {
+ h0 = ((float)heights[iy]); // 0,0 vertice
+ h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
+ h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
+ }
+ else
+ {
+ h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
+ h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
+ h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
+ }
+ */
+ h0 = ((float)heights[iy]); // 0,0 vertice
- if ((dx + dy) <= 1.0f)
+ if ((dy > dx))
{
- h0 = ((float)heights[iy]); // 0,0 vertice
- h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
- h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
+ iy += regsize;
+ h2 = (float)heights[iy]; // 0,1 vertice
+ h1 = (h2 - h0) * dy; // 0,1 vertice minus 0,0
+ h2 = ((float)heights[iy + 1] - h2) * dx; // 1,1 vertice minus 0,1
}
else
{
- h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
- h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
- h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
+ iy++;
+ h2 = (float)heights[iy]; // vertice 1,0
+ h1 = (h2 - h0) * dx; // 1,0 vertice minus 0,0
+ h2 = (((float)heights[iy + regsize]) - h2) * dy; // 1,1 vertice minus 1,0
}
return h0 + h1 + h2;