mirror of
https://github.com/opensim/opensim.git
synced 2026-08-10 03:06:05 +08:00
merge
This commit is contained in:
@@ -44,14 +44,13 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name='isReuseable'></param>
|
||||
void ReturnData(UUID id, IDynamicTexture texture);
|
||||
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams);
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||
int updateTimer);
|
||||
bool SetBlending, byte AlphaValue);
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||
int updateTimer, bool SetBlending, byte AlphaValue);
|
||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||
int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
int updateTimer);
|
||||
bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams);
|
||||
|
||||
/// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the
|
||||
/// asset service.
|
||||
@@ -62,8 +61,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// based texture or "image" to create a texture from an image at a particular URL</param>
|
||||
/// <param name="data">The data for the generator</param>
|
||||
/// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param>
|
||||
/// <param name="updateTimer">If zero, the image is never updated after the first generation. If positive
|
||||
/// the image is updated at the given interval. Not implemented for </param>
|
||||
/// <param name="SetBlending">
|
||||
/// If true, the newly generated texture is blended with the appropriate existing ones on the prim
|
||||
/// </param>
|
||||
@@ -76,7 +73,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
|
||||
/// </returns>
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
int updateTimer, bool SetBlending, byte AlphaValue);
|
||||
bool SetBlending, byte AlphaValue);
|
||||
|
||||
/// <summary>
|
||||
/// Apply a dynamically generated texture to the given prim.
|
||||
@@ -87,8 +84,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// based texture or "image" to create a texture from an image at a particular URL</param>
|
||||
/// <param name="data">The data for the generator</param>
|
||||
/// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param>
|
||||
/// <param name="updateTimer">If zero, the image is never updated after the first generation. If positive
|
||||
/// the image is updated at the given interval. Not implemented for </param>
|
||||
/// <param name="SetBlending">
|
||||
/// If true, the newly generated texture is blended with the appropriate existing ones on the prim
|
||||
/// </param>
|
||||
@@ -109,9 +104,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture
|
||||
/// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
|
||||
/// </returns>
|
||||
UUID AddDynamicTextureData(
|
||||
UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
|
||||
bool SetBlending, int disp, byte AlphaValue, int face);
|
||||
|
||||
void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
|
||||
out double xSize, out double ySize);
|
||||
|
||||
@@ -116,16 +116,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public static void PartCollisionSound(SceneObjectPart part, List<CollisionForSoundInfo> collidersinfolist)
|
||||
{
|
||||
if (part.CollisionSoundType < 0)
|
||||
return;
|
||||
|
||||
if (collidersinfolist.Count == 0 || part == null)
|
||||
return;
|
||||
|
||||
if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0)
|
||||
return;
|
||||
|
||||
if (part.ParentGroup == null)
|
||||
SceneObjectGroup sog = part.ParentGroup;
|
||||
if (sog == null || sog.IsDeleted || sog.inTransit)
|
||||
return;
|
||||
|
||||
if (part.CollisionSoundType < 0)
|
||||
if(sog.CollisionSoundThrottled(part.CollisionSoundType))
|
||||
return;
|
||||
|
||||
float volume = part.CollisionSoundVolume;
|
||||
@@ -189,15 +193,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
continue;
|
||||
}
|
||||
|
||||
SceneObjectPart otherPart = part.ParentGroup.Scene.GetSceneObjectPart(id);
|
||||
SceneObjectPart otherPart = sog.Scene.GetSceneObjectPart(id);
|
||||
if (otherPart != null)
|
||||
{
|
||||
if (otherPart.CollisionSoundType < 0 || otherPart.VolumeDetectActive)
|
||||
SceneObjectGroup othersog = otherPart.ParentGroup;
|
||||
if(othersog == null || othersog.IsDeleted || othersog.inTransit)
|
||||
continue;
|
||||
|
||||
int otherType = otherPart.CollisionSoundType;
|
||||
if (otherType < 0 || otherPart.VolumeDetectActive)
|
||||
continue;
|
||||
|
||||
if (!HaveSound)
|
||||
{
|
||||
if (otherPart.CollisionSoundType == 1)
|
||||
if(othersog.CollisionSoundThrottled(otherType))
|
||||
continue;
|
||||
|
||||
if (otherType == 1)
|
||||
{
|
||||
soundID = otherPart.CollisionSound;
|
||||
volume = otherPart.CollisionSoundVolume;
|
||||
@@ -206,7 +218,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
if (otherPart.CollisionSoundType == 2)
|
||||
if (otherType == 2)
|
||||
{
|
||||
volume = otherPart.CollisionSoundVolume;
|
||||
if (volume == 0.0f)
|
||||
|
||||
@@ -855,7 +855,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <see cref="Scene.DeleteSceneObject"/>,
|
||||
/// <see cref="Scene.SelectPrim"/>,
|
||||
/// <see cref="Scene.DeselectPrim"/>,
|
||||
/// <see cref="SceneObjectGroup.UpdatePrimFlags"/>,
|
||||
/// <see cref="SceneObjectGroup.UpdateFlags"/>,
|
||||
/// <see cref="SceneObjectGroup.AbsolutePosition"/>
|
||||
/// </remarks>
|
||||
public event ParcelPrimCountTainted OnParcelPrimCountTainted;
|
||||
|
||||
@@ -295,6 +295,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
lock (m_frames)
|
||||
{
|
||||
KeyframeTimer.Add(this);
|
||||
m_lasttickMS = Util.GetTimeStampMS();
|
||||
m_timerStopped = false;
|
||||
}
|
||||
}
|
||||
@@ -326,8 +327,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
newMotion.m_selected = true;
|
||||
}
|
||||
|
||||
newMotion.m_timerStopped = false;
|
||||
newMotion.m_running = true;
|
||||
// newMotion.m_timerStopped = false;
|
||||
// newMotion.m_running = true;
|
||||
newMotion.m_isCrossing = false;
|
||||
newMotion.m_waitingCrossing = false;
|
||||
}
|
||||
@@ -483,9 +484,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_frames.Clear();
|
||||
m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
@@ -496,8 +498,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
|
||||
}
|
||||
|
||||
public void Suspend()
|
||||
@@ -644,15 +647,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_frames.Clear();
|
||||
}
|
||||
|
||||
Vector3 m_lastPosUpdate;
|
||||
Quaternion m_lastRotationUpdate;
|
||||
Vector3 m_currentVel;
|
||||
int m_skippedUpdates;
|
||||
[NonSerialized()] Vector3 m_lastPosUpdate;
|
||||
[NonSerialized()] Quaternion m_lastRotationUpdate;
|
||||
[NonSerialized()] Vector3 m_currentVel;
|
||||
[NonSerialized()] int m_skippedUpdates;
|
||||
[NonSerialized()] double m_lasttickMS;
|
||||
|
||||
private void DoOnTimer(double tickDuration)
|
||||
{
|
||||
@@ -673,7 +677,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -696,6 +701,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return;
|
||||
}
|
||||
|
||||
double nowMS = Util.GetTimeStampMS();
|
||||
|
||||
if (m_frames.Count == 0)
|
||||
{
|
||||
lock (m_frames)
|
||||
@@ -716,10 +723,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_currentVel /= (m_currentFrame.TimeMS * 0.001f);
|
||||
|
||||
m_currentFrame.TimeMS += (int)tickDuration;
|
||||
m_lasttickMS = nowMS - 50f;
|
||||
update = true;
|
||||
}
|
||||
|
||||
m_currentFrame.TimeMS -= (int)tickDuration;
|
||||
int elapsed = (int)(nowMS - m_lasttickMS);
|
||||
if( elapsed > 3 * tickDuration)
|
||||
elapsed = (int)tickDuration;
|
||||
|
||||
m_currentFrame.TimeMS -= elapsed;
|
||||
m_lasttickMS = nowMS;
|
||||
|
||||
// Do the frame processing
|
||||
double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration;
|
||||
@@ -752,7 +765,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
bool lastSteps = remainingSteps < 4;
|
||||
// bool lastSteps = remainingSteps < 4;
|
||||
|
||||
Vector3 currentPosition = m_group.AbsolutePosition;
|
||||
Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition;
|
||||
motionThisFrame /= (float)remainingSteps;
|
||||
@@ -766,20 +780,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed);
|
||||
step.Normalize();
|
||||
m_group.RootPart.RotationOffset = step;
|
||||
/*
|
||||
if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f
|
||||
|| Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f
|
||||
|| Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f)
|
||||
update = true;
|
||||
*/
|
||||
}
|
||||
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
if(lastSteps)
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
else
|
||||
// if(lastSteps)
|
||||
// m_group.RootPart.Velocity = Vector3.Zero;
|
||||
// else
|
||||
m_group.RootPart.Velocity = m_currentVel;
|
||||
|
||||
/*
|
||||
if(!update && (
|
||||
lastSteps ||
|
||||
// lastSteps ||
|
||||
m_skippedUpdates * tickDuration > 0.5 ||
|
||||
Math.Abs(m_nextPosition.X - currentPosition.X) > 5f ||
|
||||
Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f ||
|
||||
@@ -790,15 +806,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
m_skippedUpdates++;
|
||||
|
||||
}
|
||||
if(update)
|
||||
{
|
||||
m_lastPosUpdate = m_nextPosition;
|
||||
m_lastRotationUpdate = m_group.GroupRotation;
|
||||
m_skippedUpdates = 0;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
*/
|
||||
}
|
||||
// if(update)
|
||||
// {
|
||||
// m_lastPosUpdate = m_nextPosition;
|
||||
// m_lastRotationUpdate = m_group.GroupRotation;
|
||||
// m_skippedUpdates = 0;
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
// }
|
||||
}
|
||||
|
||||
public Byte[] Serialize()
|
||||
@@ -842,8 +859,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,8 +872,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_skippedUpdates = 1000;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
// m_group.SendGroupRootTerseUpdate();
|
||||
m_group.RootPart.ScheduleTerseUpdate();
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
|
||||
@@ -425,25 +425,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
private void XWfloat(string name, float f)
|
||||
{
|
||||
writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString(name, f.ToString(Culture.FormatProvider));
|
||||
}
|
||||
|
||||
private void XWVector(string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void XWQuat(string name, Quaternion quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
|
||||
@@ -1651,10 +1651,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
physicsMS2 = (float)(tmpMS2 - tmpMS);
|
||||
tmpMS = tmpMS2;
|
||||
|
||||
/*
|
||||
// Apply any pending avatar force input to the avatar's velocity
|
||||
if (Frame % m_update_entitymovement == 0)
|
||||
m_sceneGraph.UpdateScenePresenceMovement();
|
||||
|
||||
*/
|
||||
if (Frame % (m_update_coarse_locations) == 0 && !m_sendingCoarseLocations)
|
||||
{
|
||||
m_sendingCoarseLocations = true;
|
||||
@@ -1942,7 +1943,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (!m_backingup)
|
||||
{
|
||||
m_backingup = true;
|
||||
WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0})", Name));
|
||||
}
|
||||
}
|
||||
@@ -1971,38 +1971,58 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
lock (m_returns)
|
||||
{
|
||||
EventManager.TriggerOnBackup(SimulationDataService, forced);
|
||||
|
||||
foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
|
||||
if(m_backingup)
|
||||
{
|
||||
UUID transaction = UUID.Random();
|
||||
m_log.WarnFormat("[Scene] Backup of {0} already running. New call skipped", RegionInfo.RegionName);
|
||||
return;
|
||||
}
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
|
||||
msg.toAgentID = new Guid(ret.Key.ToString());
|
||||
msg.imSessionID = new Guid(transaction.ToString());
|
||||
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
msg.fromAgentName = "Server";
|
||||
msg.dialog = (byte)19; // Object msg
|
||||
msg.fromGroup = false;
|
||||
msg.offline = (byte)1;
|
||||
msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
|
||||
msg.Position = Vector3.Zero;
|
||||
msg.RegionID = RegionInfo.RegionID.Guid;
|
||||
m_backingup = true;
|
||||
try
|
||||
{
|
||||
EventManager.TriggerOnBackup(SimulationDataService, forced);
|
||||
|
||||
// We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
|
||||
msg.binaryBucket = Util.StringToBytes256("\0");
|
||||
if (ret.Value.count > 1)
|
||||
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
else
|
||||
msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
if(m_returns.Count == 0)
|
||||
return;
|
||||
|
||||
IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
|
||||
if (tr != null)
|
||||
if (tr == null)
|
||||
return;
|
||||
|
||||
uint unixtime = (uint)Util.UnixTimeSinceEpoch();
|
||||
uint estateid = RegionInfo.EstateSettings.ParentEstateID;
|
||||
Guid regionguid = RegionInfo.RegionID.Guid;
|
||||
|
||||
foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
|
||||
{
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
msg.fromAgentID = Guid.Empty; // From server
|
||||
msg.toAgentID = ret.Key.Guid;
|
||||
msg.imSessionID = Guid.NewGuid();
|
||||
msg.timestamp = unixtime;
|
||||
msg.fromAgentName = "Server";
|
||||
msg.dialog = 19; // Object msg
|
||||
msg.fromGroup = false;
|
||||
msg.offline = 1;
|
||||
msg.ParentEstateID = estateid;
|
||||
msg.Position = Vector3.Zero;
|
||||
msg.RegionID = regionguid;
|
||||
|
||||
// We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
|
||||
msg.binaryBucket = new Byte[1] {0};
|
||||
if (ret.Value.count > 1)
|
||||
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
else
|
||||
msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
|
||||
|
||||
tr.SendInstantMessage(msg, delegate(bool success) { });
|
||||
}
|
||||
m_returns.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_backingup = false;
|
||||
}
|
||||
m_returns.Clear();
|
||||
m_backingup = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4805,16 +4825,34 @@ Label_GroupsDone:
|
||||
public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
|
||||
Vector3 lookat, uint teleportFlags)
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
|
||||
if (EntityTransferModule == null)
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
|
||||
return;
|
||||
}
|
||||
|
||||
if (region == null)
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp == null || sp.IsDeleted || sp.IsInTransit)
|
||||
return;
|
||||
|
||||
ulong regionHandle = 0;
|
||||
if(regionName == RegionInfo.RegionName)
|
||||
regionHandle = RegionInfo.RegionHandle;
|
||||
else
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
|
||||
if (region != null)
|
||||
regionHandle = region.RegionHandle;
|
||||
}
|
||||
|
||||
if(regionHandle == 0)
|
||||
{
|
||||
// can't find the region: Tell viewer and abort
|
||||
remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
|
||||
EntityTransferModule.Teleport(sp, regionHandle, position, lookat, teleportFlags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -4828,19 +4866,17 @@ Label_GroupsDone:
|
||||
public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
|
||||
Vector3 lookAt, uint teleportFlags)
|
||||
{
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp != null)
|
||||
if (EntityTransferModule == null)
|
||||
{
|
||||
if (EntityTransferModule != null)
|
||||
{
|
||||
EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
|
||||
sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator.");
|
||||
}
|
||||
m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
|
||||
return;
|
||||
}
|
||||
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp == null || sp.IsDeleted || sp.IsInTransit)
|
||||
return;
|
||||
|
||||
EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
|
||||
}
|
||||
|
||||
public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
|
||||
|
||||
@@ -1649,7 +1649,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
else // else turn it off
|
||||
vdtc = false;
|
||||
|
||||
group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc);
|
||||
group.UpdateFlags(UsePhysics, SetTemporary, SetPhantom, vdtc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1259,6 +1259,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
set { m_LoopSoundSlavePrims = value; }
|
||||
}
|
||||
|
||||
private double m_lastCollisionSoundMS;
|
||||
|
||||
/// <summary>
|
||||
/// The UUID for the region this object is in.
|
||||
/// </summary>
|
||||
@@ -1336,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public SceneObjectGroup()
|
||||
{
|
||||
|
||||
m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2716,35 +2718,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
RootPart.KeyframeMotion.Stop();
|
||||
RootPart.KeyframeMotion = null;
|
||||
}
|
||||
UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||
UpdateFlags(usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
public void ScriptSetTemporaryStatus(bool makeTemporary)
|
||||
{
|
||||
UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
|
||||
UpdateFlags(UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
public void ScriptSetPhantomStatus(bool makePhantom)
|
||||
{
|
||||
UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
|
||||
UpdateFlags(UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
public void ScriptSetVolumeDetect(bool makeVolumeDetect)
|
||||
{
|
||||
UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
|
||||
|
||||
/*
|
||||
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();
|
||||
*/
|
||||
UpdateFlags(UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
|
||||
}
|
||||
|
||||
public void applyImpulse(Vector3 impulse)
|
||||
@@ -4029,84 +4018,80 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="SetTemporary"></param>
|
||||
/// <param name="SetPhantom"></param>
|
||||
/// <param name="SetVolumeDetect"></param>
|
||||
public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
|
||||
public void UpdateFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
|
||||
{
|
||||
if (m_scene == null || IsDeleted)
|
||||
return;
|
||||
|
||||
HasGroupChanged = true;
|
||||
|
||||
SceneObjectPart selectionPart = GetPart(localID);
|
||||
|
||||
if (Scene != null)
|
||||
if (SetTemporary)
|
||||
{
|
||||
if (SetTemporary)
|
||||
{
|
||||
DetachFromBackup();
|
||||
// Remove from database and parcel prim count
|
||||
//
|
||||
m_scene.DeleteFromStorage(UUID);
|
||||
}
|
||||
else if (!Backup)
|
||||
{
|
||||
// Previously been temporary now switching back so make it
|
||||
// available for persisting again
|
||||
AttachToBackup();
|
||||
}
|
||||
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
DetachFromBackup();
|
||||
// Remove from database and parcel prim count
|
||||
//
|
||||
m_scene.DeleteFromStorage(UUID);
|
||||
}
|
||||
else if (!Backup)
|
||||
{
|
||||
// Previously been temporary now switching back so make it
|
||||
// available for persisting again
|
||||
AttachToBackup();
|
||||
}
|
||||
|
||||
if (selectionPart != null)
|
||||
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
|
||||
if (UsePhysics)
|
||||
{
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
int maxprims = m_scene.m_linksetPhysCapacity;
|
||||
bool checkShape = (maxprims > 0 &&
|
||||
parts.Length > maxprims);
|
||||
|
||||
if (Scene != null && UsePhysics)
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
int maxprims = m_scene.m_linksetPhysCapacity;
|
||||
bool checkShape = (maxprims > 0 &&
|
||||
parts.Length > maxprims);
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
if(part.PhysicsShapeType == (byte)PhysicsShapeType.None)
|
||||
continue; // assuming root type was checked elsewhere
|
||||
|
||||
if (checkShape)
|
||||
{
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
if(part.PhysicsShapeType == (byte)PhysicsShapeType.None)
|
||||
continue; // assuming root type was checked elsewhere
|
||||
|
||||
if (checkShape)
|
||||
if (--maxprims < 0)
|
||||
{
|
||||
if (--maxprims < 0)
|
||||
{
|
||||
UsePhysics = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (part.Scale.X > m_scene.m_maxPhys ||
|
||||
part.Scale.Y > m_scene.m_maxPhys ||
|
||||
part.Scale.Z > m_scene.m_maxPhys )
|
||||
{
|
||||
UsePhysics = false; // Reset physics
|
||||
UsePhysics = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
if (part.Scale.X > m_scene.m_maxPhys ||
|
||||
part.Scale.Y > m_scene.m_maxPhys ||
|
||||
part.Scale.Z > m_scene.m_maxPhys )
|
||||
{
|
||||
|
||||
if (parts[i].UUID != m_rootPart.UUID)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
UsePhysics = false; // Reset physics
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
else
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
|
||||
}
|
||||
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
|
||||
if (parts[i].UUID != m_rootPart.UUID)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
else
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
|
||||
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
}
|
||||
|
||||
public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
|
||||
@@ -5528,7 +5513,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public bool CollisionSoundThrottled(int collisionSoundType)
|
||||
{
|
||||
double time = m_lastCollisionSoundMS;
|
||||
// m_lastCollisionSoundMS = Util.GetTimeStampMS();
|
||||
// time = m_lastCollisionSoundMS - time;
|
||||
double now = Util.GetTimeStampMS();
|
||||
time = now - time;
|
||||
switch (collisionSoundType)
|
||||
{
|
||||
case 0: // default sounds
|
||||
case 2: // default sounds with volume set by script
|
||||
if(time < 300.0)
|
||||
return true;
|
||||
break;
|
||||
case 1: // selected sound
|
||||
if(time < 200.0)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_lastCollisionSoundMS = now;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -329,7 +329,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private byte[] m_TextureAnimation;
|
||||
private byte m_clickAction;
|
||||
private Color m_color = Color.Black;
|
||||
private readonly List<uint> m_lastColliders = new List<uint>();
|
||||
private List<uint> m_lastColliders = new List<uint>();
|
||||
private bool m_lastLandCollide;
|
||||
private int m_linkNum;
|
||||
|
||||
private int m_scriptAccessPin;
|
||||
@@ -369,9 +370,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected Vector3 m_lastPosition;
|
||||
protected Quaternion m_lastRotation;
|
||||
protected Vector3 m_lastVelocity;
|
||||
protected Vector3 m_lastAcceleration;
|
||||
protected Vector3 m_lastAcceleration; // acceleration is a derived var with high noise
|
||||
protected Vector3 m_lastAngularVelocity;
|
||||
protected int m_lastUpdateSentTime;
|
||||
protected double m_lastUpdateSentTime;
|
||||
protected float m_buoyancy = 0.0f;
|
||||
protected Vector3 m_force;
|
||||
protected Vector3 m_torque;
|
||||
@@ -809,7 +810,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
// If this is a linkset, we don't want the physics engine mucking up our group position here.
|
||||
PhysicsActor actor = PhysActor;
|
||||
if (ParentID == 0)
|
||||
if (_parentID == 0)
|
||||
{
|
||||
if (actor != null)
|
||||
m_groupPosition = actor.Position;
|
||||
@@ -838,7 +839,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
try
|
||||
{
|
||||
// Root prim actually goes at Position
|
||||
if (ParentID == 0)
|
||||
if (_parentID == 0)
|
||||
{
|
||||
actor.Position = value;
|
||||
}
|
||||
@@ -880,7 +881,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
ParentGroup.InvalidBoundsRadius();
|
||||
|
||||
PhysicsActor actor = PhysActor;
|
||||
if (ParentID != 0 && actor != null)
|
||||
if (_parentID != 0 && actor != null)
|
||||
{
|
||||
actor.Position = GetWorldPosition();
|
||||
actor.Orientation = GetWorldRotation();
|
||||
@@ -940,7 +941,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
PhysicsActor actor = PhysActor;
|
||||
// If this is a root of a linkset, the real rotation is what the physics engine thinks.
|
||||
// If not a root prim, the offset rotation is computed by SOG and is relative to the root.
|
||||
if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
|
||||
if (_parentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
|
||||
m_rotationOffset = actor.Orientation;
|
||||
|
||||
return m_rotationOffset;
|
||||
@@ -957,7 +958,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
try
|
||||
{
|
||||
// Root prim gets value directly
|
||||
if (ParentID == 0)
|
||||
if (_parentID == 0)
|
||||
{
|
||||
actor.Orientation = value;
|
||||
//m_log.Info("[PART]: RO1:" + actor.Orientation.ToString());
|
||||
@@ -1103,8 +1104,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_text.Length > 255)
|
||||
return m_text.Substring(0, 254);
|
||||
if (m_text.Length > 256) // yes > 254
|
||||
return m_text.Substring(0, 256);
|
||||
return m_text;
|
||||
}
|
||||
set { m_text = value; }
|
||||
@@ -1258,6 +1259,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parentID == 0)
|
||||
return GroupPosition;
|
||||
|
||||
return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
|
||||
}
|
||||
}
|
||||
@@ -1379,7 +1383,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public UUID LastOwnerID
|
||||
{
|
||||
get { return _lastOwnerID; }
|
||||
set { _lastOwnerID = value; }
|
||||
set {
|
||||
_lastOwnerID = value; }
|
||||
}
|
||||
|
||||
public UUID RezzerID
|
||||
@@ -2422,7 +2427,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
|
||||
PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
|
||||
|
||||
if (ParentID != 0 && ParentID != LocalId)
|
||||
if (_parentID != 0 && _parentID != LocalId)
|
||||
{
|
||||
PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
|
||||
|
||||
@@ -2788,12 +2793,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
ColliderArgs colliderArgs = new ColliderArgs();
|
||||
List<DetectedObject> colliding = new List<DetectedObject>();
|
||||
Scene parentScene = ParentGroup.Scene;
|
||||
foreach (uint localId in colliders)
|
||||
{
|
||||
if (localId == 0)
|
||||
continue;
|
||||
|
||||
SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
|
||||
SceneObjectPart obj = parentScene.GetSceneObjectPart(localId);
|
||||
if (obj != null)
|
||||
{
|
||||
if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
|
||||
@@ -2801,7 +2807,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
|
||||
ScenePresence av = parentScene.GetScenePresence(localId);
|
||||
if (av != null && (!av.IsChildAgent))
|
||||
{
|
||||
if (!dest.CollisionFilteredOut(av.UUID, av.Name))
|
||||
@@ -2874,10 +2880,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void PhysicsCollision(EventArgs e)
|
||||
{
|
||||
if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
|
||||
if (ParentGroup.Scene == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
|
||||
return;
|
||||
|
||||
// this a thread from physics ( heartbeat )
|
||||
bool thisHitLand = false;
|
||||
bool startLand = false;
|
||||
bool endedLand = false;
|
||||
|
||||
CollisionEventUpdate a = (CollisionEventUpdate)e;
|
||||
Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
|
||||
@@ -2887,13 +2896,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (collissionswith.Count == 0)
|
||||
{
|
||||
if (m_lastColliders.Count == 0)
|
||||
if (m_lastColliders.Count == 0 && !m_lastLandCollide)
|
||||
return; // nothing to do
|
||||
|
||||
endedLand = m_lastLandCollide;
|
||||
m_lastLandCollide = false;
|
||||
|
||||
foreach (uint localID in m_lastColliders)
|
||||
{
|
||||
endedColliders.Add(localID);
|
||||
}
|
||||
|
||||
m_lastColliders.Clear();
|
||||
}
|
||||
else
|
||||
@@ -2909,19 +2922,39 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
foreach (uint id in collissionswith.Keys)
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
if(id == 0)
|
||||
{
|
||||
startedColliders.Add(id);
|
||||
|
||||
curcontact = collissionswith[id];
|
||||
if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
|
||||
thisHitLand = true;
|
||||
if (!m_lastLandCollide)
|
||||
{
|
||||
soundinfo = new CollisionForSoundInfo();
|
||||
soundinfo.colliderID = id;
|
||||
soundinfo.position = curcontact.Position;
|
||||
soundinfo.relativeVel = curcontact.RelativeSpeed;
|
||||
soundinfolist.Add(soundinfo);
|
||||
startLand = true;
|
||||
curcontact = collissionswith[id];
|
||||
if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
|
||||
{
|
||||
soundinfo = new CollisionForSoundInfo();
|
||||
soundinfo.colliderID = id;
|
||||
soundinfo.position = curcontact.Position;
|
||||
soundinfo.relativeVel = curcontact.RelativeSpeed;
|
||||
soundinfolist.Add(soundinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
{
|
||||
startedColliders.Add(id);
|
||||
|
||||
curcontact = collissionswith[id];
|
||||
if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
|
||||
{
|
||||
soundinfo = new CollisionForSoundInfo();
|
||||
soundinfo.colliderID = id;
|
||||
soundinfo.position = curcontact.Position;
|
||||
soundinfo.relativeVel = curcontact.RelativeSpeed;
|
||||
soundinfolist.Add(soundinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2930,9 +2963,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
foreach (uint id in collissionswith.Keys)
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
startedColliders.Add(id);
|
||||
if(id == 0)
|
||||
{
|
||||
thisHitLand = true;
|
||||
if (!m_lastLandCollide)
|
||||
startLand = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisHitColliders.Add(id);
|
||||
if (!m_lastColliders.Contains(id))
|
||||
startedColliders.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2951,22 +2993,32 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
foreach (uint localID in endedColliders)
|
||||
m_lastColliders.Remove(localID);
|
||||
|
||||
if(m_lastLandCollide && !thisHitLand)
|
||||
endedLand = true;
|
||||
|
||||
m_lastLandCollide = thisHitLand;
|
||||
|
||||
// play sounds.
|
||||
if (soundinfolist.Count > 0)
|
||||
CollisionSounds.PartCollisionSound(this, soundinfolist);
|
||||
}
|
||||
|
||||
EventManager eventmanager = ParentGroup.Scene.EventManager;
|
||||
|
||||
SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
|
||||
SendCollisionEvent(scriptEvents.collision_start, startedColliders, eventmanager.TriggerScriptCollidingStart);
|
||||
if (!VolumeDetectActive)
|
||||
SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
|
||||
SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
|
||||
SendCollisionEvent(scriptEvents.collision , m_lastColliders , eventmanager.TriggerScriptColliding);
|
||||
SendCollisionEvent(scriptEvents.collision_end , endedColliders , eventmanager.TriggerScriptCollidingEnd);
|
||||
|
||||
if (startedColliders.Contains(0))
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
|
||||
if (m_lastColliders.Contains(0))
|
||||
SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
|
||||
if (endedColliders.Contains(0))
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
|
||||
if (!VolumeDetectActive)
|
||||
{
|
||||
if (startLand)
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_start, eventmanager.TriggerScriptLandCollidingStart);
|
||||
if (m_lastLandCollide)
|
||||
SendLandCollisionEvent(scriptEvents.land_collision, eventmanager.TriggerScriptLandColliding);
|
||||
if (endedLand)
|
||||
SendLandCollisionEvent(scriptEvents.land_collision_end, eventmanager.TriggerScriptLandCollidingEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// The Collision sounds code calls this
|
||||
@@ -2985,7 +3037,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
volume = 0;
|
||||
|
||||
int now = Util.EnvironmentTickCount();
|
||||
if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
|
||||
if(Util.EnvironmentTickCountSubtract(now, LastColSoundSentTime) < 200)
|
||||
return;
|
||||
|
||||
LastColSoundSentTime = now;
|
||||
@@ -3026,7 +3078,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//ParentGroup.RootPart.m_groupPosition = newpos;
|
||||
}
|
||||
/*
|
||||
if (pa != null && ParentID != 0 && ParentGroup != null)
|
||||
if (pa != null && _parentID != 0 && ParentGroup != null)
|
||||
{
|
||||
// Special case where a child object is requesting property updates.
|
||||
// This happens when linksets are modified to use flexible links rather than
|
||||
@@ -3236,7 +3288,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a terse update for this prim. Terse updates only send position,
|
||||
/// rotation, velocity and rotational velocity information.
|
||||
/// rotation, velocity and rotational velocity information. WRONG!!!!
|
||||
/// </summary>
|
||||
public void ScheduleTerseUpdate()
|
||||
{
|
||||
@@ -3295,21 +3347,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
sp.SendAttachmentUpdate(this, UpdateRequired.FULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* this does nothing
|
||||
SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
if (IsRoot)
|
||||
{
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
SendFullUpdateToClient(remoteClient, AttachedPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendFullUpdateToClient(remoteClient, AbsolutePosition);
|
||||
}
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
SendFullUpdateToClient(remoteClient);
|
||||
@@ -3325,12 +3362,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
return;
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||
{
|
||||
@@ -3344,12 +3381,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
return;
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
@@ -3395,40 +3432,129 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
|
||||
}
|
||||
|
||||
|
||||
private const float ROTATION_TOLERANCE = 0.01f;
|
||||
private const float VELOCITY_TOLERANCE = 0.1f; // terse update vel has low resolution
|
||||
private const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
|
||||
private const double TIME_MS_TOLERANCE = 200f; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
|
||||
|
||||
/// <summary>
|
||||
/// Tell all the prims which have had updates scheduled
|
||||
/// </summary>
|
||||
public void SendScheduledUpdates()
|
||||
{
|
||||
const float ROTATION_TOLERANCE = 0.01f;
|
||||
const float VELOCITY_TOLERANCE = 0.001f;
|
||||
const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
|
||||
const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
|
||||
|
||||
{
|
||||
switch (UpdateFlag)
|
||||
{
|
||||
case UpdateRequired.TERSE:
|
||||
{
|
||||
case UpdateRequired.NONE:
|
||||
ClearUpdateSchedule();
|
||||
// Throw away duplicate or insignificant updates
|
||||
if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
|
||||
!Acceleration.Equals(m_lastAcceleration) ||
|
||||
!Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
|
||||
Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
|
||||
!AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
|
||||
!OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
|
||||
Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
|
||||
break;
|
||||
|
||||
case UpdateRequired.TERSE:
|
||||
|
||||
ClearUpdateSchedule();
|
||||
bool needupdate = true;
|
||||
double now = Util.GetTimeStampMS();
|
||||
Vector3 curvel = Velocity;
|
||||
Vector3 curacc = Acceleration;
|
||||
Vector3 angvel = AngularVelocity;
|
||||
|
||||
while(true) // just to avoid ugly goto
|
||||
{
|
||||
SendTerseUpdateToAllClientsInternal();
|
||||
double elapsed = now - m_lastUpdateSentTime;
|
||||
if (elapsed > TIME_MS_TOLERANCE)
|
||||
break;
|
||||
|
||||
if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
|
||||
break;
|
||||
|
||||
// velocity change is also direction not only norm)
|
||||
if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
|
||||
break;
|
||||
|
||||
float vx = Math.Abs(curvel.X);
|
||||
if(vx > 128.0)
|
||||
break;
|
||||
float vy = Math.Abs(curvel.Y);
|
||||
if(vy > 128.0)
|
||||
break;
|
||||
float vz = Math.Abs(curvel.Z);
|
||||
if(vz > 128.0)
|
||||
break;
|
||||
|
||||
if (
|
||||
vx < VELOCITY_TOLERANCE &&
|
||||
vy < VELOCITY_TOLERANCE &&
|
||||
vz < VELOCITY_TOLERANCE
|
||||
)
|
||||
{
|
||||
if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
|
||||
break;
|
||||
|
||||
if (vx < 1e-4 &&
|
||||
vy < 1e-4 &&
|
||||
vz < 1e-4 &&
|
||||
(
|
||||
Math.Abs(m_lastVelocity.X) > 1e-4 ||
|
||||
Math.Abs(m_lastVelocity.Y) > 1e-4 ||
|
||||
Math.Abs(m_lastVelocity.Z) > 1e-4
|
||||
))
|
||||
break;
|
||||
}
|
||||
|
||||
if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE)
|
||||
break;
|
||||
|
||||
// viewer interpolators have a limit of 128m/s
|
||||
float ax = Math.Abs(angvel.X);
|
||||
if(ax > 64.0)
|
||||
break;
|
||||
float ay = Math.Abs(angvel.Y);
|
||||
if(ay > 64.0)
|
||||
break;
|
||||
float az = Math.Abs(angvel.Z);
|
||||
if(az > 64.0)
|
||||
break;
|
||||
|
||||
if (
|
||||
ax < VELOCITY_TOLERANCE &&
|
||||
ay < VELOCITY_TOLERANCE &&
|
||||
az < VELOCITY_TOLERANCE &&
|
||||
!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|
||||
)
|
||||
break;
|
||||
|
||||
needupdate = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(needupdate)
|
||||
{
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = curvel;
|
||||
m_lastAcceleration = curacc;
|
||||
m_lastAngularVelocity = angvel;
|
||||
m_lastUpdateSentTime = now;
|
||||
|
||||
ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
|
||||
{
|
||||
SendTerseUpdateToClient(client);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case UpdateRequired.FULL:
|
||||
{
|
||||
ClearUpdateSchedule();
|
||||
SendFullUpdateToAllClientsInternal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3441,13 +3567,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
if (ParentGroup == null || ParentGroup.Scene == null)
|
||||
return;
|
||||
|
||||
ClearUpdateSchedule();
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
|
||||
{
|
||||
@@ -3460,13 +3588,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
if (ParentGroup == null || ParentGroup.Scene == null)
|
||||
return;
|
||||
|
||||
ClearUpdateSchedule();
|
||||
|
||||
// Update the "last" values
|
||||
m_lastPosition = OffsetPosition;
|
||||
m_lastPosition = AbsolutePosition;
|
||||
m_lastRotation = RotationOffset;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastAcceleration = Acceleration;
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastUpdateSentTime = Environment.TickCount;
|
||||
m_lastUpdateSentTime = Util.GetTimeStampMS();
|
||||
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
@@ -4783,7 +4913,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
|
||||
pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
|
||||
pa.OnOutOfBounds += PhysicsOutOfBounds;
|
||||
|
||||
if (ParentID != 0 && ParentID != LocalId)
|
||||
if (_parentID != 0 && _parentID != LocalId)
|
||||
{
|
||||
PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
|
||||
|
||||
|
||||
@@ -279,8 +279,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private bool MouseDown = false;
|
||||
public Vector3 lastKnownAllowedPosition;
|
||||
public bool sentMessageAboutRestrictedParcelFlyingDown;
|
||||
|
||||
public Vector4 CollisionPlane = Vector4.UnitW;
|
||||
|
||||
public Vector4 m_lastCollisionPlane = Vector4.UnitW;
|
||||
private byte m_lastState;
|
||||
private Vector3 m_lastPosition;
|
||||
private Quaternion m_lastRotation;
|
||||
private Vector3 m_lastVelocity;
|
||||
@@ -2818,16 +2821,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
CameraAtAxis = agentData.CameraAtAxis;
|
||||
CameraLeftAxis = agentData.CameraLeftAxis;
|
||||
CameraUpAxis = agentData.CameraUpAxis;
|
||||
Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
|
||||
CameraRotation = camRot;
|
||||
|
||||
// The Agent's Draw distance setting
|
||||
// When we get to the point of re-computing neighbors everytime this
|
||||
// changes, then start using the agent's drawdistance rather than the
|
||||
// region's draw distance.
|
||||
|
||||
DrawDistance = agentData.Far;
|
||||
|
||||
CameraAtAxis.Normalize();
|
||||
CameraLeftAxis.Normalize();
|
||||
CameraUpAxis.Normalize();
|
||||
Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
|
||||
CameraRotation = camRot;
|
||||
|
||||
// Check if Client has camera in 'follow cam' or 'build' mode.
|
||||
// Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
|
||||
@@ -3789,29 +3789,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// Send terse position update if not sitting and position, velocity, or rotation
|
||||
// has changed significantly from last sent update
|
||||
if (!IsSatOnObject && (
|
||||
!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|
||||
|| !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
|
||||
|| !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE)
|
||||
// if velocity is zero and it wasn't zero last time, send the update
|
||||
|| (Velocity == Vector3.Zero && m_lastVelocity != Vector3.Zero)
|
||||
// if position has moved just a little and velocity is very low, send the update
|
||||
|| (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ )
|
||||
) )
|
||||
{
|
||||
/*
|
||||
if (!IsSatOnObject)
|
||||
{
|
||||
// this does need to be more complex later
|
||||
Vector3 vel = Velocity;
|
||||
Vector3 dpos = m_pos - m_lastPosition;
|
||||
if( Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
if( State != m_lastState ||
|
||||
Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
|
||||
Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE ||
|
||||
|
||||
Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE ||
|
||||
Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE ||
|
||||
Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE ||
|
||||
|
||||
(vel == Vector3.Zero && m_lastVelocity != Vector3.Zero) ||
|
||||
|
||||
Math.Abs(dpos.X) > POSITION_LARGETOLERANCE ||
|
||||
Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE ||
|
||||
@@ -3821,11 +3813,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE ||
|
||||
Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE)
|
||||
&& vel.LengthSquared() < LOWVELOCITYSQ
|
||||
))
|
||||
) ||
|
||||
|
||||
Math.Abs(CollisionPlane.X - m_lastCollisionPlane.X) > POSITION_SMALLTOLERANCE ||
|
||||
Math.Abs(CollisionPlane.Y - m_lastCollisionPlane.Y) > POSITION_SMALLTOLERANCE ||
|
||||
Math.Abs(CollisionPlane.W - m_lastCollisionPlane.W) > POSITION_SMALLTOLERANCE
|
||||
)
|
||||
{
|
||||
*/
|
||||
SendTerseUpdateToAllClients();
|
||||
// }
|
||||
}
|
||||
}
|
||||
CheckForSignificantMovement();
|
||||
}
|
||||
@@ -3921,11 +3917,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void SendTerseUpdateToAllClients()
|
||||
{
|
||||
m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
|
||||
// Update the "last" values
|
||||
m_lastState = State;
|
||||
m_lastPosition = m_pos;
|
||||
m_lastRotation = m_bodyRot;
|
||||
m_lastVelocity = Velocity;
|
||||
m_lastCollisionPlane = CollisionPlane;
|
||||
|
||||
m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
|
||||
// Update the "last" values
|
||||
TriggerScenePresenceUpdated();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
|
||||
writer.WriteStartElement("CoalescedObject");
|
||||
|
||||
writer.WriteAttributeString("x", size.X.ToString());
|
||||
writer.WriteAttributeString("y", size.Y.ToString());
|
||||
writer.WriteAttributeString("z", size.Z.ToString());
|
||||
writer.WriteAttributeString("x", size.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("y", size.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("z", size.Z.ToString(Culture.FormatProvider));
|
||||
|
||||
// Embed the offsets into the group XML
|
||||
for (int i = 0; i < coaObjects.Count; i++)
|
||||
@@ -100,9 +100,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
// i, obj.Name);
|
||||
|
||||
writer.WriteStartElement("SceneObjectGroup");
|
||||
writer.WriteAttributeString("offsetx", offsets[i].X.ToString());
|
||||
writer.WriteAttributeString("offsety", offsets[i].Y.ToString());
|
||||
writer.WriteAttributeString("offsetz", offsets[i].Z.ToString());
|
||||
writer.WriteAttributeString("offsetx", offsets[i].X.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("offsety", offsets[i].Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteAttributeString("offsetz", offsets[i].Z.ToString(Culture.FormatProvider));
|
||||
|
||||
SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
{
|
||||
using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
return FromOriginalXmlFormat(reader);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -109,11 +110,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
}
|
||||
}
|
||||
while (reader.ReadToNextSibling("Part"));
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
|
||||
if (reader.Name == "KeyframeMotion" && reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
|
||||
string innerkeytxt = reader.ReadElementContentAsString();
|
||||
sceneObject.RootPart.KeyframeMotion =
|
||||
KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(innerkeytxt));
|
||||
}
|
||||
else
|
||||
sceneObject.RootPart.KeyframeMotion = null;
|
||||
|
||||
// Script state may, or may not, exist. Not having any, is NOT
|
||||
// ever a problem.
|
||||
sceneObject.LoadScriptState(reader);
|
||||
|
||||
sceneObject.InvalidateDeepEffectivePerms();
|
||||
return sceneObject;
|
||||
}
|
||||
@@ -210,9 +223,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
|
||||
writer.WriteEndElement(); // OtherParts
|
||||
|
||||
if (sceneObject.RootPart.KeyframeMotion != null)
|
||||
{
|
||||
Byte[] data = sceneObject.RootPart.KeyframeMotion.Serialize();
|
||||
|
||||
writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty);
|
||||
writer.WriteBase64(data, 0, data.Length);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
if (doScriptStates)
|
||||
sceneObject.SaveScriptedState(writer);
|
||||
|
||||
|
||||
if (!noRootElement)
|
||||
writer.WriteEndElement(); // SceneObjectGroup
|
||||
|
||||
@@ -1459,10 +1482,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
writer.WriteElementString("Description", sop.Description);
|
||||
|
||||
writer.WriteStartElement("Color");
|
||||
writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("R", sop.Color.R.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("G", sop.Color.G.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("B", sop.Color.B.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("A", sop.Color.A.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteElementString("Text", sop.Text);
|
||||
@@ -1505,7 +1528,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString());
|
||||
WriteFlags(writer, "Flags", sop.Flags.ToString(), options);
|
||||
WriteUUID(writer, "CollisionSound", sop.CollisionSound, options);
|
||||
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
|
||||
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString(Culture.FormatProvider));
|
||||
if (sop.MediaUrl != null)
|
||||
writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
|
||||
WriteVector(writer, "AttachedPos", sop.AttachedPos);
|
||||
@@ -1525,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString());
|
||||
writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
|
||||
|
||||
writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
|
||||
writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString(Culture.FormatProvider));
|
||||
|
||||
WriteVector(writer, "Force", sop.Force);
|
||||
WriteVector(writer, "Torque", sop.Torque);
|
||||
@@ -1542,22 +1565,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
writer.WriteElementString("RotationAxisLocks", sop.RotationAxisLocks.ToString().ToLower());
|
||||
writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower());
|
||||
if (sop.Density != 1000.0f)
|
||||
writer.WriteElementString("Density", sop.Density.ToString().ToLower());
|
||||
writer.WriteElementString("Density", sop.Density.ToString(Culture.FormatProvider));
|
||||
if (sop.Friction != 0.6f)
|
||||
writer.WriteElementString("Friction", sop.Friction.ToString().ToLower());
|
||||
writer.WriteElementString("Friction", sop.Friction.ToString(Culture.FormatProvider));
|
||||
if (sop.Restitution != 0.5f)
|
||||
writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower());
|
||||
writer.WriteElementString("Bounce", sop.Restitution.ToString(Culture.FormatProvider));
|
||||
if (sop.GravityModifier != 1.0f)
|
||||
writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower());
|
||||
writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString(Culture.FormatProvider));
|
||||
WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset());
|
||||
WriteVector(writer, "CameraAtOffset", sop.GetCameraAtOffset());
|
||||
|
||||
// if (sop.Sound != UUID.Zero) force it till sop crossing does clear it on child prim
|
||||
{
|
||||
WriteUUID(writer, "SoundID", sop.Sound, options);
|
||||
writer.WriteElementString("SoundGain", sop.SoundGain.ToString().ToLower());
|
||||
writer.WriteElementString("SoundGain", sop.SoundGain.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("SoundFlags", sop.SoundFlags.ToString().ToLower());
|
||||
writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString().ToLower());
|
||||
writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString(Culture.FormatProvider));
|
||||
}
|
||||
writer.WriteElementString("SoundQueueing", sop.SoundQueueing.ToString().ToLower());
|
||||
|
||||
@@ -1577,19 +1600,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
static void WriteVector(XmlTextWriter writer, string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
static void WriteQuaternion(XmlTextWriter writer, string name, Quaternion quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
@@ -1731,22 +1754,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
// Don't serialize SculptData. It's just a copy of the asset, which can be loaded separately using 'SculptTexture'.
|
||||
|
||||
writer.WriteElementString("FlexiSoftness", shp.FlexiSoftness.ToString());
|
||||
writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString());
|
||||
writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString());
|
||||
writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString());
|
||||
writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString());
|
||||
writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString());
|
||||
writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString());
|
||||
writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString());
|
||||
writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString(Culture.FormatProvider));
|
||||
|
||||
writer.WriteElementString("LightColorR", shp.LightColorR.ToString());
|
||||
writer.WriteElementString("LightColorG", shp.LightColorG.ToString());
|
||||
writer.WriteElementString("LightColorB", shp.LightColorB.ToString());
|
||||
writer.WriteElementString("LightColorA", shp.LightColorA.ToString());
|
||||
writer.WriteElementString("LightRadius", shp.LightRadius.ToString());
|
||||
writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString());
|
||||
writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString());
|
||||
writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString());
|
||||
writer.WriteElementString("LightColorR", shp.LightColorR.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightColorG", shp.LightColorG.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightColorB", shp.LightColorB.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightColorA", shp.LightColorA.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightRadius", shp.LightRadius.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString(Culture.FormatProvider));
|
||||
writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString(Culture.FormatProvider));
|
||||
|
||||
writer.WriteElementString("FlexiEntry", shp.FlexiEntry.ToString().ToLower());
|
||||
writer.WriteElementString("LightEntry", shp.LightEntry.ToString().ToLower());
|
||||
|
||||
@@ -54,8 +54,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
|
||||
UUID ownerId = TestHelpers.ParseTail(0x1);
|
||||
SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(3, ownerId, "so1", 0x10);
|
||||
so1.ScriptSetPhysicsStatus(true);
|
||||
m_scene.AddSceneObject(so1);
|
||||
so1.ScriptSetPhysicsStatus(true);
|
||||
|
||||
Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(3));
|
||||
Assert.That(m_scene.SceneGraph.GetActiveObjectsCount(), Is.EqualTo(3));
|
||||
|
||||
@@ -65,7 +65,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
/// <value>The gathered uuids.</value>
|
||||
public IDictionary<UUID, sbyte> GatheredUuids { get; private set; }
|
||||
|
||||
public HashSet<UUID> FailedUUIDs { get; private set; }
|
||||
public HashSet<UUID> UncertainAssetsUUIDs { get; private set; }
|
||||
public int possibleNotAssetCount { get; set; }
|
||||
public int ErrorCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the next UUID to inspect.
|
||||
/// </summary>
|
||||
@@ -92,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="assetService">
|
||||
/// Asset service.
|
||||
/// </param>
|
||||
public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>()) {}
|
||||
public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>(),
|
||||
new HashSet <UUID>(),new HashSet <UUID>()) {}
|
||||
public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector) : this(assetService, collector,
|
||||
new HashSet <UUID>(), new HashSet <UUID>()) {}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
|
||||
@@ -101,16 +107,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// Asset service.
|
||||
/// </param>
|
||||
/// <param name="collector">
|
||||
/// Gathered UUIDs will be collected in this dictinaory.
|
||||
/// Gathered UUIDs will be collected in this dictionary.
|
||||
/// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected.
|
||||
/// </param>
|
||||
public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector)
|
||||
public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector, HashSet <UUID> failedIDs, HashSet <UUID> uncertainAssetsUUIDs)
|
||||
{
|
||||
m_assetService = assetService;
|
||||
GatheredUuids = collector;
|
||||
|
||||
// FIXME: Not efficient for searching, can improve.
|
||||
m_assetUuidsToInspect = new Queue<UUID>();
|
||||
FailedUUIDs = failedIDs;
|
||||
UncertainAssetsUUIDs = uncertainAssetsUUIDs;
|
||||
ErrorCount = 0;
|
||||
possibleNotAssetCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,6 +130,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="uuid">UUID.</param>
|
||||
public bool AddForInspection(UUID uuid)
|
||||
{
|
||||
if(uuid == UUID.Zero)
|
||||
return false;
|
||||
|
||||
if(FailedUUIDs.Contains(uuid))
|
||||
{
|
||||
if(UncertainAssetsUUIDs.Contains(uuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return false;
|
||||
}
|
||||
if(GatheredUuids.ContainsKey(uuid))
|
||||
return false;
|
||||
if (m_assetUuidsToInspect.Contains(uuid))
|
||||
return false;
|
||||
|
||||
@@ -141,7 +164,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public void AddForInspection(SceneObjectGroup sceneObject)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
|
||||
// "[UUID GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
|
||||
if(sceneObject.IsDeleted)
|
||||
return;
|
||||
|
||||
SceneObjectPart[] parts = sceneObject.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
@@ -149,7 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
// "[UUID GATHERER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -207,9 +232,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
|
||||
// tii.Name, tii.Type, part.Name, part.UUID);
|
||||
|
||||
if (!GatheredUuids.ContainsKey(tii.AssetID))
|
||||
AddForInspection(tii.AssetID, (sbyte)tii.Type);
|
||||
AddForInspection(tii.AssetID, (sbyte)tii.Type);
|
||||
}
|
||||
|
||||
// FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
|
||||
@@ -225,9 +248,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
|
||||
m_log.DebugFormat(
|
||||
"[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
|
||||
part.Shape.TextureEntry.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,55 +298,112 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
|
||||
private void GetAssetUuids(UUID assetUuid)
|
||||
{
|
||||
if(assetUuid == UUID.Zero)
|
||||
return;
|
||||
|
||||
if(FailedUUIDs.Contains(assetUuid))
|
||||
{
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid infinite loops
|
||||
if (GatheredUuids.ContainsKey(assetUuid))
|
||||
return;
|
||||
|
||||
AssetBase assetBase;
|
||||
try
|
||||
{
|
||||
AssetBase assetBase = GetAsset(assetUuid);
|
||||
assetBase = GetAsset(assetUuid);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to get asset {0} : {1}", assetUuid, e.Message);
|
||||
ErrorCount++;
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (null != assetBase)
|
||||
if(assetBase == null)
|
||||
{
|
||||
// m_log.ErrorFormat("[UUID GATHERER]: asset {0} not found", assetUuid);
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
UncertainAssetsUUIDs.Remove(assetUuid);
|
||||
|
||||
sbyte assetType = assetBase.Type;
|
||||
|
||||
if(assetBase.Data == null || assetBase.Data.Length == 0)
|
||||
{
|
||||
// m_log.ErrorFormat("[UUID GATHERER]: asset {0}, type {1} has no data", assetUuid, assetType);
|
||||
ErrorCount++;
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
GatheredUuids[assetUuid] = assetType;
|
||||
try
|
||||
{
|
||||
if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
|
||||
{
|
||||
sbyte assetType = assetBase.Type;
|
||||
GatheredUuids[assetUuid] = assetType;
|
||||
|
||||
if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
|
||||
{
|
||||
RecordWearableAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Gesture == assetType)
|
||||
{
|
||||
RecordGestureAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Notecard == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.LSLText == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)OpenSimAssetType.Material == assetType)
|
||||
{
|
||||
RecordMaterialAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Object == assetType)
|
||||
{
|
||||
RecordSceneObjectAssetUuids(assetBase);
|
||||
}
|
||||
RecordWearableAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Gesture == assetType)
|
||||
{
|
||||
RecordGestureAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Notecard == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.LSLText == assetType)
|
||||
{
|
||||
RecordTextEmbeddedAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)OpenSimAssetType.Material == assetType)
|
||||
{
|
||||
RecordMaterialAssetUuids(assetBase);
|
||||
}
|
||||
else if ((sbyte)AssetType.Object == assetType)
|
||||
{
|
||||
RecordSceneObjectAssetUuids(assetBase);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
|
||||
throw;
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset with id {0} type {1}: {2}", assetUuid, assetType, e.Message);
|
||||
GatheredUuids.Remove(assetUuid);
|
||||
ErrorCount++;
|
||||
FailedUUIDs.Add(assetUuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddForInspection(UUID assetUuid, sbyte assetType)
|
||||
{
|
||||
if(assetUuid == UUID.Zero)
|
||||
return;
|
||||
|
||||
// Here, we want to collect uuids which require further asset fetches but mark the others as gathered
|
||||
if(FailedUUIDs.Contains(assetUuid))
|
||||
{
|
||||
if(UncertainAssetsUUIDs.Contains(assetUuid))
|
||||
possibleNotAssetCount++;
|
||||
else
|
||||
ErrorCount++;
|
||||
return;
|
||||
}
|
||||
if(GatheredUuids.ContainsKey(assetUuid))
|
||||
return;
|
||||
try
|
||||
{
|
||||
if ((sbyte)AssetType.Bodypart == assetType
|
||||
@@ -458,8 +535,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
foreach (Match uuidMatch in uuidMatches)
|
||||
{
|
||||
UUID uuid = new UUID(uuidMatch.Value);
|
||||
if(uuid == UUID.Zero)
|
||||
continue;
|
||||
// m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid);
|
||||
|
||||
if(!UncertainAssetsUUIDs.Contains(uuid))
|
||||
UncertainAssetsUUIDs.Add(uuid);
|
||||
AddForInspection(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user