Mantis#2796. Thank you kindly, Gerhard for a patch that addresses:
On a call of llVolumeDetect(1) (or any other number !=0) volume detection is enabled. Together with VD, the phantom flag is set to the GUI. On a call of llVolumeDetect(0), vd detection is switched of again, also the phantom state is removed. On a call to llSetState(STATE_PHANTOM, false) while VD is active, also VD is switched off. The same is true for unchecking the phantom flag via GUI. This allows to take back VD without the need to script just by removing the phantom flag. Things missing in this patch: persistance of the volume-detection flag. This needs more discussion and will be included in another patch soon.0.6.2-post-fixes
parent
ad05d613a6
commit
62dd67b8b8
|
@ -1203,6 +1203,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <param name="localID"></param>
|
/// <param name="localID"></param>
|
||||||
/// <param name="packet"></param>
|
/// <param name="packet"></param>
|
||||||
/// <param name="remoteClient"></param>
|
/// <param name="remoteClient"></param>
|
||||||
|
/// This routine seems to get called when a user changes object settings in the viewer.
|
||||||
|
/// If some one can confirm that, please change the comment according.
|
||||||
protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient)
|
protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
SceneObjectGroup group = GetGroupByPrim(localID);
|
SceneObjectGroup group = GetGroupByPrim(localID);
|
||||||
|
@ -1210,7 +1212,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
|
if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
|
||||||
{
|
{
|
||||||
group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom);
|
group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom, false); // VolumeDetect can't be set via UI and will always be off when a change is made there
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1431,21 +1431,45 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
|
bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
|
||||||
bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
|
bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
|
||||||
UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom);
|
bool IsVolumeDetect = RootPart.VolumeDetectActive;
|
||||||
|
UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScriptSetTemporaryStatus(bool TemporaryStatus)
|
public void ScriptSetTemporaryStatus(bool TemporaryStatus)
|
||||||
{
|
{
|
||||||
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
||||||
bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
|
bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
|
||||||
UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom);
|
bool IsVolumeDetect = RootPart.VolumeDetectActive;
|
||||||
|
UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScriptSetPhantomStatus(bool PhantomStatus)
|
public void ScriptSetPhantomStatus(bool PhantomStatus)
|
||||||
{
|
{
|
||||||
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
||||||
bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
|
bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
|
||||||
UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus);
|
bool IsVolumeDetect = RootPart.VolumeDetectActive;
|
||||||
|
UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptSetVolumeDetect(bool VDStatus)
|
||||||
|
{
|
||||||
|
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
|
||||||
|
bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
|
||||||
|
bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
|
||||||
|
UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus);
|
||||||
|
|
||||||
|
/*
|
||||||
|
ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
|
||||||
|
|
||||||
|
if (PhysActor != null) // Should always be the case now
|
||||||
|
{
|
||||||
|
PhysActor.SetVolumeDetect(param);
|
||||||
|
}
|
||||||
|
if (param != 0)
|
||||||
|
AddFlag(PrimFlags.Phantom);
|
||||||
|
|
||||||
|
ScheduleFullUpdate();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyImpulse(PhysicsVector impulse)
|
public void applyImpulse(PhysicsVector impulse)
|
||||||
|
@ -2251,7 +2275,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="inUse"></param>
|
/// <param name="inUse"></param>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom)
|
public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect)
|
||||||
{
|
{
|
||||||
SceneObjectPart selectionPart = GetChildPart(localID);
|
SceneObjectPart selectionPart = GetChildPart(localID);
|
||||||
|
|
||||||
|
@ -2279,7 +2303,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom);
|
part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f);
|
public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f);
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public bool VolumeDetectActive = false; // XmlIgnore set to avoid problems with persistance until I come to care for this
|
||||||
|
// Certainly this must be a persistant setting finally
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This part's inventory
|
/// This part's inventory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2178,6 +2182,16 @@ if (m_shape != null) {
|
||||||
m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
|
m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ScriptSetVolumeDetect(bool SetVD)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m_parentGroup != null)
|
||||||
|
{
|
||||||
|
m_parentGroup.ScriptSetVolumeDetect(SetVD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SculptTextureCallback(UUID textureID, AssetBase texture)
|
public void SculptTextureCallback(UUID textureID, AssetBase texture)
|
||||||
{
|
{
|
||||||
if (m_shape.SculptEntry)
|
if (m_shape.SculptEntry)
|
||||||
|
@ -2484,14 +2498,6 @@ if (m_shape != null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVolumeDetect(int param)
|
|
||||||
{
|
|
||||||
if (PhysActor != null)
|
|
||||||
{
|
|
||||||
PhysActor.SetVolumeDetect(param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetGroup(UUID groupID, IClientAPI client)
|
public void SetGroup(UUID groupID, IClientAPI client)
|
||||||
{
|
{
|
||||||
_groupID = groupID;
|
_groupID = groupID;
|
||||||
|
@ -3184,17 +3190,46 @@ if (m_shape != null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom)
|
public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD)
|
||||||
{
|
{
|
||||||
bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0);
|
bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0);
|
||||||
bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0);
|
bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0);
|
||||||
bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0);
|
bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0);
|
||||||
|
bool wasVD = VolumeDetectActive;
|
||||||
|
|
||||||
if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom))
|
if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 (IsVD) // VD is active, special logic applies
|
||||||
|
{
|
||||||
|
// State machine logic for VolumeDetect
|
||||||
|
// More logic below
|
||||||
|
bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom;
|
||||||
|
|
||||||
|
if (phanReset) // Phantom changes from on to off switch VD off too
|
||||||
|
{
|
||||||
|
IsVD = 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
|
||||||
|
{
|
||||||
|
IsPhantom = false;
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (UsePhysics)
|
if (UsePhysics)
|
||||||
{
|
{
|
||||||
AddFlag(PrimFlags.Physics);
|
AddFlag(PrimFlags.Physics);
|
||||||
|
@ -3222,6 +3257,7 @@ if (m_shape != null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (IsPhantom || IsAttachment)
|
if (IsPhantom || IsAttachment)
|
||||||
{
|
{
|
||||||
AddFlag(PrimFlags.Phantom);
|
AddFlag(PrimFlags.Phantom);
|
||||||
|
@ -3232,11 +3268,13 @@ if (m_shape != null) {
|
||||||
PhysActor = null;
|
PhysActor = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // Not phantom
|
||||||
{
|
{
|
||||||
RemFlag(PrimFlags.Phantom);
|
RemFlag(PrimFlags.Phantom);
|
||||||
|
|
||||||
if (PhysActor == null)
|
if (PhysActor == null)
|
||||||
{
|
{
|
||||||
|
// It's not phantom anymore. So make sure the physics engine get's knowledge of it
|
||||||
PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
|
PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
|
||||||
Name,
|
Name,
|
||||||
Shape,
|
Shape,
|
||||||
|
@ -3261,10 +3299,11 @@ if (m_shape != null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // it already has a physical representation
|
||||||
{
|
{
|
||||||
PhysActor.IsPhysical = UsePhysics;
|
PhysActor.IsPhysical = UsePhysics;
|
||||||
DoPhysicsPropertyUpdate(UsePhysics, false);
|
|
||||||
|
DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
|
||||||
if (m_parentGroup != null)
|
if (m_parentGroup != null)
|
||||||
{
|
{
|
||||||
if (!m_parentGroup.IsDeleted)
|
if (!m_parentGroup.IsDeleted)
|
||||||
|
@ -3278,6 +3317,32 @@ if (m_shape != null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsVD)
|
||||||
|
{
|
||||||
|
// 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 (this.PhysActor != null)
|
||||||
|
{
|
||||||
|
PhysActor.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 (this.PhysActor != null)
|
||||||
|
{
|
||||||
|
PhysActor.SetVolumeDetect(0);
|
||||||
|
}
|
||||||
|
this.VolumeDetectActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (IsTemporary)
|
if (IsTemporary)
|
||||||
{
|
{
|
||||||
AddFlag(PrimFlags.TemporaryOnRez);
|
AddFlag(PrimFlags.TemporaryOnRez);
|
||||||
|
@ -3287,6 +3352,7 @@ if (m_shape != null) {
|
||||||
RemFlag(PrimFlags.TemporaryOnRez);
|
RemFlag(PrimFlags.TemporaryOnRez);
|
||||||
}
|
}
|
||||||
// System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
|
// System.Console.WriteLine("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
|
||||||
|
|
||||||
ParentGroup.HasGroupChanged = true;
|
ParentGroup.HasGroupChanged = true;
|
||||||
ScheduleFullUpdate();
|
ScheduleFullUpdate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private bool m_isphysical = false;
|
private bool m_isphysical = false;
|
||||||
private bool m_isSelected = false;
|
private bool m_isSelected = false;
|
||||||
|
|
||||||
|
internal bool m_isVolumeDetect = false; // If true, this prim only detects collisions but doesn't collide actively
|
||||||
|
|
||||||
private bool m_throttleUpdates = false;
|
private bool m_throttleUpdates = false;
|
||||||
private int throttleCounter = 0;
|
private int throttleCounter = 0;
|
||||||
public int m_interpenetrationcount = 0;
|
public int m_interpenetrationcount = 0;
|
||||||
|
@ -2226,7 +2228,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
public override void SetVolumeDetect(int param)
|
public override void SetVolumeDetect(int param)
|
||||||
{
|
{
|
||||||
|
lock (_parent_scene.OdeLock)
|
||||||
|
{
|
||||||
|
m_isVolumeDetect = (param!=0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override PhysicsVector CenterOfMass
|
public override PhysicsVector CenterOfMass
|
||||||
|
|
|
@ -797,7 +797,25 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
if (contacts[i].depth >= 0f && !checkDupe(contacts[i], p2.PhysicsActorType))
|
// Logic for collision handling
|
||||||
|
// Note, that if *all* contacts are skipped (VolumeDetect)
|
||||||
|
// The prim still detects (and forwards) collision events but
|
||||||
|
// appears to be phantom for the world
|
||||||
|
Boolean skipThisContact = false;
|
||||||
|
|
||||||
|
if (contacts[i].depth < 0f)
|
||||||
|
skipThisContact = true;
|
||||||
|
|
||||||
|
if (checkDupe(contacts[i], p2.PhysicsActorType))
|
||||||
|
skipThisContact = true;
|
||||||
|
|
||||||
|
if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect))
|
||||||
|
skipThisContact = true; // No collision on volume detect prims
|
||||||
|
|
||||||
|
if ((p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect))
|
||||||
|
skipThisContact = true; // No collision on volume detect prims
|
||||||
|
|
||||||
|
if (!skipThisContact)
|
||||||
{
|
{
|
||||||
// If we're colliding against terrain
|
// If we're colliding against terrain
|
||||||
if (name1 == "Terrain" || name2 == "Terrain")
|
if (name1 == "Terrain" || name2 == "Terrain")
|
||||||
|
|
|
@ -5736,7 +5736,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
if (!m_host.ParentGroup.IsDeleted)
|
if (!m_host.ParentGroup.IsDeleted)
|
||||||
{
|
{
|
||||||
m_host.ParentGroup.RootPart.SetVolumeDetect(detect);
|
m_host.ParentGroup.RootPart.ScriptSetVolumeDetect(detect!=0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue