From 746829967315cc82560a855a4772e45888bf8fbe Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 3 Apr 2012 05:50:13 +0100 Subject: [PATCH 1/3] Eliminate race condition where many callers would check SOP.PhysicsActor != null then assume it was still not null in later code. Another thread could come and turn off physics for a part (null PhysicsActor) at any point. Had to turn off localCopy on warp3D CoreModules section in prebuild.xml since on current nant this copies all DLLs in bin/ which can be a very large number with compiled DLLs No obvious reason for doing that copy - nothing else does it. --- .../EntityTransfer/EntityTransferModule.cs | 8 +- OpenSim/Region/Framework/Scenes/Scene.cs | 4 - OpenSim/Region/Framework/Scenes/SceneGraph.cs | 3 +- .../Framework/Scenes/SceneObjectGroup.cs | 140 +++++++----- .../Framework/Scenes/SceneObjectPart.cs | 207 ++++++++++-------- prebuild.xml | 2 +- 6 files changed, 209 insertions(+), 155 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 427a49d248..86e10d491f 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -36,6 +36,7 @@ using OpenSim.Framework.Capabilities; using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; @@ -1803,10 +1804,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (!grp.IsDeleted) { - if (grp.RootPart.PhysActor != null) - { - grp.RootPart.PhysActor.CrossingFailure(); - } + PhysicsActor pa = grp.RootPart.PhysActor; + if (pa != null) + pa.CrossingFailure(); } m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 06f7c0f64a..29825a252e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -642,10 +642,6 @@ namespace OpenSim.Region.Framework.Scenes #endregion Region Settings - MainConsole.Instance.Commands.AddCommand("Estates", false, "reload estate", - "reload estate", - "Reload the estate data", HandleReloadEstate); - //Bind Storage Manager functions to some land manager functions for this scene EventManager.OnLandObjectAdded += new EventManager.LandObjectAdded(simDataService.StoreLandObject); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 8a05772c61..0098addb42 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -306,7 +306,8 @@ namespace OpenSim.Region.Framework.Scenes if (rot != null) sceneObject.UpdateGroupRotationR((Quaternion)rot); - if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) + PhysicsActor pa = sceneObject.RootPart.PhysActor; + if (pa != null && pa.IsPhysical && vel != Vector3.Zero) { sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false); sceneObject.Velocity = vel; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 04b3766b15..87fdc41d73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -523,16 +523,21 @@ namespace OpenSim.Region.Framework.Scenes { m_isSelected = value; // Tell physics engine that group is selected - if (m_rootPart.PhysActor != null) + + PhysicsActor pa = m_rootPart.PhysActor; + if (pa != null) { - m_rootPart.PhysActor.Selected = value; + pa.Selected = value; + // Pass it on to the children. SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart child = parts[i]; - if (child.PhysActor != null) - child.PhysActor.Selected = value; + + PhysicsActor childPa = child.PhysActor; + if (childPa != null) + childPa.Selected = value; } } } @@ -1478,7 +1483,8 @@ namespace OpenSim.Region.Framework.Scenes } // Need to duplicate the physics actor as well - if (part.PhysActor != null && userExposed) + PhysicsActor originalPartPa = part.PhysActor; + if (originalPartPa != null && userExposed) { PrimitiveBaseShape pbs = newPart.Shape; @@ -1489,10 +1495,10 @@ namespace OpenSim.Region.Framework.Scenes newPart.AbsolutePosition, newPart.Scale, newPart.RotationOffset, - part.PhysActor.IsPhysical, + originalPartPa.IsPhysical, newPart.LocalId); - newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); + newPart.DoPhysicsPropertyUpdate(originalPartPa.IsPhysical, true); } } @@ -1564,45 +1570,53 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (RootPart.PhysActor != null) + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) { - RootPart.PhysActor.AddForce(impulse, true); - m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); + pa.AddForce(impulse, true); + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } public void applyAngularImpulse(Vector3 impulse) { - if (RootPart.PhysActor != null) + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) { if (!IsAttachment) { - RootPart.PhysActor.AddAngularForce(impulse, true); - m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); + pa.AddAngularForce(impulse, true); + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } public void setAngularImpulse(Vector3 impulse) { - if (RootPart.PhysActor != null) + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) { if (!IsAttachment) { - RootPart.PhysActor.Torque = impulse; - m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); + pa.Torque = impulse; + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } public Vector3 GetTorque() { - if (RootPart.PhysActor != null) + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) { if (!IsAttachment) { - Vector3 torque = RootPart.PhysActor.Torque; + Vector3 torque = pa.Torque; return torque; } } @@ -1622,19 +1636,23 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (RootPart.PhysActor != null) + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) { - RootPart.PhysActor.PIDTarget = target; - RootPart.PhysActor.PIDTau = tau; - RootPart.PhysActor.PIDActive = true; + pa.PIDTarget = target; + pa.PIDTau = tau; + pa.PIDActive = true; } } } public void stopMoveToTarget() { - if (RootPart.PhysActor != null) - RootPart.PhysActor.PIDActive = false; + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) + pa.PIDActive = false; } /// @@ -1645,18 +1663,20 @@ namespace OpenSim.Region.Framework.Scenes /// Number of seconds over which to reach target public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) { - if (RootPart.PhysActor != null) + PhysicsActor pa = RootPart.PhysActor; + + if (pa != null) { if (height != 0f) { - RootPart.PhysActor.PIDHoverHeight = height; - RootPart.PhysActor.PIDHoverType = hoverType; - RootPart.PhysActor.PIDTau = tau; - RootPart.PhysActor.PIDHoverActive = true; + pa.PIDHoverHeight = height; + pa.PIDHoverType = hoverType; + pa.PIDTau = tau; + pa.PIDHoverActive = true; } else { - RootPart.PhysActor.PIDHoverActive = false; + pa.PIDHoverActive = false; } } } @@ -2094,10 +2114,10 @@ namespace OpenSim.Region.Framework.Scenes linkPart.ParentID = 0; linkPart.LinkNum = 0; - if (linkPart.PhysActor != null) - { - m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); - } + PhysicsActor linkPartPa = linkPart.PhysActor; + + if (linkPartPa != null) + m_scene.PhysicsScene.RemovePrim(linkPartPa); // We need to reset the child part's position // ready for life as a separate object after being a part of another object @@ -2188,17 +2208,19 @@ namespace OpenSim.Region.Framework.Scenes { if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) { - if (m_rootPart.PhysActor != null) + PhysicsActor pa = m_rootPart.PhysActor; + + if (pa != null) { - if (m_rootPart.PhysActor.IsPhysical) + if (pa.IsPhysical) { if (!m_rootPart.BlockGrab) { Vector3 llmoveforce = pos - AbsolutePosition; Vector3 grabforce = llmoveforce; - grabforce = (grabforce / 10) * m_rootPart.PhysActor.Mass; - m_rootPart.PhysActor.AddForce(grabforce, true); - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + grabforce = (grabforce / 10) * pa.Mass; + pa.AddForce(grabforce, true); + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } } else @@ -2228,9 +2250,11 @@ namespace OpenSim.Region.Framework.Scenes { if (m_scene.EventManager.TriggerGroupSpinStart(UUID)) { - if (m_rootPart.PhysActor != null) + PhysicsActor pa = m_rootPart.PhysActor; + + if (pa != null) { - if (m_rootPart.PhysActor.IsPhysical) + if (pa.IsPhysical) { m_rootPart.IsWaitingForFirstSpinUpdatePacket = true; } @@ -2271,12 +2295,13 @@ namespace OpenSim.Region.Framework.Scenes // but it will result in over-shoot or under-shoot of the target orientation. // For the end user, this means that ctrl+shift+drag can be used for relative, // but not absolute, adjustments of orientation for physical prims. - if (m_scene.EventManager.TriggerGroupSpin(UUID, newOrientation)) { - if (m_rootPart.PhysActor != null) + PhysicsActor pa = m_rootPart.PhysActor; + + if (pa != null) { - if (m_rootPart.PhysActor.IsPhysical) + if (pa.IsPhysical) { if (m_rootPart.IsWaitingForFirstSpinUpdatePacket) { @@ -2302,9 +2327,9 @@ namespace OpenSim.Region.Framework.Scenes //m_log.Error("SCENE OBJECT GROUP]: rotation axis is " + rotationAxis); Vector3 spinforce = new Vector3(rotationAxis.X, rotationAxis.Y, rotationAxis.Z); - spinforce = (spinforce/8) * m_rootPart.PhysActor.Mass; // 8 is an arbitrary torque scaling factor - m_rootPart.PhysActor.AddAngularForce(spinforce,true); - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + spinforce = (spinforce/8) * pa.Mass; // 8 is an arbitrary torque scaling factor + pa.AddAngularForce(spinforce,true); + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } } else @@ -2478,8 +2503,10 @@ namespace OpenSim.Region.Framework.Scenes { part.UpdateShape(shapeBlock); - if (part.PhysActor != null) - m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); + PhysicsActor pa = m_rootPart.PhysActor; + + if (pa != null) + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } } @@ -2502,7 +2529,9 @@ namespace OpenSim.Region.Framework.Scenes scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); - if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) + PhysicsActor pa = m_rootPart.PhysActor; + + if (pa != null && pa.IsPhysical) { scale.X = Math.Min(scale.X, Scene.m_maxPhys); scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); @@ -2528,7 +2557,7 @@ namespace OpenSim.Region.Framework.Scenes float f = 1.0f; float a = 1.0f; - if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) + if (pa != null && pa.IsPhysical) { if (oldSize.X * x > m_scene.m_maxPhys) { @@ -2893,10 +2922,13 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.StoreUndoState(); m_rootPart.UpdateRotation(rot); - if (m_rootPart.PhysActor != null) + + PhysicsActor pa = m_rootPart.PhysActor; + + if (pa != null) { - m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + pa.Orientation = m_rootPart.RotationOffset; + m_scene.PhysicsScene.AddPhysicsActorTaint(pa); } SceneObjectPart[] parts = m_parts.GetArray(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 439b718bc1..2b1fba0fb1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -151,6 +151,14 @@ namespace OpenSim.Region.Framework.Scenes public int[] PayPrice = {-2,-2,-2,-2,-2}; [XmlIgnore] + /// + /// The representation of this part in the physics scene. + /// + /// + /// If you use this property more than once in a section of code then you must take a reference and use that. + /// If another thread is simultaneously turning physics off on this part then this refernece could become + /// null at any time. + /// public PhysicsActor PhysActor { get { return m_physActor; } @@ -522,10 +530,11 @@ namespace OpenSim.Region.Framework.Scenes set { m_name = value; - if (PhysActor != null) - { - PhysActor.SOPName = value; - } + + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.SOPName = value; } } @@ -535,10 +544,11 @@ namespace OpenSim.Region.Framework.Scenes set { m_material = (Material)value; - if (PhysActor != null) - { - PhysActor.SetMaterial((int)value); - } + + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.SetMaterial((int)value); } } @@ -669,9 +679,7 @@ namespace OpenSim.Region.Framework.Scenes // If this is a linkset, we don't want the physics engine mucking up our group position here. PhysicsActor actor = PhysActor; if (actor != null && ParentID == 0) - { m_groupPosition = actor.Position; - } if (ParentGroup.IsAttachment) { @@ -979,7 +987,7 @@ namespace OpenSim.Region.Framework.Scenes if (Shape.SculptEntry) CheckSculptAndLoad(); else - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } } } @@ -1505,12 +1513,14 @@ namespace OpenSim.Region.Framework.Scenes } // Basic Physics can also return null as well as an exception catch. - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { - PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info - PhysActor.SetMaterial(Material); + pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info + pa.SetMaterial(Material); DoPhysicsPropertyUpdate(RigidBody, true); - PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); + pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } } } @@ -1731,23 +1741,25 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { - if (UsePhysics != PhysActor.IsPhysical || isNew) + if (UsePhysics != pa.IsPhysical || isNew) { - if (PhysActor.IsPhysical) // implies UsePhysics==false for this block + if (pa.IsPhysical) // implies UsePhysics==false for this block { if (!isNew) ParentGroup.Scene.RemovePhysicalPrim(1); - PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; - PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; - PhysActor.delink(); + pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; + pa.OnOutOfBounds -= PhysicsOutOfBounds; + pa.delink(); if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) { // destroy all joints connected to this now deactivated body - ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); + ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); } // stop client-side interpolation of all joint proxy objects that have just been deleted @@ -1766,7 +1778,7 @@ namespace OpenSim.Region.Framework.Scenes //RotationalVelocity = new Vector3(0, 0, 0); } - PhysActor.IsPhysical = UsePhysics; + pa.IsPhysical = UsePhysics; // If we're not what we're supposed to be in the physics scene, recreate ourselves. //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); @@ -1779,13 +1791,15 @@ namespace OpenSim.Region.Framework.Scenes { ParentGroup.Scene.AddPhysicalPrim(1); - PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; - PhysActor.OnOutOfBounds += PhysicsOutOfBounds; + pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; + pa.OnOutOfBounds += PhysicsOutOfBounds; if (ParentID != 0 && ParentID != LocalId) { - if (ParentGroup.RootPart.PhysActor != null) + PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; + + if (parentPa != null) { - PhysActor.link(ParentGroup.RootPart.PhysActor); + pa.link(parentPa); } } } @@ -1797,7 +1811,7 @@ namespace OpenSim.Region.Framework.Scenes if (Shape.SculptEntry) CheckSculptAndLoad(); else - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -1908,24 +1922,30 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 GetGeometricCenter() { - if (PhysActor != null) - return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); + PhysicsActor pa = PhysActor; + + if (pa != null) + return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); else return new Vector3(0, 0, 0); } public float GetMass() { - if (PhysActor != null) - return PhysActor.Mass; + PhysicsActor pa = PhysActor; + + if (pa != null) + return pa.Mass; else return 0; } public Vector3 GetForce() { - if (PhysActor != null) - return PhysActor.Force; + PhysicsActor pa = PhysActor; + + if (pa != null) + return pa.Force; else return Vector3.Zero; } @@ -2556,9 +2576,11 @@ namespace OpenSim.Region.Framework.Scenes public void PhysicsRequestingTerseUpdate() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { - Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); + Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) @@ -2570,6 +2592,7 @@ namespace OpenSim.Region.Framework.Scenes } //ParentGroup.RootPart.m_groupPosition = newpos; } + ScheduleTerseUpdate(); } @@ -2660,7 +2683,9 @@ namespace OpenSim.Region.Framework.Scenes scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); - if (PhysActor != null && PhysActor.IsPhysical) + PhysicsActor pa = PhysActor; + + if (pa != null && pa.IsPhysical) { scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); @@ -2809,12 +2834,14 @@ namespace OpenSim.Region.Framework.Scenes m_shape.SculptData = texture.Data; } - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { // Update the physics actor with the new loaded sculpt data and set the taint signal. - PhysActor.Shape = m_shape; + pa.Shape = m_shape; - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } } } @@ -3072,10 +3099,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetBuoyancy(float fvalue) { - if (PhysActor != null) - { - PhysActor.Buoyancy = fvalue; - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.Buoyancy = fvalue; } public void SetDieAtEdge(bool p) @@ -3088,57 +3115,50 @@ namespace OpenSim.Region.Framework.Scenes public void SetFloatOnWater(int floatYN) { - if (PhysActor != null) - { - if (floatYN == 1) - { - PhysActor.FloatOnWater = true; - } - else - { - PhysActor.FloatOnWater = false; - } - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.FloatOnWater = floatYN == 1; } public void SetForce(Vector3 force) { - if (PhysActor != null) - { - PhysActor.Force = force; - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.Force = force; } public void SetVehicleType(int type) { - if (PhysActor != null) - { - PhysActor.VehicleType = type; - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.VehicleType = type; } public void SetVehicleFloatParam(int param, float value) { - if (PhysActor != null) - { - PhysActor.VehicleFloatParam(param, value); - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.VehicleFloatParam(param, value); } public void SetVehicleVectorParam(int param, Vector3 value) { - if (PhysActor != null) - { - PhysActor.VehicleVectorParam(param, value); - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.VehicleVectorParam(param, value); } public void SetVehicleRotationParam(int param, Quaternion rotation) { - if (PhysActor != null) - { - PhysActor.VehicleRotationParam(param, rotation); - } + PhysicsActor pa = PhysActor; + + if (pa != null) + pa.VehicleRotationParam(param, rotation); } /// @@ -4226,6 +4246,8 @@ namespace OpenSim.Region.Framework.Scenes if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) return; + PhysicsActor pa = PhysActor; + // Special cases for VD. VD can only be called from a script // and can't be combined with changes to other states. So we can rely // that... @@ -4241,8 +4263,9 @@ namespace OpenSim.Region.Framework.Scenes { SetVD = false; // Switch it of for the course of this routine VolumeDetectActive = false; // and also permanently - if (PhysActor != null) - PhysActor.SetVolumeDetect(0); // Let physics know about it too + + if (pa != null) + pa.SetVolumeDetect(0); // Let physics know about it too } else { @@ -4357,9 +4380,9 @@ namespace OpenSim.Region.Framework.Scenes // Defensive programming calls for a check here. // Better would be throwing an exception that could be catched by a unit test as the internal // logic should make sure, this Physactor is always here. - if (this.PhysActor != null) + if (pa != null) { - PhysActor.SetVolumeDetect(1); + pa.SetVolumeDetect(1); AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active this.VolumeDetectActive = true; } @@ -4368,11 +4391,8 @@ namespace OpenSim.Region.Framework.Scenes { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // (mumbles, well, at least if you have infinte CPU powers :-)) - PhysicsActor pa = this.PhysActor; if (pa != null) - { PhysActor.SetVolumeDetect(0); - } this.VolumeDetectActive = false; } @@ -4385,6 +4405,7 @@ namespace OpenSim.Region.Framework.Scenes { RemFlag(PrimFlags.TemporaryOnRez); } + // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); if (ParentGroup != null) @@ -4453,10 +4474,12 @@ namespace OpenSim.Region.Framework.Scenes m_shape.PathTwist = shapeBlock.PathTwist; m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { - PhysActor.Shape = m_shape; - ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); + pa.Shape = m_shape; + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } // This is what makes vehicle trailers work @@ -4598,6 +4621,8 @@ namespace OpenSim.Region.Framework.Scenes objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; } + PhysicsActor pa = PhysActor; + if ( ((AggregateScriptEvents & scriptEvents.collision) != 0) || ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || @@ -4609,18 +4634,18 @@ namespace OpenSim.Region.Framework.Scenes ) { // subscribe to physics updates. - if (PhysActor != null) + if (pa != null) { - PhysActor.OnCollisionUpdate += PhysicsCollision; - PhysActor.SubscribeEvents(1000); + pa.OnCollisionUpdate += PhysicsCollision; + pa.SubscribeEvents(1000); } } else { - if (PhysActor != null) + if (pa != null) { - PhysActor.UnSubscribeEvents(); - PhysActor.OnCollisionUpdate -= PhysicsCollision; + pa.UnSubscribeEvents(); + pa.OnCollisionUpdate -= PhysicsCollision; } } diff --git a/prebuild.xml b/prebuild.xml index a8b735ccf4..6a90d647d6 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1455,7 +1455,7 @@ - + From e480e25d8bee9180c4421834df0d898171d4c3f1 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 3 Apr 2012 06:01:05 +0100 Subject: [PATCH 2/3] Fix more SOP.PhysActor race conditions in LSL_Api --- .../Shared/Api/Implementation/LSL_Api.cs | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b502ab8f6e..8d25a62cb8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1362,7 +1362,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (scale.z < 0.01) scale.z = 0.01; - if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical) + PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; + + if (pa != null && pa.IsPhysical) { if (scale.x > World.m_maxPhys) scale.x = World.m_maxPhys; @@ -2088,7 +2090,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // but only if the object is not physial and active. This is important for rotating doors. // without the absoluteposition = absoluteposition happening, the doors do not move in the physics // scene - if (part.PhysActor != null && !part.PhysActor.IsPhysical) + PhysicsActor pa = part.PhysActor; + + if (pa != null && !pa.IsPhysical) { part.ParentGroup.ResetChildPrimPhysicsPositions(); } @@ -2819,7 +2823,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api float groupmass = new_group.GetMass(); - if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero) + PhysicsActor pa = new_group.RootPart.PhysActor; + + if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) { //Recoil. llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); @@ -2860,12 +2866,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // we need to convert from a vector describing // the angles of rotation in radians into rotation value - LSL_Rotation rot = llEuler2Rot(angle); // Per discussion with Melanie, for non-physical objects llLookAt appears to simply // set the rotation of the object, copy that behavior - if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) + PhysicsActor pa = m_host.PhysActor; + + if (strength == 0 || pa == null || !pa.IsPhysical) { llSetRot(rot); } @@ -3201,6 +3208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetHoverHeight(double height, int water, double tau) { m_host.AddScriptLPS(1); + if (m_host.PhysActor != null) { PIDHoverType hoverType = PIDHoverType.Ground; @@ -3251,7 +3259,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Per discussion with Melanie, for non-physical objects llLookAt appears to simply // set the rotation of the object, copy that behavior - if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) + PhysicsActor pa = m_host.PhysActor; + + if (strength == 0 || pa == null || !pa.IsPhysical) { llSetLocalRot(target); } @@ -10728,7 +10738,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (entity is SceneObjectPart) { - if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) + PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; + + if (pa != null && pa.IsPhysical) { if (!checkPhysical) continue; From 9a9923405a956026b1b67b4f6f993a292b230f67 Mon Sep 17 00:00:00 2001 From: Garmin Kawaguichi Date: Tue, 3 Apr 2012 16:56:51 +0200 Subject: [PATCH 3/3] terrain save-tile extensions Signed-off-by: Garmin Kawaguichi Signed-off-by: Melanie --- .../World/Terrain/FileLoaders/BMP.cs | 6 ++++++ .../World/Terrain/FileLoaders/GIF.cs | 6 ++++++ .../FileLoaders/GenericSystemDrawing.cs | 6 ++++++ .../World/Terrain/FileLoaders/JPEG.cs | 6 ++++++ .../World/Terrain/FileLoaders/LLRAW.cs | 7 +++++++ .../World/Terrain/FileLoaders/PNG.cs | 6 ++++++ .../World/Terrain/FileLoaders/RAW32.cs | 6 ++++++ .../World/Terrain/FileLoaders/TIFF.cs | 6 ++++++ .../World/Terrain/FileLoaders/Terragen.cs | 6 ++++++ .../World/Terrain/ITerrainLoader.cs | 4 ++++ .../CoreModules/World/Terrain/TerrainModule.cs | 18 +++++++++++++++--- 11 files changed, 74 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs index 90f124bcbf..fb57c8275b 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs @@ -72,5 +72,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { return "BMP"; } + + //Returns true if this extension is supported for terrain save-tile + public override bool SupportsTileSave() + { + return false; + } } } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs index f331b562cd..79cc50b386 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs @@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { return "GIF"; } + + //Returns true if this extension is supported for terrain save-tile + public override bool SupportsTileSave() + { + return false; + } } } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index 58925fd624..da81dc16a9 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -177,6 +177,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders return "SYS.DRAWING"; } + //Returns true if this extension is supported for terrain save-tile + public virtual bool SupportsTileSave() + { + return false; + } + /// /// Protected method, generates a grayscale bitmap /// image from a specified terrain channel. diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs index 1a0d8ecf60..699d67a440 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs @@ -91,6 +91,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders return "JPEG"; } + //Returns true if this extension is supported for terrain save-tile + public bool SupportsTileSave() + { + return false; + } + private static Bitmap CreateBitmapFromMap(ITerrainChannel map) { Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs index fad7641e42..62d232e833 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs @@ -254,5 +254,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { return "LL/SL RAW"; } + + //Returns true if this extension is supported for terrain save-tile + public bool SupportsTileSave() + { + return false; + } + } } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs index e009ecf833..c5c12ae6cf 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs @@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { return "PNG"; } + + //Returns true if this extension is supported for terrain save-tile + public override bool SupportsTileSave() + { + return true; + } } } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs index ba073cae5a..9fb7ef796e 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs @@ -173,5 +173,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { return "RAW32"; } + + //Returns true if this extension is supported for terrain save-tile + public bool SupportsTileSave() + { + return false; + } } } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs index fc1ad33baf..5d2f8937b4 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs @@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { return "TIFF"; } + + //Returns true if this extension is supported for terrain save-tile + public bool SupportsTileSave() + { + return false; + } } } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 2f37d9d7e9..1ebf91654c 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs @@ -323,6 +323,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders return "Terragen"; } + //Returns true if this extension is supported for terrain save-tile + public bool SupportsTileSave() + { + return false; + } + /// /// terragen SCAL floats need to be written intel ordered regardless of /// big or little endian system diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs index d407617ec5..3ba36577fe 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs @@ -32,6 +32,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain { public interface ITerrainLoader { + // Returns true if that extension can be used for terrain save-tile + // (Look into each file in Region.CoreModules.World.Terrain.FileLoaders) + bool SupportsTileSave(); + string FileExtension { get; } ITerrainChannel LoadFile(string filename); ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight); diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index b3c2969057..8535a5aceb 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -93,6 +93,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain /// private string m_supportedFileExtensions = ""; + //For terrain save-tile file extensions + private string m_supportFileExtensionsForTileSave = ""; + #region ICommandableModule Members public ICommander CommandInterface @@ -148,11 +151,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain // Generate user-readable extensions list string supportedFilesSeparator = ""; + string supportedFilesSeparatorForTileSave = ""; + m_supportFileExtensionsForTileSave = ""; foreach (KeyValuePair loader in m_loaders) { m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")"; supportedFilesSeparator = ", "; + + //For terrain save-tile file extensions + if (loader.Value.SupportsTileSave() == true) + { + m_supportFileExtensionsForTileSave += supportedFilesSeparatorForTileSave + loader.Key + " (" + loader.Value + ")"; + supportedFilesSeparatorForTileSave = ", "; + } } } @@ -589,7 +601,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain // this region is included in the tile request foreach (KeyValuePair loader in m_loaders) { - if (filename.EndsWith(loader.Key)) + if (filename.EndsWith(loader.Key) && loader.Value.SupportsTileSave()) { lock (m_scene) { @@ -610,7 +622,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain MainConsole.Instance.OutputFormat( "ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}", - m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions); + m_scene.RegionInfo.RegionName, filename, m_supportFileExtensionsForTileSave); } /// @@ -1192,7 +1204,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file."); saveToTileCommand.AddArgument("filename", "The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " + - m_supportedFileExtensions, "String"); + m_supportFileExtensionsForTileSave, "String"); saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",