From 5a71d03b7ac1de0b599f651c62bf1e33a3d1745d Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Tue, 20 Nov 2007 04:38:08 +0000 Subject: [PATCH] *Huge* structural changes in ODE/OdePrim to get all of the calls in threadlocked code. ODEPrim was almost completely re-written. Copy/Space test needed. --- .../Environment/Scenes/Scene.Inventory.cs | 2 +- OpenSim/Region/Environment/Scenes/Scene.cs | 4 +- .../Environment/Scenes/SceneObjectGroup.cs | 12 +- .../Environment/Scenes/SceneObjectPart.cs | 80 +- .../Environment/Scenes/SceneXmlLoader.cs | 4 +- .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs | 3 + .../Physics/BulletXPlugin/BulletXPlugin.cs | 3 + .../Region/Physics/Manager/PhysicsScene.cs | 4 + OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 687 +++++++++--------- OpenSim/Region/Physics/POSPlugin/POSPlugin.cs | 3 + .../Region/Physics/PhysXPlugin/PhysXPlugin.cs | 3 + 11 files changed, 439 insertions(+), 366 deletions(-) diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index bc0ccb3c9c..3c8dc0a04c 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -491,7 +491,7 @@ namespace OpenSim.Region.Environment.Scenes new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics); - rootPart.doPhysicsPropertyUpdate(UsePhysics); + rootPart.doPhysicsPropertyUpdate(UsePhysics, true); } rootPart.ScheduleFullUpdate(); diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index dcba9bda43..405f2e3c90 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -604,7 +604,7 @@ namespace OpenSim.Region.Environment.Scenes new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z), new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics); - rootPart.doPhysicsPropertyUpdate(UsePhysics); + rootPart.doPhysicsPropertyUpdate(UsePhysics, true); } MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); } @@ -657,7 +657,7 @@ namespace OpenSim.Region.Environment.Scenes new PhysicsVector(shape.Scale.X, shape.Scale.Y, shape.Scale.Z), new Quaternion(), UsePhysics); // subscribe to physics events. - rootPart.doPhysicsPropertyUpdate(UsePhysics); + rootPart.doPhysicsPropertyUpdate(UsePhysics, true); } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 38962c118b..efee81bbb9 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -150,6 +150,7 @@ namespace OpenSim.Region.Environment.Scenes m_rootPart.PhysActor.Position = new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y, m_rootPart.GroupPosition.Z); + m_scene.PhysScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } } } @@ -480,7 +481,7 @@ namespace OpenSim.Region.Environment.Scenes new Quaternion(dupe.RootPart.RotationOffset.W, dupe.RootPart.RotationOffset.X, dupe.RootPart.RotationOffset.Y, dupe.RootPart.RotationOffset.Z), dupe.RootPart.PhysActor.IsPhysical); - dupe.RootPart.doPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical); + dupe.RootPart.doPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); } // Now we've made a copy that replaces this one, we need to @@ -784,6 +785,7 @@ namespace OpenSim.Region.Environment.Scenes if (linkPart.PhysActor != null) { m_scene.PhysScene.RemovePrim(linkPart.PhysActor); + linkPart.PhysActor = null; } @@ -861,7 +863,7 @@ namespace OpenSim.Region.Environment.Scenes new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y, linkPart.RotationOffset.Z), m_rootPart.PhysActor.IsPhysical); - m_rootPart.doPhysicsPropertyUpdate(m_rootPart.PhysActor.IsPhysical); + m_rootPart.doPhysicsPropertyUpdate(m_rootPart.PhysActor.IsPhysical, true); } @@ -1170,7 +1172,7 @@ namespace OpenSim.Region.Environment.Scenes m_rootPart.RotationOffset.Y, m_rootPart.RotationOffset.Z), m_rootPart.PhysActor.IsPhysical); bool UsePhysics = ((m_rootPart.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); - m_rootPart.doPhysicsPropertyUpdate(UsePhysics); + m_rootPart.doPhysicsPropertyUpdate(UsePhysics, true); } } @@ -1196,6 +1198,7 @@ namespace OpenSim.Region.Environment.Scenes { m_rootPart.PhysActor.Size = new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); + m_scene.PhysScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } } } @@ -1286,6 +1289,7 @@ namespace OpenSim.Region.Environment.Scenes m_rootPart.PhysActor.Orientation = new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y, m_rootPart.RotationOffset.Z); + m_scene.PhysScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } ScheduleGroupForTerseUpdate(); } @@ -1303,6 +1307,7 @@ namespace OpenSim.Region.Environment.Scenes m_rootPart.PhysActor.Orientation = new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y, m_rootPart.RotationOffset.Z); + m_scene.PhysScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } AbsolutePosition = pos; ScheduleGroupForTerseUpdate(); @@ -1346,6 +1351,7 @@ namespace OpenSim.Region.Environment.Scenes m_rootPart.PhysActor.Orientation = new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, m_rootPart.RotationOffset.Y, m_rootPart.RotationOffset.Z); + m_scene.PhysScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } foreach (SceneObjectPart prim in m_parts.Values) diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 76fe4b66f2..7bab3b6cbd 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -170,9 +170,10 @@ namespace OpenSim.Region.Environment.Scenes { try { - //lock (m_scene.SyncRoot) + //lock (m_parentGroup.m_scene.SyncRoot) //{ PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z); + m_parentGroup.m_scene.PhysScene.AddPhysicsActorTaint(PhysActor); //} } catch (Exception e) @@ -225,6 +226,7 @@ namespace OpenSim.Region.Environment.Scenes //lock (m_scene.SyncRoot) //{ PhysActor.Orientation = new Quaternion(value.W, value.X, value.Y, value.Z); + m_parentGroup.m_scene.PhysScene.AddPhysicsActorTaint(PhysActor); //} } catch (Exception ex) @@ -502,7 +504,7 @@ namespace OpenSim.Region.Environment.Scenes RotationOffset = rotation; ObjectFlags = flags; bool UsePhysics = ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); - doPhysicsPropertyUpdate(UsePhysics); + doPhysicsPropertyUpdate(UsePhysics, true); ScheduleFullUpdate(); } @@ -518,7 +520,7 @@ namespace OpenSim.Region.Environment.Scenes XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart)); SceneObjectPart newobject = (SceneObjectPart) serializer.Deserialize(xmlReader); bool UsePhysics = ((newobject.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); - newobject.doPhysicsPropertyUpdate(UsePhysics); + newobject.doPhysicsPropertyUpdate(UsePhysics, true); return newobject; } @@ -586,7 +588,7 @@ namespace OpenSim.Region.Environment.Scenes Array.Copy(Shape.ExtraParams, extraP, extraP.Length); dupe.Shape.ExtraParams = extraP; bool UsePhysics = ((dupe.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) != 0); - dupe.doPhysicsPropertyUpdate(UsePhysics); + dupe.doPhysicsPropertyUpdate(UsePhysics, true); return dupe; } @@ -852,7 +854,7 @@ namespace OpenSim.Region.Environment.Scenes AddFlag(LLObject.ObjectFlags.Physics); if (!wasUsingPhysics) { - doPhysicsPropertyUpdate(UsePhysics); + doPhysicsPropertyUpdate(UsePhysics,false); } } @@ -861,7 +863,7 @@ namespace OpenSim.Region.Environment.Scenes RemFlag(LLObject.ObjectFlags.Physics); if (wasUsingPhysics) { - doPhysicsPropertyUpdate(UsePhysics); + doPhysicsPropertyUpdate(UsePhysics, false); } } @@ -892,12 +894,12 @@ namespace OpenSim.Region.Environment.Scenes new PhysicsVector(Scale.X, Scale.Y, Scale.Z), new Quaternion(RotationOffset.W, RotationOffset.X, RotationOffset.Y, RotationOffset.Z), UsePhysics); - doPhysicsPropertyUpdate(UsePhysics); + doPhysicsPropertyUpdate(UsePhysics, true); } else { PhysActor.IsPhysical = UsePhysics; - doPhysicsPropertyUpdate(UsePhysics); + doPhysicsPropertyUpdate(UsePhysics,false); } } @@ -912,36 +914,45 @@ namespace OpenSim.Region.Environment.Scenes // System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); ScheduleFullUpdate(); } - public void doPhysicsPropertyUpdate(bool UsePhysics) + public void doPhysicsPropertyUpdate(bool UsePhysics, bool isNew) { if (PhysActor != null) - { - if (PhysActor.IsPhysical) + { + if (UsePhysics != PhysActor.IsPhysical || isNew) { - 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; - - if ((ObjectFlags & (uint)LLObject.ObjectFlags.Phantom) == 0) - { - 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) + + if (PhysActor.IsPhysical) { - PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; - PhysActor.OnOutOfBounds += PhysicsOutOfBounds; + PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; + PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; + } + + PhysActor.IsPhysical = UsePhysics; + // If we're not what we're supposed to be in the physics scene, recreate ourselves. + //m_parentGroup.m_scene.PhysScene.RemovePrim(PhysActor); + /// that's not wholesome. Had to make m_scene public + //PhysActor = null; + + + if ((ObjectFlags & (uint)LLObject.ObjectFlags.Phantom) == 0) + { + //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; + } } } + m_parentGroup.m_scene.PhysScene.AddPhysicsActorTaint(PhysActor); } } @@ -1195,8 +1206,11 @@ namespace OpenSim.Region.Environment.Scenes public void PhysicsOutOfBounds(PhysicsVector pos) { OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Physical Object went out of bounds."); - doPhysicsPropertyUpdate(false); - ScheduleFullUpdate(); + RemFlag(LLObject.ObjectFlags.Physics); + doPhysicsPropertyUpdate(false,true); + m_parentGroup.m_scene.PhysScene.AddPhysicsActorTaint(PhysActor); + + } diff --git a/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs b/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs index 3b5fc575fe..5c460be85b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs +++ b/OpenSim/Region/Environment/Scenes/SceneXmlLoader.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.Environment.Scenes new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z), new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics); - rootPart.doPhysicsPropertyUpdate(UsePhysics); + rootPart.doPhysicsPropertyUpdate(UsePhysics, true); } primCount++; @@ -125,7 +125,7 @@ namespace OpenSim.Region.Environment.Scenes new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z), new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics); - rootPart.doPhysicsPropertyUpdate(UsePhysics); + rootPart.doPhysicsPropertyUpdate(UsePhysics, true); } } diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs index 25820970a6..a7f7877b63 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -114,7 +114,10 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin { return null; } + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + } public override void Simulate(float timeStep) { foreach (BasicActor actor in _actors) diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index f78e99e847..8890f9725c 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -511,7 +511,10 @@ namespace OpenSim.Region.Physics.BulletXPlugin GC.Collect(); } } + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + } public override void Simulate(float timeStep) { lock (BulletXLock) diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 6f19e72443..651992c031 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -51,6 +51,7 @@ namespace OpenSim.Region.Physics.Manager PhysicsVector size, Quaternion rotation); //To be removed public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, Quaternion rotation, bool isPhysical); + public abstract void AddPhysicsActorTaint(PhysicsActor prim); public abstract void Simulate(float timeStep); @@ -104,7 +105,10 @@ namespace OpenSim.Region.Physics.Manager MainLog.Instance.Verbose("NullPhysicsScene : AddPrim({0},{1})", position, size); return PhysicsActor.Null; } + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + } public override void Simulate(float timeStep) { m_workIndicator = (m_workIndicator + 1)%10; diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index e1dc9f8c00..84ff60cb1b 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -85,6 +85,7 @@ namespace OpenSim.Region.Physics.OdePlugin private List _characters = new List(); private List _prims = new List(); private List _activeprims = new List(); + private List _taintedPrim = new List(); public Dictionary geom_name_map = new Dictionary(); public Dictionary actor_name_map = new Dictionary(); private d.ContactGeom[] contacts = new d.ContactGeom[30]; @@ -326,13 +327,7 @@ namespace OpenSim.Region.Physics.OdePlugin chr.CollidingGround = false; chr.CollidingObj = false; d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); - foreach (OdeCharacter ch2 in _characters) - /// should be a separate space -- lots of avatars will be N**2 slow - { - - - //d.SpaceCollide2(chr.Shell, ch2.Shell, IntPtr.Zero, nearCallback); - } + } // If the sim is running slow this frame, @@ -345,20 +340,20 @@ namespace OpenSim.Region.Physics.OdePlugin if (d.BodyIsEnabled(chr.Body)) { d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); - foreach (OdePrim ch2 in _prims) + //foreach (OdePrim ch2 in _prims) /// should be a separate space -- lots of avatars will be N**2 slow - { - if (ch2.IsPhysical && d.BodyIsEnabled(ch2.Body)) - { + //{ + //if (ch2.IsPhysical && d.BodyIsEnabled(ch2.Body)) + //{ // Only test prim that are 0.03 meters away in one direction. // This should be Optimized! - if ((Math.Abs(ch2.Position.X - chr.Position.X) < 0.03) || (Math.Abs(ch2.Position.Y - chr.Position.Y) < 0.03) || (Math.Abs(ch2.Position.X - chr.Position.X) < 0.03)) - { - d.SpaceCollide2(chr.prim_geom, ch2.prim_geom, IntPtr.Zero, nearCallback); - } - } - } + //if ((Math.Abs(ch2.Position.X - chr.Position.X) < 0.03) || (Math.Abs(ch2.Position.Y - chr.Position.Y) < 0.03) || (Math.Abs(ch2.Position.X - chr.Position.X) < 0.03)) + //{ + //d.SpaceCollide2(chr.prim_geom, ch2.prim_geom, IntPtr.Zero, nearCallback); + //} + //} + //} } } } @@ -404,61 +399,71 @@ namespace OpenSim.Region.Physics.OdePlugin { lock (OdeLock) { - if (prim.IsPhysical) - { - OdePrim p; - p = (OdePrim) prim; - 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)) - { - if (!(((OdePrim)prim).m_targetSpace.Equals(null))) - { - if (d.GeomIsSpace(((OdePrim)prim).m_targetSpace)) - { - d.SpaceRemove(((OdePrim)prim).m_targetSpace, ((OdePrim)prim).prim_geom); - } - else - { - OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Invalid Scene passed to 'removeprim from scene':" + ((OdePrim)prim).m_targetSpace.ToString()); - } - } - } + OdePrim p = (OdePrim) prim; - + p.setPrimForRemoval(); + AddPhysicsActorTaint(prim); - //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) - { - if (!(((OdePrim)prim).m_targetSpace.Equals(null))) - { - if (d.GeomIsSpace(((OdePrim)prim).m_targetSpace)) - { - d.SpaceRemove(space, ((OdePrim)prim).m_targetSpace); - // free up memory used by the space. - d.SpaceDestroy(((OdePrim)prim).m_targetSpace); - int[] xyspace = calculateSpaceArrayItemFromPos(((OdePrim)prim).Position); - resetSpaceArrayItemToZero(xyspace[0],xyspace[1]); - } - else - { - OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Invalid Scene passed to 'removeprim from scene':" + ((OdePrim)prim).m_targetSpace.ToString()); - } - } - } - } - - d.GeomDestroy(((OdePrim)prim).prim_geom); - - _prims.Remove((OdePrim)prim); - } } } + public void RemovePrimThreadLocked(OdePrim prim) + { + lock (OdeLock) + { + + if (prim.IsPhysical) + { + prim.disableBody(); + } + // we don't want to remove the main space + if (prim.m_targetSpace != space && prim.IsPhysical == false) + { + // If the geometry is in the targetspace, remove it from the target space + if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom)) + { + if (!(prim.m_targetSpace.Equals(null))) + { + if (d.GeomIsSpace(prim.m_targetSpace)) + { + d.SpaceRemove(prim.m_targetSpace, prim.prim_geom); + } + else + { + OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Invalid Scene passed to 'removeprim from scene':" + ((OdePrim)prim).m_targetSpace.ToString()); + } + } + } + + + + //If there are no more geometries in the sub-space, we don't need it in the main space anymore + if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) + { + if (!(prim.m_targetSpace.Equals(null))) + { + if (d.GeomIsSpace(prim.m_targetSpace)) + { + d.SpaceRemove(space, prim.m_targetSpace); + // free up memory used by the space. + d.SpaceDestroy(prim.m_targetSpace); + int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position); + resetSpaceArrayItemToZero(xyspace[0], xyspace[1]); + } + else + { + OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Invalid Scene passed to 'removeprim from scene':" + ((OdePrim)prim).m_targetSpace.ToString()); + } + } + } + } + + d.GeomDestroy(prim.prim_geom); + + _prims.Remove(prim); + } + + } public void resetSpaceArrayItemToZero(IntPtr space) { for (int x = 0; x < staticPrimspace.GetLength(0); x++) @@ -654,8 +659,9 @@ namespace OpenSim.Region.Physics.OdePlugin lock (OdeLock) { newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical); + + _prims.Add(newPrim); } - _prims.Add(newPrim); return newPrim; } @@ -761,20 +767,23 @@ namespace OpenSim.Region.Physics.OdePlugin return result; } + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + if (prim is OdePrim) + { + OdePrim taintedprim = ((OdePrim)prim); + if (!(_taintedPrim.Contains(taintedprim))) + _taintedPrim.Add(taintedprim); + + } + } public override void Simulate(float timeStep) { step_time += timeStep; - lock (OdeLock) - { - if (_characters.Count > 0 && RENDER_FLAG) - { - Console.WriteLine("RENDER: frame"); - } - - + // If We're loaded down by something else, // or debugging with the Visual Studio project on pause // skip a few frames to catch up gracefully. @@ -792,7 +801,8 @@ namespace OpenSim.Region.Physics.OdePlugin { m_physicsiterations = 10; } - + lock (OdeLock) + { // Process 10 frames if the sim is running normal.. // process 5 frames if the sim is running slow d.WorldSetQuickStepNumIterations(world, m_physicsiterations); @@ -823,38 +833,23 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (OdeCharacter actor in _characters) { actor.UpdatePositionAndVelocity(); - if (RENDER_FLAG) - { - /// debugging code - float Zoff = -33.0f; - d.Matrix3 temp = d.BodyGetRotation(actor.Body); - //Console.WriteLine("RENDER: cylinder; " + // shape - //OdeCharacter.CAPSULE_RADIUS + ", " + OdeCharacter.CAPSULE_LENGTH + //size - //"; 0, 1, 0; " + // color - //(actor.Position.X - 128.0f) + ", " + (actor.Position.Y - 128.0f) + ", " + - //(actor.Position.Z + Zoff) + "; " + // position - //temp.M00 + "," + temp.M10 + "," + temp.M20 + ", " + // rotation - //temp.M01 + "," + temp.M11 + "," + temp.M21 + ", " + - //temp.M02 + "," + temp.M12 + "," + temp.M22); - d.Vector3 caphead; - //d.BodyGetRelPointPos(actor.Body, 0, 0, OdeCharacter.CAPSULE_LENGTH*.5f, out caphead); - d.Vector3 capfoot; - //d.BodyGetRelPointPos(actor.Body, 0, 0, -OdeCharacter.CAPSULE_LENGTH*.5f, out capfoot); - //Console.WriteLine("RENDER: sphere; " + OdeCharacter.CAPSULE_RADIUS + // shape, size - //"; 1, 0, 1; " + //color - //(caphead.X - 128.0f) + ", " + (caphead.Y - 128.0f) + ", " + (caphead.Z + Zoff) + - //"; " + // position - ///"1,0,0, 0,1,0, 0,0,1"); // rotation - // Console.WriteLine("RENDER: sphere; " + OdeCharacter.CAPSULE_RADIUS + // shape, size - //"; 1, 0, 0; " + //color - //(capfoot.X - 128.0f) + ", " + (capfoot.Y - 128.0f) + ", " + (capfoot.Z + Zoff) + - //"; " + // position - //"1,0,0, 0,1,0, 0,0,1"); // rotation - } + } + bool processedtaints = false; + foreach (OdePrim prim in _taintedPrim) + { + prim.ProcessTaints(timeStep); + if (prim.m_taintremove) + { + RemovePrimThreadLocked(prim); + } + processedtaints = true; + } + if (processedtaints) + _taintedPrim = new List(); + if (timeStep < 0.2f) { - OdePrim outofBoundsPrim = null; foreach (OdePrim actor in _activeprims) { if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) @@ -1410,6 +1405,12 @@ namespace OpenSim.Region.Physics.OdePlugin private PhysicsVector _size; private PhysicsVector _acceleration; private Quaternion _orientation; + private PhysicsVector m_taintposition; + private PhysicsVector m_taintsize; + private Quaternion m_taintrot; + private bool m_taintshape = false; + private bool m_taintPhysics = false; + public bool m_taintremove = false; private IMesh _mesh; private PrimitiveBaseShape _pbs; @@ -1441,30 +1442,33 @@ namespace OpenSim.Region.Physics.OdePlugin _velocity = new PhysicsVector(); _position = pos; - - //if (_position.X > 257) - //{ - // _position.X = 257; - //} - //if (_position.X < 0) - //{ - // _position.X = 0; - //} - //if (_position.Y > 257) - //{ - // _position.Y = 257; - // } - //if (_position.Y < 0) - //{ - // _position.Y = 0; - //} + m_taintposition = pos; + if (_position.X > 257) + { + _position.X = 257; + } + if (_position.X < 0) + { + _position.X = 0; + } + if (_position.Y > 257) + { + _position.Y = 257; + } + if (_position.Y < 0) + { + _position.Y = 0; + } _size = size; + m_taintsize = _size; _acceleration = new PhysicsVector(); m_rotationalVelocity = PhysicsVector.Zero; _orientation = rotation; + m_taintrot = _orientation; _mesh = mesh; _pbs = pbs; + _parent_scene = parent_scene; m_targetSpace = targetSpace; @@ -1585,39 +1589,237 @@ namespace OpenSim.Region.Physics.OdePlugin enableBody(); } } - - public override bool IsPhysical + public void ProcessTaints(float timestep) { - get { return m_isphysical; } - set { - - lock (OdeScene.OdeLock) - { - if (m_isphysical == value) - { - // If the object is already what the user checked - - return; - } - if (value == true) - { - if (Body == (IntPtr)0) - { - enableBody(); - } + if (m_taintposition != _position) + Move(timestep); - } - else if (value == false) - { - if (Body != (IntPtr)0) - { - disableBody(); - } - } - m_isphysical = value; + if (m_taintrot != _orientation) + rotate(timestep); + // + + if (m_taintPhysics != m_isphysical) + changePhysicsStatus(timestep); + // + + if (m_taintsize != _size) + changesize(timestep); + // + + if (m_taintshape) + changeshape(timestep); + // + + } + public void Move(float timestep) + { + if (m_isphysical) + { + // This is a fallback.. May no longer be necessary. + if (Body == (IntPtr)0) + enableBody(); + //Prim auto disable after 20 frames, + ///if you move it, re-enable the prim manually. + d.BodyEnable(Body); + d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + } + else + { + string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); + int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); + if (primScenAvatarIn == "0") + { + OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in space with no prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + " . Arr:': " + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); + } + else + { + OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in Prim space with prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); + } + m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.SpaceAdd(m_targetSpace, prim_geom); + } + + m_taintposition = _position; + } + public void rotate(float timestep) + { + + d.Quaternion myrot = new d.Quaternion(); + myrot.W = _orientation.w; + myrot.X = _orientation.x; + myrot.Y = _orientation.y; + myrot.Z = _orientation.z; + d.GeomSetQuaternion(prim_geom, ref myrot); + if (m_isphysical && Body != (IntPtr)0) + { + d.BodySetQuaternion(Body, ref myrot); + } + + m_taintrot = _orientation; + } + public void changePhysicsStatus(float timestap) + { + if (m_isphysical == true) + { + if (Body == (IntPtr)0) + { + enableBody(); } } + else + { + if (Body != (IntPtr)0) + { + disableBody(); + } + } + + + m_taintPhysics = m_isphysical; + } + public void changesize(float timestamp) + { + string oldname = _parent_scene.geom_name_map[prim_geom]; + + // Cleanup of old prim geometry + if (_mesh != null) + { + // Cleanup meshing here + } + //kill body to rebuild + if (IsPhysical && Body != (IntPtr)0) + { + disableBody(); + } + if (d.SpaceQuery(m_targetSpace, prim_geom)) + { + d.SpaceRemove(m_targetSpace, prim_geom); + } + d.GeomDestroy(prim_geom); + + // we don't need to do space calculation because the client sends a position update also. + + // Construction of new prim + if (this._parent_scene.needsMeshing(_pbs)) + { + + + // Don't need to re-enable body.. it's done in SetMesh + IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); + // createmesh returns null when it's a shape that isn't a cube. + if (mesh != null) + { + setMesh(_parent_scene, mesh); + } + else + { + prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.W = _orientation.w; + myrot.X = _orientation.x; + myrot.Y = _orientation.y; + myrot.Z = _orientation.z; + d.GeomSetQuaternion(prim_geom, ref myrot); + + + } + } + else + { + prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.W = _orientation.w; + myrot.X = _orientation.x; + myrot.Y = _orientation.y; + myrot.Z = _orientation.z; + d.GeomSetQuaternion(prim_geom, ref myrot); + + + //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); + if (IsPhysical && Body == (IntPtr)0) + { + // Re creates body on size. + // EnableBody also does setMass() + enableBody(); + d.BodyEnable(Body); + } + + } + + + _parent_scene.geom_name_map[prim_geom] = oldname; + + + m_taintsize = _size; + } + public void changeshape(float timestamp) + { + string oldname = _parent_scene.geom_name_map[prim_geom]; + + // Cleanup of old prim geometry and Bodies + if (IsPhysical && Body != (IntPtr)0) + { + disableBody(); + } + d.GeomDestroy(prim_geom); + if (_mesh != null) + { + + d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); + + } + + // Construction of new prim + if (this._parent_scene.needsMeshing(_pbs)) + { + IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); + if (mesh != null) + { + setMesh(_parent_scene, mesh); + } + else + { + prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + } + } + else + { + prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + } + if (IsPhysical && Body == (IntPtr)0) + { + //re-create new body + enableBody(); + } + else + { + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.W = _orientation.w; + myrot.X = _orientation.x; + myrot.Y = _orientation.y; + myrot.Z = _orientation.z; + d.GeomSetQuaternion(prim_geom, ref myrot); + } + _parent_scene.geom_name_map[prim_geom] = oldname; + + + + + m_taintshape = false; + } + public override bool IsPhysical + { + get { return m_isphysical; } + set{ m_isphysical = value;} + } + public void setPrimForRemoval() + { + m_taintremove = true; } public override bool Flying @@ -1656,36 +1858,7 @@ namespace OpenSim.Region.Physics.OdePlugin set { _position = value; - lock (OdeScene.OdeLock) - { - if (m_isphysical) - { - // This is a fallback.. May no longer be necessary. - if (Body == (IntPtr)0) - enableBody(); - //Prim auto disable after 20 frames, - ///if you move it, re-enable the prim manually. - d.BodyEnable(Body); - d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); - } - else - { - string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); - int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); - if (primScenAvatarIn == "0") - { - OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in space with no prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + " . Arr:': " + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); - } - else - { - OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in Prim space with prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString()); - } - m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.SpaceAdd(m_targetSpace, prim_geom); - } - - } + } } @@ -1695,78 +1868,7 @@ namespace OpenSim.Region.Physics.OdePlugin set { _size = value; - lock (OdeScene.OdeLock) - { - string oldname = _parent_scene.geom_name_map[prim_geom]; - - // Cleanup of old prim geometry - if (_mesh != null) - { - // Cleanup meshing here - } - //kill body to rebuild - if (IsPhysical && Body != (IntPtr)0) - { - disableBody(); - } - if (d.SpaceQuery(m_targetSpace,prim_geom)) { - d.SpaceRemove(m_targetSpace,prim_geom); - } - d.GeomDestroy(prim_geom); - - // we don't need to do space calculation because the client sends a position update also. - - // Construction of new prim - if (this._parent_scene.needsMeshing(_pbs)) - { - - - // Don't need to re-enable body.. it's done in SetMesh - IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); - // createmesh returns null when it's a shape that isn't a cube. - if (mesh != null) - { - setMesh(_parent_scene, mesh); - } - else - { - prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); - myrot.W = _orientation.w; - myrot.X = _orientation.x; - myrot.Y = _orientation.y; - myrot.Z = _orientation.z; - d.GeomSetQuaternion(prim_geom, ref myrot); - - - } - } else { - prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); - myrot.W = _orientation.w; - myrot.X = _orientation.x; - myrot.Y = _orientation.y; - myrot.Z = _orientation.z; - d.GeomSetQuaternion(prim_geom, ref myrot); - - - //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); - if (IsPhysical && Body == (IntPtr)0) - { - // Re creates body on size. - // EnableBody also does setMass() - enableBody(); - d.BodyEnable(Body); - } - - } - - - _parent_scene.geom_name_map[prim_geom] = oldname; - - } + } } @@ -1775,58 +1877,7 @@ namespace OpenSim.Region.Physics.OdePlugin set { _pbs = value; - lock (OdeScene.OdeLock) - { - string oldname = _parent_scene.geom_name_map[prim_geom]; - - // Cleanup of old prim geometry and Bodies - if (IsPhysical && Body != (IntPtr)0) - { - disableBody(); - } - d.GeomDestroy(prim_geom); - if (_mesh != null) - { - - d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); - - } - - // Construction of new prim - if (this._parent_scene.needsMeshing(_pbs)) - { - IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); - if (mesh != null) - { - setMesh(_parent_scene, mesh); - } - else - { - prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); - } - } else { - prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); - } - if (IsPhysical && Body == (IntPtr)0) - { - //re-create new body - enableBody(); - } - else - { - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); - myrot.W = _orientation.w; - myrot.X = _orientation.x; - myrot.Y = _orientation.y; - myrot.Z = _orientation.z; - d.GeomSetQuaternion(prim_geom, ref myrot); - } - _parent_scene.geom_name_map[prim_geom] = oldname; - - - - } + } } @@ -1856,19 +1907,7 @@ namespace OpenSim.Region.Physics.OdePlugin set { _orientation = value; - lock (OdeScene.OdeLock) - { - d.Quaternion myrot = new d.Quaternion(); - myrot.W = _orientation.w; - myrot.X = _orientation.x; - myrot.Y = _orientation.y; - myrot.Z = _orientation.z; - d.GeomSetQuaternion(prim_geom, ref myrot); - if (m_isphysical && Body != (IntPtr)0) - { - d.BodySetQuaternion(Body, ref myrot); - } - } + } } @@ -1886,10 +1925,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override void AddForce(PhysicsVector force) { } - public void Move(float timestep) - { - - } + public override PhysicsVector RotationalVelocity { get{ return m_rotationalVelocity;} @@ -1928,18 +1964,19 @@ namespace OpenSim.Region.Physics.OdePlugin - IsPhysical = false; + //IsPhysical = false; + base.RaiseOutOfBounds(_position); _velocity.X = 0; _velocity.Y = 0; _velocity.Z = 0; m_rotationalVelocity.X = 0; m_rotationalVelocity.Y = 0; m_rotationalVelocity.Z = 0; - //base.RequestPhysicsterseUpdate(); + base.RequestPhysicsterseUpdate(); m_throttleUpdates = false; throttleCounter = 0; _zeroFlag = true; - outofBounds = true; + //outofBounds = true; } if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs index cc1d16b440..15b3415966 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs @@ -163,7 +163,10 @@ namespace OpenSim.Region.Physics.POSPlugin } return false; } + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + } public override void Simulate(float timeStep) { foreach (POSCharacter character in _characters) diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs index 8956f1a7ee..799a7d40aa 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs @@ -135,7 +135,10 @@ namespace OpenSim.Region.Physics.PhysXPlugin { return AddPrim(position, size, rotation); } + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + } public override void Simulate(float timeStep) { try