From 633f4bb3d80decf4773ee577bacb153fbb4be738 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Apr 2012 09:28:17 +0100 Subject: remove possible PhysActor unexpectedly null race conditions when changing prim collision status factor out common SOP physics scene adding code into a common SOP.AddToPhysics() that is the counterpart to the existing RemoveFromPhysics() --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 - OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 131 ++++++++++++--------- 2 files changed, 74 insertions(+), 63 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 29825a2..d8cac66 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2163,12 +2163,6 @@ namespace OpenSim.Region.Framework.Scenes part.RemoveFromPhysics(); } } - -// if (rootPart.PhysActor != null) -// { -// PhysicsScene.RemovePrim(rootPart.PhysActor); -// rootPart.PhysActor = null; -// } if (UnlinkSceneObject(group, false)) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2b1fba0..9e65f5d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1488,40 +1488,17 @@ namespace OpenSim.Region.Framework.Scenes if (VolumeDetectActive) isPhantom = false; - // Added clarification.. since A rigid body is an object that you can kick around, etc. - bool RigidBody = isPhysical && !isPhantom; - // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition // or flexible if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) { - try - { - PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( - string.Format("{0}/{1}", Name, UUID), - Shape, - AbsolutePosition, - Scale, - RotationOffset, - RigidBody, - m_localId); - } - catch - { - m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); - PhysActor = null; - } + // Added clarification.. since A rigid body is an object that you can kick around, etc. + bool rigidBody = isPhysical && !isPhantom; - // Basic Physics can also return null as well as an exception catch. - PhysicsActor pa = PhysActor; + PhysicsActor pa = AddToPhysics(rigidBody); if (pa != null) - { - pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info - pa.SetMaterial(Material); - DoPhysicsPropertyUpdate(RigidBody, true); pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); - } } } } @@ -4322,41 +4299,36 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup.Scene == null) return; - if (ParentGroup.Scene.CollidablePrims && PhysActor == null) + if (ParentGroup.Scene.CollidablePrims && pa == null) { - // It's not phantom anymore. So make sure the physics engine get's knowledge of it - PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( - string.Format("{0}/{1}", Name, UUID), - Shape, - AbsolutePosition, - Scale, - RotationOffset, - UsePhysics, - m_localId); + pa = AddToPhysics(UsePhysics); - PhysActor.SetMaterial(Material); - DoPhysicsPropertyUpdate(UsePhysics, true); - - if (!ParentGroup.IsDeleted) + if (pa != null) { - if (LocalId == ParentGroup.RootPart.LocalId) + pa.SetMaterial(Material); + DoPhysicsPropertyUpdate(UsePhysics, true); + + if (!ParentGroup.IsDeleted) { - ParentGroup.CheckSculptAndLoad(); + if (LocalId == ParentGroup.RootPart.LocalId) + { + ParentGroup.CheckSculptAndLoad(); + } + } + + if ( + ((AggregateScriptEvents & scriptEvents.collision) != 0) || + ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + (CollisionSound != UUID.Zero) + ) + { + pa.OnCollisionUpdate += PhysicsCollision; + pa.SubscribeEvents(1000); } - } - - if ( - ((AggregateScriptEvents & scriptEvents.collision) != 0) || - ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || - ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - (CollisionSound != UUID.Zero) - ) - { - PhysActor.OnCollisionUpdate += PhysicsCollision; - PhysActor.SubscribeEvents(1000); } } else // it already has a physical representation @@ -4418,7 +4390,52 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// This removes the part from physics + /// Adds this part to the physics scene. + /// + /// This method also sets the PhysActor property. + /// Add this prim with a rigid body. + /// + /// The physics actor. null if there was a failure. + /// + private PhysicsActor AddToPhysics(bool rigidBody) + { + PhysicsActor pa; + + try + { + pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( + string.Format("{0}/{1}", Name, UUID), + Shape, + AbsolutePosition, + Scale, + RotationOffset, + rigidBody, + m_localId); + } + catch + { + m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); + pa = null; + } + + // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical + // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor + // being set. + PhysActor = pa; + + // Basic Physics can also return null as well as an exception catch. + if (pa != null) + { + pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info + pa.SetMaterial(Material); + DoPhysicsPropertyUpdate(rigidBody, true); + } + + return pa; + } + + /// + /// This removes the part from the physics scene. /// /// /// This isn't the same as turning off physical, since even without being physical the prim has a physics -- cgit v1.1