Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

fsassets
Diva Canto 2015-05-25 15:19:27 -07:00
commit 22ee1c30e3
20 changed files with 28059 additions and 17548 deletions

52
OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs Normal file → Executable file
View File

@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using OpenMetaverse;
@ -71,6 +72,11 @@ namespace OpenSim.Framework.Monitoring
private volatile float pendingUploads;
private volatile float activeScripts;
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>
// /// 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
// 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;
simFps = stats.StatsBlock[1].StatValue;
physicsFps = stats.StatsBlock[2].StatValue;
@ -270,6 +280,11 @@ namespace OpenSim.Framework.Monitoring
pendingUploads = stats.StatsBlock[18].StatValue;
activeScripts = stats.StatsBlock[19].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>
@ -407,6 +422,27 @@ Asset service request failures: {3}" + Environment.NewLine,
/// <returns></returns>
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);
// args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache));
// 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["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;
}
}

View File

@ -292,11 +292,11 @@ namespace OpenSim.Framework.Servers
+ " 3 = full stack trace, including common threads\n",
HandleDebugThreadpoolLevel);
m_console.Commands.AddCommand(
"Debug", false, "show threadpool calls active",
"show threadpool calls active",
"Show details about threadpool calls that are still active (currently waiting or in progress)",
HandleShowThreadpoolCallsActive);
// m_console.Commands.AddCommand(
// "Debug", false, "show threadpool calls active",
// "show threadpool calls active",
// "Show details about threadpool calls that are still active (currently waiting or in progress)",
// HandleShowThreadpoolCallsActive);
m_console.Commands.AddCommand(
"Debug", false, "show threadpool calls complete",

View File

@ -3747,6 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
avp.Sender.IsTrial = false;
avp.Sender.ID = agentID;
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());
OutPacket(avp, ThrottleOutPacketType.Task);
}

View File

@ -726,6 +726,21 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
"Show the bindings between user UUIDs and user names",
String.Empty,
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)

File diff suppressed because it is too large Load Diff

59
OpenSim/Region/Framework/Scenes/SceneGraph.cs Normal file → Executable file
View File

@ -67,7 +67,9 @@ namespace OpenSim.Region.Framework.Scenes
protected Scene m_parentScene;
protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
protected int m_numRootAgents = 0;
protected int m_numTotalPrim = 0;
protected int m_numPrim = 0;
protected int m_numMesh = 0;
protected int m_numChildAgents = 0;
protected int m_physicalPrim = 0;
@ -368,7 +370,8 @@ namespace OpenSim.Region.Framework.Scenes
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)
{
foreach (SceneObjectPart part in parts)
@ -382,7 +385,19 @@ namespace OpenSim.Region.Framework.Scenes
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);
@ -437,7 +452,21 @@ namespace OpenSim.Region.Framework.Scenes
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)
RemovePhysicalPrim(grp.PrimCount);
@ -686,10 +715,20 @@ namespace OpenSim.Region.Framework.Scenes
}
public int GetTotalObjectsCount()
{
return m_numTotalPrim;
}
public int GetTotalPrimObjectsCount()
{
return m_numPrim;
}
public int GetTotalMeshObjectsCount()
{
return m_numMesh;
}
public int GetActiveObjectsCount()
{
return m_physicalPrim;
@ -1970,7 +2009,19 @@ namespace OpenSim.Region.Framework.Scenes
// think it's selected, so it will never send a deselect...
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)
{

View File

@ -2672,20 +2672,27 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
//NonPhysicalGrabMovement(pos);
NonPhysicalGrabMovement(pos);
}
}
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)
{
AbsolutePosition = pos;
m_rootPart.SendTerseUpdateToAllClients();
if(!IsAttachment && ScriptCount() == 0)
UpdateGroupPosition(pos);
}
/// <summary>
@ -2781,16 +2788,27 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
//NonPhysicalSpinMovement(pos);
NonPhysicalSpinMovement(newOrientation);
}
}
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>
/// Set the name of a prim
/// </summary>

View File

@ -61,6 +61,10 @@ namespace OpenSim.Region.Framework.Scenes
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>
/// These are the IDs of stats sent in the StatsPacket to the viewer.
/// </summary>
@ -104,7 +108,12 @@ namespace OpenSim.Region.Framework.Scenes
ScriptEps = 31,
SimSpareMs = 32,
SimSleepMs = 33,
SimIoPumpTime = 34
SimIoPumpTime = 34,
FrameDilation = 35,
UsersLoggingIn = 36,
TotalGeoPrim = 37,
TotalMesh = 38,
ThreadCount = 39
}
/// <summary>
@ -175,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
// saved last reported value so there is something available for llGetRegionFPS
private float lastReportedSimFPS;
private float[] lastReportedSimStats = new float[22];
private float[] lastReportedSimStats = new float[m_statisticArraySize];
private float m_pfps;
/// <summary>
@ -202,6 +211,8 @@ namespace OpenSim.Region.Framework.Scenes
private int m_rootAgents;
private int m_childAgents;
private int m_numPrim;
private int m_numGeoPrim;
private int m_numMesh;
private int m_inPacketsPerSecond;
private int m_outPacketsPerSecond;
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
// 10 by default but can be changed by the OpenSim.ini configuration file
// 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,
// 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
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 RegionInfo ReportingRegion;
@ -246,11 +264,13 @@ namespace OpenSim.Region.Framework.Scenes
{
// Initialize the different frame time arrays to the correct sizes
m_totalFrameTimeMilliseconds = new double[m_numberFramesStored];
m_simulationFrameTimeMilliseconds = new
double[m_numberFramesStored];
m_simulationFrameTimeMilliseconds = new double[m_numberFramesStored];
m_physicsFrameTimeMilliseconds = 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_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
@ -284,13 +304,14 @@ namespace OpenSim.Region.Framework.Scenes
StatsManager.RegisterStat(SlowFramesStat);
}
public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene)
{
// Store the number of frames from the OpenSim.ini configuration
// file
// Store the number of frames from the OpenSim.ini configuration file
m_numberFramesStored = numberOfFrames;
}
public void Close()
{
m_report.Elapsed -= TriggerStatsHeartbeat;
@ -328,11 +349,17 @@ namespace OpenSim.Region.Framework.Scenes
double simulationSumFrameTime;
double physicsSumFrameTime;
double networkSumFrameTime;
float frameDilation;
int currentFrame;
if (!m_scene.Active)
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();
// Know what's not thread safe in Mono... modifying timers.
@ -354,21 +381,21 @@ namespace OpenSim.Region.Framework.Scenes
#region various statistic googly moogly
// ORIGINAL code commented out until we have time to add our own
// statistics to the statistics window, this will be done as a
// new section given the title of our current project
// ORIGINAL code commented out until we have time to add our own
// statistics to the statistics window, this will be done as a
// new section given the title of our current project
// We're going to lie about the FPS because we've been lying since 2008. The actual FPS is currently
// locked at a maximum of 11. Maybe at some point this can change so that we're not lying.
//int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor);
int reportedFPS = m_fps;
int reportedFPS = m_fps;
// save the reported value so there is something available for llGetRegionFPS
lastReportedSimFPS = reportedFPS / m_statsUpdateFactor;
// ORIGINAL code commented out until we have time to add our own
// statistics to the statistics window
// ORIGINAL code commented out until we have time to add our own
// statistics to the statistics window
//float physfps = ((m_pfps / 1000));
float physfps = m_numberPhysicsFrames;
float physfps = m_numberPhysicsFrames;
//if (physfps > 600)
//physfps = physfps - (physfps - 600);
@ -381,6 +408,8 @@ namespace OpenSim.Region.Framework.Scenes
m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
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_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
@ -406,7 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
if (framesUpdated == 0)
framesUpdated = 1;
for (int i = 0; i < 22; i++)
for (int i = 0; i < m_statisticArraySize; i++)
{
sb[i] = new SimStatsPacket.StatBlock();
}
@ -431,6 +460,19 @@ namespace OpenSim.Region.Framework.Scenes
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].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
@ -455,30 +497,27 @@ namespace OpenSim.Region.Framework.Scenes
sb[7].StatID = (uint) Stats.ActivePrim;
sb[7].StatValue = m_activePrim;
// ORIGINAL code commented out until we have time to add our own
// statistics to the statistics window
// ORIGINAL code commented out until we have time to add our own
// statistics to the statistics window
sb[8].StatID = (uint)Stats.FrameMS;
//sb[8].StatValue = m_frameMS / framesUpdated;
sb[8].StatValue = (float) totalSumFrameTime /
m_numberFramesStored;
sb[8].StatValue = (float) totalSumFrameTime / m_numberFramesStored;
sb[9].StatID = (uint)Stats.NetMS;
//sb[9].StatValue = m_netMS / framesUpdated;
sb[9].StatValue = (float) networkSumFrameTime /
m_numberFramesStored;
sb[9].StatValue = (float) networkSumFrameTime / m_numberFramesStored;
sb[10].StatID = (uint)Stats.PhysicsMS;
//sb[10].StatValue = m_physicsMS / framesUpdated;
sb[10].StatValue = (float) physicsSumFrameTime /
m_numberFramesStored;
sb[10].StatValue = (float) physicsSumFrameTime / m_numberFramesStored;
sb[11].StatID = (uint)Stats.ImageMS ;
sb[11].StatValue = m_imageMS / framesUpdated;
sb[12].StatID = (uint)Stats.OtherMS;
//sb[12].StatValue = m_otherMS / framesUpdated;
sb[12].StatValue = (float) simulationSumFrameTime /
m_numberFramesStored;
sb[12].StatValue = (float) simulationSumFrameTime /
m_numberFramesStored;
sb[13].StatID = (uint)Stats.InPacketsPerSecond;
sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor);
@ -507,7 +546,28 @@ namespace OpenSim.Region.Framework.Scenes
sb[21].StatID = (uint)Stats.SimSpareMs;
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;
}
@ -686,31 +746,31 @@ namespace OpenSim.Region.Framework.Scenes
m_otherMS += ms;
}
public void addPhysicsFrame(int frames)
{
// Add the number of physics frames to the correct total physics
// frames
m_numberPhysicsFrames += frames;
}
public void addPhysicsFrame(int frames)
{
// Add the number of physics frames to the correct total physics
// frames
m_numberPhysicsFrames += frames;
}
public void addFrameTimeMilliseconds(double total, double simulation,
double physics, double network)
{
// Save the frame times from the current frame into the appropriate
// arrays
m_totalFrameTimeMilliseconds[m_nextLocation] = total;
m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation;
m_physicsFrameTimeMilliseconds[m_nextLocation] = physics;
m_networkFrameTimeMilliseconds[m_nextLocation] = network;
public void addFrameTimeMilliseconds(double total, double simulation,
double physics, double network)
{
// Save the frame times from the current frame into the appropriate
// arrays
m_totalFrameTimeMilliseconds[m_nextLocation] = total;
m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation;
m_physicsFrameTimeMilliseconds[m_nextLocation] = physics;
m_networkFrameTimeMilliseconds[m_nextLocation] = network;
// Update to the next location in the list
m_nextLocation++;
// Update to the next location in the list
m_nextLocation++;
// Since the list will begin to overwrite the oldest frame values
// first, the next location needs to loop back to the beginning of the
// list whenever it reaches the end
m_nextLocation = m_nextLocation % m_numberFramesStored;
}
// Since the list will begin to overwrite the oldest frame values
// first, the next location needs to loop back to the beginning of the
// list whenever it reaches the end
m_nextLocation = m_nextLocation % m_numberFramesStored;
}
public void AddPendingDownloads(int count)
{
@ -734,6 +794,31 @@ namespace OpenSim.Region.Framework.Scenes
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
public Dictionary<string, float> GetExtraSimStats()

View File

@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Remoting.Lifetime;
@ -221,15 +222,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected float m_primSafetyCoeffX = 2.414214f;
protected float m_primSafetyCoeffY = 2.414214f;
protected float m_primSafetyCoeffZ = 1.618034f;
protected float m_floatToleranceInCastRay = 0.000001f;
protected float m_floatTolerance2InCastRay = 0.0001f;
protected bool m_useCastRayV3 = false;
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_maxHitsPerPrimInCastRay = 16;
protected int m_maxHitsPerObjectInCastRay = 16;
protected bool m_detectExitsInCastRay = false;
protected bool m_filterPartsInCastRay = 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
//as custom headers by llHTTPRequest.
@ -336,15 +349,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX);
m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY);
m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ);
m_useCastRayV3 = lslConfig.GetBoolean("UseLlCastRayV3", m_useCastRayV3);
m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay);
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_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay);
m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay);
m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay);
m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay);
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"];
@ -5777,7 +5800,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_String llGetEnv(LSL_String name)
{
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";
}
@ -5785,14 +5812,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
return World.RegionInfo.EstateSettings.EstateID.ToString();
}
else if (name == "estate_name")
{
return World.RegionInfo.EstateSettings.EstateName;
}
else if (name == "frame_number")
{
return World.Frame.ToString();
}
else if (name == "region_cpu_ratio")
{
return "1";
}
else if (name == "region_idle")
{
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")
{
return "OpenSim";
@ -5801,6 +5851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
return World.GetSimulatorVersion();
}
else if (name == "simulator_hostname")
{
IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
return UrlModule.ExternalHostNameForLSL;
}
else
{
return "";
@ -13811,8 +13866,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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();
m_host.AddScriptLPS(1);
@ -14003,29 +14062,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
/// <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
/// Uses pure geometry, bounding shapes, meshing and no physics
/// for prims, sculpts, meshes, avatars and terrain.
/// Implements all flags, reject types and data flags.
/// Can handle both objects/groups and prims/parts, by config.
/// May give poor results with multi-part meshes where "root"
/// part doesn't dominate, owing to "guessed" bounding boxes.
/// May sometimes be inaccurate owing to calculation precision
/// and a bug in libopenmetaverse PrimMesher.
/// May sometimes be inaccurate owing to calculation precision,
/// meshing detail level and a bug in libopenmetaverse PrimMesher.
/// </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
if (m_useCastRayV1)
return llCastRayV1(start, end, options);
m_host.AddScriptLPS(1);
LSL_List result = new LSL_List();
// 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
m_host.AddScriptLPS(1);
List<RayHit> rayHits = new List<RayHit>();
LSL_List result = new LSL_List();
float tol = m_floatToleranceInCastRay;
float tol2 = m_floatTolerance2InCastRay;
Vector3 pos1Ray = start;
Vector3 pos2Ray = end;
// Get input options
int rejectTypes = 0;
@ -14054,25 +14159,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0);
// Calculate some basic parameters
Vector3 ray = end - start;
float rayLength = ray.Length();
Vector3 vecRay = pos2Ray - pos1Ray;
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;
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));
return result;
}
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
World.ForEachSOG(
delegate(SceneObjectGroup group)
@ -14115,83 +14214,118 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!doPart)
continue;
}
// Parse prim/part if passed filters
// Estimate bounding box from size box
Vector3 scaleSafe = part.Scale;
// Parse prim/part and project ray if passed filters
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)
scaleSafe = scaleSafe * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ));
// Filter parts by bounding shapes
Vector3 posPartRel = part.GetWorldPosition() + posProj;
Vector3 posPartProj = posPartRel * rotProj;
if (InBoundingShapes(ray, rayLength, scaleSafe, posPartRel, posPartProj, rotProj))
shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ));
shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol));
if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
{
// Prepare data needed to check for ray hits
RayTrans rayTrans = new RayTrans();
rayTrans.PartId = part.UUID;
rayTrans.GroupId = part.ParentGroup.UUID;
rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0;
rayTrans.Scale = part.Scale;
rayTrans.PositionPartProj = posPartProj;
rayTrans.PositionProj = posProj;
rayTrans.RotationPartProj = rotProj * part.GetWorldRotation();
rayTrans.RotationBack = rotBack;
rayTrans.NeedsEnds = true;
rayTrans.RayLength = rayLength;
rayTrans.Tolerance = tol;
rayTrans.Tolerance2 = tol2;
rayTrans.ScalePart = scalePart;
rayTrans.PositionPart = posPart;
rayTrans.RotationPart = rotPart;
rayTrans.ShapeNeedsEnds = true;
rayTrans.Position1Ray = pos1Ray;
rayTrans.Position1RayProj = pos1RayProj;
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
// Make an OMV prim to be able to mesh part
Primitive omvPrim = part.Shape.ToOmvPrimitive(posPartProj, rayTrans.RotationPartProj);
byte[] sculptAsset = null;
if (omvPrim.Sculpt != null)
sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
// 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;
// When part is mesh, get and check mesh
if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
// Try to get cached mesh if configured
ulong meshKey = 0;
FacetedMesh mesh = null;
if (m_useMeshCacheInCastRay)
{
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
FacetedMesh mesh = null;
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh);
meshAsset = null;
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
mesh = null;
meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod));
lock (m_cachedMeshes)
{
m_cachedMeshes.TryGetValue(meshKey, out mesh);
}
}
// When part is sculpt, create and check mesh
// 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)
// Create mesh if no cached mesh
if (mesh == null)
{
IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
if (imgDecoder != null)
// Make an OMV prim to be able to mesh part
Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart);
byte[] sculptAsset = null;
if (omvPrim.Sculpt != null)
sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
// When part is mesh, get mesh
if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
{
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
if (sculpt != null)
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh);
meshAsset = null;
}
// When part is sculpt, create mesh
// 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)
{
IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
if (imgDecoder != null)
{
SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium);
sculpt.Dispose();
AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
mesh = null;
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
if (sculpt != null)
{
mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
sculpt.Dispose();
}
}
}
// When part is shape, create mesh
else if (omvPrim.Sculpt == null)
{
if (
omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 &&
omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 &&
omvPrim.PrimData.PathSkew == 0.0 &&
omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
)
rayTrans.ShapeNeedsEnds = false;
mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay);
}
// Cache mesh if configured
if (m_useMeshCacheInCastRay && mesh != null)
{
lock(m_cachedMeshes)
{
if (!m_cachedMeshes.ContainsKey(meshKey))
m_cachedMeshes.Add(meshKey, mesh);
}
}
}
// When part is prim, create and check mesh
else if (omvPrim.Sculpt == null)
{
if (
omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 &&
omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 &&
omvPrim.PrimData.PathSkew == 0.0 &&
omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
)
rayTrans.NeedsEnds = false;
SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
mesh = null;
}
// Check mesh for ray hits
AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
mesh = null;
}
}
}
@ -14205,38 +14339,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
World.ForEachRootScenePresence(
delegate (ScenePresence sp)
{
// Parse avatar
// Get bounding box
Vector3 lower;
Vector3 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
Vector3 posPartRel = sp.AbsolutePosition + posProj + (lower + upper) * 0.5f * sp.Rotation;
Vector3 posPartProj = posPartRel * rotProj;
if (InBoundingShapes(ray, rayLength, scale, posPartRel, posPartProj, rotProj))
// Filter avatars by shape bounding boxes
Vector3 shapeBoxMax = new Vector3(0.5f + tol, 0.5f + tol, 0.5f + tol);
if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
{
// Prepare data needed to check for ray hits
RayTrans rayTrans = new RayTrans();
rayTrans.PartId = 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.Scale = scale;
rayTrans.PositionPartProj = posPartProj;
rayTrans.PositionProj = posProj;
rayTrans.RotationPartProj = rotProj * sp.Rotation;
rayTrans.RotationBack = rotBack;
rayTrans.NeedsEnds = false;
rayTrans.RayLength = rayLength;
rayTrans.Tolerance = tol;
rayTrans.Tolerance2 = tol2;
rayTrans.ScalePart = scalePart;
rayTrans.PositionPart = posPart;
rayTrans.RotationPart = rotPart;
rayTrans.ShapeNeedsEnds = false;
rayTrans.Position1Ray = pos1Ray;
rayTrans.Position1RayProj = pos1RayProj;
rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
// Make OMV prim, create and check mesh
Primitive omvPrim = MakeOpenMetaversePrim(scale, posPartProj, rayTrans.RotationPartProj, ScriptBaseClass.PRIM_TYPE_SPHERE);
SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
// Try to get cached mesh if configured
PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere();
int lod = (int)m_avatarLodInCastRay;
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;
}
}
@ -14248,32 +14415,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
// Parse terrain
// Mesh terrain and check projected bounding box
Vector3 posPartProj = posProj * rotProj;
Quaternion rotPartProj = rotProj;
// Mesh terrain and check bounding box
Vector3 lower;
Vector3 upper;
List<Tri> triangles = TrisFromHeightmapUnderRay(start, end, out lower, out upper);
Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue);
int dummy = 0;
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)
List<Tri> triangles = TrisFromHeightmapUnderRay(pos1Ray, pos2Ray, out lower, out upper);
lower.Z -= tol;
upper.Z += tol;
if ((pos1Ray.Z >= lower.Z || pos2Ray.Z >= lower.Z) && (pos1Ray.Z <= upper.Z || pos2Ray.Z <= upper.Z))
{
// Prepare data needed to check for ray hits
RayTrans rayTrans = new RayTrans();
rayTrans.PartId = UUID.Zero;
rayTrans.GroupId = UUID.Zero;
rayTrans.Link = 0;
rayTrans.Scale = new Vector3 (1.0f, 1.0f, 1.0f);
rayTrans.PositionPartProj = posPartProj;
rayTrans.PositionProj = posProj;
rayTrans.RotationPartProj = rotPartProj;
rayTrans.RotationBack = rotBack;
rayTrans.NeedsEnds = true;
rayTrans.RayLength = rayLength;
rayTrans.Tolerance = tol;
rayTrans.Tolerance2 = tol2;
rayTrans.ScalePart = new Vector3 (1.0f, 1.0f, 1.0f);
rayTrans.PositionPart = Vector3.Zero;
rayTrans.RotationPart = Quaternion.Identity;
rayTrans.ShapeNeedsEnds = true;
rayTrans.Position1Ray = pos1Ray;
rayTrans.Position1RayProj = pos1Ray;
rayTrans.VectorRayProj = vecRay;
// Check mesh
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_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;
}
@ -14358,15 +14533,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public UUID PartId;
public UUID GroupId;
public int Link;
public Vector3 Scale;
public Vector3 PositionPartProj;
public Vector3 PositionProj;
public Quaternion RotationPartProj;
public Quaternion RotationBack;
public bool NeedsEnds;
public float RayLength;
public float Tolerance;
public float Tolerance2;
public Vector3 ScalePart;
public Vector3 PositionPart;
public Quaternion RotationPart;
public bool ShapeNeedsEnds;
public Vector3 Position1Ray;
public Vector3 Position1RayProj;
public Vector3 VectorRayProj;
}
/// <summary>
@ -14383,21 +14556,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
/// <summary>
/// Helper to parse SimpleMesh for ray hits.
/// Struct for llCastRay throttle data.
/// </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)
{
// 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)
{
for (int i = 0; i < mesh.Indices.Count; i += 3)
for (sign = -1; sign <= 1; sign += 2)
{
Tri triangle = new Tri();
triangle.p1 = mesh.Vertices[mesh.Indices[i]].Position;
triangle.p2 = mesh.Vertices[mesh.Indices[i + 1]].Position;
triangle.p3 = mesh.Vertices[mesh.Indices[i + 2]].Position;
AddRayInTri(triangle, rayTrans, ref rayHits);
dist = ((float)sign * shapeBoxMax.X - pos1RayProj.X) / vecRayProj.X;
posProj = pos1RayProj + vecRayProj * dist;
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>
@ -14409,7 +14635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
foreach (Face face in mesh.Faces)
{
for (int i = 0; i <face.Indices.Count; i += 3)
for (int i = 0; i < face.Indices.Count; i += 3)
{
Tri triangle = new Tri();
triangle.p1 = face.Vertices[face.Indices[i]].Position;
@ -14435,23 +14661,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
/// <summary>
/// Helper to add ray hit in a Tri (triangle).
/// </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
float distance;
Vector3 posHit;
Vector3 normal;
if (HitRayInTri(triangle, rayTrans, out distance, out posHit, out normal))
Vector3 posHitProj;
Vector3 normalProj;
if (HitRayInTri(triProj, rayTrans.Position1RayProj, rayTrans.VectorRayProj, out posHitProj, out normalProj))
{
// Project hit part back to normal coordinate system
Vector3 posPart = rayTrans.PositionPartProj * rayTrans.RotationBack - rayTrans.PositionProj;
// 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)
// Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) face plane through shape center
if (Math.Abs(Vector3.Dot(posHitProj, normalProj)) < m_floatToleranceInCastRay && !rayTrans.ShapeNeedsEnds)
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--)
{
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;
}
@ -14468,76 +14699,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
/// <summary>
/// Helper to find ray hit in a Tri (triangle).
/// Helper to find ray hit in triangle
/// </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
distance = 0.0f;
posHit = Vector3.Zero;
normal = Vector3.Zero;
float tol = rayTrans.Tolerance;
float tol = m_floatToleranceInCastRay;
posHitProj = Vector3.Zero;
// Project triangle on X-Y plane
Vector3 pos1 = triangle.p1 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
Vector3 pos2 = triangle.p2 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
Vector3 pos3 = triangle.p3 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
// Calculate triangle edge vectors
Vector3 vec1Proj = triProj.p2 - triProj.p1;
Vector3 vec2Proj = triProj.p3 - triProj.p2;
Vector3 vec3Proj = triProj.p1 - triProj.p3;
// Check if ray/origo inside triangle bounding rectangle
Vector3 lower = Vector3.Min(pos1, Vector3.Min(pos2, pos3));
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)
// Calculate triangle normal
normalProj = Vector3.Cross(vec1Proj, vec2Proj);
// Skip if degenerate triangle or ray parallell with triangle plane
float divisor = Vector3.Dot(vecRayProj, normalProj);
if (Math.Abs(divisor) < tol)
return false;
// Check if ray/origo inside every edge or reverse "outside" every edge on exit
float dist;
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))
// Skip if exit and not configured to detect
if (divisor > tol && !m_detectExitsInCastRay)
return false;
// Calculate normal
Vector3 normalProj = Vector3.Cross(vec1, vec2);
float normalLength = normalProj.Length();
// 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)
// Skip if outside ray ends
float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor;
if (distanceProj < -tol || distanceProj > 1 + tol)
return false;
// Calculate distance
distance = Vector3.Dot(normalProj, pos2) / normalProj.Z * -1.0f;
// Skip if outside ray
if (distance < -tol || distance > rayTrans.RayLength + tol)
// Calculate hit position in triangle
posHitProj = pos1RayProj + vecRayProj * distanceProj;
// 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;
// Calculate projected hit position
Vector3 posHitProj = new Vector3(0.0f, 0.0f, -distance);
// Project hit back to normal coordinate system
posHit = posHitProj * rayTrans.RotationBack - rayTrans.PositionProj;
normal = normalProj * rayTrans.RotationBack;
// Skip if outside triangle
if (
Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol ||
Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol ||
Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol
)
return false;
// Return hit
return true;
}
@ -14660,24 +14871,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1);
Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]);
// Adjust bounding box
zLower = Math.Min(zLower, pos1.Z);
zUpper = Math.Max(zUpper, pos1.Z);
zLower = Math.Min(zLower, pos2.Z);
zUpper = Math.Max(zUpper, pos2.Z);
// Corner 3 of 1x1 rectangle
x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1);
y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]);
// Adjust bounding box
zLower = Math.Min(zLower, pos1.Z);
zUpper = Math.Max(zUpper, pos1.Z);
zLower = Math.Min(zLower, pos3.Z);
zUpper = Math.Max(zUpper, pos3.Z);
// Corner 4 of 1x1 rectangle
x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1);
y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]);
// Adjust bounding box
zLower = Math.Min(zLower, pos1.Z);
zUpper = Math.Max(zUpper, pos1.Z);
zLower = Math.Min(zLower, pos4.Z);
zUpper = Math.Max(zUpper, pos4.Z);
// Add triangle 1
Tri triangle1 = new Tri();
@ -14694,25 +14905,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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>
/// Helper to get link number for a UUID.
/// </summary>

36
OpenSim/Region/ScriptEngine/XEngine/XEngine.cs Normal file → Executable file
View File

@ -1872,6 +1872,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
IScriptInstance instance = GetInstance(itemID);
if (instance != null)
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)
@ -1879,6 +1885,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
IScriptInstance instance = GetInstance(itemID);
if (instance != null)
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)
@ -1888,6 +1900,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
instance.Start();
else
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)
@ -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_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)
@ -2393,6 +2417,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
instance.Suspend();
// else
// 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)
@ -2404,6 +2434,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
instance.Resume();
// else
// 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)

Binary file not shown.

0
bin/LukeSkywalker.IPNetwork.dll Normal file → Executable file
View File

View File

@ -227,63 +227,6 @@
<param name="intHostEnd"></param>
<returns></returns>
</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)">
<summary>
@ -345,5 +288,62 @@
<param name="c"></param>
<returns></returns>
</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>
</doc>

Binary file not shown.

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.

View File

@ -296,7 +296,7 @@
; Simulator Stats URI
; Enable JSON simulator data by setting a URI name (case sensitive)
; Returns regular sim stats (SimFPS, ...)
; Stats_URI = "jsonSimStats"
Stats_URI = "jsonSimStats"
; Simulator StatsManager URI
; 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())
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.
; Speeds up calculations but can make them inaccurate, in some cases very inaccurate.
UseSimpleBoxesInGetBoundingBox = false
@ -1494,32 +1489,72 @@
; Worst case is twisted tube, 0.5+sqrt(1.25)
PrimBoundingBoxSafetyCoefficientZ = 1.618034
; Accepted calculation precision error in calculations in llCastRay
FloatToleranceInLlCastRay = 0.000001
; Use llCastRay V3 if true
; 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
FloatTolerance2InLlCastRay = 0.0001
; Accepted calculation precision error in calculations in llCastRay V3
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
; Maximum number of returned hits per prim from llCastRay
; Maximum number of returned hits per prim from llCastRay V3
MaxHitsPerPrimInLlCastRay = 16
; Maximum number of returned hits per object from llCastRay
; Maximum number of returned hits per object from llCastRay V3
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
; Filter on parts instead of groups in llCastRay if true
; Filter on parts instead of groups in llCastRay V3 if true
FilterPartsInLlCastRay = false
; Detect attachments in llCastRay if true
; Detect attachments in llCastRay V3 if true
DoAttachmentsInLlCastRay = false
; Use legacy version 1 of llCastRay if true
UseLlCastRayV1 = true
; Throttle period length in ms before which all old llCastRay use is discarded in llCastRay V3
; 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]
; The following set of configs pertains to search.
@ -1547,6 +1582,7 @@
; data service
;DATA_SRV_MISearch = "http://metaverseink.com/cgi-bin/register.py"
[Economy]
; 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).