ubitODE + physmanager: - Revised use of ODE collisions categories and bits(flags) for better use as filters together with top spaces (for example physical prims are on topactivespace and not physical are on topstaticspace) - Added new world raycast with filters. This blocks calling thread with a timeout of 500ms waiting for heartbeat ode thread signal job done. - Don't let ode bodies being disabled for 2 long except for vehicles. This is necessary to detect when the object is at rest at top of other and that is removed. Assume that vehicles can be enabled by used action.
parent
3999822e13
commit
86a2169d73
|
@ -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)
|
||||||
|
|
|
@ -115,10 +115,8 @@ 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.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;
|
||||||
|
@ -639,6 +637,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 +663,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 +759,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1324,6 +1323,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 +1404,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);
|
||||||
|
|
|
@ -108,25 +108,29 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private float m_waterHeight;
|
private float m_waterHeight;
|
||||||
private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
|
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
|
// Default we're a Geometry
|
||||||
private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
|
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
|
// 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;
|
public bool m_disabled;
|
||||||
|
|
||||||
|
@ -179,6 +183,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public float primOOBradiusSQ;
|
public float primOOBradiusSQ;
|
||||||
public d.Mass primdMass; // prim inertia information on it's own referencial
|
public d.Mass primdMass; // prim inertia information on it's own referencial
|
||||||
float primMass; // prim own mass
|
float primMass; // prim own mass
|
||||||
|
float primVolume; // prim own volume;
|
||||||
float _mass; // object mass acording to case
|
float _mass; // object mass acording to case
|
||||||
private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
|
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
|
public override bool Phantom // this is not reliable for internal use
|
||||||
{
|
{
|
||||||
get { return m_fakeisphantom; }
|
get { return m_fakeisphantom; }
|
||||||
|
@ -327,10 +340,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_colliderfilter == 0)
|
if (m_colliderfilter == 0)
|
||||||
{
|
|
||||||
m_softcolide = false;
|
|
||||||
m_iscolliding = false;
|
m_iscolliding = false;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
m_iscolliding = true;
|
m_iscolliding = true;
|
||||||
}
|
}
|
||||||
|
@ -422,6 +432,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
public override Vector3 GeometricCenter
|
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
|
get
|
||||||
{
|
{
|
||||||
return Vector3.Zero;
|
return Vector3.Zero;
|
||||||
|
@ -949,7 +963,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
m_iscolliding = false;
|
m_iscolliding = false;
|
||||||
m_colliderfilter = 0;
|
m_colliderfilter = 0;
|
||||||
m_softcolide = true;
|
|
||||||
m_NoColide = false;
|
m_NoColide = false;
|
||||||
|
|
||||||
hasOOBoffsetFromMesh = false;
|
hasOOBoffsetFromMesh = false;
|
||||||
|
@ -992,6 +1005,132 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
m_collisionscore = 0;
|
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)
|
private void createAMotor(Vector3 axis)
|
||||||
{
|
{
|
||||||
if (Body == IntPtr.Zero)
|
if (Body == IntPtr.Zero)
|
||||||
|
@ -1188,7 +1327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomSetCategoryBits(prim_geom, 0);
|
d.GeomSetCategoryBits(prim_geom, 0);
|
||||||
if (m_isphysical)
|
if (m_isphysical)
|
||||||
{
|
{
|
||||||
d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
|
d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1198,8 +1337,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
|
d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
CalcPrimBodyData();
|
CalcPrimBodyData();
|
||||||
|
@ -1296,6 +1435,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
prim_geom = IntPtr.Zero;
|
prim_geom = IntPtr.Zero;
|
||||||
|
collide_geom = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1319,66 +1459,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace);
|
IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace);
|
||||||
prim.m_targetSpace = targetSpace;
|
prim.m_targetSpace = targetSpace;
|
||||||
d.GeomEnable(prim_geom);
|
collide_geom = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableBodySoft()
|
public void enableBodySoft()
|
||||||
{
|
{
|
||||||
|
m_disabled = false;
|
||||||
if (!childPrim && !m_isSelected)
|
if (!childPrim && !m_isSelected)
|
||||||
{
|
{
|
||||||
if (m_isphysical && Body != IntPtr.Zero)
|
if (m_isphysical && Body != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
if (m_isphantom && !m_isVolumeDetect)
|
UpdateCollisionCatFlags();
|
||||||
{
|
ApplyCollisionCatFlags();
|
||||||
m_collisionCategories = 0;
|
|
||||||
m_collisionFlags = CollisionCategories.Land;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_collisionCategories |= CollisionCategories.Body;
|
|
||||||
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
d.BodyEnable(Body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_disabled = false;
|
resetCollisionAccounting();
|
||||||
resetCollisionAccounting(); // this sets m_disable to false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableBodySoft()
|
private void disableBodySoft()
|
||||||
|
@ -1388,45 +1485,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (m_isphysical && Body != IntPtr.Zero)
|
if (m_isphysical && Body != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
m_collisionCategories &= ~CollisionCategories.Body;
|
if (m_isSelected)
|
||||||
m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
|
m_collisionFlags = CollisionCategories.Selected;
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
m_collisionCategories = 0;
|
||||||
d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
|
m_collisionFlags = 0;
|
||||||
d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
|
ApplyCollisionCatFlags();
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
d.BodyDisable(Body);
|
d.BodyDisable(Body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1566,7 +1630,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// d.BodySetAngularDampingThreshold(Body, 0.001f);
|
// d.BodySetAngularDampingThreshold(Body, 0.001f);
|
||||||
d.BodySetDamping(Body, .002f, .002f);
|
d.BodySetDamping(Body, .002f, .002f);
|
||||||
|
|
||||||
|
|
||||||
if (m_targetSpace != IntPtr.Zero)
|
if (m_targetSpace != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||||
|
@ -1588,6 +1651,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.SpaceSetSublevel(m_targetSpace, 3);
|
d.SpaceSetSublevel(m_targetSpace, 3);
|
||||||
d.SpaceSetCleanup(m_targetSpace, false);
|
d.SpaceSetCleanup(m_targetSpace, false);
|
||||||
d.SpaceAdd(m_targetSpace, prim_geom);
|
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;
|
collide_geom = m_targetSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1619,38 +1689,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.SpaceAdd(m_targetSpace, prm.prim_geom);
|
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;
|
prm.m_collisionscore = 0;
|
||||||
|
|
||||||
if(!m_disabled)
|
if(!m_disabled)
|
||||||
|
@ -1666,45 +1704,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
createAMotor(m_angularlock);
|
createAMotor(m_angularlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_collisionscore = 0;
|
||||||
|
|
||||||
|
UpdateCollisionCatFlags();
|
||||||
|
ApplyCollisionCatFlags();
|
||||||
|
|
||||||
if (m_isSelected || m_disabled)
|
if (m_isSelected || m_disabled)
|
||||||
{
|
{
|
||||||
m_collisionCategories &= ~CollisionCategories.Body;
|
|
||||||
m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
|
|
||||||
|
|
||||||
d.GeomDisable(prim_geom);
|
|
||||||
d.BodyDisable(Body);
|
d.BodyDisable(Body);
|
||||||
}
|
}
|
||||||
else
|
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.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
|
||||||
d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.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.addActivePrim(this);
|
||||||
_parent_scene.addActiveGroups(this);
|
_parent_scene.addActiveGroups(this);
|
||||||
}
|
}
|
||||||
|
@ -1714,8 +1728,22 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (Body != IntPtr.Zero)
|
if (Body != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
_parent_scene.remActivePrim(this);
|
_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 (prim_geom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
if (m_NoColide)
|
if (m_NoColide)
|
||||||
|
@ -1725,8 +1753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
|
d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
|
||||||
}
|
}
|
||||||
UpdateDataFromGeom();
|
UpdateDataFromGeom();
|
||||||
d.GeomSetBody(prim_geom, IntPtr.Zero);
|
d.GeomSetBody(prim_geom, IntPtr.Zero);
|
||||||
|
@ -1740,8 +1768,18 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
foreach (OdePrim prm in childrenPrim)
|
foreach (OdePrim prm in childrenPrim)
|
||||||
{
|
{
|
||||||
_parent_scene.remActivePrim(prm);
|
_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.prim_geom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
if (prm.m_NoColide)
|
if (prm.m_NoColide)
|
||||||
|
@ -1751,8 +1789,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
|
d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
|
||||||
d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
|
d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
|
||||||
}
|
}
|
||||||
prm.UpdateDataFromGeom();
|
prm.UpdateDataFromGeom();
|
||||||
SetInStaticSpace(prm);
|
SetInStaticSpace(prm);
|
||||||
|
@ -2292,6 +2330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// keep using basic shape mass for now
|
// keep using basic shape mass for now
|
||||||
volume = CalculatePrimVolume();
|
volume = CalculatePrimVolume();
|
||||||
|
|
||||||
|
primVolume = volume;
|
||||||
primMass = m_density * volume;
|
primMass = m_density * volume;
|
||||||
|
|
||||||
if (primMass <= 0)
|
if (primMass <= 0)
|
||||||
|
@ -2515,11 +2554,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomSetQuaternion(prim_geom, ref myrot);
|
d.GeomSetQuaternion(prim_geom, ref myrot);
|
||||||
|
|
||||||
if (!m_isphysical)
|
if (!m_isphysical)
|
||||||
SetInStaticSpace(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_isphysical && Body == IntPtr.Zero)
|
|
||||||
{
|
{
|
||||||
|
SetInStaticSpace(this);
|
||||||
|
UpdateCollisionCatFlags();
|
||||||
|
ApplyCollisionCatFlags();
|
||||||
|
}
|
||||||
|
else
|
||||||
MakeBody();
|
MakeBody();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2602,86 +2642,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void changePhantomStatus(bool newval)
|
private void changePhantomStatus(bool newval)
|
||||||
{
|
{
|
||||||
m_isphantom = newval;
|
m_isphantom = newval;
|
||||||
|
|
||||||
if (m_isSelected)
|
UpdateCollisionCatFlags();
|
||||||
{
|
ApplyCollisionCatFlags();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeSelectedStatus(bool newval)
|
private void changeSelectedStatus(bool newval)
|
||||||
|
@ -2714,7 +2680,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (m_delaySelect || m_isphysical)
|
if (m_delaySelect || m_isphysical)
|
||||||
{
|
{
|
||||||
m_collisionCategories = CollisionCategories.Selected;
|
m_collisionCategories = CollisionCategories.Selected;
|
||||||
m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
|
m_collisionFlags = 0;
|
||||||
|
|
||||||
if (!childPrim)
|
if (!childPrim)
|
||||||
{
|
{
|
||||||
|
@ -2733,10 +2699,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
|
d.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
|
d.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags);
|
||||||
}
|
}
|
||||||
d.GeomDisable(prm.prim_geom);
|
|
||||||
}
|
}
|
||||||
prm.m_delaySelect = false;
|
prm.m_delaySelect = false;
|
||||||
}
|
}
|
||||||
|
@ -2748,13 +2713,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(prim_geom, 0);
|
d.GeomSetCategoryBits(prim_geom, 0);
|
||||||
d.GeomSetCollideBits(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
|
else
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
|
d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
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;
|
m_delaySelect = false;
|
||||||
|
@ -2769,75 +2744,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (!childPrim && Body != IntPtr.Zero && !m_disabled)
|
if (!childPrim && Body != IntPtr.Zero && !m_disabled)
|
||||||
d.BodyEnable(Body);
|
d.BodyEnable(Body);
|
||||||
|
|
||||||
if (m_isphantom && !m_isVolumeDetect)
|
UpdateCollisionCatFlags();
|
||||||
{
|
ApplyCollisionCatFlags();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_delaySelect = false;
|
m_delaySelect = false;
|
||||||
m_softcolide = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resetCollisionAccounting();
|
resetCollisionAccounting();
|
||||||
|
@ -2890,7 +2800,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (givefakepos < 0)
|
if (givefakepos < 0)
|
||||||
givefakepos = 0;
|
givefakepos = 0;
|
||||||
// changeSelectedStatus();
|
// changeSelectedStatus();
|
||||||
m_softcolide = true;
|
|
||||||
resetCollisionAccounting();
|
resetCollisionAccounting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2951,7 +2860,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
givefakeori--;
|
givefakeori--;
|
||||||
if (givefakeori < 0)
|
if (givefakeori < 0)
|
||||||
givefakeori = 0;
|
givefakeori = 0;
|
||||||
m_softcolide = true;
|
|
||||||
resetCollisionAccounting();
|
resetCollisionAccounting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3022,7 +2930,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (givefakeori < 0)
|
if (givefakeori < 0)
|
||||||
givefakeori = 0;
|
givefakeori = 0;
|
||||||
|
|
||||||
m_softcolide = true;
|
|
||||||
resetCollisionAccounting();
|
resetCollisionAccounting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3111,6 +3018,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomSetQuaternion(prim_geom, ref myrot);
|
d.GeomSetQuaternion(prim_geom, ref myrot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_isphysical)
|
||||||
|
{
|
||||||
if (chp)
|
if (chp)
|
||||||
{
|
{
|
||||||
if (parent != null)
|
if (parent != null)
|
||||||
|
@ -3120,8 +3029,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MakeBody();
|
MakeBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateCollisionCatFlags();
|
||||||
|
ApplyCollisionCatFlags();
|
||||||
|
}
|
||||||
|
|
||||||
m_softcolide = true;
|
|
||||||
resetCollisionAccounting();
|
resetCollisionAccounting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3142,18 +3057,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
m_collidesWater = newval;
|
m_collidesWater = newval;
|
||||||
|
|
||||||
if (prim_geom != IntPtr.Zero && !m_isphantom)
|
UpdateCollisionCatFlags();
|
||||||
{
|
ApplyCollisionCatFlags();
|
||||||
if (m_collidesWater)
|
|
||||||
{
|
|
||||||
m_collisionFlags |= CollisionCategories.Water;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_collisionFlags &= ~CollisionCategories.Water;
|
|
||||||
}
|
|
||||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeSetTorque(Vector3 newtorque)
|
private void changeSetTorque(Vector3 newtorque)
|
||||||
|
@ -3240,6 +3145,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private void changeVolumedetetion(bool newVolDtc)
|
private void changeVolumedetetion(bool newVolDtc)
|
||||||
{
|
{
|
||||||
m_isVolumeDetect = newVolDtc;
|
m_isVolumeDetect = newVolDtc;
|
||||||
|
UpdateCollisionCatFlags();
|
||||||
|
ApplyCollisionCatFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void changeBuilding(bool newbuilding)
|
protected void changeBuilding(bool newbuilding)
|
||||||
|
@ -3320,11 +3227,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public void Move()
|
public void Move()
|
||||||
{
|
{
|
||||||
if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
|
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)
|
// !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
|
||||||
|
|
||||||
|
if (d.BodyIsEnabled(Body))
|
||||||
|
{
|
||||||
float timestep = _parent_scene.ODE_STEPSIZE;
|
float timestep = _parent_scene.ODE_STEPSIZE;
|
||||||
|
|
||||||
// check outside region
|
// check outside region
|
||||||
|
@ -3369,7 +3278,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
_position.X = Util.Clip(lpos.X, -2f, -0.1f);
|
_position.X = Util.Clip(lpos.X, -2f, -0.1f);
|
||||||
m_outbounds = true;
|
m_outbounds = true;
|
||||||
}
|
}
|
||||||
else if(lpos.X > _parent_scene.WorldExtents.X)
|
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);
|
_position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
|
||||||
m_outbounds = true;
|
m_outbounds = true;
|
||||||
|
@ -3379,13 +3288,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
_position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
|
_position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
|
||||||
m_outbounds = true;
|
m_outbounds = true;
|
||||||
}
|
}
|
||||||
else if(lpos.Y > _parent_scene.WorldExtents.Y)
|
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);
|
_position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
|
||||||
m_outbounds = true;
|
m_outbounds = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_outbounds)
|
if (m_outbounds)
|
||||||
{
|
{
|
||||||
m_lastposition = _position;
|
m_lastposition = _position;
|
||||||
m_lastorientation = _orientation;
|
m_lastorientation = _orientation;
|
||||||
|
@ -3408,18 +3317,20 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||||
|
{
|
||||||
|
// 'VEHICLES' are dealt with in ODEDynamics.cs
|
||||||
|
m_vehicle.Step();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
float fx = 0;
|
float fx = 0;
|
||||||
float fy = 0;
|
float fy = 0;
|
||||||
float fz = 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;
|
float m_mass = _mass;
|
||||||
|
|
||||||
// fz = 0f;
|
// fz = 0f;
|
||||||
|
@ -3604,6 +3515,20 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // body disabled
|
||||||
|
{
|
||||||
|
// let vehicles sleep
|
||||||
|
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (++bodydisablecontrol < 20)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bodydisablecontrol = 0;
|
||||||
|
d.BodyEnable(Body);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{ // is not physical, or is not a body or is selected
|
{ // is not physical, or is not a body or is selected
|
||||||
// _zeroPosition = d.BodyGetPosition(Body);
|
// _zeroPosition = d.BodyGetPosition(Body);
|
||||||
|
|
|
@ -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.AllButLand;
|
||||||
|
|
||||||
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.AllButLand;
|
||||||
|
|
||||||
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.AllButLand;
|
||||||
|
|
||||||
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.AllButLand;
|
||||||
|
|
||||||
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.AllButLand;
|
||||||
|
|
||||||
|
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.AllButLand;
|
||||||
|
|
||||||
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.AllButLand;
|
||||||
|
|
||||||
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.AllButLand;
|
||||||
|
|
||||||
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.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)
|
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);
|
doSpaceRay(req);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// if we select a geom don't use filters
|
||||||
|
d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
|
||||||
doGeomRay(req);
|
doGeomRay(req);
|
||||||
if(--i < 0)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS)
|
||||||
break;
|
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,26 +338,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -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,26 +388,32 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
|
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
|
||||||
|
@ -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,32 +463,117 @@ 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.
|
|
||||||
|
// closestHit for now only works for meshs, so must do it for others
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
|
||||||
|
{
|
||||||
|
// Loop all contacts, build results.
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (!GetCurContactGeom(i, ref curcontact))
|
if (!GetCurContactGeom(i, ref curcontact))
|
||||||
break;
|
break;
|
||||||
if (p1 != null) {
|
|
||||||
if (p1 is OdePrim)
|
|
||||||
{
|
|
||||||
ContactResult collisionresult = new ContactResult();
|
|
||||||
|
|
||||||
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
|
ContactResult collisionresult = new ContactResult();
|
||||||
|
collisionresult.ConsumerID = ID;
|
||||||
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)
|
lock (m_contactResults)
|
||||||
|
{
|
||||||
m_contactResults.Add(collisionresult);
|
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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collisionresult.Depth != float.MaxValue)
|
||||||
|
{
|
||||||
|
lock (m_contactResults)
|
||||||
|
m_contactResults.Add(collisionresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -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");
|
||||||
|
if (ode_config != null && ode_config != "")
|
||||||
|
{
|
||||||
m_log.WarnFormat("ODE configuration: {0}", ode_config);
|
m_log.WarnFormat("ODE configuration: {0}", ode_config);
|
||||||
|
|
||||||
if (ode_config.Contains("ODE_Ubit"))
|
if (ode_config.Contains("ODE_Ubit"))
|
||||||
{
|
{
|
||||||
OdeUbitLib = true;
|
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))
|
||||||
{
|
{
|
||||||
|
if (TerrainHeightFieldHeightsHandlers[GroundGeom].IsAllocated)
|
||||||
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();
|
||||||
|
@ -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,39 +2398,59 @@ 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";
|
geom_name_map[WaterGeom] = "Water";
|
||||||
|
|
||||||
d.Matrix3 R = new d.Matrix3();
|
d.Matrix3 R = new d.Matrix3();
|
||||||
|
@ -2406,10 +2465,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
|
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
|
||||||
d.GeomSetRotation(WaterGeom, ref R);
|
d.GeomSetRotation(WaterGeom, ref R);
|
||||||
d.GeomSetPosition(WaterGeom, 128, 128, 0);
|
d.GeomSetPosition(WaterGeom, (float)Constants.RegionSize * 0.5f, (float)Constants.RegionSize * 0.5f, 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)
|
||||||
|
|
Loading…
Reference in New Issue