mirror of
https://github.com/opensim/opensim.git
synced 2026-08-11 20:05:33 +08:00
Merge branch 'master' into careminster-presence-refactor
This commit is contained in:
@@ -28,11 +28,12 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using OpenSim.Framework;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public abstract class EntityBase
|
||||
public abstract class EntityBase : ISceneEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// The scene to which this entity belongs
|
||||
|
||||
191
OpenSim/Region/Framework/Scenes/Prioritizer.cs
Normal file
191
OpenSim/Region/Framework/Scenes/Prioritizer.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
/*
|
||||
* Steps to add a new prioritization policy:
|
||||
*
|
||||
* - Add a new value to the UpdatePrioritizationSchemes enum.
|
||||
* - Specify this new value in the [InterestManagement] section of your
|
||||
* OpenSim.ini. The name in the config file must match the enum value name
|
||||
* (although it is not case sensitive).
|
||||
* - Write a new GetPriorityBy*() method in this class.
|
||||
* - Add a new entry to the switch statement in GetUpdatePriority() that calls
|
||||
* your method.
|
||||
*/
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public enum UpdatePrioritizationSchemes
|
||||
{
|
||||
Time = 0,
|
||||
Distance = 1,
|
||||
SimpleAngularDistance = 2,
|
||||
FrontBack = 3,
|
||||
BestAvatarResponsiveness = 4,
|
||||
}
|
||||
|
||||
public class Prioritizer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
|
||||
public Prioritizer(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
public double GetUpdatePriority(IClientAPI client, ISceneEntity entity)
|
||||
{
|
||||
switch (m_scene.UpdatePrioritizationScheme)
|
||||
{
|
||||
case UpdatePrioritizationSchemes.Time:
|
||||
return GetPriorityByTime();
|
||||
case UpdatePrioritizationSchemes.Distance:
|
||||
return GetPriorityByDistance(client, entity);
|
||||
case UpdatePrioritizationSchemes.SimpleAngularDistance:
|
||||
return GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance
|
||||
case UpdatePrioritizationSchemes.FrontBack:
|
||||
return GetPriorityByFrontBack(client, entity);
|
||||
case UpdatePrioritizationSchemes.BestAvatarResponsiveness:
|
||||
return GetPriorityByBestAvatarResponsiveness(client, entity);
|
||||
default:
|
||||
throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
|
||||
}
|
||||
}
|
||||
|
||||
private double GetPriorityByTime()
|
||||
{
|
||||
return DateTime.UtcNow.ToOADate();
|
||||
}
|
||||
|
||||
private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
|
||||
{
|
||||
ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
// If this is an update for our own avatar give it the highest priority
|
||||
if (presence == entity)
|
||||
return 0.0;
|
||||
|
||||
// Use the camera position for local agents and avatar position for remote agents
|
||||
Vector3 presencePos = (presence.IsChildAgent) ?
|
||||
presence.AbsolutePosition :
|
||||
presence.CameraPosition;
|
||||
|
||||
// Use group position for child prims
|
||||
Vector3 entityPos;
|
||||
if (entity is SceneObjectPart)
|
||||
entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
|
||||
else
|
||||
entityPos = entity.AbsolutePosition;
|
||||
|
||||
return Vector3.DistanceSquared(presencePos, entityPos);
|
||||
}
|
||||
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
|
||||
{
|
||||
ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
// If this is an update for our own avatar give it the highest priority
|
||||
if (presence == entity)
|
||||
return 0.0;
|
||||
|
||||
// Use group position for child prims
|
||||
Vector3 entityPos = entity.AbsolutePosition;
|
||||
if (entity is SceneObjectPart)
|
||||
entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
|
||||
else
|
||||
entityPos = entity.AbsolutePosition;
|
||||
|
||||
if (!presence.IsChildAgent)
|
||||
{
|
||||
// Root agent. Use distance from camera and a priority decrease for objects behind us
|
||||
Vector3 camPosition = presence.CameraPosition;
|
||||
Vector3 camAtAxis = presence.CameraAtAxis;
|
||||
|
||||
// Distance
|
||||
double priority = Vector3.DistanceSquared(camPosition, entityPos);
|
||||
|
||||
// Plane equation
|
||||
float d = -Vector3.Dot(camPosition, camAtAxis);
|
||||
float p = Vector3.Dot(camAtAxis, entityPos) + d;
|
||||
if (p < 0.0f) priority *= 2.0;
|
||||
|
||||
return priority;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Child agent. Use the normal distance method
|
||||
Vector3 presencePos = presence.AbsolutePosition;
|
||||
|
||||
return Vector3.DistanceSquared(presencePos, entityPos);
|
||||
}
|
||||
}
|
||||
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
|
||||
{
|
||||
ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
// If this is an update for our own avatar give it the highest priority
|
||||
if (presence == entity)
|
||||
return 0.0;
|
||||
|
||||
// Use group position for child prims
|
||||
Vector3 entityPos = entity.AbsolutePosition;
|
||||
if (entity is SceneObjectPart)
|
||||
entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
|
||||
else
|
||||
entityPos = entity.AbsolutePosition;
|
||||
|
||||
if (!presence.IsChildAgent)
|
||||
{
|
||||
if (entity is ScenePresence)
|
||||
return 1.0;
|
||||
|
||||
// Root agent. Use distance from camera and a priority decrease for objects behind us
|
||||
Vector3 camPosition = presence.CameraPosition;
|
||||
Vector3 camAtAxis = presence.CameraAtAxis;
|
||||
|
||||
// Distance
|
||||
double priority = Vector3.DistanceSquared(camPosition, entityPos);
|
||||
|
||||
// Plane equation
|
||||
float d = -Vector3.Dot(camPosition, camAtAxis);
|
||||
float p = Vector3.Dot(camAtAxis, entityPos) + d;
|
||||
if (p < 0.0f) priority *= 2.0;
|
||||
|
||||
if (entity is SceneObjectPart)
|
||||
{
|
||||
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
|
||||
if (physActor == null || !physActor.IsPhysical)
|
||||
priority+=100;
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Child agent. Use the normal distance method
|
||||
Vector3 presencePos = presence.AbsolutePosition;
|
||||
|
||||
return Vector3.DistanceSquared(presencePos, entityPos);
|
||||
}
|
||||
}
|
||||
|
||||
return double.NaN;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,13 +58,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public partial class Scene : SceneBase
|
||||
{
|
||||
public enum UpdatePrioritizationSchemes {
|
||||
Time = 0,
|
||||
Distance = 1,
|
||||
SimpleAngularDistance = 2,
|
||||
FrontBack = 3,
|
||||
}
|
||||
|
||||
public delegate void SynchronizeSceneHandler(Scene scene);
|
||||
public SynchronizeSceneHandler SynchronizeScene = null;
|
||||
|
||||
@@ -402,12 +395,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private int m_lastUpdate;
|
||||
private bool m_firstHeartbeat = true;
|
||||
|
||||
private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
|
||||
private bool m_reprioritization_enabled = true;
|
||||
private double m_reprioritization_interval = 5000.0;
|
||||
private double m_root_reprioritization_distance = 10.0;
|
||||
private double m_child_reprioritization_distance = 20.0;
|
||||
|
||||
private object m_deleting_scene_object = new object();
|
||||
|
||||
// the minimum time that must elapse before a changed object will be considered for persisted
|
||||
@@ -415,15 +402,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// the maximum time that must elapse before a changed object will be considered for persisted
|
||||
public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
|
||||
|
||||
private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
|
||||
private bool m_reprioritizationEnabled = true;
|
||||
private double m_reprioritizationInterval = 5000.0;
|
||||
private double m_rootReprioritizationDistance = 10.0;
|
||||
private double m_childReprioritizationDistance = 20.0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
|
||||
public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } }
|
||||
public double ReprioritizationInterval { get { return m_reprioritization_interval; } }
|
||||
public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } }
|
||||
public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } }
|
||||
public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
|
||||
public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
|
||||
public double ReprioritizationInterval { get { return m_reprioritizationInterval; } }
|
||||
public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } }
|
||||
public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } }
|
||||
|
||||
public AgentCircuitManager AuthenticateHandler
|
||||
{
|
||||
@@ -625,6 +618,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
|
||||
m_asyncSceneObjectDeleter.Enabled = true;
|
||||
|
||||
#region Region Settings
|
||||
|
||||
// Load region settings
|
||||
m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
|
||||
m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
|
||||
@@ -673,6 +668,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Region Settings
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("region", false, "reload estate",
|
||||
"reload estate",
|
||||
"Reload the estate data", HandleReloadEstate);
|
||||
@@ -717,6 +714,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
|
||||
|
||||
#region Region Config
|
||||
|
||||
try
|
||||
{
|
||||
// Region config overrides global config
|
||||
@@ -770,38 +769,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
|
||||
|
||||
IConfig interest_management_config = m_config.Configs["InterestManagement"];
|
||||
if (interest_management_config != null)
|
||||
{
|
||||
string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
|
||||
switch (update_prioritization_scheme)
|
||||
{
|
||||
case "time":
|
||||
m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
|
||||
break;
|
||||
case "distance":
|
||||
m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance;
|
||||
break;
|
||||
case "simpleangulardistance":
|
||||
m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
|
||||
break;
|
||||
case "frontback":
|
||||
m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack;
|
||||
break;
|
||||
default:
|
||||
m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
|
||||
m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
|
||||
break;
|
||||
}
|
||||
|
||||
m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
|
||||
m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
|
||||
m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
|
||||
m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
|
||||
}
|
||||
|
||||
m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
|
||||
|
||||
#region BinaryStats
|
||||
|
||||
try
|
||||
@@ -838,6 +805,38 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_log.Warn("[SCENE]: Failed to load StartupConfig");
|
||||
}
|
||||
|
||||
#endregion Region Config
|
||||
|
||||
#region Interest Management
|
||||
|
||||
if (m_config != null)
|
||||
{
|
||||
IConfig interestConfig = m_config.Configs["InterestManagement"];
|
||||
if (interestConfig != null)
|
||||
{
|
||||
string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
|
||||
|
||||
try
|
||||
{
|
||||
m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
|
||||
m_priorityScheme = UpdatePrioritizationSchemes.Time;
|
||||
}
|
||||
|
||||
m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
|
||||
m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
|
||||
m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
|
||||
m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.Info("[SCENE]: Using the " + m_priorityScheme + " prioritization scheme");
|
||||
|
||||
#endregion Interest Management
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -307,61 +307,64 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
|
||||
return false;
|
||||
|
||||
bool alreadyExisted = false;
|
||||
|
||||
if (m_parentScene.m_clampPrimSize)
|
||||
{
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
Vector3 scale = part.Shape.Scale;
|
||||
|
||||
if (scale.X > m_parentScene.m_maxNonphys)
|
||||
scale.X = m_parentScene.m_maxNonphys;
|
||||
if (scale.Y > m_parentScene.m_maxNonphys)
|
||||
scale.Y = m_parentScene.m_maxNonphys;
|
||||
if (scale.Z > m_parentScene.m_maxNonphys)
|
||||
scale.Z = m_parentScene.m_maxNonphys;
|
||||
|
||||
part.Shape.Scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
sceneObject.AttachToScene(m_parentScene);
|
||||
|
||||
if (sendClientUpdates)
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
lock (sceneObject)
|
||||
{
|
||||
if (!Entities.ContainsKey(sceneObject.UUID))
|
||||
{
|
||||
if (Entities.ContainsKey(sceneObject.UUID))
|
||||
{
|
||||
Entities.Add(sceneObject);
|
||||
m_numPrim += sceneObject.Children.Count;
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.AttachToBackup();
|
||||
|
||||
if (OnObjectCreate != null)
|
||||
OnObjectCreate(sceneObject);
|
||||
|
||||
lock (m_dictionary_lock)
|
||||
// m_log.WarnFormat(
|
||||
// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request",
|
||||
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
|
||||
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
|
||||
|
||||
if (m_parentScene.m_clampPrimSize)
|
||||
{
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
|
||||
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
|
||||
}
|
||||
Vector3 scale = part.Shape.Scale;
|
||||
|
||||
if (scale.X > m_parentScene.m_maxNonphys)
|
||||
scale.X = m_parentScene.m_maxNonphys;
|
||||
if (scale.Y > m_parentScene.m_maxNonphys)
|
||||
scale.Y = m_parentScene.m_maxNonphys;
|
||||
if (scale.Z > m_parentScene.m_maxNonphys)
|
||||
scale.Z = m_parentScene.m_maxNonphys;
|
||||
|
||||
part.Shape.Scale = scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
sceneObject.AttachToScene(m_parentScene);
|
||||
|
||||
if (sendClientUpdates)
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
Entities.Add(sceneObject);
|
||||
m_numPrim += sceneObject.Children.Count;
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.AttachToBackup();
|
||||
|
||||
if (OnObjectCreate != null)
|
||||
OnObjectCreate(sceneObject);
|
||||
|
||||
lock (m_dictionary_lock)
|
||||
{
|
||||
alreadyExisted = true;
|
||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
|
||||
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alreadyExisted;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3841,107 +3841,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
SetFromItemID(uuid);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public double GetUpdatePriority(IClientAPI client)
|
||||
{
|
||||
switch (Scene.UpdatePrioritizationScheme)
|
||||
{
|
||||
case Scene.UpdatePrioritizationSchemes.Time:
|
||||
return GetPriorityByTime();
|
||||
case Scene.UpdatePrioritizationSchemes.Distance:
|
||||
return GetPriorityByDistance(client);
|
||||
case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
|
||||
return GetPriorityBySimpleAngularDistance(client);
|
||||
case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
|
||||
return GetPriorityByFrontBack(client);
|
||||
default:
|
||||
throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
|
||||
}
|
||||
}
|
||||
|
||||
private double GetPriorityByTime()
|
||||
{
|
||||
return DateTime.Now.ToOADate();
|
||||
}
|
||||
|
||||
private double GetPriorityByDistance(IClientAPI client)
|
||||
{
|
||||
ScenePresence presence = Scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
return GetPriorityByDistance((presence.IsChildAgent) ?
|
||||
presence.AbsolutePosition : presence.CameraPosition);
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private double GetPriorityBySimpleAngularDistance(IClientAPI client)
|
||||
{
|
||||
ScenePresence presence = Scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ?
|
||||
presence.AbsolutePosition : presence.CameraPosition);
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private double GetPriorityByFrontBack(IClientAPI client)
|
||||
{
|
||||
ScenePresence presence = Scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis);
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
public double GetPriorityByDistance(Vector3 position)
|
||||
{
|
||||
return Vector3.Distance(AbsolutePosition, position);
|
||||
}
|
||||
|
||||
public double GetPriorityBySimpleAngularDistance(Vector3 position)
|
||||
{
|
||||
double distance = Vector3.Distance(position, AbsolutePosition);
|
||||
if (distance >= double.Epsilon)
|
||||
{
|
||||
float height;
|
||||
Vector3 box = GetAxisAlignedBoundingBox(out height);
|
||||
|
||||
double angle = box.X / distance;
|
||||
double max = angle;
|
||||
|
||||
angle = box.Y / distance;
|
||||
if (max < angle)
|
||||
max = angle;
|
||||
|
||||
angle = box.Z / distance;
|
||||
if (max < angle)
|
||||
max = angle;
|
||||
|
||||
return -max;
|
||||
}
|
||||
else
|
||||
return double.MinValue;
|
||||
}
|
||||
|
||||
public double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis)
|
||||
{
|
||||
// Distance
|
||||
double priority = Vector3.Distance(camPosition, AbsolutePosition);
|
||||
|
||||
// Scale
|
||||
//priority -= GroupScale().Length();
|
||||
|
||||
// Plane equation
|
||||
float d = -Vector3.Dot(camPosition, camAtAxis);
|
||||
float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d;
|
||||
if (p < 0.0f) priority *= 2.0f;
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void ResetOwnerChangeFlag()
|
||||
{
|
||||
@@ -3950,5 +3849,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
part.ResetOwnerChangeFlag();
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4090,123 +4090,9 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
|
||||
}
|
||||
}
|
||||
|
||||
public double GetUpdatePriority(IClientAPI client)
|
||||
{
|
||||
switch (Scene.UpdatePrioritizationScheme)
|
||||
{
|
||||
case Scene.UpdatePrioritizationSchemes.Time:
|
||||
return GetPriorityByTime();
|
||||
case Scene.UpdatePrioritizationSchemes.Distance:
|
||||
return GetPriorityByDistance(client);
|
||||
case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
|
||||
return GetPriorityByDistance(client);
|
||||
case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
|
||||
return GetPriorityByFrontBack(client);
|
||||
default:
|
||||
throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
|
||||
}
|
||||
}
|
||||
|
||||
private double GetPriorityByTime()
|
||||
{
|
||||
return DateTime.Now.ToOADate();
|
||||
}
|
||||
|
||||
private double GetPriorityByDistance(IClientAPI client)
|
||||
{
|
||||
ScenePresence presence = Scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
return GetPriorityByDistance((presence.IsChildAgent) ?
|
||||
presence.AbsolutePosition : presence.CameraPosition);
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private double GetPriorityByFrontBack(IClientAPI client)
|
||||
{
|
||||
ScenePresence presence = Scene.GetScenePresence(client.AgentId);
|
||||
if (presence != null)
|
||||
{
|
||||
return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis);
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private double GetPriorityByDistance(Vector3 position)
|
||||
{
|
||||
return Vector3.Distance(AbsolutePosition, position);
|
||||
}
|
||||
|
||||
private double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis)
|
||||
{
|
||||
// Distance
|
||||
double priority = Vector3.Distance(camPosition, AbsolutePosition);
|
||||
|
||||
// Plane equation
|
||||
float d = -Vector3.Dot(camPosition, camAtAxis);
|
||||
float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d;
|
||||
if (p < 0.0f) priority *= 2.0f;
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
private double GetSOGUpdatePriority(SceneObjectGroup sog)
|
||||
{
|
||||
switch (Scene.UpdatePrioritizationScheme)
|
||||
{
|
||||
case Scene.UpdatePrioritizationSchemes.Time:
|
||||
throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization");
|
||||
case Scene.UpdatePrioritizationSchemes.Distance:
|
||||
return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
|
||||
case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
|
||||
return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
|
||||
case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
|
||||
return sog.GetPriorityByFrontBack(CameraPosition, CameraAtAxis);
|
||||
default:
|
||||
throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
|
||||
}
|
||||
}
|
||||
|
||||
private double UpdatePriority(UpdatePriorityData data)
|
||||
{
|
||||
EntityBase entity;
|
||||
SceneObjectGroup group;
|
||||
|
||||
if (Scene.Entities.TryGetValue(data.localID, out entity))
|
||||
{
|
||||
group = entity as SceneObjectGroup;
|
||||
if (group != null)
|
||||
return GetSOGUpdatePriority(group);
|
||||
|
||||
ScenePresence presence = entity as ScenePresence;
|
||||
if (presence == null)
|
||||
throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence");
|
||||
switch (Scene.UpdatePrioritizationScheme)
|
||||
{
|
||||
case Scene.UpdatePrioritizationSchemes.Time:
|
||||
throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization");
|
||||
case Scene.UpdatePrioritizationSchemes.Distance:
|
||||
case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
|
||||
return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
|
||||
case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
|
||||
return GetPriorityByFrontBack(CameraPosition, CameraAtAxis);
|
||||
default:
|
||||
throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
group = Scene.GetGroupByPrim(data.localID);
|
||||
if (group != null)
|
||||
return GetSOGUpdatePriority(group);
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
private void ReprioritizeUpdates()
|
||||
{
|
||||
if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time)
|
||||
if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time)
|
||||
{
|
||||
lock (m_reprioritization_timer)
|
||||
{
|
||||
@@ -4220,7 +4106,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
|
||||
|
||||
private void Reprioritize(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
m_controllingClient.ReprioritizeUpdates(UpdatePriority);
|
||||
m_controllingClient.ReprioritizeUpdates();
|
||||
|
||||
lock (m_reprioritization_timer)
|
||||
{
|
||||
|
||||
@@ -49,18 +49,62 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
/// <summary>
|
||||
/// Test adding an object to a scene.
|
||||
/// </summary>
|
||||
[Test, LongRunning]
|
||||
[Test]
|
||||
public void TestAddSceneObject()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
|
||||
|
||||
string objName = "obj1";
|
||||
UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
|
||||
|
||||
SceneObjectPart part
|
||||
= new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
|
||||
{ Name = objName, UUID = objUuid };
|
||||
|
||||
Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True);
|
||||
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
|
||||
|
||||
//m_log.Debug("retrievedPart : {0}", retrievedPart);
|
||||
// If the parts have the same UUID then we will consider them as one and the same
|
||||
Assert.That(retrievedPart.UUID, Is.EqualTo(part.UUID));
|
||||
Assert.That(retrievedPart.Name, Is.EqualTo(objName));
|
||||
Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
|
||||
}
|
||||
|
||||
[Test]
|
||||
/// <summary>
|
||||
/// It shouldn't be possible to add a scene object if one with that uuid already exists in the scene.
|
||||
/// </summary>
|
||||
public void TestAddExistingSceneObjectUuid()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
|
||||
string obj1Name = "Alfred";
|
||||
string obj2Name = "Betty";
|
||||
UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
|
||||
|
||||
SceneObjectPart part1
|
||||
= new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
|
||||
{ Name = obj1Name, UUID = objUuid };
|
||||
|
||||
Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
|
||||
|
||||
SceneObjectPart part2
|
||||
= new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
|
||||
{ Name = obj2Name, UUID = objUuid };
|
||||
|
||||
Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part2), false), Is.False);
|
||||
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
|
||||
|
||||
//m_log.Debug("retrievedPart : {0}", retrievedPart);
|
||||
// If the parts have the same UUID then we will consider them as one and the same
|
||||
Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
|
||||
Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
TestHelper.InMethod();
|
||||
|
||||
UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
|
||||
AssetBase corruptAsset = AssetHelpers.CreateAsset(corruptAssetUuid, "CORRUPT ASSET", UUID.Zero);
|
||||
AssetBase corruptAsset
|
||||
= AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero);
|
||||
m_assetService.Store(corruptAsset);
|
||||
|
||||
IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>();
|
||||
|
||||
@@ -123,8 +123,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
foreach (SceneObjectPart part in sceneObject.GetParts())
|
||||
{
|
||||
//m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -155,7 +155,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Now analyze this prim's inventory items to preserve all the uuids that they reference
|
||||
foreach (TaskInventoryItem tii in taskDictionary.Values)
|
||||
{
|
||||
//m_log.DebugFormat("[ARCHIVER]: Analysing item asset type {0}", tii.Type);
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
|
||||
// tii.Name, tii.Type, part.Name, part.UUID);
|
||||
|
||||
if (!assetUuids.ContainsKey(tii.AssetID))
|
||||
GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids);
|
||||
|
||||
Reference in New Issue
Block a user