* ODE step two on the way to separate dynamic space allocation ( One more to go )

afrisby
Teravus Ovares 2007-11-16 08:53:37 +00:00
parent 9020ec5af9
commit b63076c303
3 changed files with 178 additions and 58 deletions

View File

@ -806,6 +806,7 @@ namespace OpenSim.Region.Environment.Scenes
bool IsTemporary = false; bool IsTemporary = false;
bool IsPhantom = false; bool IsPhantom = false;
bool CastsShadows = false; bool CastsShadows = false;
bool wasUsingPhysics = ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0);
//bool IsLocked = false; //bool IsLocked = false;
int i = 0; int i = 0;
@ -829,20 +830,25 @@ namespace OpenSim.Region.Environment.Scenes
if (UsePhysics ) if (UsePhysics )
{ {
AddFlag(LLObject.ObjectFlags.Physics); AddFlag(LLObject.ObjectFlags.Physics);
if (PhysActor != null) if (!wasUsingPhysics)
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; {
doPhysicsPropertyUpdate(UsePhysics);
}
} }
else else
{
if (m_parentGroup.m_scene.m_physicalPrim)
{ {
RemFlag(LLObject.ObjectFlags.Physics); RemFlag(LLObject.ObjectFlags.Physics);
if (PhysActor != null) if (wasUsingPhysics)
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; {
doPhysicsPropertyUpdate(UsePhysics);
} }
} }
if (IsPhantom) if (IsPhantom)
{ {
AddFlag(LLObject.ObjectFlags.Phantom); AddFlag(LLObject.ObjectFlags.Phantom);
@ -884,6 +890,35 @@ namespace OpenSim.Region.Environment.Scenes
// System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); // System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
ScheduleFullUpdate(); ScheduleFullUpdate();
} }
private void doPhysicsPropertyUpdate(bool UsePhysics)
{
if (PhysActor != null)
{
if (PhysActor.IsPhysical)
{
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
}
m_parentGroup.m_scene.PhysScene.RemovePrim(PhysActor);
/// that's not wholesome. Had to make m_scene public
PhysActor = null;
PhysActor = m_parentGroup.m_scene.PhysScene.AddPrimShape(
Name,
Shape,
new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
AbsolutePosition.Z),
new PhysicsVector(Scale.X, Scale.Y, Scale.Z),
new Quaternion(RotationOffset.W, RotationOffset.X,
RotationOffset.Y, RotationOffset.Z), UsePhysics);
if (UsePhysics)
{
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
}
}
}
public void UpdateExtraParam(ushort type, bool inUse, byte[] data) public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
{ {
@ -1130,6 +1165,13 @@ namespace OpenSim.Region.Environment.Scenes
} }
#endregion #endregion
public void PhysicsOutOfBounds(PhysicsVector pos)
{
OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Physical Object went out of bounds.");
doPhysicsPropertyUpdate(false);
ScheduleFullUpdate();
}
public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient) public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient)
{ {

View File

@ -99,6 +99,7 @@ namespace OpenSim.Region.Physics.Manager
{ {
public delegate void RequestTerseUpdate(); public delegate void RequestTerseUpdate();
public delegate void CollisionUpdate(EventArgs e); public delegate void CollisionUpdate(EventArgs e);
public delegate void OutOfBounds(PhysicsVector pos);
#pragma warning disable 67 #pragma warning disable 67
public event PositionUpdate OnPositionUpdate; public event PositionUpdate OnPositionUpdate;
@ -106,6 +107,7 @@ namespace OpenSim.Region.Physics.Manager
public event OrientationUpdate OnOrientationUpdate; public event OrientationUpdate OnOrientationUpdate;
public event RequestTerseUpdate OnRequestTerseUpdate; public event RequestTerseUpdate OnRequestTerseUpdate;
public event CollisionUpdate OnCollisionUpdate; public event CollisionUpdate OnCollisionUpdate;
public event OutOfBounds OnOutOfBounds;
#pragma warning restore 67 #pragma warning restore 67
public static PhysicsActor Null public static PhysicsActor Null
@ -130,6 +132,18 @@ namespace OpenSim.Region.Physics.Manager
OnRequestTerseUpdate(); OnRequestTerseUpdate();
} }
}
public virtual void RaiseOutOfBounds(PhysicsVector pos)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
OutOfBounds handler = OnOutOfBounds;
if (handler != null)
{
OnOutOfBounds(pos);
}
} }
public virtual void SendCollisionUpdate(EventArgs e) public virtual void SendCollisionUpdate(EventArgs e)
{ {

View File

@ -382,6 +382,24 @@ namespace OpenSim.Region.Physics.OdePlugin
p = (OdePrim) prim; p = (OdePrim) prim;
p.disableBody(); p.disableBody();
} }
// we don't want to remove the main space
if (((OdePrim)prim).m_targetSpace != space && ((OdePrim)prim).IsPhysical == false)
{
// If the geometry is in the targetspace, remove it from the target space
if (d.SpaceQuery(((OdePrim)prim).m_targetSpace, ((OdePrim)prim).prim_geom))
{
d.SpaceRemove(space, ((OdePrim)prim).prim_geom);
}
//If there are no more geometries in the sub-space, we don't need it in the main space anymore
if (d.SpaceGetNumGeoms(((OdePrim)prim).m_targetSpace) == 0)
{
d.SpaceRemove(space, ((OdePrim)prim).m_targetSpace);
// free up memory used by the space.
d.SpaceDestroy(((OdePrim)prim).m_targetSpace);
resetSpaceArrayItemToZero(calculateSpaceArrayItemFromPos(((OdePrim)prim).Position));
}
}
d.GeomDestroy(((OdePrim)prim).prim_geom); d.GeomDestroy(((OdePrim)prim).prim_geom);
@ -390,19 +408,73 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
} }
public void resetSpaceArrayItemToZero(IntPtr space)
{
for (int i = 0; i < staticPrimspace.Length; i++)
{
if (staticPrimspace[i] == space)
staticPrimspace[i] = IntPtr.Zero;
}
}
public void resetSpaceArrayItemToZero(int arrayitem)
{
staticPrimspace[arrayitem] = IntPtr.Zero;
}
public IntPtr recalculateSpaceForGeom(IntPtr geom, PhysicsVector pos) public IntPtr recalculateSpaceForGeom(IntPtr geom, PhysicsVector pos, IntPtr currentspace)
{ {
//Todo recalculate space the prim is in. //Todo recalculate space the prim is in.
// Called from setting the Position and Size of an ODEPrim so
// it's already in locked space.
// we don't want to remove the main space
// we don't need to test physical here because this function should
// never be called if the prim is physical(active)
if (currentspace != space)
{
if (d.SpaceQuery(currentspace, geom))
{
d.SpaceRemove(space, geom);
}
//If there are no more geometries in the sub-space, we don't need it in the main space anymore
if (d.SpaceGetNumGeoms(currentspace) == 0)
{
d.SpaceRemove(space, currentspace);
// free up memory used by the space.
d.SpaceDestroy(currentspace);
resetSpaceArrayItemToZero(currentspace);
}
}
// The routines in the Position and Size sections do the 'inserting' into the space,
// so all we have to do is make sure that the space that we're putting the prim into
// is in the 'main' space.
int iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos);
IntPtr newspace = calculateSpaceForGeom(pos);
if (newspace == IntPtr.Zero)
newspace = createprimspace(iprimspaceArrItem);
return newspace;
}
public IntPtr createprimspace(int iprimspaceArrItem) {
// creating a new space for prim and inserting it into main space.
staticPrimspace[iprimspaceArrItem] = d.HashSpaceCreate(IntPtr.Zero);
d.SpaceAdd(space, staticPrimspace[iprimspaceArrItem]);
return staticPrimspace[iprimspaceArrItem];
}
public IntPtr calculateSpaceForGeom(PhysicsVector pos)
{
return space; return space;
} }
public int calculateSpaceArrayItemFromPos(PhysicsVector pos)
public IntPtr calculateSpaceForNewGeom(PhysicsVector pos)
{ {
return 0;
return space;
} }
private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
@ -423,33 +495,36 @@ namespace OpenSim.Region.Physics.OdePlugin
rot.y = rotation.y; rot.y = rotation.y;
rot.z = rotation.z; rot.z = rotation.z;
IntPtr targetspace = calculateSpaceForNewGeom(pos);
int iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos);
IntPtr targetspace = calculateSpaceForGeom(pos);
if (targetspace == IntPtr.Zero)
targetspace = createprimspace(iprimspaceArrItem);
OdePrim newPrim; OdePrim newPrim;
lock (OdeLock) lock (OdeLock)
{ {
newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical); newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical);
} }
_prims.Add(newPrim); _prims.Add(newPrim);
OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Added Object");
return newPrim; return newPrim;
} }
public void addActivePrim(OdePrim activatePrim) public void addActivePrim(OdePrim activatePrim)
{ {
// adds active prim.. (ones that should be iterated over in collisions_optimized // adds active prim.. (ones that should be iterated over in collisions_optimized
lock (OdeLock)
{
_activeprims.Add(activatePrim); _activeprims.Add(activatePrim);
}
} }
public void remActivePrim(OdePrim deactivatePrim) public void remActivePrim(OdePrim deactivatePrim)
{ {
lock (OdeLock)
{
lock (_activeprims)
{
_activeprims.Remove(deactivatePrim); _activeprims.Remove(deactivatePrim);
}
}
} }
public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount) public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount)
{ {
@ -541,6 +616,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void Simulate(float timeStep) public override void Simulate(float timeStep)
{ {
step_time += timeStep; step_time += timeStep;
lock (OdeLock) lock (OdeLock)
{ {
@ -548,21 +624,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
Console.WriteLine("RENDER: frame"); Console.WriteLine("RENDER: frame");
} }
foreach (OdePrim p in _prims)
{
if (_characters.Count > 0 && RENDER_FLAG)
{
Vector3 rx, ry, rz;
p.Orientation.ToAxes(out rx, out ry, out rz);
Console.WriteLine("RENDER: block; " + p.Size.X + ", " + p.Size.Y + ", " + p.Size.Z + "; " +
" 0, 0, 1; " + //shape, size, color
(p.Position.X - 128.0f) + ", " + (p.Position.Y - 128.0f) + ", " +
(p.Position.Z - 33.0f) + "; " + // position
rx.x + "," + ry.x + "," + rz.x + ", " + // rotation
rx.y + "," + ry.y + "," + rz.y + ", " +
rx.z + "," + ry.z + "," + rz.z);
}
}
// If We're loaded down by something else, // If We're loaded down by something else,
@ -570,6 +632,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// skip a few frames to catch up gracefully. // skip a few frames to catch up gracefully.
// without shooting the physicsactors all over the place // without shooting the physicsactors all over the place
if (step_time >= m_SkipFramesAtms) if (step_time >= m_SkipFramesAtms)
{ {
// Instead of trying to catch up, it'll do one physics frame only // Instead of trying to catch up, it'll do one physics frame only
@ -580,10 +644,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_physicsiterations = 10; m_physicsiterations = 10;
} }
// Process 10 frames if the sim is running normal.. // Process 10 frames if the sim is running normal..
// process 5 frames if the sim is running slow // process 5 frames if the sim is running slow
d.WorldSetQuickStepNumIterations(world, m_physicsiterations); d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
int i = 0; int i = 0;
while (step_time > 0.0f) while (step_time > 0.0f)
{ {
@ -640,11 +706,13 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
if (timeStep < 0.2f) if (timeStep < 0.2f)
{ {
OdePrim outofBoundsPrim = null;
foreach (OdePrim actor in _activeprims) foreach (OdePrim actor in _activeprims)
{ {
if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag))
{ {
actor.UpdatePositionAndVelocity(); actor.UpdatePositionAndVelocity();
} }
} }
} }
@ -716,6 +784,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
} }
} }
# region ODE Actors
public class OdeCharacter : PhysicsActor public class OdeCharacter : PhysicsActor
{ {
@ -1185,13 +1254,14 @@ namespace OpenSim.Region.Physics.OdePlugin
private IMesh _mesh; private IMesh _mesh;
private PrimitiveBaseShape _pbs; private PrimitiveBaseShape _pbs;
private OdeScene _parent_scene; private OdeScene _parent_scene;
private IntPtr m_targetSpace = (IntPtr)0; public IntPtr m_targetSpace = (IntPtr)0;
public IntPtr prim_geom; public IntPtr prim_geom;
public IntPtr _triMeshData; public IntPtr _triMeshData;
private bool iscolliding = false; private bool iscolliding = false;
private bool m_isphysical = false; private bool m_isphysical = false;
private bool m_throttleUpdates = false; private bool m_throttleUpdates = false;
private int throttleCounter = 0; private int throttleCounter = 0;
public bool outofBounds = false;
public bool _zeroFlag = false; public bool _zeroFlag = false;
private bool m_lastUpdateSent = false; private bool m_lastUpdateSent = false;
@ -1403,6 +1473,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PhysicsVector Position public override PhysicsVector Position
{ {
get {return _position; } get {return _position; }
set set
{ {
_position = value; _position = value;
@ -1421,9 +1493,9 @@ namespace OpenSim.Region.Physics.OdePlugin
else else
{ {
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
} }
m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position);
} }
} }
} }
@ -1449,6 +1521,9 @@ namespace OpenSim.Region.Physics.OdePlugin
disableBody(); disableBody();
} }
d.GeomDestroy(prim_geom); d.GeomDestroy(prim_geom);
// Recalculate which space this geometry should be in.
m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
// Construction of new prim // Construction of new prim
if (this._parent_scene.needsMeshing(_pbs)) if (this._parent_scene.needsMeshing(_pbs))
{ {
@ -1478,7 +1553,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position);
_parent_scene.geom_name_map[prim_geom] = oldname; _parent_scene.geom_name_map[prim_geom] = oldname;
} }
@ -1639,20 +1714,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// Disables the prim's movement physics.... // Disables the prim's movement physics....
// It's a hack and will generate a console message if it fails. // It's a hack and will generate a console message if it fails.
try
{
disableBody();
}
catch (System.Exception e)
{
if (Body != (IntPtr)0)
{
d.BodyDestroy(Body);
Body = (IntPtr)0;
}
}
IsPhysical = false; IsPhysical = false;
@ -1662,10 +1724,11 @@ namespace OpenSim.Region.Physics.OdePlugin
m_rotationalVelocity.X = 0; m_rotationalVelocity.X = 0;
m_rotationalVelocity.Y = 0; m_rotationalVelocity.Y = 0;
m_rotationalVelocity.Z = 0; m_rotationalVelocity.Z = 0;
base.RequestPhysicsterseUpdate(); //base.RequestPhysicsterseUpdate();
m_throttleUpdates = false; m_throttleUpdates = false;
throttleCounter = 0; throttleCounter = 0;
_zeroFlag = true; _zeroFlag = true;
outofBounds = true;
} }
if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
@ -1755,3 +1818,4 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
} }
#endregion