diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a34079ccc8..3e08128462 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1891,6 +1891,19 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerPrimsLoaded(this);
}
+ public bool SuportsRayCastFiltered()
+ {
+ if (PhysicsScene == null)
+ return false;
+ return PhysicsScene.SuportsRaycastWorldFiltered();
+ }
+
+ public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
+ {
+ if (PhysicsScene == null)
+ return null;
+ return PhysicsScene.RaycastWorld(position, direction, length, Count,filter);
+ }
///
/// Gets a new rez location based on the raycast and the size of the object that is being rezzed.
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fd7f7d8e1a..7a634c4d6b 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -753,7 +753,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_movementAnimationUpdateCounter >= 2)
{
m_movementAnimationUpdateCounter = 0;
- if (Animator != null)
+ if (Animator != null && ParentID == 0) // skip it if sitting
{
Animator.UpdateMovementAnimations();
}
@@ -1077,10 +1077,13 @@ namespace OpenSim.Region.Framework.Scenes
public void TeleportWithMomentum(Vector3 pos)
{
bool isFlying = Flying;
+ Vector3 vel = Velocity;
RemoveFromPhysicalScene();
CheckLandingPoint(ref pos);
AbsolutePosition = pos;
AddToPhysicalScene(isFlying);
+ if (PhysicsActor != null)
+ PhysicsActor.SetMomentum(vel);
SendTerseUpdateToAllClients();
}
@@ -1385,8 +1388,16 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_followCamAuto)
{
- 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 = 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();
+ if (distTocamlen > 0)
+ {
+ distTocam *= 1.0f / distTocamlen;
+ m_scene.PhysicsScene.RaycastWorld(posAdjusted, distTocam, distTocamlen + 0.3f, RayCastCameraCallback);
+ }
}
}
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
index 2945199faf..ec717d73b0 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
@@ -140,6 +140,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public int m_eventsubscription = 0;
private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
+ private Vector3 m_taintMomentum = Vector3.Zero;
+ private bool m_haveTaintMomentum = false;
+
+
// unique UUID of this character object
public UUID m_uuid;
public bool bad = false;
@@ -800,8 +804,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (value.IsFinite())
{
- m_pidControllerActive = true;
_target_velocity = value;
+ m_pidControllerActive = true;
}
else
{
@@ -911,6 +915,14 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SetMomentum(Vector3 momentum)
{
+ if (momentum.IsFinite())
+ {
+ m_taintMomentum = momentum;
+ m_haveTaintMomentum = true;
+ _parent_scene.AddPhysicsActorTaint(this);
+ }
+ else
+ m_log.Warn("[PHYSICS] !isFinite momentum");
}
@@ -1110,9 +1122,18 @@ namespace OpenSim.Region.Physics.OdePlugin
}
// end add Kitto Flora
}
+
+ if (vel.X * vel.X + vel.Y * vel.Y + vel.Z * vel.Z > 2500.0f) // 50ms apply breaks
+ {
+ float breakfactor = 0.16f * m_mass; // will give aprox 60m/s terminal velocity at free fall
+ vec.X -= breakfactor * vel.X;
+ vec.Y -= breakfactor * vel.Y;
+ vec.Z -= breakfactor * vel.Z;
+ }
+
if (vec.IsFinite())
{
- if (!vec.ApproxEquals(Vector3.Zero, 0.02f)) // 0.01 allows 0.002 !!
+ if (vec.LengthSquared() > 0.0004f) // 0.01 allows 0.002 !!
{
//Console.WriteLine("DF 2"); // ##
@@ -1327,7 +1348,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
lock (m_syncRoot)
{
-
if (m_tainted_isPhysical != m_isPhysical)
{
if (m_tainted_isPhysical)
@@ -1369,9 +1389,9 @@ namespace OpenSim.Region.Physics.OdePlugin
{
d.GeomDestroy(Shell);
}
- catch (System.AccessViolationException)
+ catch (Exception e)
{
- m_log.Error("[PHYSICS]: PrimGeom dead");
+ m_log.ErrorFormat("[PHYSICS]: Failed to destroy character shell {0}",e.Message);
}
// Remove any old entries
//string tShell;
@@ -1418,12 +1438,21 @@ namespace OpenSim.Region.Physics.OdePlugin
{
d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
- _position.X = m_taintPosition.X;
- _position.Y = m_taintPosition.Y;
- _position.Z = m_taintPosition.Z;
}
+ _position.X = m_taintPosition.X;
+ _position.Y = m_taintPosition.Y;
+ _position.Z = m_taintPosition.Z;
}
+ if (m_haveTaintMomentum)
+ {
+ m_haveTaintMomentum = false;
+ _velocity = m_taintMomentum;
+ _target_velocity = m_taintMomentum;
+ m_pidControllerActive = true;
+ if (Body != IntPtr.Zero)
+ d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
+ }
}
}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index be67204454..b66d7f1152 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -172,6 +172,12 @@ namespace OpenSim.Region.Physics.Manager
public virtual bool Phantom { get; set; }
+ public virtual bool IsVolumeDtc
+ {
+ get { return false; }
+ set { return; }
+ }
+
public virtual byte PhysicsShapeType { get; set; }
public abstract PrimitiveBaseShape Shape { set; }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index f2c0c28dc4..d10a2aa29d 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -43,6 +43,34 @@ namespace OpenSim.Region.Physics.Manager
public delegate void JointDeactivated(PhysicsJoint joint);
public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation"
+ public enum RayFilterFlags:ushort
+ {
+ // the flags
+ water = 0x01,
+ land = 0x02,
+ agent = 0x04,
+ nonphysical = 0x08,
+ physical = 0x10,
+ phantom = 0x20,
+ volumedtc = 0x40,
+
+ // ray cast colision control (may only work for meshs)
+ BackFaceCull = 0x4000,
+ ClosestHit = 0x8000,
+
+ // some combinations
+ LSLPhanton = phantom | volumedtc,
+ PrimsNonPhantom = nonphysical | physical,
+ PrimsNonPhantomAgents = nonphysical | physical | agent,
+
+ AllPrims = nonphysical | phantom | volumedtc | physical,
+ AllButLand = agent | nonphysical | physical | phantom | volumedtc,
+
+ ClosestAndBackCull = ClosestHit | BackFaceCull,
+
+ All = 0x3f
+ }
+
///
/// Contact result from a raycast.
///
@@ -54,6 +82,8 @@ namespace OpenSim.Region.Physics.Manager
public Vector3 Normal;
}
+
+
public abstract class PhysicsScene
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -280,6 +310,16 @@ namespace OpenSim.Region.Physics.Manager
return new List();
}
+ public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
+ {
+ return null;
+ }
+
+ public virtual bool SuportsRaycastWorldFiltered()
+ {
+ return false;
+ }
+
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
public virtual List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 75fa1efd45..825b858a92 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -335,7 +335,7 @@ namespace OpenSim.Region.Physics.Meshing
if (primShape.SculptData.Length <= 0)
{
- m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName);
+ m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName);
return false;
}
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index 8e903e83ba..f002bbab45 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -339,7 +339,7 @@ namespace OpenSim.Region.Physics.Meshing
if (primShape.SculptData.Length <= 0)
{
- m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName);
+ m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName);
return false;
}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 4266fdab95..9c1b87bea8 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -115,12 +115,11 @@ namespace OpenSim.Region.Physics.OdePlugin
private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
// Default, Collide with Other Geometries, spaces, bodies and characters.
- private CollisionCategories m_collisionFlags = (CollisionCategories.Geom
- | CollisionCategories.Space
- | CollisionCategories.Body
- | CollisionCategories.Character
+ private CollisionCategories m_collisionFlags = (CollisionCategories.Character
+ | CollisionCategories.Geom
+ | CollisionCategories.VolumeDtc
);
- // we do land collisions not ode | CollisionCategories.Land);
+ // we do land collisions not ode | CollisionCategories.Land);
public IntPtr Body = IntPtr.Zero;
private OdeScene _parent_scene;
public IntPtr Shell = IntPtr.Zero;
@@ -639,6 +638,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SetMomentum(Vector3 momentum)
{
+ if (momentum.IsFinite())
+ AddChange(changes.Momentum, momentum);
}
@@ -663,8 +664,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
- d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
- d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
+ d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(Shell, (uint)m_collisionFlags);
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
@@ -759,7 +760,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_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;
}
}
@@ -991,6 +991,14 @@ namespace OpenSim.Region.Physics.OdePlugin
// end add Kitto Flora
}
+ if (vel.X * vel.X + vel.Y * vel.Y + vel.Z * vel.Z > 2500.0f) // 50m/s apply breaks
+ {
+ float breakfactor = 0.16f * m_mass; // will give aprox 60m/s terminal velocity at free fall
+ vec.X -= breakfactor * vel.X;
+ vec.Y -= breakfactor * vel.Y;
+ vec.Z -= breakfactor * vel.Z;
+ }
+
if (vec.IsFinite())
{
if (vec.X != 0 || vec.Y !=0 || vec.Z !=0)
@@ -1324,6 +1332,16 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ // for now momentum is actually velocity
+ private void changeMomentum(Vector3 newmomentum)
+ {
+ _velocity = newmomentum;
+ _target_velocity = newmomentum;
+ m_pidControllerActive = true;
+ if (Body != IntPtr.Zero)
+ d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
+ }
+
private void donullchange()
{
}
@@ -1395,6 +1413,10 @@ namespace OpenSim.Region.Physics.OdePlugin
case changes.Size:
changeSize((Vector3)arg);
break;
+
+ case changes.Momentum:
+ changeMomentum((Vector3)arg);
+ break;
/* not in use for now
case changes.Shape:
changeShape((PrimitiveBaseShape)arg);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f739183fcd..32c4722bab 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -108,25 +108,29 @@ namespace OpenSim.Region.Physics.OdePlugin
private float m_waterHeight;
private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
- private int body_autodisable_frames = 20;
+ private int body_autodisable_frames = 5;
+ private int bodydisablecontrol = 0;
- private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
- | CollisionCategories.Space
- | CollisionCategories.Body
- | CollisionCategories.Character
- );
-// private bool m_collidesLand = true;
- private bool m_collidesWater;
- public bool m_returnCollisions;
- private bool m_softcolide;
-
- private bool m_NoColide; // for now only for internal use for bad meshs
// Default we're a Geometry
private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
+ // Default colide nonphysical don't try to colide with anything
+ private const CollisionCategories m_default_collisionFlagsNotPhysical = 0;
+
+ private const CollisionCategories m_default_collisionFlagsPhysical = (CollisionCategories.Geom |
+ CollisionCategories.Character |
+ CollisionCategories.Land |
+ CollisionCategories.VolumeDtc);
+
+// private bool m_collidesLand = true;
+ private bool m_collidesWater;
+ public bool m_returnCollisions;
+
+ private bool m_NoColide; // for now only for internal use for bad meshs
+
// Default, Collide with Other Geometries, spaces and Bodies
- private CollisionCategories m_collisionFlags = m_default_collisionFlags;
+ private CollisionCategories m_collisionFlags = m_default_collisionFlagsNotPhysical;
public bool m_disabled;
@@ -179,6 +183,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public float primOOBradiusSQ;
public d.Mass primdMass; // prim inertia information on it's own referencial
float primMass; // prim own mass
+ float primVolume; // prim own volume;
float _mass; // object mass acording to case
private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
@@ -216,6 +221,14 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ public override bool IsVolumeDtc
+ {
+ set { return; }
+ get { return m_isVolumeDetect; }
+
+ }
+
+
public override bool Phantom // this is not reliable for internal use
{
get { return m_fakeisphantom; }
@@ -327,10 +340,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
if (m_colliderfilter == 0)
- {
- m_softcolide = false;
m_iscolliding = false;
- }
else
m_iscolliding = true;
}
@@ -422,6 +432,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public override Vector3 GeometricCenter
{
+ // this is not real geometric center but a average of positions relative to root prim acording to
+ // http://wiki.secondlife.com/wiki/llGetGeometricCenter
+ // ignoring tortured prims details since sl also seems to ignore
+ // so no real use in doing it on physics
get
{
return Vector3.Zero;
@@ -949,7 +963,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_iscolliding = false;
m_colliderfilter = 0;
- m_softcolide = true;
m_NoColide = false;
hasOOBoffsetFromMesh = false;
@@ -992,6 +1005,132 @@ namespace OpenSim.Region.Physics.OdePlugin
m_collisionscore = 0;
}
+ private void UpdateCollisionCatFlags()
+ {
+ if(m_isphysical && m_disabled)
+ {
+ m_collisionCategories = 0;
+ m_collisionFlags = 0;
+ }
+
+ else if (m_isSelected)
+ {
+ m_collisionCategories = CollisionCategories.Selected;
+ m_collisionFlags = 0;
+ }
+
+ else if (m_isVolumeDetect)
+ {
+ m_collisionCategories = CollisionCategories.VolumeDtc;
+ if (m_isphysical)
+ m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
+ else
+ m_collisionFlags = 0;
+ }
+ else if (m_isphantom)
+ {
+ m_collisionCategories = CollisionCategories.Phantom;
+ if (m_isphysical)
+ m_collisionFlags = CollisionCategories.Land;
+ else
+ m_collisionFlags = 0;
+ }
+ else
+ {
+ m_collisionCategories = CollisionCategories.Geom;
+ if (m_isphysical)
+ m_collisionFlags = m_default_collisionFlagsPhysical;
+ else
+ m_collisionFlags = m_default_collisionFlagsNotPhysical;
+ }
+ }
+
+ private void ApplyCollisionCatFlags()
+ {
+ if (prim_geom != IntPtr.Zero)
+ {
+ if (!childPrim && childrenPrim.Count > 0)
+ {
+ foreach (OdePrim prm in childrenPrim)
+ {
+ if (m_isphysical && m_disabled)
+ {
+ prm.m_collisionCategories = 0;
+ prm.m_collisionFlags = 0;
+ }
+ else
+ {
+ // preserve some
+ if (prm.m_isSelected)
+ {
+ prm.m_collisionCategories = CollisionCategories.Selected;
+ prm.m_collisionFlags = 0;
+ }
+ else if (prm.IsVolumeDtc)
+ {
+ prm.m_collisionCategories = CollisionCategories.VolumeDtc;
+ if (m_isphysical)
+ prm.m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
+ else
+ prm.m_collisionFlags = 0;
+ }
+ else if (prm.m_isphantom)
+ {
+ prm.m_collisionCategories = CollisionCategories.Phantom;
+ if (m_isphysical)
+ prm.m_collisionFlags = CollisionCategories.Land;
+ else
+ prm.m_collisionFlags = 0;
+ }
+ else
+ {
+ prm.m_collisionCategories = m_collisionCategories;
+ prm.m_collisionFlags = m_collisionFlags;
+ }
+ }
+
+ if (prm.prim_geom != IntPtr.Zero)
+ {
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ if (m_isphysical)
+ d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
+ else
+ d.GeomSetCollideBits(prm.prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
+ }
+ }
+ }
+ }
+
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
+ if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
+ {
+ d.GeomSetCategoryBits(collide_geom, 0);
+ d.GeomSetCollideBits(collide_geom, (uint)CollisionCategories.Land);
+ }
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
+ if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
+ {
+ d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
+ }
+ }
+ }
+ }
+
private void createAMotor(Vector3 axis)
{
if (Body == IntPtr.Zero)
@@ -1188,7 +1327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomSetCategoryBits(prim_geom, 0);
if (m_isphysical)
{
- d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
}
else
{
@@ -1198,8 +1337,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
}
CalcPrimBodyData();
@@ -1296,6 +1435,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
prim_geom = IntPtr.Zero;
+ collide_geom = IntPtr.Zero;
}
else
{
@@ -1319,66 +1459,23 @@ namespace OpenSim.Region.Physics.OdePlugin
{
IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace);
prim.m_targetSpace = targetSpace;
- d.GeomEnable(prim_geom);
+ collide_geom = IntPtr.Zero;
}
public void enableBodySoft()
{
+ m_disabled = false;
if (!childPrim && !m_isSelected)
{
if (m_isphysical && Body != IntPtr.Zero)
{
- if (m_isphantom && !m_isVolumeDetect)
- {
- m_collisionCategories = 0;
- m_collisionFlags = CollisionCategories.Land;
- }
- else
- {
- m_collisionCategories |= CollisionCategories.Body;
- m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- }
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
- foreach (OdePrim prm in childrenPrim)
- {
- prm.m_collisionCategories = m_collisionCategories;
- prm.m_collisionFlags = m_collisionFlags;
-
- if (prm.prim_geom != IntPtr.Zero)
- {
- if (prm.m_NoColide)
- {
- d.GeomSetCategoryBits(prm.prim_geom, 0);
- d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
- }
- else
- {
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
- }
- d.GeomEnable(prm.prim_geom);
- }
- }
-
- if (prim_geom != IntPtr.Zero)
- {
- if (m_NoColide)
- {
- d.GeomSetCategoryBits(prim_geom, 0);
- d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
- }
- else
- {
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- }
- d.GeomEnable(prim_geom);
- }
d.BodyEnable(Body);
}
}
- m_disabled = false;
- resetCollisionAccounting(); // this sets m_disable to false
+ resetCollisionAccounting();
}
private void disableBodySoft()
@@ -1388,45 +1485,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (m_isphysical && Body != IntPtr.Zero)
{
- m_collisionCategories &= ~CollisionCategories.Body;
- m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
-
- foreach (OdePrim prm in childrenPrim)
- {
- prm.m_collisionCategories = m_collisionCategories;
- prm.m_collisionFlags = m_collisionFlags;
-
- if (prm.prim_geom != IntPtr.Zero)
- {
- if (prm.m_NoColide)
- {
- d.GeomSetCategoryBits(prm.prim_geom, 0);
- d.GeomSetCollideBits(prm.prim_geom, 0);
- }
- else
- {
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
- }
- d.GeomDisable(prm.prim_geom);
- }
- }
-
- if (prim_geom != IntPtr.Zero)
- {
- if (m_NoColide)
- {
- d.GeomSetCategoryBits(prim_geom, 0);
- d.GeomSetCollideBits(prim_geom, 0);
- }
- else
- {
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- }
- d.GeomDisable(prim_geom);
- }
-
+ if (m_isSelected)
+ m_collisionFlags = CollisionCategories.Selected;
+ else
+ m_collisionCategories = 0;
+ m_collisionFlags = 0;
+ ApplyCollisionCatFlags();
d.BodyDisable(Body);
}
}
@@ -1566,7 +1630,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// d.BodySetAngularDampingThreshold(Body, 0.001f);
d.BodySetDamping(Body, .002f, .002f);
-
if (m_targetSpace != IntPtr.Zero)
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1588,6 +1651,13 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceSetSublevel(m_targetSpace, 3);
d.SpaceSetCleanup(m_targetSpace, false);
d.SpaceAdd(m_targetSpace, prim_geom);
+
+ d.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space |
+ CollisionCategories.Geom |
+ CollisionCategories.Phantom |
+ CollisionCategories.VolumeDtc
+ ));
+ d.GeomSetCollideBits(m_targetSpace, 0);
collide_geom = m_targetSpace;
}
@@ -1619,38 +1689,6 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceAdd(m_targetSpace, prm.prim_geom);
}
- if (m_isSelected || m_disabled)
- {
- prm.m_collisionCategories &= ~CollisionCategories.Body;
- prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
- d.GeomDisable(prm.prim_geom);
- }
- else
- {
- if (m_isphantom && !m_isVolumeDetect)
- {
- prm.m_collisionCategories = 0;
- prm.m_collisionFlags = CollisionCategories.Land;
- }
- else
- {
- prm.m_collisionCategories |= CollisionCategories.Body;
- prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- }
- d.GeomEnable(prm.prim_geom);
- }
-
- if (prm.m_NoColide)
- {
- d.GeomSetCategoryBits(prm.prim_geom, 0);
- d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
- d.GeomEnable(prm.prim_geom);
- }
- else
- {
- d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
- }
prm.m_collisionscore = 0;
if(!m_disabled)
@@ -1666,45 +1704,21 @@ namespace OpenSim.Region.Physics.OdePlugin
createAMotor(m_angularlock);
}
+ m_collisionscore = 0;
+
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
+
if (m_isSelected || m_disabled)
{
- m_collisionCategories &= ~CollisionCategories.Body;
- m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
-
- d.GeomDisable(prim_geom);
d.BodyDisable(Body);
}
else
{
- if (m_isphantom && !m_isVolumeDetect)
- {
- m_collisionCategories = 0;
- m_collisionFlags = CollisionCategories.Land;
- }
- else
- {
- m_collisionCategories |= CollisionCategories.Body;
- m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- }
-
d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
}
- if (m_NoColide)
- {
- d.GeomSetCategoryBits(prim_geom, 0);
- d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
- }
- else
- {
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- }
-
- m_collisionscore = 0;
-
- m_softcolide = true;
_parent_scene.addActivePrim(this);
_parent_scene.addActiveGroups(this);
}
@@ -1714,8 +1728,22 @@ namespace OpenSim.Region.Physics.OdePlugin
if (Body != IntPtr.Zero)
{
_parent_scene.remActivePrim(this);
- m_collisionCategories &= ~CollisionCategories.Body;
- m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
+
+ collide_geom = IntPtr.Zero;
+
+ if (m_disabled)
+ m_collisionCategories = 0;
+ else if (m_isSelected)
+ m_collisionCategories = CollisionCategories.Selected;
+ else if (m_isVolumeDetect)
+ m_collisionCategories = CollisionCategories.VolumeDtc;
+ else if (m_isphantom)
+ m_collisionCategories = CollisionCategories.Phantom;
+ else
+ m_collisionCategories = CollisionCategories.Geom;
+
+ m_collisionFlags = 0;
+
if (prim_geom != IntPtr.Zero)
{
if (m_NoColide)
@@ -1725,8 +1753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
}
UpdateDataFromGeom();
d.GeomSetBody(prim_geom, IntPtr.Zero);
@@ -1740,8 +1768,18 @@ namespace OpenSim.Region.Physics.OdePlugin
foreach (OdePrim prm in childrenPrim)
{
_parent_scene.remActivePrim(prm);
- prm.m_collisionCategories = m_collisionCategories;
- prm.m_collisionFlags = m_collisionFlags;
+
+ if (prm.m_isSelected)
+ prm.m_collisionCategories = CollisionCategories.Selected;
+ else if (prm.m_isVolumeDetect)
+ prm.m_collisionCategories = CollisionCategories.VolumeDtc;
+ else if (prm.m_isphantom)
+ prm.m_collisionCategories = CollisionCategories.Phantom;
+ else
+ prm.m_collisionCategories = CollisionCategories.Geom;
+
+ prm.m_collisionFlags = 0;
+
if (prm.prim_geom != IntPtr.Zero)
{
if (prm.m_NoColide)
@@ -1751,8 +1789,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
}
prm.UpdateDataFromGeom();
SetInStaticSpace(prm);
@@ -2292,6 +2330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// keep using basic shape mass for now
volume = CalculatePrimVolume();
+ primVolume = volume;
primMass = m_density * volume;
if (primMass <= 0)
@@ -2515,12 +2554,13 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomSetQuaternion(prim_geom, ref myrot);
if (!m_isphysical)
+ {
SetInStaticSpace(this);
- }
-
- if (m_isphysical && Body == IntPtr.Zero)
- {
- MakeBody();
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
+ }
+ else
+ MakeBody();
}
}
@@ -2602,86 +2642,12 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
-
private void changePhantomStatus(bool newval)
{
m_isphantom = newval;
- if (m_isSelected)
- {
- m_collisionCategories = CollisionCategories.Selected;
- m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
- }
- else
- {
- if (m_isphantom && !m_isVolumeDetect)
- {
- m_collisionCategories = 0;
- if (m_isphysical)
- m_collisionFlags = CollisionCategories.Land;
- else
- m_collisionFlags = 0; // should never happen
- }
-
- else
- {
- m_collisionCategories = CollisionCategories.Geom;
- if (m_isphysical)
- m_collisionCategories |= CollisionCategories.Body;
-
- m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
-
- if (m_collidesWater)
- m_collisionFlags |= CollisionCategories.Water;
- }
- }
-
- if (!childPrim)
- {
- foreach (OdePrim prm in childrenPrim)
- {
- prm.m_collisionCategories = m_collisionCategories;
- prm.m_collisionFlags = m_collisionFlags;
-
- if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
- {
- if (prm.m_NoColide)
- {
- d.GeomSetCategoryBits(prm.prim_geom, 0);
- if (m_isphysical)
- d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
- else
- d.GeomSetCollideBits(prm.prim_geom, 0);
- }
- else
- {
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
- }
- if(!m_isSelected)
- d.GeomEnable(prm.prim_geom);
- }
- }
- }
-
- if (!m_disabled && prim_geom != IntPtr.Zero)
- {
- if (m_NoColide)
- {
- d.GeomSetCategoryBits(prim_geom, 0);
- if (m_isphysical)
- d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
- else
- d.GeomSetCollideBits(prim_geom, 0);
- }
- else
- {
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- }
- if(!m_isSelected)
- d.GeomEnable(prim_geom);
- }
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
}
private void changeSelectedStatus(bool newval)
@@ -2714,7 +2680,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_delaySelect || m_isphysical)
{
m_collisionCategories = CollisionCategories.Selected;
- m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
+ m_collisionFlags = 0;
if (!childPrim)
{
@@ -2733,10 +2699,9 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ d.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags);
}
- d.GeomDisable(prm.prim_geom);
}
prm.m_delaySelect = false;
}
@@ -2748,13 +2713,23 @@ namespace OpenSim.Region.Physics.OdePlugin
{
d.GeomSetCategoryBits(prim_geom, 0);
d.GeomSetCollideBits(prim_geom, 0);
+ if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
+ {
+ d.GeomSetCategoryBits(collide_geom, 0);
+ d.GeomSetCollideBits(collide_geom, 0);
+ }
+
}
else
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
+ if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
+ {
+ d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
+ }
}
- d.GeomDisable(prim_geom);
}
m_delaySelect = false;
@@ -2769,75 +2744,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && Body != IntPtr.Zero && !m_disabled)
d.BodyEnable(Body);
- if (m_isphantom && !m_isVolumeDetect)
- {
- m_collisionCategories = 0;
- if(m_isphysical)
- m_collisionFlags = CollisionCategories.Land;
- else
- m_collisionFlags = 0;
- }
- else
- {
- m_collisionCategories = CollisionCategories.Geom;
- if (m_isphysical)
- m_collisionCategories |= CollisionCategories.Body;
-
- m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
-
- if (m_collidesWater)
- m_collisionFlags |= CollisionCategories.Water;
- }
-
- if (!childPrim)
- {
- foreach (OdePrim prm in childrenPrim)
- {
- prm.m_collisionCategories = m_collisionCategories;
- prm.m_collisionFlags = m_collisionFlags;
-
- if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
- {
- if (prm.m_NoColide)
- {
- d.GeomSetCategoryBits(prm.prim_geom, 0);
- if (m_isphysical)
- d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
- else
- d.GeomSetCollideBits(prm.prim_geom, 0);
- }
- else
- {
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
- }
- d.GeomEnable(prm.prim_geom);
- }
- prm.m_delaySelect = false;
- prm.m_softcolide = true;
- }
- }
-
- if (!m_disabled && prim_geom != IntPtr.Zero)
- {
- if (m_NoColide)
- {
- d.GeomSetCategoryBits(prim_geom, 0);
- if (m_isphysical)
- d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
- else
- d.GeomSetCollideBits(prim_geom, 0);
- }
- else
- {
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- }
- d.GeomEnable(prim_geom);
- }
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
m_delaySelect = false;
- m_softcolide = true;
}
resetCollisionAccounting();
@@ -2890,7 +2800,6 @@ namespace OpenSim.Region.Physics.OdePlugin
if (givefakepos < 0)
givefakepos = 0;
// changeSelectedStatus();
- m_softcolide = true;
resetCollisionAccounting();
}
@@ -2951,7 +2860,6 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakeori--;
if (givefakeori < 0)
givefakeori = 0;
- m_softcolide = true;
resetCollisionAccounting();
}
@@ -3022,7 +2930,6 @@ namespace OpenSim.Region.Physics.OdePlugin
if (givefakeori < 0)
givefakeori = 0;
- m_softcolide = true;
resetCollisionAccounting();
}
@@ -3111,17 +3018,25 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomSetQuaternion(prim_geom, ref myrot);
}
- if (chp)
+ if (m_isphysical)
{
- if (parent != null)
+ if (chp)
{
- parent.MakeBody();
+ if (parent != null)
+ {
+ parent.MakeBody();
+ }
}
+ else
+ MakeBody();
+ }
+
+ else
+ {
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
}
- else
- MakeBody();
- m_softcolide = true;
resetCollisionAccounting();
}
@@ -3142,18 +3057,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{
m_collidesWater = newval;
- if (prim_geom != IntPtr.Zero && !m_isphantom)
- {
- if (m_collidesWater)
- {
- m_collisionFlags |= CollisionCategories.Water;
- }
- else
- {
- m_collisionFlags &= ~CollisionCategories.Water;
- }
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- }
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
}
private void changeSetTorque(Vector3 newtorque)
@@ -3240,6 +3145,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private void changeVolumedetetion(bool newVolDtc)
{
m_isVolumeDetect = newVolDtc;
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
}
protected void changeBuilding(bool newbuilding)
@@ -3320,288 +3227,306 @@ namespace OpenSim.Region.Physics.OdePlugin
public void Move()
{
if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
- !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds)
+ !m_disabled && !m_isSelected && !m_building && !m_outbounds)
// !m_disabled && !m_isSelected && !m_building && !m_outbounds)
{
-// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
+ // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
- float timestep = _parent_scene.ODE_STEPSIZE;
-
- // check outside region
- d.Vector3 lpos;
- d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
-
- if (lpos.Z < -100 || lpos.Z > 100000f)
+ if (d.BodyIsEnabled(Body))
{
- m_outbounds = true;
+ float timestep = _parent_scene.ODE_STEPSIZE;
- lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
- _acceleration.X = 0;
- _acceleration.Y = 0;
- _acceleration.Z = 0;
+ // check outside region
+ d.Vector3 lpos;
+ d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
- _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;
- }
-
-
- float fx = 0;
- float fy = 0;
- float fz = 0;
-
- if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
- {
- // 'VEHICLES' are dealt with in ODEDynamics.cs
- m_vehicle.Step();
- }
- else
- {
- float m_mass = _mass;
-
- // fz = 0f;
- //m_log.Info(m_collisionFlags.ToString());
- if (m_usePID)
+ if (lpos.Z < -100 || lpos.Z > 100000f)
{
+ m_outbounds = true;
- // If the PID Controller isn't active then we set our force
- // calculating base velocity to the current position
+ lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
+ _acceleration.X = 0;
+ _acceleration.Y = 0;
+ _acceleration.Z = 0;
- if ((m_PIDTau < 1) && (m_PIDTau != 0))
- {
- //PID_G = PID_G / m_PIDTau;
- m_PIDTau = 1;
- }
+ _velocity.X = 0;
+ _velocity.Y = 0;
+ _velocity.Z = 0;
+ m_rotationalVelocity.X = 0;
+ m_rotationalVelocity.Y = 0;
+ m_rotationalVelocity.Z = 0;
- if ((PID_G - m_PIDTau) <= 0)
- {
- PID_G = m_PIDTau + 1;
- }
+ 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;
- 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)
- );
+ base.RequestPhysicsterseUpdate();
- // if velocity is zero, use position control; otherwise, velocity control
+ m_throttleUpdates = false;
+ throttleCounter = 0;
+ _zeroFlag = true;
- 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));
- }
+ 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;
+ }
+
else
{
- float b = (1.0f - m_buoyancy);
- fx = _parent_scene.gravityx * b;
- fy = _parent_scene.gravityy * b;
- fz = _parent_scene.gravityz * b;
+
+ 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);
+ }
+
}
+ }
+ else // body disabled
+ {
+ // let vehicles sleep
+ if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
+ return;
- 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);
- }
+ if (++bodydisablecontrol < 20)
+ return;
+ bodydisablecontrol = 0;
+ d.BodyEnable(Body);
+ return;
}
}
else
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 4b3f83b24d..5122ebfa11 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -30,10 +30,11 @@ using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
-using OpenMetaverse;
+using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OdeAPI;
using log4net;
+using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
@@ -54,9 +55,11 @@ namespace OpenSim.Region.Physics.OdePlugin
///
private OdeScene m_scene;
- IntPtr ray;
+ IntPtr ray; // the ray. we only need one for our lifetime
private const int ColisionContactGeomsPerTest = 5;
+ private const int DefaultMaxCount = 25;
+ private const int MaxTimePerCallMS = 30;
///
/// ODE near callback delegate
@@ -64,19 +67,22 @@ namespace OpenSim.Region.Physics.OdePlugin
private d.NearCallback nearCallback;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List m_contactResults = new List();
+ private RayFilterFlags CurrentRayFilter;
+ private int CurrentMaxCount;
public ODERayCastRequestManager(OdeScene pScene)
{
m_scene = pScene;
nearCallback = near;
ray = d.CreateRay(IntPtr.Zero, 1.0f);
+ d.GeomSetCategoryBits(ray,0);
}
///
- /// Queues a raycast
+ /// Queues request for a raycast to all world
///
/// Origin of Ray
- /// Ray normal
+ /// Ray direction
/// Ray length
/// Return method to send the results
public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
@@ -84,14 +90,22 @@ namespace OpenSim.Region.Physics.OdePlugin
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
- req.Count = 0;
+ req.Count = DefaultMaxCount;
req.length = length;
req.Normal = direction;
req.Origin = position;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
+ ///
+ /// Queues request for a raycast to particular part
+ ///
+ /// Origin of Ray
+ /// Ray direction
+ /// Ray length
+ /// Return method to send the results
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
@@ -100,7 +114,8 @@ namespace OpenSim.Region.Physics.OdePlugin
req.length = length;
req.Normal = direction;
req.Origin = position;
- req.Count = 0;
+ req.Count = DefaultMaxCount;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
@@ -110,10 +125,11 @@ namespace OpenSim.Region.Physics.OdePlugin
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
- req.Count = 0;
+ req.Count = DefaultMaxCount;
req.length = length;
req.Normal = direction;
req.Origin = position;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
@@ -126,7 +142,8 @@ namespace OpenSim.Region.Physics.OdePlugin
req.length = length;
req.Normal = direction;
req.Origin = position;
- req.Count = 0;
+ req.Count = DefaultMaxCount;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
@@ -148,6 +165,22 @@ namespace OpenSim.Region.Physics.OdePlugin
req.Normal = direction;
req.Origin = position;
req.Count = count;
+ req.filter = RayFilterFlags.AllPrims;
+
+ m_PendingRequests.Enqueue(req);
+ }
+
+
+ public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod)
+ {
+ ODERayRequest req = new ODERayRequest();
+ req.geom = IntPtr.Zero;
+ req.callbackMethod = retMethod;
+ req.length = length;
+ req.Normal = direction;
+ req.Origin = position;
+ req.Count = count;
+ req.filter = filter;
m_PendingRequests.Enqueue(req);
}
@@ -161,6 +194,7 @@ namespace OpenSim.Region.Physics.OdePlugin
req.Normal = direction;
req.Origin = position;
req.Count = count;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
@@ -174,6 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin
req.Normal = direction;
req.Origin = position;
req.Count = count;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
@@ -187,6 +222,7 @@ namespace OpenSim.Region.Physics.OdePlugin
req.Normal = direction;
req.Origin = position;
req.Count = count;
+ req.filter = RayFilterFlags.AllPrims;
m_PendingRequests.Enqueue(req);
}
@@ -197,63 +233,104 @@ namespace OpenSim.Region.Physics.OdePlugin
/// Time in MS the raycasts took to process.
public int ProcessQueuedRequests()
{
- int time = System.Environment.TickCount;
if (m_PendingRequests.Count <= 0)
return 0;
- if (m_scene.ContactgeomsArray == IntPtr.Zero) // oops something got wrong or scene isn't ready still
+ if (m_scene.ContactgeomsArray == IntPtr.Zero || ray == IntPtr.Zero)
+ // oops something got wrong or scene isn't ready still
{
m_PendingRequests.Clear();
return 0;
}
+ int time = Util.EnvironmentTickCount();
+
ODERayRequest req;
+ int closestHit;
+ int backfacecull;
+ CollisionCategories catflags;
- int i = 50; // arbitary limit of processed tests per frame
-
- while(m_PendingRequests.Dequeue(out req))
+ while (m_PendingRequests.Dequeue(out req))
{
- if (req.geom == IntPtr.Zero)
- doSpaceRay(req);
- else
- doGeomRay(req);
- if(--i < 0)
- break;
+ if (req.callbackMethod != null)
+ {
+ CurrentRayFilter = req.filter;
+ CurrentMaxCount = req.Count;
+
+ closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
+ backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
+
+ d.GeomRaySetLength(ray, req.length);
+ d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
+ d.GeomRaySetParams(ray, 0, backfacecull);
+ d.GeomRaySetClosestHit(ray, closestHit);
+
+ if (req.callbackMethod is RaycastCallback)
+ // if we only want one get only one per colision pair saving memory
+ CurrentRayFilter |= RayFilterFlags.ClosestHit;
+
+ if (req.geom == IntPtr.Zero)
+ {
+ // translate ray filter to colision flags
+ catflags = 0;
+ if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
+ catflags |= CollisionCategories.VolumeDtc;
+ if ((CurrentRayFilter & RayFilterFlags.phantom) != 0)
+ catflags |= CollisionCategories.Phantom;
+ if ((CurrentRayFilter & RayFilterFlags.agent) != 0)
+ catflags |= CollisionCategories.Character;
+ if ((CurrentRayFilter & RayFilterFlags.PrimsNonPhantom) != 0)
+ catflags |= CollisionCategories.Geom;
+ if ((CurrentRayFilter & RayFilterFlags.land) != 0)
+ catflags |= CollisionCategories.Land;
+ if ((CurrentRayFilter & RayFilterFlags.water) != 0)
+ catflags |= CollisionCategories.Water;
+
+ if (catflags != 0)
+ doSpaceRay(req);
+ }
+ else
+ {
+ // if we select a geom don't use filters
+ d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
+ doGeomRay(req);
+ }
+ }
+
+ if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS)
+ break;
}
lock (m_contactResults)
m_contactResults.Clear();
- return System.Environment.TickCount - time;
+ return Util.EnvironmentTickCountSubtract(time);
}
///
- /// Method that actually initiates the raycast with full top space
+ /// Method that actually initiates the raycast with spaces
///
///
+ ///
+
+ private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
+ private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
+
private void doSpaceRay(ODERayRequest req)
{
- // Create the ray
-// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
- d.GeomRaySetLength(ray, req.length);
- d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
-
- // Collide test
- d.SpaceCollide2(m_scene.TopSpace, ray, IntPtr.Zero, nearCallback);
-
- // Remove Ray
-// d.GeomDestroy(ray);
-
- if (req.callbackMethod == null)
- return;
+ // Collide tests
+ if ((CurrentRayFilter & FilterActiveSpace) != 0)
+ d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
+ if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
+ d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
if (req.callbackMethod is RaycastCallback)
{
// Define default results
bool hitYN = false;
uint hitConsumerID = 0;
- float distance = 999999999999f;
- Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
+ float distance = float.MaxValue;
+ Vector3 closestcontact = Vector3.Zero;
Vector3 snormal = Vector3.Zero;
// Find closest contact and object.
@@ -261,25 +338,30 @@ namespace OpenSim.Region.Physics.OdePlugin
{
foreach (ContactResult cResult in m_contactResults)
{
- if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
+ if(cResult.Depth < distance)
{
closestcontact = cResult.Pos;
hitConsumerID = cResult.ConsumerID;
distance = cResult.Depth;
- hitYN = true;
snormal = cResult.Normal;
}
}
m_contactResults.Clear();
}
-
+
+ if (distance > 0 && distance < float.MaxValue)
+ hitYN = true;
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
}
else
{
- ((RayCallback)req.callbackMethod)(m_contactResults);
+ List cresult = new List(m_contactResults.Count);
lock (m_PendingRequests)
+ {
+ cresult.AddRange(m_contactResults);
m_contactResults.Clear();
+ }
+ ((RayCallback)req.callbackMethod)(cresult);
}
}
@@ -289,27 +371,16 @@ namespace OpenSim.Region.Physics.OdePlugin
///
private void doGeomRay(ODERayRequest req)
{
- // Create the ray
-// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
- d.GeomRaySetLength(ray, req.length);
- d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
-
// Collide test
- d.SpaceCollide2(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
-
- // Remove Ray
-// d.GeomDestroy(ray);
-
- if (req.callbackMethod == null)
- return;
+ d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
if (req.callbackMethod is RaycastCallback)
{
// Define default results
bool hitYN = false;
uint hitConsumerID = 0;
- float distance = 999999999999f;
- Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
+ float distance = float.MaxValue;
+ Vector3 closestcontact = Vector3.Zero;
Vector3 snormal = Vector3.Zero;
// Find closest contact and object.
@@ -317,25 +388,31 @@ namespace OpenSim.Region.Physics.OdePlugin
{
foreach (ContactResult cResult in m_contactResults)
{
- if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
+ if(cResult.Depth < distance )
{
closestcontact = cResult.Pos;
hitConsumerID = cResult.ConsumerID;
distance = cResult.Depth;
- hitYN = true;
snormal = cResult.Normal;
}
}
m_contactResults.Clear();
}
+ if (distance > 0 && distance < float.MaxValue)
+ hitYN = true;
+
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
}
else
{
- ((RayCallback)req.callbackMethod)(m_contactResults);
+ List cresult = new List(m_contactResults.Count);
lock (m_PendingRequests)
+ {
+ cresult.AddRange(m_contactResults);
m_contactResults.Clear();
+ }
+ ((RayCallback)req.callbackMethod)(cresult);
}
}
@@ -350,20 +427,16 @@ namespace OpenSim.Region.Physics.OdePlugin
return true;
}
- // This is the standard Near. g2 is the ray
+ // This is the standard Near. g1 is the ray
private void near(IntPtr space, IntPtr g1, IntPtr g2)
{
- //Don't test against heightfield Geom, or you'll be sorry!
- // Exclude heightfield geom
-
- if (g1 == IntPtr.Zero || g1 == g2)
+ if (g2 == IntPtr.Zero || g1 == g2)
return;
- if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
+ if (m_contactResults.Count >= CurrentMaxCount)
return;
- // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
- if (d.GeomIsSpace(g1))
+ if (d.GeomIsSpace(g2))
{
try
{
@@ -381,10 +454,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
}
- catch (SEHException)
- {
- m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
- }
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
@@ -394,31 +463,116 @@ namespace OpenSim.Region.Physics.OdePlugin
if (count == 0)
return;
- PhysicsActor p1 = null;
+ uint ID = 0;
+ PhysicsActor p2 = null;
- if (g1 != IntPtr.Zero)
- m_scene.actor_name_map.TryGetValue(g1, out p1);
+ m_scene.actor_name_map.TryGetValue(g2, out p2);
+
+ if (p2 == null)
+ {
+ string name;
+
+ if (!m_scene.geom_name_map.TryGetValue(g2, out name))
+ return;
+
+ if (name == "Terrain")
+ {
+ // land colision
+ if ((CurrentRayFilter & RayFilterFlags.land) == 0)
+ return;
+ }
+ else if (name == "Water")
+ {
+ if ((CurrentRayFilter & RayFilterFlags.water) == 0)
+ return;
+ }
+ else
+ return;
+ }
+ else
+ {
+ if (p2 is OdePrim)
+ {
+ RayFilterFlags thisFlags;
+
+ if (p2.IsPhysical)
+ thisFlags = RayFilterFlags.physical;
+ else
+ thisFlags = RayFilterFlags.nonphysical;
+
+ if (p2.Phantom)
+ thisFlags |= RayFilterFlags.phantom;
+
+ if (p2.IsVolumeDtc)
+ thisFlags |= RayFilterFlags.volumedtc;
+
+ if ((thisFlags & CurrentRayFilter) == 0)
+ return;
+
+ ID = ((OdePrim)p2).m_localID;
+ }
+ else if (p2 is OdeCharacter)
+ {
+ if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
+ return;
+ else
+ ID = ((OdeCharacter)p2).m_localID;
+ }
+ else //??
+ return;
+ }
d.ContactGeom curcontact = new d.ContactGeom();
- // Loop over contacts, build results.
- for (int i = 0; i < count; i++)
+
+ // closestHit for now only works for meshs, so must do it for others
+ if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
{
- if (!GetCurContactGeom(i, ref curcontact))
- break;
- if (p1 != null) {
- if (p1 is OdePrim)
+ // Loop all contacts, build results.
+ for (int i = 0; i < count; i++)
+ {
+ if (!GetCurContactGeom(i, ref curcontact))
+ break;
+
+ ContactResult collisionresult = new ContactResult();
+ collisionresult.ConsumerID = ID;
+ collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
+ collisionresult.Depth = curcontact.depth;
+ collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
+ curcontact.normal.Z);
+ lock (m_contactResults)
+ {
+ m_contactResults.Add(collisionresult);
+ if (m_contactResults.Count >= CurrentMaxCount)
+ return;
+ }
+ }
+ }
+ else
+ {
+ // keep only closest contact
+ ContactResult collisionresult = new ContactResult();
+ collisionresult.ConsumerID = ID;
+ collisionresult.Depth = float.MaxValue;
+
+ for (int i = 0; i < count; i++)
+ {
+ if (!GetCurContactGeom(i, ref curcontact))
+ break;
+
+ if (curcontact.depth < collisionresult.Depth)
{
- ContactResult collisionresult = new ContactResult();
-
- collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
collisionresult.Depth = curcontact.depth;
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
curcontact.normal.Z);
- lock (m_contactResults)
- m_contactResults.Add(collisionresult);
}
}
+
+ if (collisionresult.Depth != float.MaxValue)
+ {
+ lock (m_contactResults)
+ m_contactResults.Add(collisionresult);
+ }
}
}
@@ -428,6 +582,11 @@ namespace OpenSim.Region.Physics.OdePlugin
internal void Dispose()
{
m_scene = null;
+ if (ray != IntPtr.Zero)
+ {
+ d.GeomDestroy(ray);
+ ray = IntPtr.Zero;
+ }
}
}
@@ -439,5 +598,6 @@ namespace OpenSim.Region.Physics.OdePlugin
public int Count;
public float length;
public object callbackMethod;
+ public RayFilterFlags filter;
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
index f5129cb540..0e4961b85a 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
@@ -889,13 +889,13 @@ namespace OdeAPI
public static extern IntPtr GeomGetBody(IntPtr geom);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity]
- public static extern int GeomGetCategoryBits(IntPtr geom);
+ public static extern uint GeomGetCategoryBits(IntPtr geom);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GeomGetClassData(IntPtr geom);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity]
- public static extern int GeomGetCollideBits(IntPtr geom);
+ public static extern uint GeomGetCollideBits(IntPtr geom);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity]
public static extern GeomClassID GeomGetClass(IntPtr geom);
@@ -1086,10 +1086,10 @@ namespace OdeAPI
public static extern void GeomSetBody(IntPtr geom, IntPtr body);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity]
- public static extern void GeomSetCategoryBits(IntPtr geom, int bits);
+ public static extern void GeomSetCategoryBits(IntPtr geom, uint bits);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity]
- public static extern void GeomSetCollideBits(IntPtr geom, int bits);
+ public static extern void GeomSetCollideBits(IntPtr geom, uint bits);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 3e0ccefe65..7632e25530 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,19 +60,31 @@ namespace OpenSim.Region.Physics.OdePlugin
public int lastframe;
}
+ // colision flags of things others can colide with
+ // rays, sensors, probes removed since can't be colided with
+ // The top space where things are placed provided further selection
+ // ie physical are in active space nonphysical in static
+ // this should be exclusive as possible
+
[Flags]
- public enum CollisionCategories : int
+ public enum CollisionCategories : uint
{
Disabled = 0,
- Geom = 0x00000001,
- Body = 0x00000002,
- Space = 0x00000004,
- Character = 0x00000008,
- Land = 0x00000010,
- Water = 0x00000020,
- Wind = 0x00000040,
- Sensor = 0x00000080,
- Selected = 0x00000100
+ //by 'things' types
+ Space = 0x01,
+ Geom = 0x02, // aka prim/part
+ Character = 0x04,
+ Land = 0x08,
+ Water = 0x010,
+
+ // by state
+ Phantom = 0x01000,
+ VolumeDtc = 0x02000,
+ Selected = 0x04000,
+ NoShape = 0x08000,
+
+
+ All = 0xffffffff
}
///
@@ -116,6 +128,7 @@ namespace OpenSim.Region.Physics.OdePlugin
Acceleration,
Force,
Torque,
+ Momentum,
AddForce,
AddAngForce,
@@ -186,7 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
private float waterlevel = 0f;
private int framecount = 0;
- internal IntPtr WaterGeom;
+ private IntPtr WaterGeom = IntPtr.Zero;
+ private IntPtr WaterHeightmapData = IntPtr.Zero;
+ private GCHandle WaterMapHandler = new GCHandle();
public float avPIDD = 2200f; // make it visible
public float avPIDP = 900f; // make it visible
@@ -213,9 +228,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// public int geomCrossingFailuresBeforeOutofbounds = 6;
- public int bodyFramesAutoDisable = 20;
+ public int bodyFramesAutoDisable = 5;
- private float[] _watermap;
private d.NearCallback nearCallback;
@@ -350,7 +364,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// i must RtC#FM
}
- d.HashSpaceSetLevels(TopSpace, -2, 8); // cell sizes from .25 to 256 ?? need check what this really does
+ d.HashSpaceSetLevels(TopSpace, -2, 8);
d.HashSpaceSetLevels(ActiveSpace, -2, 8);
d.HashSpaceSetLevels(StaticSpace, -2, 8);
@@ -358,13 +372,27 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceSetSublevel(ActiveSpace, 1);
d.SpaceSetSublevel(StaticSpace, 1);
+ d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
+ CollisionCategories.Geom |
+ CollisionCategories.Character |
+ CollisionCategories.Phantom |
+ CollisionCategories.VolumeDtc
+ ));
+ d.GeomSetCollideBits(ActiveSpace, 0);
+ d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space |
+ CollisionCategories.Geom |
+ CollisionCategories.Land |
+ CollisionCategories.Water |
+ CollisionCategories.Phantom |
+ CollisionCategories.VolumeDtc
+ ));
+ d.GeomSetCollideBits(StaticSpace, 0);
+
contactgroup = d.JointGroupCreate(0);
//contactgroup
d.WorldSetAutoDisableFlag(world, false);
}
-
- _watermap = new float[258 * 258];
}
// Initialize the mesh plugin
@@ -374,15 +402,18 @@ namespace OpenSim.Region.Physics.OdePlugin
// checkThread();
mesher = meshmerizer;
m_config = config;
-
+/*
string ode_config = d.GetConfiguration("ODE");
- m_log.WarnFormat("ODE configuration: {0}", ode_config);
-
- if (ode_config.Contains("ODE_Ubit"))
+ if (ode_config != null && ode_config != "")
{
- OdeUbitLib = true;
- }
+ m_log.WarnFormat("ODE configuration: {0}", ode_config);
+ if (ode_config.Contains("ODE_Ubit"))
+ {
+ OdeUbitLib = true;
+ }
+ }
+*/
/*
if (region != null)
{
@@ -518,6 +549,15 @@ namespace OpenSim.Region.Physics.OdePlugin
waitForSpaceUnlock(newspace);
d.SpaceSetSublevel(newspace, 2);
d.HashSpaceSetLevels(newspace, -2, 8);
+ d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space |
+ CollisionCategories.Geom |
+ CollisionCategories.Land |
+ CollisionCategories.Water |
+ CollisionCategories.Phantom |
+ CollisionCategories.VolumeDtc
+ ));
+ d.GeomSetCollideBits(newspace, 0);
+
staticPrimspace[i, j] = newspace;
}
// let this now be real maximum values
@@ -1745,8 +1785,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_rayCastManager.ProcessQueuedRequests();
-
-
statray += Util.EnvironmentTickCountSubtract(statstart);
collision_optimized();
statcol += Util.EnvironmentTickCountSubtract(statstart);
@@ -2125,14 +2163,14 @@ namespace OpenSim.Region.Physics.OdePlugin
RegionTerrain.Remove(pOffset);
if (GroundGeom != IntPtr.Zero)
{
+ d.GeomDestroy(GroundGeom);
+
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
{
TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
TerrainHeightFieldHeights.Remove(GroundGeom);
}
- d.SpaceRemove(StaticSpace, GroundGeom);
- d.GeomDestroy(GroundGeom);
}
}
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
@@ -2147,8 +2185,8 @@ namespace OpenSim.Region.Physics.OdePlugin
GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
if (GroundGeom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
- d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
+ d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
+ d.GeomSetCollideBits(GroundGeom, 0);
}
geom_name_map[GroundGeom] = "Terrain";
@@ -2236,14 +2274,15 @@ namespace OpenSim.Region.Physics.OdePlugin
RegionTerrain.Remove(pOffset);
if (GroundGeom != IntPtr.Zero)
{
+ d.GeomDestroy(GroundGeom);
+
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
{
- TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
+ if (TerrainHeightFieldHeightsHandlers[GroundGeom].IsAllocated)
+ TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
TerrainHeightFieldHeights.Remove(GroundGeom);
}
- d.SpaceRemove(StaticSpace, GroundGeom);
- d.GeomDestroy(GroundGeom);
}
}
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
@@ -2263,8 +2302,8 @@ namespace OpenSim.Region.Physics.OdePlugin
GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
if (GroundGeom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
- d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
+ d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
+ d.GeomSetCollideBits(GroundGeom, 0);
}
geom_name_map[GroundGeom] = "Terrain";
@@ -2359,57 +2398,76 @@ namespace OpenSim.Region.Physics.OdePlugin
public void randomizeWater(float baseheight)
{
- const uint heightmapWidth = m_regionWidth + 2;
- const uint heightmapHeight = m_regionHeight + 2;
- const uint heightmapWidthSamples = m_regionWidth + 2;
- const uint heightmapHeightSamples = m_regionHeight + 2;
+ const uint heightmapWidth = Constants.RegionSize + 2;
+ const uint heightmapHeight = Constants.RegionSize + 2;
+ const uint heightmapWidthSamples = heightmapWidth + 1;
+ const uint heightmapHeightSamples = heightmapHeight + 1;
+
const float scale = 1.0f;
const float offset = 0.0f;
- const float thickness = 2.9f;
const int wrap = 0;
- for (int i = 0; i < (258 * 258); i++)
+ float[] _watermap = new float[heightmapWidthSamples * heightmapWidthSamples];
+
+ float maxheigh = float.MinValue;
+ float minheigh = float.MaxValue;
+ float val;
+ for (int i = 0; i < (heightmapWidthSamples * heightmapHeightSamples); i++)
{
- _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f);
- // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f));
+
+ val = (baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f);
+ _watermap[i] = val;
+ if (maxheigh < val)
+ maxheigh = val;
+ if (minheigh > val)
+ minheigh = val;
}
+ float thickness = minheigh;
+
lock (OdeLock)
{
if (WaterGeom != IntPtr.Zero)
{
- d.SpaceRemove(StaticSpace, WaterGeom);
+ d.GeomDestroy(WaterGeom);
+ d.GeomHeightfieldDataDestroy(WaterHeightmapData);
+ WaterGeom = IntPtr.Zero;
+ WaterHeightmapData = IntPtr.Zero;
+ if(WaterMapHandler.IsAllocated)
+ WaterMapHandler.Free();
}
- IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
- d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight,
+
+ WaterHeightmapData = d.GeomHeightfieldDataCreate();
+
+ WaterMapHandler = GCHandle.Alloc(_watermap, GCHandleType.Pinned);
+
+ d.GeomHeightfieldDataBuildSingle(WaterHeightmapData, WaterMapHandler.AddrOfPinnedObject(), 0, heightmapWidth, heightmapHeight,
(int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
offset, thickness, wrap);
- d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight);
- WaterGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
+ d.GeomHeightfieldDataSetBounds(WaterHeightmapData, minheigh, maxheigh);
+ WaterGeom = d.CreateHeightfield(StaticSpace, WaterHeightmapData, 1);
if (WaterGeom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water));
- d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space));
+ d.GeomSetCategoryBits(WaterGeom, (uint)(CollisionCategories.Water));
+ d.GeomSetCollideBits(WaterGeom, 0);
+ geom_name_map[WaterGeom] = "Water";
+
+ d.Matrix3 R = new d.Matrix3();
+
+ Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f);
+ Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
+
+ q1 = q1 * q2;
+ Vector3 v3;
+ float angle;
+ q1.GetAxisAngle(out v3, out angle);
+
+ d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
+ d.GeomSetRotation(WaterGeom, ref R);
+ d.GeomSetPosition(WaterGeom, (float)Constants.RegionSize * 0.5f, (float)Constants.RegionSize * 0.5f, 0);
}
- geom_name_map[WaterGeom] = "Water";
-
- d.Matrix3 R = new d.Matrix3();
-
- Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f);
- Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
-
- q1 = q1 * q2;
- Vector3 v3;
- float angle;
- q1.GetAxisAngle(out v3, out angle);
-
- d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
- d.GeomSetRotation(WaterGeom, ref R);
- d.GeomSetPosition(WaterGeom, 128, 128, 0);
-
}
-
}
public override void Dispose()
@@ -2427,11 +2485,34 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ if (TerrainHeightFieldHeightsHandlers.Count > 0)
+ {
+ foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values)
+ {
+ if (gch.IsAllocated)
+ gch.Free();
+ }
+ }
+
+ if (WaterGeom != IntPtr.Zero)
+ {
+ d.GeomDestroy(WaterGeom);
+ WaterGeom = IntPtr.Zero;
+ if (WaterHeightmapData != IntPtr.Zero)
+ d.GeomHeightfieldDataDestroy(WaterHeightmapData);
+ WaterHeightmapData = IntPtr.Zero;
+
+ if (WaterMapHandler.IsAllocated)
+ WaterMapHandler.Free();
+ }
+
+
if (ContactgeomsArray != IntPtr.Zero)
Marshal.FreeHGlobal(ContactgeomsArray);
if (GlobalContactsArray != IntPtr.Zero)
Marshal.FreeHGlobal(GlobalContactsArray);
+
d.WorldDestroy(world);
//d.CloseODE();
}
@@ -2502,6 +2583,35 @@ namespace OpenSim.Region.Physics.OdePlugin
return new List(ourResults);
}
+ public override bool SuportsRaycastWorldFiltered()
+ {
+ return true;
+ }
+
+ public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
+ {
+ object SyncObject = new object();
+ List ourresults = new List();
+
+ RayCallback retMethod = delegate(List results)
+ {
+ lock (SyncObject)
+ {
+ ourresults = results;
+ Monitor.PulseAll(SyncObject);
+ }
+ };
+
+ lock (SyncObject)
+ {
+ m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod);
+ if (!Monitor.Wait(SyncObject, 500))
+ return null;
+ else
+ return ourresults;
+ }
+ }
+
public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
{
if (retMethod != null && actor !=null)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9564d4616d..3a7eb3212d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -9980,7 +9980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// return total object mass
SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
if (obj != null)
- return (double)obj.GetMass();
+ return obj.GetMass();
// the object is null so the key is for an avatar
ScenePresence avatar = World.GetScenePresence(key);
@@ -9990,7 +9990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// child agents have a mass of 1.0
return 1;
else
- return (double)avatar.PhysicsActor.Mass;
+ return avatar.GetMass();
}
catch (KeyNotFoundException)
{
@@ -11834,6 +11834,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return contacts[0];
}
+/*
+ // not done:
+ private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
+ {
+ ContactResult[] contacts = null;
+ World.ForEachSOG(delegate(SceneObjectGroup group)
+ {
+ if (m_host.ParentGroup == group)
+ return;
+
+ if (group.IsAttachment)
+ return;
+
+ if(group.RootPart.PhysActor != null)
+ return;
+
+ contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
+ });
+ return contacts;
+ }
+*/
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
{
@@ -11874,38 +11895,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
- if (checkTerrain)
- {
- ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
- if (groundContact != null)
- results.Add((ContactResult)groundContact);
- }
- if (checkAgents)
+ if (World.SuportsRayCastFiltered())
{
- ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
- foreach (ContactResult r in agentHits)
- results.Add(r);
- }
+ if (dist == 0)
+ return list;
- if (checkPhysical || checkNonPhysical)
+ RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
+ if (checkTerrain)
+ rayfilter |= RayFilterFlags.land;
+// if (checkAgents)
+// rayfilter |= RayFilterFlags.agent;
+ if (checkPhysical)
+ rayfilter |= RayFilterFlags.physical;
+ if (checkNonPhysical)
+ rayfilter |= RayFilterFlags.nonphysical;
+ if (detectPhantom)
+ rayfilter |= RayFilterFlags.LSLPhanton;
+
+ Vector3 direction = dir * ( 1/dist);
+
+ if(rayfilter == 0)
+ {
+ list.Add(new LSL_Integer(0));
+ return list;
+ }
+
+ // get some more contacts to sort ???
+ int physcount = 4 * count;
+ if (physcount > 20)
+ physcount = 20;
+
+ object physresults;
+ physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
+
+ if (physresults == null)
+ {
+ list.Add(new LSL_Integer(-3)); // timeout error
+ return list;
+ }
+
+ results = (List)physresults;
+
+ // for now physics doesn't detect sitted avatars so do it outside physics
+ if (checkAgents)
+ {
+ ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
+ foreach (ContactResult r in agentHits)
+ results.Add(r);
+ }
+
+ // bug: will not detect phantom unless they are physical
+ // don't use ObjectIntersection because its also bad
+
+ }
+ else
{
- ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
- foreach (ContactResult r in objectHits)
- results.Add(r);
+ if (checkTerrain)
+ {
+ ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
+ if (groundContact != null)
+ results.Add((ContactResult)groundContact);
+ }
+
+ if (checkAgents)
+ {
+ ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
+ foreach (ContactResult r in agentHits)
+ results.Add(r);
+ }
+
+ if (checkPhysical || checkNonPhysical || detectPhantom)
+ {
+ ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
+ foreach (ContactResult r in objectHits)
+ results.Add(r);
+ }
}
results.Sort(delegate(ContactResult a, ContactResult b)
{
- return (int)(a.Depth - b.Depth);
+ return a.Depth.CompareTo(b.Depth);
});
int values = 0;
+ SceneObjectGroup thisgrp = m_host.ParentGroup;
+
foreach (ContactResult result in results)
{
if (result.Depth > dist)
continue;
+ // physics ray can return colisions with host prim
+ if (m_host.LocalId == result.ConsumerID)
+ continue;
+
UUID itemID = UUID.Zero;
int linkNum = 0;
@@ -11913,6 +11997,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// It's a prim!
if (part != null)
{
+ // dont detect members of same object ???
+ if (part.ParentGroup == thisgrp)
+ continue;
+
if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
itemID = part.ParentGroup.UUID;
else
@@ -11923,7 +12011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else
{
ScenePresence sp = World.GetScenePresence(result.ConsumerID);
- /// It it a boy? a girl?
+ /// It it a boy? a girl?
if (sp != null)
itemID = sp.UUID;
}
@@ -11934,14 +12022,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
list.Add(new LSL_Integer(linkNum));
-
if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
-
- values++;
- count--;
- if (count == 0)
+ values++;
+ if (values >= count)
break;
}