Merge branch 'master' of ssh://melanie@3dhosting.de/var/git/careminster into careminster
commit
ab1a3688e2
|
@ -1891,6 +1891,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
EventManager.TriggerPrimsLoaded(this);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a new rez location based on the raycast and the size of the object that is being rezzed.
|
/// Gets a new rez location based on the raycast and the size of the object that is being rezzed.
|
||||||
|
|
|
@ -753,7 +753,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (m_movementAnimationUpdateCounter >= 2)
|
if (m_movementAnimationUpdateCounter >= 2)
|
||||||
{
|
{
|
||||||
m_movementAnimationUpdateCounter = 0;
|
m_movementAnimationUpdateCounter = 0;
|
||||||
if (Animator != null)
|
if (Animator != null && ParentID == 0) // skip it if sitting
|
||||||
{
|
{
|
||||||
Animator.UpdateMovementAnimations();
|
Animator.UpdateMovementAnimations();
|
||||||
}
|
}
|
||||||
|
@ -1077,10 +1077,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void TeleportWithMomentum(Vector3 pos)
|
public void TeleportWithMomentum(Vector3 pos)
|
||||||
{
|
{
|
||||||
bool isFlying = Flying;
|
bool isFlying = Flying;
|
||||||
|
Vector3 vel = Velocity;
|
||||||
RemoveFromPhysicalScene();
|
RemoveFromPhysicalScene();
|
||||||
CheckLandingPoint(ref pos);
|
CheckLandingPoint(ref pos);
|
||||||
AbsolutePosition = pos;
|
AbsolutePosition = pos;
|
||||||
AddToPhysicalScene(isFlying);
|
AddToPhysicalScene(isFlying);
|
||||||
|
if (PhysicsActor != null)
|
||||||
|
PhysicsActor.SetMomentum(vel);
|
||||||
|
|
||||||
SendTerseUpdateToAllClients();
|
SendTerseUpdateToAllClients();
|
||||||
}
|
}
|
||||||
|
@ -1385,8 +1388,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (m_followCamAuto)
|
if (m_followCamAuto)
|
||||||
{
|
{
|
||||||
Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
|
// Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
|
||||||
m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public int m_eventsubscription = 0;
|
public int m_eventsubscription = 0;
|
||||||
private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
|
private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
|
||||||
|
|
||||||
|
private Vector3 m_taintMomentum = Vector3.Zero;
|
||||||
|
private bool m_haveTaintMomentum = false;
|
||||||
|
|
||||||
|
|
||||||
// unique UUID of this character object
|
// unique UUID of this character object
|
||||||
public UUID m_uuid;
|
public UUID m_uuid;
|
||||||
public bool bad = false;
|
public bool bad = false;
|
||||||
|
@ -800,8 +804,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (value.IsFinite())
|
if (value.IsFinite())
|
||||||
{
|
{
|
||||||
m_pidControllerActive = true;
|
|
||||||
_target_velocity = value;
|
_target_velocity = value;
|
||||||
|
m_pidControllerActive = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -911,6 +915,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
public override void SetMomentum(Vector3 momentum)
|
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
|
// 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.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"); // ##
|
//Console.WriteLine("DF 2"); // ##
|
||||||
|
|
||||||
|
@ -1327,7 +1348,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
lock (m_syncRoot)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_tainted_isPhysical != m_isPhysical)
|
if (m_tainted_isPhysical != m_isPhysical)
|
||||||
{
|
{
|
||||||
if (m_tainted_isPhysical)
|
if (m_tainted_isPhysical)
|
||||||
|
@ -1369,9 +1389,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
d.GeomDestroy(Shell);
|
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
|
// Remove any old entries
|
||||||
//string tShell;
|
//string tShell;
|
||||||
|
@ -1418,12 +1438,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,12 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
|
|
||||||
public virtual bool Phantom { get; set; }
|
public virtual bool Phantom { get; set; }
|
||||||
|
|
||||||
|
public virtual bool IsVolumeDtc
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual byte PhysicsShapeType { get; set; }
|
public virtual byte PhysicsShapeType { get; set; }
|
||||||
|
|
||||||
public abstract PrimitiveBaseShape Shape { set; }
|
public abstract PrimitiveBaseShape Shape { set; }
|
||||||
|
|
|
@ -43,6 +43,34 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public delegate void JointDeactivated(PhysicsJoint joint);
|
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 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
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contact result from a raycast.
|
/// Contact result from a raycast.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -54,6 +82,8 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public Vector3 Normal;
|
public Vector3 Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class PhysicsScene
|
public abstract class PhysicsScene
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -280,6 +310,16 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
return new List<ContactResult>();
|
return new List<ContactResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, RaycastCallback retMethod){}
|
||||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
|
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
|
||||||
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
|
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
|
||||||
|
|
|
@ -335,7 +335,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
if (primShape.SculptData.Length <= 0)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,7 +339,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
if (primShape.SculptData.Length <= 0)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,12 +115,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
|
private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
|
||||||
|
|
||||||
// Default, Collide with Other Geometries, spaces, bodies and characters.
|
// Default, Collide with Other Geometries, spaces, bodies and characters.
|
||||||
private CollisionCategories m_collisionFlags = (CollisionCategories.Geom
|
private CollisionCategories m_collisionFlags = (CollisionCategories.Character
|
||||||
| CollisionCategories.Space
|
| CollisionCategories.Geom
|
||||||
| CollisionCategories.Body
|
| CollisionCategories.VolumeDtc
|
||||||
| CollisionCategories.Character
|
|
||||||
);
|
);
|
||||||
// we do land collisions not ode | CollisionCategories.Land);
|
// we do land collisions not ode | CollisionCategories.Land);
|
||||||
public IntPtr Body = IntPtr.Zero;
|
public IntPtr Body = IntPtr.Zero;
|
||||||
private OdeScene _parent_scene;
|
private OdeScene _parent_scene;
|
||||||
public IntPtr Shell = IntPtr.Zero;
|
public IntPtr Shell = IntPtr.Zero;
|
||||||
|
@ -639,6 +638,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
public override void SetMomentum(Vector3 momentum)
|
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);
|
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||||
|
|
||||||
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
|
d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
|
d.GeomSetCollideBits(Shell, (uint)m_collisionFlags);
|
||||||
|
|
||||||
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
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.geom_name_map.Remove(Shell);
|
||||||
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
|
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
|
||||||
d.GeomDestroy(Shell);
|
d.GeomDestroy(Shell);
|
||||||
_parent_scene.geom_name_map.Remove(Shell);
|
|
||||||
Shell = IntPtr.Zero;
|
Shell = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -991,6 +991,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// end add Kitto Flora
|
// 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.IsFinite())
|
||||||
{
|
{
|
||||||
if (vec.X != 0 || vec.Y !=0 || vec.Z !=0)
|
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()
|
private void donullchange()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1395,6 +1413,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
case changes.Size:
|
case changes.Size:
|
||||||
changeSize((Vector3)arg);
|
changeSize((Vector3)arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case changes.Momentum:
|
||||||
|
changeMomentum((Vector3)arg);
|
||||||
|
break;
|
||||||
/* not in use for now
|
/* not in use for now
|
||||||
case changes.Shape:
|
case changes.Shape:
|
||||||
changeShape((PrimitiveBaseShape)arg);
|
changeShape((PrimitiveBaseShape)arg);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,10 +30,11 @@ using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using OpenMetaverse;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
using OdeAPI;
|
using OdeAPI;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.OdePlugin
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
|
@ -54,9 +55,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private OdeScene m_scene;
|
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 ColisionContactGeomsPerTest = 5;
|
||||||
|
private const int DefaultMaxCount = 25;
|
||||||
|
private const int MaxTimePerCallMS = 30;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ODE near callback delegate
|
/// ODE near callback delegate
|
||||||
|
@ -64,19 +67,22 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private d.NearCallback nearCallback;
|
private d.NearCallback nearCallback;
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
||||||
|
private RayFilterFlags CurrentRayFilter;
|
||||||
|
private int CurrentMaxCount;
|
||||||
|
|
||||||
public ODERayCastRequestManager(OdeScene pScene)
|
public ODERayCastRequestManager(OdeScene pScene)
|
||||||
{
|
{
|
||||||
m_scene = pScene;
|
m_scene = pScene;
|
||||||
nearCallback = near;
|
nearCallback = near;
|
||||||
ray = d.CreateRay(IntPtr.Zero, 1.0f);
|
ray = d.CreateRay(IntPtr.Zero, 1.0f);
|
||||||
|
d.GeomSetCategoryBits(ray,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queues a raycast
|
/// Queues request for a raycast to all world
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="position">Origin of Ray</param>
|
/// <param name="position">Origin of Ray</param>
|
||||||
/// <param name="direction">Ray normal</param>
|
/// <param name="direction">Ray direction</param>
|
||||||
/// <param name="length">Ray length</param>
|
/// <param name="length">Ray length</param>
|
||||||
/// <param name="retMethod">Return method to send the results</param>
|
/// <param name="retMethod">Return method to send the results</param>
|
||||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
||||||
|
@ -84,14 +90,22 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
ODERayRequest req = new ODERayRequest();
|
ODERayRequest req = new ODERayRequest();
|
||||||
req.geom = IntPtr.Zero;
|
req.geom = IntPtr.Zero;
|
||||||
req.callbackMethod = retMethod;
|
req.callbackMethod = retMethod;
|
||||||
req.Count = 0;
|
req.Count = DefaultMaxCount;
|
||||||
req.length = length;
|
req.length = length;
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queues request for a raycast to particular part
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">Origin of Ray</param>
|
||||||
|
/// <param name="direction">Ray direction</param>
|
||||||
|
/// <param name="length">Ray length</param>
|
||||||
|
/// <param name="retMethod">Return method to send the results</param>
|
||||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
||||||
{
|
{
|
||||||
ODERayRequest req = new ODERayRequest();
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
@ -100,7 +114,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.length = length;
|
req.length = length;
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = 0;
|
req.Count = DefaultMaxCount;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -110,10 +125,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
ODERayRequest req = new ODERayRequest();
|
ODERayRequest req = new ODERayRequest();
|
||||||
req.geom = IntPtr.Zero;
|
req.geom = IntPtr.Zero;
|
||||||
req.callbackMethod = retMethod;
|
req.callbackMethod = retMethod;
|
||||||
req.Count = 0;
|
req.Count = DefaultMaxCount;
|
||||||
req.length = length;
|
req.length = length;
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +142,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.length = length;
|
req.length = length;
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = 0;
|
req.Count = DefaultMaxCount;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -148,6 +165,22 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = count;
|
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);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -161,6 +194,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = count;
|
req.Count = count;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = count;
|
req.Count = count;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -187,6 +222,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = count;
|
req.Count = count;
|
||||||
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -197,63 +233,104 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// <returns>Time in MS the raycasts took to process.</returns>
|
/// <returns>Time in MS the raycasts took to process.</returns>
|
||||||
public int ProcessQueuedRequests()
|
public int ProcessQueuedRequests()
|
||||||
{
|
{
|
||||||
int time = System.Environment.TickCount;
|
|
||||||
|
|
||||||
if (m_PendingRequests.Count <= 0)
|
if (m_PendingRequests.Count <= 0)
|
||||||
return 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();
|
m_PendingRequests.Clear();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int time = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
ODERayRequest req;
|
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)
|
if (req.callbackMethod != null)
|
||||||
doSpaceRay(req);
|
{
|
||||||
else
|
CurrentRayFilter = req.filter;
|
||||||
doGeomRay(req);
|
CurrentMaxCount = req.Count;
|
||||||
if(--i < 0)
|
|
||||||
break;
|
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)
|
lock (m_contactResults)
|
||||||
m_contactResults.Clear();
|
m_contactResults.Clear();
|
||||||
|
|
||||||
return System.Environment.TickCount - time;
|
return Util.EnvironmentTickCountSubtract(time);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Method that actually initiates the raycast with full top space
|
/// Method that actually initiates the raycast with spaces
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="req"></param>
|
/// <param name="req"></param>
|
||||||
|
///
|
||||||
|
|
||||||
|
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)
|
private void doSpaceRay(ODERayRequest req)
|
||||||
{
|
{
|
||||||
// Create the ray
|
// Collide tests
|
||||||
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
|
if ((CurrentRayFilter & FilterActiveSpace) != 0)
|
||||||
d.GeomRaySetLength(ray, req.length);
|
d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
|
||||||
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
|
||||||
|
d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
|
||||||
// Collide test
|
|
||||||
d.SpaceCollide2(m_scene.TopSpace, ray, IntPtr.Zero, nearCallback);
|
|
||||||
|
|
||||||
// Remove Ray
|
|
||||||
// d.GeomDestroy(ray);
|
|
||||||
|
|
||||||
if (req.callbackMethod == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (req.callbackMethod is RaycastCallback)
|
if (req.callbackMethod is RaycastCallback)
|
||||||
{
|
{
|
||||||
// Define default results
|
// Define default results
|
||||||
bool hitYN = false;
|
bool hitYN = false;
|
||||||
uint hitConsumerID = 0;
|
uint hitConsumerID = 0;
|
||||||
float distance = 999999999999f;
|
float distance = float.MaxValue;
|
||||||
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
|
Vector3 closestcontact = Vector3.Zero;
|
||||||
Vector3 snormal = Vector3.Zero;
|
Vector3 snormal = Vector3.Zero;
|
||||||
|
|
||||||
// Find closest contact and object.
|
// Find closest contact and object.
|
||||||
|
@ -261,25 +338,30 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
foreach (ContactResult cResult in m_contactResults)
|
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;
|
closestcontact = cResult.Pos;
|
||||||
hitConsumerID = cResult.ConsumerID;
|
hitConsumerID = cResult.ConsumerID;
|
||||||
distance = cResult.Depth;
|
distance = cResult.Depth;
|
||||||
hitYN = true;
|
|
||||||
snormal = cResult.Normal;
|
snormal = cResult.Normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_contactResults.Clear();
|
m_contactResults.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (distance > 0 && distance < float.MaxValue)
|
||||||
|
hitYN = true;
|
||||||
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((RayCallback)req.callbackMethod)(m_contactResults);
|
List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
|
||||||
lock (m_PendingRequests)
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
cresult.AddRange(m_contactResults);
|
||||||
m_contactResults.Clear();
|
m_contactResults.Clear();
|
||||||
|
}
|
||||||
|
((RayCallback)req.callbackMethod)(cresult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,27 +371,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// <param name="req"></param>
|
/// <param name="req"></param>
|
||||||
private void doGeomRay(ODERayRequest req)
|
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
|
// Collide test
|
||||||
d.SpaceCollide2(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
|
d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
|
||||||
|
|
||||||
// Remove Ray
|
|
||||||
// d.GeomDestroy(ray);
|
|
||||||
|
|
||||||
if (req.callbackMethod == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (req.callbackMethod is RaycastCallback)
|
if (req.callbackMethod is RaycastCallback)
|
||||||
{
|
{
|
||||||
// Define default results
|
// Define default results
|
||||||
bool hitYN = false;
|
bool hitYN = false;
|
||||||
uint hitConsumerID = 0;
|
uint hitConsumerID = 0;
|
||||||
float distance = 999999999999f;
|
float distance = float.MaxValue;
|
||||||
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
|
Vector3 closestcontact = Vector3.Zero;
|
||||||
Vector3 snormal = Vector3.Zero;
|
Vector3 snormal = Vector3.Zero;
|
||||||
|
|
||||||
// Find closest contact and object.
|
// Find closest contact and object.
|
||||||
|
@ -317,25 +388,31 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
foreach (ContactResult cResult in m_contactResults)
|
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;
|
closestcontact = cResult.Pos;
|
||||||
hitConsumerID = cResult.ConsumerID;
|
hitConsumerID = cResult.ConsumerID;
|
||||||
distance = cResult.Depth;
|
distance = cResult.Depth;
|
||||||
hitYN = true;
|
|
||||||
snormal = cResult.Normal;
|
snormal = cResult.Normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_contactResults.Clear();
|
m_contactResults.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (distance > 0 && distance < float.MaxValue)
|
||||||
|
hitYN = true;
|
||||||
|
|
||||||
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((RayCallback)req.callbackMethod)(m_contactResults);
|
List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
|
||||||
lock (m_PendingRequests)
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
cresult.AddRange(m_contactResults);
|
||||||
m_contactResults.Clear();
|
m_contactResults.Clear();
|
||||||
|
}
|
||||||
|
((RayCallback)req.callbackMethod)(cresult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,20 +427,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return true;
|
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)
|
private void near(IntPtr space, IntPtr g1, IntPtr g2)
|
||||||
{
|
{
|
||||||
//Don't test against heightfield Geom, or you'll be sorry!
|
if (g2 == IntPtr.Zero || g1 == g2)
|
||||||
// Exclude heightfield geom
|
|
||||||
|
|
||||||
if (g1 == IntPtr.Zero || g1 == g2)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
|
if (m_contactResults.Count >= CurrentMaxCount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
|
if (d.GeomIsSpace(g2))
|
||||||
if (d.GeomIsSpace(g1))
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -381,10 +454,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
|
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)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PhysicsActor p1 = null;
|
uint ID = 0;
|
||||||
|
PhysicsActor p2 = null;
|
||||||
|
|
||||||
if (g1 != IntPtr.Zero)
|
m_scene.actor_name_map.TryGetValue(g2, out p2);
|
||||||
m_scene.actor_name_map.TryGetValue(g1, out p1);
|
|
||||||
|
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();
|
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))
|
// Loop all contacts, build results.
|
||||||
break;
|
for (int i = 0; i < count; i++)
|
||||||
if (p1 != null) {
|
{
|
||||||
if (p1 is OdePrim)
|
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.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
||||||
collisionresult.Depth = curcontact.depth;
|
collisionresult.Depth = curcontact.depth;
|
||||||
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
||||||
curcontact.normal.Z);
|
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()
|
internal void Dispose()
|
||||||
{
|
{
|
||||||
m_scene = null;
|
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 int Count;
|
||||||
public float length;
|
public float length;
|
||||||
public object callbackMethod;
|
public object callbackMethod;
|
||||||
|
public RayFilterFlags filter;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -889,13 +889,13 @@ namespace OdeAPI
|
||||||
public static extern IntPtr GeomGetBody(IntPtr geom);
|
public static extern IntPtr GeomGetBody(IntPtr geom);
|
||||||
|
|
||||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity]
|
[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]
|
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr GeomGetClassData(IntPtr geom);
|
public static extern IntPtr GeomGetClassData(IntPtr geom);
|
||||||
|
|
||||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity]
|
[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]
|
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern GeomClassID GeomGetClass(IntPtr geom);
|
public static extern GeomClassID GeomGetClass(IntPtr geom);
|
||||||
|
@ -1086,10 +1086,10 @@ namespace OdeAPI
|
||||||
public static extern void GeomSetBody(IntPtr geom, IntPtr body);
|
public static extern void GeomSetBody(IntPtr geom, IntPtr body);
|
||||||
|
|
||||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity]
|
[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]
|
[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]
|
[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);
|
public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||||
|
|
|
@ -60,19 +60,31 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public int lastframe;
|
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]
|
[Flags]
|
||||||
public enum CollisionCategories : int
|
public enum CollisionCategories : uint
|
||||||
{
|
{
|
||||||
Disabled = 0,
|
Disabled = 0,
|
||||||
Geom = 0x00000001,
|
//by 'things' types
|
||||||
Body = 0x00000002,
|
Space = 0x01,
|
||||||
Space = 0x00000004,
|
Geom = 0x02, // aka prim/part
|
||||||
Character = 0x00000008,
|
Character = 0x04,
|
||||||
Land = 0x00000010,
|
Land = 0x08,
|
||||||
Water = 0x00000020,
|
Water = 0x010,
|
||||||
Wind = 0x00000040,
|
|
||||||
Sensor = 0x00000080,
|
// by state
|
||||||
Selected = 0x00000100
|
Phantom = 0x01000,
|
||||||
|
VolumeDtc = 0x02000,
|
||||||
|
Selected = 0x04000,
|
||||||
|
NoShape = 0x08000,
|
||||||
|
|
||||||
|
|
||||||
|
All = 0xffffffff
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -116,6 +128,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
Acceleration,
|
Acceleration,
|
||||||
Force,
|
Force,
|
||||||
Torque,
|
Torque,
|
||||||
|
Momentum,
|
||||||
|
|
||||||
AddForce,
|
AddForce,
|
||||||
AddAngForce,
|
AddAngForce,
|
||||||
|
@ -186,7 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private float waterlevel = 0f;
|
private float waterlevel = 0f;
|
||||||
private int framecount = 0;
|
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 avPIDD = 2200f; // make it visible
|
||||||
public float avPIDP = 900f; // 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 geomCrossingFailuresBeforeOutofbounds = 6;
|
||||||
|
|
||||||
public int bodyFramesAutoDisable = 20;
|
public int bodyFramesAutoDisable = 5;
|
||||||
|
|
||||||
private float[] _watermap;
|
|
||||||
|
|
||||||
private d.NearCallback nearCallback;
|
private d.NearCallback nearCallback;
|
||||||
|
|
||||||
|
@ -350,7 +364,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// i must RtC#FM
|
// 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(ActiveSpace, -2, 8);
|
||||||
d.HashSpaceSetLevels(StaticSpace, -2, 8);
|
d.HashSpaceSetLevels(StaticSpace, -2, 8);
|
||||||
|
|
||||||
|
@ -358,13 +372,27 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.SpaceSetSublevel(ActiveSpace, 1);
|
d.SpaceSetSublevel(ActiveSpace, 1);
|
||||||
d.SpaceSetSublevel(StaticSpace, 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.JointGroupCreate(0);
|
||||||
//contactgroup
|
//contactgroup
|
||||||
|
|
||||||
d.WorldSetAutoDisableFlag(world, false);
|
d.WorldSetAutoDisableFlag(world, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_watermap = new float[258 * 258];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the mesh plugin
|
// Initialize the mesh plugin
|
||||||
|
@ -374,15 +402,18 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// checkThread();
|
// checkThread();
|
||||||
mesher = meshmerizer;
|
mesher = meshmerizer;
|
||||||
m_config = config;
|
m_config = config;
|
||||||
|
/*
|
||||||
string ode_config = d.GetConfiguration("ODE");
|
string ode_config = d.GetConfiguration("ODE");
|
||||||
m_log.WarnFormat("ODE configuration: {0}", ode_config);
|
if (ode_config != null && ode_config != "")
|
||||||
|
|
||||||
if (ode_config.Contains("ODE_Ubit"))
|
|
||||||
{
|
{
|
||||||
OdeUbitLib = true;
|
m_log.WarnFormat("ODE configuration: {0}", ode_config);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ode_config.Contains("ODE_Ubit"))
|
||||||
|
{
|
||||||
|
OdeUbitLib = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
if (region != null)
|
if (region != null)
|
||||||
{
|
{
|
||||||
|
@ -518,6 +549,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
waitForSpaceUnlock(newspace);
|
waitForSpaceUnlock(newspace);
|
||||||
d.SpaceSetSublevel(newspace, 2);
|
d.SpaceSetSublevel(newspace, 2);
|
||||||
d.HashSpaceSetLevels(newspace, -2, 8);
|
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;
|
staticPrimspace[i, j] = newspace;
|
||||||
}
|
}
|
||||||
// let this now be real maximum values
|
// let this now be real maximum values
|
||||||
|
@ -1745,8 +1785,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
m_rayCastManager.ProcessQueuedRequests();
|
m_rayCastManager.ProcessQueuedRequests();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
statray += Util.EnvironmentTickCountSubtract(statstart);
|
statray += Util.EnvironmentTickCountSubtract(statstart);
|
||||||
collision_optimized();
|
collision_optimized();
|
||||||
statcol += Util.EnvironmentTickCountSubtract(statstart);
|
statcol += Util.EnvironmentTickCountSubtract(statstart);
|
||||||
|
@ -2125,14 +2163,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
RegionTerrain.Remove(pOffset);
|
RegionTerrain.Remove(pOffset);
|
||||||
if (GroundGeom != IntPtr.Zero)
|
if (GroundGeom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
d.GeomDestroy(GroundGeom);
|
||||||
|
|
||||||
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
|
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
|
||||||
{
|
{
|
||||||
TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
|
TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
|
||||||
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
|
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
|
||||||
TerrainHeightFieldHeights.Remove(GroundGeom);
|
TerrainHeightFieldHeights.Remove(GroundGeom);
|
||||||
}
|
}
|
||||||
d.SpaceRemove(StaticSpace, GroundGeom);
|
|
||||||
d.GeomDestroy(GroundGeom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
|
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
|
||||||
|
@ -2147,8 +2185,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
|
GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
|
||||||
if (GroundGeom != IntPtr.Zero)
|
if (GroundGeom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
|
d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
|
||||||
d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
|
d.GeomSetCollideBits(GroundGeom, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
geom_name_map[GroundGeom] = "Terrain";
|
geom_name_map[GroundGeom] = "Terrain";
|
||||||
|
@ -2236,14 +2274,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
RegionTerrain.Remove(pOffset);
|
RegionTerrain.Remove(pOffset);
|
||||||
if (GroundGeom != IntPtr.Zero)
|
if (GroundGeom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
|
d.GeomDestroy(GroundGeom);
|
||||||
|
|
||||||
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
|
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
|
||||||
{
|
{
|
||||||
TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
|
if (TerrainHeightFieldHeightsHandlers[GroundGeom].IsAllocated)
|
||||||
|
TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
|
||||||
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
|
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
|
||||||
TerrainHeightFieldHeights.Remove(GroundGeom);
|
TerrainHeightFieldHeights.Remove(GroundGeom);
|
||||||
}
|
}
|
||||||
d.SpaceRemove(StaticSpace, GroundGeom);
|
|
||||||
d.GeomDestroy(GroundGeom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
|
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
|
||||||
|
@ -2263,8 +2302,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
|
GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
|
||||||
if (GroundGeom != IntPtr.Zero)
|
if (GroundGeom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
|
d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
|
||||||
d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
|
d.GeomSetCollideBits(GroundGeom, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
geom_name_map[GroundGeom] = "Terrain";
|
geom_name_map[GroundGeom] = "Terrain";
|
||||||
|
@ -2359,57 +2398,76 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
public void randomizeWater(float baseheight)
|
public void randomizeWater(float baseheight)
|
||||||
{
|
{
|
||||||
const uint heightmapWidth = m_regionWidth + 2;
|
const uint heightmapWidth = Constants.RegionSize + 2;
|
||||||
const uint heightmapHeight = m_regionHeight + 2;
|
const uint heightmapHeight = Constants.RegionSize + 2;
|
||||||
const uint heightmapWidthSamples = m_regionWidth + 2;
|
const uint heightmapWidthSamples = heightmapWidth + 1;
|
||||||
const uint heightmapHeightSamples = m_regionHeight + 2;
|
const uint heightmapHeightSamples = heightmapHeight + 1;
|
||||||
|
|
||||||
const float scale = 1.0f;
|
const float scale = 1.0f;
|
||||||
const float offset = 0.0f;
|
const float offset = 0.0f;
|
||||||
const float thickness = 2.9f;
|
|
||||||
const int wrap = 0;
|
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)
|
lock (OdeLock)
|
||||||
{
|
{
|
||||||
if (WaterGeom != IntPtr.Zero)
|
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,
|
(int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
|
||||||
offset, thickness, wrap);
|
offset, thickness, wrap);
|
||||||
d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight);
|
d.GeomHeightfieldDataSetBounds(WaterHeightmapData, minheigh, maxheigh);
|
||||||
WaterGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
|
WaterGeom = d.CreateHeightfield(StaticSpace, WaterHeightmapData, 1);
|
||||||
if (WaterGeom != IntPtr.Zero)
|
if (WaterGeom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water));
|
d.GeomSetCategoryBits(WaterGeom, (uint)(CollisionCategories.Water));
|
||||||
d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space));
|
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()
|
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)
|
if (ContactgeomsArray != IntPtr.Zero)
|
||||||
Marshal.FreeHGlobal(ContactgeomsArray);
|
Marshal.FreeHGlobal(ContactgeomsArray);
|
||||||
if (GlobalContactsArray != IntPtr.Zero)
|
if (GlobalContactsArray != IntPtr.Zero)
|
||||||
Marshal.FreeHGlobal(GlobalContactsArray);
|
Marshal.FreeHGlobal(GlobalContactsArray);
|
||||||
|
|
||||||
|
|
||||||
d.WorldDestroy(world);
|
d.WorldDestroy(world);
|
||||||
//d.CloseODE();
|
//d.CloseODE();
|
||||||
}
|
}
|
||||||
|
@ -2502,6 +2583,35 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return new List<ContactResult>(ourResults);
|
return new List<ContactResult>(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<ContactResult> ourresults = new List<ContactResult>();
|
||||||
|
|
||||||
|
RayCallback retMethod = delegate(List<ContactResult> 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)
|
public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
||||||
{
|
{
|
||||||
if (retMethod != null && actor !=null)
|
if (retMethod != null && actor !=null)
|
||||||
|
|
|
@ -9980,7 +9980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// return total object mass
|
// return total object mass
|
||||||
SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
|
SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
|
||||||
if (obj != null)
|
if (obj != null)
|
||||||
return (double)obj.GetMass();
|
return obj.GetMass();
|
||||||
|
|
||||||
// the object is null so the key is for an avatar
|
// the object is null so the key is for an avatar
|
||||||
ScenePresence avatar = World.GetScenePresence(key);
|
ScenePresence avatar = World.GetScenePresence(key);
|
||||||
|
@ -9990,7 +9990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// child agents have a mass of 1.0
|
// child agents have a mass of 1.0
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return (double)avatar.PhysicsActor.Mass;
|
return avatar.GetMass();
|
||||||
}
|
}
|
||||||
catch (KeyNotFoundException)
|
catch (KeyNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -11834,6 +11834,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
return contacts[0];
|
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)
|
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 checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
|
||||||
bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
|
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);
|
if (dist == 0)
|
||||||
foreach (ContactResult r in agentHits)
|
return list;
|
||||||
results.Add(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
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<ContactResult>)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);
|
if (checkTerrain)
|
||||||
foreach (ContactResult r in objectHits)
|
{
|
||||||
results.Add(r);
|
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)
|
results.Sort(delegate(ContactResult a, ContactResult b)
|
||||||
{
|
{
|
||||||
return (int)(a.Depth - b.Depth);
|
return a.Depth.CompareTo(b.Depth);
|
||||||
});
|
});
|
||||||
|
|
||||||
int values = 0;
|
int values = 0;
|
||||||
|
SceneObjectGroup thisgrp = m_host.ParentGroup;
|
||||||
|
|
||||||
foreach (ContactResult result in results)
|
foreach (ContactResult result in results)
|
||||||
{
|
{
|
||||||
if (result.Depth > dist)
|
if (result.Depth > dist)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// physics ray can return colisions with host prim
|
||||||
|
if (m_host.LocalId == result.ConsumerID)
|
||||||
|
continue;
|
||||||
|
|
||||||
UUID itemID = UUID.Zero;
|
UUID itemID = UUID.Zero;
|
||||||
int linkNum = 0;
|
int linkNum = 0;
|
||||||
|
|
||||||
|
@ -11913,6 +11997,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// It's a prim!
|
// It's a prim!
|
||||||
if (part != null)
|
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)
|
if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
|
||||||
itemID = part.ParentGroup.UUID;
|
itemID = part.ParentGroup.UUID;
|
||||||
else
|
else
|
||||||
|
@ -11923,7 +12011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScenePresence sp = World.GetScenePresence(result.ConsumerID);
|
ScenePresence sp = World.GetScenePresence(result.ConsumerID);
|
||||||
/// It it a boy? a girl?
|
/// It it a boy? a girl?
|
||||||
if (sp != null)
|
if (sp != null)
|
||||||
itemID = sp.UUID;
|
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)
|
if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
|
||||||
list.Add(new LSL_Integer(linkNum));
|
list.Add(new LSL_Integer(linkNum));
|
||||||
|
|
||||||
|
|
||||||
if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
|
if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
|
||||||
list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
|
list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
|
||||||
|
|
||||||
values++;
|
|
||||||
count--;
|
|
||||||
|
|
||||||
if (count == 0)
|
values++;
|
||||||
|
if (values >= count)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue