diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 969ddafc2a..d4197107f9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -122,6 +122,11 @@ namespace OpenSim.Region.Framework.Scenes
/// Denote all sides of the prim
///
public const int ALL_SIDES = -1;
+
+ private const scriptEvents PhyscicsNeededSubsEvents = (
+ scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
+ scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
+ );
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -1821,18 +1826,20 @@ namespace OpenSim.Region.Framework.Scenes
///
///
///
+ ///
- public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
+ public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
{
+ VolumeDetectActive = _VolumeDetectActive; //?? as is used this is redundante
+
if (!ParentGroup.Scene.CollidablePrims)
return;
if (PhysicsShapeType == (byte)PhysShapeType.none)
return;
- bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0;
- bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0;
-
+ bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
+ bool isPhantom = (_ObjectFlags & (uint) PrimFlags.Phantom) != 0;
if (IsJoint())
{
@@ -1840,68 +1847,11 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
- // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored
-// if (VolumeDetectActive)
-// isPhantom = false;
-
- // 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))
- if ((!isPhantom || isPhysical || VolumeDetectActive) && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
- {
- Vector3 velocity = Velocity;
- Vector3 rotationalVelocity = AngularVelocity;
- try
- {
- PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
- string.Format("{0}/{1}", Name, UUID),
- Shape,
- AbsolutePosition,
- Scale,
- GetWorldRotation(),
- isPhysical,
- isPhantom,
- PhysicsShapeType,
- m_localId);
- }
- catch
- {
- m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid);
- PhysActor = null;
- }
-
- PhysicsActor pa = PhysActor;
-
- if (pa != null)
- {
- pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
- pa.SetMaterial(Material);
-
- // if root part apply vehicle
- if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
- m_vehicle.SetVehicle(pa);
-
- DoPhysicsPropertyUpdate(isPhysical, true);
- if(VolumeDetectActive) // change if not the default only
- pa.SetVolumeDetect(1);
-
- if (!building)
- pa.Building = false;
-
- Velocity = velocity;
- AngularVelocity = rotationalVelocity;
- pa.Velocity = velocity;
- pa.RotationalVelocity = rotationalVelocity;
-
- // if not vehicle and root part apply force and torque
- if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
- && LocalId == ParentGroup.RootPart.LocalId)
- {
- pa.Force = Force;
- pa.Torque = Torque;
- }
- }
- }
+ if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
+ && !(Shape.PathCurve == (byte)Extrusion.Flexible))
+ AddToPhysics(isPhysical, isPhantom, building, true);
+ else
+ PhysActor = null; // just to be sure
}
}
@@ -4628,7 +4578,6 @@ namespace OpenSim.Region.Framework.Scenes
///
///
///
-// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
{
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
@@ -4639,209 +4588,92 @@ namespace OpenSim.Region.Framework.Scenes
if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
return;
- // do this first
- if (building && PhysActor != null && PhysActor.Building != building)
- PhysActor.Building = building;
-
- // 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...
- // ... if VD is changed, all others are not.
- // ... if one of the others is changed, VD is not.
-
-/*
- if (SetVD) // VD is active, special logic applies
-
- volume detection is now independent of phantom in sl
-
- {
- // State machine logic for VolumeDetect
- // More logic below
-
-
- bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
-
- if (phanReset) // Phantom changes from on to off switch VD off too
- {
- 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
- }
- else
- {
- // If volumedetect is active we don't want phantom to be applied.
- // If this is a new call to VD out of the state "phantom"
- // this will also cause the prim to be visible to physics
- SetPhantom = false;
- }
- }
- else if (wasVD)
- {
- // Correspondingly, if VD is turned off, also turn off phantom
- SetPhantom = false;
- }
-
- if (UsePhysics && IsJoint())
- {
- SetPhantom = true;
- }
-*/
if (UsePhysics)
- {
AddFlag(PrimFlags.Physics);
-/*
- if (!wasUsingPhysics)
- {
- DoPhysicsPropertyUpdate(UsePhysics, false);
-
- if (!ParentGroup.IsDeleted)
- {
- if (LocalId == ParentGroup.RootPart.LocalId)
- {
- ParentGroup.CheckSculptAndLoad();
- }
- }
- }
- */
- }
else
- {
RemFlag(PrimFlags.Physics);
-/*
- if (wasUsingPhysics)
- {
- DoPhysicsPropertyUpdate(UsePhysics, false);
- }
-*/
- }
if (SetPhantom)
AddFlag(PrimFlags.Phantom);
else
RemFlag(PrimFlags.Phantom);
+ if (SetTemporary)
+ AddFlag(PrimFlags.TemporaryOnRez);
+ else
+ RemFlag(PrimFlags.TemporaryOnRez);
+
+ VolumeDetectActive = SetVD;
+
+ if (ParentGroup.Scene == null)
+ return;
+
+ PhysicsActor pa = PhysActor;
+
+ if (pa != null && building && pa.Building != building)
+ pa.Building = building;
+
if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
- || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
+ || (Shape.PathCurve == (byte)Extrusion.Flexible))
{
-// AddFlag(PrimFlags.Phantom);
+ if (pa != null)
+ {
+ ParentGroup.Scene.RemovePhysicalPrim(1);
+ RemoveFromPhysics();
+ }
Velocity = new Vector3(0, 0, 0);
Acceleration = new Vector3(0, 0, 0);
if (ParentGroup.RootPart == this)
AngularVelocity = new Vector3(0, 0, 0);
-
- if (PhysActor != null)
- {
- ParentGroup.Scene.RemovePhysicalPrim(1);
- RemoveFromPhysics();
- }
}
else
{
- if (ParentGroup.Scene == null)
- return;
-
if (ParentGroup.Scene.CollidablePrims)
{
- if (PhysActor == null)
+ if (pa == null)
{
- PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
- string.Format("{0}/{1}", Name, UUID),
- Shape,
- AbsolutePosition,
- Scale,
- GetWorldRotation(), //physics wants world rotation like all other functions send
- UsePhysics,
- SetPhantom,
- PhysicsShapeType,
- m_localId);
+ AddToPhysics(UsePhysics, SetPhantom, building , false);
+ pa = PhysActor;
- PhysActor.SetMaterial(Material);
-
- // if root part apply vehicle
- if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
- m_vehicle.SetVehicle(PhysActor);
-
- DoPhysicsPropertyUpdate(UsePhysics, true);
-
- if (!ParentGroup.IsDeleted)
+ if (pa != null)
{
- if (LocalId == ParentGroup.RootPart.LocalId)
+ 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) ||
+ ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
+// (CollisionSound != UUID.Zero)
+ )
{
- ParentGroup.CheckSculptAndLoad();
+ 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
{
DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
- if (!ParentGroup.IsDeleted)
- {
- if (LocalId == ParentGroup.RootPart.LocalId)
- {
- ParentGroup.CheckSculptAndLoad();
- }
- }
+ if(VolumeDetectActive)
+ pa.SetVolumeDetect(1);
+ else
+ pa.SetVolumeDetect(0);
+
+ if (pa.Building != building)
+ pa.Building = building;
}
}
- }
-
- PhysicsActor pa = PhysActor;
- if (SetVD)
- {
- // If the above logic worked (this is urgent candidate to unit tests!)
- // we now have a physicsactor.
- // 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 (pa != null)
- {
- pa.SetVolumeDetect(1);
-// AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
- this.VolumeDetectActive = true;
- }
- }
- else
- {
- // 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 :-))
- if (pa != null)
- {
- pa.SetVolumeDetect(0);
- this.VolumeDetectActive = false;
- }
- }
-
- if (SetTemporary)
- {
- AddFlag(PrimFlags.TemporaryOnRez);
- }
- else
- {
- RemFlag(PrimFlags.TemporaryOnRez);
- }
+ }
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
// and last in case we have a new actor and not building
- if (pa != null && pa.Building != building)
- pa.Building = building;
+
if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true;
@@ -4853,48 +4685,104 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Adds this part to the physics scene.
+ /// and sets the PhysActor property
///
- /// 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)
- {
+ /// Add this prim as physical.
+ /// Add this prim as phantom.
+ /// tells physics to delay full construction of object
+ /// applies velocities, force and torque
+ private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
+ {
PhysicsActor pa;
+ Vector3 velocity = Velocity;
+ Vector3 rotationalVelocity = AngularVelocity;;
+
try
{
pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
- string.Format("{0}/{1}", Name, UUID),
- Shape,
- AbsolutePosition,
- Scale,
- RotationOffset,
- rigidBody,
- m_localId);
+ string.Format("{0}/{1}", Name, UUID),
+ Shape,
+ AbsolutePosition,
+ Scale,
+ GetWorldRotation(),
+ isPhysical,
+ isPhantom,
+ PhysicsShapeType,
+ m_localId);
}
- catch
+ catch (Exception ex)
{
- m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid);
+ m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message);
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);
+
+ if (VolumeDetectActive) // change if not the default only
+ pa.SetVolumeDetect(1);
+
+ if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
+ m_vehicle.SetVehicle(pa);
+
+ // we are going to tell rest of code about physics so better have this here
+ PhysActor = pa;
+
+ // DoPhysicsPropertyUpdate(isPhysical, true);
+ // lets expand it here just with what it really needs to do
+
+ if (isPhysical)
+ {
+ if (ParentGroup.RootPart.KeyframeMotion != null)
+ ParentGroup.RootPart.KeyframeMotion.Stop();
+ ParentGroup.RootPart.KeyframeMotion = null;
+ ParentGroup.Scene.AddPhysicalPrim(1);
+
+ pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
+ pa.OnOutOfBounds += PhysicsOutOfBounds;
+
+ if (ParentID != 0 && ParentID != LocalId)
+ {
+ PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
+
+ if (parentPa != null)
+ {
+ pa.link(parentPa);
+ }
+ }
+ }
+
+ if (applyDynamics)
+ // do independent of isphysical so parameters get setted (at least some)
+ {
+ Velocity = velocity;
+ AngularVelocity = rotationalVelocity;
+ pa.Velocity = velocity;
+ pa.RotationalVelocity = rotationalVelocity;
+
+ // if not vehicle and root part apply force and torque
+ if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
+ && LocalId == ParentGroup.RootPart.LocalId)
+ {
+ pa.Force = Force;
+ pa.Torque = Torque;
+ }
+ }
+
+ if (Shape.SculptEntry)
+ CheckSculptAndLoad();
+ else
+ ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
+
+ if (!building)
+ pa.Building = false;
}
- return pa;
- }
+ PhysActor = pa;
+ }
///
/// This removes the part from the physics scene.
@@ -5103,10 +4991,6 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor pa = PhysActor;
if (pa != null)
{
- const scriptEvents NeededSubsEvents = (
- scriptEvents.collision | scriptEvents.collision_start| scriptEvents.collision_end |
- scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
- );
if (
// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -5114,7 +4998,7 @@ namespace OpenSim.Region.Framework.Scenes
// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
- ((AggregateScriptEvents & NeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
+ ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
)
{
// subscribe to physics updates.