When Flags is updated on a prim, call UpdatePrimFlagsBySync to trigger appropriate

actions when flags are changed.
dsg
Huaiyu (Kitty) Liu 2011-05-26 12:17:17 -07:00
parent d79a37e0ca
commit 486497331c
3 changed files with 286 additions and 9 deletions

View File

@ -1110,6 +1110,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
debugMsg += ", Text = " + part.Text+", Color = "+part.Color.ToString();
}
debugMsg += ", AggregateScriptEvents = " + part.AggregateScriptEvents;
ScenePresence sp = m_scene.GetScenePresence(part.AttachedAvatar);
if (sp != null)
@ -1549,12 +1550,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
List<SceneObjectPartSyncProperties> propertiesUpdated = m_primSyncInfoManager.UpdatePrimSyncInfoBySync(sop, propertiesSyncInfo);
//SYNC DEBUG
/*
if (propertiesUpdated.Contains(SceneObjectPartSyncProperties.AggregateScriptEvents))
{
//m_log.DebugFormat("AggregateScriptEvents updated: " + sop.AggregateScriptEvents);
m_log.DebugFormat("AggregateScriptEvents updated: " + sop.AggregateScriptEvents);
}
/*
if (propertiesUpdated.Contains(SceneObjectPartSyncProperties.Shape))
{
String hashedShape = Util.Md5Hash((PropertySerializer.SerializeShape(sop)));
@ -2568,11 +2569,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//m_log.DebugFormat("{0}: SendPrimPropertyUpdates for {1}, {2}, with updated properties -- {3}", LogHeader, sop.Name, sop.UUID, pString);
//DSG DEBUG
/*
if (updatedProperties.Contains(SceneObjectPartSyncProperties.GroupPosition))
if (updatedProperties.Contains(SceneObjectPartSyncProperties.AggregateScriptEvents))
{
m_log.DebugFormat("SendPrimPropertyUpdates -- prim {0}: GroupPosition: {1} ", sop.Name, sop.GroupPosition);
m_log.DebugFormat("SendPrimPropertyUpdates -- prim {0}: AggregateScriptEvents: {1} ", sop.Name, sop.AggregateScriptEvents);
}
/*
if (updatedProperties.Contains(SceneObjectPartSyncProperties.Position))
{
m_log.DebugFormat("SendPrimPropertyUpdates -- prim {0}: Position: {1} ", sop.Name, sop.PhysActor.Position);
@ -3123,6 +3125,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
case SceneObjectPartSyncProperties.AllowedDrop:
case SceneObjectPartSyncProperties.IsAttachment:
case SceneObjectPartSyncProperties.PassTouches:
case SceneObjectPartSyncProperties.VolumeDetectActive:
propertyData["Value"] = OSD.FromBoolean((bool)LastUpdateValue);
break;
@ -3350,6 +3353,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
case SceneObjectPartSyncProperties.AllowedDrop:
case SceneObjectPartSyncProperties.IsAttachment:
case SceneObjectPartSyncProperties.PassTouches:
case SceneObjectPartSyncProperties.VolumeDetectActive:
m_lastUpdateValue = (Object)(propertyData["Value"].AsBoolean());
//propertyData["Value"] = OSD.FromBoolean((bool)LastUpdateValue);
break;
@ -4183,7 +4187,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
propertyUpdatedByLocal = true;
//TEMP DEBUG
//DebugLog.DebugFormat("CompareValue_UpdateByLocal -- copy SOP's AggregateScriptEvents {0}", part.AggregateScriptEvents);
DebugLog.DebugFormat("CompareValue_UpdateByLocal -- copy SOP's AggregateScriptEvents {0}", part.AggregateScriptEvents);
}
else if (lastUpdateByLocalTS < m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
@ -4985,6 +4989,21 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
break;
case SceneObjectPartSyncProperties.VolumeDetectActive:
if (!part.VolumeDetectActive.Equals(m_propertiesSyncInfo[property].LastUpdateValue))
{
if (lastUpdateByLocalTS > m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
m_propertiesSyncInfo[property].UpdateSyncInfoByLocal(lastUpdateByLocalTS, syncID, (Object)part.VolumeDetectActive);
propertyUpdatedByLocal = true;
}
else if (lastUpdateByLocalTS < m_propertiesSyncInfo[property].LastUpdateTimeStamp)
{
//overwrite SOP's data
part.VolumeDetectActive = (bool)m_propertiesSyncInfo[property].LastUpdateValue;
}
}
break;
///////////////////////
//PhysActor properties
@ -5337,6 +5356,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return (Object)part.UpdateFlag;
case SceneObjectPartSyncProperties.Velocity:
return (Object)part.Velocity;
case SceneObjectPartSyncProperties.VolumeDetectActive:
return (Object)part.VolumeDetectActive;
///////////////////////
//PhysActor properties
@ -5458,7 +5479,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
case SceneObjectPartSyncProperties.AggregateScriptEvents:
part.AggregateScriptEvents = (scriptEvents)pSyncInfo.LastUpdateValue;
part.aggregateScriptEventSubscriptions();
//DebugLog.DebugFormat("set {0} value to be {1}", property.ToString(), part.AggregateScriptEvents);
DebugLog.DebugFormat("set {0} value to be {1}", property.ToString(), part.AggregateScriptEvents);
break;
case SceneObjectPartSyncProperties.AllowedDrop:
@ -5548,7 +5569,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
part.EveryoneMask = (uint)pSyncInfo.LastUpdateValue;
break;
case SceneObjectPartSyncProperties.Flags:
part.Flags = (PrimFlags)pSyncInfo.LastUpdateValue;
//part.Flags = (PrimFlags)pSyncInfo.LastUpdateValue;
SetSOPFlags(part, (PrimFlags)pSyncInfo.LastUpdateValue);
break;
case SceneObjectPartSyncProperties.FolderID:
part.FolderID = (UUID)pSyncInfo.LastUpdateValue;
@ -5665,6 +5687,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
case SceneObjectPartSyncProperties.Velocity:
part.Velocity = (Vector3)pSyncInfo.LastUpdateValue;
break;
case SceneObjectPartSyncProperties.VolumeDetectActive:
part.VolumeDetectActive = (bool)pSyncInfo.LastUpdateValue;
part.aggregateScriptEventSubscriptions();
break;
///////////////////////
//PhysActor properties
@ -5745,6 +5771,26 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
private void SetSOPFlags(SceneObjectPart part, PrimFlags flags)
{
//Do not set part.Flags yet,
//part.Flags = flags;
bool UsePhysics = (flags & PrimFlags.Physics) != 0;
bool IsTemporary = (flags & PrimFlags.TemporaryOnRez) != 0;
//bool IsVolumeDetect = part.VolumeDetectActive;
bool IsPhantom = (flags & PrimFlags.Phantom) != 0;
if (part.ParentGroup != null)
{
part.ParentGroup.UpdatePrimFlagsBySync(part.LocalId, UsePhysics, IsTemporary, IsPhantom, part.VolumeDetectActive);
//part.UpdatePrimFlagsBySync(UsePhysics, IsTemporary, IsPhantom, part.VolumeDetectActive);
}
part.Flags = flags;
part.aggregateScriptEventSubscriptions();
part.ScheduleFullUpdate(null);
}
//In SOP's implementation, GroupPosition and SOP.PhysActor.Position are
//correlated. We need to make sure that they are both properly synced.
private bool CompareAndUpdateSOPGroupPosition(SceneObjectPart part, long lastUpdateByLocalTS, string syncID)

View File

@ -3900,7 +3900,38 @@ namespace OpenSim.Region.Framework.Scenes
}
public void UpdatePrimFlagsBySync(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect)
{
SceneObjectPart selectionPart = GetChildPart(localID);
if (IsTemporary)
{
DetachFromBackup();
// Remove from database and parcel prim count
//
m_scene.DeleteFromStorage(UUID);
m_scene.EventManager.TriggerParcelPrimCountTainted();
}
if (selectionPart != null)
{
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
{
UsePhysics = false; // Reset physics
break;
}
}
for (int i = 0; i < parts.Length; i++)
parts[i].UpdatePrimFlagsBySync(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
}
}
///////////////////////////////////////////////////////////////////////
// Per SOP property based sync
///////////////////////////////////////////////////////////////////////

View File

@ -5026,6 +5026,7 @@ namespace OpenSim.Region.Framework.Scenes
//TODO!!!! To be handled in serialization/deserizaltion for synchronization
Sound, //This indicates any Sound related property has changed: Sound, SoundGain, SoundFlags,SoundRadius,
//Addition properties to be added here
VolumeDetectActive,
//Group properties
IsSelected,
@ -5311,6 +5312,205 @@ namespace OpenSim.Region.Framework.Scenes
}
#endregion DSG SYNC supporting functions
//Similar to UpdatePrimFlags, except that it does not trigger ScheduleFullUpdate(Flags).
public void UpdatePrimFlagsBySync(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD)
{
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
bool wasVD = VolumeDetectActive;
if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD == wasVD))
{
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 && IsJoint())
{
IsPhantom = true;
}
if (UsePhysics)
{
AddFlag(PrimFlags.Physics);
if (!wasUsingPhysics)
{
DoPhysicsPropertyUpdate(UsePhysics, false);
if (m_parentGroup != null)
{
if (!m_parentGroup.IsDeleted)
{
if (LocalId == m_parentGroup.RootPart.LocalId)
{
m_parentGroup.CheckSculptAndLoad();
}
}
}
}
}
else
{
RemFlag(PrimFlags.Physics);
if (wasUsingPhysics)
{
DoPhysicsPropertyUpdate(UsePhysics, false);
}
}
if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
{
AddFlag(PrimFlags.Phantom);
if (PhysActor != null)
{
m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
/// that's not wholesome. Had to make Scene public
PhysActor = null;
}
}
else // Not phantom
{
RemFlag(PrimFlags.Phantom);
PhysicsActor pa = PhysActor;
if (pa == null)
{
//DSG DEBUG
m_log.DebugFormat("Creating PhysActor for SOP {0}, {1}, so far Flags = ", Name, UUID, Flags.ToString());
// It's not phantom anymore. So make sure the physics engine get's knowledge of it
PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
LocalId,
string.Format("{0}/{1}", Name, UUID),
Shape,
AbsolutePosition,
Scale,
RotationOffset,
UsePhysics);
pa = PhysActor;
if (pa != null)
{
pa.LocalID = LocalId;
pa.UUID = this.UUID;
DoPhysicsPropertyUpdate(UsePhysics, true);
if (m_parentGroup != null)
{
if (!m_parentGroup.IsDeleted)
{
if (LocalId == m_parentGroup.RootPart.LocalId)
{
m_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
{
pa.IsPhysical = UsePhysics;
DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
if (m_parentGroup != null)
{
if (!m_parentGroup.IsDeleted)
{
if (LocalId == m_parentGroup.RootPart.LocalId)
{
m_parentGroup.CheckSculptAndLoad();
}
}
}
}
}
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 :-))
PhysicsActor pa = this.PhysActor;
if (pa != null)
{
PhysActor.SetVolumeDetect(0);
}
this.VolumeDetectActive = false;
}
if (IsTemporary)
{
AddFlag(PrimFlags.TemporaryOnRez);
}
else
{
RemFlag(PrimFlags.TemporaryOnRez);
}
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
ParentGroup.HasGroupChanged = true;
//ScheduleFullUpdate();
m_log.DebugFormat("End of UpdatePrimFlagsBySync for SOP {0}, {1}, so far Flags = ", Name, UUID, Flags.ToString());
//caller will trigger this, See SetSOPFlags()
//ScheduleFullUpdate(null);
}
}
//end of DSG SYNC