Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
22ee1c30e3
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -71,6 +72,11 @@ namespace OpenSim.Framework.Monitoring
|
||||||
private volatile float pendingUploads;
|
private volatile float pendingUploads;
|
||||||
private volatile float activeScripts;
|
private volatile float activeScripts;
|
||||||
private volatile float scriptLinesPerSecond;
|
private volatile float scriptLinesPerSecond;
|
||||||
|
private volatile float m_frameDilation;
|
||||||
|
private volatile float m_usersLoggingIn;
|
||||||
|
private volatile float m_totalGeoPrims;
|
||||||
|
private volatile float m_totalMeshes;
|
||||||
|
private volatile float m_inUseThreads;
|
||||||
|
|
||||||
// /// <summary>
|
// /// <summary>
|
||||||
// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
|
// /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the
|
||||||
|
@ -249,6 +255,10 @@ namespace OpenSim.Framework.Monitoring
|
||||||
{
|
{
|
||||||
// FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
|
// FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original
|
||||||
// SimStatsPacket that was being used).
|
// SimStatsPacket that was being used).
|
||||||
|
|
||||||
|
// For an unknown reason the original designers decided not to
|
||||||
|
// include the spare MS statistic inside of this class, this is
|
||||||
|
// located inside the StatsBlock at location 21, thus it is skipped
|
||||||
timeDilation = stats.StatsBlock[0].StatValue;
|
timeDilation = stats.StatsBlock[0].StatValue;
|
||||||
simFps = stats.StatsBlock[1].StatValue;
|
simFps = stats.StatsBlock[1].StatValue;
|
||||||
physicsFps = stats.StatsBlock[2].StatValue;
|
physicsFps = stats.StatsBlock[2].StatValue;
|
||||||
|
@ -270,6 +280,11 @@ namespace OpenSim.Framework.Monitoring
|
||||||
pendingUploads = stats.StatsBlock[18].StatValue;
|
pendingUploads = stats.StatsBlock[18].StatValue;
|
||||||
activeScripts = stats.StatsBlock[19].StatValue;
|
activeScripts = stats.StatsBlock[19].StatValue;
|
||||||
scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
|
scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
|
||||||
|
m_frameDilation = stats.StatsBlock[22].StatValue;
|
||||||
|
m_usersLoggingIn = stats.StatsBlock[23].StatValue;
|
||||||
|
m_totalGeoPrims = stats.StatsBlock[24].StatValue;
|
||||||
|
m_totalMeshes = stats.StatsBlock[25].StatValue;
|
||||||
|
m_inUseThreads = stats.StatsBlock[26].StatValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -407,6 +422,27 @@ Asset service request failures: {3}" + Environment.NewLine,
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override OSDMap OReport(string uptime, string version)
|
public override OSDMap OReport(string uptime, string version)
|
||||||
{
|
{
|
||||||
|
// Get the amount of physical memory, allocated with the instance of this program, in kilobytes;
|
||||||
|
// the working set is the set of memory pages currently visible to this program in physical RAM
|
||||||
|
// memory and includes both shared (e.g. system libraries) and private data
|
||||||
|
double memUsage = Process.GetCurrentProcess().WorkingSet64 / 1024.0;
|
||||||
|
|
||||||
|
// Get the number of threads from the system that are currently
|
||||||
|
// running
|
||||||
|
int numberThreadsRunning = 0;
|
||||||
|
foreach (ProcessThread currentThread in
|
||||||
|
Process.GetCurrentProcess().Threads)
|
||||||
|
{
|
||||||
|
// A known issue with the current process .Threads property is
|
||||||
|
// that it can return null threads, thus don't count those as
|
||||||
|
// running threads and prevent the program function from failing
|
||||||
|
if (currentThread != null &&
|
||||||
|
currentThread.ThreadState == ThreadState.Running)
|
||||||
|
{
|
||||||
|
numberThreadsRunning++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OSDMap args = new OSDMap(30);
|
OSDMap args = new OSDMap(30);
|
||||||
// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
|
// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
|
||||||
// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
|
// args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}",
|
||||||
|
@ -444,6 +480,22 @@ Asset service request failures: {3}" + Environment.NewLine,
|
||||||
args["Uptime"] = OSD.FromString (uptime);
|
args["Uptime"] = OSD.FromString (uptime);
|
||||||
args["Version"] = OSD.FromString (version);
|
args["Version"] = OSD.FromString (version);
|
||||||
|
|
||||||
|
args["FrameDilatn"] = OSD.FromString(String.Format("{0:0.##}", m_frameDilation));
|
||||||
|
args["Logging in Users"] = OSD.FromString(String.Format("{0:0.##}",
|
||||||
|
m_usersLoggingIn));
|
||||||
|
args["GeoPrims"] = OSD.FromString(String.Format("{0:0.##}",
|
||||||
|
m_totalGeoPrims));
|
||||||
|
args["Mesh Objects"] = OSD.FromString(String.Format("{0:0.##}",
|
||||||
|
m_totalMeshes));
|
||||||
|
args["XEngine Thread Count"] = OSD.FromString(String.Format("{0:0.##}",
|
||||||
|
m_inUseThreads));
|
||||||
|
args["Util Thread Count"] = OSD.FromString(String.Format("{0:0.##}",
|
||||||
|
Util.GetSmartThreadPoolInfo().InUseThreads));
|
||||||
|
args["System Thread Count"] = OSD.FromString(String.Format(
|
||||||
|
"{0:0.##}", numberThreadsRunning));
|
||||||
|
args["ProcMem"] = OSD.FromString(String.Format("{0:#,###,###.##}",
|
||||||
|
memUsage));
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,11 +292,11 @@ namespace OpenSim.Framework.Servers
|
||||||
+ " 3 = full stack trace, including common threads\n",
|
+ " 3 = full stack trace, including common threads\n",
|
||||||
HandleDebugThreadpoolLevel);
|
HandleDebugThreadpoolLevel);
|
||||||
|
|
||||||
m_console.Commands.AddCommand(
|
// m_console.Commands.AddCommand(
|
||||||
"Debug", false, "show threadpool calls active",
|
// "Debug", false, "show threadpool calls active",
|
||||||
"show threadpool calls active",
|
// "show threadpool calls active",
|
||||||
"Show details about threadpool calls that are still active (currently waiting or in progress)",
|
// "Show details about threadpool calls that are still active (currently waiting or in progress)",
|
||||||
HandleShowThreadpoolCallsActive);
|
// HandleShowThreadpoolCallsActive);
|
||||||
|
|
||||||
m_console.Commands.AddCommand(
|
m_console.Commands.AddCommand(
|
||||||
"Debug", false, "show threadpool calls complete",
|
"Debug", false, "show threadpool calls complete",
|
||||||
|
|
|
@ -3747,6 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
avp.Sender.IsTrial = false;
|
avp.Sender.IsTrial = false;
|
||||||
avp.Sender.ID = agentID;
|
avp.Sender.ID = agentID;
|
||||||
avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0];
|
avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0];
|
||||||
|
avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0];
|
||||||
//m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
|
//m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
|
||||||
OutPacket(avp, ThrottleOutPacketType.Task);
|
OutPacket(avp, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
|
@ -726,6 +726,21 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
"Show the bindings between user UUIDs and user names",
|
"Show the bindings between user UUIDs and user names",
|
||||||
String.Empty,
|
String.Empty,
|
||||||
HandleShowUsers);
|
HandleShowUsers);
|
||||||
|
|
||||||
|
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||||
|
"reset user cache",
|
||||||
|
"reset user cache",
|
||||||
|
"reset user cache to allow changed settings to be applied",
|
||||||
|
String.Empty,
|
||||||
|
HandleResetUserCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleResetUserCache(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
lock(m_UserCache)
|
||||||
|
{
|
||||||
|
m_UserCache.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleShowUser(string module, string[] cmd)
|
private void HandleShowUser(string module, string[] cmd)
|
||||||
|
|
|
@ -62,6 +62,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
|
private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
|
||||||
private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
|
private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
|
||||||
|
|
||||||
|
public const int m_defaultNumberFramesStored = 10;
|
||||||
|
|
||||||
public delegate void SynchronizeSceneHandler(Scene scene);
|
public delegate void SynchronizeSceneHandler(Scene scene);
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
|
@ -267,7 +269,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public float DefaultDrawDistance
|
public float DefaultDrawDistance
|
||||||
{
|
{
|
||||||
// get { return m_defaultDrawDistance; }
|
// get { return m_defaultDrawDistance; }
|
||||||
get {
|
get
|
||||||
|
{
|
||||||
if (RegionInfo != null)
|
if (RegionInfo != null)
|
||||||
{
|
{
|
||||||
float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
|
float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
|
||||||
|
@ -454,6 +457,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private string m_defaultScriptEngine;
|
private string m_defaultScriptEngine;
|
||||||
|
|
||||||
|
private int m_unixStartTime;
|
||||||
|
public int UnixStartTime
|
||||||
|
{
|
||||||
|
get { return m_unixStartTime; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tick at which the last login occurred.
|
/// Tick at which the last login occurred.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -526,6 +535,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
get { return m_sceneGraph.PhysicsScene.TimeDilation; }
|
get { return m_sceneGraph.PhysicsScene.TimeDilation; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setThreadCount(int inUseThreads)
|
||||||
|
{
|
||||||
|
// Just pass the thread count information on its way as the Scene
|
||||||
|
// does not require the value for anything at this time
|
||||||
|
StatsReporter.SetThreadCount(inUseThreads);
|
||||||
|
}
|
||||||
|
|
||||||
public SceneCommunicationService SceneGridService
|
public SceneCommunicationService SceneGridService
|
||||||
{
|
{
|
||||||
get { return m_sceneGridService; }
|
get { return m_sceneGridService; }
|
||||||
|
@ -793,12 +809,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// can be closest/random/sequence
|
// can be closest/random/sequence
|
||||||
public string SpawnPointRouting
|
public string SpawnPointRouting
|
||||||
{
|
{
|
||||||
get; private set;
|
get;
|
||||||
|
private set;
|
||||||
}
|
}
|
||||||
// allow landmarks to pass
|
// allow landmarks to pass
|
||||||
public bool TelehubAllowLandmarks
|
public bool TelehubAllowLandmarks
|
||||||
{
|
{
|
||||||
get; private set;
|
get;
|
||||||
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
@ -1107,6 +1125,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion Interest Management
|
#endregion Interest Management
|
||||||
|
|
||||||
|
// The timer used by the Stopwatch class depends on the system hardware and operating system; inform
|
||||||
|
// if the timer is based on a high-resolution performance counter or based on the system timer;
|
||||||
|
// the performance counter will provide a more precise time than the system timer
|
||||||
|
if (Stopwatch.IsHighResolution)
|
||||||
|
m_log.InfoFormat("[SCENE]: Using high-resolution performance counter for statistics.");
|
||||||
|
else
|
||||||
|
m_log.InfoFormat("[SCENE]: Using system timer for statistics.");
|
||||||
|
|
||||||
// Acquire the statistics section of the OpenSim.ini file located
|
// Acquire the statistics section of the OpenSim.ini file located
|
||||||
// in the bin directory
|
// in the bin directory
|
||||||
IConfig statisticsConfig = m_config.Configs["Statistics"];
|
IConfig statisticsConfig = m_config.Configs["Statistics"];
|
||||||
|
@ -1119,7 +1145,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// for the frame time statistics, or 10 frames if the config
|
// for the frame time statistics, or 10 frames if the config
|
||||||
// file doesn't contain a value
|
// file doesn't contain a value
|
||||||
StatsReporter = new SimStatsReporter(this,
|
StatsReporter = new SimStatsReporter(this,
|
||||||
statisticsConfig.GetInt("NumberOfFrames", 10));
|
statisticsConfig.GetInt("NumberOfFrames",
|
||||||
|
m_defaultNumberFramesStored));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1133,7 +1160,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scene(RegionInfo regInfo, PhysicsScene physicsScene) : base(regInfo)
|
public Scene(RegionInfo regInfo, PhysicsScene physicsScene)
|
||||||
|
: base(regInfo)
|
||||||
{
|
{
|
||||||
m_sceneGraph = new SceneGraph(this);
|
m_sceneGraph = new SceneGraph(this);
|
||||||
m_sceneGraph.PhysicsScene = physicsScene;
|
m_sceneGraph.PhysicsScene = physicsScene;
|
||||||
|
@ -1439,6 +1467,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_isRunning = true;
|
m_isRunning = true;
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
|
||||||
|
m_unixStartTime = Util.UnixTimeSinceEpoch();
|
||||||
// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
|
// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
|
||||||
if (m_heartbeatThread != null)
|
if (m_heartbeatThread != null)
|
||||||
{
|
{
|
||||||
|
@ -1667,7 +1696,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// at this point in time, the precise values all begin
|
// at this point in time, the precise values all begin
|
||||||
// with the keyword precise
|
// with the keyword precise
|
||||||
tmpMS = Util.EnvironmentTickCount();
|
tmpMS = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
simFrameStopwatch.Start();
|
simFrameStopwatch.Start();
|
||||||
UpdateTerrain();
|
UpdateTerrain();
|
||||||
|
|
||||||
|
@ -1679,6 +1707,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
terrainMS = Util.EnvironmentTickCountSubtract(tmpMS);
|
terrainMS = Util.EnvironmentTickCountSubtract(tmpMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At several points inside the code there was a need to
|
||||||
|
// create a more precise measurement of time elapsed. This
|
||||||
|
// led to the addition of variables that have a similar
|
||||||
|
// function and thus remain tightly connected to their
|
||||||
|
// original counterparts. However, the original code is
|
||||||
|
// not receiving comments from our group because we don't
|
||||||
|
// feel right modifying the code to that degree at this
|
||||||
|
// point in time, the precise values all begin with the
|
||||||
|
// keyword precise
|
||||||
|
|
||||||
tmpMS = Util.EnvironmentTickCount();
|
tmpMS = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
// Begin the stopwatch to track the time to prepare physics
|
// Begin the stopwatch to track the time to prepare physics
|
||||||
|
@ -1692,8 +1730,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// enabled will report the time it took to check if physics
|
// enabled will report the time it took to check if physics
|
||||||
// was enabled
|
// was enabled
|
||||||
physicsFrameStopwatch.Stop();
|
physicsFrameStopwatch.Stop();
|
||||||
precisePhysicsFrameTime =
|
precisePhysicsFrameTime = physicsFrameStopwatch.Elapsed.TotalMilliseconds;
|
||||||
physicsFrameStopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS);
|
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS);
|
||||||
|
|
||||||
// Apply any pending avatar force input to the avatar's velocity
|
// Apply any pending avatar force input to the avatar's velocity
|
||||||
|
@ -1722,11 +1759,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SynchronizeScene(this);
|
SynchronizeScene(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the main physics update time to the prepare physics
|
// Add the main physics update time to the prepare physics time
|
||||||
// time
|
|
||||||
physicsFrameStopwatch.Stop();
|
physicsFrameStopwatch.Stop();
|
||||||
precisePhysicsFrameTime +=
|
precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds;
|
||||||
physicsFrameStopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
physicsMS = Util.EnvironmentTickCountSubtract(tmpMS);
|
physicsMS = Util.EnvironmentTickCountSubtract(tmpMS);
|
||||||
|
|
||||||
// Start the stopwatch for the remainder of the simulation
|
// Start the stopwatch for the remainder of the simulation
|
||||||
|
@ -1884,6 +1919,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
RegionInfo.RegionName);
|
RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finished updating scene frame, so stop the total frame's Stopwatch
|
||||||
|
totalFrameStopwatch.Stop();
|
||||||
|
|
||||||
return spareMS >= 0;
|
return spareMS >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2804,6 +2842,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
bool vialogin;
|
bool vialogin;
|
||||||
bool reallyNew = true;
|
bool reallyNew = true;
|
||||||
|
|
||||||
|
// Update the number of users attempting to login
|
||||||
|
StatsReporter.UpdateUsersLoggingIn(true);
|
||||||
|
|
||||||
// Validation occurs in LLUDPServer
|
// Validation occurs in LLUDPServer
|
||||||
//
|
//
|
||||||
// XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
|
// XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
|
||||||
|
@ -2888,6 +2929,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
EventManager.TriggerOnClientLogin(client);
|
EventManager.TriggerOnClientLogin(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User has logged into the scene so update the list of users logging
|
||||||
|
// in
|
||||||
|
StatsReporter.UpdateUsersLoggingIn(false);
|
||||||
|
|
||||||
m_LastLogin = Util.EnvironmentTickCount();
|
m_LastLogin = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
|
|
|
@ -67,7 +67,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected Scene m_parentScene;
|
protected Scene m_parentScene;
|
||||||
protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
|
protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
|
||||||
protected int m_numRootAgents = 0;
|
protected int m_numRootAgents = 0;
|
||||||
|
protected int m_numTotalPrim = 0;
|
||||||
protected int m_numPrim = 0;
|
protected int m_numPrim = 0;
|
||||||
|
protected int m_numMesh = 0;
|
||||||
protected int m_numChildAgents = 0;
|
protected int m_numChildAgents = 0;
|
||||||
protected int m_physicalPrim = 0;
|
protected int m_physicalPrim = 0;
|
||||||
|
|
||||||
|
@ -368,7 +370,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
SceneObjectPart[] parts = sceneObject.Parts;
|
SceneObjectPart[] parts = sceneObject.Parts;
|
||||||
|
|
||||||
// Clamp child prim sizes and add child prims to the m_numPrim count
|
// Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives
|
||||||
|
// (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count
|
||||||
if (m_parentScene.m_clampPrimSize)
|
if (m_parentScene.m_clampPrimSize)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
|
@ -382,7 +385,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.Shape.Scale = scale;
|
part.Shape.Scale = scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_numPrim += parts.Length;
|
m_numTotalPrim += parts.Length;
|
||||||
|
|
||||||
|
// Go through all parts (geometric primitives and meshes) of this Scene Object
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
|
{
|
||||||
|
// Keep track of the total number of meshes or geometric primitives now in the scene;
|
||||||
|
// determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
|
||||||
|
// a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
|
||||||
|
if (part.GetPrimType() == PrimType.SCULPT)
|
||||||
|
m_numMesh++;
|
||||||
|
else
|
||||||
|
m_numPrim++;
|
||||||
|
}
|
||||||
|
|
||||||
sceneObject.AttachToScene(m_parentScene);
|
sceneObject.AttachToScene(m_parentScene);
|
||||||
|
|
||||||
|
@ -437,7 +452,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (!resultOfObjectLinked)
|
if (!resultOfObjectLinked)
|
||||||
{
|
{
|
||||||
m_numPrim -= grp.PrimCount;
|
// Decrement the total number of primitives (meshes and geometric primitives)
|
||||||
|
// that are part of the Scene Object being removed
|
||||||
|
m_numTotalPrim -= grp.PrimCount;
|
||||||
|
|
||||||
|
// Go through all parts (primitives and meshes) of this Scene Object
|
||||||
|
foreach (SceneObjectPart part in grp.Parts)
|
||||||
|
{
|
||||||
|
// Keep track of the total number of meshes or geometric primitives left in the scene;
|
||||||
|
// determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
|
||||||
|
// a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
|
||||||
|
if (part.GetPrimType() == PrimType.SCULPT)
|
||||||
|
m_numMesh--;
|
||||||
|
else
|
||||||
|
m_numPrim--;
|
||||||
|
}
|
||||||
|
|
||||||
if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||||
RemovePhysicalPrim(grp.PrimCount);
|
RemovePhysicalPrim(grp.PrimCount);
|
||||||
|
@ -686,10 +715,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetTotalObjectsCount()
|
public int GetTotalObjectsCount()
|
||||||
|
{
|
||||||
|
return m_numTotalPrim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetTotalPrimObjectsCount()
|
||||||
{
|
{
|
||||||
return m_numPrim;
|
return m_numPrim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetTotalMeshObjectsCount()
|
||||||
|
{
|
||||||
|
return m_numMesh;
|
||||||
|
}
|
||||||
|
|
||||||
public int GetActiveObjectsCount()
|
public int GetActiveObjectsCount()
|
||||||
{
|
{
|
||||||
return m_physicalPrim;
|
return m_physicalPrim;
|
||||||
|
@ -1970,7 +2009,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// think it's selected, so it will never send a deselect...
|
// think it's selected, so it will never send a deselect...
|
||||||
copy.IsSelected = false;
|
copy.IsSelected = false;
|
||||||
|
|
||||||
m_numPrim += copy.Parts.Length;
|
m_numTotalPrim += copy.Parts.Length;
|
||||||
|
|
||||||
|
// Go through all parts (primitives and meshes) of this Scene Object
|
||||||
|
foreach (SceneObjectPart part in copy.Parts)
|
||||||
|
{
|
||||||
|
// Keep track of the total number of meshes or geometric primitives now in the scene;
|
||||||
|
// determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
|
||||||
|
// a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
|
||||||
|
if (part.GetPrimType() == PrimType.SCULPT)
|
||||||
|
m_numMesh++;
|
||||||
|
else
|
||||||
|
m_numPrim++;
|
||||||
|
}
|
||||||
|
|
||||||
if (rot != Quaternion.Identity)
|
if (rot != Quaternion.Identity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2672,20 +2672,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//NonPhysicalGrabMovement(pos);
|
NonPhysicalGrabMovement(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//NonPhysicalGrabMovement(pos);
|
NonPhysicalGrabMovement(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply possition for grabbing non-physical linksets (Ctrl+Drag)
|
||||||
|
/// This MUST be blocked for linksets that contain touch scripts because the viewer triggers grab on the touch
|
||||||
|
/// event (Viewer Bug?) This would allow anyone to drag a linkset with a touch script. SL behaviour is also to
|
||||||
|
/// block grab on prims with touch events.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos">New Position</param>
|
||||||
public void NonPhysicalGrabMovement(Vector3 pos)
|
public void NonPhysicalGrabMovement(Vector3 pos)
|
||||||
{
|
{
|
||||||
AbsolutePosition = pos;
|
if(!IsAttachment && ScriptCount() == 0)
|
||||||
m_rootPart.SendTerseUpdateToAllClients();
|
UpdateGroupPosition(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -2781,16 +2788,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//NonPhysicalSpinMovement(pos);
|
NonPhysicalSpinMovement(newOrientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//NonPhysicalSpinMovement(pos);
|
NonPhysicalSpinMovement(newOrientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply rotation for spinning non-physical linksets (Ctrl+Shift+Drag)
|
||||||
|
/// As with dragging, scripted objects must be blocked from spinning
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newOrientation">New Rotation</param>
|
||||||
|
private void NonPhysicalSpinMovement(Quaternion newOrientation)
|
||||||
|
{
|
||||||
|
if(!IsAttachment && ScriptCount() == 0)
|
||||||
|
UpdateGroupRotationR(newOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the name of a prim
|
/// Set the name of a prim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -61,6 +61,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private YourStatsAreWrong handlerStatsIncorrect;
|
private YourStatsAreWrong handlerStatsIncorrect;
|
||||||
|
|
||||||
|
// Determines the size of the array that is used to collect StatBlocks
|
||||||
|
// for sending to the SimStats and SimExtraStatsCollector
|
||||||
|
private const int m_statisticArraySize = 27;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// These are the IDs of stats sent in the StatsPacket to the viewer.
|
/// These are the IDs of stats sent in the StatsPacket to the viewer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -104,7 +108,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScriptEps = 31,
|
ScriptEps = 31,
|
||||||
SimSpareMs = 32,
|
SimSpareMs = 32,
|
||||||
SimSleepMs = 33,
|
SimSleepMs = 33,
|
||||||
SimIoPumpTime = 34
|
SimIoPumpTime = 34,
|
||||||
|
FrameDilation = 35,
|
||||||
|
UsersLoggingIn = 36,
|
||||||
|
TotalGeoPrim = 37,
|
||||||
|
TotalMesh = 38,
|
||||||
|
ThreadCount = 39
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -175,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// saved last reported value so there is something available for llGetRegionFPS
|
// saved last reported value so there is something available for llGetRegionFPS
|
||||||
private float lastReportedSimFPS;
|
private float lastReportedSimFPS;
|
||||||
private float[] lastReportedSimStats = new float[22];
|
private float[] lastReportedSimStats = new float[m_statisticArraySize];
|
||||||
private float m_pfps;
|
private float m_pfps;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -202,6 +211,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private int m_rootAgents;
|
private int m_rootAgents;
|
||||||
private int m_childAgents;
|
private int m_childAgents;
|
||||||
private int m_numPrim;
|
private int m_numPrim;
|
||||||
|
private int m_numGeoPrim;
|
||||||
|
private int m_numMesh;
|
||||||
private int m_inPacketsPerSecond;
|
private int m_inPacketsPerSecond;
|
||||||
private int m_outPacketsPerSecond;
|
private int m_outPacketsPerSecond;
|
||||||
private int m_activePrim;
|
private int m_activePrim;
|
||||||
|
@ -217,7 +228,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// the Total, Simulation, Physics, and Network Frame Time; It is set to
|
// the Total, Simulation, Physics, and Network Frame Time; It is set to
|
||||||
// 10 by default but can be changed by the OpenSim.ini configuration file
|
// 10 by default but can be changed by the OpenSim.ini configuration file
|
||||||
// NumberOfFrames parameter
|
// NumberOfFrames parameter
|
||||||
private int m_numberFramesStored = 10;
|
private int m_numberFramesStored = Scene.m_defaultNumberFramesStored;
|
||||||
|
|
||||||
// The arrays that will hold the time it took to run the past N frames,
|
// The arrays that will hold the time it took to run the past N frames,
|
||||||
// where N is the num_frames_to_average given by the configuration file
|
// where N is the num_frames_to_average given by the configuration file
|
||||||
|
@ -234,6 +245,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// update for physics
|
// update for physics
|
||||||
private int m_numberPhysicsFrames;
|
private int m_numberPhysicsFrames;
|
||||||
|
|
||||||
|
// The current number of users attempting to login to the region
|
||||||
|
private int m_usersLoggingIn;
|
||||||
|
|
||||||
|
// The last reported value of threads from the SmartThreadPool inside of
|
||||||
|
// XEngine
|
||||||
|
private int m_inUseThreads;
|
||||||
|
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
|
|
||||||
private RegionInfo ReportingRegion;
|
private RegionInfo ReportingRegion;
|
||||||
|
@ -246,11 +264,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
// Initialize the different frame time arrays to the correct sizes
|
// Initialize the different frame time arrays to the correct sizes
|
||||||
m_totalFrameTimeMilliseconds = new double[m_numberFramesStored];
|
m_totalFrameTimeMilliseconds = new double[m_numberFramesStored];
|
||||||
m_simulationFrameTimeMilliseconds = new
|
m_simulationFrameTimeMilliseconds = new double[m_numberFramesStored];
|
||||||
double[m_numberFramesStored];
|
|
||||||
m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored];
|
m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored];
|
||||||
m_networkFrameTimeMilliseconds = new double[m_numberFramesStored];
|
m_networkFrameTimeMilliseconds = new double[m_numberFramesStored];
|
||||||
|
|
||||||
|
// Initialize the current number of users logging into the region
|
||||||
|
m_usersLoggingIn = 0;
|
||||||
|
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
|
m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
|
||||||
m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
|
m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
|
||||||
|
@ -284,13 +304,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
StatsManager.RegisterStat(SlowFramesStat);
|
StatsManager.RegisterStat(SlowFramesStat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene)
|
public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene)
|
||||||
{
|
{
|
||||||
// Store the number of frames from the OpenSim.ini configuration
|
// Store the number of frames from the OpenSim.ini configuration file
|
||||||
// file
|
|
||||||
m_numberFramesStored = numberOfFrames;
|
m_numberFramesStored = numberOfFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
m_report.Elapsed -= TriggerStatsHeartbeat;
|
m_report.Elapsed -= TriggerStatsHeartbeat;
|
||||||
|
@ -328,11 +349,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
double simulationSumFrameTime;
|
double simulationSumFrameTime;
|
||||||
double physicsSumFrameTime;
|
double physicsSumFrameTime;
|
||||||
double networkSumFrameTime;
|
double networkSumFrameTime;
|
||||||
|
float frameDilation;
|
||||||
|
int currentFrame;
|
||||||
|
|
||||||
if (!m_scene.Active)
|
if (!m_scene.Active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22];
|
// Create arrays to hold the statistics for this current scene,
|
||||||
|
// these will be passed to the SimExtraStatsCollector, they are also
|
||||||
|
// sent to the SimStats class
|
||||||
|
SimStatsPacket.StatBlock[] sb = new
|
||||||
|
SimStatsPacket.StatBlock[m_statisticArraySize];
|
||||||
SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
|
SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
|
||||||
|
|
||||||
// Know what's not thread safe in Mono... modifying timers.
|
// Know what's not thread safe in Mono... modifying timers.
|
||||||
|
@ -381,6 +408,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
|
m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
|
||||||
m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
|
m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
|
||||||
m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
|
m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
|
||||||
|
m_numGeoPrim = m_scene.SceneGraph.GetTotalPrimObjectsCount();
|
||||||
|
m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount();
|
||||||
m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
|
m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
|
||||||
m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
|
m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
|
||||||
|
|
||||||
|
@ -406,7 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (framesUpdated == 0)
|
if (framesUpdated == 0)
|
||||||
framesUpdated = 1;
|
framesUpdated = 1;
|
||||||
|
|
||||||
for (int i = 0; i < 22; i++)
|
for (int i = 0; i < m_statisticArraySize; i++)
|
||||||
{
|
{
|
||||||
sb[i] = new SimStatsPacket.StatBlock();
|
sb[i] = new SimStatsPacket.StatBlock();
|
||||||
}
|
}
|
||||||
|
@ -431,6 +460,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
networkSumFrameTime += m_networkFrameTimeMilliseconds[i];
|
networkSumFrameTime += m_networkFrameTimeMilliseconds[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the index that represents the current frame based on the next one known; go back
|
||||||
|
// to the last index if next one is stated to restart at 0
|
||||||
|
if (m_nextLocation == 0)
|
||||||
|
currentFrame = m_numberFramesStored - 1;
|
||||||
|
else
|
||||||
|
currentFrame = m_nextLocation - 1;
|
||||||
|
|
||||||
|
// Calculate the frame dilation; which is currently based on the ratio between the sum of the
|
||||||
|
// physics and simulation rate, and the set minimum time to run a scene's frame
|
||||||
|
frameDilation = (float)(m_simulationFrameTimeMilliseconds[currentFrame] +
|
||||||
|
m_physicsFrameTimeMilliseconds[currentFrame]) / m_scene.MinFrameTicks;
|
||||||
|
|
||||||
|
// ORIGINAL code commented out until we have time to add our own
|
||||||
sb[0].StatID = (uint) Stats.TimeDilation;
|
sb[0].StatID = (uint) Stats.TimeDilation;
|
||||||
sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
|
sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
|
||||||
|
|
||||||
|
@ -459,18 +501,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// statistics to the statistics window
|
// statistics to the statistics window
|
||||||
sb[8].StatID = (uint)Stats.FrameMS;
|
sb[8].StatID = (uint)Stats.FrameMS;
|
||||||
//sb[8].StatValue = m_frameMS / framesUpdated;
|
//sb[8].StatValue = m_frameMS / framesUpdated;
|
||||||
sb[8].StatValue = (float) totalSumFrameTime /
|
sb[8].StatValue = (float) totalSumFrameTime / m_numberFramesStored;
|
||||||
m_numberFramesStored;
|
|
||||||
|
|
||||||
sb[9].StatID = (uint)Stats.NetMS;
|
sb[9].StatID = (uint)Stats.NetMS;
|
||||||
//sb[9].StatValue = m_netMS / framesUpdated;
|
//sb[9].StatValue = m_netMS / framesUpdated;
|
||||||
sb[9].StatValue = (float) networkSumFrameTime /
|
sb[9].StatValue = (float) networkSumFrameTime / m_numberFramesStored;
|
||||||
m_numberFramesStored;
|
|
||||||
|
|
||||||
sb[10].StatID = (uint)Stats.PhysicsMS;
|
sb[10].StatID = (uint)Stats.PhysicsMS;
|
||||||
//sb[10].StatValue = m_physicsMS / framesUpdated;
|
//sb[10].StatValue = m_physicsMS / framesUpdated;
|
||||||
sb[10].StatValue = (float) physicsSumFrameTime /
|
sb[10].StatValue = (float) physicsSumFrameTime / m_numberFramesStored;
|
||||||
m_numberFramesStored;
|
|
||||||
|
|
||||||
sb[11].StatID = (uint)Stats.ImageMS ;
|
sb[11].StatID = (uint)Stats.ImageMS ;
|
||||||
sb[11].StatValue = m_imageMS / framesUpdated;
|
sb[11].StatValue = m_imageMS / framesUpdated;
|
||||||
|
@ -507,7 +546,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sb[21].StatID = (uint)Stats.SimSpareMs;
|
sb[21].StatID = (uint)Stats.SimSpareMs;
|
||||||
sb[21].StatValue = m_spareMS / framesUpdated;
|
sb[21].StatValue = m_spareMS / framesUpdated;
|
||||||
|
|
||||||
for (int i = 0; i < 22; i++)
|
// Current ratio between the sum of physics and sim rate, and the
|
||||||
|
// minimum time to run a scene's frame
|
||||||
|
sb[22].StatID = (uint)Stats.FrameDilation;
|
||||||
|
sb[22].StatValue = frameDilation;
|
||||||
|
|
||||||
|
// Current number of users currently attemptint to login to region
|
||||||
|
sb[23].StatID = (uint)Stats.UsersLoggingIn;
|
||||||
|
sb[23].StatValue = m_usersLoggingIn;
|
||||||
|
|
||||||
|
// Total number of geometric primitives in the scene
|
||||||
|
sb[24].StatID = (uint)Stats.TotalGeoPrim;
|
||||||
|
sb[24].StatValue = m_numGeoPrim;
|
||||||
|
|
||||||
|
// Total number of mesh objects in the scene
|
||||||
|
sb[25].StatID = (uint)Stats.TotalMesh;
|
||||||
|
sb[25].StatValue = m_numMesh;
|
||||||
|
|
||||||
|
// Current number of threads that XEngine is using
|
||||||
|
sb[26].StatID = (uint)Stats.ThreadCount;
|
||||||
|
sb[26].StatValue = m_inUseThreads;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_statisticArraySize; i++)
|
||||||
{
|
{
|
||||||
lastReportedSimStats[i] = sb[i].StatValue;
|
lastReportedSimStats[i] = sb[i].StatValue;
|
||||||
}
|
}
|
||||||
|
@ -734,6 +794,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AddunAckedBytes(unAckedBytes);
|
AddunAckedBytes(unAckedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateUsersLoggingIn(bool isLoggingIn)
|
||||||
|
{
|
||||||
|
// Determine whether the user has started logging in or has completed
|
||||||
|
// logging into the region
|
||||||
|
if (isLoggingIn)
|
||||||
|
{
|
||||||
|
// The user is starting to login to the region so increment the
|
||||||
|
// number of users attempting to login to the region
|
||||||
|
m_usersLoggingIn++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The user has finished logging into the region so decrement the
|
||||||
|
// number of users logging into the region
|
||||||
|
m_usersLoggingIn--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetThreadCount(int inUseThreads)
|
||||||
|
{
|
||||||
|
// Save the new number of threads to our member variable to send to
|
||||||
|
// the extra stats collector
|
||||||
|
m_inUseThreads = inUseThreads;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public Dictionary<string, float> GetExtraSimStats()
|
public Dictionary<string, float> GetExtraSimStats()
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Runtime.Remoting.Lifetime;
|
using System.Runtime.Remoting.Lifetime;
|
||||||
|
@ -221,15 +222,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
protected float m_primSafetyCoeffX = 2.414214f;
|
protected float m_primSafetyCoeffX = 2.414214f;
|
||||||
protected float m_primSafetyCoeffY = 2.414214f;
|
protected float m_primSafetyCoeffY = 2.414214f;
|
||||||
protected float m_primSafetyCoeffZ = 1.618034f;
|
protected float m_primSafetyCoeffZ = 1.618034f;
|
||||||
protected float m_floatToleranceInCastRay = 0.000001f;
|
protected bool m_useCastRayV3 = false;
|
||||||
protected float m_floatTolerance2InCastRay = 0.0001f;
|
protected float m_floatToleranceInCastRay = 0.00001f;
|
||||||
|
protected float m_floatTolerance2InCastRay = 0.001f;
|
||||||
|
protected DetailLevel m_primLodInCastRay = DetailLevel.Medium;
|
||||||
|
protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium;
|
||||||
|
protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest;
|
||||||
|
protected DetailLevel m_avatarLodInCastRay = DetailLevel.Medium;
|
||||||
protected int m_maxHitsInCastRay = 16;
|
protected int m_maxHitsInCastRay = 16;
|
||||||
protected int m_maxHitsPerPrimInCastRay = 16;
|
protected int m_maxHitsPerPrimInCastRay = 16;
|
||||||
protected int m_maxHitsPerObjectInCastRay = 16;
|
protected int m_maxHitsPerObjectInCastRay = 16;
|
||||||
protected bool m_detectExitsInCastRay = false;
|
protected bool m_detectExitsInCastRay = false;
|
||||||
protected bool m_filterPartsInCastRay = false;
|
protected bool m_filterPartsInCastRay = false;
|
||||||
protected bool m_doAttachmentsInCastRay = false;
|
protected bool m_doAttachmentsInCastRay = false;
|
||||||
protected bool m_useCastRayV1 = true;
|
protected int m_msThrottleInCastRay = 200;
|
||||||
|
protected int m_msPerRegionInCastRay = 40;
|
||||||
|
protected int m_msPerAvatarInCastRay = 10;
|
||||||
|
protected int m_msMinInCastRay = 2;
|
||||||
|
protected int m_msMaxInCastRay = 40;
|
||||||
|
protected static List<CastRayCall> m_castRayCalls = new List<CastRayCall>();
|
||||||
|
protected bool m_useMeshCacheInCastRay = true;
|
||||||
|
protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>();
|
||||||
|
|
||||||
//An array of HTTP/1.1 headers that are not allowed to be used
|
//An array of HTTP/1.1 headers that are not allowed to be used
|
||||||
//as custom headers by llHTTPRequest.
|
//as custom headers by llHTTPRequest.
|
||||||
|
@ -336,15 +349,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX);
|
m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX);
|
||||||
m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY);
|
m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY);
|
||||||
m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ);
|
m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ);
|
||||||
|
m_useCastRayV3 = lslConfig.GetBoolean("UseLlCastRayV3", m_useCastRayV3);
|
||||||
m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay);
|
m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay);
|
||||||
m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay);
|
m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay);
|
||||||
|
m_primLodInCastRay = (DetailLevel)lslConfig.GetInt("PrimDetailLevelInLlCastRay", (int)m_primLodInCastRay);
|
||||||
|
m_sculptLodInCastRay = (DetailLevel)lslConfig.GetInt("SculptDetailLevelInLlCastRay", (int)m_sculptLodInCastRay);
|
||||||
|
m_meshLodInCastRay = (DetailLevel)lslConfig.GetInt("MeshDetailLevelInLlCastRay", (int)m_meshLodInCastRay);
|
||||||
|
m_avatarLodInCastRay = (DetailLevel)lslConfig.GetInt("AvatarDetailLevelInLlCastRay", (int)m_avatarLodInCastRay);
|
||||||
m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay);
|
m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay);
|
||||||
m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay);
|
m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay);
|
||||||
m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay);
|
m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay);
|
||||||
m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay);
|
m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay);
|
||||||
m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay);
|
m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay);
|
||||||
m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay);
|
m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay);
|
||||||
m_useCastRayV1 = lslConfig.GetBoolean("UseLlCastRayV1", m_useCastRayV1);
|
m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay);
|
||||||
|
m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay);
|
||||||
|
m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay);
|
||||||
|
m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay);
|
||||||
|
m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay);
|
||||||
|
m_useMeshCacheInCastRay = lslConfig.GetBoolean("UseMeshCacheInLlCastRay", m_useMeshCacheInCastRay);
|
||||||
}
|
}
|
||||||
|
|
||||||
IConfig smtpConfig = seConfigSource.Configs["SMTP"];
|
IConfig smtpConfig = seConfigSource.Configs["SMTP"];
|
||||||
|
@ -5777,7 +5800,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public LSL_String llGetEnv(LSL_String name)
|
public LSL_String llGetEnv(LSL_String name)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
if (name == "dynamic_pathfinding")
|
if (name == "agent_limit")
|
||||||
|
{
|
||||||
|
return World.RegionInfo.RegionSettings.AgentLimit.ToString();
|
||||||
|
}
|
||||||
|
else if (name == "dynamic_pathfinding")
|
||||||
{
|
{
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
@ -5785,14 +5812,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
return World.RegionInfo.EstateSettings.EstateID.ToString();
|
return World.RegionInfo.EstateSettings.EstateID.ToString();
|
||||||
}
|
}
|
||||||
|
else if (name == "estate_name")
|
||||||
|
{
|
||||||
|
return World.RegionInfo.EstateSettings.EstateName;
|
||||||
|
}
|
||||||
else if (name == "frame_number")
|
else if (name == "frame_number")
|
||||||
{
|
{
|
||||||
return World.Frame.ToString();
|
return World.Frame.ToString();
|
||||||
}
|
}
|
||||||
|
else if (name == "region_cpu_ratio")
|
||||||
|
{
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
else if (name == "region_idle")
|
else if (name == "region_idle")
|
||||||
{
|
{
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
else if (name == "region_product_name")
|
||||||
|
{
|
||||||
|
if (World.RegionInfo.RegionType != String.Empty)
|
||||||
|
return World.RegionInfo.RegionType;
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (name == "region_product_sku")
|
||||||
|
{
|
||||||
|
return "OpenSim";
|
||||||
|
}
|
||||||
|
else if (name == "region_start_time")
|
||||||
|
{
|
||||||
|
return World.UnixStartTime.ToString();
|
||||||
|
}
|
||||||
else if (name == "sim_channel")
|
else if (name == "sim_channel")
|
||||||
{
|
{
|
||||||
return "OpenSim";
|
return "OpenSim";
|
||||||
|
@ -5801,6 +5851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
return World.GetSimulatorVersion();
|
return World.GetSimulatorVersion();
|
||||||
}
|
}
|
||||||
|
else if (name == "simulator_hostname")
|
||||||
|
{
|
||||||
|
IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
|
||||||
|
return UrlModule.ExternalHostNameForLSL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
|
@ -13811,8 +13866,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return contacts[0];
|
return contacts[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_List llCastRayV1(LSL_Vector start, LSL_Vector end, LSL_List options)
|
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
|
||||||
{
|
{
|
||||||
|
// Use llCastRay V3 if configured
|
||||||
|
if (m_useCastRayV3)
|
||||||
|
return llCastRayV3(start, end, options);
|
||||||
|
|
||||||
LSL_List list = new LSL_List();
|
LSL_List list = new LSL_List();
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
@ -14003,29 +14062,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Full implementation of llCastRay similar to SL 2015-04-21.
|
/// Implementation of llCastRay similar to SL 2015-04-21.
|
||||||
/// http://wiki.secondlife.com/wiki/LlCastRay
|
/// http://wiki.secondlife.com/wiki/LlCastRay
|
||||||
/// Uses pure geometry, bounding shapes, meshing and no physics
|
/// Uses pure geometry, bounding shapes, meshing and no physics
|
||||||
/// for prims, sculpts, meshes, avatars and terrain.
|
/// for prims, sculpts, meshes, avatars and terrain.
|
||||||
/// Implements all flags, reject types and data flags.
|
/// Implements all flags, reject types and data flags.
|
||||||
/// Can handle both objects/groups and prims/parts, by config.
|
/// Can handle both objects/groups and prims/parts, by config.
|
||||||
/// May give poor results with multi-part meshes where "root"
|
/// May sometimes be inaccurate owing to calculation precision,
|
||||||
/// part doesn't dominate, owing to "guessed" bounding boxes.
|
/// meshing detail level and a bug in libopenmetaverse PrimMesher.
|
||||||
/// May sometimes be inaccurate owing to calculation precision
|
|
||||||
/// and a bug in libopenmetaverse PrimMesher.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
|
public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options)
|
||||||
{
|
{
|
||||||
// Use llCastRay v1 if configured
|
m_host.AddScriptLPS(1);
|
||||||
if (m_useCastRayV1)
|
LSL_List result = new LSL_List();
|
||||||
return llCastRayV1(start, end, options);
|
|
||||||
|
// Prepare throttle data
|
||||||
|
int calledMs = Environment.TickCount;
|
||||||
|
Stopwatch stopWatch = new Stopwatch();
|
||||||
|
stopWatch.Start();
|
||||||
|
UUID regionId = World.RegionInfo.RegionID;
|
||||||
|
UUID userId = UUID.Zero;
|
||||||
|
int msAvailable = 0;
|
||||||
|
// Throttle per owner when attachment or "vehicle" (sat upon)
|
||||||
|
if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0)
|
||||||
|
{
|
||||||
|
userId = m_host.OwnerID;
|
||||||
|
msAvailable = m_msPerAvatarInCastRay;
|
||||||
|
}
|
||||||
|
// Throttle per parcel when not attachment or vehicle
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LandData land = World.GetLandData(m_host.GetWorldPosition());
|
||||||
|
if (land != null)
|
||||||
|
msAvailable = m_msPerRegionInCastRay * land.Area / 65536;
|
||||||
|
}
|
||||||
|
// Clamp for "oversized" parcels on varregions
|
||||||
|
if (msAvailable > m_msMaxInCastRay)
|
||||||
|
msAvailable = m_msMaxInCastRay;
|
||||||
|
|
||||||
|
// Check throttle data
|
||||||
|
int fromCalledMs = calledMs - m_msThrottleInCastRay;
|
||||||
|
lock (m_castRayCalls)
|
||||||
|
{
|
||||||
|
for (int i = m_castRayCalls.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
// Delete old calls from throttle data
|
||||||
|
if (m_castRayCalls[i].CalledMs < fromCalledMs)
|
||||||
|
m_castRayCalls.RemoveAt(i);
|
||||||
|
// Use current region (in multi-region sims)
|
||||||
|
else if (m_castRayCalls[i].RegionId == regionId)
|
||||||
|
{
|
||||||
|
// Reduce available time with recent calls
|
||||||
|
if (m_castRayCalls[i].UserId == userId)
|
||||||
|
msAvailable -= m_castRayCalls[i].UsedMs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return failure if not enough available time
|
||||||
|
if (msAvailable < m_msMinInCastRay)
|
||||||
|
{
|
||||||
|
result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
m_host.AddScriptLPS(1);
|
|
||||||
List<RayHit> rayHits = new List<RayHit>();
|
List<RayHit> rayHits = new List<RayHit>();
|
||||||
LSL_List result = new LSL_List();
|
|
||||||
float tol = m_floatToleranceInCastRay;
|
float tol = m_floatToleranceInCastRay;
|
||||||
float tol2 = m_floatTolerance2InCastRay;
|
Vector3 pos1Ray = start;
|
||||||
|
Vector3 pos2Ray = end;
|
||||||
|
|
||||||
// Get input options
|
// Get input options
|
||||||
int rejectTypes = 0;
|
int rejectTypes = 0;
|
||||||
|
@ -14054,25 +14159,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0);
|
bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0);
|
||||||
|
|
||||||
// Calculate some basic parameters
|
// Calculate some basic parameters
|
||||||
Vector3 ray = end - start;
|
Vector3 vecRay = pos2Ray - pos1Ray;
|
||||||
float rayLength = ray.Length();
|
float rayLength = vecRay.Length();
|
||||||
|
|
||||||
// Try to get a mesher and return failure if none or degenerate ray
|
// Try to get a mesher and return failure if none, degenerate ray, or max 0 hits
|
||||||
IRendering primMesher = null;
|
IRendering primMesher = null;
|
||||||
List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
|
List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
|
||||||
if (renderers.Count < 1 || rayLength < tol)
|
if (renderers.Count < 1 || rayLength < tol || m_maxHitsInCastRay < 1)
|
||||||
{
|
{
|
||||||
result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN));
|
result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
primMesher = RenderingLoader.LoadRenderer(renderers[0]);
|
primMesher = RenderingLoader.LoadRenderer(renderers[0]);
|
||||||
|
|
||||||
// Used to translate and rotate world so ray is along negative Z axis from origo and
|
|
||||||
// calculations mostly simplified to a 2D projecttion on the X-Y plane
|
|
||||||
Vector3 posProj = new Vector3(-start);
|
|
||||||
Quaternion rotProj = Vector3.RotationBetween(ray, new Vector3(0.0f, 0.0f, -1.0f));
|
|
||||||
Quaternion rotBack = Quaternion.Inverse(rotProj);
|
|
||||||
|
|
||||||
// Iterate over all objects/groups and prims/parts in region
|
// Iterate over all objects/groups and prims/parts in region
|
||||||
World.ForEachSOG(
|
World.ForEachSOG(
|
||||||
delegate(SceneObjectGroup group)
|
delegate(SceneObjectGroup group)
|
||||||
|
@ -14115,51 +14214,77 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (!doPart)
|
if (!doPart)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Parse prim/part if passed filters
|
|
||||||
|
|
||||||
// Estimate bounding box from size box
|
// Parse prim/part and project ray if passed filters
|
||||||
Vector3 scaleSafe = part.Scale;
|
Vector3 scalePart = part.Scale;
|
||||||
|
Vector3 posPart = part.GetWorldPosition();
|
||||||
|
Quaternion rotPart = part.GetWorldRotation();
|
||||||
|
Quaternion rotPartInv = Quaternion.Inverse(rotPart);
|
||||||
|
Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart;
|
||||||
|
Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart;
|
||||||
|
|
||||||
|
// Filter parts by shape bounding boxes
|
||||||
|
Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
if (!part.Shape.SculptEntry)
|
if (!part.Shape.SculptEntry)
|
||||||
scaleSafe = scaleSafe * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ));
|
shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ));
|
||||||
|
shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol));
|
||||||
// Filter parts by bounding shapes
|
if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
|
||||||
Vector3 posPartRel = part.GetWorldPosition() + posProj;
|
|
||||||
Vector3 posPartProj = posPartRel * rotProj;
|
|
||||||
if (InBoundingShapes(ray, rayLength, scaleSafe, posPartRel, posPartProj, rotProj))
|
|
||||||
{
|
{
|
||||||
// Prepare data needed to check for ray hits
|
// Prepare data needed to check for ray hits
|
||||||
RayTrans rayTrans = new RayTrans();
|
RayTrans rayTrans = new RayTrans();
|
||||||
rayTrans.PartId = part.UUID;
|
rayTrans.PartId = part.UUID;
|
||||||
rayTrans.GroupId = part.ParentGroup.UUID;
|
rayTrans.GroupId = part.ParentGroup.UUID;
|
||||||
rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0;
|
rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0;
|
||||||
rayTrans.Scale = part.Scale;
|
rayTrans.ScalePart = scalePart;
|
||||||
rayTrans.PositionPartProj = posPartProj;
|
rayTrans.PositionPart = posPart;
|
||||||
rayTrans.PositionProj = posProj;
|
rayTrans.RotationPart = rotPart;
|
||||||
rayTrans.RotationPartProj = rotProj * part.GetWorldRotation();
|
rayTrans.ShapeNeedsEnds = true;
|
||||||
rayTrans.RotationBack = rotBack;
|
rayTrans.Position1Ray = pos1Ray;
|
||||||
rayTrans.NeedsEnds = true;
|
rayTrans.Position1RayProj = pos1RayProj;
|
||||||
rayTrans.RayLength = rayLength;
|
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
|
||||||
rayTrans.Tolerance = tol;
|
|
||||||
rayTrans.Tolerance2 = tol2;
|
|
||||||
|
|
||||||
|
// Get detail level depending on type
|
||||||
|
int lod = 0;
|
||||||
|
// Mesh detail level
|
||||||
|
if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
|
||||||
|
lod = (int)m_meshLodInCastRay;
|
||||||
|
// Sculpt detail level
|
||||||
|
else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
|
||||||
|
lod = (int)m_sculptLodInCastRay;
|
||||||
|
// Shape detail level
|
||||||
|
else if (!part.Shape.SculptEntry)
|
||||||
|
lod = (int)m_primLodInCastRay;
|
||||||
|
|
||||||
|
// Try to get cached mesh if configured
|
||||||
|
ulong meshKey = 0;
|
||||||
|
FacetedMesh mesh = null;
|
||||||
|
if (m_useMeshCacheInCastRay)
|
||||||
|
{
|
||||||
|
meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod));
|
||||||
|
lock (m_cachedMeshes)
|
||||||
|
{
|
||||||
|
m_cachedMeshes.TryGetValue(meshKey, out mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create mesh if no cached mesh
|
||||||
|
if (mesh == null)
|
||||||
|
{
|
||||||
// Make an OMV prim to be able to mesh part
|
// Make an OMV prim to be able to mesh part
|
||||||
Primitive omvPrim = part.Shape.ToOmvPrimitive(posPartProj, rayTrans.RotationPartProj);
|
Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart);
|
||||||
byte[] sculptAsset = null;
|
byte[] sculptAsset = null;
|
||||||
if (omvPrim.Sculpt != null)
|
if (omvPrim.Sculpt != null)
|
||||||
sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
|
sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
|
||||||
|
|
||||||
// When part is mesh, get and check mesh
|
// When part is mesh, get mesh
|
||||||
if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
|
if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
|
||||||
{
|
{
|
||||||
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
|
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
|
||||||
FacetedMesh mesh = null;
|
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh);
|
||||||
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh);
|
|
||||||
meshAsset = null;
|
meshAsset = null;
|
||||||
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
|
||||||
mesh = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When part is sculpt, create and check mesh
|
// When part is sculpt, create mesh
|
||||||
// Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt.
|
// Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt.
|
||||||
else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
|
else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
|
||||||
{
|
{
|
||||||
|
@ -14169,15 +14294,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
|
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
|
||||||
if (sculpt != null)
|
if (sculpt != null)
|
||||||
{
|
{
|
||||||
SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium);
|
mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
|
||||||
sculpt.Dispose();
|
sculpt.Dispose();
|
||||||
AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
|
|
||||||
mesh = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When part is prim, create and check mesh
|
// When part is shape, create mesh
|
||||||
else if (omvPrim.Sculpt == null)
|
else if (omvPrim.Sculpt == null)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
@ -14186,12 +14309,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
omvPrim.PrimData.PathSkew == 0.0 &&
|
omvPrim.PrimData.PathSkew == 0.0 &&
|
||||||
omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
|
omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
|
||||||
)
|
)
|
||||||
rayTrans.NeedsEnds = false;
|
rayTrans.ShapeNeedsEnds = false;
|
||||||
SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
|
mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay);
|
||||||
AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
|
|
||||||
mesh = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache mesh if configured
|
||||||
|
if (m_useMeshCacheInCastRay && mesh != null)
|
||||||
|
{
|
||||||
|
lock(m_cachedMeshes)
|
||||||
|
{
|
||||||
|
if (!m_cachedMeshes.ContainsKey(meshKey))
|
||||||
|
m_cachedMeshes.Add(meshKey, mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check mesh for ray hits
|
||||||
|
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
||||||
|
mesh = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14205,38 +14339,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
World.ForEachRootScenePresence(
|
World.ForEachRootScenePresence(
|
||||||
delegate (ScenePresence sp)
|
delegate (ScenePresence sp)
|
||||||
{
|
{
|
||||||
// Parse avatar
|
|
||||||
|
|
||||||
// Get bounding box
|
// Get bounding box
|
||||||
Vector3 lower;
|
Vector3 lower;
|
||||||
Vector3 upper;
|
Vector3 upper;
|
||||||
BoundingBoxOfScenePresence(sp, out lower, out upper);
|
BoundingBoxOfScenePresence(sp, out lower, out upper);
|
||||||
Vector3 scale = upper - lower;
|
// Parse avatar
|
||||||
|
Vector3 scalePart = upper - lower;
|
||||||
|
Vector3 posPart = sp.AbsolutePosition;
|
||||||
|
Quaternion rotPart = sp.GetWorldRotation();
|
||||||
|
Quaternion rotPartInv = Quaternion.Inverse(rotPart);
|
||||||
|
posPart = posPart + (lower + upper) * 0.5f * rotPart;
|
||||||
|
// Project ray
|
||||||
|
Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart;
|
||||||
|
Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart;
|
||||||
|
|
||||||
// Filter avatars by bounding shapes
|
// Filter avatars by shape bounding boxes
|
||||||
Vector3 posPartRel = sp.AbsolutePosition + posProj + (lower + upper) * 0.5f * sp.Rotation;
|
Vector3 shapeBoxMax = new Vector3(0.5f + tol, 0.5f + tol, 0.5f + tol);
|
||||||
Vector3 posPartProj = posPartRel * rotProj;
|
if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
|
||||||
if (InBoundingShapes(ray, rayLength, scale, posPartRel, posPartProj, rotProj))
|
|
||||||
{
|
{
|
||||||
// Prepare data needed to check for ray hits
|
// Prepare data needed to check for ray hits
|
||||||
RayTrans rayTrans = new RayTrans();
|
RayTrans rayTrans = new RayTrans();
|
||||||
rayTrans.PartId = sp.UUID;
|
rayTrans.PartId = sp.UUID;
|
||||||
rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID;
|
rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID;
|
||||||
rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0;
|
rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0;
|
||||||
rayTrans.Scale = scale;
|
rayTrans.ScalePart = scalePart;
|
||||||
rayTrans.PositionPartProj = posPartProj;
|
rayTrans.PositionPart = posPart;
|
||||||
rayTrans.PositionProj = posProj;
|
rayTrans.RotationPart = rotPart;
|
||||||
rayTrans.RotationPartProj = rotProj * sp.Rotation;
|
rayTrans.ShapeNeedsEnds = false;
|
||||||
rayTrans.RotationBack = rotBack;
|
rayTrans.Position1Ray = pos1Ray;
|
||||||
rayTrans.NeedsEnds = false;
|
rayTrans.Position1RayProj = pos1RayProj;
|
||||||
rayTrans.RayLength = rayLength;
|
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
|
||||||
rayTrans.Tolerance = tol;
|
|
||||||
rayTrans.Tolerance2 = tol2;
|
|
||||||
|
|
||||||
// Make OMV prim, create and check mesh
|
// Try to get cached mesh if configured
|
||||||
Primitive omvPrim = MakeOpenMetaversePrim(scale, posPartProj, rayTrans.RotationPartProj, ScriptBaseClass.PRIM_TYPE_SPHERE);
|
PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere();
|
||||||
SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
|
int lod = (int)m_avatarLodInCastRay;
|
||||||
AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
|
ulong meshKey = prim.GetMeshKey(Vector3.One, (float)(4 << lod));
|
||||||
|
FacetedMesh mesh = null;
|
||||||
|
if (m_useMeshCacheInCastRay)
|
||||||
|
{
|
||||||
|
lock (m_cachedMeshes)
|
||||||
|
{
|
||||||
|
m_cachedMeshes.TryGetValue(meshKey, out mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create mesh if no cached mesh
|
||||||
|
if (mesh == null)
|
||||||
|
{
|
||||||
|
// Make OMV prim and create mesh
|
||||||
|
prim.Scale = scalePart;
|
||||||
|
Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart);
|
||||||
|
mesh = primMesher.GenerateFacetedMesh(omvPrim, m_avatarLodInCastRay);
|
||||||
|
|
||||||
|
// Cache mesh if configured
|
||||||
|
if (m_useMeshCacheInCastRay && mesh != null)
|
||||||
|
{
|
||||||
|
lock(m_cachedMeshes)
|
||||||
|
{
|
||||||
|
if (!m_cachedMeshes.ContainsKey(meshKey))
|
||||||
|
m_cachedMeshes.Add(meshKey, mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check mesh for ray hits
|
||||||
|
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
|
||||||
mesh = null;
|
mesh = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14248,32 +14415,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
// Parse terrain
|
// Parse terrain
|
||||||
|
|
||||||
// Mesh terrain and check projected bounding box
|
// Mesh terrain and check bounding box
|
||||||
Vector3 posPartProj = posProj * rotProj;
|
|
||||||
Quaternion rotPartProj = rotProj;
|
|
||||||
Vector3 lower;
|
Vector3 lower;
|
||||||
Vector3 upper;
|
Vector3 upper;
|
||||||
List<Tri> triangles = TrisFromHeightmapUnderRay(start, end, out lower, out upper);
|
List<Tri> triangles = TrisFromHeightmapUnderRay(pos1Ray, pos2Ray, out lower, out upper);
|
||||||
Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
|
lower.Z -= tol;
|
||||||
Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue);
|
upper.Z += tol;
|
||||||
int dummy = 0;
|
if ((pos1Ray.Z >= lower.Z || pos2Ray.Z >= lower.Z) && (pos1Ray.Z <= upper.Z || pos2Ray.Z <= upper.Z))
|
||||||
AddBoundingBoxOfSimpleBox(lower, upper, posPartProj, rotPartProj, true, ref lowerBox, ref upperBox, ref dummy);
|
|
||||||
if (lowerBox.X <= tol && lowerBox.Y <= tol && lowerBox.Z <= tol && upperBox.X >= -tol && upperBox.Y >= -tol && upperBox.Z >= -rayLength - tol)
|
|
||||||
{
|
{
|
||||||
// Prepare data needed to check for ray hits
|
// Prepare data needed to check for ray hits
|
||||||
RayTrans rayTrans = new RayTrans();
|
RayTrans rayTrans = new RayTrans();
|
||||||
rayTrans.PartId = UUID.Zero;
|
rayTrans.PartId = UUID.Zero;
|
||||||
rayTrans.GroupId = UUID.Zero;
|
rayTrans.GroupId = UUID.Zero;
|
||||||
rayTrans.Link = 0;
|
rayTrans.Link = 0;
|
||||||
rayTrans.Scale = new Vector3 (1.0f, 1.0f, 1.0f);
|
rayTrans.ScalePart = new Vector3 (1.0f, 1.0f, 1.0f);
|
||||||
rayTrans.PositionPartProj = posPartProj;
|
rayTrans.PositionPart = Vector3.Zero;
|
||||||
rayTrans.PositionProj = posProj;
|
rayTrans.RotationPart = Quaternion.Identity;
|
||||||
rayTrans.RotationPartProj = rotPartProj;
|
rayTrans.ShapeNeedsEnds = true;
|
||||||
rayTrans.RotationBack = rotBack;
|
rayTrans.Position1Ray = pos1Ray;
|
||||||
rayTrans.NeedsEnds = true;
|
rayTrans.Position1RayProj = pos1Ray;
|
||||||
rayTrans.RayLength = rayLength;
|
rayTrans.VectorRayProj = vecRay;
|
||||||
rayTrans.Tolerance = tol;
|
|
||||||
rayTrans.Tolerance2 = tol2;
|
|
||||||
|
|
||||||
// Check mesh
|
// Check mesh
|
||||||
AddRayInTris(triangles, rayTrans, ref rayHits);
|
AddRayInTris(triangles, rayTrans, ref rayHits);
|
||||||
|
@ -14347,6 +14508,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
result.Add(new LSL_Vector(rayHit.Normal));
|
result.Add(new LSL_Vector(rayHit.Normal));
|
||||||
}
|
}
|
||||||
result.Add(new LSL_Integer(hitCount));
|
result.Add(new LSL_Integer(hitCount));
|
||||||
|
|
||||||
|
// Add to throttle data
|
||||||
|
stopWatch.Stop();
|
||||||
|
CastRayCall castRayCall = new CastRayCall();
|
||||||
|
castRayCall.RegionId = regionId;
|
||||||
|
castRayCall.UserId = userId;
|
||||||
|
castRayCall.CalledMs = calledMs;
|
||||||
|
castRayCall.UsedMs = (int)stopWatch.ElapsedMilliseconds;
|
||||||
|
lock (m_castRayCalls)
|
||||||
|
{
|
||||||
|
m_castRayCalls.Add(castRayCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return hits
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14358,15 +14533,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public UUID PartId;
|
public UUID PartId;
|
||||||
public UUID GroupId;
|
public UUID GroupId;
|
||||||
public int Link;
|
public int Link;
|
||||||
public Vector3 Scale;
|
public Vector3 ScalePart;
|
||||||
public Vector3 PositionPartProj;
|
public Vector3 PositionPart;
|
||||||
public Vector3 PositionProj;
|
public Quaternion RotationPart;
|
||||||
public Quaternion RotationPartProj;
|
public bool ShapeNeedsEnds;
|
||||||
public Quaternion RotationBack;
|
public Vector3 Position1Ray;
|
||||||
public bool NeedsEnds;
|
public Vector3 Position1RayProj;
|
||||||
public float RayLength;
|
public Vector3 VectorRayProj;
|
||||||
public float Tolerance;
|
|
||||||
public float Tolerance2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -14383,21 +14556,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper to parse SimpleMesh for ray hits.
|
/// Struct for llCastRay throttle data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void AddRayInSimpleMesh(SimpleMesh mesh, RayTrans rayTrans, ref List<RayHit> rayHits)
|
public struct CastRayCall
|
||||||
{
|
{
|
||||||
if (mesh != null)
|
public UUID RegionId;
|
||||||
|
public UUID UserId;
|
||||||
|
public int CalledMs;
|
||||||
|
public int UsedMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to check if a ray intersects a shape bounding box.
|
||||||
|
/// </summary>
|
||||||
|
private bool RayIntersectsShapeBox(Vector3 pos1RayProj, Vector3 pos2RayProj, Vector3 shapeBoxMax)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mesh.Indices.Count; i += 3)
|
// Skip if ray can't intersect bounding box;
|
||||||
|
Vector3 rayBoxProjMin = Vector3.Min(pos1RayProj, pos2RayProj);
|
||||||
|
Vector3 rayBoxProjMax = Vector3.Max(pos1RayProj, pos2RayProj);
|
||||||
|
if (
|
||||||
|
rayBoxProjMin.X > shapeBoxMax.X || rayBoxProjMin.Y > shapeBoxMax.Y || rayBoxProjMin.Z > shapeBoxMax.Z ||
|
||||||
|
rayBoxProjMax.X < -shapeBoxMax.X || rayBoxProjMax.Y < -shapeBoxMax.Y || rayBoxProjMax.Z < -shapeBoxMax.Z
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if ray intersect any bounding box side
|
||||||
|
int sign = 0;
|
||||||
|
float dist = 0.0f;
|
||||||
|
Vector3 posProj = Vector3.Zero;
|
||||||
|
Vector3 vecRayProj = pos2RayProj - pos1RayProj;
|
||||||
|
|
||||||
|
// Check both X sides unless ray is parallell to them
|
||||||
|
if (Math.Abs(vecRayProj.X) > m_floatToleranceInCastRay)
|
||||||
{
|
{
|
||||||
Tri triangle = new Tri();
|
for (sign = -1; sign <= 1; sign += 2)
|
||||||
triangle.p1 = mesh.Vertices[mesh.Indices[i]].Position;
|
{
|
||||||
triangle.p2 = mesh.Vertices[mesh.Indices[i + 1]].Position;
|
dist = ((float)sign * shapeBoxMax.X - pos1RayProj.X) / vecRayProj.X;
|
||||||
triangle.p3 = mesh.Vertices[mesh.Indices[i + 2]].Position;
|
posProj = pos1RayProj + vecRayProj * dist;
|
||||||
AddRayInTri(triangle, rayTrans, ref rayHits);
|
if (Math.Abs(posProj.Y) <= shapeBoxMax.Y && Math.Abs(posProj.Z) <= shapeBoxMax.Z)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check both Y sides unless ray is parallell to them
|
||||||
|
if (Math.Abs(vecRayProj.Y) > m_floatToleranceInCastRay)
|
||||||
|
{
|
||||||
|
for (sign = -1; sign <= 1; sign += 2)
|
||||||
|
{
|
||||||
|
dist = ((float)sign * shapeBoxMax.Y - pos1RayProj.Y) / vecRayProj.Y;
|
||||||
|
posProj = pos1RayProj + vecRayProj * dist;
|
||||||
|
if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Z) <= shapeBoxMax.Z)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check both Z sides unless ray is parallell to them
|
||||||
|
if (Math.Abs(vecRayProj.Z) > m_floatToleranceInCastRay)
|
||||||
|
{
|
||||||
|
for (sign = -1; sign <= 1; sign += 2)
|
||||||
|
{
|
||||||
|
dist = ((float)sign * shapeBoxMax.Z - pos1RayProj.Z) / vecRayProj.Z;
|
||||||
|
posProj = pos1RayProj + vecRayProj * dist;
|
||||||
|
if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Y) <= shapeBoxMax.Y)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No hits on bounding box so return false
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -14435,23 +14661,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper to add ray hit in a Tri (triangle).
|
/// Helper to add ray hit in a Tri (triangle).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void AddRayInTri(Tri triangle, RayTrans rayTrans, ref List<RayHit> rayHits)
|
private void AddRayInTri(Tri triProj, RayTrans rayTrans, ref List<RayHit> rayHits)
|
||||||
{
|
{
|
||||||
// Check for hit in triangle
|
// Check for hit in triangle
|
||||||
float distance;
|
Vector3 posHitProj;
|
||||||
Vector3 posHit;
|
Vector3 normalProj;
|
||||||
Vector3 normal;
|
if (HitRayInTri(triProj, rayTrans.Position1RayProj, rayTrans.VectorRayProj, out posHitProj, out normalProj))
|
||||||
if (HitRayInTri(triangle, rayTrans, out distance, out posHit, out normal))
|
|
||||||
{
|
{
|
||||||
// Project hit part back to normal coordinate system
|
// Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) face plane through shape center
|
||||||
Vector3 posPart = rayTrans.PositionPartProj * rayTrans.RotationBack - rayTrans.PositionProj;
|
if (Math.Abs(Vector3.Dot(posHitProj, normalProj)) < m_floatToleranceInCastRay && !rayTrans.ShapeNeedsEnds)
|
||||||
// Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) faces plane through shape center
|
|
||||||
if (Math.Abs(Vector3.Dot(posPart, normal) - Vector3.Dot(posHit, normal)) < rayTrans.Tolerance && !rayTrans.NeedsEnds)
|
|
||||||
return;
|
return;
|
||||||
// Remove duplicate hits at triangle edges and intersections
|
|
||||||
|
// Transform hit and normal to region coordinate system
|
||||||
|
Vector3 posHit = rayTrans.PositionPart + (posHitProj * rayTrans.ScalePart) * rayTrans.RotationPart;
|
||||||
|
Vector3 normal = Vector3.Normalize((normalProj * rayTrans.ScalePart) * rayTrans.RotationPart);
|
||||||
|
|
||||||
|
// Remove duplicate hits at triangle intersections
|
||||||
|
float distance = Vector3.Distance(rayTrans.Position1Ray, posHit);
|
||||||
for (int i = rayHits.Count - 1; i >= 0; i--)
|
for (int i = rayHits.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (rayHits[i].PartId == rayTrans.PartId && Math.Abs(rayHits[i].Distance - distance) < rayTrans.Tolerance2)
|
if (rayHits[i].PartId != rayTrans.PartId)
|
||||||
|
break;
|
||||||
|
if (Math.Abs(rayHits[i].Distance - distance) < m_floatTolerance2InCastRay)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14468,76 +14699,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper to find ray hit in a Tri (triangle).
|
/// Helper to find ray hit in triangle
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool HitRayInTri(Tri triangle, RayTrans rayTrans, out float distance, out Vector3 posHit, out Vector3 normal)
|
bool HitRayInTri(Tri triProj, Vector3 pos1RayProj, Vector3 vecRayProj, out Vector3 posHitProj, out Vector3 normalProj)
|
||||||
{
|
{
|
||||||
// Initialize
|
float tol = m_floatToleranceInCastRay;
|
||||||
distance = 0.0f;
|
posHitProj = Vector3.Zero;
|
||||||
posHit = Vector3.Zero;
|
|
||||||
normal = Vector3.Zero;
|
|
||||||
float tol = rayTrans.Tolerance;
|
|
||||||
|
|
||||||
// Project triangle on X-Y plane
|
// Calculate triangle edge vectors
|
||||||
Vector3 pos1 = triangle.p1 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
|
Vector3 vec1Proj = triProj.p2 - triProj.p1;
|
||||||
Vector3 pos2 = triangle.p2 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
|
Vector3 vec2Proj = triProj.p3 - triProj.p2;
|
||||||
Vector3 pos3 = triangle.p3 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
|
Vector3 vec3Proj = triProj.p1 - triProj.p3;
|
||||||
|
|
||||||
// Check if ray/origo inside triangle bounding rectangle
|
// Calculate triangle normal
|
||||||
Vector3 lower = Vector3.Min(pos1, Vector3.Min(pos2, pos3));
|
normalProj = Vector3.Cross(vec1Proj, vec2Proj);
|
||||||
Vector3 upper = Vector3.Max(pos1, Vector3.Max(pos2, pos3));
|
|
||||||
if (lower.X > tol || lower.Y > tol || lower.Z > tol || upper.X < -tol || upper.Y < -tol || upper.Z < -rayTrans.RayLength - tol)
|
// Skip if degenerate triangle or ray parallell with triangle plane
|
||||||
|
float divisor = Vector3.Dot(vecRayProj, normalProj);
|
||||||
|
if (Math.Abs(divisor) < tol)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check if ray/origo inside every edge or reverse "outside" every edge on exit
|
// Skip if exit and not configured to detect
|
||||||
float dist;
|
if (divisor > tol && !m_detectExitsInCastRay)
|
||||||
bool inside = true;
|
|
||||||
bool outside = true;
|
|
||||||
Vector3 vec1 = pos2 - pos1;
|
|
||||||
dist = pos1.X * vec1.Y - pos1.Y * vec1.X;
|
|
||||||
if (dist < -tol)
|
|
||||||
inside = false;
|
|
||||||
if (dist > tol)
|
|
||||||
outside = false;
|
|
||||||
Vector3 vec2 = pos3 - pos2;
|
|
||||||
dist = pos2.X * vec2.Y - pos2.Y * vec2.X;
|
|
||||||
if (dist < -tol)
|
|
||||||
inside = false;
|
|
||||||
if (dist > tol)
|
|
||||||
outside = false;
|
|
||||||
Vector3 vec3 = pos1 - pos3;
|
|
||||||
dist = pos3.X * vec3.Y - pos3.Y * vec3.X;
|
|
||||||
if (dist < -tol)
|
|
||||||
inside = false;
|
|
||||||
if (dist > tol)
|
|
||||||
outside = false;
|
|
||||||
|
|
||||||
// Skip if ray/origo outside
|
|
||||||
if (!inside && !(outside && m_detectExitsInCastRay))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Calculate normal
|
// Skip if outside ray ends
|
||||||
Vector3 normalProj = Vector3.Cross(vec1, vec2);
|
float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor;
|
||||||
float normalLength = normalProj.Length();
|
if (distanceProj < -tol || distanceProj > 1 + tol)
|
||||||
// Skip if degenerate triangle
|
|
||||||
if (normalLength < tol)
|
|
||||||
return false;
|
|
||||||
normalProj = normalProj / normalLength;
|
|
||||||
// Skip if ray parallell to triangle plane
|
|
||||||
if (Math.Abs(normalProj.Z) < tol)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Calculate distance
|
// Calculate hit position in triangle
|
||||||
distance = Vector3.Dot(normalProj, pos2) / normalProj.Z * -1.0f;
|
posHitProj = pos1RayProj + vecRayProj * distanceProj;
|
||||||
// Skip if outside ray
|
|
||||||
if (distance < -tol || distance > rayTrans.RayLength + tol)
|
// Skip if outside triangle bounding box
|
||||||
|
Vector3 triProjMin = Vector3.Min(Vector3.Min(triProj.p1, triProj.p2), triProj.p3);
|
||||||
|
Vector3 triProjMax = Vector3.Max(Vector3.Max(triProj.p1, triProj.p2), triProj.p3);
|
||||||
|
if (
|
||||||
|
posHitProj.X < triProjMin.X - tol || posHitProj.Y < triProjMin.Y - tol || posHitProj.Z < triProjMin.Z - tol ||
|
||||||
|
posHitProj.X > triProjMax.X + tol || posHitProj.Y > triProjMax.Y + tol || posHitProj.Z > triProjMax.Z + tol
|
||||||
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Calculate projected hit position
|
// Skip if outside triangle
|
||||||
Vector3 posHitProj = new Vector3(0.0f, 0.0f, -distance);
|
if (
|
||||||
// Project hit back to normal coordinate system
|
Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol ||
|
||||||
posHit = posHitProj * rayTrans.RotationBack - rayTrans.PositionProj;
|
Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol ||
|
||||||
normal = normalProj * rayTrans.RotationBack;
|
Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Return hit
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14660,24 +14871,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1);
|
y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1);
|
||||||
Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]);
|
Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]);
|
||||||
// Adjust bounding box
|
// Adjust bounding box
|
||||||
zLower = Math.Min(zLower, pos1.Z);
|
zLower = Math.Min(zLower, pos2.Z);
|
||||||
zUpper = Math.Max(zUpper, pos1.Z);
|
zUpper = Math.Max(zUpper, pos2.Z);
|
||||||
|
|
||||||
// Corner 3 of 1x1 rectangle
|
// Corner 3 of 1x1 rectangle
|
||||||
x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1);
|
x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1);
|
||||||
y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
|
y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
|
||||||
Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]);
|
Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]);
|
||||||
// Adjust bounding box
|
// Adjust bounding box
|
||||||
zLower = Math.Min(zLower, pos1.Z);
|
zLower = Math.Min(zLower, pos3.Z);
|
||||||
zUpper = Math.Max(zUpper, pos1.Z);
|
zUpper = Math.Max(zUpper, pos3.Z);
|
||||||
|
|
||||||
// Corner 4 of 1x1 rectangle
|
// Corner 4 of 1x1 rectangle
|
||||||
x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1);
|
x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1);
|
||||||
y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
|
y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
|
||||||
Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]);
|
Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]);
|
||||||
// Adjust bounding box
|
// Adjust bounding box
|
||||||
zLower = Math.Min(zLower, pos1.Z);
|
zLower = Math.Min(zLower, pos4.Z);
|
||||||
zUpper = Math.Max(zUpper, pos1.Z);
|
zUpper = Math.Max(zUpper, pos4.Z);
|
||||||
|
|
||||||
// Add triangle 1
|
// Add triangle 1
|
||||||
Tri triangle1 = new Tri();
|
Tri triangle1 = new Tri();
|
||||||
|
@ -14694,25 +14905,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
triangles.Add(triangle2);
|
triangles.Add(triangle2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper to check if a ray intersects bounding shapes.
|
|
||||||
/// </summary>
|
|
||||||
private bool InBoundingShapes(Vector3 ray, float rayLength, Vector3 scale, Vector3 posPartRel, Vector3 posPartProj, Quaternion rotProj)
|
|
||||||
{
|
|
||||||
float tol = m_floatToleranceInCastRay;
|
|
||||||
|
|
||||||
// Check if ray intersects projected bounding box
|
|
||||||
Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
|
|
||||||
Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue);
|
|
||||||
int dummy = 0;
|
|
||||||
AddBoundingBoxOfSimpleBox(scale * -0.5f, scale * 0.5f, posPartProj, rotProj, true, ref lowerBox, ref upperBox, ref dummy);
|
|
||||||
if (lowerBox.X > tol || lowerBox.Y > tol || lowerBox.Z > tol || upperBox.X < -tol || upperBox.Y < -tol || upperBox.Z < -rayLength - tol)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Passed bounding shape filters, so return true
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper to get link number for a UUID.
|
/// Helper to get link number for a UUID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1872,6 +1872,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
IScriptInstance instance = GetInstance(itemID);
|
IScriptInstance instance = GetInstance(itemID);
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
instance.ApiResetScript();
|
instance.ApiResetScript();
|
||||||
|
|
||||||
|
// Send the new number of threads that are in use by the thread
|
||||||
|
// pool, I believe that by adding them to the locations where the
|
||||||
|
// script is changing states that I will catch all changes to the
|
||||||
|
// thread pool
|
||||||
|
m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetScript(UUID itemID)
|
public void ResetScript(UUID itemID)
|
||||||
|
@ -1879,6 +1885,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
IScriptInstance instance = GetInstance(itemID);
|
IScriptInstance instance = GetInstance(itemID);
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
instance.ResetScript(m_WaitForEventCompletionOnScriptStop);
|
instance.ResetScript(m_WaitForEventCompletionOnScriptStop);
|
||||||
|
|
||||||
|
// Send the new number of threads that are in use by the thread
|
||||||
|
// pool, I believe that by adding them to the locations where the
|
||||||
|
// script is changing states that I will catch all changes to the
|
||||||
|
// thread pool
|
||||||
|
m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartScript(UUID itemID)
|
public void StartScript(UUID itemID)
|
||||||
|
@ -1888,6 +1900,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
instance.Start();
|
instance.Start();
|
||||||
else
|
else
|
||||||
m_runFlags.AddOrUpdate(itemID, true, 240);
|
m_runFlags.AddOrUpdate(itemID, true, 240);
|
||||||
|
|
||||||
|
// Send the new number of threads that are in use by the thread
|
||||||
|
// pool, I believe that by adding them to the locations where the
|
||||||
|
// script is changing states that I will catch all changes to the
|
||||||
|
// thread pool
|
||||||
|
m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopScript(UUID itemID)
|
public void StopScript(UUID itemID)
|
||||||
|
@ -1903,6 +1921,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name);
|
// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name);
|
||||||
m_runFlags.AddOrUpdate(itemID, false, 240);
|
m_runFlags.AddOrUpdate(itemID, false, 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send the new number of threads that are in use by the thread
|
||||||
|
// pool, I believe that by adding them to the locations where the
|
||||||
|
// script is changing states that I will catch all changes to the
|
||||||
|
// thread pool
|
||||||
|
m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetectParams GetDetectParams(UUID itemID, int idx)
|
public DetectParams GetDetectParams(UUID itemID, int idx)
|
||||||
|
@ -2393,6 +2417,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
instance.Suspend();
|
instance.Suspend();
|
||||||
// else
|
// else
|
||||||
// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
|
// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
|
||||||
|
|
||||||
|
// Send the new number of threads that are in use by the thread
|
||||||
|
// pool, I believe that by adding them to the locations where the
|
||||||
|
// script is changing states that I will catch all changes to the
|
||||||
|
// thread pool
|
||||||
|
m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResumeScript(UUID itemID)
|
public void ResumeScript(UUID itemID)
|
||||||
|
@ -2404,6 +2434,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
instance.Resume();
|
instance.Resume();
|
||||||
// else
|
// else
|
||||||
// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
|
// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
|
||||||
|
|
||||||
|
// Send the new number of threads that are in use by the thread
|
||||||
|
// pool, I believe that by adding them to the locations where the
|
||||||
|
// script is changing states that I will catch all changes to the
|
||||||
|
// thread pool
|
||||||
|
m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasScript(UUID itemID, out bool running)
|
public bool HasScript(UUID itemID, out bool running)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -227,63 +227,6 @@
|
||||||
<param name="intHostEnd"></param>
|
<param name="intHostEnd"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Byte[])">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="xmlData"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.String)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="xmlData"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Xml.XmlTextReader)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="xmlData"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlBytes(OpenMetaverse.StructuredData.OSD)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="data"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlString(OpenMetaverse.StructuredData.OSD)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="data"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlElement(System.Xml.XmlTextWriter,OpenMetaverse.StructuredData.OSD)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="writer"></param>
|
|
||||||
<param name="data"></param>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.TryValidateLLSDXml(System.Xml.XmlTextReader,System.String@)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="xmlData"></param>
|
|
||||||
<param name="error"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ParseLLSDXmlElement(System.Xml.XmlTextReader)">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
<param name="reader"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
||||||
<summary>
|
<summary>
|
||||||
|
|
||||||
|
@ -345,5 +288,62 @@
|
||||||
<param name="c"></param>
|
<param name="c"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Byte[])">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="xmlData"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.String)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="xmlData"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Xml.XmlTextReader)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="xmlData"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlBytes(OpenMetaverse.StructuredData.OSD)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="data"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlString(OpenMetaverse.StructuredData.OSD)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="data"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlElement(System.Xml.XmlTextWriter,OpenMetaverse.StructuredData.OSD)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="writer"></param>
|
||||||
|
<param name="data"></param>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.TryValidateLLSDXml(System.Xml.XmlTextReader,System.String@)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="xmlData"></param>
|
||||||
|
<param name="error"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:OpenMetaverse.StructuredData.OSDParser.ParseLLSDXmlElement(System.Xml.XmlTextReader)">
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
</summary>
|
||||||
|
<param name="reader"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
|
Binary file not shown.
39902
bin/OpenMetaverse.XML
39902
bin/OpenMetaverse.XML
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -296,7 +296,7 @@
|
||||||
; Simulator Stats URI
|
; Simulator Stats URI
|
||||||
; Enable JSON simulator data by setting a URI name (case sensitive)
|
; Enable JSON simulator data by setting a URI name (case sensitive)
|
||||||
; Returns regular sim stats (SimFPS, ...)
|
; Returns regular sim stats (SimFPS, ...)
|
||||||
; Stats_URI = "jsonSimStats"
|
Stats_URI = "jsonSimStats"
|
||||||
|
|
||||||
; Simulator StatsManager URI
|
; Simulator StatsManager URI
|
||||||
; Enable fetch of StatsManager registered stats. Fetch is query which can optionally
|
; Enable fetch of StatsManager registered stats. Fetch is query which can optionally
|
||||||
|
@ -1397,11 +1397,6 @@
|
||||||
; Maximum number of external urls that scripts can set up in this simulator (e.g. via llRequestURL())
|
; Maximum number of external urls that scripts can set up in this simulator (e.g. via llRequestURL())
|
||||||
max_external_urls_per_simulator = 100
|
max_external_urls_per_simulator = 100
|
||||||
|
|
||||||
; Use version 1 of llCastRay as default if true. If set to false, the new
|
|
||||||
; version of llCastRay will be used. This gives better accuracy but
|
|
||||||
; uses more CPU and may may be slow on some servers
|
|
||||||
UseLlCastRayV1 = true
|
|
||||||
|
|
||||||
; Use size boxes instead of meshed prims, sculpts and mesh when calculating bounding boxes.
|
; Use size boxes instead of meshed prims, sculpts and mesh when calculating bounding boxes.
|
||||||
; Speeds up calculations but can make them inaccurate, in some cases very inaccurate.
|
; Speeds up calculations but can make them inaccurate, in some cases very inaccurate.
|
||||||
UseSimpleBoxesInGetBoundingBox = false
|
UseSimpleBoxesInGetBoundingBox = false
|
||||||
|
@ -1494,32 +1489,72 @@
|
||||||
; Worst case is twisted tube, 0.5+sqrt(1.25)
|
; Worst case is twisted tube, 0.5+sqrt(1.25)
|
||||||
PrimBoundingBoxSafetyCoefficientZ = 1.618034
|
PrimBoundingBoxSafetyCoefficientZ = 1.618034
|
||||||
|
|
||||||
; Accepted calculation precision error in calculations in llCastRay
|
; Use llCastRay V3 if true
|
||||||
FloatToleranceInLlCastRay = 0.000001
|
; Gives better accuracy and can be faster on some servers, but slower on others,
|
||||||
|
; compared to previous version of llCastRay
|
||||||
|
; Generates geometry meshes and can therefore use much system resources
|
||||||
|
UseLlCastRayV3 = false
|
||||||
|
|
||||||
; Accepted distance difference between duplicate hits in llCastRay
|
; Accepted calculation precision error in calculations in llCastRay V3
|
||||||
FloatTolerance2InLlCastRay = 0.0001
|
FloatToleranceInLlCastRay = 0.00001
|
||||||
|
|
||||||
; Maximum number of returned hits from llCastRay
|
; Accepted distance difference between duplicate hits in llCastRay V3
|
||||||
|
FloatTolerance2InLlCastRay = 0.001
|
||||||
|
|
||||||
|
; Detail level when rendering prims in llCastRay V3
|
||||||
|
; 0 = Low, 1 = Medium, 2 = High, 3 = Highest, higer level gives better accuracy but slower call
|
||||||
|
PrimDetailLevelInLlCastRay = 1
|
||||||
|
|
||||||
|
; Detail level when rendering sculpts in llCastRay V3
|
||||||
|
; 0 = Low, 1 = Medium, 2 = High, 3 = Highest, higer level gives better accuracy but slower call
|
||||||
|
SculptDetailLevelInLlCastRay = 1
|
||||||
|
|
||||||
|
; Detail level when rendering meshes in llCastRay V3
|
||||||
|
; 0 = Low, 1 = Medium, 2 = High, 3 = Highest, higer level gives better accuracy but slower call
|
||||||
|
MeshDetailLevelInLlCastRay = 3
|
||||||
|
|
||||||
|
; Detail level when rendering avatar capsules in llCastRay V3
|
||||||
|
; 0 = Low, 1 = Medium, 2 = High, 3 = Highest, higer level gives better accuracy but slower call
|
||||||
|
AvatarDetailLevelInLlCastRay = 1
|
||||||
|
|
||||||
|
; Maximum number of returned hits from llCastRay V3
|
||||||
MaxHitsInLlCastRay = 16
|
MaxHitsInLlCastRay = 16
|
||||||
|
|
||||||
; Maximum number of returned hits per prim from llCastRay
|
; Maximum number of returned hits per prim from llCastRay V3
|
||||||
MaxHitsPerPrimInLlCastRay = 16
|
MaxHitsPerPrimInLlCastRay = 16
|
||||||
|
|
||||||
; Maximum number of returned hits per object from llCastRay
|
; Maximum number of returned hits per object from llCastRay V3
|
||||||
MaxHitsPerObjectInLlCastRay = 16
|
MaxHitsPerObjectInLlCastRay = 16
|
||||||
|
|
||||||
; Report ray intersections with surfaces on exits from a prim as hits in llCastRay if true
|
; Report ray intersections with surfaces on exits from a prim as hits in llCastRay V3 if true
|
||||||
DetectExitHitsInLlCastRay = false
|
DetectExitHitsInLlCastRay = false
|
||||||
|
|
||||||
; Filter on parts instead of groups in llCastRay if true
|
; Filter on parts instead of groups in llCastRay V3 if true
|
||||||
FilterPartsInLlCastRay = false
|
FilterPartsInLlCastRay = false
|
||||||
|
|
||||||
; Detect attachments in llCastRay if true
|
; Detect attachments in llCastRay V3 if true
|
||||||
DoAttachmentsInLlCastRay = false
|
DoAttachmentsInLlCastRay = false
|
||||||
|
|
||||||
; Use legacy version 1 of llCastRay if true
|
; Throttle period length in ms before which all old llCastRay use is discarded in llCastRay V3
|
||||||
UseLlCastRayV1 = true
|
; The sum of AvailableTimeInMsPerRegionInLlCastRay and all AvailableTimeInMsPerAvatarInLlCastRay should not exceed this
|
||||||
|
ThrottleTimeInMsInLlCastRay = 200
|
||||||
|
|
||||||
|
; Available time in ms for llCastRay per throttle period and 65536 m2 land area in llCastRay V3
|
||||||
|
AvailableTimeInMsPerRegionInLlCastRay = 40
|
||||||
|
|
||||||
|
; Available time in ms for llCastRay per throttle period and avatar when script in attachment or vehicle in llCastRay V3
|
||||||
|
AvailableTimeInMsPerAvatarInLlCastRay = 10
|
||||||
|
|
||||||
|
; Required available time in ms left to perform a new llCastRay in llCastRay V3
|
||||||
|
RequiredAvailableTimeInMsInLlCastRay = 2
|
||||||
|
|
||||||
|
; Maximum available time in ms possible in llCastRay V3, not to get too high values with varregions
|
||||||
|
MaximumAvailableTimeInMsInLlCastRay = 40
|
||||||
|
|
||||||
|
; Use cached meshes in llCastRay V3 if true
|
||||||
|
; Improves performance but uses more memory
|
||||||
|
UseMeshCacheInLlCastRay = true
|
||||||
|
|
||||||
|
|
||||||
[DataSnapshot]
|
[DataSnapshot]
|
||||||
; The following set of configs pertains to search.
|
; The following set of configs pertains to search.
|
||||||
|
@ -1547,6 +1582,7 @@
|
||||||
; data service
|
; data service
|
||||||
;DATA_SRV_MISearch = "http://metaverseink.com/cgi-bin/register.py"
|
;DATA_SRV_MISearch = "http://metaverseink.com/cgi-bin/register.py"
|
||||||
|
|
||||||
|
|
||||||
[Economy]
|
[Economy]
|
||||||
; These economy values get used in the BetaGridLikeMoneyModule. - This module is for demonstration only -
|
; These economy values get used in the BetaGridLikeMoneyModule. - This module is for demonstration only -
|
||||||
; The default economy module only implements just enough to allow free actions (transfer of objects, etc).
|
; The default economy module only implements just enough to allow free actions (transfer of objects, etc).
|
||||||
|
|
Loading…
Reference in New Issue