diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 708da155a2..d8cb11c0f8 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -737,12 +737,27 @@ namespace OpenSim.Region.Environment.Scenes m_statsReporter.addOtherMS(otherMS); m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScripts()); m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS()); - + } catch (NotImplementedException) { throw; } + catch (System.AccessViolationException e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + + } + catch (System.NullReferenceException e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + + } + catch (System.InvalidOperationException e) + { + m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); + + } catch (Exception e) { m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index e8d4766aa7..519858b30b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -1265,23 +1265,11 @@ namespace OpenSim.Region.Environment.Scenes if (part != null) { part.UpdateShape(shapeBlock); - } - if (m_rootPart.PhysActor != null) - { - m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); - m_rootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - m_rootPart.Name, - m_rootPart.Shape, - new PhysicsVector(m_rootPart.AbsolutePosition.X, m_rootPart.AbsolutePosition.Y, - m_rootPart.AbsolutePosition.Z), - new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z), - new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X, - 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, true); + if (part.PhysActor != null) + m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); } + } #endregion @@ -1299,15 +1287,24 @@ namespace OpenSim.Region.Environment.Scenes if (part != null) { part.Resize(scale); - if (part.UUID == m_rootPart.UUID) + if (part.PhysActor != null) { - if (m_rootPart.PhysActor != null) - { - m_rootPart.PhysActor.Size = - new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); - } + part.PhysActor.Size = + new PhysicsVector(scale.X, scale.Y, scale.Z); + m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); } + if (part.UUID != m_rootPart.UUID) + ScheduleGroupForFullUpdate(); + + //if (part.UUID == m_rootPart.UUID) + //{ + //if (m_rootPart.PhysActor != null) + //{ + //m_rootPart.PhysActor.Size = + //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); + //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + //} + //} } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 1d5dd5b5ce..5756a0bc64 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -1182,6 +1182,10 @@ namespace OpenSim.Region.Environment.Scenes m_shape.PathTaperY = shapeBlock.PathTaperY; m_shape.PathTwist = shapeBlock.PathTwist; m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; + if (PhysActor != null) + { + PhysActor.Shape = m_shape; + } ScheduleFullUpdate(); } @@ -1583,6 +1587,7 @@ namespace OpenSim.Region.Environment.Scenes public void Resize(LLVector3 scale) { m_shape.Scale = scale; + ScheduleFullUpdate(); } diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index a6acdeb5bf..6b8d0e2f4f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -508,7 +508,12 @@ namespace OpenSim.Region.Physics.OdePlugin public override PhysicsVector Velocity { - get { return _velocity; } + get { + if (_zeroFlag) + return PhysicsVector.Zero; + m_lastUpdateSent = false; + return _velocity; + } set { m_pidControllerActive = true; @@ -612,7 +617,7 @@ namespace OpenSim.Region.Physics.OdePlugin _zeroPosition = d.BodyGetPosition(Body); } //PidStatus = true; - + PhysicsVector vec = new PhysicsVector(); d.Vector3 vel = d.BodyGetLinearVel(Body); float movementdivisor = 1f; diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 59c1f873b5..fae53167aa 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -682,6 +682,11 @@ namespace OpenSim.Region.Physics.OdePlugin public void changePhysicsStatus(float timestap) { + while (ode.lockquery()) + { + } + ode.dlock(_parent_scene.world); + if (m_isphysical == true) { if (Body == (IntPtr) 0) @@ -696,6 +701,9 @@ namespace OpenSim.Region.Physics.OdePlugin disableBody(); } } + + ode.dunlock(_parent_scene.world); + resetCollisionAccounting(); m_taintPhysics = m_isphysical; } @@ -730,7 +738,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.SpaceRemove(m_targetSpace, prim_geom); } d.GeomDestroy(prim_geom); - + prim_geom = (IntPtr)0; // we don't need to do space calculation because the client sends a position update also. // Construction of new prim @@ -742,6 +750,23 @@ namespace OpenSim.Region.Physics.OdePlugin if (mesh != null) { setMesh(_parent_scene, mesh); + 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); + } } else { @@ -870,37 +895,120 @@ namespace OpenSim.Region.Physics.OdePlugin disableBody(); } d.GeomDestroy(prim_geom); - if (_mesh != null) - { - d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); - } + prim_geom = (IntPtr) 0; + // we don't need to do space calculation because the client sends a position update also. // Construction of new prim if (_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); + 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); + } } else + { + if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) + { + if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000)) + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); + } + else + { + m_log.Info("[PHYSICS]: Failed to load a sphere bad size"); + _parent_scene.waitForSpaceUnlock(m_targetSpace); + SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + + } + else + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + } + //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight) + //{ + //Cyllinder + //if (_size.X == _size.Y) + //{ + // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z); + //} + //else + //{ + //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + //} + //} + else + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + //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 + { + if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); + } + else + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + } + //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight) + //{ + //Cyllinder + //if (_size.X == _size.Y) + //{ + //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z); + //} + //else + //{ + //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + //} + //} + else { _parent_scene.waitForSpaceUnlock(m_targetSpace); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); } - } - else - { - _parent_scene.waitForSpaceUnlock(m_targetSpace); - SetGeom(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; @@ -908,6 +1016,16 @@ namespace OpenSim.Region.Physics.OdePlugin 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; @@ -924,7 +1042,7 @@ namespace OpenSim.Region.Physics.OdePlugin } ode.dlock(_parent_scene.world); - System.Threading.Thread.Sleep(2); + lock (m_forcelist) { //m_log.Info("[PHYSICS]: dequeing forcelist"); @@ -1048,7 +1166,11 @@ namespace OpenSim.Region.Physics.OdePlugin public override PrimitiveBaseShape Shape { - set { _pbs = value; } + set { + + _pbs = value; + m_taintshape = true; + } } public override PhysicsVector Velocity diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 3d70a3da53..d7d9ab12b0 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -330,6 +330,7 @@ namespace OpenSim.Region.Physics.OdePlugin catch (SEHException) { m_log.Error("[PHYSICS]: 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."); + ode.drelease(world); base.TriggerPhysicsBasedRestart(); } catch (System.AccessViolationException) @@ -737,87 +738,92 @@ namespace OpenSim.Region.Physics.OdePlugin /// public void RemovePrimThreadLocked(OdePrim prim) { - while (ode.lockquery()) + lock (ode) { - } - ode.dlock(world); - //System.Threading.Thread.Sleep(20); - prim.ResetTaints(); - - - if (prim.IsPhysical) + if (prim.prim_geom != (IntPtr)0) { - 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 - //m_log.Warn(prim.m_targetSpace); - if (prim.prim_geom == (IntPtr)0) - prim.prim_geom = prim.prev_geom; + while (ode.lockquery()) + { + } + ode.dlock(world); + //System.Threading.Thread.Sleep(20); + prim.ResetTaints(); - if (prim.m_targetSpace != (IntPtr)0) - { - if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom)) - { - - if (d.GeomIsSpace(prim.m_targetSpace)) - { - waitForSpaceUnlock(prim.m_targetSpace); - d.SpaceRemove(prim.m_targetSpace, prim.prim_geom); - prim.m_targetSpace = space; - } - else - { - m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + - ((OdePrim)prim).m_targetSpace.ToString()); - } - - } - } - //m_log.Warn(prim.prim_geom); - try - { - if (prim.prim_geom != (IntPtr)0) - { - d.GeomDestroy(prim.prim_geom); - prim.prim_geom = (IntPtr) 0; - } - - } - catch (System.AccessViolationException) - { - m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); - } - _prims.Remove(prim); - //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.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 + //m_log.Warn(prim.m_targetSpace); + + + if (prim.m_targetSpace != (IntPtr)0) + { + if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom)) + { + + if (d.GeomIsSpace(prim.m_targetSpace)) + { + waitForSpaceUnlock(prim.m_targetSpace); + d.SpaceRemove(prim.m_targetSpace, prim.prim_geom); + prim.m_targetSpace = space; + } + else + { + m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + + ((OdePrim)prim).m_targetSpace.ToString()); + } + + } + } + //m_log.Warn(prim.prim_geom); + try + { + if (prim.prim_geom != (IntPtr)0) + { + d.GeomDestroy(prim.prim_geom); + prim.prim_geom = (IntPtr)0; + } + + } + catch (System.AccessViolationException) + { + m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); + } + _prims.Remove(prim); + + //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)) - //{ - //waitForSpaceUnlock(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 - //{ - //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + - //((OdePrim) prim).m_targetSpace.ToString()); - //} + //if (d.GeomIsSpace(prim.m_targetSpace)) + //{ + //waitForSpaceUnlock(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 + //{ + //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + + //((OdePrim) prim).m_targetSpace.ToString()); + //} + //} + //} + } - - - ode.dunlock(world); + + + ode.dunlock(world); + } + } } /// /// Takes a space pointer and zeros out the array we're using to hold the spaces @@ -1238,6 +1244,7 @@ namespace OpenSim.Region.Physics.OdePlugin catch (StackOverflowException) { m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim."); + ode.drelease(world); base.TriggerPhysicsBasedRestart(); } @@ -1249,33 +1256,32 @@ namespace OpenSim.Region.Physics.OdePlugin while (step_time > 0.0f) { - foreach (OdeCharacter actor in _characters) + lock (ode) { - actor.Move(timeStep); - actor.collidelock = true; - } - if (!ode.lockquery()) - { - ode.dlock(world); + if (!ode.lockquery()) + { + ode.dlock(world); + foreach (OdeCharacter actor in _characters) + { + actor.Move(timeStep); + + } + - collision_optimized(timeStep); + collision_optimized(timeStep); - d.WorldQuickStep(world, ODE_STEPSIZE); - - d.JointGroupEmpty(contactgroup); - ode.dunlock(world); + d.WorldQuickStep(world, ODE_STEPSIZE); - step_time -= ODE_STEPSIZE; - i++; - } - else - { - fps = 0; - } + d.JointGroupEmpty(contactgroup); + ode.dunlock(world); - foreach (OdeCharacter actor in _characters) - { - actor.collidelock = false; + step_time -= ODE_STEPSIZE; + i++; + } + else + { + fps = 0; + } } }