Physical phantoms testable with chOde. Volume detection was changed and also needs testing. Started making it more independent of phantom acording to new sl. ** 99.999...% UNTESTED ***

avinationmerge
UbitUmarov 2012-03-11 11:01:38 +00:00
parent dab7e03584
commit 7832889437
1 changed files with 159 additions and 152 deletions

View File

@ -1577,16 +1577,12 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
/// <param name="rootObjectFlags"></param> /// <param name="rootObjectFlags"></param>
/// <param name="VolumeDetectActive"></param> /// <param name="VolumeDetectActive"></param>
// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building) public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
{ {
if (!ParentGroup.Scene.CollidablePrims) if (!ParentGroup.Scene.CollidablePrims)
return; return;
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}",
// Name, LocalId, UUID, m_physicalPrim);
bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0;
bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0;
@ -1597,15 +1593,16 @@ namespace OpenSim.Region.Framework.Scenes
else else
{ {
// Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored
if (VolumeDetectActive) // if (VolumeDetectActive)
isPhantom = false; // isPhantom = false;
// Added clarification.. since A rigid body is an object that you can kick around, etc. // Added clarification.. since A rigid body is an object that you can kick around, etc.
bool RigidBody = isPhysical && !isPhantom; // 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 // 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 // or flexible
if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.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 velocity = Velocity;
Vector3 rotationalVelocity = AngularVelocity; Vector3 rotationalVelocity = AngularVelocity;
@ -1616,9 +1613,9 @@ namespace OpenSim.Region.Framework.Scenes
Shape, Shape,
AbsolutePosition, AbsolutePosition,
Scale, Scale,
// RotationOffset, GetWorldRotation(),
GetWorldRotation(), // physics wants world rotation isPhysical,
RigidBody, isPhantom,
m_localId); m_localId);
} }
catch catch
@ -1637,8 +1634,9 @@ namespace OpenSim.Region.Framework.Scenes
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId) if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
m_vehicle.SetVehicle(PhysActor); m_vehicle.SetVehicle(PhysActor);
DoPhysicsPropertyUpdate(RigidBody, true); DoPhysicsPropertyUpdate(isPhysical, true);
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); if(VolumeDetectActive) // change if not the default only
PhysActor.SetVolumeDetect(1);
if (!building) if (!building)
PhysActor.Building = false; PhysActor.Building = false;
@ -1888,73 +1886,62 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (UsePhysics != PhysActor.IsPhysical || isNew) if (UsePhysics != PhysActor.IsPhysical || isNew)
{ {
if (PhysActor.IsPhysical) // implies UsePhysics==false for this block if (PhysActor.IsPhysical)
{ {
if (!isNew) if (!isNew) // implies UsePhysics==false for this block
{
ParentGroup.Scene.RemovePhysicalPrim(1); ParentGroup.Scene.RemovePhysicalPrim(1);
Velocity = new Vector3(0, 0, 0); Velocity = new Vector3(0, 0, 0);
Acceleration = new Vector3(0, 0, 0); Acceleration = new Vector3(0, 0, 0);
if (ParentGroup.RootPart == this) if (ParentGroup.RootPart == this)
AngularVelocity = new Vector3(0, 0, 0); AngularVelocity = new Vector3(0, 0, 0);
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; if (PhysActor.Phantom)
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
PhysActor.delink();
if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew))
{
// destroy all joints connected to this now deactivated body
ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor);
}
// stop client-side interpolation of all joint proxy objects that have just been deleted
// this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback,
// which stops client-side interpolation of deactivated joint proxy objects.
}
if (!UsePhysics && !isNew)
{
// reset velocity to 0 on physics switch-off. Without that, the client thinks the
// prim still has velocity and continues to interpolate its position along the old
// velocity-vector.
Velocity = new Vector3(0, 0, 0);
Acceleration = new Vector3(0, 0, 0);
if (ParentGroup.RootPart == this)
AngularVelocity = new Vector3(0, 0, 0);
//RotationalVelocity = new Vector3(0, 0, 0);
}
PhysActor.IsPhysical = UsePhysics;
// If we're not what we're supposed to be in the physics scene, recreate ourselves.
//m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
/// that's not wholesome. Had to make Scene public
//PhysActor = null;
if ((Flags & PrimFlags.Phantom) == 0)
{
if (UsePhysics)
{
if (ParentGroup.RootPart.KeyframeMotion != null)
ParentGroup.RootPart.KeyframeMotion.Stop();
ParentGroup.RootPart.KeyframeMotion = null;
ParentGroup.Scene.AddPhysicalPrim(1);
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
if (ParentID != 0 && ParentID != LocalId)
{ {
if (ParentGroup.RootPart.PhysActor != null) RemoveFromPhysics();
{ return;
PhysActor.link(ParentGroup.RootPart.PhysActor); }
}
PhysActor.IsPhysical = UsePhysics;
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
PhysActor.delink();
if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
{
// destroy all joints connected to this now deactivated body
ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor);
}
}
}
if (PhysActor.IsPhysical != UsePhysics)
PhysActor.IsPhysical = UsePhysics;
if (UsePhysics)
{
if (ParentGroup.RootPart.KeyframeMotion != null)
ParentGroup.RootPart.KeyframeMotion.Stop();
ParentGroup.RootPart.KeyframeMotion = null;
ParentGroup.Scene.AddPhysicalPrim(1);
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
if (ParentID != 0 && ParentID != LocalId)
{
if (ParentGroup.RootPart.PhysActor != null)
{
PhysActor.link(ParentGroup.RootPart.PhysActor);
} }
} }
} }
} }
bool phan = ((Flags & PrimFlags.Phantom) != 0);
if (PhysActor.Phantom != phan)
PhysActor.Phantom = phan;
// If this part is a sculpt then delay the physics update until we've asynchronously loaded the // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
// mesh data. // mesh data.
if (Shape.SculptEntry) if (Shape.SculptEntry)
@ -4355,40 +4342,45 @@ namespace OpenSim.Region.Framework.Scenes
bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
bool wasVD = VolumeDetectActive; bool wasVD = VolumeDetectActive;
// m_log.DebugFormat("[SOP]: Old states: phys: {0} temp: {1} phan: {2} vd: {3}", wasUsingPhysics, wasTemporary, wasPhantom, wasVD);
// m_log.DebugFormat("[SOP]: New states: phys: {0} temp: {1} phan: {2} vd: {3}", UsePhysics, SetTemporary, SetPhantom, SetVD);
if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
return; 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 // 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 // and can't be combined with changes to other states. So we can rely
// that... // that...
// ... if VD is changed, all others are not. // ... if VD is changed, all others are not.
// ... if one of the others is changed, VD is not. // ... if one of the others is changed, VD is not.
// do this first
if (building && PhysActor != null && PhysActor.Building != building)
PhysActor.Building = building;
if (SetVD) // VD is active, special logic applies
{
// 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 if (SetVD) // VD is active, special logic applies
{
SetVD = false; // Switch it of for the course of this routine /* volume detection is now independent of phantom in sl
VolumeDetectActive = false; // and also permanently
if (PhysActor != null) {
PhysActor.SetVolumeDetect(0); // Let physics know about it too // State machine logic for VolumeDetect
} // More logic below
else
{
// If volumedetect is active we don't want phantom to be applied. bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
// If this is a new call to VD out of the state "phantom"
// this will also cause the prim to be visible to physics 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; SetPhantom = false;
} /* }
} }
else if (wasVD) else if (wasVD)
{ {
@ -4400,10 +4392,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
SetPhantom = true; SetPhantom = true;
} }
*/
if (UsePhysics) if (UsePhysics)
{ {
AddFlag(PrimFlags.Physics); AddFlag(PrimFlags.Physics);
/*
if (!wasUsingPhysics) if (!wasUsingPhysics)
{ {
DoPhysicsPropertyUpdate(UsePhysics, false); DoPhysicsPropertyUpdate(UsePhysics, false);
@ -4416,84 +4409,99 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
*/
} }
else else
{ {
RemFlag(PrimFlags.Physics); RemFlag(PrimFlags.Physics);
/*
if (wasUsingPhysics) if (wasUsingPhysics)
{ {
DoPhysicsPropertyUpdate(UsePhysics, false); DoPhysicsPropertyUpdate(UsePhysics, false);
} }
*/
} }
if (SetPhantom if (SetPhantom)
|| ParentGroup.IsAttachment AddFlag(PrimFlags.Phantom);
else
RemFlag(PrimFlags.Phantom);
if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment
|| (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
{ {
AddFlag(PrimFlags.Phantom); AddFlag(PrimFlags.Phantom);
if (PhysActor != null) Velocity = new Vector3(0, 0, 0);
RemoveFromPhysics(); Acceleration = new Vector3(0, 0, 0);
} if (ParentGroup.RootPart == this)
else // Not phantom AngularVelocity = new Vector3(0, 0, 0);
{
RemFlag(PrimFlags.Phantom);
if (PhysActor != null)
{
ParentGroup.Scene.RemovePhysicalPrim(1);
RemoveFromPhysics();
}
}
else
{
if (ParentGroup.Scene == null) if (ParentGroup.Scene == null)
return; return;
if (ParentGroup.Scene.CollidablePrims && PhysActor == null) if (ParentGroup.Scene.CollidablePrims)
{ {
// It's not phantom anymore. So make sure the physics engine get's knowledge of it if (PhysActor == null)
PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
string.Format("{0}/{1}", Name, UUID),
Shape,
AbsolutePosition,
Scale,
// RotationOffset,
GetWorldRotation(), //physics wants world rotation like all other functions send
UsePhysics,
m_localId);
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 (LocalId == ParentGroup.RootPart.LocalId) 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,
m_localId);
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)
{ {
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)
)
{
PhysActor.OnCollisionUpdate += PhysicsCollision;
PhysActor.SubscribeEvents(1000);
} }
} }
else // it already has a physical representation
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; DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
PhysActor.SubscribeEvents(1000);
}
}
else // it already has a physical representation
{
DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
if (!ParentGroup.IsDeleted) if (!ParentGroup.IsDeleted)
{
if (LocalId == ParentGroup.RootPart.LocalId)
{ {
ParentGroup.CheckSculptAndLoad(); if (LocalId == ParentGroup.RootPart.LocalId)
{
ParentGroup.CheckSculptAndLoad();
}
} }
} }
} }
@ -4509,7 +4517,7 @@ namespace OpenSim.Region.Framework.Scenes
if (this.PhysActor != null) if (this.PhysActor != null)
{ {
PhysActor.SetVolumeDetect(1); PhysActor.SetVolumeDetect(1);
AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active // AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
this.VolumeDetectActive = true; this.VolumeDetectActive = true;
} }
} }
@ -4517,8 +4525,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
// Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // 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 :-)) // (mumbles, well, at least if you have infinte CPU powers :-))
PhysicsActor pa = this.PhysActor; if (this.PhysActor != null)
if (pa != null)
{ {
PhysActor.SetVolumeDetect(0); PhysActor.SetVolumeDetect(0);
} }