diff options
author | Justin Clark-Casey (justincc) | 2012-04-03 09:28:17 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-04-03 09:28:17 +0100 |
commit | 633f4bb3d80decf4773ee577bacb153fbb4be738 (patch) | |
tree | e70c777f462a17d73a5bc0db59aefa63aa6d781d | |
parent | Fix more SOP.PhysActor race conditions in LSL_Api (diff) | |
download | opensim-SC-633f4bb3d80decf4773ee577bacb153fbb4be738.zip opensim-SC-633f4bb3d80decf4773ee577bacb153fbb4be738.tar.gz opensim-SC-633f4bb3d80decf4773ee577bacb153fbb4be738.tar.bz2 opensim-SC-633f4bb3d80decf4773ee577bacb153fbb4be738.tar.xz |
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()
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 6 | ||||
-rw-r--r-- | 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 | |||
2163 | part.RemoveFromPhysics(); | 2163 | part.RemoveFromPhysics(); |
2164 | } | 2164 | } |
2165 | } | 2165 | } |
2166 | |||
2167 | // if (rootPart.PhysActor != null) | ||
2168 | // { | ||
2169 | // PhysicsScene.RemovePrim(rootPart.PhysActor); | ||
2170 | // rootPart.PhysActor = null; | ||
2171 | // } | ||
2172 | 2166 | ||
2173 | if (UnlinkSceneObject(group, false)) | 2167 | if (UnlinkSceneObject(group, false)) |
2174 | { | 2168 | { |
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 | |||
1488 | if (VolumeDetectActive) | 1488 | if (VolumeDetectActive) |
1489 | isPhantom = false; | 1489 | isPhantom = false; |
1490 | 1490 | ||
1491 | // Added clarification.. since A rigid body is an object that you can kick around, etc. | ||
1492 | bool RigidBody = isPhysical && !isPhantom; | ||
1493 | |||
1494 | // 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 | 1491 | // 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 |
1495 | // or flexible | 1492 | // or flexible |
1496 | if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) | 1493 | if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) |
1497 | { | 1494 | { |
1498 | try | 1495 | // Added clarification.. since A rigid body is an object that you can kick around, etc. |
1499 | { | 1496 | bool rigidBody = isPhysical && !isPhantom; |
1500 | PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( | ||
1501 | string.Format("{0}/{1}", Name, UUID), | ||
1502 | Shape, | ||
1503 | AbsolutePosition, | ||
1504 | Scale, | ||
1505 | RotationOffset, | ||
1506 | RigidBody, | ||
1507 | m_localId); | ||
1508 | } | ||
1509 | catch | ||
1510 | { | ||
1511 | m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); | ||
1512 | PhysActor = null; | ||
1513 | } | ||
1514 | 1497 | ||
1515 | // Basic Physics can also return null as well as an exception catch. | 1498 | PhysicsActor pa = AddToPhysics(rigidBody); |
1516 | PhysicsActor pa = PhysActor; | ||
1517 | 1499 | ||
1518 | if (pa != null) | 1500 | if (pa != null) |
1519 | { | ||
1520 | pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info | ||
1521 | pa.SetMaterial(Material); | ||
1522 | DoPhysicsPropertyUpdate(RigidBody, true); | ||
1523 | pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); | 1501 | pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); |
1524 | } | ||
1525 | } | 1502 | } |
1526 | } | 1503 | } |
1527 | } | 1504 | } |
@@ -4322,41 +4299,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
4322 | if (ParentGroup.Scene == null) | 4299 | if (ParentGroup.Scene == null) |
4323 | return; | 4300 | return; |
4324 | 4301 | ||
4325 | if (ParentGroup.Scene.CollidablePrims && PhysActor == null) | 4302 | if (ParentGroup.Scene.CollidablePrims && pa == null) |
4326 | { | 4303 | { |
4327 | // It's not phantom anymore. So make sure the physics engine get's knowledge of it | 4304 | pa = AddToPhysics(UsePhysics); |
4328 | PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( | ||
4329 | string.Format("{0}/{1}", Name, UUID), | ||
4330 | Shape, | ||
4331 | AbsolutePosition, | ||
4332 | Scale, | ||
4333 | RotationOffset, | ||
4334 | UsePhysics, | ||
4335 | m_localId); | ||
4336 | 4305 | ||
4337 | PhysActor.SetMaterial(Material); | 4306 | if (pa != null) |
4338 | DoPhysicsPropertyUpdate(UsePhysics, true); | ||
4339 | |||
4340 | if (!ParentGroup.IsDeleted) | ||
4341 | { | 4307 | { |
4342 | if (LocalId == ParentGroup.RootPart.LocalId) | 4308 | pa.SetMaterial(Material); |
4309 | DoPhysicsPropertyUpdate(UsePhysics, true); | ||
4310 | |||
4311 | if (!ParentGroup.IsDeleted) | ||
4343 | { | 4312 | { |
4344 | ParentGroup.CheckSculptAndLoad(); | 4313 | if (LocalId == ParentGroup.RootPart.LocalId) |
4314 | { | ||
4315 | ParentGroup.CheckSculptAndLoad(); | ||
4316 | } | ||
4317 | } | ||
4318 | |||
4319 | if ( | ||
4320 | ((AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
4321 | ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
4322 | ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
4323 | ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
4324 | ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
4325 | ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
4326 | (CollisionSound != UUID.Zero) | ||
4327 | ) | ||
4328 | { | ||
4329 | pa.OnCollisionUpdate += PhysicsCollision; | ||
4330 | pa.SubscribeEvents(1000); | ||
4345 | } | 4331 | } |
4346 | } | ||
4347 | |||
4348 | if ( | ||
4349 | ((AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
4350 | ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
4351 | ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
4352 | ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
4353 | ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
4354 | ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
4355 | (CollisionSound != UUID.Zero) | ||
4356 | ) | ||
4357 | { | ||
4358 | PhysActor.OnCollisionUpdate += PhysicsCollision; | ||
4359 | PhysActor.SubscribeEvents(1000); | ||
4360 | } | 4332 | } |
4361 | } | 4333 | } |
4362 | else // it already has a physical representation | 4334 | else // it already has a physical representation |
@@ -4418,7 +4390,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
4418 | } | 4390 | } |
4419 | 4391 | ||
4420 | /// <summary> | 4392 | /// <summary> |
4421 | /// This removes the part from physics | 4393 | /// Adds this part to the physics scene. |
4394 | /// </summary> | ||
4395 | /// <remarks>This method also sets the PhysActor property.</remarks> | ||
4396 | /// <param name="rigidBody">Add this prim with a rigid body.</param> | ||
4397 | /// <returns> | ||
4398 | /// The physics actor. null if there was a failure. | ||
4399 | /// </returns> | ||
4400 | private PhysicsActor AddToPhysics(bool rigidBody) | ||
4401 | { | ||
4402 | PhysicsActor pa; | ||
4403 | |||
4404 | try | ||
4405 | { | ||
4406 | pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( | ||
4407 | string.Format("{0}/{1}", Name, UUID), | ||
4408 | Shape, | ||
4409 | AbsolutePosition, | ||
4410 | Scale, | ||
4411 | RotationOffset, | ||
4412 | rigidBody, | ||
4413 | m_localId); | ||
4414 | } | ||
4415 | catch | ||
4416 | { | ||
4417 | m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); | ||
4418 | pa = null; | ||
4419 | } | ||
4420 | |||
4421 | // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical | ||
4422 | // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor | ||
4423 | // being set. | ||
4424 | PhysActor = pa; | ||
4425 | |||
4426 | // Basic Physics can also return null as well as an exception catch. | ||
4427 | if (pa != null) | ||
4428 | { | ||
4429 | pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info | ||
4430 | pa.SetMaterial(Material); | ||
4431 | DoPhysicsPropertyUpdate(rigidBody, true); | ||
4432 | } | ||
4433 | |||
4434 | return pa; | ||
4435 | } | ||
4436 | |||
4437 | /// <summary> | ||
4438 | /// This removes the part from the physics scene. | ||
4422 | /// </summary> | 4439 | /// </summary> |
4423 | /// <remarks> | 4440 | /// <remarks> |
4424 | /// This isn't the same as turning off physical, since even without being physical the prim has a physics | 4441 | /// This isn't the same as turning off physical, since even without being physical the prim has a physics |