diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 46bfa59271..ce269fabc1 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -246,6 +246,9 @@ namespace OpenSim.Region.Physics.Manager
public abstract void AddPhysicsActorTaint(PhysicsActor prim);
+
+ public virtual void PrepareSimulation() { }
+
///
/// Perform a simulation of the current physics scene over the given timestep.
///
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index c2c4384efb..535a4e2fb0 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -1325,12 +1325,48 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+
+ private void SetGeom(IntPtr geom)
+ {
+ prim_geom = geom;
+ //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
+ if (prim_geom != IntPtr.Zero)
+ {
+
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ if (m_isphysical)
+ {
+ d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCollideBits(prim_geom, 0);
+ d.GeomDisable(prim_geom);
+ }
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
+ }
+
+ UpdatePrimBodyData();
+ _parent_scene.actor_name_map[prim_geom] = this;
+
+ }
+ else
+ m_log.Warn("Setting bad Geom");
+ }
+
private bool GetMeshGeom()
{
IntPtr vertices, indices;
int vertexCount, indexCount;
int vertexStride, triStride;
+
IMesh mesh = m_mesh;
if (mesh == null)
@@ -1356,6 +1392,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_mesh = null;
return false;
}
+
+ IntPtr geo = IntPtr.Zero;
+
try
{
_triMeshData = d.GeomTriMeshDataCreate();
@@ -1363,7 +1402,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
d.GeomTriMeshDataPreprocess(_triMeshData);
- prim_geom = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
+ geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
}
catch (Exception e)
@@ -1380,15 +1419,15 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
_triMeshData = IntPtr.Zero;
- prim_geom = IntPtr.Zero;
m_hasOBB = false;
m_OBBOffset = Vector3.Zero;
m_OBB = _size * 0.5f;
m_physCost = 0.1f;
- m_streamCost = 1.0f;
+ m_streamCost = 1.0f;
+
_parent_scene.mesher.ReleaseMesh(mesh);
- m_meshState = MeshState.AssetFailed;
+ m_meshState = MeshState.MeshFailed;
m_mesh = null;
return false;
}
@@ -1397,12 +1436,13 @@ namespace OpenSim.Region.Physics.OdePlugin
// todo
m_streamCost = 1.0f;
+ SetGeom(geo);
+
return true;
}
private void CreateGeom()
{
- IntPtr geo = IntPtr.Zero;
bool hasMesh = false;
m_NoColide = false;
@@ -1418,8 +1458,11 @@ namespace OpenSim.Region.Physics.OdePlugin
m_NoColide = true;
}
+
if (!hasMesh)
{
+ IntPtr geo = IntPtr.Zero;
+
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
&& _size.X == _size.Y && _size.Y == _size.Z)
{ // it's a sphere
@@ -1447,7 +1490,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
m_physCost = 0.1f;
m_streamCost = 1.0f;
- prim_geom = geo;
+ SetGeom(geo);
}
}
@@ -2740,8 +2783,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
}
-
-
private void changeAddPhysRep(ODEPhysRepData repData)
{
_size = repData.size; //??
@@ -2763,10 +2804,6 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim_geom != IntPtr.Zero)
{
- UpdatePrimBodyData();
-
- _parent_scene.actor_name_map[prim_geom] = this;
-
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
d.Quaternion myrot = new d.Quaternion();
myrot.X = _orientation.X;
@@ -2774,23 +2811,23 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.Z = _orientation.Z;
myrot.W = _orientation.W;
d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
- if (!m_isphysical)
- {
- SetInStaticSpace(this);
- UpdateCollisionCatFlags();
- ApplyCollisionCatFlags();
- }
- else
- MakeBody();
+ if (!m_isphysical)
+ {
+ SetInStaticSpace(this);
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
+ }
+ else
+ MakeBody();
- if ((m_meshState & MeshState.NeedMask) != 0)
- {
- repData.size = _size;
- repData.pbs = _pbs;
- repData.shapetype = m_shapetype;
- _parent_scene.m_meshWorker.RequestMesh(repData);
- }
+ if ((m_meshState & MeshState.NeedMask) != 0)
+ {
+ repData.size = _size;
+ repData.pbs = _pbs;
+ repData.shapetype = m_shapetype;
+ _parent_scene.m_meshWorker.RequestMesh(repData);
}
}
@@ -2831,14 +2868,10 @@ namespace OpenSim.Region.Physics.OdePlugin
primVolume = repData.volume;
- CreateGeom();
+ CreateGeom();
if (prim_geom != IntPtr.Zero)
{
- UpdatePrimBodyData();
-
- _parent_scene.actor_name_map[prim_geom] = this;
-
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
d.Quaternion myrot = new d.Quaternion();
myrot.X = _orientation.X;
@@ -2846,30 +2879,29 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.Z = _orientation.Z;
myrot.W = _orientation.W;
d.GeomSetQuaternion(prim_geom, ref myrot);
-
- if (m_isphysical)
- {
- if (chp)
- {
- if (parent != null)
- {
- parent.MakeBody();
- }
- }
- else
- MakeBody();
- }
-
- else
- {
- SetInStaticSpace(this);
- UpdateCollisionCatFlags();
- ApplyCollisionCatFlags();
- }
-
- resetCollisionAccounting();
}
+ if (m_isphysical)
+ {
+ if (chp)
+ {
+ if (parent != null)
+ {
+ parent.MakeBody();
+ }
+ }
+ else
+ MakeBody();
+ }
+ else
+ {
+ SetInStaticSpace(this);
+ UpdateCollisionCatFlags();
+ ApplyCollisionCatFlags();
+ }
+
+ resetCollisionAccounting();
+
if ((m_meshState & MeshState.NeedMask) != 0)
{
repData.size = _size;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 21fe9c08f7..06cb3029b4 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -129,7 +129,7 @@ namespace OpenSim.Region.Physics.OdePlugin
req.length = length;
req.Normal = direction;
req.Origin = position;
- req.filter = RayFilterFlags.AllPrims;
+ req.filter = RayFilterFlags.AllPrims | RayFilterFlags.land;
m_PendingRequests.Enqueue(req);
}
@@ -261,6 +261,12 @@ namespace OpenSim.Region.Physics.OdePlugin
closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
+ // current ode land to ray collisions is very bad
+ // so for now limit its range badly
+
+ if (req.length > 30.0f && (CurrentRayFilter & RayFilterFlags.land) != 0)
+ req.length = 30.0f;
+
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);
@@ -288,7 +294,10 @@ namespace OpenSim.Region.Physics.OdePlugin
catflags |= CollisionCategories.Water;
if (catflags != 0)
+ {
+ d.GeomSetCollideBits(ray, (uint)catflags);
doSpaceRay(req);
+ }
}
else
{
@@ -314,7 +323,8 @@ namespace OpenSim.Region.Physics.OdePlugin
///
private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
- private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
+// private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
+ private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
private void doSpaceRay(ODERayRequest req)
{
@@ -323,6 +333,8 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
+ if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
+ d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
if (req.callbackMethod is RaycastCallback)
{
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index ed2a531f55..beaba13280 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -300,6 +300,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public IntPtr TopSpace; // the global space
public IntPtr ActiveSpace; // space for active prims
public IntPtr StaticSpace; // space for the static things around
+ public IntPtr GroundSpace; // space for ground
// some speedup variables
private int spaceGridMaxX;
@@ -372,6 +373,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// now the major subspaces
ActiveSpace = d.HashSpaceCreate(TopSpace);
StaticSpace = d.HashSpaceCreate(TopSpace);
+ GroundSpace = d.HashSpaceCreate(TopSpace);
}
catch
{
@@ -381,10 +383,12 @@ namespace OpenSim.Region.Physics.OdePlugin
d.HashSpaceSetLevels(TopSpace, -2, 8);
d.HashSpaceSetLevels(ActiveSpace, -2, 8);
d.HashSpaceSetLevels(StaticSpace, -2, 8);
+ d.HashSpaceSetLevels(GroundSpace, 0, 8);
// demote to second level
d.SpaceSetSublevel(ActiveSpace, 1);
d.SpaceSetSublevel(StaticSpace, 1);
+ d.SpaceSetSublevel(GroundSpace, 1);
d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
CollisionCategories.Geom |
@@ -402,6 +406,8 @@ namespace OpenSim.Region.Physics.OdePlugin
));
d.GeomSetCollideBits(StaticSpace, 0);
+ d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land));
+ d.GeomSetCollideBits(GroundSpace, 0);
contactgroup = d.JointGroupCreate(0);
//contactgroup
@@ -1210,6 +1216,7 @@ namespace OpenSim.Region.Physics.OdePlugin
chr.CollidingObj = false;
// do colisions with static space
d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback);
+ // no coll with gnd
}
}
catch (AccessViolationException)
@@ -1238,7 +1245,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!prm.m_outbounds)
{
if (d.BodyIsEnabled(prm.Body))
+ {
d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
+ d.SpaceCollide2(GroundSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
+ }
}
}
}
@@ -1595,8 +1605,52 @@ namespace OpenSim.Region.Physics.OdePlugin
///
///
public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ }
+
+ // does all pending changes generated during region load process
+ public override void PrepareSimulation()
+ {
+ lock (OdeLock)
{
+ if (world == IntPtr.Zero)
+ {
+ ChangesQueue.Clear();
+ return;
+ }
+
+ ODEchangeitem item;
+
+ int donechanges = 0;
+ if (ChangesQueue.Count > 0)
+ {
+ m_log.InfoFormat("[ODE] start processing pending actor operations");
+ int tstart = Util.EnvironmentTickCount();
+
+ while (ChangesQueue.Dequeue(out item))
+ {
+ if (item.actor != null)
+ {
+ try
+ {
+ if (item.actor is OdeCharacter)
+ ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
+ else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
+ RemovePrimThreadLocked((OdePrim)item.actor);
+ }
+ catch
+ {
+ m_log.WarnFormat("[PHYSICS]: Operation failed for a actor {0} {1}",
+ item.actor.Name, item.what.ToString());
+ }
+ }
+ donechanges++;
+ }
+ int time = Util.EnvironmentTickCountSubtract(tstart);
+ m_log.InfoFormat("[ODE] finished {0} operations in {1}ms", donechanges, time);
+ }
}
+ }
///
/// This is our main simulate loop
@@ -1642,7 +1696,40 @@ namespace OpenSim.Region.Physics.OdePlugin
lock(OdeLock)
{
if (world == IntPtr.Zero)
+ {
+ ChangesQueue.Clear();
return 0;
+ }
+
+ ODEchangeitem item;
+
+ if (ChangesQueue.Count > 0)
+ {
+ int ttmpstart = Util.EnvironmentTickCount();
+ int ttmp;
+
+ while (ChangesQueue.Dequeue(out item))
+ {
+ if (item.actor != null)
+ {
+ try
+ {
+ if (item.actor is OdeCharacter)
+ ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
+ else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
+ RemovePrimThreadLocked((OdePrim)item.actor);
+ }
+ catch
+ {
+ m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
+ item.actor.Name, item.what.ToString());
+ }
+ }
+ ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
+ if (ttmp > 20)
+ break;
+ }
+ }
d.WorldSetQuickStepNumIterations(world, curphysiteractions);
@@ -1653,35 +1740,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// clear pointer/counter to contacts to pass into joints
m_global_contactcount = 0;
- ODEchangeitem item;
-
- if(ChangesQueue.Count >0)
- {
- int ttmpstart = Util.EnvironmentTickCount();
- int ttmp;
-
- while(ChangesQueue.Dequeue(out item))
- {
- if (item.actor != null)
- {
- try
- {
- if (item.actor is OdeCharacter)
- ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
- else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
- RemovePrimThreadLocked((OdePrim)item.actor);
- }
- catch
- {
- m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
- item.actor.Name, item.what.ToString());
- }
- }
- ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
- if (ttmp > 20)
- break;
- }
- }
// Move characters
lock (_characters)
@@ -1813,10 +1871,47 @@ namespace OpenSim.Region.Physics.OdePlugin
mesher.ExpireReleaseMeshs();
m_lastMeshExpire = now;
}
+
+// information block running in debug only
/*
- int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
- int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
+ int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
+ int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
+ int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace);
+
+ int nactivegeoms = 0;
+ int nactivespaces = 0;
+
+ int nstaticgeoms = 0;
+ int nstaticspaces = 0;
+ IntPtr sp;
+
+ for (int i = 0; i < ntopactivegeoms; i++)
+ {
+ sp = d.SpaceGetGeom(ActiveSpace, i);
+ if (d.GeomIsSpace(sp))
+ {
+ nactivespaces++;
+ nactivegeoms += d.SpaceGetNumGeoms(sp);
+ }
+ else
+ nactivegeoms++;
+ }
+
+ for (int i = 0; i < ntopstaticgeoms; i++)
+ {
+ sp = d.SpaceGetGeom(StaticSpace, i);
+ if (d.GeomIsSpace(sp))
+ {
+ nstaticspaces++;
+ nstaticgeoms += d.SpaceGetNumGeoms(sp);
+ }
+ else
+ nstaticgeoms++;
+ }
+
int ntopgeoms = d.SpaceGetNumGeoms(TopSpace);
+
+ int totgeoms = nstaticgeoms + nactivegeoms + ngroundgeoms + 1; // one ray
int nbodies = d.NTotalBodies;
int ngeoms = d.NTotalGeoms;
*/
@@ -2113,7 +2208,9 @@ namespace OpenSim.Region.Physics.OdePlugin
offset, thickness, wrap);
d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
- GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
+
+ GroundGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1);
+
if (GroundGeom != IntPtr.Zero)
{
d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
@@ -2234,12 +2331,13 @@ namespace OpenSim.Region.Physics.OdePlugin
thickness, wrap);
// d.GeomUbitTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
- GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
+ GroundGeom = d.CreateUbitTerrain(GroundSpace, HeightmapData, 1);
if (GroundGeom != IntPtr.Zero)
{
d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
d.GeomSetCollideBits(GroundGeom, 0);
+
PhysicsActor pa = new NullPhysicsActor();
pa.Name = "Terrain";
pa.PhysicsActorType = (int)ActorTypes.Ground;
@@ -2455,6 +2553,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomDestroy(GroundGeom);
}
+
RegionTerrain.Clear();
if (TerrainHeightFieldHeightsHandlers.Count > 0)