From ee485187db20de24718b394d9ec6f503c578e491 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 30 Dec 2016 04:57:34 +0000 Subject: remove a gc.collect that isn't very usefull --- OpenSim/Region/PhysicsModules/Ode/OdeScene.cs | 4495 +++++++++++-------------- 1 file changed, 1873 insertions(+), 2622 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs index ed2aad4..410463c 100644 --- a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs +++ b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs @@ -25,52 +25,54 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// changes for varsize regions -// note that raycasts need to have limited range -// (even in normal regions) -// or application thread stack may just blowup -// see RayCast(ODERayCastRequest req) +// Revision 2011/12/13 by Ubit Umarov +//#define SPAM using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Linq; using System.Reflection; -using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Threading; +using System.IO; +using System.Diagnostics; using log4net; using Nini.Config; using Mono.Addins; -using OpenMetaverse; +using OdeAPI; using OpenSim.Framework; -using OpenSim.Region.PhysicsModules.SharedBase; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.PhysicsModules.SharedBase; +using OpenMetaverse; -namespace OpenSim.Region.PhysicsModule.ODE +namespace OpenSim.Region.PhysicsModule.ubOde { - public enum StatusIndicators : int - { - Generic = 0, - Start = 1, - End = 2 - } + // colision flags of things others can colide with + // rays, sensors, probes removed since can't be colided with + // The top space where things are placed provided further selection + // ie physical are in active space nonphysical in static + // this should be exclusive as possible [Flags] - public enum CollisionCategories : int + public enum CollisionCategories : uint { Disabled = 0, - Geom = 0x00000001, - Body = 0x00000002, - Space = 0x00000004, - Character = 0x00000008, - Land = 0x00000010, - Water = 0x00000020, - Wind = 0x00000040, - Sensor = 0x00000080, - Selected = 0x00000100 + //by 'things' types + Space = 0x01, + Geom = 0x02, // aka prim/part + Character = 0x04, + Land = 0x08, + Water = 0x010, + + // by state + Phantom = 0x01000, + VolumeDtc = 0x02000, + Selected = 0x04000, + NoShape = 0x08000, + + + All = 0xffffffff } /// @@ -91,908 +93,631 @@ namespace OpenSim.Region.PhysicsModule.ODE /// Plastic = 5, /// - Rubber = 6 - } + Rubber = 6, - public class OdeScene : PhysicsScene + light = 7 // compatibility with old viewers + } + + public enum changes : int { - private readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString()); - - // private Dictionary m_storedCollisions = new Dictionary(); - - /// - /// Provide a sync object so that only one thread calls d.Collide() at a time across all OdeScene instances. - /// - /// - /// With ODE as of r1755 (though also tested on r1860), only one thread can call d.Collide() at a - /// time, even where physics objects are in entirely different ODE worlds. This is because generating contacts - /// uses a static cache at the ODE level. - /// - /// Without locking, simulators running multiple regions will eventually crash with a native stack trace similar - /// to - /// - /// mono() [0x489171] - /// mono() [0x4d154f] - /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f6ded592c60] - /// .../opensim/bin/libode-x86_64.so(_ZN6Opcode11OBBCollider8_CollideEPKNS_14AABBNoLeafNodeE+0xd7a) [0x7f6dd822628a] - /// - /// ODE provides an experimental option to cache in thread local storage but compiling ODE with this option - /// causes OpenSimulator to immediately crash with a native stack trace similar to - /// - /// mono() [0x489171] - /// mono() [0x4d154f] - /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f03c9849c60] - /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82] - /// - internal static Object UniversalColliderSyncObject = new Object(); - internal static Object SimulationLock = new Object(); - - /// - /// Is stats collecting enabled for this ODE scene? - /// - public bool CollectStats { get; set; } - - /// - /// Statistics for this scene. - /// - private Dictionary m_stats = new Dictionary(); - - /// - /// Stat name for total number of avatars in this ODE scene. - /// - public const string ODETotalAvatarsStatName = "ODETotalAvatars"; - - /// - /// Stat name for total number of prims in this ODE scene. - /// - public const string ODETotalPrimsStatName = "ODETotalPrims"; - - /// - /// Stat name for total number of prims with active physics in this ODE scene. - /// - public const string ODEActivePrimsStatName = "ODEActivePrims"; - - /// - /// Stat name for the total time spent in ODE frame processing. - /// - /// - /// A sanity check for the main scene loop physics time. - /// - public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; - - /// - /// Stat name for time spent processing avatar taints per frame - /// - public const string ODEAvatarTaintMsStatName = "ODEAvatarTaintFrameMS"; - - /// - /// Stat name for time spent processing prim taints per frame - /// - public const string ODEPrimTaintMsStatName = "ODEPrimTaintFrameMS"; - - /// - /// Stat name for time spent calculating avatar forces per frame. - /// - public const string ODEAvatarForcesFrameMsStatName = "ODEAvatarForcesFrameMS"; - - /// - /// Stat name for time spent calculating prim forces per frame - /// - public const string ODEPrimForcesFrameMsStatName = "ODEPrimForcesFrameMS"; - - /// - /// Stat name for time spent fulfilling raycasting requests per frame - /// - public const string ODERaycastingFrameMsStatName = "ODERaycastingFrameMS"; - - /// - /// Stat name for time spent in native code that actually steps through the simulation. - /// - public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; - - /// - /// Stat name for the number of milliseconds that ODE spends in native space collision code. - /// - public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS"; - - /// - /// Stat name for milliseconds that ODE spends in native geom collision code. - /// - public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; - - /// - /// Time spent in collision processing that is not spent in native space or geom collision code. - /// - public const string ODEOtherCollisionFrameMsStatName = "ODEOtherCollisionFrameMS"; - - /// - /// Stat name for time spent notifying listeners of collisions - /// - public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS"; - - /// - /// Stat name for milliseconds spent updating avatar position and velocity - /// - public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS"; - - /// - /// Stat name for the milliseconds spent updating prim position and velocity - /// - public const string ODEPrimUpdateFrameMsStatName = "ODEPrimUpdateFrameMS"; + Add = 0, // arg null. finishs the prim creation. should be used internally only ( to remove later ?) + Remove, + Link, // arg AuroraODEPrim new parent prim or null to delink. Makes the prim part of a object with prim parent as root + // or removes from a object if arg is null + DeLink, + Position, // arg Vector3 new position in world coords. Changes prim position. Prim must know if it is root or child + Orientation, // arg Quaternion new orientation in world coords. Changes prim position. Prim must know it it is root or child + PosOffset, // not in use + // arg Vector3 new position in local coords. Changes prim position in object + OriOffset, // not in use + // arg Vector3 new position in local coords. Changes prim position in object + Velocity, + TargetVelocity, + AngVelocity, + Acceleration, + Force, + Torque, + Momentum, + + AddForce, + AddAngForce, + AngLock, + + Buoyancy, + + PIDTarget, + PIDTau, + PIDActive, + + PIDHoverHeight, + PIDHoverType, + PIDHoverTau, + PIDHoverActive, + + Size, + AvatarSize, + Shape, + PhysRepData, + AddPhysRep, + + CollidesWater, + VolumeDtc, + + Physical, + Phantom, + Selected, + disabled, + building, + + VehicleType, + VehicleFloatParam, + VehicleVectorParam, + VehicleRotationParam, + VehicleFlags, + SetVehicle, + + Null //keep this last used do dim the methods array. does nothing but pulsing the prim + } - /// - /// Stat name for avatar collisions with another entity. - /// - public const string ODEAvatarContactsStatsName = "ODEAvatarContacts"; + public struct ODEchangeitem + { + public PhysicsActor actor; + public OdeCharacter character; + public changes what; + public Object arg; + } - /// - /// Stat name for prim collisions with another entity. - /// - public const string ODEPrimContactsStatName = "ODEPrimContacts"; + public class ODEScene : PhysicsScene + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /// - /// Used to hold tick numbers for stat collection purposes. - /// - private int m_nativeCollisionStartTick; + public bool m_OSOdeLib = false; + public Scene m_frameWorkScene = null; - /// - /// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback. - /// - private bool m_inCollisionTiming; +// private int threadid = 0; - /// - /// A temporary holder for the number of avatar collisions in a frame, so we can work out how many object - /// collisions occured using the _perloopcontact if stats collection is enabled. - /// - private int m_tempAvatarCollisionsThisFrame; +// const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; - /// - /// Used in calculating physics frame time dilation - /// - private int tickCountFrameRun; + const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; + const float comumContactERP = 0.75f; + const float comumContactCFM = 0.0001f; + const float comumContactSLIP = 0f; + + float frictionMovementMult = 0.8f; - /// - /// Used in calculating physics frame time dilation - /// - private int latertickcount; + float TerrainBounce = 0.1f; + float TerrainFriction = 0.3f; - private Random fluidRandomizer = new Random(Environment.TickCount); + public float AvatarFriction = 0;// 0.9f * 0.5f; + // this netx dimensions are only relevant for terrain partition (mega regions) + // WorldExtents below has the simulation dimensions + // they should be identical except on mega regions private uint m_regionWidth = Constants.RegionSize; private uint m_regionHeight = Constants.RegionSize; - private float ODE_STEPSIZE = 0.0178f; - private float metersInSpace = 29.9f; + public float ODE_STEPSIZE = 0.020f; + public float HalfOdeStep = 0.01f; + public int odetimestepMS = 20; // rounded + private float metersInSpace = 25.6f; private float m_timeDilation = 1.0f; + private DateTime m_lastframe; + private DateTime m_lastMeshExpire; + public float gravityx = 0f; public float gravityy = 0f; public float gravityz = -9.8f; - public float AvatarTerminalVelocity { get; set; } - - private float contactsurfacelayer = 0.001f; - - private int HashspaceLow = -5; - private int HashspaceHigh = 12; - private float waterlevel = 0f; private int framecount = 0; - //private int m_returncollisions = 10; - - private IntPtr contactgroup; - -// internal IntPtr WaterGeom; - - private float nmTerrainContactFriction = 255.0f; - private float nmTerrainContactBounce = 0.1f; - private float nmTerrainContactERP = 0.1025f; - - private float mTerrainContactFriction = 75f; - private float mTerrainContactBounce = 0.1f; - private float mTerrainContactERP = 0.05025f; - - private float nmAvatarObjectContactFriction = 250f; - private float nmAvatarObjectContactBounce = 0.1f; - - private float mAvatarObjectContactFriction = 75f; - private float mAvatarObjectContactBounce = 0.1f; - - private float avPIDD = 3200f; - private float avPIDP = 1400f; - private float avCapRadius = 0.37f; - private float avStandupTensor = 2000000f; - - /// - /// true = old compatibility mode with leaning capsule; false = new corrected mode - /// - /// - /// Even when set to false, the capsule still tilts but this is done in a different way. - /// - public bool IsAvCapsuleTilted { get; private set; } private float avDensity = 80f; private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorRun = 0.8f; private float minimumGroundFlightOffset = 3f; public float maximumMassObject = 10000.01f; + public float geomDefaultDensity = 10.0f; - public bool meshSculptedPrim = true; - public bool forceSimplePrimMeshing = false; - - public float meshSculptLOD = 32; - public float MeshSculptphysicalLOD = 16; - - public float geomDefaultDensity = 10.000006836f; - - public int geomContactPointsStartthrottle = 3; - public int geomUpdatesPerThrottledUpdate = 15; - private const int avatarExpectedContacts = 3; + public float maximumAngularVelocity = 12.0f; // default 12rad/s + public float maxAngVelocitySQ = 144f; // squared value public float bodyPIDD = 35f; public float bodyPIDG = 25; - public int bodyFramesAutoDisable = 20; - - private bool m_filterCollisions = true; + public int bodyFramesAutoDisable = 5; private d.NearCallback nearCallback; - public d.TriCallback triCallback; - public d.TriArrayCallback triArrayCallback; - - /// - /// Avatars in the physics scene. - /// - private readonly HashSet _characters = new HashSet(); - - /// - /// Prims in the physics scene. - /// - private readonly HashSet _prims = new HashSet(); - - /// - /// Prims in the physics scene that are subject to physics, not just collisions. - /// - private readonly HashSet _activeprims = new HashSet(); - - /// - /// Prims that the simulator has created/deleted/updated and so need updating in ODE. - /// - private readonly HashSet _taintedPrims = new HashSet(); - - /// - /// Record a character that has taints to be processed. - /// - private readonly HashSet _taintedActors = new HashSet(); - - /// - /// Keep record of contacts in the physics loop so that we can remove duplicates. - /// - private readonly List _perloopContact = new List(); - - /// - /// A dictionary of actors that should receive collision events. - /// - private readonly Dictionary m_collisionEventActors = new Dictionary(); - /// - /// A dictionary of collision event changes that are waiting to be processed. - /// - private readonly Dictionary m_collisionEventActorsChanges = new Dictionary(); + private Dictionary _prims = new Dictionary(); + private HashSet _characters = new HashSet(); + private HashSet _activeprims = new HashSet(); + private HashSet _activegroups = new HashSet(); - /// - /// Maps a unique geometry id (a memory location) to a physics actor name. - /// - /// - /// Only actors participating in collisions have geometries. This has to be maintained separately from - /// actor_name_map because terrain and water currently don't conceptually have a physics actor of their own - /// apart from the singleton PANull - /// - public Dictionary geom_name_map = new Dictionary(); + public OpenSim.Framework.LocklessQueue ChangesQueue = new OpenSim.Framework.LocklessQueue(); /// - /// Maps a unique geometry id (a memory location) to a physics actor. + /// A list of actors that should receive collision events. /// - /// - /// Only actors participating in collisions have geometries. - /// + private List _collisionEventPrim = new List(); + private List _collisionEventPrimRemove = new List(); + + private HashSet _badCharacter = new HashSet(); public Dictionary actor_name_map = new Dictionary(); - /// - /// Defects list to remove characters that no longer have finite positions due to some other bug. - /// - /// - /// Used repeatedly in Simulate() but initialized once here. - /// - private readonly List defects = new List(); + private float contactsurfacelayer = 0.002f; - private bool m_NINJA_physics_joints_enabled = false; - //private Dictionary jointpart_name_map = new Dictionary(); - private readonly Dictionary> joints_connecting_actor = new Dictionary>(); - private d.ContactGeom[] contacts; + private int contactsPerCollision = 80; + internal IntPtr ContactgeomsArray = IntPtr.Zero; + private IntPtr GlobalContactsArray = IntPtr.Zero; + private d.Contact SharedTmpcontact = new d.Contact(); - /// - /// Lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active - /// - private readonly List requestedJointsToBeCreated = new List(); + const int maxContactsbeforedeath = 6000; + private volatile int m_global_contactcount = 0; - /// - /// can lock for longer. accessed only by OdeScene. - /// - private readonly List pendingJoints = new List(); + private IntPtr contactgroup; - /// - /// can lock for longer. accessed only by OdeScene. - /// - private readonly List activeJoints = new List(); + public ContactData[] m_materialContactsData = new ContactData[8]; - /// - /// lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active - /// - private readonly List requestedJointsToBeDeleted = new List(); - - private Object externalJointRequestsLock = new Object(); - private readonly Dictionary SOPName_to_activeJoint = new Dictionary(); - private readonly Dictionary SOPName_to_pendingJoint = new Dictionary(); - private readonly DoubleDictionary RegionTerrain = new DoubleDictionary(); - private readonly Dictionary TerrainHeightFieldHeights = new Dictionary(); - - private d.Contact contact; - private d.Contact TerrainContact; - private d.Contact AvatarMovementprimContact; - private d.Contact AvatarMovementTerrainContact; - private d.Contact WaterContact; - private d.Contact[,] m_materialContacts; - - private int m_physicsiterations = 10; + private IntPtr TerrainGeom; + private float[] TerrainHeightFieldHeight; + private GCHandle TerrainHeightFieldHeightsHandler = new GCHandle(); + + private int m_physicsiterations = 15; private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag - private readonly PhysicsActor PANull = new NullPhysicsActor(); +// private PhysicsActor PANull = new NullPhysicsActor(); private float step_time = 0.0f; + public IntPtr world; - private uint obj2LocalID = 0; - private OdeCharacter cc1; - private OdePrim cp1; - private OdeCharacter cc2; - private OdePrim cp2; - private int p1ExpectedPoints = 0; - private int p2ExpectedPoints = 0; - public IntPtr space; + // split the spaces acording to contents type + // ActiveSpace contains characters and active prims + // StaticSpace contains land and other that is mostly static in enviroment + // this can contain subspaces, like the grid in staticspace + // as now space only contains this 2 top spaces - // split static geometry collision handling into spaces of 30 meters - public IntPtr[,] staticPrimspace; + public IntPtr TopSpace; // the global space + public IntPtr ActiveSpace; // space for active prims + public IntPtr CharsSpace; // space for active prims + public IntPtr StaticSpace; // space for the static things around + public IntPtr GroundSpace; // space for ground - /// - /// Used to lock the entire physics scene. Locked during the main part of Simulate() - /// - internal Object OdeLock = new Object(); + // some speedup variables + private int spaceGridMaxX; + private int spaceGridMaxY; + private float spacesPerMeterX; + private float spacesPerMeterY; - private bool _worldInitialized = false; + // split static geometry collision into a grid as before + private IntPtr[,] staticPrimspace; + private IntPtr[] staticPrimspaceOffRegion; + + public Object OdeLock; + public static Object SimulationLock; public IMesher mesher; - private IConfigSource m_config; + public IConfigSource m_config; public bool physics_logging = false; public int physics_logging_interval = 0; public bool physics_logging_append_existing_logfile = false; - private bool avplanted = false; - private bool av_av_collisions_off = false; + public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); - public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); - public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); + private ODERayCastRequestManager m_rayCastManager; + public ODEMeshWorker m_meshWorker; - private volatile int m_global_contactcount = 0; + /* maybe needed if ode uses tls + private void checkThread() + { - private Vector3 m_worldOffset = Vector3.Zero; - public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); - private PhysicsScene m_parentScene = null; + int th = Thread.CurrentThread.ManagedThreadId; + if(th != threadid) + { + threadid = th; + d.AllocateODEDataForThread(~0U); + } + } + */ - float spacesPerMeterX; - float spacesPerMeterY; - int spaceGridMaxX; - int spaceGridMaxY; + IConfig physicsconfig = null; - private ODERayCastRequestManager m_rayCastManager; - - public Scene m_frameWorkScene = null; + public ODEScene(Scene pscene, IConfigSource psourceconfig, string pname, string pversion, bool pOSOdeLib) + { + OdeLock = new Object(); - public OdeScene(Scene pscene, IConfigSource psourceconfig, string pname, string pversion) - { - m_config = psourceconfig; - m_frameWorkScene = pscene; - EngineType = pname; PhysicsSceneName = EngineType + "/" + pscene.RegionInfo.RegionName; EngineName = pname + " " + pversion; + m_config = psourceconfig; + m_OSOdeLib = pOSOdeLib; + +// m_OSOdeLib = false; //debug - pscene.RegisterModuleInterface(this); - Vector3 extent = new Vector3(pscene.RegionInfo.RegionSizeX, pscene.RegionInfo.RegionSizeY, pscene.RegionInfo.RegionSizeZ); - Initialise(extent); - InitialiseFromConfig(m_config); + m_frameWorkScene = pscene; - // This may not be that good since terrain may not be avaiable at this point - base.Initialise(pscene.PhysicsRequestAsset, - (pscene.Heightmap != null ? pscene.Heightmap.GetFloatsSerialised() : new float[(int)(extent.X * extent.Y)]), - (float)pscene.RegionInfo.RegionSettings.WaterHeight); + m_frameWorkScene.RegisterModuleInterface(this); + Initialization(); + + base.Initialise(m_frameWorkScene.PhysicsRequestAsset, + (m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]), + (float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight); } - public void RegionLoaded() + public void RegionLoaded() { mesher = m_frameWorkScene.RequestModuleInterface(); if (mesher == null) - m_log.WarnFormat("[ODE SCENE]: No mesher in {0}. Things will not work well.", PhysicsSceneName); - - m_frameWorkScene.PhysicsEnabled = true; + { + m_log.ErrorFormat("[ubOde] No mesher. module disabled"); + return; + } + + m_meshWorker = new ODEMeshWorker(this, m_log, mesher, physicsconfig); + m_frameWorkScene.PhysicsEnabled = true; } - /// /// Initiailizes the scene /// Sets many properties that ODE requires to be stable /// These settings need to be tweaked 'exactly' right or weird stuff happens. /// - private void Initialise(Vector3 regionExtent) + private void Initialization() { - WorldExtents.X = regionExtent.X; - m_regionWidth = (uint)regionExtent.X; - WorldExtents.Y = regionExtent.Y; - m_regionHeight = (uint)regionExtent.Y; - + d.AllocateODEDataForThread(~0U); + + SimulationLock = new Object(); + nearCallback = near; + m_rayCastManager = new ODERayCastRequestManager(this); - // Create the world and the first space - world = d.WorldCreate(); - space = d.HashSpaceCreate(IntPtr.Zero); + WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX; + m_regionWidth = (uint)WorldExtents.X; + WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY; + m_regionHeight = (uint)WorldExtents.Y; + + lock (OdeLock) + { + // Create the world and the first space + try + { + world = d.WorldCreate(); + TopSpace = d.HashSpaceCreate(IntPtr.Zero); - contactgroup = d.JointGroupCreate(0); + // now the major subspaces + ActiveSpace = d.HashSpaceCreate(TopSpace); + CharsSpace = d.HashSpaceCreate(TopSpace); + StaticSpace = d.HashSpaceCreate(TopSpace); + GroundSpace = d.HashSpaceCreate(TopSpace); + } + catch + { + // i must RtC#FM + // i did! + } - d.WorldSetAutoDisableFlag(world, false); - } + d.HashSpaceSetLevels(TopSpace, -5, 12); + d.HashSpaceSetLevels(ActiveSpace, -5, 10); + d.HashSpaceSetLevels(CharsSpace, -4, 3); + d.HashSpaceSetLevels(StaticSpace, -5, 12); + d.HashSpaceSetLevels(GroundSpace, 0, 8); - // Initialize from configs - private void InitialiseFromConfig(IConfigSource config) - { - InitializeExtraStats(); + // demote to second level + d.SpaceSetSublevel(ActiveSpace, 1); + d.SpaceSetSublevel(CharsSpace, 1); + d.SpaceSetSublevel(StaticSpace, 1); + d.SpaceSetSublevel(GroundSpace, 1); + + d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Character | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Character | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Character | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(CharsSpace, 0); + + d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + // CollisionCategories.Land | + // CollisionCategories.Water | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(StaticSpace, 0); + + d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); + d.GeomSetCollideBits(GroundSpace, 0); + + contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1); + //contactgroup + + d.WorldSetAutoDisableFlag(world, false); + } - m_config = config; - // Defaults - avPIDD = 2200.0f; - avPIDP = 900.0f; - avStandupTensor = 550000f; + // checkThread(); + + + // Defaults int contactsPerCollision = 80; + physicsconfig = null; + if (m_config != null) { - IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; + physicsconfig = m_config.Configs["ODEPhysicsSettings"]; if (physicsconfig != null) { - CollectStats = physicsconfig.GetBoolean("collect_stats", false); + gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); + gravityy = physicsconfig.GetFloat("world_gravityy", gravityy); + gravityz = physicsconfig.GetFloat("world_gravityz", gravityz); - gravityx = physicsconfig.GetFloat("world_gravityx", 0f); - gravityy = physicsconfig.GetFloat("world_gravityy", 0f); - gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); + metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); - float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 54f); - AvatarTerminalVelocity = Util.Clamp(avatarTerminalVelocity, 0, 255f); - if (AvatarTerminalVelocity != avatarTerminalVelocity) - { - m_log.WarnFormat( - "[ODE SCENE]: avatar_terminal_velocity of {0} is invalid. Clamping to {1}", - avatarTerminalVelocity, AvatarTerminalVelocity); - } + // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); + + ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); - HashspaceLow = physicsconfig.GetInt("world_hashspace_level_low", -5); - HashspaceHigh = physicsconfig.GetInt("world_hashspace_level_high", 12); + avDensity = physicsconfig.GetFloat("av_density", avDensity); + avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); + avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun); - metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f); + contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); - contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", 0.001f); + geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); + bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); - nmTerrainContactFriction = physicsconfig.GetFloat("nm_terraincontact_friction", 255.0f); - nmTerrainContactBounce = physicsconfig.GetFloat("nm_terraincontact_bounce", 0.1f); - nmTerrainContactERP = physicsconfig.GetFloat("nm_terraincontact_erp", 0.1025f); + physics_logging = physicsconfig.GetBoolean("physics_logging", false); + physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); + physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); + + minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset); + maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject); - mTerrainContactFriction = physicsconfig.GetFloat("m_terraincontact_friction", 75f); - mTerrainContactBounce = physicsconfig.GetFloat("m_terraincontact_bounce", 0.05f); - mTerrainContactERP = physicsconfig.GetFloat("m_terraincontact_erp", 0.05025f); + avDensity *= 3f / 80f; // scale other engines density option to this + } + } - nmAvatarObjectContactFriction = physicsconfig.GetFloat("objectcontact_friction", 250f); - nmAvatarObjectContactBounce = physicsconfig.GetFloat("objectcontact_bounce", 0.2f); + float heartbeat = 1/m_frameWorkScene.FrameTime; + maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI; + maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity; - mAvatarObjectContactFriction = physicsconfig.GetFloat("m_avatarobjectcontact_friction", 75f); - mAvatarObjectContactBounce = physicsconfig.GetFloat("m_avatarobjectcontact_bounce", 0.1f); + d.WorldSetCFM(world, comumContactCFM); + d.WorldSetERP(world, comumContactERP); - ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); - m_physicsiterations = physicsconfig.GetInt("world_solver_iterations", 10); + d.WorldSetGravity(world, gravityx, gravityy, gravityz); - avDensity = physicsconfig.GetFloat("av_density", 80f); -// avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f); - avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); - avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); - avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); - avplanted = physicsconfig.GetBoolean("av_planted", false); - av_av_collisions_off = physicsconfig.GetBoolean("av_av_collisions_off", false); + d.WorldSetLinearDamping(world, 0.002f); + d.WorldSetAngularDamping(world, 0.002f); + d.WorldSetAngularDampingThreshold(world, 0f); + d.WorldSetLinearDampingThreshold(world, 0f); + d.WorldSetMaxAngularSpeed(world, maximumAngularVelocity); - IsAvCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); + d.WorldSetQuickStepNumIterations(world, m_physicsiterations); - contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); + d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); + d.WorldSetContactMaxCorrectingVel(world, 60.0f); - geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5); - geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); + HalfOdeStep = ODE_STEPSIZE * 0.5f; + odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); - geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); - bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); + ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); + GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf); - bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f); - bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f); + SharedTmpcontact.geom.g1 = IntPtr.Zero; + SharedTmpcontact.geom.g2 = IntPtr.Zero; - forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); - meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true); - meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); - MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); - m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false); + SharedTmpcontact.geom.side1 = -1; + SharedTmpcontact.geom.side2 = -1; - avPIDD = physicsconfig.GetFloat("av_pid_derivative", 2200.0f); - avPIDP = physicsconfig.GetFloat("av_pid_proportional", 900.0f); - avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor", 550000f); + SharedTmpcontact.surface.mode = comumContactFlags; + SharedTmpcontact.surface.mu = 0; + SharedTmpcontact.surface.bounce = 0; + SharedTmpcontact.surface.soft_cfm = comumContactCFM; + SharedTmpcontact.surface.soft_erp = comumContactERP; + SharedTmpcontact.surface.slip1 = comumContactSLIP; + SharedTmpcontact.surface.slip2 = comumContactSLIP; - physics_logging = physicsconfig.GetBoolean("physics_logging", false); - physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); - physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); + m_materialContactsData[(int)Material.Stone].mu = 0.8f; + m_materialContactsData[(int)Material.Stone].bounce = 0.4f; -// m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); - minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); - maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); - } - } + m_materialContactsData[(int)Material.Metal].mu = 0.3f; + m_materialContactsData[(int)Material.Metal].bounce = 0.4f; - contacts = new d.ContactGeom[contactsPerCollision]; + m_materialContactsData[(int)Material.Glass].mu = 0.2f; + m_materialContactsData[(int)Material.Glass].bounce = 0.7f; - spacesPerMeterX = 1.0f / metersInSpace; - spacesPerMeterY = 1.0f / metersInSpace; + m_materialContactsData[(int)Material.Wood].mu = 0.6f; + m_materialContactsData[(int)Material.Wood].bounce = 0.5f; + m_materialContactsData[(int)Material.Flesh].mu = 0.9f; + m_materialContactsData[(int)Material.Flesh].bounce = 0.3f; + + m_materialContactsData[(int)Material.Plastic].mu = 0.4f; + m_materialContactsData[(int)Material.Plastic].bounce = 0.7f; + + m_materialContactsData[(int)Material.Rubber].mu = 0.9f; + m_materialContactsData[(int)Material.Rubber].bounce = 0.95f; + + m_materialContactsData[(int)Material.light].mu = 0.0f; + m_materialContactsData[(int)Material.light].bounce = 0.0f; + + + spacesPerMeterX = 1.0f / metersInSpace; + spacesPerMeterY = spacesPerMeterX; spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX); spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY); - // note: limit number of spaces if (spaceGridMaxX > 24) { spaceGridMaxX = 24; - spacesPerMeterX = spaceGridMaxX / WorldExtents.X; + spacesPerMeterX = spaceGridMaxX / WorldExtents.X; } + if (spaceGridMaxY > 24) { spaceGridMaxY = 24; spacesPerMeterY = spaceGridMaxY / WorldExtents.Y; } - staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; - - // make this index limits - spaceGridMaxX--; - spaceGridMaxY--; - - // Centeral contact friction and bounce - // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why - // an avatar falls through in Z but not in X or Y when walking on a prim. - contact.surface.mode |= d.ContactFlags.SoftERP; - contact.surface.mu = nmAvatarObjectContactFriction; - contact.surface.bounce = nmAvatarObjectContactBounce; - contact.surface.soft_cfm = 0.010f; - contact.surface.soft_erp = 0.010f; - - // Terrain contact friction and Bounce - // This is the *non* moving version. Use this when an avatar - // isn't moving to keep it in place better - TerrainContact.surface.mode |= d.ContactFlags.SoftERP; - TerrainContact.surface.mu = nmTerrainContactFriction; - TerrainContact.surface.bounce = nmTerrainContactBounce; - TerrainContact.surface.soft_erp = nmTerrainContactERP; - - WaterContact.surface.mode |= (d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM); - WaterContact.surface.mu = 0f; // No friction - WaterContact.surface.bounce = 0.0f; // No bounce - WaterContact.surface.soft_cfm = 0.010f; - WaterContact.surface.soft_erp = 0.010f; - - // Prim contact friction and bounce - // THis is the *non* moving version of friction and bounce - // Use this when an avatar comes in contact with a prim - // and is moving - AvatarMovementprimContact.surface.mu = mAvatarObjectContactFriction; - AvatarMovementprimContact.surface.bounce = mAvatarObjectContactBounce; - - // Terrain contact friction bounce and various error correcting calculations - // Use this when an avatar is in contact with the terrain and moving. - AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP; - AvatarMovementTerrainContact.surface.mu = mTerrainContactFriction; - AvatarMovementTerrainContact.surface.bounce = mTerrainContactBounce; - AvatarMovementTerrainContact.surface.soft_erp = mTerrainContactERP; - - /* - - Stone = 0, - /// - Metal = 1, - /// - Glass = 2, - /// - Wood = 3, - /// - Flesh = 4, - /// - Plastic = 5, - /// - Rubber = 6 - */ - - m_materialContacts = new d.Contact[7,2]; - - m_materialContacts[(int)Material.Stone, 0] = new d.Contact(); - m_materialContacts[(int)Material.Stone, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Stone, 0].surface.mu = nmAvatarObjectContactFriction; - m_materialContacts[(int)Material.Stone, 0].surface.bounce = nmAvatarObjectContactBounce; - m_materialContacts[(int)Material.Stone, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Stone, 0].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Stone, 1] = new d.Contact(); - m_materialContacts[(int)Material.Stone, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Stone, 1].surface.mu = mAvatarObjectContactFriction; - m_materialContacts[(int)Material.Stone, 1].surface.bounce = mAvatarObjectContactBounce; - m_materialContacts[(int)Material.Stone, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Stone, 1].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Metal, 0] = new d.Contact(); - m_materialContacts[(int)Material.Metal, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Metal, 0].surface.mu = nmAvatarObjectContactFriction; - m_materialContacts[(int)Material.Metal, 0].surface.bounce = nmAvatarObjectContactBounce; - m_materialContacts[(int)Material.Metal, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Metal, 0].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Metal, 1] = new d.Contact(); - m_materialContacts[(int)Material.Metal, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Metal, 1].surface.mu = mAvatarObjectContactFriction; - m_materialContacts[(int)Material.Metal, 1].surface.bounce = mAvatarObjectContactBounce; - m_materialContacts[(int)Material.Metal, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Metal, 1].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Glass, 0] = new d.Contact(); - m_materialContacts[(int)Material.Glass, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Glass, 0].surface.mu = 1f; - m_materialContacts[(int)Material.Glass, 0].surface.bounce = 0.5f; - m_materialContacts[(int)Material.Glass, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Glass, 0].surface.soft_erp = 0.010f; + staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; - /* - private float nmAvatarObjectContactFriction = 250f; - private float nmAvatarObjectContactBounce = 0.1f; + // create all spaces now + int i, j; + IntPtr newspace; - private float mAvatarObjectContactFriction = 75f; - private float mAvatarObjectContactBounce = 0.1f; - */ - m_materialContacts[(int)Material.Glass, 1] = new d.Contact(); - m_materialContacts[(int)Material.Glass, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Glass, 1].surface.mu = 1f; - m_materialContacts[(int)Material.Glass, 1].surface.bounce = 0.5f; - m_materialContacts[(int)Material.Glass, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Glass, 1].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Wood, 0] = new d.Contact(); - m_materialContacts[(int)Material.Wood, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Wood, 0].surface.mu = nmAvatarObjectContactFriction; - m_materialContacts[(int)Material.Wood, 0].surface.bounce = nmAvatarObjectContactBounce; - m_materialContacts[(int)Material.Wood, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Wood, 0].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Wood, 1] = new d.Contact(); - m_materialContacts[(int)Material.Wood, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Wood, 1].surface.mu = mAvatarObjectContactFriction; - m_materialContacts[(int)Material.Wood, 1].surface.bounce = mAvatarObjectContactBounce; - m_materialContacts[(int)Material.Wood, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Wood, 1].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Flesh, 0] = new d.Contact(); - m_materialContacts[(int)Material.Flesh, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Flesh, 0].surface.mu = nmAvatarObjectContactFriction; - m_materialContacts[(int)Material.Flesh, 0].surface.bounce = nmAvatarObjectContactBounce; - m_materialContacts[(int)Material.Flesh, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Flesh, 0].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Flesh, 1] = new d.Contact(); - m_materialContacts[(int)Material.Flesh, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Flesh, 1].surface.mu = mAvatarObjectContactFriction; - m_materialContacts[(int)Material.Flesh, 1].surface.bounce = mAvatarObjectContactBounce; - m_materialContacts[(int)Material.Flesh, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Flesh, 1].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Plastic, 0] = new d.Contact(); - m_materialContacts[(int)Material.Plastic, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Plastic, 0].surface.mu = nmAvatarObjectContactFriction; - m_materialContacts[(int)Material.Plastic, 0].surface.bounce = nmAvatarObjectContactBounce; - m_materialContacts[(int)Material.Plastic, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Plastic, 0].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Plastic, 1] = new d.Contact(); - m_materialContacts[(int)Material.Plastic, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Plastic, 1].surface.mu = mAvatarObjectContactFriction; - m_materialContacts[(int)Material.Plastic, 1].surface.bounce = mAvatarObjectContactBounce; - m_materialContacts[(int)Material.Plastic, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Plastic, 1].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Rubber, 0] = new d.Contact(); - m_materialContacts[(int)Material.Rubber, 0].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Rubber, 0].surface.mu = nmAvatarObjectContactFriction; - m_materialContacts[(int)Material.Rubber, 0].surface.bounce = nmAvatarObjectContactBounce; - m_materialContacts[(int)Material.Rubber, 0].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Rubber, 0].surface.soft_erp = 0.010f; - - m_materialContacts[(int)Material.Rubber, 1] = new d.Contact(); - m_materialContacts[(int)Material.Rubber, 1].surface.mode |= d.ContactFlags.SoftERP; - m_materialContacts[(int)Material.Rubber, 1].surface.mu = mAvatarObjectContactFriction; - m_materialContacts[(int)Material.Rubber, 1].surface.bounce = mAvatarObjectContactBounce; - m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f; - m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f; - - d.HashSpaceSetLevels(space, HashspaceLow, HashspaceHigh); - - // Set the gravity,, don't disable things automatically (we set it explicitly on some things) + for (i = 0; i < spaceGridMaxX; i++) + for (j = 0; j < spaceGridMaxY; j++) + { + newspace = d.HashSpaceCreate(StaticSpace); + d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); + waitForSpaceUnlock(newspace); + d.SpaceSetSublevel(newspace, 2); + d.HashSpaceSetLevels(newspace, -2, 8); + d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Land | + CollisionCategories.Water | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(newspace, 0); - d.WorldSetGravity(world, gravityx, gravityy, gravityz); - d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); + staticPrimspace[i, j] = newspace; + } - d.WorldSetLinearDamping(world, 256f); - d.WorldSetAngularDamping(world, 256f); - d.WorldSetAngularDampingThreshold(world, 256f); - d.WorldSetLinearDampingThreshold(world, 256f); - d.WorldSetMaxAngularSpeed(world, 256f); + // let this now be index limit + spaceGridMaxX--; + spaceGridMaxY--; - d.WorldSetQuickStepNumIterations(world, m_physicsiterations); - //d.WorldSetContactMaxCorrectingVel(world, 1000.0f); + // create 4 off world spaces (x<0,x>max,y<0,y>max) + staticPrimspaceOffRegion = new IntPtr[4]; - for (int i = 0; i < staticPrimspace.GetLength(0); i++) + for (i = 0; i < 4; i++) { - for (int j = 0; j < staticPrimspace.GetLength(1); j++) - { - staticPrimspace[i, j] = IntPtr.Zero; - } + newspace = d.HashSpaceCreate(StaticSpace); + d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); + waitForSpaceUnlock(newspace); + d.SpaceSetSublevel(newspace, 2); + d.HashSpaceSetLevels(newspace, -2, 8); + d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Land | + CollisionCategories.Water | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(newspace, 0); + + staticPrimspaceOffRegion[i] = newspace; } - _worldInitialized = true; + m_lastframe = DateTime.UtcNow; + m_lastMeshExpire = m_lastframe; + } + + internal void waitForSpaceUnlock(IntPtr space) + { + //if (space != IntPtr.Zero) + //while (d.SpaceLockQuery(space)) { } // Wait and do nothing } #region Collision Detection - /// - /// Collides two geometries. - /// - /// - /// - /// /param> - /// - /// - /// - private int CollideGeoms( - IntPtr geom1, IntPtr geom2, int maxContacts, d.ContactGeom[] contactsArray, int contactGeomSize) + // sets a global contact for a joint for contactgeom , and base contact description) + private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom,bool smooth) { - int count; + if (m_global_contactcount >= maxContactsbeforedeath) + return IntPtr.Zero; - lock (OdeScene.UniversalColliderSyncObject) - { - // We do this inside the lock so that we don't count any delay in acquiring it - if (CollectStats) - m_nativeCollisionStartTick = Util.EnvironmentTickCount(); + m_global_contactcount++; + if(smooth) + SharedTmpcontact.geom.depth = contactGeom.depth * 0.05f; + else + SharedTmpcontact.geom.depth = contactGeom.depth; + SharedTmpcontact.geom.pos = contactGeom.pos; + SharedTmpcontact.geom.normal = contactGeom.normal; - count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); - } + IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); + Marshal.StructureToPtr(SharedTmpcontact, contact, true); + return d.JointCreateContactPtr(world, contactgroup, contact); + } - // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably - // negligable - if (CollectStats) - m_stats[ODENativeGeomCollisionFrameMsStatName] - += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); + private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) + { + if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision) + return false; - return count; + IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); + newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom)); + return true; } /// - /// Collide two spaces or a space and a geometry. - /// - /// - /// /param> - /// - private void CollideSpaces(IntPtr space1, IntPtr space2, IntPtr data) - { - if (CollectStats) - { - m_inCollisionTiming = true; - m_nativeCollisionStartTick = Util.EnvironmentTickCount(); - } - - d.SpaceCollide2(space1, space2, data, nearCallback); - - if (CollectStats && m_inCollisionTiming) - { - m_stats[ODENativeSpaceCollisionFrameMsStatName] - += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); - m_inCollisionTiming = false; - } - } - - /// - /// This is our near callback. A geometry is near a body + /// This is our near callback. A geometry is near a body /// /// The space that contains the geoms. Remember, spaces are also geoms /// a geometry or space /// another geometry or space + /// + private void near(IntPtr space, IntPtr g1, IntPtr g2) { - if (CollectStats && m_inCollisionTiming) - { - m_stats[ODENativeSpaceCollisionFrameMsStatName] - += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); - m_inCollisionTiming = false; - } - -// m_log.DebugFormat("[PHYSICS]: Colliding {0} and {1} in {2}", g1, g2, space); // no lock here! It's invoked from within Simulate(), which is thread-locked + if (m_global_contactcount >= maxContactsbeforedeath) + return; + // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { - if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) - return; - - // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { - CollideSpaces(g1, g2, IntPtr.Zero); + d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { - m_log.Error("[ODE SCENE]: Unable to collide test a space"); + m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } - //Colliding a space or a geom with a space or a geom. so drill down - - //Collide all geoms in each space.. - //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); - //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); + //here one should check collisions of geoms inside a space + // but on each space we only should have geoms that not colide amoung each other + // so we don't dig inside spaces return; } - if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) - return; - + // get geom bodies to check if we already a joint contact + // guess this shouldn't happen now IntPtr b1 = d.GeomGetBody(g1); IntPtr b2 = d.GeomGetBody(g2); // d.GeomClassID id = d.GeomGetClass(g1); - String name1 = null; - String name2 = null; - - if (!geom_name_map.TryGetValue(g1, out name1)) - { - name1 = "null"; - } - if (!geom_name_map.TryGetValue(g2, out name2)) - { - name2 = "null"; - } - // Figure out how many contact points we have int count = 0; - try { // Colliding Geom To Geom @@ -1003,444 +728,329 @@ namespace OpenSim.Region.PhysicsModule.ODE if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; + /* + // debug + PhysicsActor dp2; + if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) + { + d.AABB aabb; + d.GeomGetAABB(g2, out aabb); + float x = aabb.MaxX - aabb.MinX; + float y = aabb.MaxY - aabb.MinY; + float z = aabb.MaxZ - aabb.MinZ; + if (x > 60.0f || y > 60.0f || z > 60.0f) + { + if (!actor_name_map.TryGetValue(g2, out dp2)) + m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2"); + else + m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})", + dp2.Name, dp2.Size, x, y, z, + dp2.Position.ToString(), + dp2.Orientation.ToString(), + dp2.Orientation.Length()); + return; + } + } + // + */ - count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.unmanagedSizeOf); - - // All code after this is only relevant if we have any collisions - if (count <= 0) - return; - if (count > contacts.Length) - m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); + if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || + d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) + { + int cflags; + unchecked + { + cflags = (int)(1 | d.CONTACTS_UNIMPORTANT); + } + count = d.CollidePtr(g1, g2, cflags, ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + } + else + count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (SEHException) { - m_log.Error( - "[ODE SCENE]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); + m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); + // ode.drelease(world); base.TriggerPhysicsBasedRestart(); } catch (Exception e) { - m_log.ErrorFormat("[ODE SCENE]: Unable to collide test an object: {0}", e.Message); + m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } + // contacts done + if (count == 0) + return; + + // try get physical actors PhysicsActor p1; PhysicsActor p2; - - p1ExpectedPoints = 0; - p2ExpectedPoints = 0; - + if (!actor_name_map.TryGetValue(g1, out p1)) { - p1 = PANull; + m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 1"); + return; } if (!actor_name_map.TryGetValue(g2, out p2)) { - p2 = PANull; + m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2"); + return; } - ContactPoint maxDepthContact = new ContactPoint(); - if (p1.CollisionScore + count >= float.MaxValue) - p1.CollisionScore = 0; - p1.CollisionScore += count; - if (p2.CollisionScore + count >= float.MaxValue) - p2.CollisionScore = 0; - p2.CollisionScore += count; + // get first contact + d.ContactGeom curContact = new d.ContactGeom(); - for (int i = 0; i < count; i++) - { - d.ContactGeom curContact = contacts[i]; + if (!GetCurContactGeom(0, ref curContact)) + return; - if (curContact.depth > maxDepthContact.PenetrationDepth) - { - maxDepthContact = new ContactPoint( - new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), - new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), - curContact.depth - ); - } + ContactPoint maxDepthContact = new ContactPoint(); - //m_log.Warn("[CCOUNT]: " + count); - IntPtr joint; - // If we're colliding with terrain, use 'TerrainContact' instead of contact. - // allows us to have different settings - - // We only need to test p2 for 'jump crouch purposes' - if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) - { - // Testing if the collision is at the feet of the avatar + // do volume detection case + if ((p1.IsVolumeDtc || p2.IsVolumeDtc)) + { + maxDepthContact = new ContactPoint( + new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), + new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), + curContact.depth, false + ); - //m_log.DebugFormat("[PHYSICS]: {0} - {1} - {2} - {3}", curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); - if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)) - p2.IsColliding = true; - } - else - { - p2.IsColliding = true; - } - - //if ((framecount % m_returncollisions) == 0) + collision_accounting_events(p1, p2, maxDepthContact); + return; + } - switch (p1.PhysicsActorType) - { - case (int)ActorTypes.Agent: - p1ExpectedPoints = avatarExpectedContacts; - p2.CollidingObj = true; - break; - case (int)ActorTypes.Prim: - if (p1 != null && p1 is OdePrim) - p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts; + // big messy collision analises - if (p2.Velocity.LengthSquared() > 0.0f) - p2.CollidingObj = true; - break; - case (int)ActorTypes.Unknown: - p2.CollidingGround = true; - break; - default: - p2.CollidingGround = true; - break; - } + float mu = 0; + float bounce = 0; +// bool IgnoreNegSides = false; - // we don't want prim or avatar to explode + ContactData contactdata1 = new ContactData(0, 0, false); + ContactData contactdata2 = new ContactData(0, 0, false); - #region InterPenetration Handling - Unintended physics explosions + bool dop1ava = false; + bool dop2ava = false; + bool ignore = false; + bool smoothMesh = false; - if (curContact.depth >= 0.08f) - { - if (curContact.depth >= 1.00f) + switch (p1.PhysicsActorType) + { + case (int)ActorTypes.Agent: { - //m_log.Info("[P]: " + contact.depth.ToString()); - if ((p2.PhysicsActorType == (int) ActorTypes.Agent && - p1.PhysicsActorType == (int) ActorTypes.Unknown) || - (p1.PhysicsActorType == (int) ActorTypes.Agent && - p2.PhysicsActorType == (int) ActorTypes.Unknown)) + dop1ava = true; + switch (p2.PhysicsActorType) { - if (p2.PhysicsActorType == (int) ActorTypes.Agent) - { - if (p2 is OdeCharacter) - { - OdeCharacter character = (OdeCharacter) p2; - - //p2.CollidingObj = true; - curContact.depth = 0.00000003f; - p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); - curContact.pos = - new d.Vector3(curContact.pos.X + (p1.Size.X/2), - curContact.pos.Y + (p1.Size.Y/2), - curContact.pos.Z + (p1.Size.Z/2)); - character.SetPidStatus(true); - } - } + case (int)ActorTypes.Agent: + case (int)ActorTypes.Prim: + break; - if (p1.PhysicsActorType == (int) ActorTypes.Agent) - { - if (p1 is OdeCharacter) - { - OdeCharacter character = (OdeCharacter) p1; - - //p2.CollidingObj = true; - curContact.depth = 0.00000003f; - p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); - curContact.pos = - new d.Vector3(curContact.pos.X + (p1.Size.X/2), - curContact.pos.Y + (p1.Size.Y/2), - curContact.pos.Z + (p1.Size.Z/2)); - character.SetPidStatus(true); - } - } + default: + ignore = true; // avatar to terrain and water ignored + break; } + break; } - } - #endregion - - // Logic for collision handling - // Note, that if *all* contacts are skipped (VolumeDetect) - // The prim still detects (and forwards) collision events but - // appears to be phantom for the world - Boolean skipThisContact = false; + case (int)ActorTypes.Prim: + { + switch (p2.PhysicsActorType) + { + case (int)ActorTypes.Agent: + dop2ava = true; + break; - if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect)) - skipThisContact = true; // No collision on volume detect prims + case (int)ActorTypes.Prim: + Vector3 relV = p1.rootVelocity - p2.rootVelocity; + float relVlenSQ = relV.LengthSquared(); + if (relVlenSQ > 0.0001f) + { + p1.CollidingObj = true; + p2.CollidingObj = true; + } + p1.getContactData(ref contactdata1); + p2.getContactData(ref contactdata2); + bounce = contactdata1.bounce * contactdata2.bounce; + mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); - if (av_av_collisions_off) - if ((p1 is OdeCharacter) && (p2 is OdeCharacter)) - skipThisContact = true; + if (relVlenSQ > 0.01f) + mu *= frictionMovementMult; - if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) - skipThisContact = true; // No collision on volume detect prims + if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass && + d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) + smoothMesh = true; + break; - if (!skipThisContact && curContact.depth < 0f) - skipThisContact = true; + case (int)ActorTypes.Ground: + p1.getContactData(ref contactdata1); + bounce = contactdata1.bounce * TerrainBounce; + mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); - if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType)) - skipThisContact = true; + Vector3 v1 = p1.rootVelocity; + if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) + mu *= frictionMovementMult; + p1.CollidingGround = true; - const int maxContactsbeforedeath = 4000; - joint = IntPtr.Zero; + if(d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) + smoothMesh = true; + break; - if (!skipThisContact) - { - _perloopContact.Add(curContact); + case (int)ActorTypes.Water: + default: + ignore = true; + break; + } + } + break; - if (name1 == "Terrain" || name2 == "Terrain") + case (int)ActorTypes.Ground: + if (p2.PhysicsActorType == (int)ActorTypes.Prim) { - if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && - (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) - { - p2ExpectedPoints = avatarExpectedContacts; - // Avatar is moving on terrain, use the movement terrain contact - AvatarMovementTerrainContact.geom = curContact; - - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); - m_global_contactcount++; - } - } - else - { - if (p2.PhysicsActorType == (int)ActorTypes.Agent) - { - p2ExpectedPoints = avatarExpectedContacts; - // Avatar is standing on terrain, use the non moving terrain contact - TerrainContact.geom = curContact; + p2.CollidingGround = true; + p2.getContactData(ref contactdata2); + bounce = contactdata2.bounce * TerrainBounce; + mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); + +// if (curContact.side1 > 0) // should be 2 ? +// IgnoreNegSides = true; + Vector3 v2 = p2.rootVelocity; + if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) + mu *= frictionMovementMult; + + if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass) + smoothMesh = true; + } + else + ignore = true; + break; - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); - m_global_contactcount++; - } - } - else - { - if (p2.PhysicsActorType == (int)ActorTypes.Prim && p1.PhysicsActorType == (int)ActorTypes.Prim) - { - // prim prim contact - // int pj294950 = 0; - int movintYN = 0; - int material = (int) Material.Wood; - // prim terrain contact - if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) - { - movintYN = 1; - } + case (int)ActorTypes.Water: + default: + break; + } - if (p2 is OdePrim) - { - material = ((OdePrim) p2).m_material; - p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; - } - - // Unnessesary because p1 is defined above - //if (p1 is OdePrim) - // { - // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts; - // } - //m_log.DebugFormat("Material: {0}", material); + if (ignore) + return; - m_materialContacts[material, movintYN].geom = curContact; + IntPtr Joint; + bool FeetCollision = false; + int ncontacts = 0; - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); - m_global_contactcount++; - } - } - else - { - int movintYN = 0; - // prim terrain contact - if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) - { - movintYN = 1; - } + int i = 0; - int material = (int)Material.Wood; + maxDepthContact = new ContactPoint(); + maxDepthContact.PenetrationDepth = float.MinValue; + ContactPoint minDepthContact = new ContactPoint(); + minDepthContact.PenetrationDepth = float.MaxValue; - if (p2 is OdePrim) - { - material = ((OdePrim)p2).m_material; - p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; - } + SharedTmpcontact.geom.depth = 0; + SharedTmpcontact.surface.mu = mu; + SharedTmpcontact.surface.bounce = bounce; - //m_log.DebugFormat("Material: {0}", material); - m_materialContacts[material, movintYN].geom = curContact; + d.ContactGeom altContact = new d.ContactGeom(); + bool useAltcontact = false; + bool noskip = true; - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); - m_global_contactcount++; - } - } - } - } - //if (p2.PhysicsActorType == (int)ActorTypes.Prim) - //{ - //m_log.Debug("[PHYSICS]: prim contacting with ground"); - //} - } - else if (name1 == "Water" || name2 == "Water") - { - /* - if ((p2.PhysicsActorType == (int) ActorTypes.Prim)) - { - } - else - { - } - */ - //WaterContact.surface.soft_cfm = 0.0000f; - //WaterContact.surface.soft_erp = 0.00000f; - if (curContact.depth > 0.1f) - { - curContact.depth *= 52; - //contact.normal = new d.Vector3(0, 0, 1); - //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); - } + if(dop1ava || dop2ava) + smoothMesh = false; - WaterContact.geom = curContact; + while (true) + { + noskip = true; + useAltcontact = false; - if (m_global_contactcount < maxContactsbeforedeath) + if (dop1ava) + { + if ((((OdeCharacter)p1).Collide(g1, g2, false, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision))) + { + if (p2.PhysicsActorType == (int)ActorTypes.Agent) { - joint = d.JointCreateContact(world, contactgroup, ref WaterContact); - m_global_contactcount++; + p1.CollidingObj = true; + p2.CollidingObj = true; } - //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth); + else if (p2.rootVelocity.LengthSquared() > 0.0f) + p2.CollidingObj = true; } else + noskip = false; + } + else if (dop2ava) + { + if ((((OdeCharacter)p2).Collide(g2, g1, true, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision))) { - if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) + if (p1.PhysicsActorType == (int)ActorTypes.Agent) { - p2ExpectedPoints = avatarExpectedContacts; - if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) - { - // Avatar is moving on a prim, use the Movement prim contact - AvatarMovementprimContact.geom = curContact; - - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); - m_global_contactcount++; - } - } - else - { - // Avatar is standing still on a prim, use the non movement contact - contact.geom = curContact; - - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref contact); - m_global_contactcount++; - } - } - } - else if (p2.PhysicsActorType == (int)ActorTypes.Prim) - { - //p1.PhysicsActorType - int material = (int)Material.Wood; - - if (p2 is OdePrim) - { - material = ((OdePrim)p2).m_material; - p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; - } - - //m_log.DebugFormat("Material: {0}", material); - m_materialContacts[material, 0].geom = curContact; - - if (m_global_contactcount < maxContactsbeforedeath) - { - joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); - m_global_contactcount++; - } + p1.CollidingObj = true; + p2.CollidingObj = true; } + else if (p1.rootVelocity.LengthSquared() > 0.0f) + p1.CollidingObj = true; } - - if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide! - { - d.JointAttach(joint, b1, b2); - m_global_contactcount++; - } + else + noskip = false; } - collision_accounting_events(p1, p2, maxDepthContact); - - if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle)) + if (noskip) { - // If there are more then 3 contact points, it's likely - // that we've got a pile of objects, so ... - // We don't want to send out hundreds of terse updates over and over again - // so lets throttle them and send them again after it's somewhat sorted out. - p2.ThrottleUpdates = true; - } - //m_log.Debug(count.ToString()); - //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); - } - } + if(useAltcontact) + Joint = CreateContacJoint(ref altContact,smoothMesh); + else + Joint = CreateContacJoint(ref curContact,smoothMesh); - private bool checkDupe(d.ContactGeom contactGeom, int atype) - { - if (!m_filterCollisions) - return false; + if (Joint == IntPtr.Zero) + break; - bool result = false; + d.JointAttach(Joint, b1, b2); - ActorTypes at = (ActorTypes)atype; + ncontacts++; - foreach (d.ContactGeom contact in _perloopContact) - { - //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) - //{ - // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2) - if (at == ActorTypes.Agent) - { - if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) - && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) - && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))) + if (curContact.depth > maxDepthContact.PenetrationDepth) { - if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) - { - result = true; - break; - } + maxDepthContact.Position.X = curContact.pos.X; + maxDepthContact.Position.Y = curContact.pos.Y; + maxDepthContact.Position.Z = curContact.pos.Z; + maxDepthContact.PenetrationDepth = curContact.depth; + maxDepthContact.CharacterFeet = FeetCollision; } - } - else if (at == ActorTypes.Prim) - { - if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))) + + if (curContact.depth < minDepthContact.PenetrationDepth) { - if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) - { - if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f) - { - result = true; - break; - } - } - //m_log.DebugFormat("[Collision]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); - //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); + minDepthContact.PenetrationDepth = curContact.depth; + minDepthContact.SurfaceNormal.X = curContact.normal.X; + minDepthContact.SurfaceNormal.Y = curContact.normal.Y; + minDepthContact.SurfaceNormal.Z = curContact.normal.Z; } } + + if (++i >= count) + break; + + if (!GetCurContactGeom(i, ref curContact)) + break; } - return result; + if (ncontacts > 0) + { + maxDepthContact.SurfaceNormal.X = minDepthContact.SurfaceNormal.X; + maxDepthContact.SurfaceNormal.Y = minDepthContact.SurfaceNormal.Y; + maxDepthContact.SurfaceNormal.Z = minDepthContact.SurfaceNormal.Z; + + collision_accounting_events(p1, p2, maxDepthContact); + } } private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { - // obj1LocalID = 0; - //returncollisions = false; - obj2LocalID = 0; - //ctype = 0; - //cStartStop = 0; -// if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) -// return; + uint obj2LocalID = 0; + + // update actors collision score + if (p1.CollisionScore < float.MaxValue) + p1.CollisionScore += 1.0f; + if (p2.CollisionScore < float.MaxValue) + p2.CollisionScore += 1.0f; + bool p1events = p1.SubscribedEvents(); bool p2events = p2.SubscribedEvents(); @@ -1454,367 +1064,168 @@ namespace OpenSim.Region.PhysicsModule.ODE Vector3 vel = Vector3.Zero; if (p2 != null && p2.IsPhysical) - vel = p2.Velocity; + vel = p2.rootVelocity; if (p1 != null && p1.IsPhysical) - vel -= p1.Velocity; + vel -= p1.rootVelocity; contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal); - switch ((ActorTypes)p2.PhysicsActorType) + switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: - cc2 = (OdeCharacter)p2; - - // obj1LocalID = cc2.m_localID; - switch ((ActorTypes)p1.PhysicsActorType) + case ActorTypes.Prim: + { + switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: - cc1 = (OdeCharacter)p1; - obj2LocalID = cc1.LocalID; - cc1.AddCollisionEvent(cc2.LocalID, contact); - break; - case ActorTypes.Prim: - if (p1 is OdePrim) + if (p2events) { - cp1 = (OdePrim) p1; - obj2LocalID = cp1.LocalID; - cp1.AddCollisionEvent(cc2.LocalID, contact); + AddCollisionEventReporting(p2); + p2.AddCollisionEvent(p1.ParentActor.LocalID, contact); } + obj2LocalID = p2.ParentActor.LocalID; break; case ActorTypes.Ground: case ActorTypes.Unknown: + default: obj2LocalID = 0; break; } - - cc2.AddCollisionEvent(obj2LocalID, contact); + if (p1events) + { + contact.SurfaceNormal = -contact.SurfaceNormal; + contact.RelativeSpeed = -contact.RelativeSpeed; + AddCollisionEventReporting(p1); + p1.AddCollisionEvent(obj2LocalID, contact); + } break; - - case ActorTypes.Prim: - - if (p2 is OdePrim) + } + case ActorTypes.Ground: + case ActorTypes.Unknown: + default: + { + if (p2events && !p2.IsVolumeDtc) { - cp2 = (OdePrim) p2; - - // obj1LocalID = cp2.m_localID; - switch ((ActorTypes) p1.PhysicsActorType) - { - case ActorTypes.Agent: - if (p1 is OdeCharacter) - { - cc1 = (OdeCharacter) p1; - obj2LocalID = cc1.LocalID; - cc1.AddCollisionEvent(cp2.LocalID, contact); - } - break; - case ActorTypes.Prim: - - if (p1 is OdePrim) - { - cp1 = (OdePrim) p1; - obj2LocalID = cp1.LocalID; - cp1.AddCollisionEvent(cp2.LocalID, contact); - } - break; - - case ActorTypes.Ground: - case ActorTypes.Unknown: - obj2LocalID = 0; - break; - } - - cp2.AddCollisionEvent(obj2LocalID, contact); + AddCollisionEventReporting(p2); + p2.AddCollisionEvent(0, contact); } break; + } } } + /// /// This is our collision testing routine in ODE /// + /// private void collision_optimized() { - _perloopContact.Clear(); - - foreach (OdeCharacter chr in _characters) - { - // Reset the collision values to false - // since we don't know if we're colliding yet - if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) - continue; - - chr.IsColliding = false; - chr.CollidingGround = false; - chr.CollidingObj = false; - - // Test the avatar's geometry for collision with the space - // This will return near and the space that they are the closest to - // And we'll run this again against the avatar and the space segment - // This will return with a bunch of possible objects in the space segment - // and we'll run it again on all of them. + lock (_characters) + { try { - CollideSpaces(space, chr.Shell, IntPtr.Zero); + foreach (OdeCharacter chr in _characters) + { + if (chr == null) + continue; + + chr.IsColliding = false; + // chr.CollidingGround = false; not done here + chr.CollidingObj = false; + + if(chr.Body == IntPtr.Zero || chr.collider == IntPtr.Zero ) + continue; + + // do colisions with static space + d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); + + // no coll with gnd + } + // chars with chars + d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); + } catch (AccessViolationException) { - m_log.ErrorFormat("[ODE SCENE]: Unable to space collide {0}", PhysicsSceneName); + m_log.Warn("[PHYSICS]: Unable to collide Character to static space"); } - - //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); - //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10) - //{ - //chr.Position.Z = terrainheight + 10.0f; - //forcedZ = true; - //} + } - if (CollectStats) + lock (_activeprims) { - m_tempAvatarCollisionsThisFrame = _perloopContact.Count; - m_stats[ODEAvatarContactsStatsName] += m_tempAvatarCollisionsThisFrame; + foreach (OdePrim aprim in _activeprims) + { + aprim.CollisionScore = 0; + aprim.IsColliding = false; + } } - - List removeprims = null; - foreach (OdePrim chr in _activeprims) + lock (_activegroups) { - if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) + try { - try + foreach (OdePrim aprim in _activegroups) { - lock (chr) + if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body) && + aprim.collide_geom != IntPtr.Zero) { - if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) - { - CollideSpaces(space, chr.prim_geom, IntPtr.Zero); - } - else - { - if (removeprims == null) - { - removeprims = new List(); - } - removeprims.Add(chr); - m_log.Error( - "[ODE SCENE]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!"); - } + d.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); + d.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); } } - catch (AccessViolationException) - { - m_log.Error("[ODE SCENE]: Unable to space collide"); - } } - } - - if (CollectStats) - m_stats[ODEPrimContactsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame; - - if (removeprims != null) - { - foreach (OdePrim chr in removeprims) + catch (Exception e) { - _activeprims.Remove(chr); + m_log.Warn("[PHYSICS]: Unable to collide Active to Static: " + e.Message); } } - } - - #endregion - // Recovered for use by fly height. Kitto Flora - internal float GetTerrainHeightAtXY(float x, float y) - { - IntPtr heightFieldGeom = IntPtr.Zero; - int offsetX = 0; - int offsetY = 0; - - if(RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom)) + // colide active amoung them + try { - if (heightFieldGeom != IntPtr.Zero) - { - if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) - { - - int index; - - - if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y || - (int)x < 0.001f || (int)y < 0.001f) - return 0; - - x = x - offsetX + 1f; - y = y - offsetY + 1f; - - // map is rotated - index = (int)x * ((int)m_regionHeight + 3) + (int)y; - - if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) - { - //m_log.DebugFormat("x{0} y{1} = {2}", x, y, (float)TerrainHeightFieldHeights[heightFieldGeom][index]); - return (float)TerrainHeightFieldHeights[heightFieldGeom][index]; - } - - else - return 0f; - } - else - { - return 0f; - } - - } - else - { - return 0f; - } + d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); + } + catch (Exception e) + { + m_log.Warn("[PHYSICS]: Unable to collide in Active: " + e.Message); + } + // and with chars + try + { + d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); } - else + catch (Exception e) { - return 0f; + m_log.Warn("[PHYSICS]: Unable to collide Active to Character: " + e.Message); } - } -// End recovered. Kitto Flora + } + #endregion /// /// Add actor to the list that should receive collision events in the simulate loop. /// /// - internal void AddCollisionEventReporting(PhysicsActor obj) + public void AddCollisionEventReporting(PhysicsActor obj) { -// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID); - - lock (m_collisionEventActorsChanges) - m_collisionEventActorsChanges[obj.LocalID] = obj; + if (!_collisionEventPrim.Contains(obj)) + _collisionEventPrim.Add(obj); } /// /// Remove actor from the list that should receive collision events in the simulate loop. /// /// - internal void RemoveCollisionEventReporting(PhysicsActor obj) - { -// m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID); - - lock (m_collisionEventActorsChanges) - m_collisionEventActorsChanges[obj.LocalID] = null; - } - - #region Add/Remove Entities - - public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) - { - d.AllocateODEDataForThread(0); - - OdeCharacter newAv - = new OdeCharacter( - avName, this, position, velocity, size, avPIDD, avPIDP, - avCapRadius, avStandupTensor, avDensity, - avMovementDivisorWalk, avMovementDivisorRun); - - newAv.Flying = isFlying; - newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; - newAv.m_avatarplanted = avplanted; - - return newAv; - } - - public override void RemoveAvatar(PhysicsActor actor) - { -// m_log.DebugFormat( -// "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2}", -// actor.Name, actor.LocalID, Name); - - lock (OdeLock) - { - d.AllocateODEDataForThread(0); - - ((OdeCharacter) actor).Destroy(); - } - } - - internal void AddCharacter(OdeCharacter chr) - { - chr.m_avatarplanted = avplanted; - if (!_characters.Contains(chr)) - { - _characters.Add(chr); - -// m_log.DebugFormat( -// "[ODE SCENE]: Adding physics character {0} {1} to physics scene {2}. Count now {3}", -// chr.Name, chr.LocalID, Name, _characters.Count); - - if (chr.bad) - m_log.ErrorFormat("[ODE SCENE]: Added BAD actor {0} to characters list", chr.m_uuid); - } - else - { - m_log.ErrorFormat( - "[ODE SCENE]: Tried to add character {0} {1} but they are already in the set!", - chr.Name, chr.LocalID); - } - } - - internal void RemoveCharacter(OdeCharacter chr) - { - if (_characters.Contains(chr)) - { - _characters.Remove(chr); - -// m_log.DebugFormat( -// "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2}. Count now {3}", -// chr.Name, chr.LocalID, Name, _characters.Count); - } - else - { - m_log.ErrorFormat( - "[ODE SCENE]: Tried to remove character {0} {1} but they are not in the list!", - chr.Name, chr.LocalID); - } - } - - private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, - PrimitiveBaseShape pbs, bool isphysical, uint localID) + public void RemoveCollisionEventReporting(PhysicsActor obj) { - Vector3 pos = position; - Vector3 siz = size; - Quaternion rot = rotation; - - - OdePrim newPrim; - lock (OdeLock) + lock(_collisionEventPrimRemove) { - d.AllocateODEDataForThread(0); - newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical); - - lock (_prims) - _prims.Add(newPrim); + if (_collisionEventPrim.Contains(obj) && !_collisionEventPrimRemove.Contains(obj)) + _collisionEventPrimRemove.Add(obj); } - newPrim.LocalID = localID; - return newPrim; - } - - /// - /// Make this prim subject to physics. - /// - /// - internal void ActivatePrim(OdePrim prim) - { - // adds active prim.. (ones that should be iterated over in collisions_optimized - if (!_activeprims.Contains(prim)) - _activeprims.Add(prim); - //else - // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, uint localid) - { -// m_log.DebugFormat("[ODE SCENE]: Adding physics prim {0} {1} to physics scene {2}", primName, localid, Name); - - return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); } public override float TimeDilation @@ -1824,362 +1235,133 @@ namespace OpenSim.Region.PhysicsModule.ODE public override bool SupportsNINJAJoints { - get { return m_NINJA_physics_joints_enabled; } - } - - // internal utility function: must be called within a lock (OdeLock) - private void InternalAddActiveJoint(PhysicsJoint joint) - { - activeJoints.Add(joint); - SOPName_to_activeJoint.Add(joint.ObjectNameInScene, joint); + get { return false; } } - // internal utility function: must be called within a lock (OdeLock) - private void InternalAddPendingJoint(OdePhysicsJoint joint) - { - pendingJoints.Add(joint); - SOPName_to_pendingJoint.Add(joint.ObjectNameInScene, joint); - } + #region Add/Remove Entities - // internal utility function: must be called within a lock (OdeLock) - private void InternalRemovePendingJoint(PhysicsJoint joint) + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) { - pendingJoints.Remove(joint); - SOPName_to_pendingJoint.Remove(joint.ObjectNameInScene); + return null; } - // internal utility function: must be called within a lock (OdeLock) - private void InternalRemoveActiveJoint(PhysicsJoint joint) + public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying) { - activeJoints.Remove(joint); - SOPName_to_activeJoint.Remove(joint.ObjectNameInScene); + OdeCharacter newAv = new OdeCharacter(localID, avName, this, position, + size, feetOffset, avDensity, avMovementDivisorWalk, avMovementDivisorRun); + newAv.Flying = isFlying; + newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; + + return newAv; } - public override void DumpJointInfo() + public void AddCharacter(OdeCharacter chr) { - string hdr = "[NINJA] JOINTINFO: "; - foreach (PhysicsJoint j in pendingJoints) - { - m_log.Debug(hdr + " pending joint, Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); - } - m_log.Debug(hdr + pendingJoints.Count + " total pending joints"); - foreach (string jointName in SOPName_to_pendingJoint.Keys) - { - m_log.Debug(hdr + " pending joints dict contains Name: " + jointName); - } - m_log.Debug(hdr + SOPName_to_pendingJoint.Keys.Count + " total pending joints dict entries"); - foreach (PhysicsJoint j in activeJoints) + lock (_characters) { - m_log.Debug(hdr + " active joint, Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); - } - m_log.Debug(hdr + activeJoints.Count + " total active joints"); - foreach (string jointName in SOPName_to_activeJoint.Keys) - { - m_log.Debug(hdr + " active joints dict contains Name: " + jointName); - } - m_log.Debug(hdr + SOPName_to_activeJoint.Keys.Count + " total active joints dict entries"); - - m_log.Debug(hdr + " Per-body joint connectivity information follows."); - m_log.Debug(hdr + joints_connecting_actor.Keys.Count + " bodies are connected by joints."); - foreach (string actorName in joints_connecting_actor.Keys) - { - m_log.Debug(hdr + " Actor " + actorName + " has the following joints connecting it"); - foreach (PhysicsJoint j in joints_connecting_actor[actorName]) + if (!_characters.Contains(chr)) { - m_log.Debug(hdr + " * joint Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); + _characters.Add(chr); + if (chr.bad) + m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); } - m_log.Debug(hdr + joints_connecting_actor[actorName].Count + " connecting joints total for this actor"); } } - public override void RequestJointDeletion(string ObjectNameInScene) + public void RemoveCharacter(OdeCharacter chr) { - lock (externalJointRequestsLock) + lock (_characters) { - if (!requestedJointsToBeDeleted.Contains(ObjectNameInScene)) // forbid same deletion request from entering twice to prevent spurious deletions processed asynchronously + if (_characters.Contains(chr)) { - requestedJointsToBeDeleted.Add(ObjectNameInScene); + _characters.Remove(chr); } } } - private void DeleteRequestedJoints() + public void BadCharacter(OdeCharacter chr) { - List myRequestedJointsToBeDeleted; - lock (externalJointRequestsLock) + lock (_badCharacter) { - // make a local copy of the shared list for processing (threading issues) - myRequestedJointsToBeDeleted = new List(requestedJointsToBeDeleted); - } - - foreach (string jointName in myRequestedJointsToBeDeleted) - { - lock (OdeLock) - { - //m_log.Debug("[NINJA] trying to deleting requested joint " + jointName); - if (SOPName_to_activeJoint.ContainsKey(jointName) || SOPName_to_pendingJoint.ContainsKey(jointName)) - { - OdePhysicsJoint joint = null; - if (SOPName_to_activeJoint.ContainsKey(jointName)) - { - joint = SOPName_to_activeJoint[jointName] as OdePhysicsJoint; - InternalRemoveActiveJoint(joint); - } - else if (SOPName_to_pendingJoint.ContainsKey(jointName)) - { - joint = SOPName_to_pendingJoint[jointName] as OdePhysicsJoint; - InternalRemovePendingJoint(joint); - } - - if (joint != null) - { - //m_log.Debug("joint.BodyNames.Count is " + joint.BodyNames.Count + " and contents " + joint.BodyNames); - for (int iBodyName = 0; iBodyName < 2; iBodyName++) - { - string bodyName = joint.BodyNames[iBodyName]; - if (bodyName != "NULL") - { - joints_connecting_actor[bodyName].Remove(joint); - if (joints_connecting_actor[bodyName].Count == 0) - { - joints_connecting_actor.Remove(bodyName); - } - } - } - - DoJointDeactivated(joint); - if (joint.jointID != IntPtr.Zero) - { - d.JointDestroy(joint.jointID); - joint.jointID = IntPtr.Zero; - //DoJointErrorMessage(joint, "successfully destroyed joint " + jointName); - } - else - { - //m_log.Warn("[NINJA] Ignoring re-request to destroy joint " + jointName); - } - } - else - { - // DoJointErrorMessage(joint, "coult not find joint to destroy based on name " + jointName); - } - } - else - { - // DoJointErrorMessage(joint, "WARNING - joint removal failed, joint " + jointName); - } - } - } - - // remove processed joints from the shared list - lock (externalJointRequestsLock) - { - foreach (string jointName in myRequestedJointsToBeDeleted) - { - requestedJointsToBeDeleted.Remove(jointName); - } + if (!_badCharacter.Contains(chr)) + _badCharacter.Add(chr); } } - // for pending joints we don't know if their associated bodies exist yet or not. - // the joint is actually created during processing of the taints - private void CreateRequestedJoints() + public override void RemoveAvatar(PhysicsActor actor) { - List myRequestedJointsToBeCreated; - lock (externalJointRequestsLock) - { - // make a local copy of the shared list for processing (threading issues) - myRequestedJointsToBeCreated = new List(requestedJointsToBeCreated); - } - - foreach (PhysicsJoint joint in myRequestedJointsToBeCreated) - { - lock (OdeLock) - { - if (SOPName_to_pendingJoint.ContainsKey(joint.ObjectNameInScene) && SOPName_to_pendingJoint[joint.ObjectNameInScene] != null) - { - DoJointErrorMessage(joint, "WARNING: ignoring request to re-add already pending joint Name:" + joint.ObjectNameInScene + " type:" + joint.Type + " parms: " + joint.RawParams + " pos: " + joint.Position + " rot:" + joint.Rotation); - continue; - } - if (SOPName_to_activeJoint.ContainsKey(joint.ObjectNameInScene) && SOPName_to_activeJoint[joint.ObjectNameInScene] != null) - { - DoJointErrorMessage(joint, "WARNING: ignoring request to re-add already active joint Name:" + joint.ObjectNameInScene + " type:" + joint.Type + " parms: " + joint.RawParams + " pos: " + joint.Position + " rot:" + joint.Rotation); - continue; - } - - InternalAddPendingJoint(joint as OdePhysicsJoint); - - if (joint.BodyNames.Count >= 2) - { - for (int iBodyName = 0; iBodyName < 2; iBodyName++) - { - string bodyName = joint.BodyNames[iBodyName]; - if (bodyName != "NULL") - { - if (!joints_connecting_actor.ContainsKey(bodyName)) - { - joints_connecting_actor.Add(bodyName, new List()); - } - joints_connecting_actor[bodyName].Add(joint); - } - } - } - } - } - - // remove processed joints from shared list - lock (externalJointRequestsLock) + //m_log.Debug("[PHYSICS]:ODELOCK"); + lock (OdeLock) { - foreach (PhysicsJoint joint in myRequestedJointsToBeCreated) - { - requestedJointsToBeCreated.Remove(joint); - } + d.AllocateODEDataForThread(0); + ((OdeCharacter) actor).Destroy(); } } - /// - /// Add a request for joint creation. - /// - /// - /// this joint will just be added to a waiting list that is NOT processed during the main - /// Simulate() loop (to avoid deadlocks). After Simulate() is finished, we handle unprocessed joint requests. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public override PhysicsJoint RequestJointCreation( - string objectNameInScene, PhysicsJointType jointType, Vector3 position, - Quaternion rotation, string parms, List bodyNames, string trackedBodyName, Quaternion localRotation) - { - OdePhysicsJoint joint = new OdePhysicsJoint(); - joint.ObjectNameInScene = objectNameInScene; - joint.Type = jointType; - joint.Position = position; - joint.Rotation = rotation; - joint.RawParams = parms; - joint.BodyNames = new List(bodyNames); - joint.TrackedBodyName = trackedBodyName; - joint.LocalRotation = localRotation; - joint.jointID = IntPtr.Zero; - joint.ErrorMessageCount = 0; - lock (externalJointRequestsLock) + public void addActivePrim(OdePrim activatePrim) + { + // adds active prim.. + lock (_activeprims) { - if (!requestedJointsToBeCreated.Contains(joint)) // forbid same creation request from entering twice - { - requestedJointsToBeCreated.Add(joint); - } + if (!_activeprims.Contains(activatePrim)) + _activeprims.Add(activatePrim); } - - return joint; } - private void RemoveAllJointsConnectedToActor(PhysicsActor actor) + public void addActiveGroups(OdePrim activatePrim) { - //m_log.Debug("RemoveAllJointsConnectedToActor: start"); - if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null) + lock (_activegroups) { - List jointsToRemove = new List(); - //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism) - foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName]) - { - jointsToRemove.Add(j); - } - foreach (PhysicsJoint j in jointsToRemove) - { - //m_log.Debug("RemoveAllJointsConnectedToActor: about to request deletion of " + j.ObjectNameInScene); - RequestJointDeletion(j.ObjectNameInScene); - //m_log.Debug("RemoveAllJointsConnectedToActor: done request deletion of " + j.ObjectNameInScene); - j.TrackedBodyName = null; // *IMMEDIATELY* prevent any further movement of this joint (else a deleted actor might cause spurious tracking motion of the joint for a few frames, leading to the joint proxy object disappearing) - } + if (!_activegroups.Contains(activatePrim)) + _activegroups.Add(activatePrim); } } - public override void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor) + private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, + PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID) { - //m_log.Debug("RemoveAllJointsConnectedToActorThreadLocked: start"); + OdePrim newPrim; lock (OdeLock) { - //m_log.Debug("RemoveAllJointsConnectedToActorThreadLocked: got lock"); - RemoveAllJointsConnectedToActor(actor); + + newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID); } + return newPrim; } - // normally called from within OnJointMoved, which is called from within a lock (OdeLock) - public override Vector3 GetJointAnchor(PhysicsJoint joint) + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid) { - Debug.Assert(joint.IsInPhysicsEngine); - d.Vector3 pos = new d.Vector3(); + return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid); + } - if (!(joint is OdePhysicsJoint)) - { - DoJointErrorMessage(joint, "warning: non-ODE joint requesting anchor: " + joint.ObjectNameInScene); - } - else - { - OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint; - switch (odeJoint.Type) - { - case PhysicsJointType.Ball: - d.JointGetBallAnchor(odeJoint.jointID, out pos); - break; - case PhysicsJointType.Hinge: - d.JointGetHingeAnchor(odeJoint.jointID, out pos); - break; - } - } - return new Vector3(pos.X, pos.Y, pos.Z); + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) + { + return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid); } - /// - /// Get joint axis. - /// - /// - /// normally called from within OnJointMoved, which is called from within a lock (OdeLock) - /// WARNING: ODE sometimes returns <0,0,0> as the joint axis! Therefore this function - /// appears to be unreliable. Fortunately we can compute the joint axis ourselves by - /// keeping track of the joint's original orientation relative to one of the involved bodies. - /// - /// - /// - public override Vector3 GetJointAxis(PhysicsJoint joint) + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid) { - Debug.Assert(joint.IsInPhysicsEngine); - d.Vector3 axis = new d.Vector3(); + return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid); + } - if (!(joint is OdePhysicsJoint)) + public void remActivePrim(OdePrim deactivatePrim) + { + lock (_activeprims) { - DoJointErrorMessage(joint, "warning: non-ODE joint requesting anchor: " + joint.ObjectNameInScene); + _activeprims.Remove(deactivatePrim); } - else - { - OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint; - switch (odeJoint.Type) - { - case PhysicsJointType.Ball: - DoJointErrorMessage(joint, "warning - axis requested for ball joint: " + joint.ObjectNameInScene); - break; - case PhysicsJointType.Hinge: - d.JointGetHingeAxis(odeJoint.jointID, out axis); - break; - } - } - return new Vector3(axis.X, axis.Y, axis.Z); } - - /// - /// Stop this prim being subject to physics - /// - /// - internal void DeactivatePrim(OdePrim prim) + public void remActiveGroup(OdePrim deactivatePrim) { - _activeprims.Remove(prim); + lock (_activegroups) + { + _activegroups.Remove(deactivatePrim); + } } public override void RemovePrim(PhysicsActor prim) @@ -2188,434 +1370,200 @@ namespace OpenSim.Region.PhysicsModule.ODE // removed in the next physics simulate pass. if (prim is OdePrim) { - lock (OdeLock) +// lock (OdeLock) { - OdePrim p = (OdePrim) prim; - + + OdePrim p = (OdePrim)prim; p.setPrimForRemoval(); - AddPhysicsActorTaint(prim); } } } - /// - /// This is called from within simulate but outside the locked portion - /// We need to do our own locking here - /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in - /// Simulate() -- justincc). - /// - /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. - /// - /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory - /// that the space was using. - /// - /// - internal void RemovePrimThreadLocked(OdePrim prim) + public void RemovePrimThreadLocked(OdePrim prim) { -// m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID); - + //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); lock (prim) { - RemoveCollisionEventReporting(prim); - - if (prim.prim_geom != IntPtr.Zero) - { - prim.ResetTaints(); - - if (prim.IsPhysical) - { - prim.disableBody(); - if (prim.childPrim) - { - prim.childPrim = false; - prim.Body = IntPtr.Zero; - prim.m_disabled = true; - prim.IsPhysical = false; - } - - - } - prim.m_targetSpace = IntPtr.Zero; - if (!prim.RemoveGeom()) - m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); - - lock (_prims) - _prims.Remove(prim); - - - if (SupportsNINJAJoints) - RemoveAllJointsConnectedToActorThreadLocked(prim); - } +// RemoveCollisionEventReporting(prim); + lock (_prims) + _prims.Remove(prim.LocalID); } - } - #endregion + } - #region Space Separation Calculation + public void addToPrims(OdePrim prim) + { + lock (_prims) + _prims[prim.LocalID] = prim; + } - /// - /// Takes a space pointer and zeros out the array we're using to hold the spaces - /// - /// - private void resetSpaceArrayItemToZero(IntPtr pSpace) + public OdePrim getPrim(uint id) { - for (int x = 0; x < staticPrimspace.GetLength(0); x++) + lock (_prims) { - for (int y = 0; y < staticPrimspace.GetLength(1); y++) - { - if (staticPrimspace[x, y] == pSpace) - staticPrimspace[x, y] = IntPtr.Zero; - } + if(_prims.ContainsKey(id)) + return _prims[id]; + else + return null; } } -// private void resetSpaceArrayItemToZero(int arrayitemX, int arrayitemY) -// { -// staticPrimspace[arrayitemX, arrayitemY] = IntPtr.Zero; -// } - - /// - /// Called when a static prim moves. Allocates a space for the prim based on its position - /// - /// the pointer to the geom that moved - /// the position that the geom moved to - /// a pointer to the space it was in before it was moved. - /// a pointer to the new space it's in - internal IntPtr recalculateSpaceForGeom(IntPtr geom, Vector3 pos, IntPtr currentspace) + public bool havePrim(OdePrim prm) { - // Called from setting the Position and Size of an ODEPrim so - // it's already in locked space. - - // we don't want to remove the main space - // we don't need to test physical here because this function should - // never be called if the prim is physical(active) + lock (_prims) + return _prims.ContainsKey(prm.LocalID); + } - // All physical prim end up in the root space - //Thread.Sleep(20); - if (currentspace != space) + public void changePrimID(OdePrim prim,uint oldID) + { + lock (_prims) { - //m_log.Info("[SPACE]: C:" + currentspace.ToString() + " g:" + geom.ToString()); - //if (currentspace == IntPtr.Zero) - //{ - //int adfadf = 0; - //} - if (d.SpaceQuery(currentspace, geom) && currentspace != IntPtr.Zero) - { - if (d.GeomIsSpace(currentspace)) - { -// waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); - } - else - { - m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + currentspace + - " Geom:" + geom); - } - } - else - { - IntPtr sGeomIsIn = d.GeomGetSpace(geom); - if (sGeomIsIn != IntPtr.Zero) - { - if (d.GeomIsSpace(currentspace)) - { -// waitForSpaceUnlock(sGeomIsIn); - d.SpaceRemove(sGeomIsIn, geom); - } - else - { - m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + - sGeomIsIn + " Geom:" + geom); - } - } - } - - //If there are no more geometries in the sub-space, we don't need it in the main space anymore - if (d.SpaceGetNumGeoms(currentspace) == 0) - { - if (currentspace != IntPtr.Zero) - { - if (d.GeomIsSpace(currentspace)) - { - d.SpaceRemove(space, currentspace); - // free up memory used by the space. - - resetSpaceArrayItemToZero(currentspace); - } - else - { - m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + - currentspace + " Geom:" + geom); - } - } - } + if(_prims.ContainsKey(oldID)) + _prims.Remove(oldID); + _prims[prim.LocalID] = prim; } - else + } + + public bool haveActor(PhysicsActor actor) + { + if (actor is OdePrim) { - // this is a physical object that got disabled. ;.; - if (currentspace != IntPtr.Zero && geom != IntPtr.Zero) - { - if (d.SpaceQuery(currentspace, geom)) - { - if (d.GeomIsSpace(currentspace)) - { -// waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); - } - else - { - m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + - currentspace + " Geom:" + geom); - } - } - else - { - IntPtr sGeomIsIn = d.GeomGetSpace(geom); - if (sGeomIsIn != IntPtr.Zero) - { - if (d.GeomIsSpace(sGeomIsIn)) - { -// waitForSpaceUnlock(sGeomIsIn); - d.SpaceRemove(sGeomIsIn, geom); - } - else - { - m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + - sGeomIsIn + " Geom:" + geom); - } - } - } - } + lock (_prims) + return _prims.ContainsKey(((OdePrim)actor).LocalID); } - - // The routines in the Position and Size sections do the 'inserting' into the space, - // so all we have to do is make sure that the space that we're putting the prim into - // is in the 'main' space. - int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos); - IntPtr newspace = calculateSpaceForGeom(pos); - - if (newspace == IntPtr.Zero) + else if (actor is OdeCharacter) { - newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); - d.HashSpaceSetLevels(newspace, HashspaceLow, HashspaceHigh); + lock (_characters) + return _characters.Contains((OdeCharacter)actor); } - - return newspace; + return false; } - /// - /// Creates a new space at X Y - /// - /// - /// - /// A pointer to the created space - internal IntPtr createprimspace(int iprimspaceArrItemX, int iprimspaceArrItemY) - { - // creating a new space for prim and inserting it into main space. - staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); - d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); -// waitForSpaceUnlock(space); - d.SpaceSetSublevel(space, 1); - d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); - - return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; - } + #endregion - /// - /// Calculates the space the prim should be in by its position - /// - /// - /// a pointer to the space. This could be a new space or reused space. - internal IntPtr calculateSpaceForGeom(Vector3 pos) - { - int[] xyspace = calculateSpaceArrayItemFromPos(pos); - //m_log.Info("[Physics]: Attempting to use arrayItem: " + xyspace[0].ToString() + "," + xyspace[1].ToString()); - return staticPrimspace[xyspace[0], xyspace[1]]; - } + #region Space Separation Calculation /// - /// Holds the space allocation logic + /// Called when a static prim moves or becomes static + /// Places the prim in a space one the static sub-spaces grid /// - /// - /// an array item based on the position - internal int[] calculateSpaceArrayItemFromPos(Vector3 pos) + /// the pointer to the geom that moved + /// the position that the geom moved to + /// a pointer to the space it was in before it was moved. + /// a pointer to the new space it's in + public IntPtr MoveGeomToStaticSpace(IntPtr geom, Vector3 pos, IntPtr currentspace) { - int[] returnint = new int[2]; + // moves a prim into another static sub-space or from another space into a static sub-space - returnint[0] = (int) (pos.X * spacesPerMeterX); - - if (returnint[0] > spaceGridMaxX) - returnint[0] = spaceGridMaxX; - if (returnint[0] < 0) - returnint[0] = 0; - - returnint[1] = (int)(pos.Y * spacesPerMeterY); - if (returnint[1] > spaceGridMaxY) - returnint[1] = spaceGridMaxY; - if (returnint[1] < 0) - returnint[1] = 0; - - return returnint; - } - - #endregion + // Called ODEPrim so + // it's already in locked space. - /// - /// Routine to figure out if we need to mesh this prim with our mesher - /// - /// - /// - internal bool needsMeshing(PrimitiveBaseShape pbs) - { - // most of this is redundant now as the mesher will return null if it cant mesh a prim - // but we still need to check for sculptie meshing being enabled so this is the most - // convenient place to do it for now... + if (geom == IntPtr.Zero) // shouldn't happen + return IntPtr.Zero; - // //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f) - // //m_log.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString()); - int iPropertiesNotSupportedDefault = 0; + // get the static sub-space for current position + IntPtr newspace = calculateSpaceForGeom(pos); - if (pbs.SculptEntry && !meshSculptedPrim) - { -#if SPAM - m_log.Warn("NonMesh"); -#endif - return false; - } + if (newspace == currentspace) // if we are there all done + return newspace; - // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim - if (!forceSimplePrimMeshing && !pbs.SculptEntry) + // else remove it from its current space + if (currentspace != IntPtr.Zero && d.SpaceQuery(currentspace, geom)) { - if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) - || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 - && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) + if (d.GeomIsSpace(currentspace)) { + waitForSpaceUnlock(currentspace); + d.SpaceRemove(currentspace, geom); - if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 - && pbs.ProfileHollow == 0 - && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 - && pbs.PathBegin == 0 && pbs.PathEnd == 0 - && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 - && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 - && pbs.PathShearX == 0 && pbs.PathShearY == 0) + if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) { -#if SPAM - m_log.Warn("NonMesh"); -#endif - return false; + d.SpaceDestroy(currentspace); } } + else + { + m_log.Info("[Physics]: Invalid or empty Space passed to 'MoveGeomToStaticSpace':" + currentspace + + " Geom:" + geom); + } } + else // odd currentspace is null or doesn't contain the geom? lets try the geom ideia of current space + { + currentspace = d.GeomGetSpace(geom); + if (currentspace != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { + waitForSpaceUnlock(currentspace); + d.SpaceRemove(currentspace, geom); - if (pbs.ProfileHollow != 0) - iPropertiesNotSupportedDefault++; - - if ((pbs.PathBegin != 0) || pbs.PathEnd != 0) - iPropertiesNotSupportedDefault++; + if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) + { + d.SpaceDestroy(currentspace); + } - if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) - iPropertiesNotSupportedDefault++; + } + } + } - if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) - iPropertiesNotSupportedDefault++; + // put the geom in the newspace + waitForSpaceUnlock(newspace); + d.SpaceAdd(newspace, geom); - if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) - iPropertiesNotSupportedDefault++; + // let caller know this newspace + return newspace; + } - if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) - iPropertiesNotSupportedDefault++; + /// + /// Calculates the space the prim should be in by its position + /// + /// + /// a pointer to the space. This could be a new space or reused space. + public IntPtr calculateSpaceForGeom(Vector3 pos) + { + int x, y; - if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) - iPropertiesNotSupportedDefault++; + if (pos.X < 0) + return staticPrimspaceOffRegion[0]; - if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) - iPropertiesNotSupportedDefault++; + if (pos.Y < 0) + return staticPrimspaceOffRegion[2]; - if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1) - iPropertiesNotSupportedDefault++; + x = (int)(pos.X * spacesPerMeterX); + if (x > spaceGridMaxX) + return staticPrimspaceOffRegion[1]; + + y = (int)(pos.Y * spacesPerMeterY); + if (y > spaceGridMaxY) + return staticPrimspaceOffRegion[3]; - // test for torus - if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square) - { - if (pbs.PathCurve == (byte)Extrusion.Curve1) - { - iPropertiesNotSupportedDefault++; - } - } - else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) - { - if (pbs.PathCurve == (byte)Extrusion.Straight) - { - iPropertiesNotSupportedDefault++; - } + return staticPrimspace[x, y]; + } + + #endregion - // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits - else if (pbs.PathCurve == (byte)Extrusion.Curve1) - { - iPropertiesNotSupportedDefault++; - } - } - else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) - { - if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2) - { - iPropertiesNotSupportedDefault++; - } - } - else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) - { - if (pbs.PathCurve == (byte)Extrusion.Straight) - { - iPropertiesNotSupportedDefault++; - } - else if (pbs.PathCurve == (byte)Extrusion.Curve1) - { - iPropertiesNotSupportedDefault++; - } - } - if (pbs.SculptEntry && meshSculptedPrim) - iPropertiesNotSupportedDefault++; + /// + /// Called to queue a change to a actor + /// to use in place of old taint mechanism so changes do have a time sequence + /// - if (iPropertiesNotSupportedDefault == 0) - { -#if SPAM - m_log.Warn("NonMesh"); -#endif - return false; - } -#if SPAM - m_log.Debug("Mesh"); -#endif - return true; + public void AddChange(PhysicsActor actor, changes what, Object arg) + { + ODEchangeitem item = new ODEchangeitem(); + item.actor = actor; + item.what = what; + item.arg = arg; + ChangesQueue.Enqueue(item); } /// /// Called after our prim properties are set Scale, position etc. - /// - /// /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex /// This assures us that we have no race conditions - /// - /// - public override void AddPhysicsActorTaint(PhysicsActor actor) + /// + /// + public override void AddPhysicsActorTaint(PhysicsActor prim) { - if (actor is OdePrim) - { - OdePrim taintedprim = ((OdePrim)actor); - lock (_taintedPrims) - _taintedPrims.Add(taintedprim); - } - else if (actor is OdeCharacter) - { - OdeCharacter taintedchar = ((OdeCharacter)actor); - lock (_taintedActors) - { - _taintedActors.Add(taintedchar); - if (taintedchar.bad) - m_log.ErrorFormat("[ODE SCENE]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); - } - } } // does all pending changes generated during region load process @@ -2625,319 +1573,315 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (world == IntPtr.Zero) { - _taintedPrims.Clear();; + ChangesQueue.Clear(); return; } + d.AllocateODEDataForThread(~0U); + + ODEchangeitem item; + int donechanges = 0; - if (_taintedPrims.Count > 0) + if (ChangesQueue.Count > 0) { - - m_log.InfoFormat("[Ode] start processing pending actor operations"); + m_log.InfoFormat("[ubOde] start processing pending actor operations"); int tstart = Util.EnvironmentTickCount(); - d.AllocateODEDataForThread(0); - - lock (_taintedPrims) + while (ChangesQueue.Dequeue(out item)) { - foreach (OdePrim prim in _taintedPrims) + if (item.actor != null) { - if (prim.m_taintremove) - RemovePrimThreadLocked(prim); - else - prim.ProcessTaints(); - - prim.m_collisionscore = 0; - donechanges++; + try + { + if (item.actor is OdeCharacter) + ((OdeCharacter)item.actor).DoAChange(item.what, item.arg); + else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) + RemovePrimThreadLocked((OdePrim)item.actor); + } + catch + { + m_log.WarnFormat("[PHYSICS]: Operation failed for a actor {0} {1}", + item.actor.Name, item.what.ToString()); + } } - _taintedPrims.Clear(); + donechanges++; } - int time = Util.EnvironmentTickCountSubtract(tstart); - m_log.InfoFormat("[Ode] finished {0} operations in {1}ms", donechanges, time); + m_log.InfoFormat("[ubOde] finished {0} operations in {1}ms", donechanges, time); } - m_log.InfoFormat("[Ode] {0} prim actors loaded",_prims.Count); + m_log.InfoFormat("[ubOde] {0} prim actors loaded",_prims.Count); } } - /// /// This is our main simulate loop - /// - /// /// It's thread locked by a Mutex in the scene. /// It holds Collisions, it instructs ODE to step through the physical reactions /// It moves the objects around in memory /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) - /// + /// /// - /// The number of frames simulated over that period. - public override float Simulate(float timeStep) + /// + public override float Simulate(float reqTimeStep) { - if (!_worldInitialized) - return 1.0f; + DateTime now = DateTime.UtcNow; + TimeSpan timedif = now - m_lastframe; + float timeStep = (float)timedif.TotalSeconds; + m_lastframe = now; + + // acumulate time so we can reduce error + step_time += timeStep; - int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; - int tempTick = 0, tempTick2 = 0; + if (step_time < HalfOdeStep) + return 0; - if (framecount >= int.MaxValue) + if (framecount < 0) framecount = 0; framecount++; +// checkThread(); + int nodeframes = 0; float fps = 0; - step_time += timeStep; - - float HalfOdeStep = ODE_STEPSIZE * 0.5f; - if (step_time < HalfOdeStep) - return 0; - - - // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential - // deadlock if the collision event tries to lock something else later on which is already locked by a - // caller that is adding or removing the collision event. - lock (m_collisionEventActorsChanges) + lock (SimulationLock) + lock(OdeLock) { - foreach (KeyValuePair kvp in m_collisionEventActorsChanges) + if (world == IntPtr.Zero) { - if (kvp.Value == null) - m_collisionEventActors.Remove(kvp.Key); - else - m_collisionEventActors[kvp.Key] = kvp.Value; + ChangesQueue.Clear(); + return 0; } - m_collisionEventActorsChanges.Clear(); - } - - if (SupportsNINJAJoints) - { - DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks - CreateRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks - } - - - lock (OdeLock) - { + ODEchangeitem item; + +// d.WorldSetQuickStepNumIterations(world, curphysiteractions); + + int loopstartMS = Util.EnvironmentTickCount(); + int looptimeMS = 0; + int changestimeMS = 0; + int maxChangestime = (int)(reqTimeStep * 500f); // half the time + int maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time + d.AllocateODEDataForThread(~0U); - - while (step_time > HalfOdeStep) + + if (ChangesQueue.Count > 0) { - try + while (ChangesQueue.Dequeue(out item)) { - if (CollectStats) - tempTick = Util.EnvironmentTickCount(); - - lock (_taintedActors) - { - foreach (OdeCharacter character in _taintedActors) - character.ProcessTaints(); - - _taintedActors.Clear(); - } - - if (CollectStats) - { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODEAvatarTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; - } - - lock (_taintedPrims) + if (item.actor != null) { - foreach (OdePrim prim in _taintedPrims) + try { - if (prim.m_taintremove) - { -// Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name); - RemovePrimThreadLocked(prim); - } - else - { -// Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name); - prim.ProcessTaints(); - } - - prim.m_collisionscore = 0; - - // This loop can block up the Heartbeat for a very long time on large regions. - // We need to let the Watchdog know that the Heartbeat is not dead - // NOTE: This is currently commented out, but if things like OAR loading are - // timing the heartbeat out we will need to uncomment it - //Watchdog.UpdateThread(); + if (item.actor is OdeCharacter) + ((OdeCharacter)item.actor).DoAChange(item.what, item.arg); + else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) + RemovePrimThreadLocked((OdePrim)item.actor); + } + catch + { + m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}", + item.actor.Name, item.what.ToString()); } - - if (SupportsNINJAJoints) - SimulatePendingNINJAJoints(); - - _taintedPrims.Clear(); } + changestimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); + if (changestimeMS > maxChangestime) + break; + } + } - if (CollectStats) - { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODEPrimTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; - } + // do simulation taking at most 150ms total time including changes + while (step_time > HalfOdeStep) + { + try + { + // clear pointer/counter to contacts to pass into joints + m_global_contactcount = 0; - // Move characters - foreach (OdeCharacter actor in _characters) - actor.Move(defects); - if (defects.Count != 0) + // Move characters + lock (_characters) { - foreach (OdeCharacter actor in defects) + List defects = new List(); + foreach (OdeCharacter actor in _characters) { - m_log.ErrorFormat( - "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when moving", - actor.Name, actor.LocalID, PhysicsSceneName); - - RemoveCharacter(actor); - actor.DestroyOdeStructures(); + if (actor != null) + actor.Move(defects); + } + if (defects.Count != 0) + { + foreach (OdeCharacter defect in defects) + { + RemoveCharacter(defect); + } + defects.Clear(); } - - defects.Clear(); - } - - if (CollectStats) - { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODEAvatarForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; } // Move other active objects - foreach (OdePrim prim in _activeprims) - { - prim.m_collisionscore = 0; - prim.Move(timeStep); - } - - if (CollectStats) + lock (_activegroups) { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODEPrimForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; + foreach (OdePrim aprim in _activegroups) + { + aprim.Move(); + } } - + m_rayCastManager.ProcessQueuedRequests(); - if (CollectStats) - { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODERaycastingFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; - } - collision_optimized(); + List sleepers = new List(); - if (CollectStats) - { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODEOtherCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; - } - - foreach (PhysicsActor obj in m_collisionEventActors.Values) + foreach (PhysicsActor obj in _collisionEventPrim) { - // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); + if (obj == null) + continue; switch ((ActorTypes)obj.PhysicsActorType) { case ActorTypes.Agent: OdeCharacter cobj = (OdeCharacter)obj; - cobj.AddCollisionFrameTime(100); - cobj.SendCollisions(); + cobj.SendCollisions((int)(odetimestepMS)); break; case ActorTypes.Prim: OdePrim pobj = (OdePrim)obj; - pobj.SendCollisions(); + if (!pobj.m_outbounds) + { + pobj.SendCollisions((int)(odetimestepMS)); + if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected && + !pobj.m_disabled && !pobj.m_building && + !d.BodyIsEnabled(pobj.Body)) + sleepers.Add(pobj); + } break; } } -// if (m_global_contactcount > 0) -// m_log.DebugFormat( -// "[PHYSICS]: Collision contacts to process this frame = {0}", m_global_contactcount); + foreach(OdePrim prm in sleepers) + prm.SleeperAddCollisionEvents(); + sleepers.Clear(); - m_global_contactcount = 0; - - if (CollectStats) + lock(_collisionEventPrimRemove) { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; + foreach (PhysicsActor obj in _collisionEventPrimRemove) + _collisionEventPrim.Remove(obj); + + _collisionEventPrimRemove.Clear(); } - lock(SimulationLock) - d.WorldQuickStep(world, ODE_STEPSIZE); + // do a ode simulation step + d.WorldQuickStep(world, ODE_STEPSIZE); + d.JointGroupEmpty(contactgroup); + + // update managed ideia of physical data and do updates to core + /* + lock (_characters) + { + foreach (OdeCharacter actor in _characters) + { + if (actor != null) + { + if (actor.bad) + m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); - if (CollectStats) - m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); + actor.UpdatePositionAndVelocity(); + } + } + } + */ - d.JointGroupEmpty(contactgroup); + lock (_activegroups) + { + { + foreach (OdePrim actor in _activegroups) + { + if (actor.IsPhysical) + { + actor.UpdatePositionAndVelocity(framecount); + } + } + } + } } catch (Exception e) { - m_log.ErrorFormat("[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e); + m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); +// ode.dunlock(world); } step_time -= ODE_STEPSIZE; - fps += ODE_STEPSIZE; - } - - if (CollectStats) - tempTick = Util.EnvironmentTickCount(); - - foreach (OdeCharacter actor in _characters) - { - if (actor.bad) - m_log.ErrorFormat("[ODE SCENE]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); + nodeframes++; - actor.UpdatePositionAndVelocity(defects); + looptimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); + if (looptimeMS > maxLoopTime) + break; } - if (defects.Count != 0) + lock (_badCharacter) { - foreach (OdeCharacter actor in defects) + if (_badCharacter.Count > 0) { - m_log.ErrorFormat( - "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when updating position and velocity", - actor.Name, actor.LocalID, PhysicsSceneName); + foreach (OdeCharacter chr in _badCharacter) + { + RemoveCharacter(chr); + } - RemoveCharacter(actor); - actor.DestroyOdeStructures(); + _badCharacter.Clear(); } - - defects.Clear(); } - if (CollectStats) + timedif = now - m_lastMeshExpire; + + if (timedif.Seconds > 10) { - tempTick2 = Util.EnvironmentTickCount(); - m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); - tempTick = tempTick2; + mesher.ExpireReleaseMeshs(); + m_lastMeshExpire = now; } - //if (timeStep < 0.2f) +// information block for in debug breakpoint only +/* + int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); + int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); + int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace); + + int nactivegeoms = 0; + int nactivespaces = 0; + + int nstaticgeoms = 0; + int nstaticspaces = 0; + IntPtr sp; - foreach (OdePrim prim in _activeprims) + for (int i = 0; i < ntopactivegeoms; i++) { - if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag)) + sp = d.SpaceGetGeom(ActiveSpace, i); + if (d.GeomIsSpace(sp)) { - prim.UpdatePositionAndVelocity(); - - if (SupportsNINJAJoints) - SimulateActorPendingJoints(prim); + nactivespaces++; + nactivegeoms += d.SpaceGetNumGeoms(sp); } + else + nactivegeoms++; } - if (CollectStats) - m_stats[ODEPrimUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); + for (int i = 0; i < ntopstaticgeoms; i++) + { + sp = d.SpaceGetGeom(StaticSpace, i); + if (d.GeomIsSpace(sp)) + { + nstaticspaces++; + nstaticgeoms += d.SpaceGetNumGeoms(sp); + } + else + nstaticgeoms++; + } - //DumpJointInfo(); + int ntopgeoms = d.SpaceGetNumGeoms(TopSpace); + int totgeoms = nstaticgeoms + nactivegeoms + ngroundgeoms + 1; // one ray + int nbodies = d.NTotalBodies; + int ngeoms = d.NTotalGeoms; +*/ // Finished with all sim stepping. If requested, dump world state to file for debugging. // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? @@ -2956,291 +1900,303 @@ namespace OpenSim.Region.PhysicsModule.ODE d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } + + fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep; - latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun); - - // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics - // has a max of 100 ms to run theoretically. - // If the main loop stalls, it calls Simulate later which makes the tick count ms larger. - // If Physics stalls, it takes longer which makes the tick count ms larger. - - if (latertickcount < 100) - { + if(step_time < HalfOdeStep) m_timeDilation = 1.0f; + else if (step_time > m_SkipFramesAtms) + { + // if we lag too much skip frames + m_timeDilation = 0.0f; + step_time = 0; + m_lastframe = DateTime.UtcNow; // skip also the time lost } else { - m_timeDilation = 100f / latertickcount; - //m_timeDilation = Math.Min((Math.Max(100 - (Util.EnvironmentTickCount() - tickCountFrameRun), 1) / 100f), 1.0f); + m_timeDilation = ODE_STEPSIZE / step_time; + if (m_timeDilation > 1) + m_timeDilation = 1; } - - tickCountFrameRun = Util.EnvironmentTickCount(); - - if (CollectStats) - m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick); } - fps *= 1.0f/timeStep; return fps; } /// - /// Simulate pending NINJA joints. - /// - /// - /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else. - /// - private void SimulatePendingNINJAJoints() - { - // Create pending joints, if possible - - // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating - // a joint requires specifying the body id of both involved bodies - if (pendingJoints.Count > 0) - { - List successfullyProcessedPendingJoints = new List(); - //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); - foreach (PhysicsJoint joint in pendingJoints) - { - //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); - string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); - List jointBodies = new List(); - bool allJointBodiesAreReady = true; - foreach (string jointParam in jointParams) - { - if (jointParam == "NULL") - { - //DoJointErrorMessage(joint, "attaching NULL joint to world"); - jointBodies.Add(IntPtr.Zero); - } - else - { - //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); - bool foundPrim = false; - lock (_prims) - { - foreach (OdePrim prim in _prims) // FIXME: inefficient - { - if (prim.SOPName == jointParam) - { - //DoJointErrorMessage(joint, "found for prim name: " + jointParam); - if (prim.IsPhysical && prim.Body != IntPtr.Zero) - { - jointBodies.Add(prim.Body); - foundPrim = true; - break; - } - else - { - DoJointErrorMessage(joint, "prim name " + jointParam + - " exists but is not (yet) physical; deferring joint creation. " + - "IsPhysical property is " + prim.IsPhysical + - " and body is " + prim.Body); - foundPrim = false; - break; - } - } - } - } - if (foundPrim) - { - // all is fine - } - else - { - allJointBodiesAreReady = false; - break; - } - } - } + public override void GetResults() + { + } + + public override bool IsThreaded + { + // for now we won't be multithreaded + get { return (false); } + } + + public float GetTerrainHeightAtXY(float x, float y) + { + if (TerrainGeom == IntPtr.Zero) + return 0f; + + if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) + return 0f; + + // TerrainHeightField for ODE as offset 1m + x += 1f; + y += 1f; + + // make position fit into array + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + // integer indexs + int ix; + int iy; + // interpolators offset + float dx; + float dy; + + int regsizeX = (int)m_regionWidth + 3; // map size see setterrain number of samples + int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples + int regsize = regsizeX; + + if (m_OSOdeLib) + { + if (x < regsizeX - 1) + { + ix = (int)x; + dx = x - (float)ix; + } + else // out world use external height + { + ix = regsizeX - 2; + dx = 0; + } + if (y < regsizeY - 1) + { + iy = (int)y; + dy = y - (float)iy; + } + else + { + iy = regsizeY - 2; + dy = 0; + } + } + else + { + // we still have square fixed size regions + // also flip x and y because of how map is done for ODE fliped axis + // so ix,iy,dx and dy are inter exchanged + + regsize = regsizeY; + + if (x < regsizeX - 1) + { + iy = (int)x; + dy = x - (float)iy; + } + else // out world use external height + { + iy = regsizeX - 2; + dy = 0; + } + if (y < regsizeY - 1) + { + ix = (int)y; + dx = y - (float)ix; + } + else + { + ix = regsizeY - 2; + dx = 0; + } + } - if (allJointBodiesAreReady) - { - //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); - if (jointBodies[0] == jointBodies[1]) + float h0; + float h1; + float h2; + + iy *= regsize; + iy += ix; // all indexes have iy + ix + + float[] heights = TerrainHeightFieldHeight; + /* + if ((dx + dy) <= 1.0f) { - DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); + h0 = ((float)heights[iy]); // 0,0 vertice + h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 + h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 } else { - switch (joint.Type) - { - case PhysicsJointType.Ball: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating ball joint "); - odeJoint = d.JointCreateBall(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetBallAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - //DoJointErrorMessage(joint, "ODE joint setting OK"); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); - //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); - //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); - //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); - - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - case PhysicsJointType.Hinge: - { - IntPtr odeJoint; - //DoJointErrorMessage(joint, "ODE creating hinge joint "); - odeJoint = d.JointCreateHinge(world, IntPtr.Zero); - //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); - //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetHingeAnchor(odeJoint, - joint.Position.X, - joint.Position.Y, - joint.Position.Z); - // We use the orientation of the x-axis of the joint's coordinate frame - // as the axis for the hinge. - - // Therefore, we must get the joint's coordinate frame based on the - // joint.Rotation field, which originates from the orientation of the - // joint's proxy object in the scene. - - // The joint's coordinate frame is defined as the transformation matrix - // that converts a vector from joint-local coordinates into world coordinates. - // World coordinates are defined as the XYZ coordinate system of the sim, - // as shown in the top status-bar of the viewer. - - // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) - // and use that as the hinge axis. - - //joint.Rotation.Normalize(); - Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); - - // Now extract the X axis of the joint's coordinate frame. - - // Do not try to use proxyFrame.AtAxis or you will become mired in the - // tar pit of transposed, inverted, and generally messed-up orientations. - // (In other words, Matrix4.AtAxis() is borked.) - // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness - - // Instead, compute the X axis of the coordinate frame by transforming - // the (1,0,0) vector. At least that works. - - //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); - Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); - //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); - //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); - d.JointSetHingeAxis(odeJoint, - jointAxis.X, - jointAxis.Y, - jointAxis.Z); - //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); - if (joint is OdePhysicsJoint) - { - ((OdePhysicsJoint)joint).jointID = odeJoint; - } - else - { - DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); - } - } - break; - } - successfullyProcessedPendingJoints.Add(joint); + h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice + h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 + h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 } - } - else - { - DoJointErrorMessage(joint, "joint could not yet be created; still pending"); - } - } + */ + h0 = ((float)heights[iy]); // 0,0 vertice - foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) - { - //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); - //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); - InternalRemovePendingJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); - InternalAddActiveJoint(successfullyProcessedJoint); - //DoJointErrorMessage(successfullyProcessedJoint, "done"); - } + if (dy>dx) + { + iy += regsize; + h2 = (float)heights[iy]; // 0,1 vertice + h1 = (h2 - h0) * dy; // 0,1 vertice minus 0,0 + h2 = ((float)heights[iy + 1] - h2) * dx; // 1,1 vertice minus 0,1 } + else + { + iy++; + h2 = (float)heights[iy]; // vertice 1,0 + h1 = (h2 - h0) * dx; // 1,0 vertice minus 0,0 + h2 = (((float)heights[iy + regsize]) - h2) * dy; // 1,1 vertice minus 1,0 + } + + return h0 + h1 + h2; } - /// - /// Simulate the joint proxies of a NINJA actor. - /// - /// - /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there. - /// - /// - private void SimulateActorPendingJoints(OdePrim actor) + public Vector3 GetTerrainNormalAtXY(float x, float y) { - // If an actor moved, move its joint proxy objects as well. - // There seems to be an event PhysicsActor.OnPositionUpdate that could be used - // for this purpose but it is never called! So we just do the joint - // movement code here. + Vector3 norm = new Vector3(0, 0, 1); + + if (TerrainGeom == IntPtr.Zero) + return norm; + + if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) + return norm; - if (actor.SOPName != null && - joints_connecting_actor.ContainsKey(actor.SOPName) && - joints_connecting_actor[actor.SOPName] != null && - joints_connecting_actor[actor.SOPName].Count > 0) + // TerrainHeightField for ODE as offset 1m + x += 1f; + y += 1f; + + // make position fit into array + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + // integer indexs + int ix; + int iy; + // interpolators offset + float dx; + float dy; + + int regsizeX = (int)m_regionWidth + 3; // map size see setterrain number of samples + int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples + int regsize = regsizeX; + + int xstep = 1; + int ystep = regsizeX; + bool firstTri = false; + + if (m_OSOdeLib) { - foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) + if (x < regsizeX - 1) { - if (affectedJoint.IsInPhysicsEngine) - { - DoJointMoved(affectedJoint); - } - else - { - DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); - } + ix = (int)x; + dx = x - (float)ix; + } + else // out world use external height + { + ix = regsizeX - 2; + dx = 0; + } + if (y < regsizeY - 1) + { + iy = (int)y; + dy = y - (float)iy; + } + else + { + iy = regsizeY - 2; + dy = 0; } + firstTri = dy > dx; } - } - - public override void GetResults() - { - } - - public override bool IsThreaded - { - // for now we won't be multithreaded - get { return false; } - } - public override void SetTerrain(float[] heightMap) - { - if (m_worldOffset != Vector3.Zero && m_parentScene != null) + else { - if (m_parentScene is OdeScene) + xstep = regsizeY; + ystep = 1; + regsize = regsizeY; + + // we still have square fixed size regions + // also flip x and y because of how map is done for ODE fliped axis + // so ix,iy,dx and dy are inter exchanged + if (x < regsizeX - 1) { - ((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset); + iy = (int)x; + dy = x - (float)iy; } + else // out world use external height + { + iy = regsizeX - 2; + dy = 0; + } + if (y < regsizeY - 1) + { + ix = (int)y; + dx = y - (float)ix; + } + else + { + ix = regsizeY - 2; + dx = 0; + } + firstTri = dx > dy; + } + + float h0; + float h1; + float h2; + + iy *= regsize; + iy += ix; // all indexes have iy + ix + + float[] heights = TerrainHeightFieldHeight; + + if (firstTri) + { + h1 = ((float)heights[iy]); // 0,0 vertice + iy += ystep; + h0 = (float)heights[iy]; // 0,1 + h2 = (float)heights[iy+xstep]; // 1,1 vertice + norm.X = h0 - h2; + norm.Y = h1 - h0; } else { - SetTerrain(heightMap, m_worldOffset); + h2 = ((float)heights[iy]); // 0,0 vertice + iy += xstep; + h0 = ((float)heights[iy]); // 1,0 vertice + h1 = (float)heights[iy+ystep]; // vertice 1,1 + norm.X = h2 - h0; + norm.Y = h0 - h1; } + norm.Z = 1; + norm.Normalize(); + return norm; + } + + public override void SetTerrain(float[] heightMap) + { + if (m_OSOdeLib) + OSSetTerrain(heightMap); + else + OriSetTerrain(heightMap); } - private void SetTerrain(float[] heightMap, Vector3 pOffset) + public void OriSetTerrain(float[] heightMap) { - int startTime = Util.EnvironmentTickCount(); - m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0} with offset {1}", PhysicsSceneName, pOffset); + // assumes 1m size grid and constante size square regions + // needs to know about sims around in future - float[] _heightmap; - // ok im lasy this are just a aliases uint regionsizeX = m_regionWidth; uint regionsizeY = m_regionHeight; @@ -3258,7 +2214,7 @@ namespace OpenSim.Region.PhysicsModule.ODE const float thickness = 10f; const int wrap = 0; - + float hfmin = float.MaxValue; float hfmax = float.MinValue; float val; @@ -3267,13 +2223,11 @@ namespace OpenSim.Region.PhysicsModule.ODE uint maxXX = regionsizeX - 1; uint maxYY = regionsizeY - 1; - // flipping map adding one margin all around so things don't fall in edges uint xt = 0; xx = 0; - for (uint x = 0; x < heightmapWidthSamples; x++) { if (x > 1 && xx < maxXX) @@ -3286,7 +2240,7 @@ namespace OpenSim.Region.PhysicsModule.ODE val = heightMap[yy + xx]; if (val < 0.0f) - val = 0.0f; + val = 0.0f; // no neg terrain as in chode _heightmap[xt + y] = val; if (hfmin > val) @@ -3301,69 +2255,164 @@ namespace OpenSim.Region.PhysicsModule.ODE { d.AllocateODEDataForThread(~0U); - IntPtr GroundGeom = IntPtr.Zero; - if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) + if (TerrainGeom != IntPtr.Zero) { - RegionTerrain.Remove(pOffset); - if (GroundGeom != IntPtr.Zero) - { - if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) - { - TerrainHeightFieldHeights.Remove(GroundGeom); - } - d.SpaceRemove(space, GroundGeom); - d.GeomDestroy(GroundGeom); - } + actor_name_map.Remove(TerrainGeom); + d.GeomDestroy(TerrainGeom); } + + if (TerrainHeightFieldHeightsHandler.IsAllocated) + TerrainHeightFieldHeightsHandler.Free(); + IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); - d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, - heightmapWidth, heightmapHeight, - (int)heightmapWidthSamples, - (int)heightmapHeightSamples, - scale, offset, thickness, wrap); + + TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); + + d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, + heightmapHeight, heightmapWidth , + (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, + offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); - GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); - if (GroundGeom != IntPtr.Zero) + + TerrainGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1); + + if (TerrainGeom != IntPtr.Zero) { - d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); - d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); + d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); + d.GeomSetCollideBits(TerrainGeom, 0); + PhysicsActor pa = new NullPhysicsActor(); + pa.Name = "Terrain"; + pa.PhysicsActorType = (int)ActorTypes.Ground; + actor_name_map[TerrainGeom] = pa; + +// geom_name_map[GroundGeom] = "Terrain"; + + d.Quaternion q = new d.Quaternion(); + q.X = 0.5f; + q.Y = 0.5f; + q.Z = 0.5f; + q.W = 0.5f; + + d.GeomSetQuaternion(TerrainGeom, ref q); + d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); + TerrainHeightFieldHeight = _heightmap; } - geom_name_map[GroundGeom] = "Terrain"; + else + TerrainHeightFieldHeightsHandler.Free(); + } + } + + public void OSSetTerrain(float[] heightMap) + { + // assumes 1m size grid and constante size square regions + // needs to know about sims around in future - d.Matrix3 R = new d.Matrix3(); + float[] _heightmap; + + uint regionsizeX = m_regionWidth; + uint regionsizeY = m_regionHeight; + + uint heightmapWidth = regionsizeX + 2; + uint heightmapHeight = regionsizeY + 2; + + uint heightmapWidthSamples = heightmapWidth + 1; + uint heightmapHeightSamples = heightmapHeight + 1; - Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); - Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); + _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; + + + float hfmin = float.MaxValue; +// float hfmax = float.MinValue; + float val; + + + uint maxXX = regionsizeX - 1; + uint maxYY = regionsizeY - 1; + // adding one margin all around so things don't fall in edges - q1 = q1 * q2; - Vector3 v3; - float angle; - q1.GetAxisAngle(out v3, out angle); + uint xx; + uint yy = 0; + uint yt = 0; - d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); - d.GeomSetRotation(GroundGeom, ref R); - d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0.0f); - IntPtr testGround = IntPtr.Zero; - if (RegionTerrain.TryGetValue(pOffset, out testGround)) + for (uint y = 0; y < heightmapHeightSamples; y++) + { + if (y > 1 && y < maxYY) + yy += regionsizeX; + xx = 0; + for (uint x = 0; x < heightmapWidthSamples; x++) { - RegionTerrain.Remove(pOffset); + if (x > 1 && x < maxXX) + xx++; + + val = heightMap[yy + xx]; + if (val < 0.0f) + val = 0.0f; // no neg terrain as in chode + _heightmap[yt + x] = val; + + if (hfmin > val) + hfmin = val; +// if (hfmax < val) +// hfmax = val; } - RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); - TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); + yt += heightmapWidthSamples; } - m_log.DebugFormat( - "[ODE SCENE]: Setting terrain for {0} took {1}ms", PhysicsSceneName, Util.EnvironmentTickCountSubtract(startTime)); + lock (OdeLock) + { + if (TerrainGeom != IntPtr.Zero) + { + actor_name_map.Remove(TerrainGeom); + d.GeomDestroy(TerrainGeom); + } + + if (TerrainHeightFieldHeightsHandler.IsAllocated) + TerrainHeightFieldHeightsHandler.Free(); + + TerrainHeightFieldHeight = null; + + IntPtr HeightmapData = d.GeomOSTerrainDataCreate(); + + const int wrap = 0; + float thickness = hfmin; + if (thickness < 0) + thickness = 1; + + TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); + + d.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, + (int)heightmapWidthSamples, (int)heightmapHeightSamples, + thickness, wrap); + +// d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); + TerrainGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1); + if (TerrainGeom != IntPtr.Zero) + { + d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); + d.GeomSetCollideBits(TerrainGeom, 0); + + PhysicsActor pa = new NullPhysicsActor(); + pa.Name = "Terrain"; + pa.PhysicsActorType = (int)ActorTypes.Ground; + actor_name_map[TerrainGeom] = pa; + +// geom_name_map[GroundGeom] = "Terrain"; + + d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); + TerrainHeightFieldHeight = _heightmap; + } + else + TerrainHeightFieldHeightsHandler.Free(); + } } public override void DeleteTerrain() { } - internal float GetWaterLevel() + public float GetWaterLevel() { return waterlevel; } @@ -3373,19 +2422,19 @@ namespace OpenSim.Region.PhysicsModule.ODE waterlevel = baseheight; } - [HandleProcessCorruptedStateExceptions] public override void Dispose() { - lock(SimulationLock) - lock(OdeLock) + lock (OdeLock) { - if(world == IntPtr.Zero) - return; - _worldInitialized = false; + if (world == IntPtr.Zero) + return; d.AllocateODEDataForThread(~0U); + if (m_meshWorker != null) + m_meshWorker.Stop(); + if (m_rayCastManager != null) { m_rayCastManager.Dispose(); @@ -3394,37 +2443,49 @@ namespace OpenSim.Region.PhysicsModule.ODE lock (_prims) { - foreach (OdePrim prm in _prims) + ChangesQueue.Clear(); + foreach (OdePrim prm in _prims.Values) { - RemovePrim(prm); + prm.DoAChange(changes.Remove, null); + _collisionEventPrim.Remove(prm); } + _prims.Clear(); } - //foreach (OdeCharacter act in _characters) - //{ - //RemoveAvatar(act); - //} - IntPtr GroundGeom = IntPtr.Zero; - if (RegionTerrain.TryGetValue(m_worldOffset, out GroundGeom)) + OdeCharacter[] chtorem; + lock (_characters) { - RegionTerrain.Remove(m_worldOffset); - if (GroundGeom != IntPtr.Zero) - { - if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) - TerrainHeightFieldHeights.Remove(GroundGeom); - d.GeomDestroy(GroundGeom); - } - } + chtorem = new OdeCharacter[_characters.Count]; + _characters.CopyTo(chtorem); + } - try + ChangesQueue.Clear(); + foreach (OdeCharacter ch in chtorem) + ch.DoAChange(changes.Remove, null); + + if (TerrainGeom != IntPtr.Zero) + d.GeomDestroy(TerrainGeom); + TerrainGeom = IntPtr.Zero; + + if (TerrainHeightFieldHeightsHandler.IsAllocated) + TerrainHeightFieldHeightsHandler.Free(); + + TerrainHeightFieldHeight = null; + + if (ContactgeomsArray != IntPtr.Zero) { - d.WorldDestroy(world); - world = IntPtr.Zero; + Marshal.FreeHGlobal(ContactgeomsArray); + ContactgeomsArray = IntPtr.Zero; } - catch (AccessViolationException e) + if (GlobalContactsArray != IntPtr.Zero) { - m_log.ErrorFormat("[ODE SCENE]: exception {0}", e.Message); + Marshal.FreeHGlobal(GlobalContactsArray); + GlobalContactsArray = IntPtr.Zero; } + + d.WorldDestroy(world); + world = IntPtr.Zero; + //d.CloseODE(); } } @@ -3436,17 +2497,13 @@ namespace OpenSim.Region.PhysicsModule.ODE public override Dictionary GetTopColliders() { Dictionary topColliders; + List orderedPrims; + lock (_activeprims) + orderedPrims = new List(_activeprims); - lock (_prims) - { - List orderedPrims = new List(_prims); - orderedPrims.Sort(compareByCollisionsDesc); - topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); - - foreach (OdePrim p in _prims) - p.CollisionScore = 0; - } - + orderedPrims.Sort(compareByCollisionsDesc); + topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); + return topColliders; } @@ -3459,7 +2516,16 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (retMethod != null) { - m_rayCastManager.QueueRequest(position, direction, length, retMethod); + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = 0; + req.filter = RayFilterFlags.AllPrims; + + m_rayCastManager.QueueRequest(req); } } @@ -3467,75 +2533,260 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (retMethod != null) { - m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = RayFilterFlags.AllPrims; + + m_rayCastManager.QueueRequest(req); } } + public override List RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) { - ContactResult[] ourResults = null; + List ourresults = new List(); + object SyncObject = new object(); + + RayCallback retMethod = delegate(List results) + { + lock (SyncObject) + { + ourresults = results; + Monitor.PulseAll(SyncObject); + } + }; + + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = RayFilterFlags.AllPrims; + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return null; + else + return ourresults; + } + } + + public override bool SupportsRaycastWorldFiltered() + { + return true; + } + + public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) + { + object SyncObject = new object(); + List ourresults = new List(); + + RayCallback retMethod = delegate(List results) + { + lock (SyncObject) + { + ourresults = results; + Monitor.PulseAll(SyncObject); + } + }; + + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = filter; + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return null; + else + return ourresults; + } + } + + public override List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) + { + if (actor == null) + return new List(); + + IntPtr geom; + if (actor is OdePrim) + geom = ((OdePrim)actor).prim_geom; + else if (actor is OdeCharacter) + geom = ((OdePrim)actor).prim_geom; + else + return new List(); + + if (geom == IntPtr.Zero) + return new List(); + + List ourResults = null; + object SyncObject = new object(); + RayCallback retMethod = delegate(List results) { - ourResults = new ContactResult[results.Count]; - results.CopyTo(ourResults, 0); + lock (SyncObject) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + } + }; + + ODERayRequest req = new ODERayRequest(); + req.actor = actor; + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + req.Count = Count; + req.filter = flags; + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); + } + + if (ourResults == null) + return new List(); + return ourResults; + } + + public override List BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags) + { + List ourResults = null; + object SyncObject = new object(); + + ProbeBoxCallback retMethod = delegate(List results) + { + lock (SyncObject) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + } }; - int waitTime = 0; - m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); - while (ourResults == null && waitTime < 1000) + + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.Normal = size; + req.Origin = position; + req.orientation = orientation; + req.Count = Count; + req.filter = flags; + + lock (SyncObject) { - Thread.Sleep(1); - waitTime++; + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); } + if (ourResults == null) - return new List (); - return new List(ourResults); + return new List(); + return ourResults; } - public override Dictionary GetStats() + public override List SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags) { - if (!CollectStats) - return null; + List ourResults = null; + object SyncObject = new object(); + + ProbeSphereCallback retMethod = delegate(List results) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + }; - Dictionary returnStats; + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.length = radius; + req.Origin = position; + req.Count = Count; + req.filter = flags; - lock (OdeLock) + + lock (SyncObject) { - returnStats = new Dictionary(m_stats); + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); + } + + if (ourResults == null) + return new List(); + return ourResults; + } - // FIXME: This is a SUPER DUMB HACK until we can establish stats that aren't subject to a division by - // 3 from the SimStatsReporter. - returnStats[ODETotalAvatarsStatName] = _characters.Count * 3; - returnStats[ODETotalPrimsStatName] = _prims.Count * 3; - returnStats[ODEActivePrimsStatName] = _activeprims.Count * 3; + public override List PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags) + { + IntPtr geom = IntPtr.Zero;; - InitializeExtraStats(); + if (actor != null) + { + if (actor is OdePrim) + geom = ((OdePrim)actor).prim_geom; + else if (actor is OdeCharacter) + geom = ((OdePrim)actor).prim_geom; } - returnStats[ODEOtherCollisionFrameMsStatName] - = returnStats[ODEOtherCollisionFrameMsStatName] - - returnStats[ODENativeSpaceCollisionFrameMsStatName] - - returnStats[ODENativeGeomCollisionFrameMsStatName]; + List ourResults = null; + object SyncObject = new object(); + + ProbePlaneCallback retMethod = delegate(List results) + { + ourResults = results; + Monitor.PulseAll(SyncObject); + }; + + ODERayRequest req = new ODERayRequest(); + req.actor = null; + req.callbackMethod = retMethod; + req.length = plane.W; + req.Normal.X = plane.X; + req.Normal.Y = plane.Y; + req.Normal.Z = plane.Z; + req.Count = Count; + req.filter = flags; + + lock (SyncObject) + { + m_rayCastManager.QueueRequest(req); + if (!Monitor.Wait(SyncObject, 500)) + return new List(); + } - return returnStats; + if (ourResults == null) + return new List(); + return ourResults; } - private void InitializeExtraStats() + public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) { - m_stats[ODETotalFrameMsStatName] = 0; - m_stats[ODEAvatarTaintMsStatName] = 0; - m_stats[ODEPrimTaintMsStatName] = 0; - m_stats[ODEAvatarForcesFrameMsStatName] = 0; - m_stats[ODEPrimForcesFrameMsStatName] = 0; - m_stats[ODERaycastingFrameMsStatName] = 0; - m_stats[ODENativeStepFrameMsStatName] = 0; - m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; - m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; - m_stats[ODEOtherCollisionFrameMsStatName] = 0; - m_stats[ODECollisionNotificationFrameMsStatName] = 0; - m_stats[ODEAvatarContactsStatsName] = 0; - m_stats[ODEPrimContactsStatName] = 0; - m_stats[ODEAvatarUpdateFrameMsStatName] = 0; - m_stats[ODEPrimUpdateFrameMsStatName] = 0; + Util.FireAndForget( delegate + { + ODESitAvatar sitAvatar = new ODESitAvatar(this, m_rayCastManager); + if(sitAvatar != null) + sitAvatar.Sit(actor, AbsolutePosition, CameraPosition, offset, AvatarSize, PhysicsSitResponse); + }); + return 1; } + } } -- cgit v1.1 From 1507c5230bdac908ebba267ed7e8169e4ee8ab74 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 30 Dec 2016 05:13:53 +0000 Subject: remove a gc.collect that isn't very usefull (on the right engine this time) --- OpenSim/Region/PhysicsModules/Ode/OdeScene.cs | 4497 +++++++++++++---------- OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | 2 - 2 files changed, 2623 insertions(+), 1876 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs index 410463c..ed2aad4 100644 --- a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs +++ b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs @@ -25,54 +25,52 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// Revision 2011/12/13 by Ubit Umarov -//#define SPAM +// changes for varsize regions +// note that raycasts need to have limited range +// (even in normal regions) +// or application thread stack may just blowup +// see RayCast(ODERayCastRequest req) using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Threading; -using System.IO; -using System.Diagnostics; using log4net; using Nini.Config; using Mono.Addins; -using OdeAPI; +using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.PhysicsModules.SharedBase; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.PhysicsModules.SharedBase; -using OpenMetaverse; -namespace OpenSim.Region.PhysicsModule.ubOde +namespace OpenSim.Region.PhysicsModule.ODE { - // colision flags of things others can colide with - // rays, sensors, probes removed since can't be colided with - // The top space where things are placed provided further selection - // ie physical are in active space nonphysical in static - // this should be exclusive as possible + public enum StatusIndicators : int + { + Generic = 0, + Start = 1, + End = 2 + } [Flags] - public enum CollisionCategories : uint + public enum CollisionCategories : int { Disabled = 0, - //by 'things' types - Space = 0x01, - Geom = 0x02, // aka prim/part - Character = 0x04, - Land = 0x08, - Water = 0x010, - - // by state - Phantom = 0x01000, - VolumeDtc = 0x02000, - Selected = 0x04000, - NoShape = 0x08000, - - - All = 0xffffffff + Geom = 0x00000001, + Body = 0x00000002, + Space = 0x00000004, + Character = 0x00000008, + Land = 0x00000010, + Water = 0x00000020, + Wind = 0x00000040, + Sensor = 0x00000080, + Selected = 0x00000100 } /// @@ -93,631 +91,908 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// Plastic = 5, /// - Rubber = 6, - - light = 7 // compatibility with old viewers - } - - public enum changes : int - { - Add = 0, // arg null. finishs the prim creation. should be used internally only ( to remove later ?) - Remove, - Link, // arg AuroraODEPrim new parent prim or null to delink. Makes the prim part of a object with prim parent as root - // or removes from a object if arg is null - DeLink, - Position, // arg Vector3 new position in world coords. Changes prim position. Prim must know if it is root or child - Orientation, // arg Quaternion new orientation in world coords. Changes prim position. Prim must know it it is root or child - PosOffset, // not in use - // arg Vector3 new position in local coords. Changes prim position in object - OriOffset, // not in use - // arg Vector3 new position in local coords. Changes prim position in object - Velocity, - TargetVelocity, - AngVelocity, - Acceleration, - Force, - Torque, - Momentum, - - AddForce, - AddAngForce, - AngLock, - - Buoyancy, - - PIDTarget, - PIDTau, - PIDActive, - - PIDHoverHeight, - PIDHoverType, - PIDHoverTau, - PIDHoverActive, - - Size, - AvatarSize, - Shape, - PhysRepData, - AddPhysRep, - - CollidesWater, - VolumeDtc, - - Physical, - Phantom, - Selected, - disabled, - building, - - VehicleType, - VehicleFloatParam, - VehicleVectorParam, - VehicleRotationParam, - VehicleFlags, - SetVehicle, - - Null //keep this last used do dim the methods array. does nothing but pulsing the prim + Rubber = 6 } - public struct ODEchangeitem + public class OdeScene : PhysicsScene { - public PhysicsActor actor; - public OdeCharacter character; - public changes what; - public Object arg; - } + private readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString()); - public class ODEScene : PhysicsScene - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + // private Dictionary m_storedCollisions = new Dictionary(); + + /// + /// Provide a sync object so that only one thread calls d.Collide() at a time across all OdeScene instances. + /// + /// + /// With ODE as of r1755 (though also tested on r1860), only one thread can call d.Collide() at a + /// time, even where physics objects are in entirely different ODE worlds. This is because generating contacts + /// uses a static cache at the ODE level. + /// + /// Without locking, simulators running multiple regions will eventually crash with a native stack trace similar + /// to + /// + /// mono() [0x489171] + /// mono() [0x4d154f] + /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f6ded592c60] + /// .../opensim/bin/libode-x86_64.so(_ZN6Opcode11OBBCollider8_CollideEPKNS_14AABBNoLeafNodeE+0xd7a) [0x7f6dd822628a] + /// + /// ODE provides an experimental option to cache in thread local storage but compiling ODE with this option + /// causes OpenSimulator to immediately crash with a native stack trace similar to + /// + /// mono() [0x489171] + /// mono() [0x4d154f] + /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f03c9849c60] + /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82] + /// + internal static Object UniversalColliderSyncObject = new Object(); + internal static Object SimulationLock = new Object(); + + /// + /// Is stats collecting enabled for this ODE scene? + /// + public bool CollectStats { get; set; } - public bool m_OSOdeLib = false; - public Scene m_frameWorkScene = null; + /// + /// Statistics for this scene. + /// + private Dictionary m_stats = new Dictionary(); -// private int threadid = 0; + /// + /// Stat name for total number of avatars in this ODE scene. + /// + public const string ODETotalAvatarsStatName = "ODETotalAvatars"; -// const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; + /// + /// Stat name for total number of prims in this ODE scene. + /// + public const string ODETotalPrimsStatName = "ODETotalPrims"; - const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; - const float comumContactERP = 0.75f; - const float comumContactCFM = 0.0001f; - const float comumContactSLIP = 0f; - - float frictionMovementMult = 0.8f; + /// + /// Stat name for total number of prims with active physics in this ODE scene. + /// + public const string ODEActivePrimsStatName = "ODEActivePrims"; + + /// + /// Stat name for the total time spent in ODE frame processing. + /// + /// + /// A sanity check for the main scene loop physics time. + /// + public const string ODETotalFrameMsStatName = "ODETotalFrameMS"; + + /// + /// Stat name for time spent processing avatar taints per frame + /// + public const string ODEAvatarTaintMsStatName = "ODEAvatarTaintFrameMS"; + + /// + /// Stat name for time spent processing prim taints per frame + /// + public const string ODEPrimTaintMsStatName = "ODEPrimTaintFrameMS"; + + /// + /// Stat name for time spent calculating avatar forces per frame. + /// + public const string ODEAvatarForcesFrameMsStatName = "ODEAvatarForcesFrameMS"; + + /// + /// Stat name for time spent calculating prim forces per frame + /// + public const string ODEPrimForcesFrameMsStatName = "ODEPrimForcesFrameMS"; + + /// + /// Stat name for time spent fulfilling raycasting requests per frame + /// + public const string ODERaycastingFrameMsStatName = "ODERaycastingFrameMS"; + + /// + /// Stat name for time spent in native code that actually steps through the simulation. + /// + public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS"; + + /// + /// Stat name for the number of milliseconds that ODE spends in native space collision code. + /// + public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS"; + + /// + /// Stat name for milliseconds that ODE spends in native geom collision code. + /// + public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS"; + + /// + /// Time spent in collision processing that is not spent in native space or geom collision code. + /// + public const string ODEOtherCollisionFrameMsStatName = "ODEOtherCollisionFrameMS"; + + /// + /// Stat name for time spent notifying listeners of collisions + /// + public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS"; + + /// + /// Stat name for milliseconds spent updating avatar position and velocity + /// + public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS"; + + /// + /// Stat name for the milliseconds spent updating prim position and velocity + /// + public const string ODEPrimUpdateFrameMsStatName = "ODEPrimUpdateFrameMS"; + + /// + /// Stat name for avatar collisions with another entity. + /// + public const string ODEAvatarContactsStatsName = "ODEAvatarContacts"; + + /// + /// Stat name for prim collisions with another entity. + /// + public const string ODEPrimContactsStatName = "ODEPrimContacts"; + + /// + /// Used to hold tick numbers for stat collection purposes. + /// + private int m_nativeCollisionStartTick; + + /// + /// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback. + /// + private bool m_inCollisionTiming; + + /// + /// A temporary holder for the number of avatar collisions in a frame, so we can work out how many object + /// collisions occured using the _perloopcontact if stats collection is enabled. + /// + private int m_tempAvatarCollisionsThisFrame; + + /// + /// Used in calculating physics frame time dilation + /// + private int tickCountFrameRun; - float TerrainBounce = 0.1f; - float TerrainFriction = 0.3f; + /// + /// Used in calculating physics frame time dilation + /// + private int latertickcount; - public float AvatarFriction = 0;// 0.9f * 0.5f; + private Random fluidRandomizer = new Random(Environment.TickCount); - // this netx dimensions are only relevant for terrain partition (mega regions) - // WorldExtents below has the simulation dimensions - // they should be identical except on mega regions private uint m_regionWidth = Constants.RegionSize; private uint m_regionHeight = Constants.RegionSize; - public float ODE_STEPSIZE = 0.020f; - public float HalfOdeStep = 0.01f; - public int odetimestepMS = 20; // rounded - private float metersInSpace = 25.6f; + private float ODE_STEPSIZE = 0.0178f; + private float metersInSpace = 29.9f; private float m_timeDilation = 1.0f; - private DateTime m_lastframe; - private DateTime m_lastMeshExpire; - public float gravityx = 0f; public float gravityy = 0f; public float gravityz = -9.8f; + public float AvatarTerminalVelocity { get; set; } + + private float contactsurfacelayer = 0.001f; + + private int HashspaceLow = -5; + private int HashspaceHigh = 12; + private float waterlevel = 0f; private int framecount = 0; + //private int m_returncollisions = 10; + + private IntPtr contactgroup; + +// internal IntPtr WaterGeom; + + private float nmTerrainContactFriction = 255.0f; + private float nmTerrainContactBounce = 0.1f; + private float nmTerrainContactERP = 0.1025f; + + private float mTerrainContactFriction = 75f; + private float mTerrainContactBounce = 0.1f; + private float mTerrainContactERP = 0.05025f; + + private float nmAvatarObjectContactFriction = 250f; + private float nmAvatarObjectContactBounce = 0.1f; + + private float mAvatarObjectContactFriction = 75f; + private float mAvatarObjectContactBounce = 0.1f; + + private float avPIDD = 3200f; + private float avPIDP = 1400f; + private float avCapRadius = 0.37f; + private float avStandupTensor = 2000000f; + + /// + /// true = old compatibility mode with leaning capsule; false = new corrected mode + /// + /// + /// Even when set to false, the capsule still tilts but this is done in a different way. + /// + public bool IsAvCapsuleTilted { get; private set; } private float avDensity = 80f; private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorRun = 0.8f; private float minimumGroundFlightOffset = 3f; public float maximumMassObject = 10000.01f; - public float geomDefaultDensity = 10.0f; - public float maximumAngularVelocity = 12.0f; // default 12rad/s - public float maxAngVelocitySQ = 144f; // squared value + public bool meshSculptedPrim = true; + public bool forceSimplePrimMeshing = false; + + public float meshSculptLOD = 32; + public float MeshSculptphysicalLOD = 16; + + public float geomDefaultDensity = 10.000006836f; + + public int geomContactPointsStartthrottle = 3; + public int geomUpdatesPerThrottledUpdate = 15; + private const int avatarExpectedContacts = 3; public float bodyPIDD = 35f; public float bodyPIDG = 25; - public int bodyFramesAutoDisable = 5; + public int bodyFramesAutoDisable = 20; + + private bool m_filterCollisions = true; private d.NearCallback nearCallback; + public d.TriCallback triCallback; + public d.TriArrayCallback triArrayCallback; + + /// + /// Avatars in the physics scene. + /// + private readonly HashSet _characters = new HashSet(); - private Dictionary _prims = new Dictionary(); - private HashSet _characters = new HashSet(); - private HashSet _activeprims = new HashSet(); - private HashSet _activegroups = new HashSet(); + /// + /// Prims in the physics scene. + /// + private readonly HashSet _prims = new HashSet(); - public OpenSim.Framework.LocklessQueue ChangesQueue = new OpenSim.Framework.LocklessQueue(); + /// + /// Prims in the physics scene that are subject to physics, not just collisions. + /// + private readonly HashSet _activeprims = new HashSet(); /// - /// A list of actors that should receive collision events. + /// Prims that the simulator has created/deleted/updated and so need updating in ODE. /// - private List _collisionEventPrim = new List(); - private List _collisionEventPrimRemove = new List(); - - private HashSet _badCharacter = new HashSet(); + private readonly HashSet _taintedPrims = new HashSet(); + + /// + /// Record a character that has taints to be processed. + /// + private readonly HashSet _taintedActors = new HashSet(); + + /// + /// Keep record of contacts in the physics loop so that we can remove duplicates. + /// + private readonly List _perloopContact = new List(); + + /// + /// A dictionary of actors that should receive collision events. + /// + private readonly Dictionary m_collisionEventActors = new Dictionary(); + + /// + /// A dictionary of collision event changes that are waiting to be processed. + /// + private readonly Dictionary m_collisionEventActorsChanges = new Dictionary(); + + /// + /// Maps a unique geometry id (a memory location) to a physics actor name. + /// + /// + /// Only actors participating in collisions have geometries. This has to be maintained separately from + /// actor_name_map because terrain and water currently don't conceptually have a physics actor of their own + /// apart from the singleton PANull + /// + public Dictionary geom_name_map = new Dictionary(); + + /// + /// Maps a unique geometry id (a memory location) to a physics actor. + /// + /// + /// Only actors participating in collisions have geometries. + /// public Dictionary actor_name_map = new Dictionary(); - private float contactsurfacelayer = 0.002f; + /// + /// Defects list to remove characters that no longer have finite positions due to some other bug. + /// + /// + /// Used repeatedly in Simulate() but initialized once here. + /// + private readonly List defects = new List(); - private int contactsPerCollision = 80; - internal IntPtr ContactgeomsArray = IntPtr.Zero; - private IntPtr GlobalContactsArray = IntPtr.Zero; - private d.Contact SharedTmpcontact = new d.Contact(); + private bool m_NINJA_physics_joints_enabled = false; + //private Dictionary jointpart_name_map = new Dictionary(); + private readonly Dictionary> joints_connecting_actor = new Dictionary>(); + private d.ContactGeom[] contacts; - const int maxContactsbeforedeath = 6000; - private volatile int m_global_contactcount = 0; + /// + /// Lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active + /// + private readonly List requestedJointsToBeCreated = new List(); - private IntPtr contactgroup; + /// + /// can lock for longer. accessed only by OdeScene. + /// + private readonly List pendingJoints = new List(); - public ContactData[] m_materialContactsData = new ContactData[8]; + /// + /// can lock for longer. accessed only by OdeScene. + /// + private readonly List activeJoints = new List(); - private IntPtr TerrainGeom; - private float[] TerrainHeightFieldHeight; - private GCHandle TerrainHeightFieldHeightsHandler = new GCHandle(); - - private int m_physicsiterations = 15; + /// + /// lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active + /// + private readonly List requestedJointsToBeDeleted = new List(); + + private Object externalJointRequestsLock = new Object(); + private readonly Dictionary SOPName_to_activeJoint = new Dictionary(); + private readonly Dictionary SOPName_to_pendingJoint = new Dictionary(); + private readonly DoubleDictionary RegionTerrain = new DoubleDictionary(); + private readonly Dictionary TerrainHeightFieldHeights = new Dictionary(); + + private d.Contact contact; + private d.Contact TerrainContact; + private d.Contact AvatarMovementprimContact; + private d.Contact AvatarMovementTerrainContact; + private d.Contact WaterContact; + private d.Contact[,] m_materialContacts; + + private int m_physicsiterations = 10; private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag -// private PhysicsActor PANull = new NullPhysicsActor(); + private readonly PhysicsActor PANull = new NullPhysicsActor(); private float step_time = 0.0f; - public IntPtr world; + private uint obj2LocalID = 0; + private OdeCharacter cc1; + private OdePrim cp1; + private OdeCharacter cc2; + private OdePrim cp2; + private int p1ExpectedPoints = 0; + private int p2ExpectedPoints = 0; - // split the spaces acording to contents type - // ActiveSpace contains characters and active prims - // StaticSpace contains land and other that is mostly static in enviroment - // this can contain subspaces, like the grid in staticspace - // as now space only contains this 2 top spaces + public IntPtr space; - public IntPtr TopSpace; // the global space - public IntPtr ActiveSpace; // space for active prims - public IntPtr CharsSpace; // space for active prims - public IntPtr StaticSpace; // space for the static things around - public IntPtr GroundSpace; // space for ground + // split static geometry collision handling into spaces of 30 meters + public IntPtr[,] staticPrimspace; - // some speedup variables - private int spaceGridMaxX; - private int spaceGridMaxY; - private float spacesPerMeterX; - private float spacesPerMeterY; - - // split static geometry collision into a grid as before - private IntPtr[,] staticPrimspace; - private IntPtr[] staticPrimspaceOffRegion; + /// + /// Used to lock the entire physics scene. Locked during the main part of Simulate() + /// + internal Object OdeLock = new Object(); - public Object OdeLock; - public static Object SimulationLock; + private bool _worldInitialized = false; public IMesher mesher; - public IConfigSource m_config; + private IConfigSource m_config; public bool physics_logging = false; public int physics_logging_interval = 0; public bool physics_logging_append_existing_logfile = false; - public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); + private bool avplanted = false; + private bool av_av_collisions_off = false; - private ODERayCastRequestManager m_rayCastManager; - public ODEMeshWorker m_meshWorker; + public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); + public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); - /* maybe needed if ode uses tls - private void checkThread() - { + private volatile int m_global_contactcount = 0; - int th = Thread.CurrentThread.ManagedThreadId; - if(th != threadid) - { - threadid = th; - d.AllocateODEDataForThread(~0U); - } - } - */ + private Vector3 m_worldOffset = Vector3.Zero; + public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); + private PhysicsScene m_parentScene = null; - IConfig physicsconfig = null; + float spacesPerMeterX; + float spacesPerMeterY; + int spaceGridMaxX; + int spaceGridMaxY; - public ODEScene(Scene pscene, IConfigSource psourceconfig, string pname, string pversion, bool pOSOdeLib) - { - OdeLock = new Object(); + private ODERayCastRequestManager m_rayCastManager; + + public Scene m_frameWorkScene = null; + public OdeScene(Scene pscene, IConfigSource psourceconfig, string pname, string pversion) + { + m_config = psourceconfig; + m_frameWorkScene = pscene; + EngineType = pname; PhysicsSceneName = EngineType + "/" + pscene.RegionInfo.RegionName; EngineName = pname + " " + pversion; - m_config = psourceconfig; - m_OSOdeLib = pOSOdeLib; - -// m_OSOdeLib = false; //debug - m_frameWorkScene = pscene; + pscene.RegisterModuleInterface(this); + Vector3 extent = new Vector3(pscene.RegionInfo.RegionSizeX, pscene.RegionInfo.RegionSizeY, pscene.RegionInfo.RegionSizeZ); + Initialise(extent); + InitialiseFromConfig(m_config); - m_frameWorkScene.RegisterModuleInterface(this); + // This may not be that good since terrain may not be avaiable at this point + base.Initialise(pscene.PhysicsRequestAsset, + (pscene.Heightmap != null ? pscene.Heightmap.GetFloatsSerialised() : new float[(int)(extent.X * extent.Y)]), + (float)pscene.RegionInfo.RegionSettings.WaterHeight); - Initialization(); - - base.Initialise(m_frameWorkScene.PhysicsRequestAsset, - (m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]), - (float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight); } - public void RegionLoaded() + public void RegionLoaded() { mesher = m_frameWorkScene.RequestModuleInterface(); if (mesher == null) - { - m_log.ErrorFormat("[ubOde] No mesher. module disabled"); - return; - } - - m_meshWorker = new ODEMeshWorker(this, m_log, mesher, physicsconfig); - m_frameWorkScene.PhysicsEnabled = true; + m_log.WarnFormat("[ODE SCENE]: No mesher in {0}. Things will not work well.", PhysicsSceneName); + + m_frameWorkScene.PhysicsEnabled = true; } + /// /// Initiailizes the scene /// Sets many properties that ODE requires to be stable /// These settings need to be tweaked 'exactly' right or weird stuff happens. /// - private void Initialization() + private void Initialise(Vector3 regionExtent) { - d.AllocateODEDataForThread(~0U); - - SimulationLock = new Object(); - + WorldExtents.X = regionExtent.X; + m_regionWidth = (uint)regionExtent.X; + WorldExtents.Y = regionExtent.Y; + m_regionHeight = (uint)regionExtent.Y; + nearCallback = near; - m_rayCastManager = new ODERayCastRequestManager(this); - WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX; - m_regionWidth = (uint)WorldExtents.X; - WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY; - m_regionHeight = (uint)WorldExtents.Y; - - lock (OdeLock) - { - // Create the world and the first space - try - { - world = d.WorldCreate(); - TopSpace = d.HashSpaceCreate(IntPtr.Zero); - - // now the major subspaces - ActiveSpace = d.HashSpaceCreate(TopSpace); - CharsSpace = d.HashSpaceCreate(TopSpace); - StaticSpace = d.HashSpaceCreate(TopSpace); - GroundSpace = d.HashSpaceCreate(TopSpace); - } - catch - { - // i must RtC#FM - // i did! - } - - d.HashSpaceSetLevels(TopSpace, -5, 12); - d.HashSpaceSetLevels(ActiveSpace, -5, 10); - d.HashSpaceSetLevels(CharsSpace, -4, 3); - d.HashSpaceSetLevels(StaticSpace, -5, 12); - d.HashSpaceSetLevels(GroundSpace, 0, 8); - - // demote to second level - d.SpaceSetSublevel(ActiveSpace, 1); - d.SpaceSetSublevel(CharsSpace, 1); - d.SpaceSetSublevel(StaticSpace, 1); - d.SpaceSetSublevel(GroundSpace, 1); - - d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Character | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Character | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Character | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(CharsSpace, 0); - - d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - // CollisionCategories.Land | - // CollisionCategories.Water | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(StaticSpace, 0); - - d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); - d.GeomSetCollideBits(GroundSpace, 0); - - contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1); - //contactgroup - - d.WorldSetAutoDisableFlag(world, false); - } + // Create the world and the first space + world = d.WorldCreate(); + space = d.HashSpaceCreate(IntPtr.Zero); + contactgroup = d.JointGroupCreate(0); - // checkThread(); + d.WorldSetAutoDisableFlag(world, false); + } + // Initialize from configs + private void InitialiseFromConfig(IConfigSource config) + { + InitializeExtraStats(); + m_config = config; // Defaults - int contactsPerCollision = 80; + avPIDD = 2200.0f; + avPIDP = 900.0f; + avStandupTensor = 550000f; - physicsconfig = null; + int contactsPerCollision = 80; if (m_config != null) { - physicsconfig = m_config.Configs["ODEPhysicsSettings"]; + IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; if (physicsconfig != null) { - gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); - gravityy = physicsconfig.GetFloat("world_gravityy", gravityy); - gravityz = physicsconfig.GetFloat("world_gravityz", gravityz); - - metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); - - // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); - - ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); - - avDensity = physicsconfig.GetFloat("av_density", avDensity); - avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); - avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun); - - contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); - - geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); - bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); - - physics_logging = physicsconfig.GetBoolean("physics_logging", false); - physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); - physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); - - minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset); - maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject); + CollectStats = physicsconfig.GetBoolean("collect_stats", false); - avDensity *= 3f / 80f; // scale other engines density option to this - } - } + gravityx = physicsconfig.GetFloat("world_gravityx", 0f); + gravityy = physicsconfig.GetFloat("world_gravityy", 0f); + gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); - float heartbeat = 1/m_frameWorkScene.FrameTime; - maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI; - maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity; + float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 54f); + AvatarTerminalVelocity = Util.Clamp(avatarTerminalVelocity, 0, 255f); + if (AvatarTerminalVelocity != avatarTerminalVelocity) + { + m_log.WarnFormat( + "[ODE SCENE]: avatar_terminal_velocity of {0} is invalid. Clamping to {1}", + avatarTerminalVelocity, AvatarTerminalVelocity); + } - d.WorldSetCFM(world, comumContactCFM); - d.WorldSetERP(world, comumContactERP); + HashspaceLow = physicsconfig.GetInt("world_hashspace_level_low", -5); + HashspaceHigh = physicsconfig.GetInt("world_hashspace_level_high", 12); - d.WorldSetGravity(world, gravityx, gravityy, gravityz); + metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f); - d.WorldSetLinearDamping(world, 0.002f); - d.WorldSetAngularDamping(world, 0.002f); - d.WorldSetAngularDampingThreshold(world, 0f); - d.WorldSetLinearDampingThreshold(world, 0f); - d.WorldSetMaxAngularSpeed(world, maximumAngularVelocity); + contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", 0.001f); - d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + nmTerrainContactFriction = physicsconfig.GetFloat("nm_terraincontact_friction", 255.0f); + nmTerrainContactBounce = physicsconfig.GetFloat("nm_terraincontact_bounce", 0.1f); + nmTerrainContactERP = physicsconfig.GetFloat("nm_terraincontact_erp", 0.1025f); - d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); - d.WorldSetContactMaxCorrectingVel(world, 60.0f); + mTerrainContactFriction = physicsconfig.GetFloat("m_terraincontact_friction", 75f); + mTerrainContactBounce = physicsconfig.GetFloat("m_terraincontact_bounce", 0.05f); + mTerrainContactERP = physicsconfig.GetFloat("m_terraincontact_erp", 0.05025f); - HalfOdeStep = ODE_STEPSIZE * 0.5f; - odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); + nmAvatarObjectContactFriction = physicsconfig.GetFloat("objectcontact_friction", 250f); + nmAvatarObjectContactBounce = physicsconfig.GetFloat("objectcontact_bounce", 0.2f); - ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); - GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf); + mAvatarObjectContactFriction = physicsconfig.GetFloat("m_avatarobjectcontact_friction", 75f); + mAvatarObjectContactBounce = physicsconfig.GetFloat("m_avatarobjectcontact_bounce", 0.1f); - SharedTmpcontact.geom.g1 = IntPtr.Zero; - SharedTmpcontact.geom.g2 = IntPtr.Zero; + ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); + m_physicsiterations = physicsconfig.GetInt("world_solver_iterations", 10); - SharedTmpcontact.geom.side1 = -1; - SharedTmpcontact.geom.side2 = -1; + avDensity = physicsconfig.GetFloat("av_density", 80f); +// avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f); + avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); + avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); + avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); + avplanted = physicsconfig.GetBoolean("av_planted", false); + av_av_collisions_off = physicsconfig.GetBoolean("av_av_collisions_off", false); - SharedTmpcontact.surface.mode = comumContactFlags; - SharedTmpcontact.surface.mu = 0; - SharedTmpcontact.surface.bounce = 0; - SharedTmpcontact.surface.soft_cfm = comumContactCFM; - SharedTmpcontact.surface.soft_erp = comumContactERP; - SharedTmpcontact.surface.slip1 = comumContactSLIP; - SharedTmpcontact.surface.slip2 = comumContactSLIP; + IsAvCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); - m_materialContactsData[(int)Material.Stone].mu = 0.8f; - m_materialContactsData[(int)Material.Stone].bounce = 0.4f; + contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); - m_materialContactsData[(int)Material.Metal].mu = 0.3f; - m_materialContactsData[(int)Material.Metal].bounce = 0.4f; + geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5); + geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); - m_materialContactsData[(int)Material.Glass].mu = 0.2f; - m_materialContactsData[(int)Material.Glass].bounce = 0.7f; + geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); + bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); - m_materialContactsData[(int)Material.Wood].mu = 0.6f; - m_materialContactsData[(int)Material.Wood].bounce = 0.5f; + bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f); + bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f); - m_materialContactsData[(int)Material.Flesh].mu = 0.9f; - m_materialContactsData[(int)Material.Flesh].bounce = 0.3f; + forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); + meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true); + meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); + MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); + m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false); - m_materialContactsData[(int)Material.Plastic].mu = 0.4f; - m_materialContactsData[(int)Material.Plastic].bounce = 0.7f; + avPIDD = physicsconfig.GetFloat("av_pid_derivative", 2200.0f); + avPIDP = physicsconfig.GetFloat("av_pid_proportional", 900.0f); + avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor", 550000f); - m_materialContactsData[(int)Material.Rubber].mu = 0.9f; - m_materialContactsData[(int)Material.Rubber].bounce = 0.95f; + physics_logging = physicsconfig.GetBoolean("physics_logging", false); + physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); + physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); - m_materialContactsData[(int)Material.light].mu = 0.0f; - m_materialContactsData[(int)Material.light].bounce = 0.0f; +// m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); + minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); + maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); + } + } + contacts = new d.ContactGeom[contactsPerCollision]; spacesPerMeterX = 1.0f / metersInSpace; - spacesPerMeterY = spacesPerMeterX; + spacesPerMeterY = 1.0f / metersInSpace; + spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX); spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY); + // note: limit number of spaces if (spaceGridMaxX > 24) { spaceGridMaxX = 24; - spacesPerMeterX = spaceGridMaxX / WorldExtents.X; + spacesPerMeterX = spaceGridMaxX / WorldExtents.X; } - if (spaceGridMaxY > 24) { spaceGridMaxY = 24; spacesPerMeterY = spaceGridMaxY / WorldExtents.Y; } - staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; + staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; + + // make this index limits + spaceGridMaxX--; + spaceGridMaxY--; - // create all spaces now - int i, j; - IntPtr newspace; + // Centeral contact friction and bounce + // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why + // an avatar falls through in Z but not in X or Y when walking on a prim. + contact.surface.mode |= d.ContactFlags.SoftERP; + contact.surface.mu = nmAvatarObjectContactFriction; + contact.surface.bounce = nmAvatarObjectContactBounce; + contact.surface.soft_cfm = 0.010f; + contact.surface.soft_erp = 0.010f; + + // Terrain contact friction and Bounce + // This is the *non* moving version. Use this when an avatar + // isn't moving to keep it in place better + TerrainContact.surface.mode |= d.ContactFlags.SoftERP; + TerrainContact.surface.mu = nmTerrainContactFriction; + TerrainContact.surface.bounce = nmTerrainContactBounce; + TerrainContact.surface.soft_erp = nmTerrainContactERP; + + WaterContact.surface.mode |= (d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM); + WaterContact.surface.mu = 0f; // No friction + WaterContact.surface.bounce = 0.0f; // No bounce + WaterContact.surface.soft_cfm = 0.010f; + WaterContact.surface.soft_erp = 0.010f; + + // Prim contact friction and bounce + // THis is the *non* moving version of friction and bounce + // Use this when an avatar comes in contact with a prim + // and is moving + AvatarMovementprimContact.surface.mu = mAvatarObjectContactFriction; + AvatarMovementprimContact.surface.bounce = mAvatarObjectContactBounce; + + // Terrain contact friction bounce and various error correcting calculations + // Use this when an avatar is in contact with the terrain and moving. + AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP; + AvatarMovementTerrainContact.surface.mu = mTerrainContactFriction; + AvatarMovementTerrainContact.surface.bounce = mTerrainContactBounce; + AvatarMovementTerrainContact.surface.soft_erp = mTerrainContactERP; - for (i = 0; i < spaceGridMaxX; i++) - for (j = 0; j < spaceGridMaxY; j++) - { - newspace = d.HashSpaceCreate(StaticSpace); - d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); - waitForSpaceUnlock(newspace); - d.SpaceSetSublevel(newspace, 2); - d.HashSpaceSetLevels(newspace, -2, 8); - d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Land | - CollisionCategories.Water | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(newspace, 0); + /* + + Stone = 0, + /// + Metal = 1, + /// + Glass = 2, + /// + Wood = 3, + /// + Flesh = 4, + /// + Plastic = 5, + /// + Rubber = 6 + */ + + m_materialContacts = new d.Contact[7,2]; + + m_materialContacts[(int)Material.Stone, 0] = new d.Contact(); + m_materialContacts[(int)Material.Stone, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Stone, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Stone, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Stone, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Stone, 1] = new d.Contact(); + m_materialContacts[(int)Material.Stone, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Stone, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Stone, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Stone, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Metal, 0] = new d.Contact(); + m_materialContacts[(int)Material.Metal, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Metal, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Metal, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Metal, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Metal, 1] = new d.Contact(); + m_materialContacts[(int)Material.Metal, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Metal, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Metal, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Metal, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Glass, 0] = new d.Contact(); + m_materialContacts[(int)Material.Glass, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 0].surface.mu = 1f; + m_materialContacts[(int)Material.Glass, 0].surface.bounce = 0.5f; + m_materialContacts[(int)Material.Glass, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Glass, 0].surface.soft_erp = 0.010f; - staticPrimspace[i, j] = newspace; - } + /* + private float nmAvatarObjectContactFriction = 250f; + private float nmAvatarObjectContactBounce = 0.1f; - // let this now be index limit - spaceGridMaxX--; - spaceGridMaxY--; + private float mAvatarObjectContactFriction = 75f; + private float mAvatarObjectContactBounce = 0.1f; + */ + m_materialContacts[(int)Material.Glass, 1] = new d.Contact(); + m_materialContacts[(int)Material.Glass, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 1].surface.mu = 1f; + m_materialContacts[(int)Material.Glass, 1].surface.bounce = 0.5f; + m_materialContacts[(int)Material.Glass, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Glass, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Wood, 0] = new d.Contact(); + m_materialContacts[(int)Material.Wood, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Wood, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Wood, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Wood, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Wood, 1] = new d.Contact(); + m_materialContacts[(int)Material.Wood, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Wood, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Wood, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Wood, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Flesh, 0] = new d.Contact(); + m_materialContacts[(int)Material.Flesh, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Flesh, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Flesh, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Flesh, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Flesh, 1] = new d.Contact(); + m_materialContacts[(int)Material.Flesh, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Flesh, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Flesh, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Flesh, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Plastic, 0] = new d.Contact(); + m_materialContacts[(int)Material.Plastic, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Plastic, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Plastic, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Plastic, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Plastic, 1] = new d.Contact(); + m_materialContacts[(int)Material.Plastic, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Plastic, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Plastic, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Plastic, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Rubber, 0] = new d.Contact(); + m_materialContacts[(int)Material.Rubber, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Rubber, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Rubber, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Rubber, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Rubber, 1] = new d.Contact(); + m_materialContacts[(int)Material.Rubber, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Rubber, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f; + + d.HashSpaceSetLevels(space, HashspaceLow, HashspaceHigh); + + // Set the gravity,, don't disable things automatically (we set it explicitly on some things) - // create 4 off world spaces (x<0,x>max,y<0,y>max) - staticPrimspaceOffRegion = new IntPtr[4]; + d.WorldSetGravity(world, gravityx, gravityy, gravityz); + d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); - for (i = 0; i < 4; i++) - { - newspace = d.HashSpaceCreate(StaticSpace); - d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); - waitForSpaceUnlock(newspace); - d.SpaceSetSublevel(newspace, 2); - d.HashSpaceSetLevels(newspace, -2, 8); - d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Land | - CollisionCategories.Water | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(newspace, 0); + d.WorldSetLinearDamping(world, 256f); + d.WorldSetAngularDamping(world, 256f); + d.WorldSetAngularDampingThreshold(world, 256f); + d.WorldSetLinearDampingThreshold(world, 256f); + d.WorldSetMaxAngularSpeed(world, 256f); - staticPrimspaceOffRegion[i] = newspace; - } + d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + //d.WorldSetContactMaxCorrectingVel(world, 1000.0f); - m_lastframe = DateTime.UtcNow; - m_lastMeshExpire = m_lastframe; - } + for (int i = 0; i < staticPrimspace.GetLength(0); i++) + { + for (int j = 0; j < staticPrimspace.GetLength(1); j++) + { + staticPrimspace[i, j] = IntPtr.Zero; + } + } - internal void waitForSpaceUnlock(IntPtr space) - { - //if (space != IntPtr.Zero) - //while (d.SpaceLockQuery(space)) { } // Wait and do nothing + _worldInitialized = true; } #region Collision Detection - // sets a global contact for a joint for contactgeom , and base contact description) - private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom,bool smooth) + /// + /// Collides two geometries. + /// + /// + /// + /// /param> + /// + /// + /// + private int CollideGeoms( + IntPtr geom1, IntPtr geom2, int maxContacts, d.ContactGeom[] contactsArray, int contactGeomSize) { - if (m_global_contactcount >= maxContactsbeforedeath) - return IntPtr.Zero; + int count; - m_global_contactcount++; - if(smooth) - SharedTmpcontact.geom.depth = contactGeom.depth * 0.05f; - else - SharedTmpcontact.geom.depth = contactGeom.depth; - SharedTmpcontact.geom.pos = contactGeom.pos; - SharedTmpcontact.geom.normal = contactGeom.normal; + lock (OdeScene.UniversalColliderSyncObject) + { + // We do this inside the lock so that we don't count any delay in acquiring it + if (CollectStats) + m_nativeCollisionStartTick = Util.EnvironmentTickCount(); - IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); - Marshal.StructureToPtr(SharedTmpcontact, contact, true); - return d.JointCreateContactPtr(world, contactgroup, contact); - } + count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); + } - private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) - { - if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision) - return false; + // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably + // negligable + if (CollectStats) + m_stats[ODENativeGeomCollisionFrameMsStatName] + += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); - IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); - newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom)); - return true; + return count; } /// - /// This is our near callback. A geometry is near a body + /// Collide two spaces or a space and a geometry. /// - /// The space that contains the geoms. Remember, spaces are also geoms + /// + /// /param> + /// + private void CollideSpaces(IntPtr space1, IntPtr space2, IntPtr data) + { + if (CollectStats) + { + m_inCollisionTiming = true; + m_nativeCollisionStartTick = Util.EnvironmentTickCount(); + } + + d.SpaceCollide2(space1, space2, data, nearCallback); + + if (CollectStats && m_inCollisionTiming) + { + m_stats[ODENativeSpaceCollisionFrameMsStatName] + += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); + m_inCollisionTiming = false; + } + } + + /// + /// This is our near callback. A geometry is near a body + /// + /// The space that contains the geoms. Remember, spaces are also geoms /// a geometry or space /// another geometry or space - /// - private void near(IntPtr space, IntPtr g1, IntPtr g2) { - // no lock here! It's invoked from within Simulate(), which is thread-locked + if (CollectStats && m_inCollisionTiming) + { + m_stats[ODENativeSpaceCollisionFrameMsStatName] + += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick); + m_inCollisionTiming = false; + } - if (m_global_contactcount >= maxContactsbeforedeath) - return; +// m_log.DebugFormat("[PHYSICS]: Colliding {0} and {1} in {2}", g1, g2, space); + // no lock here! It's invoked from within Simulate(), which is thread-locked // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively - if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) - return; - if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + + // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { - d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + CollideSpaces(g1, g2, IntPtr.Zero); } catch (AccessViolationException) { - m_log.Warn("[PHYSICS]: Unable to collide test a space"); + m_log.Error("[ODE SCENE]: Unable to collide test a space"); return; } - //here one should check collisions of geoms inside a space - // but on each space we only should have geoms that not colide amoung each other - // so we don't dig inside spaces + //Colliding a space or a geom with a space or a geom. so drill down + + //Collide all geoms in each space.. + //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); + //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } - // get geom bodies to check if we already a joint contact - // guess this shouldn't happen now + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + IntPtr b1 = d.GeomGetBody(g1); IntPtr b2 = d.GeomGetBody(g2); // d.GeomClassID id = d.GeomGetClass(g1); + String name1 = null; + String name2 = null; + + if (!geom_name_map.TryGetValue(g1, out name1)) + { + name1 = "null"; + } + if (!geom_name_map.TryGetValue(g2, out name2)) + { + name2 = "null"; + } + // Figure out how many contact points we have int count = 0; + try { // Colliding Geom To Geom @@ -728,329 +1003,444 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; - /* - // debug - PhysicsActor dp2; - if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) - { - d.AABB aabb; - d.GeomGetAABB(g2, out aabb); - float x = aabb.MaxX - aabb.MinX; - float y = aabb.MaxY - aabb.MinY; - float z = aabb.MaxZ - aabb.MinZ; - if (x > 60.0f || y > 60.0f || z > 60.0f) - { - if (!actor_name_map.TryGetValue(g2, out dp2)) - m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2"); - else - m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})", - dp2.Name, dp2.Size, x, y, z, - dp2.Position.ToString(), - dp2.Orientation.ToString(), - dp2.Orientation.Length()); - return; - } - } - // - */ + count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.unmanagedSizeOf); - if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || - d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) - { - int cflags; - unchecked - { - cflags = (int)(1 | d.CONTACTS_UNIMPORTANT); - } - count = d.CollidePtr(g1, g2, cflags, ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); - } - else - count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + // All code after this is only relevant if we have any collisions + if (count <= 0) + return; + + if (count > contacts.Length) + m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); } catch (SEHException) { - m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); - // ode.drelease(world); + m_log.Error( + "[ODE SCENE]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); base.TriggerPhysicsBasedRestart(); } catch (Exception e) { - m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); + m_log.ErrorFormat("[ODE SCENE]: Unable to collide test an object: {0}", e.Message); return; } - // contacts done - if (count == 0) - return; - - // try get physical actors PhysicsActor p1; PhysicsActor p2; - + + p1ExpectedPoints = 0; + p2ExpectedPoints = 0; + if (!actor_name_map.TryGetValue(g1, out p1)) { - m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 1"); - return; + p1 = PANull; } if (!actor_name_map.TryGetValue(g2, out p2)) { - m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2"); - return; + p2 = PANull; } - - // get first contact - d.ContactGeom curContact = new d.ContactGeom(); - - if (!GetCurContactGeom(0, ref curContact)) - return; - ContactPoint maxDepthContact = new ContactPoint(); + if (p1.CollisionScore + count >= float.MaxValue) + p1.CollisionScore = 0; + p1.CollisionScore += count; - // do volume detection case - if ((p1.IsVolumeDtc || p2.IsVolumeDtc)) + if (p2.CollisionScore + count >= float.MaxValue) + p2.CollisionScore = 0; + p2.CollisionScore += count; + + for (int i = 0; i < count; i++) { - maxDepthContact = new ContactPoint( - new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), - new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), - curContact.depth, false + d.ContactGeom curContact = contacts[i]; + + if (curContact.depth > maxDepthContact.PenetrationDepth) + { + maxDepthContact = new ContactPoint( + new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), + new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), + curContact.depth ); + } - collision_accounting_events(p1, p2, maxDepthContact); - return; - } + //m_log.Warn("[CCOUNT]: " + count); + IntPtr joint; + // If we're colliding with terrain, use 'TerrainContact' instead of contact. + // allows us to have different settings + + // We only need to test p2 for 'jump crouch purposes' + if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) + { + // Testing if the collision is at the feet of the avatar + + //m_log.DebugFormat("[PHYSICS]: {0} - {1} - {2} - {3}", curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); + if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)) + p2.IsColliding = true; + } + else + { + p2.IsColliding = true; + } + + //if ((framecount % m_returncollisions) == 0) - // big messy collision analises + switch (p1.PhysicsActorType) + { + case (int)ActorTypes.Agent: + p1ExpectedPoints = avatarExpectedContacts; + p2.CollidingObj = true; + break; + case (int)ActorTypes.Prim: + if (p1 != null && p1 is OdePrim) + p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts; - float mu = 0; - float bounce = 0; -// bool IgnoreNegSides = false; + if (p2.Velocity.LengthSquared() > 0.0f) + p2.CollidingObj = true; + break; + case (int)ActorTypes.Unknown: + p2.CollidingGround = true; + break; + default: + p2.CollidingGround = true; + break; + } - ContactData contactdata1 = new ContactData(0, 0, false); - ContactData contactdata2 = new ContactData(0, 0, false); + // we don't want prim or avatar to explode - bool dop1ava = false; - bool dop2ava = false; - bool ignore = false; - bool smoothMesh = false; + #region InterPenetration Handling - Unintended physics explosions - switch (p1.PhysicsActorType) - { - case (int)ActorTypes.Agent: + if (curContact.depth >= 0.08f) + { + if (curContact.depth >= 1.00f) { - dop1ava = true; - switch (p2.PhysicsActorType) + //m_log.Info("[P]: " + contact.depth.ToString()); + if ((p2.PhysicsActorType == (int) ActorTypes.Agent && + p1.PhysicsActorType == (int) ActorTypes.Unknown) || + (p1.PhysicsActorType == (int) ActorTypes.Agent && + p2.PhysicsActorType == (int) ActorTypes.Unknown)) { - case (int)ActorTypes.Agent: - case (int)ActorTypes.Prim: - break; + if (p2.PhysicsActorType == (int) ActorTypes.Agent) + { + if (p2 is OdeCharacter) + { + OdeCharacter character = (OdeCharacter) p2; + + //p2.CollidingObj = true; + curContact.depth = 0.00000003f; + p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); + curContact.pos = + new d.Vector3(curContact.pos.X + (p1.Size.X/2), + curContact.pos.Y + (p1.Size.Y/2), + curContact.pos.Z + (p1.Size.Z/2)); + character.SetPidStatus(true); + } + } - default: - ignore = true; // avatar to terrain and water ignored - break; + if (p1.PhysicsActorType == (int) ActorTypes.Agent) + { + if (p1 is OdeCharacter) + { + OdeCharacter character = (OdeCharacter) p1; + + //p2.CollidingObj = true; + curContact.depth = 0.00000003f; + p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); + curContact.pos = + new d.Vector3(curContact.pos.X + (p1.Size.X/2), + curContact.pos.Y + (p1.Size.Y/2), + curContact.pos.Z + (p1.Size.Z/2)); + character.SetPidStatus(true); + } + } } - break; } + } - case (int)ActorTypes.Prim: - { - switch (p2.PhysicsActorType) - { - case (int)ActorTypes.Agent: - dop2ava = true; - break; + #endregion - case (int)ActorTypes.Prim: - Vector3 relV = p1.rootVelocity - p2.rootVelocity; - float relVlenSQ = relV.LengthSquared(); - if (relVlenSQ > 0.0001f) - { - p1.CollidingObj = true; - p2.CollidingObj = true; - } - p1.getContactData(ref contactdata1); - p2.getContactData(ref contactdata2); - bounce = contactdata1.bounce * contactdata2.bounce; - mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); + // Logic for collision handling + // Note, that if *all* contacts are skipped (VolumeDetect) + // The prim still detects (and forwards) collision events but + // appears to be phantom for the world + Boolean skipThisContact = false; - if (relVlenSQ > 0.01f) - mu *= frictionMovementMult; + if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect)) + skipThisContact = true; // No collision on volume detect prims - if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass && - d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) - smoothMesh = true; - break; + if (av_av_collisions_off) + if ((p1 is OdeCharacter) && (p2 is OdeCharacter)) + skipThisContact = true; - case (int)ActorTypes.Ground: - p1.getContactData(ref contactdata1); - bounce = contactdata1.bounce * TerrainBounce; - mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); + if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) + skipThisContact = true; // No collision on volume detect prims - Vector3 v1 = p1.rootVelocity; - if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) - mu *= frictionMovementMult; - p1.CollidingGround = true; + if (!skipThisContact && curContact.depth < 0f) + skipThisContact = true; - if(d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) - smoothMesh = true; - break; + if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType)) + skipThisContact = true; - case (int)ActorTypes.Water: - default: - ignore = true; - break; - } - } - break; + const int maxContactsbeforedeath = 4000; + joint = IntPtr.Zero; - case (int)ActorTypes.Ground: - if (p2.PhysicsActorType == (int)ActorTypes.Prim) - { - p2.CollidingGround = true; - p2.getContactData(ref contactdata2); - bounce = contactdata2.bounce * TerrainBounce; - mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); - -// if (curContact.side1 > 0) // should be 2 ? -// IgnoreNegSides = true; - Vector3 v2 = p2.rootVelocity; - if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) - mu *= frictionMovementMult; - - if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass) - smoothMesh = true; - } - else - ignore = true; - break; + if (!skipThisContact) + { + _perloopContact.Add(curContact); - case (int)ActorTypes.Water: - default: - break; - } + if (name1 == "Terrain" || name2 == "Terrain") + { + if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && + (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + { + p2ExpectedPoints = avatarExpectedContacts; + // Avatar is moving on terrain, use the movement terrain contact + AvatarMovementTerrainContact.geom = curContact; - if (ignore) - return; + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); + m_global_contactcount++; + } + } + else + { + if (p2.PhysicsActorType == (int)ActorTypes.Agent) + { + p2ExpectedPoints = avatarExpectedContacts; + // Avatar is standing on terrain, use the non moving terrain contact + TerrainContact.geom = curContact; - IntPtr Joint; - bool FeetCollision = false; - int ncontacts = 0; + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); + m_global_contactcount++; + } + } + else + { + if (p2.PhysicsActorType == (int)ActorTypes.Prim && p1.PhysicsActorType == (int)ActorTypes.Prim) + { + // prim prim contact + // int pj294950 = 0; + int movintYN = 0; + int material = (int) Material.Wood; + // prim terrain contact + if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) + { + movintYN = 1; + } - int i = 0; + if (p2 is OdePrim) + { + material = ((OdePrim) p2).m_material; + p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; + } + + // Unnessesary because p1 is defined above + //if (p1 is OdePrim) + // { + // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts; + // } + //m_log.DebugFormat("Material: {0}", material); - maxDepthContact = new ContactPoint(); - maxDepthContact.PenetrationDepth = float.MinValue; - ContactPoint minDepthContact = new ContactPoint(); - minDepthContact.PenetrationDepth = float.MaxValue; + m_materialContacts[material, movintYN].geom = curContact; - SharedTmpcontact.geom.depth = 0; - SharedTmpcontact.surface.mu = mu; - SharedTmpcontact.surface.bounce = bounce; + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + m_global_contactcount++; + } + } + else + { + int movintYN = 0; + // prim terrain contact + if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) + { + movintYN = 1; + } - d.ContactGeom altContact = new d.ContactGeom(); - bool useAltcontact = false; - bool noskip = true; + int material = (int)Material.Wood; - if(dop1ava || dop2ava) - smoothMesh = false; + if (p2 is OdePrim) + { + material = ((OdePrim)p2).m_material; + p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; + } - while (true) - { - noskip = true; - useAltcontact = false; + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, movintYN].geom = curContact; - if (dop1ava) - { - if ((((OdeCharacter)p1).Collide(g1, g2, false, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision))) + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + m_global_contactcount++; + } + } + } + } + //if (p2.PhysicsActorType == (int)ActorTypes.Prim) + //{ + //m_log.Debug("[PHYSICS]: prim contacting with ground"); + //} + } + else if (name1 == "Water" || name2 == "Water") { - if (p2.PhysicsActorType == (int)ActorTypes.Agent) + /* + if ((p2.PhysicsActorType == (int) ActorTypes.Prim)) { - p1.CollidingObj = true; - p2.CollidingObj = true; } - else if (p2.rootVelocity.LengthSquared() > 0.0f) - p2.CollidingObj = true; + else + { + } + */ + //WaterContact.surface.soft_cfm = 0.0000f; + //WaterContact.surface.soft_erp = 0.00000f; + if (curContact.depth > 0.1f) + { + curContact.depth *= 52; + //contact.normal = new d.Vector3(0, 0, 1); + //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); + } + + WaterContact.geom = curContact; + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref WaterContact); + m_global_contactcount++; + } + //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth); } else - noskip = false; - } - else if (dop2ava) - { - if ((((OdeCharacter)p2).Collide(g2, g1, true, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision))) { - if (p1.PhysicsActorType == (int)ActorTypes.Agent) + if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) { - p1.CollidingObj = true; - p2.CollidingObj = true; + p2ExpectedPoints = avatarExpectedContacts; + if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + { + // Avatar is moving on a prim, use the Movement prim contact + AvatarMovementprimContact.geom = curContact; + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); + m_global_contactcount++; + } + } + else + { + // Avatar is standing still on a prim, use the non movement contact + contact.geom = curContact; + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref contact); + m_global_contactcount++; + } + } + } + else if (p2.PhysicsActorType == (int)ActorTypes.Prim) + { + //p1.PhysicsActorType + int material = (int)Material.Wood; + + if (p2 is OdePrim) + { + material = ((OdePrim)p2).m_material; + p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts; + } + + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, 0].geom = curContact; + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); + m_global_contactcount++; + } } - else if (p1.rootVelocity.LengthSquared() > 0.0f) - p1.CollidingObj = true; } - else - noskip = false; + + if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide! + { + d.JointAttach(joint, b1, b2); + m_global_contactcount++; + } } - if (noskip) + collision_accounting_events(p1, p2, maxDepthContact); + + if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle)) { - if(useAltcontact) - Joint = CreateContacJoint(ref altContact,smoothMesh); - else - Joint = CreateContacJoint(ref curContact,smoothMesh); + // If there are more then 3 contact points, it's likely + // that we've got a pile of objects, so ... + // We don't want to send out hundreds of terse updates over and over again + // so lets throttle them and send them again after it's somewhat sorted out. + p2.ThrottleUpdates = true; + } + //m_log.Debug(count.ToString()); + //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); + } + } - if (Joint == IntPtr.Zero) - break; + private bool checkDupe(d.ContactGeom contactGeom, int atype) + { + if (!m_filterCollisions) + return false; - d.JointAttach(Joint, b1, b2); + bool result = false; - ncontacts++; + ActorTypes at = (ActorTypes)atype; - if (curContact.depth > maxDepthContact.PenetrationDepth) + foreach (d.ContactGeom contact in _perloopContact) + { + //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) + //{ + // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2) + if (at == ActorTypes.Agent) + { + if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) + && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) + && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))) { - maxDepthContact.Position.X = curContact.pos.X; - maxDepthContact.Position.Y = curContact.pos.Y; - maxDepthContact.Position.Z = curContact.pos.Z; - maxDepthContact.PenetrationDepth = curContact.depth; - maxDepthContact.CharacterFeet = FeetCollision; + if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) + { + result = true; + break; + } } - - if (curContact.depth < minDepthContact.PenetrationDepth) + } + else if (at == ActorTypes.Prim) + { + if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))) { - minDepthContact.PenetrationDepth = curContact.depth; - minDepthContact.SurfaceNormal.X = curContact.normal.X; - minDepthContact.SurfaceNormal.Y = curContact.normal.Y; - minDepthContact.SurfaceNormal.Z = curContact.normal.Z; + if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) + { + if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f) + { + result = true; + break; + } + } + //m_log.DebugFormat("[Collision]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); + //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); } } - - if (++i >= count) - break; - - if (!GetCurContactGeom(i, ref curContact)) - break; } - if (ncontacts > 0) - { - maxDepthContact.SurfaceNormal.X = minDepthContact.SurfaceNormal.X; - maxDepthContact.SurfaceNormal.Y = minDepthContact.SurfaceNormal.Y; - maxDepthContact.SurfaceNormal.Z = minDepthContact.SurfaceNormal.Z; - - collision_accounting_events(p1, p2, maxDepthContact); - } + return result; } private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { - uint obj2LocalID = 0; - - // update actors collision score - if (p1.CollisionScore < float.MaxValue) - p1.CollisionScore += 1.0f; - if (p2.CollisionScore < float.MaxValue) - p2.CollisionScore += 1.0f; - + // obj1LocalID = 0; + //returncollisions = false; + obj2LocalID = 0; + //ctype = 0; + //cStartStop = 0; +// if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) +// return; bool p1events = p1.SubscribedEvents(); bool p2events = p2.SubscribedEvents(); @@ -1064,170 +1454,369 @@ namespace OpenSim.Region.PhysicsModule.ubOde Vector3 vel = Vector3.Zero; if (p2 != null && p2.IsPhysical) - vel = p2.rootVelocity; + vel = p2.Velocity; if (p1 != null && p1.IsPhysical) - vel -= p1.rootVelocity; + vel -= p1.Velocity; contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal); - switch ((ActorTypes)p1.PhysicsActorType) + switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: - case ActorTypes.Prim: - { - switch ((ActorTypes)p2.PhysicsActorType) + cc2 = (OdeCharacter)p2; + + // obj1LocalID = cc2.m_localID; + switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: + cc1 = (OdeCharacter)p1; + obj2LocalID = cc1.LocalID; + cc1.AddCollisionEvent(cc2.LocalID, contact); + break; + case ActorTypes.Prim: - if (p2events) + if (p1 is OdePrim) { - AddCollisionEventReporting(p2); - p2.AddCollisionEvent(p1.ParentActor.LocalID, contact); + cp1 = (OdePrim) p1; + obj2LocalID = cp1.LocalID; + cp1.AddCollisionEvent(cc2.LocalID, contact); } - obj2LocalID = p2.ParentActor.LocalID; break; case ActorTypes.Ground: case ActorTypes.Unknown: - default: obj2LocalID = 0; break; } - if (p1events) - { - contact.SurfaceNormal = -contact.SurfaceNormal; - contact.RelativeSpeed = -contact.RelativeSpeed; - AddCollisionEventReporting(p1); - p1.AddCollisionEvent(obj2LocalID, contact); - } + + cc2.AddCollisionEvent(obj2LocalID, contact); break; - } - case ActorTypes.Ground: - case ActorTypes.Unknown: - default: - { - if (p2events && !p2.IsVolumeDtc) + + case ActorTypes.Prim: + + if (p2 is OdePrim) { - AddCollisionEventReporting(p2); - p2.AddCollisionEvent(0, contact); + cp2 = (OdePrim) p2; + + // obj1LocalID = cp2.m_localID; + switch ((ActorTypes) p1.PhysicsActorType) + { + case ActorTypes.Agent: + if (p1 is OdeCharacter) + { + cc1 = (OdeCharacter) p1; + obj2LocalID = cc1.LocalID; + cc1.AddCollisionEvent(cp2.LocalID, contact); + } + break; + case ActorTypes.Prim: + + if (p1 is OdePrim) + { + cp1 = (OdePrim) p1; + obj2LocalID = cp1.LocalID; + cp1.AddCollisionEvent(cp2.LocalID, contact); + } + break; + + case ActorTypes.Ground: + case ActorTypes.Unknown: + obj2LocalID = 0; + break; + } + + cp2.AddCollisionEvent(obj2LocalID, contact); } break; - } } } - /// /// This is our collision testing routine in ODE /// - /// private void collision_optimized() { - lock (_characters) - { + _perloopContact.Clear(); + + foreach (OdeCharacter chr in _characters) + { + // Reset the collision values to false + // since we don't know if we're colliding yet + if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) + continue; + + chr.IsColliding = false; + chr.CollidingGround = false; + chr.CollidingObj = false; + + // Test the avatar's geometry for collision with the space + // This will return near and the space that they are the closest to + // And we'll run this again against the avatar and the space segment + // This will return with a bunch of possible objects in the space segment + // and we'll run it again on all of them. try { - foreach (OdeCharacter chr in _characters) - { - if (chr == null) - continue; - - chr.IsColliding = false; - // chr.CollidingGround = false; not done here - chr.CollidingObj = false; - - if(chr.Body == IntPtr.Zero || chr.collider == IntPtr.Zero ) - continue; - - // do colisions with static space - d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); - - // no coll with gnd - } - // chars with chars - d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); - + CollideSpaces(space, chr.Shell, IntPtr.Zero); } catch (AccessViolationException) { - m_log.Warn("[PHYSICS]: Unable to collide Character to static space"); + m_log.ErrorFormat("[ODE SCENE]: Unable to space collide {0}", PhysicsSceneName); } + + //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); + //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10) + //{ + //chr.Position.Z = terrainheight + 10.0f; + //forcedZ = true; + //} + } + if (CollectStats) + { + m_tempAvatarCollisionsThisFrame = _perloopContact.Count; + m_stats[ODEAvatarContactsStatsName] += m_tempAvatarCollisionsThisFrame; } - lock (_activeprims) + List removeprims = null; + foreach (OdePrim chr in _activeprims) { - foreach (OdePrim aprim in _activeprims) + if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) { - aprim.CollisionScore = 0; - aprim.IsColliding = false; - } - } - lock (_activegroups) - { - try - { - foreach (OdePrim aprim in _activegroups) + try { - if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body) && - aprim.collide_geom != IntPtr.Zero) + lock (chr) { - d.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); - d.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); + if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) + { + CollideSpaces(space, chr.prim_geom, IntPtr.Zero); + } + else + { + if (removeprims == null) + { + removeprims = new List(); + } + removeprims.Add(chr); + m_log.Error( + "[ODE SCENE]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!"); + } } } - } - catch (Exception e) - { - m_log.Warn("[PHYSICS]: Unable to collide Active to Static: " + e.Message); + catch (AccessViolationException) + { + m_log.Error("[ODE SCENE]: Unable to space collide"); + } } } - // colide active amoung them - try - { - d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); - } - catch (Exception e) + if (CollectStats) + m_stats[ODEPrimContactsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame; + + if (removeprims != null) { - m_log.Warn("[PHYSICS]: Unable to collide in Active: " + e.Message); + foreach (OdePrim chr in removeprims) + { + _activeprims.Remove(chr); + } } + } - // and with chars - try + #endregion + + // Recovered for use by fly height. Kitto Flora + internal float GetTerrainHeightAtXY(float x, float y) + { + IntPtr heightFieldGeom = IntPtr.Zero; + int offsetX = 0; + int offsetY = 0; + + if(RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom)) { - d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); + if (heightFieldGeom != IntPtr.Zero) + { + if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) + { + + int index; + + + if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y || + (int)x < 0.001f || (int)y < 0.001f) + return 0; + + x = x - offsetX + 1f; + y = y - offsetY + 1f; + + // map is rotated + index = (int)x * ((int)m_regionHeight + 3) + (int)y; + + if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) + { + //m_log.DebugFormat("x{0} y{1} = {2}", x, y, (float)TerrainHeightFieldHeights[heightFieldGeom][index]); + return (float)TerrainHeightFieldHeights[heightFieldGeom][index]; + } + + else + return 0f; + } + else + { + return 0f; + } + + } + else + { + return 0f; + } + } - catch (Exception e) + else { - m_log.Warn("[PHYSICS]: Unable to collide Active to Character: " + e.Message); + return 0f; } - } + } +// End recovered. Kitto Flora - #endregion /// /// Add actor to the list that should receive collision events in the simulate loop. /// /// - public void AddCollisionEventReporting(PhysicsActor obj) + internal void AddCollisionEventReporting(PhysicsActor obj) { - if (!_collisionEventPrim.Contains(obj)) - _collisionEventPrim.Add(obj); +// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID); + + lock (m_collisionEventActorsChanges) + m_collisionEventActorsChanges[obj.LocalID] = obj; } /// /// Remove actor from the list that should receive collision events in the simulate loop. /// /// - public void RemoveCollisionEventReporting(PhysicsActor obj) + internal void RemoveCollisionEventReporting(PhysicsActor obj) + { +// m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID); + + lock (m_collisionEventActorsChanges) + m_collisionEventActorsChanges[obj.LocalID] = null; + } + + #region Add/Remove Entities + + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) { - lock(_collisionEventPrimRemove) + d.AllocateODEDataForThread(0); + + OdeCharacter newAv + = new OdeCharacter( + avName, this, position, velocity, size, avPIDD, avPIDP, + avCapRadius, avStandupTensor, avDensity, + avMovementDivisorWalk, avMovementDivisorRun); + + newAv.Flying = isFlying; + newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; + newAv.m_avatarplanted = avplanted; + + return newAv; + } + + public override void RemoveAvatar(PhysicsActor actor) + { +// m_log.DebugFormat( +// "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2}", +// actor.Name, actor.LocalID, Name); + + lock (OdeLock) { - if (_collisionEventPrim.Contains(obj) && !_collisionEventPrimRemove.Contains(obj)) - _collisionEventPrimRemove.Add(obj); + d.AllocateODEDataForThread(0); + + ((OdeCharacter) actor).Destroy(); + } + } + + internal void AddCharacter(OdeCharacter chr) + { + chr.m_avatarplanted = avplanted; + if (!_characters.Contains(chr)) + { + _characters.Add(chr); + +// m_log.DebugFormat( +// "[ODE SCENE]: Adding physics character {0} {1} to physics scene {2}. Count now {3}", +// chr.Name, chr.LocalID, Name, _characters.Count); + + if (chr.bad) + m_log.ErrorFormat("[ODE SCENE]: Added BAD actor {0} to characters list", chr.m_uuid); + } + else + { + m_log.ErrorFormat( + "[ODE SCENE]: Tried to add character {0} {1} but they are already in the set!", + chr.Name, chr.LocalID); + } + } + + internal void RemoveCharacter(OdeCharacter chr) + { + if (_characters.Contains(chr)) + { + _characters.Remove(chr); + +// m_log.DebugFormat( +// "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2}. Count now {3}", +// chr.Name, chr.LocalID, Name, _characters.Count); + } + else + { + m_log.ErrorFormat( + "[ODE SCENE]: Tried to remove character {0} {1} but they are not in the list!", + chr.Name, chr.LocalID); } } + private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, + PrimitiveBaseShape pbs, bool isphysical, uint localID) + { + Vector3 pos = position; + Vector3 siz = size; + Quaternion rot = rotation; + + + OdePrim newPrim; + lock (OdeLock) + { + d.AllocateODEDataForThread(0); + newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical); + + lock (_prims) + _prims.Add(newPrim); + } + newPrim.LocalID = localID; + return newPrim; + } + + /// + /// Make this prim subject to physics. + /// + /// + internal void ActivatePrim(OdePrim prim) + { + // adds active prim.. (ones that should be iterated over in collisions_optimized + if (!_activeprims.Contains(prim)) + _activeprims.Add(prim); + //else + // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); + } + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, uint localid) + { +// m_log.DebugFormat("[ODE SCENE]: Adding physics prim {0} {1} to physics scene {2}", primName, localid, Name); + + return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); + } + public override float TimeDilation { get { return m_timeDilation; } @@ -1235,133 +1824,362 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override bool SupportsNINJAJoints { - get { return false; } + get { return m_NINJA_physics_joints_enabled; } } - #region Add/Remove Entities + // internal utility function: must be called within a lock (OdeLock) + private void InternalAddActiveJoint(PhysicsJoint joint) + { + activeJoints.Add(joint); + SOPName_to_activeJoint.Add(joint.ObjectNameInScene, joint); + } - public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) + // internal utility function: must be called within a lock (OdeLock) + private void InternalAddPendingJoint(OdePhysicsJoint joint) { - return null; + pendingJoints.Add(joint); + SOPName_to_pendingJoint.Add(joint.ObjectNameInScene, joint); } - public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying) + // internal utility function: must be called within a lock (OdeLock) + private void InternalRemovePendingJoint(PhysicsJoint joint) { - OdeCharacter newAv = new OdeCharacter(localID, avName, this, position, - size, feetOffset, avDensity, avMovementDivisorWalk, avMovementDivisorRun); - newAv.Flying = isFlying; - newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; - - return newAv; + pendingJoints.Remove(joint); + SOPName_to_pendingJoint.Remove(joint.ObjectNameInScene); + } + + // internal utility function: must be called within a lock (OdeLock) + private void InternalRemoveActiveJoint(PhysicsJoint joint) + { + activeJoints.Remove(joint); + SOPName_to_activeJoint.Remove(joint.ObjectNameInScene); } - public void AddCharacter(OdeCharacter chr) + public override void DumpJointInfo() { - lock (_characters) + string hdr = "[NINJA] JOINTINFO: "; + foreach (PhysicsJoint j in pendingJoints) + { + m_log.Debug(hdr + " pending joint, Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); + } + m_log.Debug(hdr + pendingJoints.Count + " total pending joints"); + foreach (string jointName in SOPName_to_pendingJoint.Keys) + { + m_log.Debug(hdr + " pending joints dict contains Name: " + jointName); + } + m_log.Debug(hdr + SOPName_to_pendingJoint.Keys.Count + " total pending joints dict entries"); + foreach (PhysicsJoint j in activeJoints) + { + m_log.Debug(hdr + " active joint, Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); + } + m_log.Debug(hdr + activeJoints.Count + " total active joints"); + foreach (string jointName in SOPName_to_activeJoint.Keys) + { + m_log.Debug(hdr + " active joints dict contains Name: " + jointName); + } + m_log.Debug(hdr + SOPName_to_activeJoint.Keys.Count + " total active joints dict entries"); + + m_log.Debug(hdr + " Per-body joint connectivity information follows."); + m_log.Debug(hdr + joints_connecting_actor.Keys.Count + " bodies are connected by joints."); + foreach (string actorName in joints_connecting_actor.Keys) { - if (!_characters.Contains(chr)) + m_log.Debug(hdr + " Actor " + actorName + " has the following joints connecting it"); + foreach (PhysicsJoint j in joints_connecting_actor[actorName]) { - _characters.Add(chr); - if (chr.bad) - m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); + m_log.Debug(hdr + " * joint Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); } + m_log.Debug(hdr + joints_connecting_actor[actorName].Count + " connecting joints total for this actor"); } } - public void RemoveCharacter(OdeCharacter chr) + public override void RequestJointDeletion(string ObjectNameInScene) { - lock (_characters) + lock (externalJointRequestsLock) { - if (_characters.Contains(chr)) + if (!requestedJointsToBeDeleted.Contains(ObjectNameInScene)) // forbid same deletion request from entering twice to prevent spurious deletions processed asynchronously { - _characters.Remove(chr); + requestedJointsToBeDeleted.Add(ObjectNameInScene); } } } - public void BadCharacter(OdeCharacter chr) + private void DeleteRequestedJoints() { - lock (_badCharacter) + List myRequestedJointsToBeDeleted; + lock (externalJointRequestsLock) { - if (!_badCharacter.Contains(chr)) - _badCharacter.Add(chr); + // make a local copy of the shared list for processing (threading issues) + myRequestedJointsToBeDeleted = new List(requestedJointsToBeDeleted); + } + + foreach (string jointName in myRequestedJointsToBeDeleted) + { + lock (OdeLock) + { + //m_log.Debug("[NINJA] trying to deleting requested joint " + jointName); + if (SOPName_to_activeJoint.ContainsKey(jointName) || SOPName_to_pendingJoint.ContainsKey(jointName)) + { + OdePhysicsJoint joint = null; + if (SOPName_to_activeJoint.ContainsKey(jointName)) + { + joint = SOPName_to_activeJoint[jointName] as OdePhysicsJoint; + InternalRemoveActiveJoint(joint); + } + else if (SOPName_to_pendingJoint.ContainsKey(jointName)) + { + joint = SOPName_to_pendingJoint[jointName] as OdePhysicsJoint; + InternalRemovePendingJoint(joint); + } + + if (joint != null) + { + //m_log.Debug("joint.BodyNames.Count is " + joint.BodyNames.Count + " and contents " + joint.BodyNames); + for (int iBodyName = 0; iBodyName < 2; iBodyName++) + { + string bodyName = joint.BodyNames[iBodyName]; + if (bodyName != "NULL") + { + joints_connecting_actor[bodyName].Remove(joint); + if (joints_connecting_actor[bodyName].Count == 0) + { + joints_connecting_actor.Remove(bodyName); + } + } + } + + DoJointDeactivated(joint); + if (joint.jointID != IntPtr.Zero) + { + d.JointDestroy(joint.jointID); + joint.jointID = IntPtr.Zero; + //DoJointErrorMessage(joint, "successfully destroyed joint " + jointName); + } + else + { + //m_log.Warn("[NINJA] Ignoring re-request to destroy joint " + jointName); + } + } + else + { + // DoJointErrorMessage(joint, "coult not find joint to destroy based on name " + jointName); + } + } + else + { + // DoJointErrorMessage(joint, "WARNING - joint removal failed, joint " + jointName); + } + } + } + + // remove processed joints from the shared list + lock (externalJointRequestsLock) + { + foreach (string jointName in myRequestedJointsToBeDeleted) + { + requestedJointsToBeDeleted.Remove(jointName); + } } } - public override void RemoveAvatar(PhysicsActor actor) + // for pending joints we don't know if their associated bodies exist yet or not. + // the joint is actually created during processing of the taints + private void CreateRequestedJoints() { - //m_log.Debug("[PHYSICS]:ODELOCK"); - lock (OdeLock) + List myRequestedJointsToBeCreated; + lock (externalJointRequestsLock) { - d.AllocateODEDataForThread(0); - ((OdeCharacter) actor).Destroy(); + // make a local copy of the shared list for processing (threading issues) + myRequestedJointsToBeCreated = new List(requestedJointsToBeCreated); } - } + foreach (PhysicsJoint joint in myRequestedJointsToBeCreated) + { + lock (OdeLock) + { + if (SOPName_to_pendingJoint.ContainsKey(joint.ObjectNameInScene) && SOPName_to_pendingJoint[joint.ObjectNameInScene] != null) + { + DoJointErrorMessage(joint, "WARNING: ignoring request to re-add already pending joint Name:" + joint.ObjectNameInScene + " type:" + joint.Type + " parms: " + joint.RawParams + " pos: " + joint.Position + " rot:" + joint.Rotation); + continue; + } + if (SOPName_to_activeJoint.ContainsKey(joint.ObjectNameInScene) && SOPName_to_activeJoint[joint.ObjectNameInScene] != null) + { + DoJointErrorMessage(joint, "WARNING: ignoring request to re-add already active joint Name:" + joint.ObjectNameInScene + " type:" + joint.Type + " parms: " + joint.RawParams + " pos: " + joint.Position + " rot:" + joint.Rotation); + continue; + } + + InternalAddPendingJoint(joint as OdePhysicsJoint); - public void addActivePrim(OdePrim activatePrim) - { - // adds active prim.. - lock (_activeprims) + if (joint.BodyNames.Count >= 2) + { + for (int iBodyName = 0; iBodyName < 2; iBodyName++) + { + string bodyName = joint.BodyNames[iBodyName]; + if (bodyName != "NULL") + { + if (!joints_connecting_actor.ContainsKey(bodyName)) + { + joints_connecting_actor.Add(bodyName, new List()); + } + joints_connecting_actor[bodyName].Add(joint); + } + } + } + } + } + + // remove processed joints from shared list + lock (externalJointRequestsLock) { - if (!_activeprims.Contains(activatePrim)) - _activeprims.Add(activatePrim); + foreach (PhysicsJoint joint in myRequestedJointsToBeCreated) + { + requestedJointsToBeCreated.Remove(joint); + } } } - public void addActiveGroups(OdePrim activatePrim) + /// + /// Add a request for joint creation. + /// + /// + /// this joint will just be added to a waiting list that is NOT processed during the main + /// Simulate() loop (to avoid deadlocks). After Simulate() is finished, we handle unprocessed joint requests. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override PhysicsJoint RequestJointCreation( + string objectNameInScene, PhysicsJointType jointType, Vector3 position, + Quaternion rotation, string parms, List bodyNames, string trackedBodyName, Quaternion localRotation) { - lock (_activegroups) + OdePhysicsJoint joint = new OdePhysicsJoint(); + joint.ObjectNameInScene = objectNameInScene; + joint.Type = jointType; + joint.Position = position; + joint.Rotation = rotation; + joint.RawParams = parms; + joint.BodyNames = new List(bodyNames); + joint.TrackedBodyName = trackedBodyName; + joint.LocalRotation = localRotation; + joint.jointID = IntPtr.Zero; + joint.ErrorMessageCount = 0; + + lock (externalJointRequestsLock) { - if (!_activegroups.Contains(activatePrim)) - _activegroups.Add(activatePrim); + if (!requestedJointsToBeCreated.Contains(joint)) // forbid same creation request from entering twice + { + requestedJointsToBeCreated.Add(joint); + } } + + return joint; } - private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, - PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID) + private void RemoveAllJointsConnectedToActor(PhysicsActor actor) { - OdePrim newPrim; - lock (OdeLock) + //m_log.Debug("RemoveAllJointsConnectedToActor: start"); + if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null) { - - newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID); + List jointsToRemove = new List(); + //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism) + foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName]) + { + jointsToRemove.Add(j); + } + foreach (PhysicsJoint j in jointsToRemove) + { + //m_log.Debug("RemoveAllJointsConnectedToActor: about to request deletion of " + j.ObjectNameInScene); + RequestJointDeletion(j.ObjectNameInScene); + //m_log.Debug("RemoveAllJointsConnectedToActor: done request deletion of " + j.ObjectNameInScene); + j.TrackedBodyName = null; // *IMMEDIATELY* prevent any further movement of this joint (else a deleted actor might cause spurious tracking motion of the joint for a few frames, leading to the joint proxy object disappearing) + } } - return newPrim; } - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid) + public override void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor) { - return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid); + //m_log.Debug("RemoveAllJointsConnectedToActorThreadLocked: start"); + lock (OdeLock) + { + //m_log.Debug("RemoveAllJointsConnectedToActorThreadLocked: got lock"); + RemoveAllJointsConnectedToActor(actor); + } } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, uint localid) + // normally called from within OnJointMoved, which is called from within a lock (OdeLock) + public override Vector3 GetJointAnchor(PhysicsJoint joint) { - return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid); - } + Debug.Assert(joint.IsInPhysicsEngine); + d.Vector3 pos = new d.Vector3(); - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid) - { - return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid); + if (!(joint is OdePhysicsJoint)) + { + DoJointErrorMessage(joint, "warning: non-ODE joint requesting anchor: " + joint.ObjectNameInScene); + } + else + { + OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint; + switch (odeJoint.Type) + { + case PhysicsJointType.Ball: + d.JointGetBallAnchor(odeJoint.jointID, out pos); + break; + case PhysicsJointType.Hinge: + d.JointGetHingeAnchor(odeJoint.jointID, out pos); + break; + } + } + return new Vector3(pos.X, pos.Y, pos.Z); } - public void remActivePrim(OdePrim deactivatePrim) + /// + /// Get joint axis. + /// + /// + /// normally called from within OnJointMoved, which is called from within a lock (OdeLock) + /// WARNING: ODE sometimes returns <0,0,0> as the joint axis! Therefore this function + /// appears to be unreliable. Fortunately we can compute the joint axis ourselves by + /// keeping track of the joint's original orientation relative to one of the involved bodies. + /// + /// + /// + public override Vector3 GetJointAxis(PhysicsJoint joint) { - lock (_activeprims) + Debug.Assert(joint.IsInPhysicsEngine); + d.Vector3 axis = new d.Vector3(); + + if (!(joint is OdePhysicsJoint)) { - _activeprims.Remove(deactivatePrim); + DoJointErrorMessage(joint, "warning: non-ODE joint requesting anchor: " + joint.ObjectNameInScene); } - } - public void remActiveGroup(OdePrim deactivatePrim) - { - lock (_activegroups) + else { - _activegroups.Remove(deactivatePrim); + OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint; + switch (odeJoint.Type) + { + case PhysicsJointType.Ball: + DoJointErrorMessage(joint, "warning - axis requested for ball joint: " + joint.ObjectNameInScene); + break; + case PhysicsJointType.Hinge: + d.JointGetHingeAxis(odeJoint.jointID, out axis); + break; + } } + return new Vector3(axis.X, axis.Y, axis.Z); + } + + /// + /// Stop this prim being subject to physics + /// + /// + internal void DeactivatePrim(OdePrim prim) + { + _activeprims.Remove(prim); } public override void RemovePrim(PhysicsActor prim) @@ -1370,200 +2188,434 @@ namespace OpenSim.Region.PhysicsModule.ubOde // removed in the next physics simulate pass. if (prim is OdePrim) { -// lock (OdeLock) + lock (OdeLock) { - - OdePrim p = (OdePrim)prim; + OdePrim p = (OdePrim) prim; + p.setPrimForRemoval(); + AddPhysicsActorTaint(prim); } } } - public void RemovePrimThreadLocked(OdePrim prim) + /// + /// This is called from within simulate but outside the locked portion + /// We need to do our own locking here + /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in + /// Simulate() -- justincc). + /// + /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. + /// + /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory + /// that the space was using. + /// + /// + internal void RemovePrimThreadLocked(OdePrim prim) { - //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); +// m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID); + lock (prim) { -// RemoveCollisionEventReporting(prim); - lock (_prims) - _prims.Remove(prim.LocalID); - } + RemoveCollisionEventReporting(prim); - } + if (prim.prim_geom != IntPtr.Zero) + { + prim.ResetTaints(); - public void addToPrims(OdePrim prim) - { - lock (_prims) - _prims[prim.LocalID] = prim; + if (prim.IsPhysical) + { + prim.disableBody(); + if (prim.childPrim) + { + prim.childPrim = false; + prim.Body = IntPtr.Zero; + prim.m_disabled = true; + prim.IsPhysical = false; + } + + + } + prim.m_targetSpace = IntPtr.Zero; + if (!prim.RemoveGeom()) + m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); + + lock (_prims) + _prims.Remove(prim); + + + if (SupportsNINJAJoints) + RemoveAllJointsConnectedToActorThreadLocked(prim); + } + } } - public OdePrim getPrim(uint id) + #endregion + + #region Space Separation Calculation + + /// + /// Takes a space pointer and zeros out the array we're using to hold the spaces + /// + /// + private void resetSpaceArrayItemToZero(IntPtr pSpace) { - lock (_prims) + for (int x = 0; x < staticPrimspace.GetLength(0); x++) { - if(_prims.ContainsKey(id)) - return _prims[id]; - else - return null; + for (int y = 0; y < staticPrimspace.GetLength(1); y++) + { + if (staticPrimspace[x, y] == pSpace) + staticPrimspace[x, y] = IntPtr.Zero; + } } } - public bool havePrim(OdePrim prm) - { - lock (_prims) - return _prims.ContainsKey(prm.LocalID); - } +// private void resetSpaceArrayItemToZero(int arrayitemX, int arrayitemY) +// { +// staticPrimspace[arrayitemX, arrayitemY] = IntPtr.Zero; +// } - public void changePrimID(OdePrim prim,uint oldID) + /// + /// Called when a static prim moves. Allocates a space for the prim based on its position + /// + /// the pointer to the geom that moved + /// the position that the geom moved to + /// a pointer to the space it was in before it was moved. + /// a pointer to the new space it's in + internal IntPtr recalculateSpaceForGeom(IntPtr geom, Vector3 pos, IntPtr currentspace) { - lock (_prims) + // Called from setting the Position and Size of an ODEPrim so + // it's already in locked space. + + // we don't want to remove the main space + // we don't need to test physical here because this function should + // never be called if the prim is physical(active) + + // All physical prim end up in the root space + //Thread.Sleep(20); + if (currentspace != space) { - if(_prims.ContainsKey(oldID)) - _prims.Remove(oldID); - _prims[prim.LocalID] = prim; + //m_log.Info("[SPACE]: C:" + currentspace.ToString() + " g:" + geom.ToString()); + //if (currentspace == IntPtr.Zero) + //{ + //int adfadf = 0; + //} + if (d.SpaceQuery(currentspace, geom) && currentspace != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { +// waitForSpaceUnlock(currentspace); + d.SpaceRemove(currentspace, geom); + } + else + { + m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + currentspace + + " Geom:" + geom); + } + } + else + { + IntPtr sGeomIsIn = d.GeomGetSpace(geom); + if (sGeomIsIn != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { +// waitForSpaceUnlock(sGeomIsIn); + d.SpaceRemove(sGeomIsIn, geom); + } + else + { + m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + + sGeomIsIn + " Geom:" + geom); + } + } + } + + //If there are no more geometries in the sub-space, we don't need it in the main space anymore + if (d.SpaceGetNumGeoms(currentspace) == 0) + { + if (currentspace != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { + d.SpaceRemove(space, currentspace); + // free up memory used by the space. + + resetSpaceArrayItemToZero(currentspace); + } + else + { + m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + + currentspace + " Geom:" + geom); + } + } + } } - } - - public bool haveActor(PhysicsActor actor) - { - if (actor is OdePrim) + else { - lock (_prims) - return _prims.ContainsKey(((OdePrim)actor).LocalID); + // this is a physical object that got disabled. ;.; + if (currentspace != IntPtr.Zero && geom != IntPtr.Zero) + { + if (d.SpaceQuery(currentspace, geom)) + { + if (d.GeomIsSpace(currentspace)) + { +// waitForSpaceUnlock(currentspace); + d.SpaceRemove(currentspace, geom); + } + else + { + m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + + currentspace + " Geom:" + geom); + } + } + else + { + IntPtr sGeomIsIn = d.GeomGetSpace(geom); + if (sGeomIsIn != IntPtr.Zero) + { + if (d.GeomIsSpace(sGeomIsIn)) + { +// waitForSpaceUnlock(sGeomIsIn); + d.SpaceRemove(sGeomIsIn, geom); + } + else + { + m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + + sGeomIsIn + " Geom:" + geom); + } + } + } + } } - else if (actor is OdeCharacter) + + // The routines in the Position and Size sections do the 'inserting' into the space, + // so all we have to do is make sure that the space that we're putting the prim into + // is in the 'main' space. + int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos); + IntPtr newspace = calculateSpaceForGeom(pos); + + if (newspace == IntPtr.Zero) { - lock (_characters) - return _characters.Contains((OdeCharacter)actor); + newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); + d.HashSpaceSetLevels(newspace, HashspaceLow, HashspaceHigh); } - return false; + + return newspace; } - #endregion + /// + /// Creates a new space at X Y + /// + /// + /// + /// A pointer to the created space + internal IntPtr createprimspace(int iprimspaceArrItemX, int iprimspaceArrItemY) + { + // creating a new space for prim and inserting it into main space. + staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); + d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); +// waitForSpaceUnlock(space); + d.SpaceSetSublevel(space, 1); + d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); + + return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; + } - #region Space Separation Calculation + /// + /// Calculates the space the prim should be in by its position + /// + /// + /// a pointer to the space. This could be a new space or reused space. + internal IntPtr calculateSpaceForGeom(Vector3 pos) + { + int[] xyspace = calculateSpaceArrayItemFromPos(pos); + //m_log.Info("[Physics]: Attempting to use arrayItem: " + xyspace[0].ToString() + "," + xyspace[1].ToString()); + return staticPrimspace[xyspace[0], xyspace[1]]; + } /// - /// Called when a static prim moves or becomes static - /// Places the prim in a space one the static sub-spaces grid + /// Holds the space allocation logic /// - /// the pointer to the geom that moved - /// the position that the geom moved to - /// a pointer to the space it was in before it was moved. - /// a pointer to the new space it's in - public IntPtr MoveGeomToStaticSpace(IntPtr geom, Vector3 pos, IntPtr currentspace) + /// + /// an array item based on the position + internal int[] calculateSpaceArrayItemFromPos(Vector3 pos) { - // moves a prim into another static sub-space or from another space into a static sub-space + int[] returnint = new int[2]; - // Called ODEPrim so - // it's already in locked space. + returnint[0] = (int) (pos.X * spacesPerMeterX); + + if (returnint[0] > spaceGridMaxX) + returnint[0] = spaceGridMaxX; + if (returnint[0] < 0) + returnint[0] = 0; + + returnint[1] = (int)(pos.Y * spacesPerMeterY); + if (returnint[1] > spaceGridMaxY) + returnint[1] = spaceGridMaxY; + if (returnint[1] < 0) + returnint[1] = 0; + + return returnint; + } + + #endregion - if (geom == IntPtr.Zero) // shouldn't happen - return IntPtr.Zero; + /// + /// Routine to figure out if we need to mesh this prim with our mesher + /// + /// + /// + internal bool needsMeshing(PrimitiveBaseShape pbs) + { + // most of this is redundant now as the mesher will return null if it cant mesh a prim + // but we still need to check for sculptie meshing being enabled so this is the most + // convenient place to do it for now... - // get the static sub-space for current position - IntPtr newspace = calculateSpaceForGeom(pos); + // //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f) + // //m_log.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString()); + int iPropertiesNotSupportedDefault = 0; - if (newspace == currentspace) // if we are there all done - return newspace; + if (pbs.SculptEntry && !meshSculptedPrim) + { +#if SPAM + m_log.Warn("NonMesh"); +#endif + return false; + } - // else remove it from its current space - if (currentspace != IntPtr.Zero && d.SpaceQuery(currentspace, geom)) + // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim + if (!forceSimplePrimMeshing && !pbs.SculptEntry) { - if (d.GeomIsSpace(currentspace)) + if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) + || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 + && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) { - waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); - if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) + if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 + && pbs.ProfileHollow == 0 + && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 + && pbs.PathBegin == 0 && pbs.PathEnd == 0 + && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 + && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 + && pbs.PathShearX == 0 && pbs.PathShearY == 0) { - d.SpaceDestroy(currentspace); +#if SPAM + m_log.Warn("NonMesh"); +#endif + return false; } } - else - { - m_log.Info("[Physics]: Invalid or empty Space passed to 'MoveGeomToStaticSpace':" + currentspace + - " Geom:" + geom); - } } - else // odd currentspace is null or doesn't contain the geom? lets try the geom ideia of current space - { - currentspace = d.GeomGetSpace(geom); - if (currentspace != IntPtr.Zero) - { - if (d.GeomIsSpace(currentspace)) - { - waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); - if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) - { - d.SpaceDestroy(currentspace); - } + if (pbs.ProfileHollow != 0) + iPropertiesNotSupportedDefault++; - } - } - } + if ((pbs.PathBegin != 0) || pbs.PathEnd != 0) + iPropertiesNotSupportedDefault++; - // put the geom in the newspace - waitForSpaceUnlock(newspace); - d.SpaceAdd(newspace, geom); + if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) + iPropertiesNotSupportedDefault++; - // let caller know this newspace - return newspace; - } + if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) + iPropertiesNotSupportedDefault++; - /// - /// Calculates the space the prim should be in by its position - /// - /// - /// a pointer to the space. This could be a new space or reused space. - public IntPtr calculateSpaceForGeom(Vector3 pos) - { - int x, y; + if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) + iPropertiesNotSupportedDefault++; - if (pos.X < 0) - return staticPrimspaceOffRegion[0]; + if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) + iPropertiesNotSupportedDefault++; - if (pos.Y < 0) - return staticPrimspaceOffRegion[2]; + if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) + iPropertiesNotSupportedDefault++; - x = (int)(pos.X * spacesPerMeterX); - if (x > spaceGridMaxX) - return staticPrimspaceOffRegion[1]; - - y = (int)(pos.Y * spacesPerMeterY); - if (y > spaceGridMaxY) - return staticPrimspaceOffRegion[3]; + if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) + iPropertiesNotSupportedDefault++; - return staticPrimspace[x, y]; - } - - #endregion + if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1) + iPropertiesNotSupportedDefault++; + + // test for torus + if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square) + { + if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + { + if (pbs.PathCurve == (byte)Extrusion.Straight) + { + iPropertiesNotSupportedDefault++; + } + // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits + else if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + { + if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + { + if (pbs.PathCurve == (byte)Extrusion.Straight) + { + iPropertiesNotSupportedDefault++; + } + else if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } - /// - /// Called to queue a change to a actor - /// to use in place of old taint mechanism so changes do have a time sequence - /// + if (pbs.SculptEntry && meshSculptedPrim) + iPropertiesNotSupportedDefault++; - public void AddChange(PhysicsActor actor, changes what, Object arg) - { - ODEchangeitem item = new ODEchangeitem(); - item.actor = actor; - item.what = what; - item.arg = arg; - ChangesQueue.Enqueue(item); + if (iPropertiesNotSupportedDefault == 0) + { +#if SPAM + m_log.Warn("NonMesh"); +#endif + return false; + } +#if SPAM + m_log.Debug("Mesh"); +#endif + return true; } /// /// Called after our prim properties are set Scale, position etc. + /// + /// /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex /// This assures us that we have no race conditions - /// - /// - public override void AddPhysicsActorTaint(PhysicsActor prim) + /// + /// + public override void AddPhysicsActorTaint(PhysicsActor actor) { + if (actor is OdePrim) + { + OdePrim taintedprim = ((OdePrim)actor); + lock (_taintedPrims) + _taintedPrims.Add(taintedprim); + } + else if (actor is OdeCharacter) + { + OdeCharacter taintedchar = ((OdeCharacter)actor); + lock (_taintedActors) + { + _taintedActors.Add(taintedchar); + if (taintedchar.bad) + m_log.ErrorFormat("[ODE SCENE]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); + } + } } // does all pending changes generated during region load process @@ -1573,315 +2625,319 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (world == IntPtr.Zero) { - ChangesQueue.Clear(); + _taintedPrims.Clear();; return; } - d.AllocateODEDataForThread(~0U); - - ODEchangeitem item; - int donechanges = 0; - if (ChangesQueue.Count > 0) + if (_taintedPrims.Count > 0) { - m_log.InfoFormat("[ubOde] start processing pending actor operations"); + + m_log.InfoFormat("[Ode] start processing pending actor operations"); int tstart = Util.EnvironmentTickCount(); - while (ChangesQueue.Dequeue(out item)) + d.AllocateODEDataForThread(0); + + lock (_taintedPrims) { - if (item.actor != null) + foreach (OdePrim prim in _taintedPrims) { - try - { - if (item.actor is OdeCharacter) - ((OdeCharacter)item.actor).DoAChange(item.what, item.arg); - else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) - RemovePrimThreadLocked((OdePrim)item.actor); - } - catch - { - m_log.WarnFormat("[PHYSICS]: Operation failed for a actor {0} {1}", - item.actor.Name, item.what.ToString()); - } + if (prim.m_taintremove) + RemovePrimThreadLocked(prim); + else + prim.ProcessTaints(); + + prim.m_collisionscore = 0; + donechanges++; } - donechanges++; + _taintedPrims.Clear(); } + int time = Util.EnvironmentTickCountSubtract(tstart); - m_log.InfoFormat("[ubOde] finished {0} operations in {1}ms", donechanges, time); + m_log.InfoFormat("[Ode] finished {0} operations in {1}ms", donechanges, time); } - m_log.InfoFormat("[ubOde] {0} prim actors loaded",_prims.Count); + m_log.InfoFormat("[Ode] {0} prim actors loaded",_prims.Count); } } + /// /// This is our main simulate loop + /// + /// /// It's thread locked by a Mutex in the scene. /// It holds Collisions, it instructs ODE to step through the physical reactions /// It moves the objects around in memory /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) - /// + /// /// - /// - public override float Simulate(float reqTimeStep) + /// The number of frames simulated over that period. + public override float Simulate(float timeStep) { - DateTime now = DateTime.UtcNow; - TimeSpan timedif = now - m_lastframe; - float timeStep = (float)timedif.TotalSeconds; - m_lastframe = now; - - // acumulate time so we can reduce error - step_time += timeStep; + if (!_worldInitialized) + return 1.0f; - if (step_time < HalfOdeStep) - return 0; + int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; + int tempTick = 0, tempTick2 = 0; - if (framecount < 0) + if (framecount >= int.MaxValue) framecount = 0; framecount++; -// checkThread(); - int nodeframes = 0; float fps = 0; - lock (SimulationLock) - lock(OdeLock) + step_time += timeStep; + + float HalfOdeStep = ODE_STEPSIZE * 0.5f; + if (step_time < HalfOdeStep) + return 0; + + + // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential + // deadlock if the collision event tries to lock something else later on which is already locked by a + // caller that is adding or removing the collision event. + lock (m_collisionEventActorsChanges) { - if (world == IntPtr.Zero) + foreach (KeyValuePair kvp in m_collisionEventActorsChanges) { - ChangesQueue.Clear(); - return 0; + if (kvp.Value == null) + m_collisionEventActors.Remove(kvp.Key); + else + m_collisionEventActors[kvp.Key] = kvp.Value; } - ODEchangeitem item; - -// d.WorldSetQuickStepNumIterations(world, curphysiteractions); - - int loopstartMS = Util.EnvironmentTickCount(); - int looptimeMS = 0; - int changestimeMS = 0; - int maxChangestime = (int)(reqTimeStep * 500f); // half the time - int maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time - + m_collisionEventActorsChanges.Clear(); + } + + if (SupportsNINJAJoints) + { + DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks + CreateRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks + } + + + lock (OdeLock) + { d.AllocateODEDataForThread(~0U); - - if (ChangesQueue.Count > 0) - { - while (ChangesQueue.Dequeue(out item)) - { - if (item.actor != null) - { - try - { - if (item.actor is OdeCharacter) - ((OdeCharacter)item.actor).DoAChange(item.what, item.arg); - else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) - RemovePrimThreadLocked((OdePrim)item.actor); - } - catch - { - m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}", - item.actor.Name, item.what.ToString()); - } - } - changestimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); - if (changestimeMS > maxChangestime) - break; - } - } - // do simulation taking at most 150ms total time including changes - while (step_time > HalfOdeStep) + while (step_time > HalfOdeStep) { try { - // clear pointer/counter to contacts to pass into joints - m_global_contactcount = 0; + if (CollectStats) + tempTick = Util.EnvironmentTickCount(); + lock (_taintedActors) + { + foreach (OdeCharacter character in _taintedActors) + character.ProcessTaints(); - // Move characters - lock (_characters) + _taintedActors.Clear(); + } + + if (CollectStats) { - List defects = new List(); - foreach (OdeCharacter actor in _characters) - { - if (actor != null) - actor.Move(defects); - } - if (defects.Count != 0) + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEAvatarTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + + lock (_taintedPrims) + { + foreach (OdePrim prim in _taintedPrims) { - foreach (OdeCharacter defect in defects) + if (prim.m_taintremove) + { +// Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name); + RemovePrimThreadLocked(prim); + } + else { - RemoveCharacter(defect); +// Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name); + prim.ProcessTaints(); } - defects.Clear(); + + prim.m_collisionscore = 0; + + // This loop can block up the Heartbeat for a very long time on large regions. + // We need to let the Watchdog know that the Heartbeat is not dead + // NOTE: This is currently commented out, but if things like OAR loading are + // timing the heartbeat out we will need to uncomment it + //Watchdog.UpdateThread(); } + + if (SupportsNINJAJoints) + SimulatePendingNINJAJoints(); + + _taintedPrims.Clear(); } - // Move other active objects - lock (_activegroups) + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEPrimTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + + // Move characters + foreach (OdeCharacter actor in _characters) + actor.Move(defects); + + if (defects.Count != 0) { - foreach (OdePrim aprim in _activegroups) + foreach (OdeCharacter actor in defects) { - aprim.Move(); + m_log.ErrorFormat( + "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when moving", + actor.Name, actor.LocalID, PhysicsSceneName); + + RemoveCharacter(actor); + actor.DestroyOdeStructures(); } + + defects.Clear(); + } + + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEAvatarForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + + // Move other active objects + foreach (OdePrim prim in _activeprims) + { + prim.m_collisionscore = 0; + prim.Move(timeStep); + } + + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEPrimForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; } - + m_rayCastManager.ProcessQueuedRequests(); + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODERaycastingFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + collision_optimized(); - List sleepers = new List(); - foreach (PhysicsActor obj in _collisionEventPrim) + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEOtherCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; + } + + foreach (PhysicsActor obj in m_collisionEventActors.Values) { - if (obj == null) - continue; + // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); switch ((ActorTypes)obj.PhysicsActorType) { case ActorTypes.Agent: OdeCharacter cobj = (OdeCharacter)obj; - cobj.SendCollisions((int)(odetimestepMS)); + cobj.AddCollisionFrameTime(100); + cobj.SendCollisions(); break; case ActorTypes.Prim: OdePrim pobj = (OdePrim)obj; - if (!pobj.m_outbounds) - { - pobj.SendCollisions((int)(odetimestepMS)); - if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected && - !pobj.m_disabled && !pobj.m_building && - !d.BodyIsEnabled(pobj.Body)) - sleepers.Add(pobj); - } + pobj.SendCollisions(); break; } } - foreach(OdePrim prm in sleepers) - prm.SleeperAddCollisionEvents(); - sleepers.Clear(); +// if (m_global_contactcount > 0) +// m_log.DebugFormat( +// "[PHYSICS]: Collision contacts to process this frame = {0}", m_global_contactcount); - lock(_collisionEventPrimRemove) - { - foreach (PhysicsActor obj in _collisionEventPrimRemove) - _collisionEventPrim.Remove(obj); + m_global_contactcount = 0; - _collisionEventPrimRemove.Clear(); + if (CollectStats) + { + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; } - // do a ode simulation step - d.WorldQuickStep(world, ODE_STEPSIZE); - d.JointGroupEmpty(contactgroup); - - // update managed ideia of physical data and do updates to core - /* - lock (_characters) - { - foreach (OdeCharacter actor in _characters) - { - if (actor != null) - { - if (actor.bad) - m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); + lock(SimulationLock) + d.WorldQuickStep(world, ODE_STEPSIZE); - actor.UpdatePositionAndVelocity(); - } - } - } - */ + if (CollectStats) + m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); - lock (_activegroups) - { - { - foreach (OdePrim actor in _activegroups) - { - if (actor.IsPhysical) - { - actor.UpdatePositionAndVelocity(framecount); - } - } - } - } + d.JointGroupEmpty(contactgroup); } catch (Exception e) { - m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); -// ode.dunlock(world); + m_log.ErrorFormat("[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e); } step_time -= ODE_STEPSIZE; - nodeframes++; + fps += ODE_STEPSIZE; + } - looptimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); - if (looptimeMS > maxLoopTime) - break; + if (CollectStats) + tempTick = Util.EnvironmentTickCount(); + + foreach (OdeCharacter actor in _characters) + { + if (actor.bad) + m_log.ErrorFormat("[ODE SCENE]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); + + actor.UpdatePositionAndVelocity(defects); } - lock (_badCharacter) + if (defects.Count != 0) { - if (_badCharacter.Count > 0) + foreach (OdeCharacter actor in defects) { - foreach (OdeCharacter chr in _badCharacter) - { - RemoveCharacter(chr); - } + m_log.ErrorFormat( + "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when updating position and velocity", + actor.Name, actor.LocalID, PhysicsSceneName); - _badCharacter.Clear(); + RemoveCharacter(actor); + actor.DestroyOdeStructures(); } - } - timedif = now - m_lastMeshExpire; + defects.Clear(); + } - if (timedif.Seconds > 10) + if (CollectStats) { - mesher.ExpireReleaseMeshs(); - m_lastMeshExpire = now; + tempTick2 = Util.EnvironmentTickCount(); + m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick); + tempTick = tempTick2; } -// information block for in debug breakpoint only -/* - int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); - int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); - int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace); - - int nactivegeoms = 0; - int nactivespaces = 0; - - int nstaticgeoms = 0; - int nstaticspaces = 0; - IntPtr sp; + //if (timeStep < 0.2f) - for (int i = 0; i < ntopactivegeoms; i++) + foreach (OdePrim prim in _activeprims) { - sp = d.SpaceGetGeom(ActiveSpace, i); - if (d.GeomIsSpace(sp)) + if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag)) { - nactivespaces++; - nactivegeoms += d.SpaceGetNumGeoms(sp); - } - else - nactivegeoms++; - } + prim.UpdatePositionAndVelocity(); - for (int i = 0; i < ntopstaticgeoms; i++) - { - sp = d.SpaceGetGeom(StaticSpace, i); - if (d.GeomIsSpace(sp)) - { - nstaticspaces++; - nstaticgeoms += d.SpaceGetNumGeoms(sp); + if (SupportsNINJAJoints) + SimulateActorPendingJoints(prim); } - else - nstaticgeoms++; } - int ntopgeoms = d.SpaceGetNumGeoms(TopSpace); + if (CollectStats) + m_stats[ODEPrimUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); + + //DumpJointInfo(); - int totgeoms = nstaticgeoms + nactivegeoms + ngroundgeoms + 1; // one ray - int nbodies = d.NTotalBodies; - int ngeoms = d.NTotalGeoms; -*/ // Finished with all sim stepping. If requested, dump world state to file for debugging. // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? @@ -1900,303 +2956,291 @@ namespace OpenSim.Region.PhysicsModule.ubOde d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } - - fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep; - - if(step_time < HalfOdeStep) - m_timeDilation = 1.0f; - else if (step_time > m_SkipFramesAtms) - { - // if we lag too much skip frames - m_timeDilation = 0.0f; - step_time = 0; - m_lastframe = DateTime.UtcNow; // skip also the time lost - } - else - { - m_timeDilation = ODE_STEPSIZE / step_time; - if (m_timeDilation > 1) - m_timeDilation = 1; - } - } - - return fps; - } - - /// - public override void GetResults() - { - } - - public override bool IsThreaded - { - // for now we won't be multithreaded - get { return (false); } - } - - public float GetTerrainHeightAtXY(float x, float y) - { - if (TerrainGeom == IntPtr.Zero) - return 0f; - - if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) - return 0f; - // TerrainHeightField for ODE as offset 1m - x += 1f; - y += 1f; + latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun); - // make position fit into array - if (x < 0) - x = 0; - if (y < 0) - y = 0; + // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics + // has a max of 100 ms to run theoretically. + // If the main loop stalls, it calls Simulate later which makes the tick count ms larger. + // If Physics stalls, it takes longer which makes the tick count ms larger. - // integer indexs - int ix; - int iy; - // interpolators offset - float dx; - float dy; - - int regsizeX = (int)m_regionWidth + 3; // map size see setterrain number of samples - int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples - int regsize = regsizeX; - - if (m_OSOdeLib) - { - if (x < regsizeX - 1) - { - ix = (int)x; - dx = x - (float)ix; - } - else // out world use external height - { - ix = regsizeX - 2; - dx = 0; - } - if (y < regsizeY - 1) + if (latertickcount < 100) { - iy = (int)y; - dy = y - (float)iy; + m_timeDilation = 1.0f; } else { - iy = regsizeY - 2; - dy = 0; + m_timeDilation = 100f / latertickcount; + //m_timeDilation = Math.Min((Math.Max(100 - (Util.EnvironmentTickCount() - tickCountFrameRun), 1) / 100f), 1.0f); } - } - else - { - // we still have square fixed size regions - // also flip x and y because of how map is done for ODE fliped axis - // so ix,iy,dx and dy are inter exchanged - regsize = regsizeY; + tickCountFrameRun = Util.EnvironmentTickCount(); - if (x < regsizeX - 1) - { - iy = (int)x; - dy = x - (float)iy; - } - else // out world use external height - { - iy = regsizeX - 2; - dy = 0; - } - if (y < regsizeY - 1) - { - ix = (int)y; - dx = y - (float)ix; - } - else - { - ix = regsizeY - 2; - dx = 0; - } + if (CollectStats) + m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick); } - float h0; - float h1; - float h2; + fps *= 1.0f/timeStep; + return fps; + } - iy *= regsize; - iy += ix; // all indexes have iy + ix + /// + /// Simulate pending NINJA joints. + /// + /// + /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else. + /// + private void SimulatePendingNINJAJoints() + { + // Create pending joints, if possible + + // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating + // a joint requires specifying the body id of both involved bodies + if (pendingJoints.Count > 0) + { + List successfullyProcessedPendingJoints = new List(); + //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); + foreach (PhysicsJoint joint in pendingJoints) + { + //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); + string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + List jointBodies = new List(); + bool allJointBodiesAreReady = true; + foreach (string jointParam in jointParams) + { + if (jointParam == "NULL") + { + //DoJointErrorMessage(joint, "attaching NULL joint to world"); + jointBodies.Add(IntPtr.Zero); + } + else + { + //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); + bool foundPrim = false; + lock (_prims) + { + foreach (OdePrim prim in _prims) // FIXME: inefficient + { + if (prim.SOPName == jointParam) + { + //DoJointErrorMessage(joint, "found for prim name: " + jointParam); + if (prim.IsPhysical && prim.Body != IntPtr.Zero) + { + jointBodies.Add(prim.Body); + foundPrim = true; + break; + } + else + { + DoJointErrorMessage(joint, "prim name " + jointParam + + " exists but is not (yet) physical; deferring joint creation. " + + "IsPhysical property is " + prim.IsPhysical + + " and body is " + prim.Body); + foundPrim = false; + break; + } + } + } + } + if (foundPrim) + { + // all is fine + } + else + { + allJointBodiesAreReady = false; + break; + } + } + } - float[] heights = TerrainHeightFieldHeight; - /* - if ((dx + dy) <= 1.0f) + if (allJointBodiesAreReady) + { + //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); + if (jointBodies[0] == jointBodies[1]) { - h0 = ((float)heights[iy]); // 0,0 vertice - h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 - h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 + DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); } else { - h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice - h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 - h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 + switch (joint.Type) + { + case PhysicsJointType.Ball: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating ball joint "); + odeJoint = d.JointCreateBall(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetBallAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + //DoJointErrorMessage(joint, "ODE joint setting OK"); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); + //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); + //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); + + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + case PhysicsJointType.Hinge: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating hinge joint "); + odeJoint = d.JointCreateHinge(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetHingeAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + // We use the orientation of the x-axis of the joint's coordinate frame + // as the axis for the hinge. + + // Therefore, we must get the joint's coordinate frame based on the + // joint.Rotation field, which originates from the orientation of the + // joint's proxy object in the scene. + + // The joint's coordinate frame is defined as the transformation matrix + // that converts a vector from joint-local coordinates into world coordinates. + // World coordinates are defined as the XYZ coordinate system of the sim, + // as shown in the top status-bar of the viewer. + + // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) + // and use that as the hinge axis. + + //joint.Rotation.Normalize(); + Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); + + // Now extract the X axis of the joint's coordinate frame. + + // Do not try to use proxyFrame.AtAxis or you will become mired in the + // tar pit of transposed, inverted, and generally messed-up orientations. + // (In other words, Matrix4.AtAxis() is borked.) + // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness + + // Instead, compute the X axis of the coordinate frame by transforming + // the (1,0,0) vector. At least that works. + + //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); + Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); + //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); + //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); + d.JointSetHingeAxis(odeJoint, + jointAxis.X, + jointAxis.Y, + jointAxis.Z); + //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + } + successfullyProcessedPendingJoints.Add(joint); } - */ - h0 = ((float)heights[iy]); // 0,0 vertice + } + else + { + DoJointErrorMessage(joint, "joint could not yet be created; still pending"); + } + } - if (dy>dx) - { - iy += regsize; - h2 = (float)heights[iy]; // 0,1 vertice - h1 = (h2 - h0) * dy; // 0,1 vertice minus 0,0 - h2 = ((float)heights[iy + 1] - h2) * dx; // 1,1 vertice minus 0,1 - } - else - { - iy++; - h2 = (float)heights[iy]; // vertice 1,0 - h1 = (h2 - h0) * dx; // 1,0 vertice minus 0,0 - h2 = (((float)heights[iy + regsize]) - h2) * dy; // 1,1 vertice minus 1,0 + foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) + { + //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); + //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); + InternalRemovePendingJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); + InternalAddActiveJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "done"); + } } - - return h0 + h1 + h2; } - public Vector3 GetTerrainNormalAtXY(float x, float y) + /// + /// Simulate the joint proxies of a NINJA actor. + /// + /// + /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there. + /// + /// + private void SimulateActorPendingJoints(OdePrim actor) { - Vector3 norm = new Vector3(0, 0, 1); - - if (TerrainGeom == IntPtr.Zero) - return norm; - - if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) - return norm; - - // TerrainHeightField for ODE as offset 1m - x += 1f; - y += 1f; - - // make position fit into array - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - // integer indexs - int ix; - int iy; - // interpolators offset - float dx; - float dy; - - int regsizeX = (int)m_regionWidth + 3; // map size see setterrain number of samples - int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples - int regsize = regsizeX; - - int xstep = 1; - int ystep = regsizeX; - bool firstTri = false; - - if (m_OSOdeLib) - { - if (x < regsizeX - 1) - { - ix = (int)x; - dx = x - (float)ix; - } - else // out world use external height - { - ix = regsizeX - 2; - dx = 0; - } - if (y < regsizeY - 1) - { - iy = (int)y; - dy = y - (float)iy; - } - else - { - iy = regsizeY - 2; - dy = 0; - } - firstTri = dy > dx; - } + // If an actor moved, move its joint proxy objects as well. + // There seems to be an event PhysicsActor.OnPositionUpdate that could be used + // for this purpose but it is never called! So we just do the joint + // movement code here. - else + if (actor.SOPName != null && + joints_connecting_actor.ContainsKey(actor.SOPName) && + joints_connecting_actor[actor.SOPName] != null && + joints_connecting_actor[actor.SOPName].Count > 0) { - xstep = regsizeY; - ystep = 1; - regsize = regsizeY; - - // we still have square fixed size regions - // also flip x and y because of how map is done for ODE fliped axis - // so ix,iy,dx and dy are inter exchanged - if (x < regsizeX - 1) - { - iy = (int)x; - dy = x - (float)iy; - } - else // out world use external height - { - iy = regsizeX - 2; - dy = 0; - } - if (y < regsizeY - 1) - { - ix = (int)y; - dx = y - (float)ix; - } - else + foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) { - ix = regsizeY - 2; - dx = 0; + if (affectedJoint.IsInPhysicsEngine) + { + DoJointMoved(affectedJoint); + } + else + { + DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); + } } - firstTri = dx > dy; } + } - float h0; - float h1; - float h2; - - iy *= regsize; - iy += ix; // all indexes have iy + ix + public override void GetResults() + { + } - float[] heights = TerrainHeightFieldHeight; + public override bool IsThreaded + { + // for now we won't be multithreaded + get { return false; } + } - if (firstTri) + public override void SetTerrain(float[] heightMap) + { + if (m_worldOffset != Vector3.Zero && m_parentScene != null) { - h1 = ((float)heights[iy]); // 0,0 vertice - iy += ystep; - h0 = (float)heights[iy]; // 0,1 - h2 = (float)heights[iy+xstep]; // 1,1 vertice - norm.X = h0 - h2; - norm.Y = h1 - h0; + if (m_parentScene is OdeScene) + { + ((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset); + } } else { - h2 = ((float)heights[iy]); // 0,0 vertice - iy += xstep; - h0 = ((float)heights[iy]); // 1,0 vertice - h1 = (float)heights[iy+ystep]; // vertice 1,1 - norm.X = h2 - h0; - norm.Y = h0 - h1; + SetTerrain(heightMap, m_worldOffset); } - norm.Z = 1; - norm.Normalize(); - return norm; - } - - public override void SetTerrain(float[] heightMap) - { - if (m_OSOdeLib) - OSSetTerrain(heightMap); - else - OriSetTerrain(heightMap); } - public void OriSetTerrain(float[] heightMap) + private void SetTerrain(float[] heightMap, Vector3 pOffset) { - // assumes 1m size grid and constante size square regions - // needs to know about sims around in future + int startTime = Util.EnvironmentTickCount(); + m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0} with offset {1}", PhysicsSceneName, pOffset); + float[] _heightmap; + // ok im lasy this are just a aliases uint regionsizeX = m_regionWidth; uint regionsizeY = m_regionHeight; @@ -2214,7 +3258,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde const float thickness = 10f; const int wrap = 0; - + float hfmin = float.MaxValue; float hfmax = float.MinValue; float val; @@ -2223,11 +3267,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde uint maxXX = regionsizeX - 1; uint maxYY = regionsizeY - 1; + // flipping map adding one margin all around so things don't fall in edges uint xt = 0; xx = 0; + for (uint x = 0; x < heightmapWidthSamples; x++) { if (x > 1 && xx < maxXX) @@ -2240,7 +3286,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde val = heightMap[yy + xx]; if (val < 0.0f) - val = 0.0f; // no neg terrain as in chode + val = 0.0f; _heightmap[xt + y] = val; if (hfmin > val) @@ -2255,164 +3301,69 @@ namespace OpenSim.Region.PhysicsModule.ubOde { d.AllocateODEDataForThread(~0U); - if (TerrainGeom != IntPtr.Zero) + IntPtr GroundGeom = IntPtr.Zero; + if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) { - actor_name_map.Remove(TerrainGeom); - d.GeomDestroy(TerrainGeom); + RegionTerrain.Remove(pOffset); + if (GroundGeom != IntPtr.Zero) + { + if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) + { + TerrainHeightFieldHeights.Remove(GroundGeom); + } + d.SpaceRemove(space, GroundGeom); + d.GeomDestroy(GroundGeom); + } } - - if (TerrainHeightFieldHeightsHandler.IsAllocated) - TerrainHeightFieldHeightsHandler.Free(); - IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); - - TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); - - d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, - heightmapHeight, heightmapWidth , - (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, - offset, thickness, wrap); + d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, + heightmapWidth, heightmapHeight, + (int)heightmapWidthSamples, + (int)heightmapHeightSamples, + scale, offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); - - TerrainGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1); - - if (TerrainGeom != IntPtr.Zero) + GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); + if (GroundGeom != IntPtr.Zero) { - d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); - d.GeomSetCollideBits(TerrainGeom, 0); + d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); + d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); - PhysicsActor pa = new NullPhysicsActor(); - pa.Name = "Terrain"; - pa.PhysicsActorType = (int)ActorTypes.Ground; - actor_name_map[TerrainGeom] = pa; - -// geom_name_map[GroundGeom] = "Terrain"; - - d.Quaternion q = new d.Quaternion(); - q.X = 0.5f; - q.Y = 0.5f; - q.Z = 0.5f; - q.W = 0.5f; - - d.GeomSetQuaternion(TerrainGeom, ref q); - d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); - TerrainHeightFieldHeight = _heightmap; } - else - TerrainHeightFieldHeightsHandler.Free(); - } - } - - public void OSSetTerrain(float[] heightMap) - { - // assumes 1m size grid and constante size square regions - // needs to know about sims around in future + geom_name_map[GroundGeom] = "Terrain"; - float[] _heightmap; - - uint regionsizeX = m_regionWidth; - uint regionsizeY = m_regionHeight; - - uint heightmapWidth = regionsizeX + 2; - uint heightmapHeight = regionsizeY + 2; - - uint heightmapWidthSamples = heightmapWidth + 1; - uint heightmapHeightSamples = heightmapHeight + 1; + d.Matrix3 R = new d.Matrix3(); - _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; - - - float hfmin = float.MaxValue; -// float hfmax = float.MinValue; - float val; - - - uint maxXX = regionsizeX - 1; - uint maxYY = regionsizeY - 1; - // adding one margin all around so things don't fall in edges + Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); + Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); - uint xx; - uint yy = 0; - uint yt = 0; + q1 = q1 * q2; + Vector3 v3; + float angle; + q1.GetAxisAngle(out v3, out angle); - for (uint y = 0; y < heightmapHeightSamples; y++) - { - if (y > 1 && y < maxYY) - yy += regionsizeX; - xx = 0; - for (uint x = 0; x < heightmapWidthSamples; x++) + d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); + d.GeomSetRotation(GroundGeom, ref R); + d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0.0f); + IntPtr testGround = IntPtr.Zero; + if (RegionTerrain.TryGetValue(pOffset, out testGround)) { - if (x > 1 && x < maxXX) - xx++; - - val = heightMap[yy + xx]; - if (val < 0.0f) - val = 0.0f; // no neg terrain as in chode - _heightmap[yt + x] = val; - - if (hfmin > val) - hfmin = val; -// if (hfmax < val) -// hfmax = val; + RegionTerrain.Remove(pOffset); } - yt += heightmapWidthSamples; + RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); + TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); } - lock (OdeLock) - { - if (TerrainGeom != IntPtr.Zero) - { - actor_name_map.Remove(TerrainGeom); - d.GeomDestroy(TerrainGeom); - } - - if (TerrainHeightFieldHeightsHandler.IsAllocated) - TerrainHeightFieldHeightsHandler.Free(); - - TerrainHeightFieldHeight = null; - - IntPtr HeightmapData = d.GeomOSTerrainDataCreate(); - - const int wrap = 0; - float thickness = hfmin; - if (thickness < 0) - thickness = 1; - - TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); - - d.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, - (int)heightmapWidthSamples, (int)heightmapHeightSamples, - thickness, wrap); - -// d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); - TerrainGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1); - if (TerrainGeom != IntPtr.Zero) - { - d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); - d.GeomSetCollideBits(TerrainGeom, 0); - - PhysicsActor pa = new NullPhysicsActor(); - pa.Name = "Terrain"; - pa.PhysicsActorType = (int)ActorTypes.Ground; - actor_name_map[TerrainGeom] = pa; - -// geom_name_map[GroundGeom] = "Terrain"; - - d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); - TerrainHeightFieldHeight = _heightmap; - } - else - TerrainHeightFieldHeightsHandler.Free(); - } + m_log.DebugFormat( + "[ODE SCENE]: Setting terrain for {0} took {1}ms", PhysicsSceneName, Util.EnvironmentTickCountSubtract(startTime)); } public override void DeleteTerrain() { } - public float GetWaterLevel() + internal float GetWaterLevel() { return waterlevel; } @@ -2422,18 +3373,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde waterlevel = baseheight; } + [HandleProcessCorruptedStateExceptions] public override void Dispose() { - lock (OdeLock) + lock(SimulationLock) + lock(OdeLock) { - - if (world == IntPtr.Zero) + if(world == IntPtr.Zero) return; - d.AllocateODEDataForThread(~0U); + _worldInitialized = false; - if (m_meshWorker != null) - m_meshWorker.Stop(); + d.AllocateODEDataForThread(~0U); if (m_rayCastManager != null) { @@ -2443,49 +3394,37 @@ namespace OpenSim.Region.PhysicsModule.ubOde lock (_prims) { - ChangesQueue.Clear(); - foreach (OdePrim prm in _prims.Values) + foreach (OdePrim prm in _prims) { - prm.DoAChange(changes.Remove, null); - _collisionEventPrim.Remove(prm); + RemovePrim(prm); } - _prims.Clear(); } - OdeCharacter[] chtorem; - lock (_characters) + //foreach (OdeCharacter act in _characters) + //{ + //RemoveAvatar(act); + //} + IntPtr GroundGeom = IntPtr.Zero; + if (RegionTerrain.TryGetValue(m_worldOffset, out GroundGeom)) { - chtorem = new OdeCharacter[_characters.Count]; - _characters.CopyTo(chtorem); - } - - ChangesQueue.Clear(); - foreach (OdeCharacter ch in chtorem) - ch.DoAChange(changes.Remove, null); - - if (TerrainGeom != IntPtr.Zero) - d.GeomDestroy(TerrainGeom); - TerrainGeom = IntPtr.Zero; - - if (TerrainHeightFieldHeightsHandler.IsAllocated) - TerrainHeightFieldHeightsHandler.Free(); - - TerrainHeightFieldHeight = null; + RegionTerrain.Remove(m_worldOffset); + if (GroundGeom != IntPtr.Zero) + { + if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) + TerrainHeightFieldHeights.Remove(GroundGeom); + d.GeomDestroy(GroundGeom); + } + } - if (ContactgeomsArray != IntPtr.Zero) + try { - Marshal.FreeHGlobal(ContactgeomsArray); - ContactgeomsArray = IntPtr.Zero; + d.WorldDestroy(world); + world = IntPtr.Zero; } - if (GlobalContactsArray != IntPtr.Zero) + catch (AccessViolationException e) { - Marshal.FreeHGlobal(GlobalContactsArray); - GlobalContactsArray = IntPtr.Zero; + m_log.ErrorFormat("[ODE SCENE]: exception {0}", e.Message); } - - d.WorldDestroy(world); - world = IntPtr.Zero; - //d.CloseODE(); } } @@ -2497,13 +3436,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override Dictionary GetTopColliders() { Dictionary topColliders; - List orderedPrims; - lock (_activeprims) - orderedPrims = new List(_activeprims); - orderedPrims.Sort(compareByCollisionsDesc); - topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); - + lock (_prims) + { + List orderedPrims = new List(_prims); + orderedPrims.Sort(compareByCollisionsDesc); + topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); + + foreach (OdePrim p in _prims) + p.CollisionScore = 0; + } + return topColliders; } @@ -2516,16 +3459,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (retMethod != null) { - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = 0; - req.filter = RayFilterFlags.AllPrims; - - m_rayCastManager.QueueRequest(req); + m_rayCastManager.QueueRequest(position, direction, length, retMethod); } } @@ -2533,260 +3467,75 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (retMethod != null) { - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = Count; - req.filter = RayFilterFlags.AllPrims; - - m_rayCastManager.QueueRequest(req); + m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); } } - public override List RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) { - List ourresults = new List(); - object SyncObject = new object(); - - RayCallback retMethod = delegate(List results) - { - lock (SyncObject) - { - ourresults = results; - Monitor.PulseAll(SyncObject); - } - }; - - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = Count; - req.filter = RayFilterFlags.AllPrims; - - lock (SyncObject) - { - m_rayCastManager.QueueRequest(req); - if (!Monitor.Wait(SyncObject, 500)) - return null; - else - return ourresults; - } - } - - public override bool SupportsRaycastWorldFiltered() - { - return true; - } - - public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) - { - object SyncObject = new object(); - List ourresults = new List(); - - RayCallback retMethod = delegate(List results) - { - lock (SyncObject) - { - ourresults = results; - Monitor.PulseAll(SyncObject); - } - }; - - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = Count; - req.filter = filter; - - lock (SyncObject) - { - m_rayCastManager.QueueRequest(req); - if (!Monitor.Wait(SyncObject, 500)) - return null; - else - return ourresults; - } - } - - public override List RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags) - { - if (actor == null) - return new List(); - - IntPtr geom; - if (actor is OdePrim) - geom = ((OdePrim)actor).prim_geom; - else if (actor is OdeCharacter) - geom = ((OdePrim)actor).prim_geom; - else - return new List(); - - if (geom == IntPtr.Zero) - return new List(); - - List ourResults = null; - object SyncObject = new object(); - + ContactResult[] ourResults = null; RayCallback retMethod = delegate(List results) { - lock (SyncObject) - { - ourResults = results; - Monitor.PulseAll(SyncObject); - } - }; - - ODERayRequest req = new ODERayRequest(); - req.actor = actor; - req.callbackMethod = retMethod; - req.length = length; - req.Normal = direction; - req.Origin = position; - req.Count = Count; - req.filter = flags; - - lock (SyncObject) - { - m_rayCastManager.QueueRequest(req); - if (!Monitor.Wait(SyncObject, 500)) - return new List(); - } - - if (ourResults == null) - return new List(); - return ourResults; - } - - public override List BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags) - { - List ourResults = null; - object SyncObject = new object(); - - ProbeBoxCallback retMethod = delegate(List results) - { - lock (SyncObject) - { - ourResults = results; - Monitor.PulseAll(SyncObject); - } + ourResults = new ContactResult[results.Count]; + results.CopyTo(ourResults, 0); }; - - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.Normal = size; - req.Origin = position; - req.orientation = orientation; - req.Count = Count; - req.filter = flags; - - lock (SyncObject) + int waitTime = 0; + m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); + while (ourResults == null && waitTime < 1000) { - m_rayCastManager.QueueRequest(req); - if (!Monitor.Wait(SyncObject, 500)) - return new List(); + Thread.Sleep(1); + waitTime++; } - if (ourResults == null) - return new List(); - return ourResults; + return new List (); + return new List(ourResults); } - public override List SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags) + public override Dictionary GetStats() { - List ourResults = null; - object SyncObject = new object(); - - ProbeSphereCallback retMethod = delegate(List results) - { - ourResults = results; - Monitor.PulseAll(SyncObject); - }; + if (!CollectStats) + return null; - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.length = radius; - req.Origin = position; - req.Count = Count; - req.filter = flags; + Dictionary returnStats; - - lock (SyncObject) + lock (OdeLock) { - m_rayCastManager.QueueRequest(req); - if (!Monitor.Wait(SyncObject, 500)) - return new List(); - } - - if (ourResults == null) - return new List(); - return ourResults; - } + returnStats = new Dictionary(m_stats); - public override List PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags) - { - IntPtr geom = IntPtr.Zero;; + // FIXME: This is a SUPER DUMB HACK until we can establish stats that aren't subject to a division by + // 3 from the SimStatsReporter. + returnStats[ODETotalAvatarsStatName] = _characters.Count * 3; + returnStats[ODETotalPrimsStatName] = _prims.Count * 3; + returnStats[ODEActivePrimsStatName] = _activeprims.Count * 3; - if (actor != null) - { - if (actor is OdePrim) - geom = ((OdePrim)actor).prim_geom; - else if (actor is OdeCharacter) - geom = ((OdePrim)actor).prim_geom; + InitializeExtraStats(); } - List ourResults = null; - object SyncObject = new object(); - - ProbePlaneCallback retMethod = delegate(List results) - { - ourResults = results; - Monitor.PulseAll(SyncObject); - }; - - ODERayRequest req = new ODERayRequest(); - req.actor = null; - req.callbackMethod = retMethod; - req.length = plane.W; - req.Normal.X = plane.X; - req.Normal.Y = plane.Y; - req.Normal.Z = plane.Z; - req.Count = Count; - req.filter = flags; - - lock (SyncObject) - { - m_rayCastManager.QueueRequest(req); - if (!Monitor.Wait(SyncObject, 500)) - return new List(); - } + returnStats[ODEOtherCollisionFrameMsStatName] + = returnStats[ODEOtherCollisionFrameMsStatName] + - returnStats[ODENativeSpaceCollisionFrameMsStatName] + - returnStats[ODENativeGeomCollisionFrameMsStatName]; - if (ourResults == null) - return new List(); - return ourResults; + return returnStats; } - public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse) + private void InitializeExtraStats() { - Util.FireAndForget( delegate - { - ODESitAvatar sitAvatar = new ODESitAvatar(this, m_rayCastManager); - if(sitAvatar != null) - sitAvatar.Sit(actor, AbsolutePosition, CameraPosition, offset, AvatarSize, PhysicsSitResponse); - }); - return 1; + m_stats[ODETotalFrameMsStatName] = 0; + m_stats[ODEAvatarTaintMsStatName] = 0; + m_stats[ODEPrimTaintMsStatName] = 0; + m_stats[ODEAvatarForcesFrameMsStatName] = 0; + m_stats[ODEPrimForcesFrameMsStatName] = 0; + m_stats[ODERaycastingFrameMsStatName] = 0; + m_stats[ODENativeStepFrameMsStatName] = 0; + m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0; + m_stats[ODENativeGeomCollisionFrameMsStatName] = 0; + m_stats[ODEOtherCollisionFrameMsStatName] = 0; + m_stats[ODECollisionNotificationFrameMsStatName] = 0; + m_stats[ODEAvatarContactsStatsName] = 0; + m_stats[ODEPrimContactsStatName] = 0; + m_stats[ODEAvatarUpdateFrameMsStatName] = 0; + m_stats[ODEPrimUpdateFrameMsStatName] = 0; } - } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index f642699..410463c 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs @@ -2267,8 +2267,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); - GC.Collect(1); - TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, -- cgit v1.1 From f510898188e7ba54460858a9c934e898b15de2ce Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Dec 2016 14:33:15 +0000 Subject: Fake accepting materials (Type == -2) on FSAssets. Materials are created with an MD5 hash based UUID in order to stop proliferation of orphaned assets. Therefore a UUID collision is expected on materials and should not have been treated as an error. --- OpenSim/Services/FSAssetService/FSAssetService.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Services/FSAssetService/FSAssetService.cs b/OpenSim/Services/FSAssetService/FSAssetService.cs index 7f14462..cddd288 100644 --- a/OpenSim/Services/FSAssetService/FSAssetService.cs +++ b/OpenSim/Services/FSAssetService/FSAssetService.cs @@ -668,6 +668,9 @@ namespace OpenSim.Services.FSAssetService if (!m_DataConnector.Store(asset.Metadata, hash)) { + if (asset.Metadata.Type == -2) + return asset.ID; + return UUID.Zero.ToString(); } else -- cgit v1.1 From da08e2e5f5be597919b4844675af944e4461711f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 30 Dec 2016 19:12:56 +0000 Subject: mantis 8106: improve avatar walk in mouselook --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5082b9d..f906d9f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3674,12 +3674,18 @@ namespace OpenSim.Region.Framework.Scenes // vec, Rotation, thisAddSpeedModifier, Name); // rotate from avatar coord space to world - // for now all controls assume this is only a rotation around Z - // if not all checks below need to be done before this rotation - Vector3 direc = vec * Rotation; + Quaternion rot = Rotation; + if (!Flying && PresenceType != PresenceType.Npc) + { + // force rotation to be around Z only, if not flying + // needed for mouselook + rot.X = 0; + rot.Y = 0; + } + + Vector3 direc = vec * rot; direc.Normalize(); - // mouse look situation ? if ((vec.Z == 0f) && !Flying) direc.Z = 0f; // Prevent camera WASD up. -- cgit v1.1 From 7abb0477ed740663934fa908b282eb51055bc132 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 31 Dec 2016 08:58:06 -0800 Subject: Replaced OpenMetaverse libs/xmls with new ones. Also added a file in openmetaverse_data that was added recently to libomv and was missing. --- bin/OpenMetaverse.Rendering.Meshmerizer.dll | Bin 20480 -> 20480 bytes bin/OpenMetaverse.StructuredData.dll | Bin 102400 -> 102400 bytes bin/OpenMetaverse.XML | 39018 +++++++++++++------------- bin/OpenMetaverse.dll | Bin 2195456 -> 2199552 bytes bin/OpenMetaverseTypes.XML | 303 +- bin/OpenMetaverseTypes.dll | Bin 110592 -> 110592 bytes bin/openmetaverse_data/avatar_skeleton.xml | 81 + 7 files changed, 19982 insertions(+), 19420 deletions(-) create mode 100644 bin/openmetaverse_data/avatar_skeleton.xml diff --git a/bin/OpenMetaverse.Rendering.Meshmerizer.dll b/bin/OpenMetaverse.Rendering.Meshmerizer.dll index cca8f3f..1a12a1e 100755 Binary files a/bin/OpenMetaverse.Rendering.Meshmerizer.dll and b/bin/OpenMetaverse.Rendering.Meshmerizer.dll differ diff --git a/bin/OpenMetaverse.StructuredData.dll b/bin/OpenMetaverse.StructuredData.dll index 41dd0cc..7aeb089 100755 Binary files a/bin/OpenMetaverse.StructuredData.dll and b/bin/OpenMetaverse.StructuredData.dll differ diff --git a/bin/OpenMetaverse.XML b/bin/OpenMetaverse.XML index 36e5b92..ce8ca86 100644 --- a/bin/OpenMetaverse.XML +++ b/bin/OpenMetaverse.XML @@ -218,6 +218,9 @@ Event message when an object uses llOwnerSay + + Event message when an object uses llRegionSayTo + Special value to support llRegionSay, never sent to the client @@ -880,6 +883,13 @@ Manager class for our own avatar + + + Called once attachment resource usage information has been collected + + Indicates if operation was successfull + Attachment resource usage information + The event subscribers. null if no subcribers @@ -891,6 +901,9 @@ Thread sync lock object + + Raised when a scripted object or agent within range sends a public message + The event subscribers. null if no subcribers @@ -902,6 +915,10 @@ Thread sync lock object + + Raised when a scripted object sends a dialog box containing possible + options an agent can respond to + The event subscribers. null if no subcribers @@ -913,6 +930,9 @@ Thread sync lock object + + Raised when an object requests a change in the permissions an agent has permitted + The event subscribers. null if no subcribers @@ -924,6 +944,9 @@ Thread sync lock object + + Raised when a script requests an agent open the specified URL + The event subscribers. null if no subcribers @@ -935,6 +958,9 @@ Thread sync lock object + + Raised when an agents currency balance is updated + The event subscribers. null if no subcribers @@ -946,6 +972,9 @@ Thread sync lock object + + Raised when a transaction occurs involving currency such as a land purchase + The event subscribers. null if no subcribers @@ -957,6 +986,10 @@ Thread sync lock object + + Raised when an ImprovedInstantMessage packet is recieved from the simulator, this is used for everything from + private messaging to friendship offers. The Dialog field defines what type of message has arrived + The event subscribers. null if no subcribers @@ -968,6 +1001,10 @@ Thread sync lock object + + Raised when an agent has requested a teleport to another location, or when responding to a lure. Raised multiple times + for each teleport indicating the progress of the request + The event subscribers. null if no subcribers @@ -979,6 +1016,9 @@ Thread sync lock object + + Raised when a simulator sends agent specific information for our avatar. + The event subscribers. null if no subcribers @@ -990,6 +1030,9 @@ Thread sync lock object + + Raised when our agents animation playlist changes + The event subscribers. null if no subcribers @@ -1001,6 +1044,9 @@ Thread sync lock object + + Raised when an object or avatar forcefully collides with our agent + The event subscribers. null if no subcribers @@ -1012,6 +1058,9 @@ Thread sync lock object + + Raised when our agent crosses a region border into another region + The event subscribers. null if no subcribers @@ -1023,6 +1072,9 @@ Thread sync lock object + + Raised when our agent succeeds or fails to join a group chat session + The event subscribers. null if no subcribers @@ -1034,6 +1086,10 @@ Thread sync lock object + + Raised when a simulator sends an urgent message usually indication the recent failure of + another action we have attempted to take such as an attempt to enter a parcel where we are denied access + The event subscribers. null if no subcribers @@ -1045,6 +1101,9 @@ Thread sync lock object + + Raised when a script attempts to take or release specified controls for our agent + The event subscribers. null if no subcribers @@ -1056,6 +1115,10 @@ Thread sync lock object + + Raised when the simulator detects our agent is trying to view something + beyond its limits + The event subscribers. null if no subcribers @@ -1067,6 +1130,9 @@ Thread sync lock object + + Raised when a script sensor reply is received from a simulator + The event subscribers. null if no subcribers @@ -1078,6 +1144,9 @@ Thread sync lock object + + Raised in response to a request + The event subscribers. null if no subcribers @@ -1089,6 +1158,9 @@ Thread sync lock object + + Raised when an avatar enters a group chat session we are participating in + The event subscribers. null if no subcribers @@ -1100,6 +1172,9 @@ Thread sync lock object + + Raised when an agent exits a group chat session we are participating in + The event subscribers, null of no subscribers @@ -1111,6 +1186,10 @@ Thread sync lock object + + Raised when the simulator sends us data containing + the details of display name change + The event subscribers. null if no subcribers @@ -1122,6 +1201,9 @@ Thread sync lock object + + Raised when a scripted object or agent within range sends a public message + Reference to the GridClient instance @@ -1139,6 +1221,96 @@ Dictionary containing mute list keyead on mute name and key + + Your (client) avatars + "client", "agent", and "avatar" all represent the same thing + + + Temporary assigned to this session, used for + verifying our identity in packets + + + Shared secret that is never sent over the wire + + + Your (client) avatar ID, local to the current region/sim + + + Where the avatar started at login. Can be "last", "home" + or a login + + + The access level of this agent, usually M, PG or A + + + The CollisionPlane of Agent + + + An representing the velocity of our agent + + + An representing the acceleration of our agent + + + A which specifies the angular speed, and axis about which an Avatar is rotating. + + + Position avatar client will goto when login to 'home' or during + teleport request to 'home' region. + + + LookAt point saved/restored with HomePosition + + + Avatar First Name (i.e. Philip) + + + Avatar Last Name (i.e. Linden) + + + LookAt point received with the login response message + + + Avatar Full Name (i.e. Philip Linden) + + + Gets the health of the agent + + + Gets the current balance of the agent + + + Gets the local ID of the prim the agent is sitting on, + zero if the avatar is not currently sitting + + + Gets the of the agents active group. + + + Gets the Agents powers in the currently active group + + + Current status message for teleporting + + + Current position of the agent as a relative offset from + the simulator, or the parent object if we are sitting on something + + + Current rotation of the agent as a relative rotation from + the simulator, or the parent object if we are sitting on something + + + Current position of the agent in the simulator + + + + A representing the agents current rotation + + + + Returns the global grid position of the avatar + Various abilities and preferences sent by the grid @@ -1251,7 +1423,7 @@ Start a friends conference List of UUIDs to start a conference with - the temportary session ID returned in the callback> + the temportary session ID returned in the callback> @@ -2000,188 +2172,167 @@ The sender The EventArgs object containing the packet data - - Raised when a scripted object or agent within range sends a public message - - - Raised when a scripted object sends a dialog box containing possible - options an agent can respond to - - - Raised when an object requests a change in the permissions an agent has permitted - - - Raised when a script requests an agent open the specified URL - - - Raised when an agents currency balance is updated - - - Raised when a transaction occurs involving currency such as a land purchase - - - Raised when an ImprovedInstantMessage packet is recieved from the simulator, this is used for everything from - private messaging to friendship offers. The Dialog field defines what type of message has arrived + + + Agent movement and camera control + + Agent movement is controlled by setting specific + After the control flags are set, An AgentUpdate is required to update the simulator of the specified flags + This is most easily accomplished by setting one or more of the AgentMovement properties + + Movement of an avatar is always based on a compass direction, for example AtPos will move the + agent from West to East or forward on the X Axis, AtNeg will of course move agent from + East to West or backward on the X Axis, LeftPos will be South to North or forward on the Y Axis + The Z axis is Up, finer grained control of movements can be done using the Nudge properties + - - Raised when an agent has requested a teleport to another location, or when responding to a lure. Raised multiple times - for each teleport indicating the progress of the request + + + Camera controls for the agent, mostly a thin wrapper around + CoordinateFrame. This class is only responsible for state + tracking and math, it does not send any packets + - - Raised when a simulator sends agent specific information for our avatar. + + - - Raised when our agents animation playlist changes + + The camera is a local frame of reference inside of + the larger grid space. This is where the math happens - - Raised when an object or avatar forcefully collides with our agent + + - - Raised when our agent crosses a region border into another region + + - - Raised when our agent succeeds or fails to join a group chat session + + - - Raised when a simulator sends an urgent message usually indication the recent failure of - another action we have attempted to take such as an attempt to enter a parcel where we are denied access + + - - Raised when a script attempts to take or release specified controls for our agent + + + Default constructor + - - Raised when the simulator detects our agent is trying to view something - beyond its limits + + Move agent positive along the X axis - - Raised when a script sensor reply is received from a simulator + + Move agent negative along the X axis - - Raised in response to a request + + Move agent positive along the Y axis - - Raised when an avatar enters a group chat session we are participating in + + Move agent negative along the Y axis - - Raised when an agent exits a group chat session we are participating in + + Move agent positive along the Z axis - - Raised when the simulator sends us data containing - the details of display name change + + Move agent negative along the Z axis - - Raised when a scripted object or agent within range sends a public message + + - - Your (client) avatars - "client", "agent", and "avatar" all represent the same thing + + - - Temporary assigned to this session, used for - verifying our identity in packets + + - - Shared secret that is never sent over the wire + + - - Your (client) avatar ID, local to the current region/sim + + - - Where the avatar started at login. Can be "last", "home" - or a login + + - - The access level of this agent, usually M, PG or A + + - - The CollisionPlane of Agent + + Causes simulator to make agent fly - - An representing the velocity of our agent + + Stop movement - - An representing the acceleration of our agent + + Finish animation - - A which specifies the angular speed, and axis about which an Avatar is rotating. + + Stand up from a sit - - Position avatar client will goto when login to 'home' or during - teleport request to 'home' region. + + Tells simulator to sit agent on ground - - LookAt point saved/restored with HomePosition + + Place agent into mouselook mode - - Avatar First Name (i.e. Philip) + + Nudge agent positive along the X axis - - Avatar Last Name (i.e. Linden) + + Nudge agent negative along the X axis - - LookAt point received with the login response message + + Nudge agent positive along the Y axis - - Avatar Full Name (i.e. Philip Linden) + + Nudge agent negative along the Y axis - - Gets the health of the agent + + Nudge agent positive along the Z axis - - Gets the current balance of the agent + + Nudge agent negative along the Z axis - - Gets the local ID of the prim the agent is sitting on, - zero if the avatar is not currently sitting + + - - Gets the of the agents active group. + + - - Gets the Agents powers in the currently active group + + Tell simulator to mark agent as away - - Current status message for teleporting + + - - Current position of the agent as a relative offset from - the simulator, or the parent object if we are sitting on something + + - - Current rotation of the agent as a relative rotation from - the simulator, or the parent object if we are sitting on something + + - - Current position of the agent in the simulator + + - + - A representing the agents current rotation + Returns "always run" value, or changes it by sending a SetAlwaysRunPacket - - Returns the global grid position of the avatar + + The current value of the agent control flags - - - Called once attachment resource usage information has been collected - - Indicates if operation was successfull - Attachment resource usage information + + Gets or sets the interval in milliseconds at which + AgentUpdate packets are sent to the current simulator. Setting + this to a non-zero value will also enable the packet sending if + it was previously off, and setting it to zero will disable - - - Agent movement and camera control - - Agent movement is controlled by setting specific - After the control flags are set, An AgentUpdate is required to update the simulator of the specified flags - This is most easily accomplished by setting one or more of the AgentMovement properties - - Movement of an avatar is always based on a compass direction, for example AtPos will move the - agent from West to East or forward on the X Axis, AtNeg will of course move agent from - East to West or backward on the X Axis, LeftPos will be South to North or forward on the Y Axis - The Z axis is Up, finer grained control of movements can be done using the Nudge properties - + + Gets or sets whether AgentUpdate packets are sent to + the current simulator + + + Reset movement controls every time we send an update Agent camera controls @@ -2297,154 +2448,6 @@ Angle in radians - - Move agent positive along the X axis - - - Move agent negative along the X axis - - - Move agent positive along the Y axis - - - Move agent negative along the Y axis - - - Move agent positive along the Z axis - - - Move agent negative along the Z axis - - - - - - - - - - - - - - - - - - - - - - - - Causes simulator to make agent fly - - - Stop movement - - - Finish animation - - - Stand up from a sit - - - Tells simulator to sit agent on ground - - - Place agent into mouselook mode - - - Nudge agent positive along the X axis - - - Nudge agent negative along the X axis - - - Nudge agent positive along the Y axis - - - Nudge agent negative along the Y axis - - - Nudge agent positive along the Z axis - - - Nudge agent negative along the Z axis - - - - - - - - - Tell simulator to mark agent as away - - - - - - - - - - - - - - - - Returns "always run" value, or changes it by sending a SetAlwaysRunPacket - - - - The current value of the agent control flags - - - Gets or sets the interval in milliseconds at which - AgentUpdate packets are sent to the current simulator. Setting - this to a non-zero value will also enable the packet sending if - it was previously off, and setting it to zero will disable - - - Gets or sets whether AgentUpdate packets are sent to - the current simulator - - - Reset movement controls every time we send an update - - - - Camera controls for the agent, mostly a thin wrapper around - CoordinateFrame. This class is only responsible for state - tracking and math, it does not send any packets - - - - - - - The camera is a local frame of reference inside of - the larger grid space. This is where the math happens - - - - Default constructor - - - - - - - - - - - - - - Used to specify movement actions for your agent @@ -2556,13 +2559,6 @@ of setting the maturity access level - - - Creates new instance of the EventArgs class - - Has setting new maturty access level succeeded - New maturity access level as returned by the simulator - New maturity accesss level returned from the sim @@ -2573,24 +2569,17 @@ True if setting the new maturity access level has succedded - + - + Creates new instance of the EventArgs class + Has setting new maturty access level succeeded + New maturity access level as returned by the simulator - + - Construct a new instance of the ChatEventArgs object + - Sim from which the message originates - The message sent - The audible level of the message - The type of message sent: whisper, shout, etc - The source type of the message sender - The name of the agent or object sending the message - The ID of the agent or object sending the message - The ID of the object owner, or the agent ID sending the message - The position of the agent or object sending the message Get the simulator sending the message @@ -2619,22 +2608,22 @@ Get the position of the agent or object sending the message - - Contains the data sent when a primitive opens a dialog with this agent - - + - Construct a new instance of the ScriptDialogEventArgs + Construct a new instance of the ChatEventArgs object - The dialog message - The name of the object that sent the dialog request - The ID of the image to be displayed - The ID of the primitive sending the dialog - The first name of the senders owner - The last name of the senders owner - The communication channel the dialog was sent on - The string labels containing the options presented in this dialog - UUID of the scritped object owner + Sim from which the message originates + The message sent + The audible level of the message + The type of message sent: whisper, shout, etc + The source type of the message sender + The name of the agent or object sending the message + The ID of the agent or object sending the message + The ID of the object owner, or the agent ID sending the message + The position of the agent or object sending the message + + + Contains the data sent when a primitive opens a dialog with this agent Get the dialog message @@ -2664,21 +2653,24 @@ UUID of the scritped object owner + + + Construct a new instance of the ScriptDialogEventArgs + + The dialog message + The name of the object that sent the dialog request + The ID of the image to be displayed + The ID of the primitive sending the dialog + The first name of the senders owner + The last name of the senders owner + The communication channel the dialog was sent on + The string labels containing the options presented in this dialog + UUID of the scritped object owner + Contains the data sent when a primitive requests debit or other permissions requesting a YES or NO answer - - - Construct a new instance of the ScriptQuestionEventArgs - - The simulator containing the object sending the request - The ID of the script making the request - The ID of the primitive containing the script making the request - The name of the primitive making the request - The name of the owner of the object making the request - The permissions being requested - Get the simulator containing the object sending the request @@ -2697,21 +2689,21 @@ Get the permissions being requested + + + Construct a new instance of the ScriptQuestionEventArgs + + The simulator containing the object sending the request + The ID of the script making the request + The ID of the primitive containing the script making the request + The name of the primitive making the request + The name of the owner of the object making the request + The permissions being requested + Contains the data sent when a primitive sends a request to an agent to open the specified URL - - - Construct a new instance of the LoadUrlEventArgs - - The name of the object sending the request - The ID of the object sending the request - The ID of the owner of the object sending the request - True if the object is owned by a group - The message sent with the request - The URL the object sent - Get the name of the object sending the request @@ -2730,9 +2722,26 @@ Get the URL the object sent + + + Construct a new instance of the LoadUrlEventArgs + + The name of the object sending the request + The ID of the object sending the request + The ID of the owner of the object sending the request + True if the object is owned by a group + The message sent with the request + The URL the object sent + The date received from an ImprovedInstantMessage + + Get the InstantMessage object + + + Get the simulator where the InstantMessage origniated + Construct a new instance of the InstantMessageEventArgs object @@ -2740,42 +2749,24 @@ the InstantMessage object the simulator where the InstantMessage origniated - - Get the InstantMessage object - - - Get the simulator where the InstantMessage origniated - Contains the currency balance - + - Construct a new BalanceEventArgs object + Get the currenct balance - The currenct balance - + - Get the currenct balance + Construct a new BalanceEventArgs object + The currenct balance Contains the transaction summary when an item is purchased, money is given, or land is purchased - - - Construct a new instance of the MoneyBalanceReplyEventArgs object - - The ID of the transaction - True of the transaction was successful - The current currency balance - The meters credited - The meters comitted - A brief description of the transaction - Transaction info - Get the ID of the transaction @@ -2797,19 +2788,20 @@ Detailed transaction information - - Data sent from the simulator containing information about your agent and active group information - - + - Construct a new instance of the AgentDataReplyEventArgs object + Construct a new instance of the MoneyBalanceReplyEventArgs object - The agents first name - The agents last name - The agents active group ID - The group title of the agents active group - The combined group powers the agent has in the active group - The name of the group the agent has currently active + The ID of the transaction + True of the transaction was successful + The current currency balance + The meters credited + The meters comitted + A brief description of the transaction + Transaction info + + + Data sent from the simulator containing information about your agent and active group information Get the agents first name @@ -2829,34 +2821,35 @@ Get the active group name of your agent + + + Construct a new instance of the AgentDataReplyEventArgs object + + The agents first name + The agents last name + The agents active group ID + The group title of the agents active group + The combined group powers the agent has in the active group + The name of the group the agent has currently active + Data sent by the simulator to indicate the active/changed animations applied to your agent + + Get the dictionary that contains the changed animations + Construct a new instance of the AnimationsChangedEventArgs class The dictionary that contains the changed animations - - Get the dictionary that contains the changed animations - Data sent from a simulator indicating a collision with your agent - - - Construct a new instance of the MeanCollisionEventArgs class - - The type of collision that occurred - The ID of the agent or object that perpetrated the agression - The ID of the Victim - The strength of the collision - The Time the collision occurred - Get the Type of collision @@ -2872,9 +2865,25 @@ Get the time the collision occurred + + + Construct a new instance of the MeanCollisionEventArgs class + + The type of collision that occurred + The ID of the agent or object that perpetrated the agression + The ID of the Victim + The strength of the collision + The Time the collision occurred + Data sent to your agent when it crosses region boundaries + + Get the simulator your agent just left + + + Get the simulator your agent is now in + Construct a new instance of the RegionCrossedEventArgs class @@ -2882,24 +2891,9 @@ The simulator your agent just left The simulator your agent is now in - - Get the simulator your agent just left - - - Get the simulator your agent is now in - Data sent from the simulator when your agent joins a group chat session - - - Construct a new instance of the GroupChatJoinedEventArgs class - - The ID of the session - The name of the session - A temporary session id used for establishing new sessions - True of your agent successfully joined the session - Get the ID of the group chat session @@ -2912,29 +2906,30 @@ True if your agent successfully joined the session + + + Construct a new instance of the GroupChatJoinedEventArgs class + + The ID of the session + The name of the session + A temporary session id used for establishing new sessions + True of your agent successfully joined the session + Data sent by the simulator containing urgent messages + + Get the alert message + Construct a new instance of the AlertMessageEventArgs class The alert message - - Get the alert message - Data sent by a script requesting to take or release specified controls to your agent - - - Construct a new instance of the ScriptControlEventArgs class - - The controls the script is attempting to take or release to the agent - True if the script is passing controls back to the agent - True if the script is requesting controls be released to the script - Get the controls the script is attempting to take or release to the agent @@ -2944,41 +2939,34 @@ True if the script is requesting controls be released to the script + + + Construct a new instance of the ScriptControlEventArgs class + + The controls the script is attempting to take or release to the agent + True if the script is passing controls back to the agent + True if the script is requesting controls be released to the script + Data sent from the simulator to an agent to indicate its view limits + + Get the collision plane + Construct a new instance of the CameraConstraintEventArgs class The collision plane - - Get the collision plane - Data containing script sensor requests which allow an agent to know the specific details of a primitive sending script sensor requests - - - Construct a new instance of the ScriptSensorReplyEventArgs - - The ID of the primitive sending the sensor - The ID of the group associated with the primitive - The name of the primitive sending the sensor - The ID of the primitive sending the sensor - The ID of the owner of the primitive sending the sensor - The position of the primitive sending the sensor - The range the primitive specified to scan - The rotation of the primitive sending the sensor - The type of sensor the primitive sent - The velocity of the primitive sending the sensor - Get the ID of the primitive sending the sensor @@ -3009,12 +2997,24 @@ Get the velocity of the primitive sending the sensor + + + Construct a new instance of the ScriptSensorReplyEventArgs + + The ID of the primitive sending the sensor + The ID of the group associated with the primitive + The name of the primitive sending the sensor + The ID of the primitive sending the sensor + The ID of the owner of the primitive sending the sensor + The position of the primitive sending the sensor + The range the primitive specified to scan + The rotation of the primitive sending the sensor + The type of sensor the primitive sent + The velocity of the primitive sending the sensor + Contains the response data returned from the simulator in response to a - - Construct a new instance of the AvatarSitResponseEventArgs object - Get the ID of the primitive the agent will be sitting on @@ -3036,9 +3036,18 @@ Get the rotation of the agent when seated + + Construct a new instance of the AvatarSitResponseEventArgs object + Data sent when an agent joins a chat session your agent is currently participating in + + Get the ID of the chat session + + + Get the ID of the agent that joined + Construct a new instance of the ChatSessionMemberAddedEventArgs object @@ -3046,15 +3055,15 @@ The ID of the chat session The ID of the agent joining - - Get the ID of the chat session - - - Get the ID of the agent that joined - Data sent when an agent exits a chat session your agent is currently participating in + + Get the ID of the chat session + + + Get the ID of the agent that left + Construct a new instance of the ChatSessionMemberLeftEventArgs object @@ -3062,18 +3071,9 @@ The ID of the chat session The ID of the Agent that left - - Get the ID of the chat session - - - Get the ID of the agent that left - Event arguments with the result of setting display name operation - - Default constructor - Status code, 200 indicates settign display name was successful @@ -3083,12 +3083,40 @@ Details of the newly set display name + + Default constructor + Throttles the network traffic for various different traffic types. Access this class through GridClient.Throttle + + Maximum bits per second for resending unacknowledged packets + + + Maximum bits per second for LayerData terrain + + + Maximum bits per second for LayerData wind data + + + Maximum bits per second for LayerData clouds + + + Unknown, includes object data + + + Maximum bits per second for textures + + + Maximum bits per second for downloaded assets + + + Maximum bits per second the entire connection, divided up + between invidiual streams using default multipliers + Default constructor, uses a default high total of 1500 KBps (1536000) @@ -3125,35 +3153,10 @@ Byte array containing all the throttle values - - Maximum bits per second for resending unacknowledged packets - - - Maximum bits per second for LayerData terrain - - - Maximum bits per second for LayerData wind data - - - Maximum bits per second for LayerData clouds - - - Unknown, includes object data - - - Maximum bits per second for textures - - - Maximum bits per second for downloaded assets - - - Maximum bits per second the entire connection, divided up - between invidiual streams using default multipliers - - - - Static pre-defined animations available to all agents - + + + Static pre-defined animations available to all agents + Agent with afraid expression on face @@ -3583,6 +3586,12 @@ Appearance Flags, introdued with server side baking, currently unused + + Mask for multiple attachments + + + Mapping between BakeType and AvatarTextureIndex + Maximum number of concurrent downloads for wearable assets and textures @@ -3617,12 +3626,6 @@ Total number of wearables per bake layer - - Mask for multiple attachments - - - Mapping between BakeType and AvatarTextureIndex - Map of what wearables are included in each bake @@ -3634,6 +3637,54 @@ Default avatar texture, used to detect when a custom texture is not set for a face + + + Contains information about a wearable inventory item + + + + Inventory ItemID of the wearable + + + AssetID of the wearable asset + + + WearableType of the wearable + + + AssetType of the wearable + + + Asset data for the wearable + + + + Data collected from visual params for each wearable + needed for the calculation of the color + + + + + Holds a texture assetID and the data needed to bake this layer into + an outfit texture. Used to keep track of currently worn textures + and baking data + + + + A texture AssetID + + + Asset data for the texture + + + Collection of alpha masks that needs applying + + + Tint that should be applied to the texture + + + Where on avatar does this texture belong + The event subscribers. null if no subcribers @@ -3645,6 +3696,11 @@ Thread sync lock object + + Triggered when an AgentWearablesUpdate packet is received, + telling us what our avatar is currently wearing + request. + The event subscribers. null if no subcribers @@ -3656,6 +3712,12 @@ Thread sync lock object + + Raised when an AgentCachedTextureResponse packet is + received, giving a list of cached bakes that were found on the + simulator + request. + The event subscribers. null if no subcribers @@ -3666,6 +3728,13 @@ Thread sync lock object + + + Raised when appearance data is sent to the simulator, also indicates + the main appearance thread is finished. + + request. + The event subscribers. null if no subcribers @@ -3677,6 +3746,17 @@ Thread sync lock object + + + Triggered when the simulator requests the agent rebake its appearance. + + + + + + Returns true if AppearanceManager is busy and trying to set or change appearance will fail + + Visual parameters last sent to the sim @@ -4085,83 +4165,6 @@ A BakeType A list of texture slots that are inputs for the given bake - - Triggered when an AgentWearablesUpdate packet is received, - telling us what our avatar is currently wearing - request. - - - Raised when an AgentCachedTextureResponse packet is - received, giving a list of cached bakes that were found on the - simulator - request. - - - - Raised when appearance data is sent to the simulator, also indicates - the main appearance thread is finished. - - request. - - - - Triggered when the simulator requests the agent rebake its appearance. - - - - - - Returns true if AppearanceManager is busy and trying to set or change appearance will fail - - - - - Contains information about a wearable inventory item - - - - Inventory ItemID of the wearable - - - AssetID of the wearable asset - - - WearableType of the wearable - - - AssetType of the wearable - - - Asset data for the wearable - - - - Data collected from visual params for each wearable - needed for the calculation of the color - - - - - Holds a texture assetID and the data needed to bake this layer into - an outfit texture. Used to keep track of currently worn textures - and baking data - - - - A texture AssetID - - - Asset data for the texture - - - Collection of alpha masks that needs applying - - - Tint that should be applied to the texture - - - Where on avatar does this texture belong - Contains the Event data returned from the data server from an AgentWearablesRequest @@ -4177,18 +4180,21 @@ Contains the Event data returned from an AppearanceSetRequest + + Indicates whether appearance setting was successful + Triggered when appearance data is sent to the sim and the main appearance thread is done. Indicates whether appearance setting was successful - - Indicates whether appearance setting was successful - Contains the Event data returned from the data server from an RebakeAvatarTextures + + The ID of the Texture Layer to bake + Triggered when the simulator sends a request for this agent to rebake @@ -4196,14 +4202,22 @@ The ID of the Texture Layer to bake - - The ID of the Texture Layer to bake - Class that handles the local asset cache + + + Allows setting weather to periodicale prune the cache if it grows too big + Default is enabled, when caching is enabled + + + + + How long (in ms) between cache checks (default is 5 min.) + + Default constructor @@ -4308,17 +4322,6 @@ Byte size we want to output String with humanly readable file size - - - Allows setting weather to periodicale prune the cache if it grows too big - Default is enabled, when caching is enabled - - - - - How long (in ms) between cache checks (default is 5 min.) - - Helper class for sorting files by their last accessed time @@ -4468,6 +4471,26 @@ Number of milliseconds to wait for a transfer header packet if out of order data was received + + + Callback used for various asset download requests + + Transfer information + Downloaded asset, null on fail + + + + Callback used upon competition of baked texture upload + + Asset UUID of the newly uploaded baked texture + + + + A callback that fires upon the completition of the RequestMesh call + + Was the download successfull + Resulting mesh or null on problems + The event subscribers. null if no subcribers @@ -4479,6 +4502,9 @@ Thread sync lock object + + Raised when the simulator responds sends + The event subscribers. null if no subcribers @@ -4490,6 +4516,9 @@ Thread sync lock object + + Raised during upload completes + The event subscribers. null if no subcribers @@ -4501,6 +4530,9 @@ Thread sync lock object + + Raised during upload with progres update + The event subscribers. null if no subcribers @@ -4512,6 +4544,9 @@ Thread sync lock object + + Fired when the simulator sends an InitiateDownloadPacket, used to download terrain .raw files + The event subscribers. null if no subcribers @@ -4523,6 +4558,9 @@ Thread sync lock object + + Fired when a texture is in the process of being downloaded by the TexturePipeline class + Texture download cache @@ -4831,41 +4869,6 @@ The sender The EventArgs object containing the packet data - - Raised when the simulator responds sends - - - Raised during upload completes - - - Raised during upload with progres update - - - Fired when the simulator sends an InitiateDownloadPacket, used to download terrain .raw files - - - Fired when a texture is in the process of being downloaded by the TexturePipeline class - - - - Callback used for various asset download requests - - Transfer information - Downloaded asset, null on fail - - - - Callback used upon competition of baked texture upload - - Asset UUID of the newly uploaded baked texture - - - - A callback that fires upon the completition of the RequestMesh call - - Was the download successfull - Resulting mesh or null on problems - Xfer data @@ -4897,30738 +4900,31127 @@ Represents an avatar (other than your own) - - - Particle system specific enumerators, flags and methods. - - - - - Current version of the media data for the prim - - - + - Array of media entries indexed by face number + Positive and negative ratings - - - - - - - - - - - - - - - - - + + Positive ratings for Behavior - - + + Negative ratings for Behavior - - Foliage type for this primitive. Only applicable if this - primitive is foliage + + Positive ratings for Appearance - - Unknown + + Negative ratings for Appearance - - + + Positive ratings for Building - - + + Negative ratings for Building - - + + Positive ratings given by this avatar - - + + Negative ratings given by this avatar - - + + + Avatar properties including about text, profile URL, image IDs and + publishing settings + - - + + First Life about text - - + + First Life image ID - + - + - + - + - - + + Profile image ID - - + + Flags of the profile - - Identifies the owner if audio or a particle system is - active + + Web URL for this profile - - + + Should this profile be published on the web - - + + Avatar Online Status - - + + Is this a mature profile - + - + - - + + + Avatar interests including spoken languages, skills, and "want to" + choices + - - + + Languages profile field - + - + - + - + - - + + Groups that this avatar is a member of - - Objects physics engine propertis + + Positive and negative ratings - - Extra data about primitive + + Avatar properties including about text, profile URL, image IDs and + publishing settings - - Indicates if prim is attached to an avatar + + Avatar interests including spoken languages, skills, and "want to" + choices - - Number of clients referencing this prim + + Movement control flags for avatars. Typically not set or used by + clients. To move your avatar, use Client.Self.Movement instead - + - Default constructor + Contains the visual parameters describing the deformation of the avatar - + - Packs PathTwist, PathTwistBegin, PathRadiusOffset, and PathSkew - parameters in to signed eight bit values + Appearance version. Value greater than 0 indicates using server side baking - Floating point parameter to pack - Signed eight bit value containing the packed parameter - + - Unpacks PathTwist, PathTwistBegin, PathRadiusOffset, and PathSkew - parameters from signed eight bit integers to floating point values + Version of the Current Outfit Folder that the appearance is based on - Signed eight bit value to unpack - Unpacked floating point value - - - - - - - - - Uses basic heuristics to estimate the primitive shape - + - Complete structure for the particle system + Appearance flags. Introduced with server side baking, currently unused. - - Particle Flags - There appears to be more data packed in to this area - for many particle systems. It doesn't appear to be flag values - and serialization breaks unless there is a flag for every - possible bit so it is left as an unsigned integer - - - pattern of particles + + + List of current avatar animations + - - A representing the maximimum age (in seconds) particle will be displayed - Maximum value is 30 seconds + + First name - - A representing the number of seconds, - from when the particle source comes into view, - or the particle system's creation, that the object will emits particles; - after this time period no more particles are emitted + + Last name - - A in radians that specifies where particles will not be created + + Full name - - A in radians that specifies where particles will be created + + Active group - - A representing the number of seconds between burts. + + + Default constructor + - - A representing the number of meters - around the center of the source where particles will be created. + + Information about agents display name - - A representing in seconds, the minimum speed between bursts of new particles - being emitted + + Agent UUID - - A representing in seconds the maximum speed of new particles being emitted. + + Username - - A representing the maximum number of particles emitted per burst + + Display name - - A which represents the velocity (speed) from the source which particles are emitted + + First name (legacy) - - A which represents the Acceleration from the source which particles are emitted + + Last name (legacy) - - The Key of the texture displayed on the particle + + Full name (legacy) - - The Key of the specified target object or avatar particles will follow + + Is display name default display name - - Flags of particle from + + Cache display name until - - Max Age particle system will emit particles for + + Last updated timestamp - - The the particle has at the beginning of its lifecycle + + + Creates AgentDisplayName object from OSD + + Incoming OSD data + AgentDisplayName object - - The the particle has at the ending of its lifecycle + + + Return object as OSD map + + OSD containing agent's display name data - - A that represents the starting X size of the particle - Minimum value is 0, maximum value is 4 + + + Holds group information for Avatars such as those you might find in a profile + - - A that represents the starting Y size of the particle - Minimum value is 0, maximum value is 4 + + true of Avatar accepts group notices - - A that represents the ending X size of the particle - Minimum value is 0, maximum value is 4 + + Groups Key - - A that represents the ending Y size of the particle - Minimum value is 0, maximum value is 4 + + Texture Key for groups insignia - - A that represents the start glow value - Minimum value is 0, maximum value is 1 + + Name of the group - - A that represents the end glow value - Minimum value is 0, maximum value is 1 + + Powers avatar has in the group - - OpenGL blend function to use at particle source + + Avatars Currently selected title - - OpenGL blend function to use at particle destination + + true of Avatar has chosen to list this in their profile - + - Can this particle system be packed in a legacy compatible way + Contains an animation currently being played by an agent - True if the particle system doesn't use new particle system features - - - Decodes a byte[] array into a ParticleSystem Object - - ParticleSystem object - Start position for BitPacker + + The ID of the animation asset - + + A number to indicate start order of currently playing animations + On Linden Grids this number is unique per region, with OpenSim it is per client + + + + + - Generate byte[] array from particle data + Holds group information on an individual profile pick - Byte array - + - Particle source pattern + Retrieve friend status notifications, and retrieve avatar names and + profiles - - None + + The event subscribers, null of no subscribers - - Drop particles from source position with no force + + Raises the AvatarAnimation Event + An AvatarAnimationEventArgs object containing + the data sent from the simulator - - "Explode" particles in all directions + + Thread sync lock object - - Particles shoot across a 2D area + + Raised when the simulator sends us data containing + an agents animation playlist - - Particles shoot across a 3D Cone + + The event subscribers, null of no subscribers - - Inverse of AngleCone (shoot particles everywhere except the 3D cone defined + + Raises the AvatarAppearance Event + A AvatarAppearanceEventArgs object containing + the data sent from the simulator - - - Particle Data Flags - + + Thread sync lock object - - None + + Raised when the simulator sends us data containing + the appearance information for an agent - - Interpolate color and alpha from start to end + + The event subscribers, null of no subscribers - - Interpolate scale from start to end + + Raises the UUIDNameReply Event + A UUIDNameReplyEventArgs object containing + the data sent from the simulator - - Bounce particles off particle sources Z height + + Thread sync lock object - - velocity of particles is dampened toward the simulators wind + + Raised when the simulator sends us data containing + agent names/id values - - Particles follow the source + + The event subscribers, null of no subscribers - - Particles point towards the direction of source's velocity + + Raises the AvatarInterestsReply Event + A AvatarInterestsReplyEventArgs object containing + the data sent from the simulator - - Target of the particles + + Thread sync lock object - - Particles are sent in a straight line + + Raised when the simulator sends us data containing + the interests listed in an agents profile - - Particles emit a glow + + The event subscribers, null of no subscribers - - used for point/grab/touch + + Raises the AvatarPropertiesReply Event + A AvatarPropertiesReplyEventArgs object containing + the data sent from the simulator - - continuous ribbon particle + + Thread sync lock object - - particle data contains glow + + Raised when the simulator sends us data containing + profile property information for an agent - - particle data contains blend functions + + The event subscribers, null of no subscribers - - - Particle Flags Enum - + + Raises the AvatarGroupsReply Event + A AvatarGroupsReplyEventArgs object containing + the data sent from the simulator - - None + + Thread sync lock object - - Acceleration and velocity for particles are - relative to the object rotation + + Raised when the simulator sends us data containing + the group membership an agent is a member of - - Particles use new 'correct' angle parameters + + The event subscribers, null of no subscribers - - - Parameters used to construct a visual representation of a primitive - + + Raises the AvatarPickerReply Event + A AvatarPickerReplyEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + name/id pair - - + + The event subscribers, null of no subscribers - - + + Raises the ViewerEffectPointAt Event + A ViewerEffectPointAtEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + the objects and effect when an agent is pointing at - - + + The event subscribers, null of no subscribers - - + + Raises the ViewerEffectLookAt Event + A ViewerEffectLookAtEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + the objects and effect when an agent is looking at - - + + The event subscribers, null of no subscribers - - + + Raises the ViewerEffect Event + A ViewerEffectEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + an agents viewer effect information - - + + The event subscribers, null of no subscribers - - + + Raises the AvatarPicksReply Event + A AvatarPicksReplyEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + the top picks from an agents profile - - + + The event subscribers, null of no subscribers - - + + Raises the PickInfoReply Event + A PickInfoReplyEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - - Calculdates hash code for prim construction data - - The has + + Raised when the simulator sends us data containing + the Pick details - - Attachment point to an avatar + + The event subscribers, null of no subscribers - - + + Raises the AvatarClassifiedReply Event + A AvatarClassifiedReplyEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + the classified ads an agent has placed - - + + The event subscribers, null of no subscribers - - - Information on the flexible properties of a primitive - + + Raises the ClassifiedInfoReply Event + A ClassifiedInfoReplyEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + the details of a classified ad - - + + The event subscribers, null of no subscribers - - + + Raises the DisplayNameUpdate Event + A DisplayNameUpdateEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + the details of display name change - + - Default constructor + Callback giving results when fetching display names + If the request was successful + Array of display names + Array of UUIDs that could not be fetched - + - + Represents other avatars - - + - - - - - + + Tracks the specified avatar on your map + Avatar ID to track - + - + Request a single avatar name - + The avatar key to retrieve a name for - + - Information on the light properties of a primitive + Request a list of avatar names + The avatar keys to retrieve names for - - - - - - - - - - - - - - - - + - Default constructor + Check if Display Names functionality is available + True if Display name functionality is available - + - + Request retrieval of display names (max 90 names per request) - - + List of UUIDs to lookup + Callback to report result of the operation - + - + Start a request for Avatar Properties - + - + - + Search for an avatar (first name, last name) - + The name to search for + An ID to associate with this query - + - Information on the light properties of a primitive as texture map + Start a request for Avatar Picks + UUID of the avatar - - - - - - - + - Default constructor + Start a request for Avatar Classifieds + UUID of the avatar - + - + Start a request for details of a specific profile pick - - + UUID of the avatar + UUID of the profile pick - + - + Start a request for details of a specific profile classified - + UUID of the avatar + UUID of the profile classified - - - - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Information on the sculpt properties of a sculpted primitive - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Default constructor - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - - - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Render inside out (inverts the normals). - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - + - Render an X axis mirror of the sculpty. + EQ Message fired when someone nearby changes their display name + The message key + the IMessage object containing the deserialized data sent from the simulator + The which originated the packet - + - Extended properties to describe an object + Crossed region handler for message that comes across the EventQueue. Sent to an agent + when the agent crosses a sim border into a new region. + The message key + the IMessage object containing the deserialized data sent from the simulator + The which originated the packet - - - - - - - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Provides data for the event + The event occurs when the simulator sends + the animation playlist for an agent + + The following code example uses the and + properties to display the animation playlist of an avatar on the window. + + // subscribe to the event + Client.Avatars.AvatarAnimation += Avatars_AvatarAnimation; + + private void Avatars_AvatarAnimation(object sender, AvatarAnimationEventArgs e) + { + // create a dictionary of "known" animations from the Animations class using System.Reflection + Dictionary<UUID, string> systemAnimations = new Dictionary<UUID, string>(); + Type type = typeof(Animations); + System.Reflection.FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); + foreach (System.Reflection.FieldInfo field in fields) + { + systemAnimations.Add((UUID)field.GetValue(type), field.Name); + } + + // find out which animations being played are known animations and which are assets + foreach (Animation animation in e.Animations) + { + if (systemAnimations.ContainsKey(animation.AnimationID)) + { + Console.WriteLine("{0} is playing {1} ({2}) sequence {3}", e.AvatarID, + systemAnimations[animation.AnimationID], animation.AnimationSequence); + } + else + { + Console.WriteLine("{0} is playing {1} (Asset) sequence {2}", e.AvatarID, + animation.AnimationID, animation.AnimationSequence); + } + } + } + + - - + + Get the ID of the agent - - + + Get the list of animations to start - - + + + Construct a new instance of the AvatarAnimationEventArgs class + + The ID of the agent + The list of animations to start - - + + Provides data for the event + The event occurs when the simulator sends + the appearance data for an avatar + + The following code example uses the and + properties to display the selected shape of an avatar on the window. + + // subscribe to the event + Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; + + // handle the data when the event is raised + void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) + { + Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") + } + + - - + + Get the Simulator this request is from of the agent - - + + Get the ID of the agent - - + + true if the agent is a trial account - - + + Get the default agent texture - - + + Get the agents appearance layer textures - - + + Get the for the agent - - + + Version of the appearance system used. + Value greater than 0 indicates that server side baking is used - - + + Version of the Current Outfit Folder the appearance is based on - - + + Appearance flags, introduced with server side baking, currently unused - + - Default constructor + Construct a new instance of the AvatarAppearanceEventArgs class + The simulator request was from + The ID of the agent + true of the agent is a trial account + The default agent texture + The agents appearance layer textures + The for the agent - - - Set the properties that are set in an ObjectPropertiesFamily packet - - that has - been partially filled by an ObjectPropertiesFamily packet - - - - Describes physics attributes of the prim - - - - Primitive's local ID + + Represents the interests from the profile of an agent - - Density (1000 for normal density) + + Get the ID of the agent - - Friction + + The properties of an agent - - Gravity multiplier (1 for normal gravity) + + Get the ID of the agent - - Type of physics representation of this primitive in the simulator + + Get the ID of the agent - - Restitution + + Get the ID of the agent - - - Creates PhysicsProperties from OSD - - OSDMap with incoming data - Deserialized PhysicsProperties object + + Get the ID of the avatar - + - Serializes PhysicsProperties to OSD + Event args class for display name notification messages - OSDMap with serialized PhysicsProperties data - + - Texture animation mode + Wrapper around a byte array that allows bit to be packed and unpacked + one at a time or by a variable amount. Useful for very tightly packed + data like LayerData packets - - Disable texture animation - - - Enable texture animation - - - Loop when animating textures + + - - Animate in reverse direction + + - - Animate forward then reverse + + - - Slide texture smoothly instead of frame-stepping + + + Default constructor, initialize the bit packer / bit unpacker + with a byte array and starting position + + Byte array to pack bits in to or unpack from + Starting position in the byte array - - Rotate texture instead of using frames + + + Pack a floating point value in to the data + + Floating point value to pack - - Scale texture instead of using frames + + + Pack part or all of an integer in to the data + + Integer containing the data to pack + Number of bits of the integer to pack - + - A single textured face. Don't instantiate this class yourself, use the - methods in TextureEntry + Pack part or all of an unsigned integer in to the data + Unsigned integer containing the data to pack + Number of bits of the integer to pack - + - Contains the definition for individual faces + Pack a single bit in to the data - + Bit to pack - + - - - - - - - - - - - - - - - - - - - - - - + + + + - - + + + + + - - + + + + + - - + + + Unpacking a floating point value from the data + + Unpacked floating point value - - In the future this will specify whether a webpage is - attached to this face + + + Unpack a variable number of bits from the data in to integer format + + Number of bits to unpack + An integer containing the unpacked bits + This function is only useful up to 32 bits - - + + + Unpack a variable number of bits from the data in to unsigned + integer format + + Number of bits to unpack + An unsigned integer containing the unpacked bits + This function is only useful up to 32 bits - - + + + Unpack a 16-bit signed integer + + 16-bit signed integer - + - Represents all of the texturable faces for an object + Unpack a 16-bit unsigned integer - Grid objects have infinite faces, with each face - using the properties of the default face unless set otherwise. So if - you have a TextureEntry with a default texture uuid of X, and face 18 - has a texture UUID of Y, every face would be textured with X except for - face 18 that uses Y. In practice however, primitives utilize a maximum - of nine faces + 16-bit unsigned integer - - + + + Unpack a 32-bit signed integer + + 32-bit signed integer - - + + + Unpack a 32-bit unsigned integer + + 32-bit unsigned integer - + - Constructor that takes a default texture UUID + Reads in a byte array of an Animation Asset created by the SecondLife(tm) client. - Texture UUID to use as the default texture - + - Constructor that takes a TextureEntryFace for the - default face + Rotation Keyframe count (used internally) - Face to use as the default face - + - Constructor that creates the TextureEntry class from a byte array + Position Keyframe count (used internally) - Byte array containing the TextureEntry field - Starting position of the TextureEntry field in - the byte array - Length of the TextureEntry field, in bytes - + - This will either create a new face if a custom face for the given - index is not defined, or return the custom face for that index if - it already exists + Animation Priority - The index number of the face to create or - retrieve - A TextureEntryFace containing all the properties for that - face - + - + The animation length in seconds. - - - + - + Expression set in the client. Null if [None] is selected - - + - + The time in seconds to start the animation - - + - + The time in seconds to end the animation - - + - Controls the texture animation of a particular prim + Loop the animation - - + + + Meta data. Ease in Seconds. + - - + + + Meta data. Ease out seconds. + - - + + + Meta Data for the Hand Pose + - - + + + Number of joints defined in the animation + - - + + + Contains an array of joints + - - + + + Searialize an animation asset into it's joints/keyframes/meta data + + - - + + + Variable length strings seem to be null terminated in the animation asset.. but.. + use with caution, home grown. + advances the index. + + The animation asset byte array + The offset to start reading + a string - + - + Read in a Joint from an animation asset byte array + Variable length Joint fields, yay! + Advances the index - - + animation asset byte array + Byte Offset of the start of the joint + The Joint data serialized into the binBVHJoint structure - + - + Read Keyframes of a certain type + advance i + Animation Byte array + Offset in the Byte Array. Will be advanced + Number of Keyframes + Scaling Min to pass to the Uint16ToFloat method + Scaling Max to pass to the Uint16ToFloat method - - Groups that this avatar is a member of + + + Determines whether the specified is equal to the current . + + + true if the specified is equal to the current ; otherwise, false. + + The to compare with the current . + The parameter is null. + 2 - - Positive and negative ratings + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + 2 - - Avatar properties including about text, profile URL, image IDs and - publishing settings + + + A Joint and it's associated meta data and keyframes + - - Avatar interests including spoken languages, skills, and "want to" - choices + + + Indicates whether this instance and a specified object are equal. + + + true if and this instance are the same type and represent the same value; otherwise, false. + + Another object to compare to. + 2 - - Movement control flags for avatars. Typically not set or used by - clients. To move your avatar, use Client.Self.Movement instead + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + 2 - + - Contains the visual parameters describing the deformation of the avatar + Name of the Joint. Matches the avatar_skeleton.xml in client distros - + - Appearance version. Value greater than 0 indicates using server side baking + Joint Animation Override? Was the same as the Priority in testing.. - + - Version of the Current Outfit Folder that the appearance is based on + Array of Rotation Keyframes in order from earliest to latest - + - Appearance flags. Introduced with server side baking, currently unused. + Array of Position Keyframes in order from earliest to latest + This seems to only be for the Pelvis? - + - List of current avatar animations + Custom application data that can be attached to a joint - + - Default constructor + A Joint Keyframe. This is either a position or a rotation. - - First name - - - Last name + + + Either a Vector3 position or a Vector3 Euler rotation + - - Full name + + + Poses set in the animation metadata for the hands. + - - Active group + + + Capabilities is the name of the bi-directional HTTP REST protocol + used to communicate non real-time transactions such as teleporting or + group messaging + - + - Positive and negative ratings + Triggered when an event is received via the EventQueueGet + capability + Event name + Decoded event data + The simulator that generated the event - - Positive ratings for Behavior + + Reference to the simulator this system is connected to - - Negative ratings for Behavior + + Capabilities URI this system was initialized with - - Positive ratings for Appearance + + Whether the capabilities event queue is connected and + listening for incoming events - - Negative ratings for Appearance + + + Default constructor + + + - - Positive ratings for Building + + + Request the URI of a named capability + + Name of the capability to request + The URI of the requested capability, or String.Empty if + the capability does not exist - - Negative ratings for Building + + + Process any incoming events, check to see if we have a message created for the event, + + + - - Positive ratings given by this avatar + + + Attempts to convert an LLSD structure to a known Packet type + + Event name, this must match an actual + packet name for a Packet to be successfully built + LLSD to convert to a Packet + A Packet on success, otherwise null - - Negative ratings given by this avatar + + + A custom decoder callback + + The key of the object + the data to decode + A string represending the fieldData - + - Avatar properties including about text, profile URL, image IDs and - publishing settings + Add a custom decoder callback + The key of the field to decode + The custom decode handler - - First Life about text + + + Remove a custom decoder callback + + The key of the field to decode + The custom decode handler - - First Life image ID - - - + + + Creates a formatted string containing the values of a Packet + + The Packet + A formatted string of values of the nested items in the Packet object - - + + + Decode an IMessage object into a beautifully formatted string + + The IMessage object + Recursion level (used for indenting) + A formatted string containing the names and values of the source object - - + + + Thrown when a packet could not be successfully deserialized + - - + + + Default constructor + - - Profile image ID + + + Constructor that takes an additional error message + + An error message to attach to this exception - - Flags of the profile + + + The header of a message template packet. Holds packet flags, sequence + number, packet ID, and any ACKs that will be appended at the end of + the packet + - - Web URL for this profile + + + Convert the AckList to a byte array, used for packet serializing + + Reference to the target byte array + Beginning position to start writing to in the byte + array, will be updated with the ending position of the ACK list - - Should this profile be published on the web + + + + + + + + - - Avatar Online Status + + + + + + + - - Is this a mature profile + + + A block of data in a packet. Packets are composed of one or more blocks, + each block containing one or more fields + - - + + Current length of the data in this packet - - + + + Create a block from a byte array + + Byte array containing the serialized block + Starting position of the block in the byte array. + This will point to the data after the end of the block when the + call returns - + - Avatar interests including spoken languages, skills, and "want to" - choices + Serialize this block into a byte array + Byte array to serialize this block into + Starting position in the byte array to serialize to. + This will point to the position directly after the end of the + serialized block when the call returns - - Languages profile field + + A generic value, not an actual packet type - - + + - - + + - - + + - - + + - - Information about agents display name + + - - Agent UUID + + - - Username + + - - Display name + + - - First name (legacy) + + - - Last name (legacy) + + - - Is display name default display name + + - - Cache display name until + + - - Last updated timestamp + + - - - Creates AgentDisplayName object from OSD - - Incoming OSD data - AgentDisplayName object + + - - - Return object as OSD map - - OSD containing agent's display name data + + - - Full name (legacy) + + - - - Holds group information for Avatars such as those you might find in a profile - + + - - true of Avatar accepts group notices + + - - Groups Key + + - - Texture Key for groups insignia + + - - Name of the group + + - - Powers avatar has in the group + + - - Avatars Currently selected title + + - - true of Avatar has chosen to list this in their profile + + - - - Contains an animation currently being played by an agent - + + - - The ID of the animation asset + + - - A number to indicate start order of currently playing animations - On Linden Grids this number is unique per region, with OpenSim it is per client + + - - + + - - - Holds group information on an individual profile pick - + + - - - Retrieve friend status notifications, and retrieve avatar names and - profiles - + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarAnimation Event - An AvatarAnimationEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarAppearance Event - A AvatarAppearanceEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the UUIDNameReply Event - A UUIDNameReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarInterestsReply Event - A AvatarInterestsReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarPropertiesReply Event - A AvatarPropertiesReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarGroupsReply Event - A AvatarGroupsReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarPickerReply Event - A AvatarPickerReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the ViewerEffectPointAt Event - A ViewerEffectPointAtEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the ViewerEffectLookAt Event - A ViewerEffectLookAtEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the ViewerEffect Event - A ViewerEffectEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarPicksReply Event - A AvatarPicksReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the PickInfoReply Event - A PickInfoReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the AvatarClassifiedReply Event - A AvatarClassifiedReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the ClassifiedInfoReply Event - A ClassifiedInfoReplyEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the DisplayNameUpdate Event - A DisplayNameUpdateEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - - Represents other avatars - - + + - - Tracks the specified avatar on your map - Avatar ID to track + + - - - Request a single avatar name - - The avatar key to retrieve a name for + + - - - Request a list of avatar names - - The avatar keys to retrieve names for + + - - - Check if Display Names functionality is available - - True if Display name functionality is available + + - - - Request retrieval of display names (max 90 names per request) - - List of UUIDs to lookup - Callback to report result of the operation + + - - - Start a request for Avatar Properties - - + + - - - Search for an avatar (first name, last name) - - The name to search for - An ID to associate with this query + + - - - Start a request for Avatar Picks - - UUID of the avatar + + - - - Start a request for Avatar Classifieds - - UUID of the avatar + + - - - Start a request for details of a specific profile pick - - UUID of the avatar - UUID of the profile pick + + - - - Start a request for details of a specific profile classified - - UUID of the avatar - UUID of the profile classified + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - - EQ Message fired when someone nearby changes their display name - - The message key - the IMessage object containing the deserialized data sent from the simulator - The which originated the packet + + - - - Crossed region handler for message that comes across the EventQueue. Sent to an agent - when the agent crosses a sim border into a new region. - - The message key - the IMessage object containing the deserialized data sent from the simulator - The which originated the packet + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Raised when the simulator sends us data containing - an agents animation playlist + + - - Raised when the simulator sends us data containing - the appearance information for an agent + + - - Raised when the simulator sends us data containing - agent names/id values + + - - Raised when the simulator sends us data containing - the interests listed in an agents profile + + - - Raised when the simulator sends us data containing - profile property information for an agent + + - - Raised when the simulator sends us data containing - the group membership an agent is a member of + + - - Raised when the simulator sends us data containing - name/id pair + + - - Raised when the simulator sends us data containing - the objects and effect when an agent is pointing at + + - - Raised when the simulator sends us data containing - the objects and effect when an agent is looking at + + - - Raised when the simulator sends us data containing - an agents viewer effect information + + - - Raised when the simulator sends us data containing - the top picks from an agents profile + + - - Raised when the simulator sends us data containing - the Pick details + + - - Raised when the simulator sends us data containing - the classified ads an agent has placed + + - - Raised when the simulator sends us data containing - the details of a classified ad + + - - Raised when the simulator sends us data containing - the details of display name change + + - - - Callback giving results when fetching display names - - If the request was successful - Array of display names - Array of UUIDs that could not be fetched + + - - Provides data for the event - The event occurs when the simulator sends - the animation playlist for an agent - - The following code example uses the and - properties to display the animation playlist of an avatar on the window. - - // subscribe to the event - Client.Avatars.AvatarAnimation += Avatars_AvatarAnimation; - - private void Avatars_AvatarAnimation(object sender, AvatarAnimationEventArgs e) - { - // create a dictionary of "known" animations from the Animations class using System.Reflection - Dictionary<UUID, string> systemAnimations = new Dictionary<UUID, string>(); - Type type = typeof(Animations); - System.Reflection.FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); - foreach (System.Reflection.FieldInfo field in fields) - { - systemAnimations.Add((UUID)field.GetValue(type), field.Name); - } - - // find out which animations being played are known animations and which are assets - foreach (Animation animation in e.Animations) - { - if (systemAnimations.ContainsKey(animation.AnimationID)) - { - Console.WriteLine("{0} is playing {1} ({2}) sequence {3}", e.AvatarID, - systemAnimations[animation.AnimationID], animation.AnimationSequence); - } - else - { - Console.WriteLine("{0} is playing {1} (Asset) sequence {2}", e.AvatarID, - animation.AnimationID, animation.AnimationSequence); - } - } - } - - + + - - - Construct a new instance of the AvatarAnimationEventArgs class - - The ID of the agent - The list of animations to start + + - - Get the ID of the agent + + - - Get the list of animations to start + + - - Provides data for the event - The event occurs when the simulator sends - the appearance data for an avatar - - The following code example uses the and - properties to display the selected shape of an avatar on the window. - - // subscribe to the event - Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; - - // handle the data when the event is raised - void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) - { - Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") - } - - + + - - - Construct a new instance of the AvatarAppearanceEventArgs class - - The simulator request was from - The ID of the agent - true of the agent is a trial account - The default agent texture - The agents appearance layer textures - The for the agent + + - - Get the Simulator this request is from of the agent + + - - Get the ID of the agent + + - - true if the agent is a trial account + + - - Get the default agent texture + + - - Get the agents appearance layer textures + + - - Get the for the agent + + - - Version of the appearance system used. - Value greater than 0 indicates that server side baking is used + + - - Version of the Current Outfit Folder the appearance is based on + + - - Appearance flags, introduced with server side baking, currently unused + + - - Represents the interests from the profile of an agent + + - - Get the ID of the agent + + - - The properties of an agent + + - - Get the ID of the agent + + - - Get the ID of the agent + + - - Get the ID of the agent + + - - Get the ID of the avatar + + - - - Event args class for display name notification messages - + + - - - Wrapper around a byte array that allows bit to be packed and unpacked - one at a time or by a variable amount. Useful for very tightly packed - data like LayerData packets - + + - - + + - - - Default constructor, initialize the bit packer / bit unpacker - with a byte array and starting position - - Byte array to pack bits in to or unpack from - Starting position in the byte array + + - - - Pack a floating point value in to the data - - Floating point value to pack + + - - - Pack part or all of an integer in to the data - - Integer containing the data to pack - Number of bits of the integer to pack + + - - - Pack part or all of an unsigned integer in to the data - - Unsigned integer containing the data to pack - Number of bits of the integer to pack + + - - - Pack a single bit in to the data - - Bit to pack + + - - - - - - - - + + - - - - - + + - - - - - + + - - - Unpacking a floating point value from the data - - Unpacked floating point value + + - - - Unpack a variable number of bits from the data in to integer format - - Number of bits to unpack - An integer containing the unpacked bits - This function is only useful up to 32 bits + + - - - Unpack a variable number of bits from the data in to unsigned - integer format - - Number of bits to unpack - An unsigned integer containing the unpacked bits - This function is only useful up to 32 bits + + - - - Unpack a 16-bit signed integer - - 16-bit signed integer + + - - - Unpack a 16-bit unsigned integer - - 16-bit unsigned integer + + - - - Unpack a 32-bit signed integer - - 32-bit signed integer + + - - - Unpack a 32-bit unsigned integer - - 32-bit unsigned integer + + - - + + - - + + - - - Reads in a byte array of an Animation Asset created by the SecondLife(tm) client. - + + - - - Rotation Keyframe count (used internally) - + + - - - Position Keyframe count (used internally) - + + - - - Animation Priority - + + - - - The animation length in seconds. - + + - - - Expression set in the client. Null if [None] is selected - + + - - - The time in seconds to start the animation - + + - - - The time in seconds to end the animation - + + - - - Loop the animation - + + - - - Meta data. Ease in Seconds. - + + - - - Meta data. Ease out seconds. - + + - - - Meta Data for the Hand Pose - + + - - - Number of joints defined in the animation - + + - - - Contains an array of joints - + + - - - Searialize an animation asset into it's joints/keyframes/meta data - - + + - - - Variable length strings seem to be null terminated in the animation asset.. but.. - use with caution, home grown. - advances the index. - - The animation asset byte array - The offset to start reading - a string + + - - - Read in a Joint from an animation asset byte array - Variable length Joint fields, yay! - Advances the index - - animation asset byte array - Byte Offset of the start of the joint - The Joint data serialized into the binBVHJoint structure + + - - - Read Keyframes of a certain type - advance i - - Animation Byte array - Offset in the Byte Array. Will be advanced - Number of Keyframes - Scaling Min to pass to the Uint16ToFloat method - Scaling Max to pass to the Uint16ToFloat method - + + - - - Determines whether the specified is equal to the current . - - - true if the specified is equal to the current ; otherwise, false. - - The to compare with the current . - The parameter is null. - 2 + + - - - Serves as a hash function for a particular type. - - - A hash code for the current . - - 2 + + - - - A Joint and it's associated meta data and keyframes - + + - - - Indicates whether this instance and a specified object are equal. - - - true if and this instance are the same type and represent the same value; otherwise, false. - - Another object to compare to. - 2 + + - - - Returns the hash code for this instance. - - - A 32-bit signed integer that is the hash code for this instance. - - 2 + + - - - Name of the Joint. Matches the avatar_skeleton.xml in client distros - + + - - - Joint Animation Override? Was the same as the Priority in testing.. - + + - - - Array of Rotation Keyframes in order from earliest to latest - + + - - - Array of Position Keyframes in order from earliest to latest - This seems to only be for the Pelvis? - + + - - - Custom application data that can be attached to a joint - + + - - - A Joint Keyframe. This is either a position or a rotation. - + + - - - Either a Vector3 position or a Vector3 Euler rotation - + + - - - Poses set in the animation metadata for the hands. - + + - - - Capabilities is the name of the bi-directional HTTP REST protocol - used to communicate non real-time transactions such as teleporting or - group messaging - + + - - Reference to the simulator this system is connected to + + - - - Default constructor - - - + + - - - Request the URI of a named capability - - Name of the capability to request - The URI of the requested capability, or String.Empty if - the capability does not exist + + - - - Process any incoming events, check to see if we have a message created for the event, - - - + + - - Capabilities URI this system was initialized with + + - - Whether the capabilities event queue is connected and - listening for incoming events + + - - - Triggered when an event is received via the EventQueueGet - capability - - Event name - Decoded event data - The simulator that generated the event + + - - - Attempts to convert an LLSD structure to a known Packet type - - Event name, this must match an actual - packet name for a Packet to be successfully built - LLSD to convert to a Packet - A Packet on success, otherwise null + + - - - - - Looking direction, must be a normalized vector - Up direction, must be a normalized vector + + - - - Align the coordinate frame X and Y axis with a given rotation - around the Z axis in radians - - Absolute rotation around the Z axis in - radians + + - - Origin position of this coordinate frame + + - - X axis of this coordinate frame, or Forward/At in grid terms + + - - Y axis of this coordinate frame, or Left in grid terms + + - - Z axis of this coordinate frame, or Up in grid terms + + - - - Access to the data server which allows searching for land, events, people, etc - + + - - The event subscribers. null if no subcribers + + - - Raises the EventInfoReply event - An EventInfoReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the DirEventsReply event - An DirEventsReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the PlacesReply event - A PlacesReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the DirPlacesReply event - A DirPlacesReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the DirClassifiedsReply event - A DirClassifiedsReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the DirGroupsReply event - A DirGroupsReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the DirPeopleReply event - A DirPeopleReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the DirLandReply event - A DirLandReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - - Constructs a new instance of the DirectoryManager class - - An instance of GridClient + + - - - Query the data server for a list of classified ads containing the specified string. - Defaults to searching for classified placed in any category, and includes PG, Adult and Mature - results. - - Responses are sent 16 per response packet, there is no way to know how many results a query reply will contain however assuming - the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received - - The event is raised when a response is received from the simulator - - A string containing a list of keywords to search for - A UUID to correlate the results when the event is raised + + - - - Query the data server for a list of classified ads which contain specified keywords (Overload) - - The event is raised when a response is received from the simulator - - A string containing a list of keywords to search for - The category to search - A set of flags which can be ORed to modify query options - such as classified maturity rating. - A UUID to correlate the results when the event is raised - - Search classified ads containing the key words "foo" and "bar" in the "Any" category that are either PG or Mature - - UUID searchID = StartClassifiedSearch("foo bar", ClassifiedCategories.Any, ClassifiedQueryFlags.PG | ClassifiedQueryFlags.Mature); - - - - Responses are sent 16 at a time, there is no way to know how many results a query reply will contain however assuming - the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received - + + - - - Starts search for places (Overloaded) - - The event is raised when a response is received from the simulator - - Search text - Each request is limited to 100 places - being returned. To get the first 100 result entries of a request use 0, - from 100-199 use 1, 200-299 use 2, etc. - A UUID to correlate the results when the event is raised + + - - - Queries the dataserver for parcels of land which are flagged to be shown in search - - The event is raised when a response is received from the simulator - - A string containing a list of keywords to search for separated by a space character - A set of flags which can be ORed to modify query options - such as classified maturity rating. - The category to search - Each request is limited to 100 places - being returned. To get the first 100 result entries of a request use 0, - from 100-199 use 1, 200-299 use 2, etc. - A UUID to correlate the results when the event is raised - - Search places containing the key words "foo" and "bar" in the "Any" category that are either PG or Adult - - UUID searchID = StartDirPlacesSearch("foo bar", DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeAdult, ParcelCategory.Any, 0); - - - - Additional information on the results can be obtained by using the ParcelManager.InfoRequest method - + + - - - Starts a search for land sales using the directory - - The event is raised when a response is received from the simulator - - What type of land to search for. Auction, - estate, mainland, "first land", etc - The OnDirLandReply event handler must be registered before - calling this function. There is no way to determine how many - results will be returned, or how many times the callback will be - fired other than you won't get more than 100 total parcels from - each query. + + - - - Starts a search for land sales using the directory - - The event is raised when a response is received from the simulator - - What type of land to search for. Auction, - estate, mainland, "first land", etc - Maximum price to search for - Maximum area to search for - Each request is limited to 100 parcels - being returned. To get the first 100 parcels of a request use 0, - from 100-199 use 1, 200-299 use 2, etc. - The OnDirLandReply event handler must be registered before - calling this function. There is no way to determine how many - results will be returned, or how many times the callback will be - fired other than you won't get more than 100 total parcels from - each query. + + - - - Send a request to the data server for land sales listings - - - Flags sent to specify query options - - Available flags: - Specify the parcel rating with one or more of the following: - IncludePG IncludeMature IncludeAdult - - Specify the field to pre sort the results with ONLY ONE of the following: - PerMeterSort NameSort AreaSort PricesSort - - Specify the order the results are returned in, if not specified the results are pre sorted in a Descending Order - SortAsc - - Specify additional filters to limit the results with one or both of the following: - LimitByPrice LimitByArea - - Flags can be combined by separating them with the | (pipe) character - - Additional details can be found in - - What type of land to search for. Auction, - Estate or Mainland - Maximum price to search for when the - DirFindFlags.LimitByPrice flag is specified in findFlags - Maximum area to search for when the - DirFindFlags.LimitByArea flag is specified in findFlags - Each request is limited to 100 parcels - being returned. To get the first 100 parcels of a request use 0, - from 100-199 use 100, 200-299 use 200, etc. - The event will be raised with the response from the simulator - - There is no way to determine how many results will be returned, or how many times the callback will be - fired other than you won't get more than 100 total parcels from - each reply. - - Any land set for sale to either anybody or specific to the connected agent will be included in the - results if the land is included in the query - - - // request all mainland, any maturity rating that is larger than 512 sq.m - StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort | DirFindFlags.LimitByArea | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult, SearchTypeFlags.Mainland, 0, 512, 0); - + + - - - Search for Groups - - The name or portion of the name of the group you wish to search for - Start from the match number - + + - - - Search for Groups - - The name or portion of the name of the group you wish to search for - Start from the match number - Search flags - + + - - - Search the People directory for other avatars - - The name or portion of the name of the avatar you wish to search for - - + + - - - Search Places for parcels of land you personally own - + + - - - Searches Places for land owned by the specified group - - ID of the group you want to recieve land list for (You must be a member of the group) - Transaction (Query) ID which can be associated with results from your request. + + - - - Search the Places directory for parcels that are listed in search and contain the specified keywords - - A string containing the keywords to search for - Transaction (Query) ID which can be associated with results from your request. + + - - - Search Places - All Options - - One of the Values from the DirFindFlags struct, ie: AgentOwned, GroupOwned, etc. - One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer - A string containing a list of keywords to search for separated by a space character - String Simulator Name to search in - LLUID of group you want to recieve results for - Transaction (Query) ID which can be associated with results from your request. - Transaction (Query) ID which can be associated with results from your request. + + - - - Search All Events with specifid searchText in all categories, includes PG, Mature and Adult - - A string containing a list of keywords to search for separated by a space character - Each request is limited to 100 entries - being returned. To get the first group of entries of a request use 0, - from 100-199 use 100, 200-299 use 200, etc. - UUID of query to correlate results in callback. + + - - - Search Events - - A string containing a list of keywords to search for separated by a space character - One or more of the following flags: DateEvents, IncludePG, IncludeMature, IncludeAdult - from the Enum - - Multiple flags can be combined by separating the flags with the | (pipe) character - "u" for in-progress and upcoming events, -or- number of days since/until event is scheduled - For example "0" = Today, "1" = tomorrow, "2" = following day, "-1" = yesterday, etc. - Each request is limited to 100 entries - being returned. To get the first group of entries of a request use 0, - from 100-199 use 100, 200-299 use 200, etc. - EventCategory event is listed under. - UUID of query to correlate results in callback. + + - - Requests Event Details - ID of Event returned from the method + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming event message - The Unique Capabilities Key - The event message containing the data - The simulator the message originated from + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming event message - The Unique Capabilities Key - The event message containing the data - The simulator the message originated from + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Classified Ad categories + + - - Classified is listed in the Any category + + - - Classified is shopping related + + - - Classified is + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - Event Categories + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - Query Flags used in many of the DirectoryManager methods to specify which query to execute and how to return the results. - - Flags can be combined using the | (pipe) character, not all flags are available in all queries - + + - - Query the People database + + - - + + - - + + - - Query the Groups database + + - - Query the Events database + + - - Query the land holdings database for land owned by the currently connected agent + + - - + + - - Query the land holdings database for land which is owned by a Group + + - - Specifies the query should pre sort the results based upon traffic - when searching the Places database + + - - + + - - + + - - + + - - + + - - Specifies the query should pre sort the results in an ascending order when searching the land sales database. - This flag is only used when searching the land sales database + + - - Specifies the query should pre sort the results using the SalePrice field when searching the land sales database. - This flag is only used when searching the land sales database + + - - Specifies the query should pre sort the results by calculating the average price/sq.m (SalePrice / Area) when searching the land sales database. - This flag is only used when searching the land sales database + + - - Specifies the query should pre sort the results using the ParcelSize field when searching the land sales database. - This flag is only used when searching the land sales database + + - - Specifies the query should pre sort the results using the Name field when searching the land sales database. - This flag is only used when searching the land sales database + + - - When set, only parcels less than the specified Price will be included when searching the land sales database. - This flag is only used when searching the land sales database + + - - When set, only parcels greater than the specified Size will be included when searching the land sales database. - This flag is only used when searching the land sales database + + - - + + - - + + - - Include PG land in results. This flag is used when searching both the Groups, Events and Land sales databases + + - - Include Mature land in results. This flag is used when searching both the Groups, Events and Land sales databases + + - - Include Adult land in results. This flag is used when searching both the Groups, Events and Land sales databases + + - - + + - - - Land types to search dataserver for - + + - - Search Auction, Mainland and Estate + + - - Land which is currently up for auction + + - - Parcels which are on the mainland (Linden owned) continents + + - - Parcels which are on privately owned simulators + + - - - The content rating of the event - - - - Event is PG + + - - Event is Mature + + - - Event is Adult + + - - - Classified Ad Options - - There appear to be two formats the flags are packed in. - This set of flags is for the newer style + + - - + + - - + + - - + + - - + + - - + + - - - Classified ad query options - + + - - Include all ads in results + + - - Include PG ads in results + + - - Include Mature ads in results + + - - Include Adult ads in results + + - - - The For Sale flag in PlacesReplyData - + + - - Parcel is not listed for sale + + - - Parcel is For Sale + + - - - A classified ad on the grid - + + - - UUID for this ad, useful for looking up detailed - information about it + + - - The title of this classified ad + + - - Flags that show certain options applied to the classified + + - - Creation date of the ad + + - - Expiration date of the ad + + - - Price that was paid for this ad + + - - Print the struct data as a string - A string containing the field name, and field value + + - - - A parcel retrieved from the dataserver such as results from the - "For-Sale" listings or "Places" Search - + + - - The unique dataserver parcel ID - This id is used to obtain additional information from the entry - by using the method + + - - A string containing the name of the parcel + + - - The size of the parcel - This field is not returned for Places searches + + - - The price of the parcel - This field is not returned for Places searches + + - - If True, this parcel is flagged to be auctioned + + - - If true, this parcel is currently set for sale + + - - Parcel traffic + + - - Print the struct data as a string - A string containing the field name, and field value + + - - - An Avatar returned from the dataserver - + + - - Online status of agent - This field appears to be obsolete and always returns false + + - - The agents first name + + - - The agents last name + + - - The agents + + - - Print the struct data as a string - A string containing the field name, and field value + + - - - Response to a "Groups" Search - + + - - The Group ID + + - - The name of the group + + - - The current number of members + + - - Print the struct data as a string - A string containing the field name, and field value + + - - - Parcel information returned from a request - - Represents one of the following: - A parcel of land on the grid that has its Show In Search flag set - A parcel of land owned by the agent making the request - A parcel of land owned by a group the agent making the request is a member of - - - In a request for Group Land, the First record will contain an empty record - - Note: This is not the same as searching the land for sale data source - + + - - The ID of the Agent of Group that owns the parcel + + - - The name + + - - The description + + - - The Size of the parcel + + - - The billable Size of the parcel, for mainland - parcels this will match the ActualArea field. For Group owned land this will be 10 percent smaller - than the ActualArea. For Estate land this will always be 0 + + - - Indicates the ForSale status of the parcel + + - - The Gridwide X position + + - - The Gridwide Y position + + - - The Z position of the parcel, or 0 if no landing point set + + - - The name of the Region the parcel is located in + + - - The Asset ID of the parcels Snapshot texture + + - - The calculated visitor traffic + + - - The billing product SKU - Known values are: - - 023Mainland / Full Region - 024Estate / Full Region - 027Estate / Openspace - 029Estate / Homestead - 129Mainland / Homestead (Linden Owned) - - + + - - No longer used, will always be 0 + + - - Get a SL URL for the parcel - A string, containing a standard SLURL + + - - Print the struct data as a string - A string containing the field name, and field value + + - - - An "Event" Listing summary - + + - - The ID of the event creator + + - - The name of the event + + - - The events ID + + - - A string containing the short date/time the event will begin + + - - The event start time in Unixtime (seconds since epoch) + + - - The events maturity rating + + - - Print the struct data as a string - A string containing the field name, and field value + + - - - The details of an "Event" - + + - - The events ID + + - - The ID of the event creator + + - - The name of the event + + - - The category + + - - The events description + + - - The short date/time the event will begin + + - - The event start time in Unixtime (seconds since epoch) UTC adjusted + + - - The length of the event in minutes + + - - 0 if no cover charge applies + + - - The cover charge amount in L$ if applicable + + - - The name of the region where the event is being held + + - - The gridwide location of the event + + - - The maturity rating + + - - Get a SL URL for the parcel where the event is hosted - A string, containing a standard SLURL + + - - Print the struct data as a string - A string containing the field name, and field value + + - - Contains the Event data returned from the data server from an EventInfoRequest + + - - Construct a new instance of the EventInfoReplyEventArgs class - A single EventInfo object containing the details of an event + + - - - A single EventInfo object containing the details of an event - + + - - Contains the "Event" detail data returned from the data server + + - - Construct a new instance of the DirEventsReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list containing the "Events" returned by the search query + + - - The ID returned by + + - - A list of "Events" returned by the data server + + - - Contains the "Event" list data returned from the data server + + - - Construct a new instance of PlacesReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list containing the "Places" returned by the data server query + + - - The ID returned by + + - - A list of "Places" returned by the data server + + - - Contains the places data returned from the data server + + - - Construct a new instance of the DirPlacesReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list containing land data returned by the data server + + - - The ID returned by + + - - A list containing Places data returned by the data server + + - - Contains the classified data returned from the data server + + - - Construct a new instance of the DirClassifiedsReplyEventArgs class - A list of classified ad data returned from the data server + + - - A list containing Classified Ads returned by the data server + + - - Contains the group data returned from the data server + + - - Construct a new instance of the DirGroupsReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list of groups data returned by the data server + + - - The ID returned by + + - - A list containing Groups data returned by the data server + + - - Contains the people data returned from the data server + + - - Construct a new instance of the DirPeopleReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list of people data returned by the data server + + - - The ID returned by + + - - A list containing People data returned by the data server + + - - Contains the land sales data returned from the data server + + - - Construct a new instance of the DirLandReplyEventArgs class - A list of parcels for sale returned by the data server + + - - A list containing land forsale data returned by the data server + + - - - Represends individual HTTP Download request - + + - - URI of the item to fetch + + - - Timout specified in milliseconds + + - - Download progress callback + + - - Download completed callback + + - - Accept the following content type + + - - How many times will this request be retried + + - - Current fetch attempt + + - - Default constructor + + - - Constructor + + - - - Manages async HTTP downloads with a limit on maximum - concurrent downloads - + + - - Default constructor + + - - Cleanup method + + - - Setup http download request + + - - Check the queue for pending work + + - - Enqueue a new HTTP download + + - - Maximum number of parallel downloads from a single endpoint + + - - Client certificate + + - - Describes tasks returned in LandStatReply + + - - - Estate level administration and utilities - + + - - Textures for each of the four terrain height levels + + - - Upper/lower texture boundaries for each corner of the sim + + - - - Constructor for EstateTools class - - + + - - The event subscribers. null if no subcribers + + - - Raises the TopCollidersReply event - A TopCollidersReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the TopScriptsReply event - A TopScriptsReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the EstateUsersReply event - A EstateUsersReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the EstateGroupsReply event - A EstateGroupsReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the EstateManagersReply event - A EstateManagersReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the EstateBansReply event - A EstateBansReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the EstateCovenantReply event - A EstateCovenantReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the EstateUpdateInfoReply event - A EstateUpdateInfoReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - - Requests estate information such as top scripts and colliders - - - - - + + - - Requests estate settings, including estate manager and access/ban lists + + - - Requests the "Top Scripts" list for the current region + + - - Requests the "Top Colliders" list for the current region + + - - - Set several estate specific configuration variables - - The Height of the waterlevel over the entire estate. Defaults to 20 - The maximum height change allowed above the baked terrain. Defaults to 4 - The minimum height change allowed below the baked terrain. Defaults to -4 - true to use - if True forces the sun position to the position in SunPosition - The current position of the sun on the estate, or when FixedSun is true the static position - the sun will remain. 6.0 = Sunrise, 30.0 = Sunset + + - - - Request return of objects owned by specified avatar - - The Agents owning the primitives to return - specify the coverage and type of objects to be included in the return - true to perform return on entire estate + + - - - - + + - - - Used for setting and retrieving various estate panel settings - - EstateOwnerMessage Method field - List of parameters to include + + - - - Kick an avatar from an estate - - Key of Agent to remove + + - - - Ban an avatar from an estate - Key of Agent to remove - Ban user from this estate and all others owned by the estate owner + + - - Unban an avatar from an estate - Key of Agent to remove - /// Unban user from this estate and all others owned by the estate owner + + - - - Send a message dialog to everyone in an entire estate - - Message to send all users in the estate + + - - - Send a message dialog to everyone in a simulator - - Message to send all users in the simulator + + - - - Send an avatar back to their home location - - Key of avatar to send home + + - - - Begin the region restart process - + + - - - Cancels a region restart - + + - - Estate panel "Region" tab settings + + - - Estate panel "Debug" tab settings + + - - Used for setting the region's terrain textures for its four height levels - - - - + + - - Used for setting sim terrain texture heights + + - - Requests the estate covenant + + - - - Upload a terrain RAW file - - A byte array containing the encoded terrain data - The name of the file being uploaded - The Id of the transfer request + + - - - Teleports all users home in current Estate - + + - - - Remove estate manager - Key of Agent to Remove - removes manager to this estate and all others owned by the estate owner + + - - - Add estate manager - Key of Agent to Add - Add agent as manager to this estate and all others owned by the estate owner + + - - - Add's an agent to the estate Allowed list - Key of Agent to Add - Add agent as an allowed reisdent to All estates if true + + - - - Removes an agent from the estate Allowed list - Key of Agent to Remove - Removes agent as an allowed reisdent from All estates if true + + - - - - Add's a group to the estate Allowed list - Key of Group to Add - Add Group as an allowed group to All estates if true + + - - - - Removes a group from the estate Allowed list - Key of Group to Remove - Removes Group as an allowed Group from All estates if true + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Raised when the data server responds to a request. + + - - Used in the ReportType field of a LandStatRequest + + - - Used by EstateOwnerMessage packets + + - - Used by EstateOwnerMessage packets + + - - - - + + - - No flags set + + - - Only return targets scripted objects + + - - Only return targets objects if on others land + + - - Returns target's scripted objects and objects on other parcels + + - - Ground texture settings for each corner of the region + + - - Used by GroundTextureHeightSettings + + - - The high and low texture thresholds for each corner of the sim + + - - Raised on LandStatReply when the report type is for "top colliders" + + - - Construct a new instance of the TopCollidersReplyEventArgs class - The number of returned items in LandStatReply - Dictionary of Object UUIDs to tasks returned in LandStatReply + + - - - The number of returned items in LandStatReply - + + - - - A Dictionary of Object UUIDs to tasks returned in LandStatReply - + + - - Raised on LandStatReply when the report type is for "top Scripts" + + - - Construct a new instance of the TopScriptsReplyEventArgs class - The number of returned items in LandStatReply - Dictionary of Object UUIDs to tasks returned in LandStatReply + + - - - The number of scripts returned in LandStatReply - + + - - - A Dictionary of Object UUIDs to tasks returned in LandStatReply - + + - - Returned, along with other info, upon a successful .RequestInfo() + + - - Construct a new instance of the EstateBansReplyEventArgs class - The estate's identifier on the grid - The number of returned items in LandStatReply - User UUIDs banned + + - - - The identifier of the estate - + + - - - The number of returned itmes - + + - - - List of UUIDs of Banned Users - + + - - Returned, along with other info, upon a successful .RequestInfo() + + - - Construct a new instance of the EstateUsersReplyEventArgs class - The estate's identifier on the grid - The number of users - Allowed users UUIDs + + - - - The identifier of the estate - + + - - - The number of returned items - + + - - - List of UUIDs of Allowed Users - + + - - Returned, along with other info, upon a successful .RequestInfo() + + - - Construct a new instance of the EstateGroupsReplyEventArgs class - The estate's identifier on the grid - The number of Groups - Allowed Groups UUIDs + + - - - The identifier of the estate - + + - - - The number of returned items - + + - - - List of UUIDs of Allowed Groups - + + - - Returned, along with other info, upon a successful .RequestInfo() + + - - Construct a new instance of the EstateManagersReplyEventArgs class - The estate's identifier on the grid - The number of Managers - Managers UUIDs + + - - - The identifier of the estate - + + - - - The number of returned items - + + - - - List of UUIDs of the Estate's Managers - + + - - Returned, along with other info, upon a successful .RequestInfo() + + - - Construct a new instance of the EstateCovenantReplyEventArgs class - The Covenant ID - The timestamp - The estate's name - The Estate Owner's ID (can be a GroupID) + + - - - The Covenant - + + - - - The timestamp - + + - - - The Estate name - + + - - - The Estate Owner's ID (can be a GroupID) - + + - - Returned, along with other info, upon a successful .RequestInfo() + + - - Construct a new instance of the EstateUpdateInfoReplyEventArgs class - The estate's name - The Estate Owners ID (can be a GroupID) - The estate's identifier on the grid - + + - - - The estate's name - + + - - - The Estate Owner's ID (can be a GroupID) - + + - - - The identifier of the estate on the grid - + + - - + + - - - Registers, unregisters, and fires events generated by incoming packets - + + - - Reference to the GridClient object + + - - - Default constructor - - + + - - - Register an event handler - - Use PacketType.Default to fire this event on every - incoming packet - Packet type to register the handler for - Callback to be fired - True if this callback should be ran - asynchronously, false to run it synchronous + + - - - Unregister an event handler - - Packet type to unregister the handler for - Callback to be unregistered + + - - - Fire the events registered for this packet type - - Incoming packet type - Incoming packet - Simulator this packet was received from + + - - - Object that is passed to worker threads in the ThreadPool for - firing packet callbacks - + + - - Callback to fire for this packet + + - - Reference to the simulator that this packet came from + + - - The packet that needs to be processed + + - - - Registers, unregisters, and fires events generated by the Capabilities - event queue - + + - - Reference to the GridClient object + + - - - Default constructor - - Reference to the GridClient object + + - - - Register an new event handler for a capabilities event sent via the EventQueue - - Use String.Empty to fire this event on every CAPS event - Capability event name to register the - handler for - Callback to fire + + - - - Unregister a previously registered capabilities handler - - Capability event name unregister the - handler for - Callback to unregister + + - - - Fire the events registered for this event type synchronously - - Capability name - Decoded event body - Reference to the simulator that - generated this event + + - - - Fire the events registered for this event type asynchronously - - Capability name - Decoded event body - Reference to the simulator that - generated this event + + - - - Object that is passed to worker threads in the ThreadPool for - firing CAPS callbacks - + + - - Callback to fire for this packet + + - - Name of the CAPS event + + - - Strongly typed decoded data + + - - Reference to the simulator that generated this event + + - - - - + + - - The avatar has no rights + + - - The avatar can see the online status of the target avatar + + - - The avatar can see the location of the target avatar on the map + + - - The avatar can modify the ojects of the target avatar + + - - - This class holds information about an avatar in the friends list. There are two ways - to interface to this class. The first is through the set of boolean properties. This is the typical - way clients of this class will use it. The second interface is through two bitflag properties, - TheirFriendsRights and MyFriendsRights - + + - - - Used internally when building the initial list of friends at login time - - System ID of the avatar being prepesented - Rights the friend has to see you online and to modify your objects - Rights you have to see your friend online and to modify their objects + + - - - FriendInfo represented as a string - - A string reprentation of both my rights and my friends rights + + - - - System ID of the avatar - + + - - - full name of the avatar - + + - - - True if the avatar is online - + + - - - True if the friend can see if I am online - + + - - - True if the friend can see me on the map - + + - - - True if the freind can modify my objects - + + - - - True if I can see if my friend is online - + + - - - True if I can see if my friend is on the map - + + - - - True if I can modify my friend's objects - + + - - - My friend's rights represented as bitmapped flags - + + - - - My rights represented as bitmapped flags - + + - - - This class is used to add and remove avatars from your friends list and to manage their permission. - - - - The event subscribers. null if no subcribers + + - - Raises the FriendOnline event - A FriendInfoEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendOffline event - A FriendInfoEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendRightsUpdate event - A FriendInfoEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendNames event - A FriendNamesEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendshipOffered event - A FriendshipOfferedEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendshipResponse event - A FriendshipResponseEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendshipTerminated event - A FriendshipTerminatedEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the FriendFoundReply event - A FriendFoundReplyEventArgs object containing the - data returned from the data server + + - - Thread sync lock object + + - - - A dictionary of key/value pairs containing known friends of this avatar. - - The Key is the of the friend, the value is a - object that contains detailed information including permissions you have and have given to the friend - + + - - - A Dictionary of key/value pairs containing current pending frienship offers. - - The key is the of the avatar making the request, - the value is the of the request which is used to accept - or decline the friendship offer - + + - - - Internal constructor - - A reference to the GridClient Object + + - - - Accept a friendship request - - agentID of avatatar to form friendship with - imSessionID of the friendship request message + + - - - Decline a friendship request - - of friend - imSessionID of the friendship request message + + - - - Overload: Offer friendship to an avatar. - - System ID of the avatar you are offering friendship to + + - - - Offer friendship to an avatar. - - System ID of the avatar you are offering friendship to - A message to send with the request + + - - - Terminate a friendship with an avatar - - System ID of the avatar you are terminating the friendship with + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - - Change the rights of a friend avatar. - - the of the friend - the new rights to give the friend - This method will implicitly set the rights to those passed in the rights parameter. + + - - - Use to map a friends location on the grid. - - Friends UUID to find - + + - - - Use to track a friends movement on the grid - - Friends Key + + - - - Ask for a notification of friend's online status - - Friend's UUID + + - - - This handles the asynchronous response of a RequestAvatarNames call. - - - names cooresponding to the the list of IDs sent the the RequestAvatarNames call. + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - - Populate FriendList with data from the login reply - - true if login was successful - true if login request is requiring a redirect - A string containing the response to the login request - A string containing the reason for the request - A object containing the decoded - reply from the login server + + - - Raised when the simulator sends notification one of the members in our friends list comes online + + - - Raised when the simulator sends notification one of the members in our friends list goes offline + + - - Raised when the simulator sends notification one of the members in our friends list grants or revokes permissions + + - - Raised when the simulator sends us the names on our friends list + + - - Raised when the simulator sends notification another agent is offering us friendship + + - - Raised when a request we sent to friend another agent is accepted or declined + + - - Raised when the simulator sends notification one of the members in our friends list has terminated - our friendship + + - - Raised when the simulator sends the location of a friend we have - requested map location info for + + - - Contains information on a member of our friends list + + - - - Construct a new instance of the FriendInfoEventArgs class - - The FriendInfo + + - - Get the FriendInfo + + - - Contains Friend Names + + - - - Construct a new instance of the FriendNamesEventArgs class - - A dictionary where the Key is the ID of the Agent, - and the Value is a string containing their name + + - - A dictionary where the Key is the ID of the Agent, - and the Value is a string containing their name + + - - Sent when another agent requests a friendship with our agent + + - - - Construct a new instance of the FriendshipOfferedEventArgs class - - The ID of the agent requesting friendship - The name of the agent requesting friendship - The ID of the session, used in accepting or declining the - friendship offer + + - - Get the ID of the agent requesting friendship + + - - Get the name of the agent requesting friendship + + - - Get the ID of the session, used in accepting or declining the - friendship offer + + - - A response containing the results of our request to form a friendship with another agent + + - - - Construct a new instance of the FriendShipResponseEventArgs class - - The ID of the agent we requested a friendship with - The name of the agent we requested a friendship with - true if the agent accepted our friendship offer + + - - Get the ID of the agent we requested a friendship with + + - - Get the name of the agent we requested a friendship with + + - - true if the agent accepted our friendship offer + + - - Contains data sent when a friend terminates a friendship with us + + - - - Construct a new instance of the FrindshipTerminatedEventArgs class - - The ID of the friend who terminated the friendship with us - The name of the friend who terminated the friendship with us + + - - Get the ID of the agent that terminated the friendship with us + + - - Get the name of the agent that terminated the friendship with us + + - - - Data sent in response to a request which contains the information to allow us to map the friends location - + + - - - Construct a new instance of the FriendFoundReplyEventArgs class - - The ID of the agent we have requested location information for - The region handle where our friend is located - The simulator local position our friend is located + + - - Get the ID of the agent we have received location information for + + - - Get the region handle where our mapped friend is located + + - - Get the simulator local position where our friend is located + + - - - Main class to expose grid functionality to clients. All of the - classes needed for sending and receiving data are accessible through - this class. - - - - // Example minimum code required to instantiate class and - // connect to a simulator. - using System; - using System.Collections.Generic; - using System.Text; - using OpenMetaverse; - - namespace FirstBot - { - class Bot - { - public static GridClient Client; - static void Main(string[] args) - { - Client = new GridClient(); // instantiates the GridClient class - // to the global Client object - // Login to Simulator - Client.Network.Login("FirstName", "LastName", "Password", "FirstBot", "1.0"); - // Wait for a Keypress - Console.ReadLine(); - // Logout of simulator - Client.Network.Logout(); - } - } - } - - + + - - Networking subsystem + + - - Settings class including constant values and changeable - parameters for everything + + - - Parcel (subdivided simulator lots) subsystem + + - - Our own avatars subsystem + + - - Other avatars subsystem + + - - Estate subsystem + + - - Friends list subsystem + + - - Grid (aka simulator group) subsystem + + - - Object subsystem + + - - Group subsystem + + - - Asset subsystem + + - - Appearance subsystem + + - - Inventory subsystem + + - - Directory searches including classifieds, people, land - sales, etc + + - - Handles land, wind, and cloud heightmaps + + - - Handles sound-related networking + + - - Throttling total bandwidth usage, or allocating bandwidth - for specific data stream types + + - - - Default constructor - + + - - - Return the full name of this instance - - Client avatars full name + + - - - Map layer request type - + + - - Objects and terrain are shown + + - - Only the terrain is shown, no objects + + - - Overlay showing land for sale and for auction + + - - - Type of grid item, such as telehub, event, populator location, etc. - + + - - Telehub + + - - PG rated event + + - - Mature rated event + + - - Popular location + + - - Locations of avatar groups in a region + + - - Land for sale + + - - Classified ad + + - - Adult rated event + + - - Adult land for sale + + - - - Information about a region on the grid map - + + - - Sim X position on World Map + + - - Sim Y position on World Map + + - - Sim Name (NOTE: In lowercase!) + + - - + + - - Appears to always be zero (None) + + - - Sim's defined Water Height + + - - + + - - UUID of the World Map image + + - - Unique identifier for this region, a combination of the X - and Y position + + - - - - - + + - - - - - + + - - - - - - + + - - - Visual chunk of the grid map - + + - - - Base class for Map Items - + + - - The Global X position of the item + + - - The Global Y position of the item + + - - Get the Local X position of the item + + - - Get the Local Y position of the item + + - - Get the Handle of the region + + - - - Represents an agent or group of agents location - + + - - - Represents a Telehub location - + + - - - Represents a non-adult parcel of land for sale - + + - - - Represents an Adult parcel of land for sale - + + - - - Represents a PG Event - + + - - - Represents a Mature event - + + - - - Represents an Adult event - + + - - - Manages grid-wide tasks such as the world map - + + - - The event subscribers. null if no subcribers + + - - Raises the CoarseLocationUpdate event - A CoarseLocationUpdateEventArgs object containing the - data sent by simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GridRegion event - A GridRegionEventArgs object containing the - data sent by simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GridLayer event - A GridLayerEventArgs object containing the - data sent by simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GridItems event - A GridItemEventArgs object containing the - data sent by simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the RegionHandleReply event - A RegionHandleReplyEventArgs object containing the - data sent by simulator + + - - Thread sync lock object + + - - A dictionary of all the regions, indexed by region name + + - - A dictionary of all the regions, indexed by region handle + + - - - Constructor - - Instance of GridClient object to associate with this GridManager instance + + - - - - - + + - - - Request a map layer - - The name of the region - The type of layer + + - - - - - - - - - - + + - - - - - - - - - + + - - - - - - - + + - - - Request data for all mainland (Linden managed) simulators - + + - - - Request the region handle for the specified region UUID - - UUID of the region to look up + + - - - Get grid region information using the region name, this function - will block until it can find the region or gives up - - Name of sim you're looking for - Layer that you are requesting - Will contain a GridRegion for the sim you're - looking for if successful, otherwise an empty structure - True if the GridRegion was successfully fetched, otherwise - false + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Raised when the simulator sends a - containing the location of agents in the simulator + + - - Raised when the simulator sends a Region Data in response to - a Map request + + - - Raised when the simulator sends GridLayer object containing - a map tile coordinates and texture information + + - - Raised when the simulator sends GridItems object containing - details on events, land sales at a specific location + + - - Raised in response to a Region lookup + + - - Unknown + + - - Current direction of the sun + + - - Current angular velocity of the sun + + - - Microseconds since the start of SL 4-hour day + + - - - Avatar group management - + + - - Key of Group Member + + - - Total land contribution + + - - Online status information + + - - Abilities that the Group Member has + + - - Current group title + + - - Is a group owner + + - - - Role manager for a group - + + - - Key of the group + + - - Key of Role + + - - Name of Role + + - - Group Title associated with Role + + - - Description of Role + + - - Abilities Associated with Role + + - - Returns the role's title - The role's title + + - - - Class to represent Group Title - + + - - Key of the group + + - - ID of the role title belongs to + + - - Group Title + + - - Whether title is Active + + - - Returns group title + + - - - Represents a group on the grid - + + - - Key of Group + + - - Key of Group Insignia + + - - Key of Group Founder + + - - Key of Group Role for Owners + + - - Name of Group + + - - Text of Group Charter + + - - Title of "everyone" role + + - - Is the group open for enrolement to everyone + + - - Will group show up in search + + - - + + - - + + - - + + - - Is the group Mature + + - - Cost of group membership + + - - + + - - + + - - The total number of current members this group has + + - - The number of roles this group has configured + + - - Show this group in agent's profile + + - - Returns the name of the group - A string containing the name of the group + + - - - A group Vote - + + - - Key of Avatar who created Vote + + - - Text of the Vote proposal + + - - Total number of votes + + - - - A group proposal - + + - - The Text of the proposal + + - - The minimum number of members that must vote before proposal passes or failes + + - - The required ration of yes/no votes required for vote to pass - The three options are Simple Majority, 2/3 Majority, and Unanimous - TODO: this should be an enum + + - - The duration in days votes are accepted + + - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - Struct representing a group notice - + + - - + + - - + + - - + + - - + + - - - - - + + - - - Struct representing a group notice list entry - + + - - Notice ID + + - - Creation timestamp of notice + + - - Agent name who created notice + + - - Notice subject + + - - Is there an attachment? + + - - Attachment Type + + - - - Struct representing a member of a group chat session and their settings - + + - - The of the Avatar + + - - True if user has voice chat enabled + + - - True of Avatar has moderator abilities + + - - True if a moderator has muted this avatars chat + + - - True if a moderator has muted this avatars voice + + - - - Role update flags - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - Can send invitations to groups default role + + - - Can eject members from group + + - - Can toggle 'Open Enrollment' and change 'Signup fee' + + - - Member is visible in the public member list + + - - Can create new roles + + - - Can delete existing roles + + - - Can change Role names, titles and descriptions + + - - Can assign other members to assigners role + + - - Can assign other members to any role + + - - Can remove members from roles + + - - Can assign and remove abilities in roles + + - - Can change group Charter, Insignia, 'Publish on the web' and which - members are publicly visible in group member listings + + - - Can buy land or deed land to group + + - - Can abandon group owned land to Governor Linden on mainland, or Estate owner for - private estates + + - - Can set land for-sale information on group owned parcels + + - - Can subdivide and join parcels + + - - Can join group chat sessions + + - - Can use voice chat in Group Chat sessions + + - - Can moderate group chat sessions + + - - Can toggle "Show in Find Places" and set search category + + - - Can change parcel name, description, and 'Publish on web' settings + + - - Can set the landing point and teleport routing on group land + + - - Can change music and media settings + + - - Can toggle 'Edit Terrain' option in Land settings + + - - Can toggle various About Land > Options settings + + - - Can always terraform land, even if parcel settings have it turned off + + - - Can always fly while over group owned land + + - - Can always rez objects on group owned land + + - - Can always create landmarks for group owned parcels + + - - Can set home location on any group owned parcel + + - - Can modify public access settings for group owned parcels + + - - Can manager parcel ban lists on group owned land + + - - Can manage pass list sales information + + - - Can eject and freeze other avatars on group owned land + + - - Can return objects set to group + + - - Can return non-group owned/set objects + + - - Can return group owned objects + + - - Can landscape using Linden plants + + - - Can deed objects to group + + - - Can move group owned objects + + - - Can set group owned objects for-sale + + - - Pay group liabilities and receive group dividends + + - - List and Host group events + + - - Can send group notices + + - - Can receive group notices + + - - Can create group proposals + + - - Can vote on group proposals + + - - - Ban actions available for group members - + + - - Ban agent from joining a group + + - - Remove restriction on agent jointing a group + + - - - Handles all network traffic related to reading and writing group - information - + + - - The event subscribers. null if no subcribers + + - - Raises the CurrentGroups event - A CurrentGroupsEventArgs object containing the - data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupNamesReply event - A GroupNamesEventArgs object containing the - data response from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupProfile event - An GroupProfileEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupMembers event - A GroupMembersEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupRolesDataReply event - A GroupRolesDataReplyEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupRoleMembersReply event - A GroupRolesRoleMembersReplyEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupTitlesReply event - A GroupTitlesReplyEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupAccountSummary event - A GroupAccountSummaryReplyEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupCreated event - An GroupCreatedEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupJoined event - A GroupOperationEventArgs object containing the - result of the operation returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupLeft event - A GroupOperationEventArgs object containing the - result of the operation returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupDropped event - An GroupDroppedEventArgs object containing the - the group your agent left + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupMemberEjected event - An GroupMemberEjectedEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupNoticesListReply event - An GroupNoticesListReplyEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the GroupInvitation event - An GroupInvitationEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - The event subscribers. null if no subcribers + + - - Raises the BannedAgents event - An BannedAgentsEventArgs object containing the - data returned from the simulator + + - - Thread sync lock object + + - - A reference to the current instance + + - - Currently-active group members requests + + - - Currently-active group roles requests + + - - Currently-active group role-member requests + + - - Dictionary keeping group members while request is in progress + + - - Dictionary keeping mebmer/role mapping while request is in progress + + - - Dictionary keeping GroupRole information while request is in progress + + - - Caches group name lookups + + - - - Construct a new instance of the GroupManager class - - A reference to the current instance + + - - - Request a current list of groups the avatar is a member of. - - CAPS Event Queue must be running for this to work since the results - come across CAPS. + + - - - Lookup name of group based on groupID - - groupID of group to lookup name for. + + - - - Request lookup of multiple group names - - List of group IDs to request. + + - - Lookup group profile data such as name, enrollment, founder, logo, etc - Subscribe to OnGroupProfile event to receive the results. - group ID (UUID) + + - - Request a list of group members. - Subscribe to OnGroupMembers event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache + + - - Request group roles - Subscribe to OnGroupRoles event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache + + - - Request members (members,role) role mapping for a group. - Subscribe to OnGroupRolesMembers event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache + + - - Request a groups Titles - Subscribe to OnGroupTitles event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache + + - - Begin to get the group account summary - Subscribe to the OnGroupAccountSummary event to receive the results. - group ID (UUID) - How long of an interval - Which interval (0 for current, 1 for last) + + - - Invites a user to a group - The group to invite to - A list of roles to invite a person to - Key of person to invite + + - - Set a group as the current active group - group ID (UUID) + + - - Change the role that determines your active title - Group ID to use - Role ID to change to + + - - Set this avatar's tier contribution - Group ID to change tier in - amount of tier to donate + + - - - Save wheather agent wants to accept group notices and list this group in their profile - - Group - Accept notices from this group - List this group in the profile + + - - Request to join a group - Subscribe to OnGroupJoined event for confirmation. - group ID (UUID) to join. + + - - - Request to create a new group. If the group is successfully - created, L$100 will automatically be deducted - - Subscribe to OnGroupCreated event to receive confirmation. - Group struct containing the new group info + + - - Update a group's profile and other information - Groups ID (UUID) to update. - Group struct to update. + + - - Eject a user from a group - Group ID to eject the user from - Avatar's key to eject + + - - Update role information - Modified role to be updated + + - - Create a new group role - Group ID to update - Role to create + + - - Delete a group role - Group ID to update - Role to delete + + - - Remove an avatar from a role - Group ID to update - Role ID to be removed from - Avatar's Key to remove + + - - Assign an avatar to a role - Group ID to update - Role ID to assign to - Avatar's ID to assign to role + + - - Request the group notices list - Group ID to fetch notices for + + - - Request a group notice by key - ID of group notice + + - - Send out a group notice - Group ID to update - GroupNotice structure containing notice data + + - - Start a group proposal (vote) - The Group ID to send proposal to - GroupProposal structure containing the proposal + + - - Request to leave a group - Subscribe to OnGroupLeft event to receive confirmation - The group to leave + + - - - Gets the URI of the cpability for handling group bans - - Group ID - null, if the feature is not supported, or URI of the capability + + - - - Request a list of residents banned from joining a group - - UUID of the group + + - - - Request a list of residents banned from joining a group - - UUID of the group - Callback on request completition + + - - - Request that group of agents be banned or unbanned from the group - - Group ID - Ban/Unban action - Array of agents UUIDs to ban + + - - - Request that group of agents be banned or unbanned from the group - - Group ID - Ban/Unban action - Array of agents UUIDs to ban - Callback + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Raised when the simulator sends us data containing - our current group membership + + - - Raised when the simulator responds to a RequestGroupName - or RequestGroupNames request + + - - Raised when the simulator responds to a request + + - - Raised when the simulator responds to a request + + - - Raised when the simulator responds to a request + + - - Raised when the simulator responds to a request + + - - Raised when the simulator responds to a request + + - - Raised when a response to a RequestGroupAccountSummary is returned - by the simulator + + - - Raised when a request to create a group is successful + + - - Raised when a request to join a group either - fails or succeeds + + - - Raised when a request to leave a group either - fails or succeeds + + - - Raised when A group is removed from the group server + + - - Raised when a request to eject a member from a group either - fails or succeeds + + - - Raised when the simulator sends us group notices - + + - - Raised when another agent invites our avatar to join a group + + - - Raised when another agent invites our avatar to join a group + + - - Contains the current groups your agent is a member of + + - - Construct a new instance of the CurrentGroupsEventArgs class - The current groups your agent is a member of + + - - Get the current groups your agent is a member of + + - - A Dictionary of group names, where the Key is the groups ID and the value is the groups name + + - - Construct a new instance of the GroupNamesEventArgs class - The Group names dictionary + + - - Get the Group Names dictionary + + - - Represents the members of a group + + - - - Construct a new instance of the GroupMembersReplyEventArgs class - - The ID of the request - The ID of the group - The membership list of the group + + - - Get the ID as returned by the request to correlate - this result set and the request + + - - Get the ID of the group + + - - Get the dictionary of members + + - - Represents the roles associated with a group + + - - Construct a new instance of the GroupRolesDataReplyEventArgs class - The ID as returned by the request to correlate - this result set and the request - The ID of the group - The dictionary containing the roles + + - - Get the ID as returned by the request to correlate - this result set and the request + + - - Get the ID of the group + + - - Get the dictionary containing the roles + + - - Represents the Role to Member mappings for a group + + - - Construct a new instance of the GroupRolesMembersReplyEventArgs class - The ID as returned by the request to correlate - this result set and the request - The ID of the group - The member to roles map + + - - Get the ID as returned by the request to correlate - this result set and the request + + - - Get the ID of the group + + - - Get the member to roles map + + - - Represents the titles for a group + + - - Construct a new instance of the GroupTitlesReplyEventArgs class - The ID as returned by the request to correlate - this result set and the request - The ID of the group - The titles + + - - Get the ID as returned by the request to correlate - this result set and the request + + - - Get the ID of the group + + - - Get the titles + + - - Represents the summary data for a group + + - - Construct a new instance of the GroupAccountSummaryReplyEventArgs class - The ID of the group - The summary data + + - - Get the ID of the group + + - - Get the summary data + + - - A response to a group create request + + - - Construct a new instance of the GroupCreatedReplyEventArgs class - The ID of the group - the success or faulure of the request - A string containing additional information + + - - Get the ID of the group + + - - true of the group was created successfully + + - - A string containing the message + + - - Represents a response to a request + + - - Construct a new instance of the GroupOperationEventArgs class - The ID of the group - true of the request was successful + + - - Get the ID of the group + + - - true of the request was successful + + - - Represents your agent leaving a group + + - - Construct a new instance of the GroupDroppedEventArgs class - The ID of the group + + - - Get the ID of the group + + - - Represents a list of active group notices + + - - Construct a new instance of the GroupNoticesListReplyEventArgs class - The ID of the group - The list containing active notices + + - - Get the ID of the group + + - - Get the notices list + + - - Represents the profile of a group + + - - Construct a new instance of the GroupProfileEventArgs class - The group profile + + - - Get the group profile + + - - - Provides notification of a group invitation request sent by another Avatar - - The invitation is raised when another avatar makes an offer for our avatar - to join a group. + + - - The ID of the Avatar sending the group invitation + + - - The name of the Avatar sending the group invitation + + - - A message containing the request information which includes - the name of the group, the groups charter and the fee to join details + + - - The Simulator + + - - Set to true to accept invitation, false to decline + + - - - Result of the request for list of agents banned from a group - + + - - Indicates if list of banned agents for a group was successfully retrieved + + - - Indicates if list of banned agents for a group was successfully retrieved + + - - Array containing a list of UUIDs of the agents banned from a group + + - - - Static helper functions and global variables - + + - - This header flag signals that ACKs are appended to the packet + + - - This header flag signals that this packet has been sent before + + - - This header flags signals that an ACK is expected for this packet + + - - This header flag signals that the message is compressed using zerocoding + + - - - - - - + + - - - - - - - + + - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Origin position of this coordinate frame + + + X axis of this coordinate frame, or Forward/At in grid terms + + + Y axis of this coordinate frame, or Left in grid terms + + + Z axis of this coordinate frame, or Up in grid terms + + - - - + Looking direction, must be a normalized vector + Up direction, must be a normalized vector - + - Given an X/Y location in absolute (grid-relative) terms, a region - handle is returned along with the local X/Y location in that region + Align the coordinate frame X and Y axis with a given rotation + around the Z axis in radians - The absolute X location, a number such as - 255360.35 - The absolute Y location, a number such as - 255360.35 - The sim-local X position of the global X - position, a value from 0.0 to 256.0 - The sim-local Y position of the global Y - position, a value from 0.0 to 256.0 - A 64-bit region handle that can be used to teleport to + Absolute rotation around the Z axis in + radians - + - Converts a floating point number to a terse string format used for - transmitting numbers in wearable asset files + Access to the data server which allows searching for land, events, people, etc - Floating point number to convert to a string - A terse string representation of the input number - - - Convert a variable length field (byte array) to a string, with a - field name prepended to each line of the output - - If the byte array has unprintable characters in it, a - hex dump will be written instead - The StringBuilder object to write to - The byte array to convert to a string - A field name to prepend to each line of output + + Classified Ad categories - - - Decode a zerocoded byte array, used to decompress packets marked - with the zerocoded flag - - Any time a zero is encountered, the next byte is a count - of how many zeroes to expand. One zero is encoded with 0x00 0x01, - two zeroes is 0x00 0x02, three zeroes is 0x00 0x03, etc. The - first four bytes are copied directly to the output buffer. - - The byte array to decode - The length of the byte array to decode. This - would be the length of the packet up to (but not including) any - appended ACKs - The output byte array to decode to - The length of the output buffer + + Classified is listed in the Any category - - - Encode a byte array with zerocoding. Used to compress packets marked - with the zerocoded flag. Any zeroes in the array are compressed down - to a single zero byte followed by a count of how many zeroes to expand - out. A single zero becomes 0x00 0x01, two zeroes becomes 0x00 0x02, - three zeroes becomes 0x00 0x03, etc. The first four bytes are copied - directly to the output buffer. - - The byte array to encode - The length of the byte array to encode - The output byte array to encode to - The length of the output buffer + + Classified is shopping related - - - Calculates the CRC (cyclic redundancy check) needed to upload inventory. - - Creation date - Sale type - Inventory type - Type - Asset ID - Group ID - Sale price - Owner ID - Creator ID - Item ID - Folder ID - Everyone mask (permissions) - Flags - Next owner mask (permissions) - Group mask (permissions) - Owner mask (permissions) - The calculated CRC + + Classified is - - - Attempts to load a file embedded in the assembly - - The filename of the resource to load - A Stream for the requested file, or null if the resource - was not successfully loaded + + - - - Attempts to load a file either embedded in the assembly or found in - a given search path - - The filename of the resource to load - An optional path that will be searched if - the asset is not found embedded in the assembly - A Stream for the requested file, or null if the resource - was not successfully loaded + + - - - Converts a list of primitives to an object that can be serialized - with the LLSD system - - Primitives to convert to a serializable object - An object that can be serialized with LLSD + + - - - Deserializes OSD in to a list of primitives - - Structure holding the serialized primitive list, - must be of the SDMap type - A list of deserialized primitives + + - - - Converts a struct or class object containing fields only into a key value separated string - - The struct object - A string containing the struct fields as the keys, and the field value as the value separated - - - // Add the following code to any struct or class containing only fields to override the ToString() - // method to display the values of the passed object - - /// Print the struct data as a string - ///A string containing the field name, and field value - public override string ToString() - { - return Helpers.StructToString(this); - } - - + + - - - Passed to Logger.Log() to identify the severity of a log entry - + + - - No logging information will be output + + - - Non-noisy useful information, may be helpful in - debugging a problem + + Event Categories - - A non-critical error occurred. A warning will not - prevent the rest of the library from operating as usual, - although it may be indicative of an underlying issue + + - - A critical error has occurred. Generally this will - be followed by the network layer shutting down, although the - stability of the library after an error is uncertain + + - - Used for internal testing, this logging level can - generate very noisy (long and/or repetitive) messages. Don't - pass this to the Log() function, use DebugLog() instead. - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - The InternalDictionary class is used through the library for storing key/value pairs. - It is intended to be a replacement for the generic Dictionary class and should - be used in its place. It contains several methods for allowing access to the data from - outside the library that are read only and thread safe. + Query Flags used in many of the DirectoryManager methods to specify which query to execute and how to return the results. + Flags can be combined using the | (pipe) character, not all flags are available in all queries - Key - Value - - Internal dictionary that this class wraps around. Do not - modify or enumerate the contents of this dictionary without locking - on this member + + Query the People database - - - Initializes a new instance of the Class - with the specified key/value, has the default initial capacity. - - - - // initialize a new InternalDictionary named testDict with a string as the key and an int as the value. - public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(); - - + + - - - Initializes a new instance of the Class - with the specified key/value, has its initial valies copied from the specified - - - - to copy initial values from - - - // initialize a new InternalDictionary named testAvName with a UUID as the key and an string as the value. - // populates with copied values from example KeyNameCache Dictionary. - - // create source dictionary - Dictionary<UUID, string> KeyNameCache = new Dictionary<UUID, string>(); - KeyNameCache.Add("8300f94a-7970-7810-cf2c-fc9aa6cdda24", "Jack Avatar"); - KeyNameCache.Add("27ba1e40-13f7-0708-3e98-5819d780bd62", "Jill Avatar"); - - // Initialize new dictionary. - public InternalDictionary<UUID, string> testAvName = new InternalDictionary<UUID, string>(KeyNameCache); - - + + - - - Initializes a new instance of the Class - with the specified key/value, With its initial capacity specified. - - Initial size of dictionary - - - // initialize a new InternalDictionary named testDict with a string as the key and an int as the value, - // initially allocated room for 10 entries. - public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(10); - - + + Query the Groups database - - - Try to get entry from with specified key - - Key to use for lookup - Value returned - if specified key exists, if not found - - - // find your avatar using the Simulator.ObjectsAvatars InternalDictionary: - Avatar av; - if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) - Console.WriteLine("Found Avatar {0}", av.Name); - - - + + Query the Events database - - - Finds the specified match. - - The match. - Matched value - - - // use a delegate to find a prim in the ObjectsPrimitives InternalDictionary - // with the ID 95683496 - uint findID = 95683496; - Primitive findPrim = sim.ObjectsPrimitives.Find( - delegate(Primitive prim) { return prim.ID == findID; }); - - + + Query the land holdings database for land owned by the currently connected agent - - Find All items in an - return matching items. - a containing found items. - - Find All prims within 20 meters and store them in a List - - int radius = 20; - List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( - delegate(Primitive prim) { - Vector3 pos = prim.Position; - return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); - } - ); - - + + - - Find All items in an - return matching keys. - a containing found keys. - - Find All keys which also exist in another dictionary - - List<UUID> matches = myDict.FindAll( - delegate(UUID id) { - return myOtherDict.ContainsKey(id); - } - ); - - + + Query the land holdings database for land which is owned by a Group - - Perform an on each entry in an - to perform - - - // Iterates over the ObjectsPrimitives InternalDictionary and prints out some information. - Client.Network.CurrentSim.ObjectsPrimitives.ForEach( - delegate(Primitive prim) - { - if (prim.Text != null) - { - Console.WriteLine("NAME={0} ID = {1} TEXT = '{2}'", - prim.PropertiesFamily.Name, prim.ID, prim.Text); - } - }); - - + + Specifies the query should pre sort the results based upon traffic + when searching the Places database - - Perform an on each key of an - to perform + + - - - Perform an on each KeyValuePair of an - - to perform + + - - Check if Key exists in Dictionary - Key to check for - if found, otherwise + + - - Check if Value exists in Dictionary - Value to check for - if found, otherwise + + - - - Adds the specified key to the dictionary, dictionary locking is not performed, - - - The key - The value + + Specifies the query should pre sort the results in an ascending order when searching the land sales database. + This flag is only used when searching the land sales database - - - Removes the specified key, dictionary locking is not performed - - The key. - if successful, otherwise + + Specifies the query should pre sort the results using the SalePrice field when searching the land sales database. + This flag is only used when searching the land sales database - - - Gets the number of Key/Value pairs contained in the - + + Specifies the query should pre sort the results by calculating the average price/sq.m (SalePrice / Area) when searching the land sales database. + This flag is only used when searching the land sales database - - - Indexer for the dictionary - - The key - The value + + Specifies the query should pre sort the results using the ParcelSize field when searching the land sales database. + This flag is only used when searching the land sales database - + + Specifies the query should pre sort the results using the Name field when searching the land sales database. + This flag is only used when searching the land sales database + + + When set, only parcels less than the specified Price will be included when searching the land sales database. + This flag is only used when searching the land sales database + + + When set, only parcels greater than the specified Size will be included when searching the land sales database. + This flag is only used when searching the land sales database + + + + + + + + + Include PG land in results. This flag is used when searching both the Groups, Events and Land sales databases + + + Include Mature land in results. This flag is used when searching both the Groups, Events and Land sales databases + + + Include Adult land in results. This flag is used when searching both the Groups, Events and Land sales databases + + + + + - Exception class to identify inventory exceptions + Land types to search dataserver for - + + Search Auction, Mainland and Estate + + + Land which is currently up for auction + + + Parcels which are on the mainland (Linden owned) continents + + + Parcels which are on privately owned simulators + + - Responsible for maintaining inventory structure. Inventory constructs nodes - and manages node children as is necessary to maintain a coherant hirarchy. - Other classes should not manipulate or create InventoryNodes explicitly. When - A node's parent changes (when a folder is moved, for example) simply pass - Inventory the updated InventoryFolder and it will make the appropriate changes - to its internal representation. + The content rating of the event - - The event subscribers, null of no subscribers + + Event is PG - - Raises the InventoryObjectUpdated Event - A InventoryObjectUpdatedEventArgs object containing - the data sent from the simulator + + Event is Mature - - Thread sync lock object + + Event is Adult - - The event subscribers, null of no subscribers + + + Classified Ad Options + + There appear to be two formats the flags are packed in. + This set of flags is for the newer style - - Raises the InventoryObjectRemoved Event - A InventoryObjectRemovedEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the InventoryObjectAdded Event - A InventoryObjectAddedEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + - + - Returns the contents of the specified folder + Classified ad query options - A folder's UUID - The contents of the folder corresponding to folder - When folder does not exist in the inventory - - - Updates the state of the InventoryNode and inventory data structure that - is responsible for the InventoryObject. If the item was previously not added to inventory, - it adds the item, and updates structure accordingly. If it was, it updates the - InventoryNode, changing the parent node if item.parentUUID does - not match node.Parent.Data.UUID. - - You can not set the inventory root folder using this method - - The InventoryObject to store + + Include all ads in results - + + Include PG ads in results + + + Include Mature ads in results + + + Include Adult ads in results + + - Removes the InventoryObject and all related node data from Inventory. + The For Sale flag in PlacesReplyData - The InventoryObject to remove. - + + Parcel is not listed for sale + + + Parcel is For Sale + + - Used to find out if Inventory contains the InventoryObject - specified by uuid. + A classified ad on the grid - The UUID to check. - true if inventory contains uuid, false otherwise - + + UUID for this ad, useful for looking up detailed + information about it + + + The title of this classified ad + + + Flags that show certain options applied to the classified + + + Creation date of the ad + + + Expiration date of the ad + + + Price that was paid for this ad + + + Print the struct data as a string + A string containing the field name, and field value + + - Saves the current inventory structure to a cache file + A parcel retrieved from the dataserver such as results from the + "For-Sale" listings or "Places" Search - Name of the cache file to save to - + + The unique dataserver parcel ID + This id is used to obtain additional information from the entry + by using the method + + + A string containing the name of the parcel + + + The size of the parcel + This field is not returned for Places searches + + + The price of the parcel + This field is not returned for Places searches + + + If True, this parcel is flagged to be auctioned + + + If true, this parcel is currently set for sale + + + Parcel traffic + + + Print the struct data as a string + A string containing the field name, and field value + + - Loads in inventory cache file into the inventory structure. Note only valid to call after login has been successful. + An Avatar returned from the dataserver - Name of the cache file to load - The number of inventory items sucessfully reconstructed into the inventory node tree - - Raised when the simulator sends us data containing - ... + + Online status of agent + This field appears to be obsolete and always returns false - - Raised when the simulator sends us data containing - ... + + The agents first name - - Raised when the simulator sends us data containing - ... + + The agents last name + + + The agents + + + Print the struct data as a string + A string containing the field name, and field value - + - The root folder of this avatars inventory + Response to a "Groups" Search - - - The default shared library folder - + + The Group ID - - - The root node of the avatars inventory - + + The name of the group - - - The root node of the default shared library - + + The current number of members - + + Print the struct data as a string + A string containing the field name, and field value + + - By using the bracket operator on this class, the program can get the - InventoryObject designated by the specified uuid. If the value for the corresponding - UUID is null, the call is equivelant to a call to RemoveNodeFor(this[uuid]). - If the value is non-null, it is equivelant to a call to UpdateNodeFor(value), - the uuid parameter is ignored. + Parcel information returned from a request + + Represents one of the following: + A parcel of land on the grid that has its Show In Search flag set + A parcel of land owned by the agent making the request + A parcel of land owned by a group the agent making the request is a member of + + + In a request for Group Land, the First record will contain an empty record + + Note: This is not the same as searching the land for sale data source - The UUID of the InventoryObject to get or set, ignored if set to non-null value. - The InventoryObject corresponding to uuid. - - Sort by name + + The ID of the Agent of Group that owns the parcel - - Sort by date + + The name - - Sort folders by name, regardless of whether items are - sorted by name or date + + The description - - Place system folders at the top + + The Size of the parcel - - - Possible destinations for DeRezObject request - + + The billable Size of the parcel, for mainland + parcels this will match the ActualArea field. For Group owned land this will be 10 percent smaller + than the ActualArea. For Estate land this will always be 0 - - + + Indicates the ForSale status of the parcel - - Copy from in-world to agent inventory + + The Gridwide X position - - Derez to TaskInventory + + The Gridwide Y position - - + + The Z position of the parcel, or 0 if no landing point set - - Take Object + + The name of the Region the parcel is located in - - + + The Asset ID of the parcels Snapshot texture - - Delete Object + + The calculated visitor traffic - - Put an avatar attachment into agent inventory + + The billing product SKU + Known values are: + + 023Mainland / Full Region + 024Estate / Full Region + 027Estate / Openspace + 029Estate / Homestead + 129Mainland / Homestead (Linden Owned) + + - - + + No longer used, will always be 0 - - Return an object back to the owner's inventory + + Get a SL URL for the parcel + A string, containing a standard SLURL - - Return a deeded object back to the last owner's inventory + + Print the struct data as a string + A string containing the field name, and field value - + - Upper half of the Flags field for inventory items + An "Event" Listing summary - - Indicates that the NextOwner permission will be set to the - most restrictive set of permissions found in the object set - (including linkset items and object inventory items) on next rez - - - Indicates that the object sale information has been - changed - - - If set, and a slam bit is set, indicates BaseMask will be overwritten on Rez + + The ID of the event creator - - If set, and a slam bit is set, indicates OwnerMask will be overwritten on Rez + + The name of the event - - If set, and a slam bit is set, indicates GroupMask will be overwritten on Rez + + The events ID - - If set, and a slam bit is set, indicates EveryoneMask will be overwritten on Rez + + A string containing the short date/time the event will begin - - If set, and a slam bit is set, indicates NextOwnerMask will be overwritten on Rez + + The event start time in Unixtime (seconds since epoch) - - Indicates whether this object is composed of multiple - items or not + + The events maturity rating - - Indicates that the asset is only referenced by this - inventory item. If this item is deleted or updated to reference a - new assetID, the asset can be deleted + + Print the struct data as a string + A string containing the field name, and field value - + - Base Class for Inventory Items + The details of an "Event" - - of item/folder + + The events ID - - of parent folder + + The ID of the event creator - - Name of item/folder + + The name of the event - - Item/Folder Owners + + The category - - - Constructor, takes an itemID as a parameter - - The of the item + + The events description - - - - - + + The short date/time the event will begin - - - - - + + The event start time in Unixtime (seconds since epoch) UTC adjusted - - - Generates a number corresponding to the value of the object to support the use of a hash table, - suitable for use in hashing algorithms and data structures such as a hash table - - A Hashcode of all the combined InventoryBase fields + + The length of the event in minutes - - - Determine whether the specified object is equal to the current object - - InventoryBase object to compare against - true if objects are the same + + 0 if no cover charge applies - - - Determine whether the specified object is equal to the current object - - InventoryBase object to compare against - true if objects are the same + + The cover charge amount in L$ if applicable - - - Convert inventory to OSD - - OSD representation + + The name of the region where the event is being held - - - An Item in Inventory - + + The gridwide location of the event - - The of this item + + The maturity rating - - The combined of this item + + Get a SL URL for the parcel where the event is hosted + A string, containing a standard SLURL - - The type of item from + + Print the struct data as a string + A string containing the field name, and field value - - The type of item from the enum + + The event subscribers. null if no subcribers - - The of the creator of this item + + Raises the EventInfoReply event + An EventInfoReplyEventArgs object containing the + data returned from the data server - - A Description of this item + + Thread sync lock object - - The s this item is set to or owned by + + Raised when the data server responds to a request. - - If true, item is owned by a group + + The event subscribers. null if no subcribers - - The price this item can be purchased for + + Raises the DirEventsReply event + An DirEventsReplyEventArgs object containing the + data returned from the data server - - The type of sale from the enum + + Thread sync lock object - - Combined flags from + + Raised when the data server responds to a request. - - Time and date this inventory item was created, stored as - UTC (Coordinated Universal Time) + + The event subscribers. null if no subcribers - - Used to update the AssetID in requests sent to the server + + Raises the PlacesReply event + A PlacesReplyEventArgs object containing the + data returned from the data server - - The of the previous owner of the item + + Thread sync lock object - - - Construct a new InventoryItem object - - The of the item + + Raised when the data server responds to a request. - - - Construct a new InventoryItem object of a specific Type - - The type of item from - of the item + + The event subscribers. null if no subcribers - - - Indicates inventory item is a link - - True if inventory item is a link to another inventory item + + Raises the DirPlacesReply event + A DirPlacesReplyEventArgs object containing the + data returned from the data server - - - - - + + Thread sync lock object - - - - - + + Raised when the data server responds to a request. - - - Generates a number corresponding to the value of the object to support the use of a hash table. - Suitable for use in hashing algorithms and data structures such as a hash table - - A Hashcode of all the combined InventoryItem fields + + The event subscribers. null if no subcribers - - - Compares an object - - The object to compare - true if comparison object matches + + Raises the DirClassifiedsReply event + A DirClassifiedsReplyEventArgs object containing the + data returned from the data server - - - Determine whether the specified object is equal to the current object - - The object to compare against - true if objects are the same + + Thread sync lock object - - - Determine whether the specified object is equal to the current object - - The object to compare against - true if objects are the same + + Raised when the data server responds to a request. - - - Create InventoryItem from OSD - - OSD Data that makes up InventoryItem - Inventory item created + + The event subscribers. null if no subcribers - - - Convert InventoryItem to OSD - - OSD representation of InventoryItem + + Raises the DirGroupsReply event + A DirGroupsReplyEventArgs object containing the + data returned from the data server - - - InventoryTexture Class representing a graphical image - - + + Thread sync lock object - - - Construct an InventoryTexture object - - A which becomes the - objects AssetUUID + + Raised when the data server responds to a request. - - - Construct an InventoryTexture object from a serialization stream - + + The event subscribers. null if no subcribers - - - InventorySound Class representing a playable sound - + + Raises the DirPeopleReply event + A DirPeopleReplyEventArgs object containing the + data returned from the data server - - - Construct an InventorySound object - - A which becomes the - objects AssetUUID + + Thread sync lock object - - - Construct an InventorySound object from a serialization stream - + + Raised when the data server responds to a request. - - - InventoryCallingCard Class, contains information on another avatar - + + The event subscribers. null if no subcribers - - - Construct an InventoryCallingCard object - - A which becomes the - objects AssetUUID + + Raises the DirLandReply event + A DirLandReplyEventArgs object containing the + data returned from the data server - - - Construct an InventoryCallingCard object from a serialization stream - + + Thread sync lock object - + + Raised when the data server responds to a request. + + - InventoryLandmark Class, contains details on a specific location + Constructs a new instance of the DirectoryManager class + An instance of GridClient - + - Construct an InventoryLandmark object + Query the data server for a list of classified ads containing the specified string. + Defaults to searching for classified placed in any category, and includes PG, Adult and Mature + results. + + Responses are sent 16 per response packet, there is no way to know how many results a query reply will contain however assuming + the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received + + The event is raised when a response is received from the simulator - A which becomes the - objects AssetUUID + A string containing a list of keywords to search for + A UUID to correlate the results when the event is raised - + - Construct an InventoryLandmark object from a serialization stream + Query the data server for a list of classified ads which contain specified keywords (Overload) + + The event is raised when a response is received from the simulator + A string containing a list of keywords to search for + The category to search + A set of flags which can be ORed to modify query options + such as classified maturity rating. + A UUID to correlate the results when the event is raised + + Search classified ads containing the key words "foo" and "bar" in the "Any" category that are either PG or Mature + + UUID searchID = StartClassifiedSearch("foo bar", ClassifiedCategories.Any, ClassifiedQueryFlags.PG | ClassifiedQueryFlags.Mature); + + + + Responses are sent 16 at a time, there is no way to know how many results a query reply will contain however assuming + the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received + - + - Landmarks use the InventoryItemFlags struct and will have a flag of 1 set if they have been visited + Starts search for places (Overloaded) + + The event is raised when a response is received from the simulator + Search text + Each request is limited to 100 places + being returned. To get the first 100 result entries of a request use 0, + from 100-199 use 1, 200-299 use 2, etc. + A UUID to correlate the results when the event is raised - + - InventoryObject Class contains details on a primitive or coalesced set of primitives + Queries the dataserver for parcels of land which are flagged to be shown in search + + The event is raised when a response is received from the simulator + A string containing a list of keywords to search for separated by a space character + A set of flags which can be ORed to modify query options + such as classified maturity rating. + The category to search + Each request is limited to 100 places + being returned. To get the first 100 result entries of a request use 0, + from 100-199 use 1, 200-299 use 2, etc. + A UUID to correlate the results when the event is raised + + Search places containing the key words "foo" and "bar" in the "Any" category that are either PG or Adult + + UUID searchID = StartDirPlacesSearch("foo bar", DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeAdult, ParcelCategory.Any, 0); + + + + Additional information on the results can be obtained by using the ParcelManager.InfoRequest method + - + - Construct an InventoryObject object + Starts a search for land sales using the directory + + The event is raised when a response is received from the simulator - A which becomes the - objects AssetUUID + What type of land to search for. Auction, + estate, mainland, "first land", etc + The OnDirLandReply event handler must be registered before + calling this function. There is no way to determine how many + results will be returned, or how many times the callback will be + fired other than you won't get more than 100 total parcels from + each query. - + - Construct an InventoryObject object from a serialization stream + Starts a search for land sales using the directory + + The event is raised when a response is received from the simulator + What type of land to search for. Auction, + estate, mainland, "first land", etc + Maximum price to search for + Maximum area to search for + Each request is limited to 100 parcels + being returned. To get the first 100 parcels of a request use 0, + from 100-199 use 1, 200-299 use 2, etc. + The OnDirLandReply event handler must be registered before + calling this function. There is no way to determine how many + results will be returned, or how many times the callback will be + fired other than you won't get more than 100 total parcels from + each query. - + - Gets or sets the upper byte of the Flags value + Send a request to the data server for land sales listings + + Flags sent to specify query options + + Available flags: + Specify the parcel rating with one or more of the following: + IncludePG IncludeMature IncludeAdult + + Specify the field to pre sort the results with ONLY ONE of the following: + PerMeterSort NameSort AreaSort PricesSort + + Specify the order the results are returned in, if not specified the results are pre sorted in a Descending Order + SortAsc + + Specify additional filters to limit the results with one or both of the following: + LimitByPrice LimitByArea + + Flags can be combined by separating them with the | (pipe) character + + Additional details can be found in + + What type of land to search for. Auction, + Estate or Mainland + Maximum price to search for when the + DirFindFlags.LimitByPrice flag is specified in findFlags + Maximum area to search for when the + DirFindFlags.LimitByArea flag is specified in findFlags + Each request is limited to 100 parcels + being returned. To get the first 100 parcels of a request use 0, + from 100-199 use 100, 200-299 use 200, etc. + The event will be raised with the response from the simulator + + There is no way to determine how many results will be returned, or how many times the callback will be + fired other than you won't get more than 100 total parcels from + each reply. + + Any land set for sale to either anybody or specific to the connected agent will be included in the + results if the land is included in the query + + + // request all mainland, any maturity rating that is larger than 512 sq.m + StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort | DirFindFlags.LimitByArea | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult, SearchTypeFlags.Mainland, 0, 512, 0); + - + - Gets or sets the object attachment point, the lower byte of the Flags value + Search for Groups + The name or portion of the name of the group you wish to search for + Start from the match number + - + - InventoryNotecard Class, contains details on an encoded text document + Search for Groups + The name or portion of the name of the group you wish to search for + Start from the match number + Search flags + - + - Construct an InventoryNotecard object + Search the People directory for other avatars - A which becomes the - objects AssetUUID + The name or portion of the name of the avatar you wish to search for + + - + - Construct an InventoryNotecard object from a serialization stream + Search Places for parcels of land you personally own - + - InventoryCategory Class + Searches Places for land owned by the specified group - TODO: Is this even used for anything? + ID of the group you want to recieve land list for (You must be a member of the group) + Transaction (Query) ID which can be associated with results from your request. - + - Construct an InventoryCategory object + Search the Places directory for parcels that are listed in search and contain the specified keywords - A which becomes the - objects AssetUUID + A string containing the keywords to search for + Transaction (Query) ID which can be associated with results from your request. - + - Construct an InventoryCategory object from a serialization stream + Search Places - All Options + One of the Values from the DirFindFlags struct, ie: AgentOwned, GroupOwned, etc. + One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer + A string containing a list of keywords to search for separated by a space character + String Simulator Name to search in + LLUID of group you want to recieve results for + Transaction (Query) ID which can be associated with results from your request. + Transaction (Query) ID which can be associated with results from your request. - + - InventoryLSL Class, represents a Linden Scripting Language object + Search All Events with specifid searchText in all categories, includes PG, Mature and Adult + A string containing a list of keywords to search for separated by a space character + Each request is limited to 100 entries + being returned. To get the first group of entries of a request use 0, + from 100-199 use 100, 200-299 use 200, etc. + UUID of query to correlate results in callback. - + - Construct an InventoryLSL object + Search Events - A which becomes the - objects AssetUUID + A string containing a list of keywords to search for separated by a space character + One or more of the following flags: DateEvents, IncludePG, IncludeMature, IncludeAdult + from the Enum + + Multiple flags can be combined by separating the flags with the | (pipe) character + "u" for in-progress and upcoming events, -or- number of days since/until event is scheduled + For example "0" = Today, "1" = tomorrow, "2" = following day, "-1" = yesterday, etc. + Each request is limited to 100 entries + being returned. To get the first group of entries of a request use 0, + from 100-199 use 100, 200-299 use 200, etc. + EventCategory event is listed under. + UUID of query to correlate results in callback. - - - Construct an InventoryLSL object from a serialization stream - + + Requests Event Details + ID of Event returned from the method - - - InventorySnapshot Class, an image taken with the viewer - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Construct an InventorySnapshot object - - A which becomes the - objects AssetUUID + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Construct an InventorySnapshot object from a serialization stream - + + Process an incoming event message + The Unique Capabilities Key + The event message containing the data + The simulator the message originated from - - - InventoryAttachment Class, contains details on an attachable object - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Construct an InventoryAttachment object - - A which becomes the - objects AssetUUID + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Construct an InventoryAttachment object from a serialization stream - + + Process an incoming event message + The Unique Capabilities Key + The event message containing the data + The simulator the message originated from - - - Get the last AttachmentPoint this object was attached to - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - InventoryWearable Class, details on a clothing item or body part - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Construct an InventoryWearable object - - A which becomes the - objects AssetUUID + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Construct an InventoryWearable object from a serialization stream - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - The , Skin, Shape, Skirt, Etc - + + Contains the Event data returned from the data server from an EventInfoRequest - + - InventoryAnimation Class, A bvh encoded object which animates an avatar + A single EventInfo object containing the details of an event - - - Construct an InventoryAnimation object - - A which becomes the - objects AssetUUID + + Construct a new instance of the EventInfoReplyEventArgs class + A single EventInfo object containing the details of an event - - - Construct an InventoryAnimation object from a serialization stream - + + Contains the "Event" detail data returned from the data server - - - InventoryGesture Class, details on a series of animations, sounds, and actions - + + The ID returned by - - - Construct an InventoryGesture object - - A which becomes the - objects AssetUUID + + A list of "Events" returned by the data server - - - Construct an InventoryGesture object from a serialization stream - + + Construct a new instance of the DirEventsReplyEventArgs class + The ID of the query returned by the data server. + This will correlate to the ID returned by the method + A list containing the "Events" returned by the search query - - - A folder contains s and has certain attributes specific - to itself - + + Contains the "Event" list data returned from the data server - - The Preferred for a folder. + + The ID returned by - - The Version of this folder + + A list of "Places" returned by the data server - - Number of child items this folder contains. + + Construct a new instance of PlacesReplyEventArgs class + The ID of the query returned by the data server. + This will correlate to the ID returned by the method + A list containing the "Places" returned by the data server query - - - Constructor - - UUID of the folder + + Contains the places data returned from the data server - - - - - + + The ID returned by - - - Get Serilization data for this InventoryFolder object - + + A list containing Places data returned by the data server - - - Construct an InventoryFolder object from a serialization stream - + + Construct a new instance of the DirPlacesReplyEventArgs class + The ID of the query returned by the data server. + This will correlate to the ID returned by the method + A list containing land data returned by the data server - - - - - + + Contains the classified data returned from the data server - - - - - - + + A list containing Classified Ads returned by the data server - - - - - - + + Construct a new instance of the DirClassifiedsReplyEventArgs class + A list of classified ad data returned from the data server - - - - - - + + Contains the group data returned from the data server - - - Create InventoryFolder from OSD - - OSD Data that makes up InventoryFolder - Inventory folder created + + The ID returned by - - - Convert InventoryItem to OSD - - OSD representation of InventoryItem + + A list containing Groups data returned by the data server - - - Tools for dealing with agents inventory - + + Construct a new instance of the DirGroupsReplyEventArgs class + The ID of the query returned by the data server. + This will correlate to the ID returned by the method + A list of groups data returned by the data server - - Used for converting shadow_id to asset_id + + Contains the people data returned from the data server - - The event subscribers, null of no subscribers + + The ID returned by - - Raises the ItemReceived Event - A ItemReceivedEventArgs object containing - the data sent from the simulator + + A list containing People data returned by the data server - - Thread sync lock object + + Construct a new instance of the DirPeopleReplyEventArgs class + The ID of the query returned by the data server. + This will correlate to the ID returned by the method + A list of people data returned by the data server - - The event subscribers, null of no subscribers + + Contains the land sales data returned from the data server - - Raises the FolderUpdated Event - A FolderUpdatedEventArgs object containing - the data sent from the simulator + + A list containing land forsale data returned by the data server - - Thread sync lock object + + Construct a new instance of the DirLandReplyEventArgs class + A list of parcels for sale returned by the data server - - The event subscribers, null of no subscribers + + + Represends individual HTTP Download request + - - Raises the InventoryObjectOffered Event - A InventoryObjectOfferedEventArgs object containing - the data sent from the simulator + + URI of the item to fetch - - Thread sync lock object + + Timout specified in milliseconds - - The event subscribers, null of no subscribers + + Download progress callback - - Raises the TaskItemReceived Event - A TaskItemReceivedEventArgs object containing - the data sent from the simulator + + Download completed callback - - Thread sync lock object + + Accept the following content type - - The event subscribers, null of no subscribers + + How many times will this request be retried - - Raises the FindObjectByPath Event - A FindObjectByPathEventArgs object containing - the data sent from the simulator + + Current fetch attempt - - Thread sync lock object + + Default constructor - - The event subscribers, null of no subscribers + + Constructor - - Raises the TaskInventoryReply Event - A TaskInventoryReplyEventArgs object containing - the data sent from the simulator + + + Manages async HTTP downloads with a limit on maximum + concurrent downloads + - - Thread sync lock object + + Maximum number of parallel downloads from a single endpoint - - The event subscribers, null of no subscribers + + Client certificate - - Raises the SaveAssetToInventory Event - A SaveAssetToInventoryEventArgs object containing - the data sent from the simulator + + Default constructor - - Thread sync lock object + + Cleanup method - - The event subscribers, null of no subscribers + + Setup http download request - - Raises the ScriptRunningReply Event - A ScriptRunningReplyEventArgs object containing - the data sent from the simulator + + Check the queue for pending work - - Thread sync lock object + + Enqueue a new HTTP download - - Partial mapping of AssetTypes to folder names + + Describes tasks returned in LandStatReply - + - Default constructor + Estate level administration and utilities - Reference to the GridClient object - - - Fetch an inventory item from the dataserver - - The items - The item Owners - a integer representing the number of milliseconds to wait for results - An object on success, or null if no item was found - Items will also be sent to the event + + Textures for each of the four terrain height levels - - - Request A single inventory item - - The items - The item Owners - + + Upper/lower texture boundaries for each corner of the sim - + - Request inventory items + Constructor for EstateTools class - Inventory items to request - Owners of the inventory items - + - - - Request inventory items via Capabilities - - Inventory items to request - Owners of the inventory items - + + Used in the ReportType field of a LandStatRequest - - - Get contents of a folder - - The of the folder to search - The of the folders owner - true to retrieve folders - true to retrieve items - sort order to return results in - a integer representing the number of milliseconds to wait for results - A list of inventory items matching search criteria within folder - - InventoryFolder.DescendentCount will only be accurate if both folders and items are - requested + + Used by EstateOwnerMessage packets - - - Request the contents of an inventory folder - - The folder to search - The folder owners - true to return s contained in folder - true to return s containd in folder - the sort order to return items in - + + Used by EstateOwnerMessage packets - + - Request the contents of an inventory folder using HTTP capabilities + - The folder to search - The folder owners - true to return s contained in folder - true to return s containd in folder - the sort order to return items in - - - - Returns the UUID of the folder (category) that defaults to - containing 'type'. The folder is not necessarily only for that - type - - This will return the root folder if one does not exist - - The UUID of the desired folder if found, the UUID of the RootFolder - if not found, or UUID.Zero on failure + + No flags set - - - Find an object in inventory using a specific path to search - - The folder to begin the search in - The object owners - A string path to search - milliseconds to wait for a reply - Found items or if - timeout occurs or item is not found + + Only return targets scripted objects - - - Find inventory items by path - - The folder to begin the search in - The object owners - A string path to search, folders/objects separated by a '/' - Results are sent to the event + + Only return targets objects if on others land - - - Search inventory Store object for an item or folder - - The folder to begin the search in - An array which creates a path to search - Number of levels below baseFolder to conduct searches - if True, will stop searching after first match is found - A list of inventory items found + + Returns target's scripted objects and objects on other parcels - - - Move an inventory item or folder to a new location - - The item or folder to move - The to move item or folder to + + Ground texture settings for each corner of the region - - - Move an inventory item or folder to a new location and change its name - - The item or folder to move - The to move item or folder to - The name to change the item or folder to + + Used by GroundTextureHeightSettings - - - Move and rename a folder - - The source folders - The destination folders - The name to change the folder to + + The high and low texture thresholds for each corner of the sim - - - Update folder properties - - of the folder to update - Sets folder's parent to - Folder name - Folder type + + The event subscribers. null if no subcribers - - - Move a folder - - The source folders - The destination folders + + Raises the TopCollidersReply event + A TopCollidersReplyEventArgs object containing the + data returned from the data server - - - Move multiple folders, the keys in the Dictionary parameter, - to a new parents, the value of that folder's key. - - A Dictionary containing the - of the source as the key, and the - of the destination as the value + + Thread sync lock object - - - Move an inventory item to a new folder - - The of the source item to move - The of the destination folder + + Raised when the data server responds to a request. - - - Move and rename an inventory item - - The of the source item to move - The of the destination folder - The name to change the folder to + + The event subscribers. null if no subcribers - - - Move multiple inventory items to new locations - - A Dictionary containing the - of the source item as the key, and the - of the destination folder as the value + + Raises the TopScriptsReply event + A TopScriptsReplyEventArgs object containing the + data returned from the data server - - - Remove descendants of a folder - - The of the folder + + Thread sync lock object - - - Remove a single item from inventory - - The of the inventory item to remove + + Raised when the data server responds to a request. - - - Remove a folder from inventory - - The of the folder to remove + + The event subscribers. null if no subcribers - - - Remove multiple items or folders from inventory - - A List containing the s of items to remove - A List containing the s of the folders to remove + + Raises the EstateUsersReply event + A EstateUsersReplyEventArgs object containing the + data returned from the data server - - - Empty the Lost and Found folder - + + Thread sync lock object - - - Empty the Trash folder - + + Raised when the data server responds to a request. - - - - - - - - - Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here. - - - + + The event subscribers. null if no subcribers - - - - - - - - - Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here. - - - - + + Raises the EstateGroupsReply event + A EstateGroupsReplyEventArgs object containing the + data returned from the data server - - - Creates a new inventory folder - - ID of the folder to put this folder in - Name of the folder to create - The UUID of the newly created folder + + Thread sync lock object - - - Creates a new inventory folder - - ID of the folder to put this folder in - Name of the folder to create - Sets this folder as the default folder - for new assets of the specified type. Use AssetType.Unknown - to create a normal folder, otherwise it will likely create a - duplicate of an existing folder type - The UUID of the newly created folder - If you specify a preferred type of AsseType.Folder - it will create a new root folder which may likely cause all sorts - of strange problems + + Raised when the data server responds to a request. - - - Create an inventory item and upload asset data - - Asset data - Inventory item name - Inventory item description - Asset type - Inventory type - Put newly created inventory in this folder - Delegate that will receive feedback on success or failure + + The event subscribers. null if no subcribers - - - Create an inventory item and upload asset data - - Asset data - Inventory item name - Inventory item description - Asset type - Inventory type - Put newly created inventory in this folder - Permission of the newly created item - (EveryoneMask, GroupMask, and NextOwnerMask of Permissions struct are supported) - Delegate that will receive feedback on success or failure + + Raises the EstateManagersReply event + A EstateManagersReplyEventArgs object containing the + data returned from the data server - - - Creates inventory link to another inventory item or folder - - Put newly created link in folder with this UUID - Inventory item or folder - Method to call upon creation of the link + + Thread sync lock object - - - Creates inventory link to another inventory item - - Put newly created link in folder with this UUID - Original inventory item - Method to call upon creation of the link + + Raised when the data server responds to a request. - - - Creates inventory link to another inventory folder - - Put newly created link in folder with this UUID - Original inventory folder - Method to call upon creation of the link + + The event subscribers. null if no subcribers - - - Creates inventory link to another inventory item or folder - - Put newly created link in folder with this UUID - Original item's UUID - Name - Description - Asset Type - Inventory Type - Transaction UUID - Method to call upon creation of the link + + Raises the EstateBansReply event + A EstateBansReplyEventArgs object containing the + data returned from the data server - - - - - - - - + + Thread sync lock object - - - - - - - - - + + Raised when the data server responds to a request. - - - - - - - - - + + The event subscribers. null if no subcribers - - - Request a copy of an asset embedded within a notecard - - Usually UUID.Zero for copying an asset from a notecard - UUID of the notecard to request an asset from - Target folder for asset to go to in your inventory - UUID of the embedded asset - callback to run when item is copied to inventory + + Raises the EstateCovenantReply event + A EstateCovenantReplyEventArgs object containing the + data returned from the data server - - - - - + + Thread sync lock object - - - - - + + Raised when the data server responds to a request. - - - - - - + + The event subscribers. null if no subcribers + + + Raises the EstateUpdateInfoReply event + A EstateUpdateInfoReplyEventArgs object containing the + data returned from the data server + + + Thread sync lock object - - - - - - - + + Raised when the data server responds to a request. - + - Save changes to notecard embedded in object contents + Requests estate information such as top scripts and colliders - Encoded notecard asset data - Notecard UUID - Object's UUID - Called upon finish of the upload with status information + + + + - - - Upload new gesture asset for an inventory gesture item - - Encoded gesture asset - Gesture inventory UUID - Callback whick will be called when upload is complete + + Requests estate settings, including estate manager and access/ban lists - - - Update an existing script in an agents Inventory - - A byte[] array containing the encoded scripts contents - the itemID of the script - if true, sets the script content to run on the mono interpreter - + + Requests the "Top Scripts" list for the current region - - - Update an existing script in an task Inventory - - A byte[] array containing the encoded scripts contents - the itemID of the script - UUID of the prim containting the script - if true, sets the script content to run on the mono interpreter - if true, sets the script to running - + + Requests the "Top Colliders" list for the current region - + - Rez an object from inventory + Set several estate specific configuration variables - Simulator to place object in - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details + The Height of the waterlevel over the entire estate. Defaults to 20 + The maximum height change allowed above the baked terrain. Defaults to 4 + The minimum height change allowed below the baked terrain. Defaults to -4 + true to use + if True forces the sun position to the position in SunPosition + The current position of the sun on the estate, or when FixedSun is true the static position + the sun will remain. 6.0 = Sunrise, 30.0 = Sunset - + - Rez an object from inventory + Request return of objects owned by specified avatar - Simulator to place object in - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - UUID of group to own the object + The Agents owning the primitives to return + specify the coverage and type of objects to be included in the return + true to perform return on entire estate - - - Rez an object from inventory - - Simulator to place object in - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - UUID of group to own the object - User defined queryID to correlate replies - If set to true, the CreateSelected flag - will be set on the rezzed object + + + + - + - Rez an object from inventory + Used for setting and retrieving various estate panel settings - Simulator to place object in - TaskID object when rezzed - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - UUID of group to own the object - User defined queryID to correlate replies - If set to true, the CreateSelected flag - will be set on the rezzed object + EstateOwnerMessage Method field + List of parameters to include - + - DeRez an object from the simulator to the agents Objects folder in the agents Inventory + Kick an avatar from an estate - The simulator Local ID of the object - If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed + Key of Agent to remove - + - DeRez an object from the simulator and return to inventory - - The simulator Local ID of the object - The type of destination from the enum - The destination inventory folders -or- - if DeRezzing object to a tasks Inventory, the Tasks - The transaction ID for this request which - can be used to correlate this request with other packets - If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed + Ban an avatar from an estate + Key of Agent to remove + Ban user from this estate and all others owned by the estate owner - - - Rez an item from inventory to its previous simulator location - - - - - + + Unban an avatar from an estate + Key of Agent to remove + /// Unban user from this estate and all others owned by the estate owner - + - Give an inventory item to another avatar + Send a message dialog to everyone in an entire estate - The of the item to give - The name of the item - The type of the item from the enum - The of the recipient - true to generate a beameffect during transfer + Message to send all users in the estate - + - Give an inventory Folder with contents to another avatar + Send a message dialog to everyone in a simulator - The of the Folder to give - The name of the folder - The type of the item from the enum - The of the recipient - true to generate a beameffect during transfer + Message to send all users in the simulator - + - Copy or move an from agent inventory to a task (primitive) inventory + Send an avatar back to their home location - The target object - The item to copy or move from inventory - - For items with copy permissions a copy of the item is placed in the tasks inventory, - for no-copy items the object is moved to the tasks inventory + Key of avatar to send home - + - Retrieve a listing of the items contained in a task (Primitive) + Begin the region restart process - The tasks - The tasks simulator local ID - milliseconds to wait for reply from simulator - A list containing the inventory items inside the task or null - if a timeout occurs - This request blocks until the response from the simulator arrives - or timeoutMS is exceeded - + - Request the contents of a tasks (primitives) inventory from the - current simulator + Cancels a region restart - The LocalID of the object - - - - Request the contents of a tasks (primitives) inventory - - The simulator Local ID of the object - A reference to the simulator object that contains the object - + + Estate panel "Region" tab settings - - - Move an item from a tasks (Primitive) inventory to the specified folder in the avatars inventory - - LocalID of the object in the simulator - UUID of the task item to move - The ID of the destination folder in this agents inventory - Simulator Object - Raises the event + + Estate panel "Debug" tab settings - - - Remove an item from an objects (Prim) Inventory - - LocalID of the object in the simulator - UUID of the task item to remove - Simulator Object - You can confirm the removal by comparing the tasks inventory serial before and after the - request with the request combined with - the event + + Used for setting the region's terrain textures for its four height levels + + + + - - - Copy an InventoryScript item from the Agents Inventory into a primitives task inventory - - An unsigned integer representing a primitive being simulated - An which represents a script object from the agents inventory - true to set the scripts running state to enabled - A Unique Transaction ID - - The following example shows the basic steps necessary to copy a script from the agents inventory into a tasks inventory - and assumes the script exists in the agents inventory. - - uint primID = 95899503; // Fake prim ID - UUID scriptID = UUID.Parse("92a7fe8a-e949-dd39-a8d8-1681d8673232"); // Fake Script UUID in Inventory - - Client.Inventory.FolderContents(Client.Inventory.FindFolderForType(AssetType.LSLText), Client.Self.AgentID, - false, true, InventorySortOrder.ByName, 10000); - - Client.Inventory.RezScript(primID, (InventoryItem)Client.Inventory.Store[scriptID]); - - + + Used for setting sim terrain texture heights - - - Request the running status of a script contained in a task (primitive) inventory - - The ID of the primitive containing the script - The ID of the script - The event can be used to obtain the results of the - request - + + Requests the estate covenant - + - Send a request to set the running state of a script contained in a task (primitive) inventory + Upload a terrain RAW file - The ID of the primitive containing the script - The ID of the script - true to set the script running, false to stop a running script - To verify the change you can use the method combined - with the event + A byte array containing the encoded terrain data + The name of the file being uploaded + The Id of the transfer request - + - Create a CRC from an InventoryItem + Teleports all users home in current Estate - The source InventoryItem - A uint representing the source InventoryItem as a CRC - + - Reverses a cheesy XORing with a fixed UUID to convert a shadow_id to an asset_id - - Obfuscated shadow_id value - Deobfuscated asset_id value + Remove estate manager + Key of Agent to Remove + removes manager to this estate and all others owned by the estate owner - + - Does a cheesy XORing with a fixed UUID to convert an asset_id to a shadow_id - - asset_id value to obfuscate - Obfuscated shadow_id value + Add estate manager + Key of Agent to Add + Add agent as manager to this estate and all others owned by the estate owner - + - Wrapper for creating a new object - - The type of item from the enum - The of the newly created object - An object with the type and id passed + Add's an agent to the estate Allowed list + Key of Agent to Add + Add agent as an allowed reisdent to All estates if true - + - Parse the results of a RequestTaskInventory() response - - A string which contains the data from the task reply - A List containing the items contained within the tasks inventory - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + Removes an agent from the estate Allowed list + Key of Agent to Remove + Removes agent as an allowed reisdent from All estates if true - - - UpdateCreateInventoryItem packets are received when a new inventory item - is created. This may occur when an object that's rezzed in world is - taken into inventory, when an item is created using the CreateInventoryItem - packet, or when an object is purchased - - The sender - The EventArgs object containing the packet data + + + + Add's a group to the estate Allowed list + Key of Group to Add + Add Group as an allowed group to All estates if true - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + + + Removes a group from the estate Allowed list + Key of Group to Remove + Removes Group as an allowed Group from All estates if true - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - - Raised when the simulator sends us data containing - ... - - - Raised when the simulator sends us data containing - ... - - - Raised when the simulator sends us data containing - an inventory object sent by another avatar or primitive - - - Raised when the simulator sends us data containing - ... - - - Raised when the simulator sends us data containing - ... - - - Raised when the simulator sends us data containing - ... - - - Raised when the simulator sends us data containing - ... - - - Raised when the simulator sends us data containing - ... + + Raised on LandStatReply when the report type is for "top colliders" - + - Get this agents Inventory data + The number of returned items in LandStatReply - + - Callback for inventory item creation finishing + A Dictionary of Object UUIDs to tasks returned in LandStatReply - Whether the request to create an inventory - item succeeded or not - Inventory item being created. If success is - false this will be null - - - Callback for an inventory item being create from an uploaded asset - - true if inventory item creation was successful - - - + + Construct a new instance of the TopCollidersReplyEventArgs class + The number of returned items in LandStatReply + Dictionary of Object UUIDs to tasks returned in LandStatReply - - - - - + + Raised on LandStatReply when the report type is for "top Scripts" - + - Reply received when uploading an inventory asset + The number of scripts returned in LandStatReply - Has upload been successful - Error message if upload failed - Inventory asset UUID - New asset UUID - + - Delegate that is invoked when script upload is completed + A Dictionary of Object UUIDs to tasks returned in LandStatReply - Has upload succeded (note, there still might be compile errors) - Upload status message - Is compilation successful - If compilation failed, list of error messages, null on compilation success - Script inventory UUID - Script's new asset UUID - - Set to true to accept offer, false to decline it + + Construct a new instance of the TopScriptsReplyEventArgs class + The number of returned items in LandStatReply + Dictionary of Object UUIDs to tasks returned in LandStatReply - - The folder to accept the inventory into, if null default folder for will be used + + Returned, along with other info, upon a successful .RequestInfo() - + - Callback when an inventory object is accepted and received from a - task inventory. This is the callback in which you actually get - the ItemID, as in ObjectOfferedCallback it is null when received - from a task. + The identifier of the estate - + - + The number of returned itmes - + - + List of UUIDs of Banned Users - - - - De-serialization constructor for the InventoryNode Class - + + Construct a new instance of the EstateBansReplyEventArgs class + The estate's identifier on the grid + The number of returned items in LandStatReply + User UUIDs banned - + + Returned, along with other info, upon a successful .RequestInfo() + + - Serialization handler for the InventoryNode Class + The identifier of the estate - + - De-serialization handler for the InventoryNode Class + The number of returned items - + - + List of UUIDs of Allowed Users - - - - - - - User data - - + + Construct a new instance of the EstateUsersReplyEventArgs class + The estate's identifier on the grid + The number of users + Allowed users UUIDs - - + + Returned, along with other info, upon a successful .RequestInfo() - - + + + The identifier of the estate + - + - For inventory folder nodes specifies weather the folder needs to be - refreshed from the server + The number of returned items - + - Singleton logging class for the entire library + List of UUIDs of Allowed Groups - - log4net logging engine + + Construct a new instance of the EstateGroupsReplyEventArgs class + The estate's identifier on the grid + The number of Groups + Allowed Groups UUIDs - + + Returned, along with other info, upon a successful .RequestInfo() + + - Default constructor + The identifier of the estate - + - Send a log message to the logging engine + The number of returned items - The log message - The severity of the log entry - + - Send a log message to the logging engine + List of UUIDs of the Estate's Managers - The log message - The severity of the log entry - Instance of the client - + + Construct a new instance of the EstateManagersReplyEventArgs class + The estate's identifier on the grid + The number of Managers + Managers UUIDs + + + Returned, along with other info, upon a successful .RequestInfo() + + - Send a log message to the logging engine + The Covenant - The log message - The severity of the log entry - Exception that was raised - + - Send a log message to the logging engine + The timestamp - The log message - The severity of the log entry - Instance of the client - Exception that was raised - + - If the library is compiled with DEBUG defined, an event will be - fired if an OnLogMessage handler is registered and the - message will be sent to the logging engine + The Estate name - The message to log at the DEBUG level to the - current logging engine - + - If the library is compiled with DEBUG defined and - GridClient.Settings.DEBUG is true, an event will be - fired if an OnLogMessage handler is registered and the - message will be sent to the logging engine + The Estate Owner's ID (can be a GroupID) - The message to log at the DEBUG level to the - current logging engine - Instance of the client - - Triggered whenever a message is logged. If this is left - null, log messages will go to the console + + Construct a new instance of the EstateCovenantReplyEventArgs class + The Covenant ID + The timestamp + The estate's name + The Estate Owner's ID (can be a GroupID) - + + Returned, along with other info, upon a successful .RequestInfo() + + - Callback used for client apps to receive log messages from - the library + The estate's name - Data being logged - The severity of the log entry from - + - + The Estate Owner's ID (can be a GroupID) - - - - - - - - - - - - - - + + + The identifier of the estate on the grid + - + - - + + Construct a new instance of the EstateUpdateInfoReplyEventArgs class + The estate's name + The Estate Owners ID (can be a GroupID) + The estate's identifier on the grid + - + - Status of the last application run. - Used for error reporting to the grid login service for statistical purposes. + Registers, unregisters, and fires events generated by incoming packets - - Application exited normally - - - Application froze - - - Application detected error and exited abnormally - - - Other crash - - - Application froze during logout - - - Application crashed during logout - - + - Login Request Parameters + Object that is passed to worker threads in the ThreadPool for + firing packet callbacks - - The URL of the Login Server - - - The number of milliseconds to wait before a login is considered - failed due to timeout - - - The request method - login_to_simulator is currently the only supported method - - - The Agents First name - - - The Agents Last name - - - A md5 hashed password - plaintext password will be automatically hashed + + Callback to fire for this packet - - The agents starting location once logged in - Either "last", "home", or a string encoded URI - containing the simulator name and x/y/z coordinates e.g: uri:hooper&128&152&17 + + Reference to the simulator that this packet came from - - A string containing the client software channel information - Second Life Release + + The packet that needs to be processed - - The client software version information - The official viewer uses: Second Life Release n.n.n.n - where n is replaced with the current version of the viewer + + Reference to the GridClient object - - A string containing the platform information the agent is running on + + + Default constructor + + - - A string hash of the network cards Mac Address + + + Register an event handler + + Use PacketType.Default to fire this event on every + incoming packet + Packet type to register the handler for + Callback to be fired + True if this callback should be ran + asynchronously, false to run it synchronous - - Unknown or deprecated + + + Unregister an event handler + + Packet type to unregister the handler for + Callback to be unregistered - - A string hash of the first disk drives ID used to identify this clients uniqueness + + + Fire the events registered for this packet type + + Incoming packet type + Incoming packet + Simulator this packet was received from - - A string containing the viewers Software, this is not directly sent to the login server but - instead is used to generate the Version string + + + Registers, unregisters, and fires events generated by the Capabilities + event queue + - - A string representing the software creator. This is not directly sent to the login server but - is used by the library to generate the Version information + + + Object that is passed to worker threads in the ThreadPool for + firing CAPS callbacks + - - If true, this agent agrees to the Terms of Service of the grid its connecting to + + Callback to fire for this packet - - Unknown + + Name of the CAPS event - - Status of the last application run sent to the grid login server for statistical purposes + + Strongly typed decoded data - - An array of string sent to the login server to enable various options + + Reference to the simulator that generated this event - - A randomly generated ID to distinguish between login attempts. This value is only used - internally in the library and is never sent over the wire + + Reference to the GridClient object - + - Default constuctor, initializes sane default values + Default constructor + Reference to the GridClient object - + - Instantiates new LoginParams object and fills in the values + Register an new event handler for a capabilities event sent via the EventQueue - Instance of GridClient to read settings from - Login first name - Login last name - Password - Login channnel (application name) - Client version, should be application name + version number + Use String.Empty to fire this event on every CAPS event + Capability event name to register the + handler for + Callback to fire - + - Instantiates new LoginParams object and fills in the values + Unregister a previously registered capabilities handler - Instance of GridClient to read settings from - Login first name - Login last name - Password - Login channnel (application name) - Client version, should be application name + version number - URI of the login server + Capability event name unregister the + handler for + Callback to unregister - + - The decoded data returned from the login server after a successful login + Fire the events registered for this event type synchronously + Capability name + Decoded event body + Reference to the simulator that + generated this event - - true, false, indeterminate - - - Login message of the day - - - M or PG, also agent_region_access and agent_access_max - - + - Parse LLSD Login Reply Data + Fire the events registered for this event type asynchronously - An - contaning the login response data - XML-RPC logins do not require this as XML-RPC.NET - automatically populates the struct properly using attributes + Capability name + Decoded event body + Reference to the simulator that + generated this event - - - Login Routines - + - NetworkManager is responsible for managing the network layer of - OpenMetaverse. It tracks all the server connections, serializes - outgoing traffic and deserializes incoming traffic, and provides - instances of delegates for network-related events. + - - The event subscribers, null of no subscribers - - - Raises the LoginProgress Event - A LoginProgressEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Seed CAPS URL returned from the login server - - - Maximum number of groups an agent can belong to, -1 for unlimited + + The avatar has no rights - - Server side baking service URL + + The avatar can see the online status of the target avatar - - Parsed login response data + + The avatar can see the location of the target avatar on the map - - A list of packets obtained during the login process which - networkmanager will log but not process + + The avatar can modify the ojects of the target avatar - + - Generate sane default values for a login request + This class holds information about an avatar in the friends list. There are two ways + to interface to this class. The first is through the set of boolean properties. This is the typical + way clients of this class will use it. The second interface is through two bitflag properties, + TheirFriendsRights and MyFriendsRights - Account first name - Account last name - Account password - Client application name (channel) - Client application name + version - A populated struct containing - sane defaults - + - Simplified login that takes the most common and required fields + System ID of the avatar - Account first name - Account last name - Account password - Client application name (channel) - Client application name + version - Whether the login was successful or not. On failure the - LoginErrorKey string will contain the error code and LoginMessage - will contain a description of the error - + - Simplified login that takes the most common fields along with a - starting location URI, and can accept an MD5 string instead of a - plaintext password + full name of the avatar - Account first name - Account last name - Account password or MD5 hash of the password - such as $1$1682a1e45e9f957dcdf0bb56eb43319c - Client application name (channel) - Starting location URI that can be built with - StartLocation() - Client application name + version - Whether the login was successful or not. On failure the - LoginErrorKey string will contain the error code and LoginMessage - will contain a description of the error - + - Login that takes a struct of all the values that will be passed to - the login server + True if the avatar is online - The values that will be passed to the login - server, all fields must be set even if they are String.Empty - Whether the login was successful or not. On failure the - LoginErrorKey string will contain the error code and LoginMessage - will contain a description of the error - + - Build a start location URI for passing to the Login function + True if the friend can see if I am online - Name of the simulator to start in - X coordinate to start at - Y coordinate to start at - Z coordinate to start at - String with a URI that can be used to login to a specified - location - + - LoginParams and the initial login XmlRpcRequest were made on a remote machine. - This method now initializes libomv with the results. + True if the friend can see me on the map - + - Handles response from XML-RPC login replies + True if the freind can modify my objects - + - Handles response from XML-RPC login replies with already parsed LoginResponseData + True if I can see if my friend is online - + - Handle response from LLSD login replies + True if I can see if my friend is on the map - - - - + - Get current OS + True if I can modify my friend's objects - Either "Win" or "Linux" - + - Get clients default Mac Address + My friend's rights represented as bitmapped flags - A string containing the first found Mac Address - - - The event subscribers, null of no subscribers - - - Raises the PacketSent Event - A PacketSentEventArgs object containing - the data sent from the simulator - - Thread sync lock object + + + My rights represented as bitmapped flags + - - The event subscribers, null of no subscribers + + + Used internally when building the initial list of friends at login time + + System ID of the avatar being prepesented + Rights the friend has to see you online and to modify your objects + Rights you have to see your friend online and to modify their objects - - Raises the LoggedOut Event - A LoggedOutEventArgs object containing - the data sent from the simulator + + + FriendInfo represented as a string + + A string reprentation of both my rights and my friends rights - - Thread sync lock object + + + This class is used to add and remove avatars from your friends list and to manage their permission. + - - The event subscribers, null of no subscribers + + The event subscribers. null if no subcribers - - Raises the SimConnecting Event - A SimConnectingEventArgs object containing - the data sent from the simulator + + Raises the FriendOnline event + A FriendInfoEventArgs object containing the + data returned from the data server - + Thread sync lock object - - The event subscribers, null of no subscribers + + Raised when the simulator sends notification one of the members in our friends list comes online - - Raises the SimConnected Event - A SimConnectedEventArgs object containing - the data sent from the simulator + + The event subscribers. null if no subcribers - + + Raises the FriendOffline event + A FriendInfoEventArgs object containing the + data returned from the data server + + Thread sync lock object - - The event subscribers, null of no subscribers + + Raised when the simulator sends notification one of the members in our friends list goes offline - - Raises the SimDisconnected Event - A SimDisconnectedEventArgs object containing - the data sent from the simulator + + The event subscribers. null if no subcribers - + + Raises the FriendRightsUpdate event + A FriendInfoEventArgs object containing the + data returned from the data server + + Thread sync lock object - - The event subscribers, null of no subscribers + + Raised when the simulator sends notification one of the members in our friends list grants or revokes permissions - - Raises the Disconnected Event - A DisconnectedEventArgs object containing - the data sent from the simulator + + The event subscribers. null if no subcribers - + + Raises the FriendNames event + A FriendNamesEventArgs object containing the + data returned from the data server + + Thread sync lock object - - The event subscribers, null of no subscribers + + Raised when the simulator sends us the names on our friends list - - Raises the SimChanged Event - A SimChangedEventArgs object containing - the data sent from the simulator + + The event subscribers. null if no subcribers - + + Raises the FriendshipOffered event + A FriendshipOfferedEventArgs object containing the + data returned from the data server + + Thread sync lock object - - The event subscribers, null of no subscribers + + Raised when the simulator sends notification another agent is offering us friendship - - Raises the EventQueueRunning Event - A EventQueueRunningEventArgs object containing - the data sent from the simulator + + The event subscribers. null if no subcribers - + + Raises the FriendshipResponse event + A FriendshipResponseEventArgs object containing the + data returned from the data server + + Thread sync lock object - - All of the simulators we are currently connected to + + Raised when a request we sent to friend another agent is accepted or declined - - Handlers for incoming capability events + + The event subscribers. null if no subcribers - - Handlers for incoming packets + + Raises the FriendshipTerminated event + A FriendshipTerminatedEventArgs object containing the + data returned from the data server - - Incoming packets that are awaiting handling + + Thread sync lock object - - Outgoing packets that are awaiting handling + + Raised when the simulator sends notification one of the members in our friends list has terminated + our friendship - - - Default constructor - - Reference to the GridClient object + + The event subscribers. null if no subcribers - - - Register an event handler for a packet. This is a low level event - interface and should only be used if you are doing something not - supported in the library - - Packet type to trigger events for - Callback to fire when a packet of this type - is received + + Raises the FriendFoundReply event + A FriendFoundReplyEventArgs object containing the + data returned from the data server - - - Register an event handler for a packet. This is a low level event - interface and should only be used if you are doing something not - supported in the library - - Packet type to trigger events for - Callback to fire when a packet of this type - is received - True if the callback should be ran - asynchronously. Only set this to false (synchronous for callbacks - that will always complete quickly) - If any callback for a packet type is marked as - asynchronous, all callbacks for that packet type will be fired - asynchronously + + Thread sync lock object - - - Unregister an event handler for a packet. This is a low level event - interface and should only be used if you are doing something not - supported in the library - - Packet type this callback is registered with - Callback to stop firing events for + + Raised when the simulator sends the location of a friend we have + requested map location info for - + - Register a CAPS event handler. This is a low level event interface - and should only be used if you are doing something not supported in - the library + A dictionary of key/value pairs containing known friends of this avatar. + + The Key is the of the friend, the value is a + object that contains detailed information including permissions you have and have given to the friend - Name of the CAPS event to register a handler for - Callback to fire when a CAPS event is received - + - Unregister a CAPS event handler. This is a low level event interface - and should only be used if you are doing something not supported in - the library + A Dictionary of key/value pairs containing current pending frienship offers. + + The key is the of the avatar making the request, + the value is the of the request which is used to accept + or decline the friendship offer - Name of the CAPS event this callback is - registered with - Callback to stop firing events for - + - Send a packet to the simulator the avatar is currently occupying + Internal constructor - Packet to send + A reference to the GridClient Object - + - Send a packet to a specified simulator + Accept a friendship request - Packet to send - Simulator to send the packet to + agentID of avatatar to form friendship with + imSessionID of the friendship request message - + - Connect to a simulator + Decline a friendship request - IP address to connect to - Port to connect to - Handle for this simulator, to identify its - location in the grid - Whether to set CurrentSim to this new - connection, use this if the avatar is moving in to this simulator - URL of the capabilities server to use for - this sim connection - A Simulator object on success, otherwise null + of friend + imSessionID of the friendship request message - + - Connect to a simulator + Overload: Offer friendship to an avatar. - IP address and port to connect to - Handle for this simulator, to identify its - location in the grid - Whether to set CurrentSim to this new - connection, use this if the avatar is moving in to this simulator - URL of the capabilities server to use for - this sim connection - A Simulator object on success, otherwise null + System ID of the avatar you are offering friendship to - + - Initiate a blocking logout request. This will return when the logout - handshake has completed or when Settings.LOGOUT_TIMEOUT - has expired and the network layer is manually shut down + Offer friendship to an avatar. + System ID of the avatar you are offering friendship to + A message to send with the request - + - Initiate the logout process. Check if logout succeeded with the - OnLogoutReply event, and if this does not fire the - Shutdown() function needs to be manually called + Terminate a friendship with an avatar + System ID of the avatar you are terminating the friendship with - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + + - Close a connection to the given simulator + Change the rights of a friend avatar. - - + the of the friend + the new rights to give the friend + This method will implicitly set the rights to those passed in the rights parameter. - + - Shutdown will disconnect all the sims except for the current sim - first, and then kill the connection to CurrentSim. This should only - be called if the logout process times out on RequestLogout + Use to map a friends location on the grid. - Type of shutdown + Friends UUID to find + - + - Shutdown will disconnect all the sims except for the current sim - first, and then kill the connection to CurrentSim. This should only - be called if the logout process times out on RequestLogout + Use to track a friends movement on the grid - Type of shutdown - Shutdown message + Friends Key - + - Searches through the list of currently connected simulators to find - one attached to the given IPEndPoint + Ask for a notification of friend's online status - IPEndPoint of the Simulator to search for - A Simulator reference on success, otherwise null + Friend's UUID - + - Fire an event when an event queue connects for capabilities + This handles the asynchronous response of a RequestAvatarNames call. - Simulator the event queue is attached to + + names cooresponding to the the list of IDs sent the the RequestAvatarNames call. - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - + Process an incoming packet and raise the appropriate events The sender The EventArgs object containing the packet data - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + + Populate FriendList with data from the login reply + + true if login was successful + true if login request is requiring a redirect + A string containing the response to the login request + A string containing the reason for the request + A object containing the decoded + reply from the login server - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Contains information on a member of our friends list - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Get the FriendInfo - - Raised when the simulator sends us data containing - ... + + + Construct a new instance of the FriendInfoEventArgs class + + The FriendInfo - - Called when a reply is received from the login server, the - login sequence will block until this event returns + + Contains Friend Names - - Current state of logging in + + A dictionary where the Key is the ID of the Agent, + and the Value is a string containing their name - - Upon login failure, contains a short string key for the - type of login error that occurred + + + Construct a new instance of the FriendNamesEventArgs class + + A dictionary where the Key is the ID of the Agent, + and the Value is a string containing their name - - The raw XML-RPC reply from the login server, exactly as it - was received (minus the HTTP header) + + Sent when another agent requests a friendship with our agent - - During login this contains a descriptive version of - LoginStatusCode. After a successful login this will contain the - message of the day, and after a failed login a descriptive error - message will be returned + + Get the ID of the agent requesting friendship - - Raised when the simulator sends us data containing - ... + + Get the name of the agent requesting friendship - - Raised when the simulator sends us data containing - ... + + Get the ID of the session, used in accepting or declining the + friendship offer - - Raised when the simulator sends us data containing - ... + + + Construct a new instance of the FriendshipOfferedEventArgs class + + The ID of the agent requesting friendship + The name of the agent requesting friendship + The ID of the session, used in accepting or declining the + friendship offer - - Raised when the simulator sends us data containing - ... + + A response containing the results of our request to form a friendship with another agent - - Raised when the simulator sends us data containing - ... + + Get the ID of the agent we requested a friendship with - - Raised when the simulator sends us data containing - ... + + Get the name of the agent we requested a friendship with + + + true if the agent accepted our friendship offer + + + + Construct a new instance of the FriendShipResponseEventArgs class + + The ID of the agent we requested a friendship with + The name of the agent we requested a friendship with + true if the agent accepted our friendship offer + + + Contains data sent when a friend terminates a friendship with us + + + Get the ID of the agent that terminated the friendship with us + + + Get the name of the agent that terminated the friendship with us + + + + Construct a new instance of the FrindshipTerminatedEventArgs class + + The ID of the friend who terminated the friendship with us + The name of the friend who terminated the friendship with us + + + + Data sent in response to a request which contains the information to allow us to map the friends location + + + + Get the ID of the agent we have received location information for + + + Get the region handle where our mapped friend is located + + + Get the simulator local position where our friend is located + + + + Construct a new instance of the FriendFoundReplyEventArgs class + + The ID of the agent we have requested location information for + The region handle where our friend is located + The simulator local position our friend is located + + + + Main class to expose grid functionality to clients. All of the + classes needed for sending and receiving data are accessible through + this class. + + + + // Example minimum code required to instantiate class and + // connect to a simulator. + using System; + using System.Collections.Generic; + using System.Text; + using OpenMetaverse; + + namespace FirstBot + { + class Bot + { + public static GridClient Client; + static void Main(string[] args) + { + Client = new GridClient(); // instantiates the GridClient class + // to the global Client object + // Login to Simulator + Client.Network.Login("FirstName", "LastName", "Password", "FirstBot", "1.0"); + // Wait for a Keypress + Console.ReadLine(); + // Logout of simulator + Client.Network.Logout(); + } + } + } + + + + + Networking subsystem + + + Settings class including constant values and changeable + parameters for everything + + + Parcel (subdivided simulator lots) subsystem + + + Our own avatars subsystem + + + Other avatars subsystem + + + Estate subsystem + + + Friends list subsystem + + + Grid (aka simulator group) subsystem + + + Object subsystem + + + Group subsystem - - Raised when the simulator sends us data containing - ... + + Asset subsystem - - Raised when the simulator sends us data containing - ... + + Appearance subsystem - - Unique identifier associated with our connections to - simulators + + Inventory subsystem - - The simulator that the logged in avatar is currently - occupying + + Directory searches including classifieds, people, land + sales, etc - - Shows whether the network layer is logged in to the - grid or not + + Handles land, wind, and cloud heightmaps - - Number of packets in the incoming queue + + Handles sound-related networking - - Number of packets in the outgoing queue + + Throttling total bandwidth usage, or allocating bandwidth + for specific data stream types - + - + Default constructor - - - - - - + - Explains why a simulator or the grid disconnected from us + Return the full name of this instance + Client avatars full name - - The client requested the logout or simulator disconnect + + + Map layer request type + - - The server notified us that it is disconnecting + + Objects and terrain are shown - - Either a socket was closed or network traffic timed out + + Only the terrain is shown, no objects - - The last active simulator shut down + + Overlay showing land for sale and for auction - + - Holds a simulator reference and a decoded packet, these structs are put in - the packet inbox for event handling + Type of grid item, such as telehub, event, populator location, etc. - - Reference to the simulator that this packet came from + + Telehub - - Packet that needs to be processed + + PG rated event - - - Holds a simulator reference and a serialized packet, these structs are put in - the packet outbox for sending - + + Mature rated event - - Reference to the simulator this packet is destined for + + Popular location - - Packet that needs to be sent + + Locations of avatar groups in a region - - Sequence number of the wrapped packet + + Land for sale - - Number of times this packet has been resent + + Classified ad - - Environment.TickCount when this packet was last sent over the wire + + Adult rated event - - Type of the packet + + Adult land for sale - + - A Name Value pair with additional settings, used in the protocol - primarily to transmit avatar names and active group in object packets + Information about a region on the grid map - - + + Sim X position on World Map - - + + Sim Y position on World Map - - + + Sim Name (NOTE: In lowercase!) - + - + + Appears to always be zero (None) + + + Sim's defined Water Height + + - + + UUID of the World Map image + + + Unique identifier for this region, a combination of the X + and Y position + + - Constructor that takes all the fields as parameters + - - - - - + - + - Constructor that takes a single line from a NameValue field + - - - - Type of the value - - - Unknown + - - String value + + + + + + - - + + + Visual chunk of the grid map + - - + + + Base class for Map Items + - - + + The Global X position of the item - - + + The Global Y position of the item - - Deprecated + + Get the Local X position of the item - - String value, but designated as an asset + + Get the Local Y position of the item - - + + Get the Handle of the region - + - + Represents an agent or group of agents location - - - - - + + + Represents a Telehub location + - - + + + Represents a non-adult parcel of land for sale + - - + + + Represents an Adult parcel of land for sale + - + - + Represents a PG Event - - + + + Represents a Mature event + - - + + + Represents an Adult event + - - + + + Manages grid-wide tasks such as the world map + - - + + The event subscribers. null if no subcribers - - + + Raises the CoarseLocationUpdate event + A CoarseLocationUpdateEventArgs object containing the + data sent by simulator - - - - + + Thread sync lock object - - No report + + Raised when the simulator sends a + containing the location of agents in the simulator - - Unknown report type + + The event subscribers. null if no subcribers - - Bug report + + Raises the GridRegion event + A GridRegionEventArgs object containing the + data sent by simulator - - Complaint report + + Thread sync lock object - - Customer service report + + Raised when the simulator sends a Region Data in response to + a Map request - - - Bitflag field for ObjectUpdateCompressed data blocks, describing - which options are present for each object - + + The event subscribers. null if no subcribers - - Unknown + + Raises the GridLayer event + A GridLayerEventArgs object containing the + data sent by simulator - - Whether the object has a TreeSpecies + + Thread sync lock object - - Whether the object has floating text ala llSetText + + Raised when the simulator sends GridLayer object containing + a map tile coordinates and texture information - - Whether the object has an active particle system + + The event subscribers. null if no subcribers - - Whether the object has sound attached to it + + Raises the GridItems event + A GridItemEventArgs object containing the + data sent by simulator - - Whether the object is attached to a root object or not + + Thread sync lock object - - Whether the object has texture animation settings + + Raised when the simulator sends GridItems object containing + details on events, land sales at a specific location - - Whether the object has an angular velocity + + The event subscribers. null if no subcribers - - Whether the object has a name value pairs string + + Raises the RegionHandleReply event + A RegionHandleReplyEventArgs object containing the + data sent by simulator - - Whether the object has a Media URL set + + Thread sync lock object - - - Specific Flags for MultipleObjectUpdate requests - + + Raised in response to a Region lookup - - None + + Unknown - - Change position of prims + + Current direction of the sun - - Change rotation of prims + + Current angular velocity of the sun - - Change size of prims + + Microseconds since the start of SL 4-hour day - - Perform operation on link set + + A dictionary of all the regions, indexed by region name - - Scale prims uniformly, same as selecing ctrl+shift in the - viewer. Used in conjunction with Scale + + A dictionary of all the regions, indexed by region handle - + - Special values in PayPriceReply. If the price is not one of these - literal value of the price should be use + Constructor + Instance of GridClient object to associate with this GridManager instance - + - Indicates that this pay option should be hidden + + - + - Indicates that this pay option should have the default value + Request a map layer + The name of the region + The type of layer - + - Contains the variables sent in an object update packet for objects. - Used to track position and movement of prims and avatars + + + + + + + - - + + + + + + + + + - - + + + + + + + - - + + + Request data for all mainland (Linden managed) simulators + - - + + + Request the region handle for the specified region UUID + + UUID of the region to look up - - + + + Get grid region information using the region name, this function + will block until it can find the region or gives up + + Name of sim you're looking for + Layer that you are requesting + Will contain a GridRegion for the sim you're + looking for if successful, otherwise an empty structure + True if the GridRegion was successfully fetched, otherwise + false - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - + - Handles all network traffic related to prims and avatar positions and - movement. + Avatar group management - - The event subscribers, null of no subscribers + + Key of Group Member - - Thread sync lock object + + Total land contribution - - The event subscribers, null of no subscribers + + Online status information - - Raises the ObjectProperties Event - A ObjectPropertiesEventArgs object containing - the data sent from the simulator + + Abilities that the Group Member has - - Thread sync lock object + + Current group title - - The event subscribers, null of no subscribers + + Is a group owner - - Raises the ObjectPropertiesUpdated Event - A ObjectPropertiesUpdatedEventArgs object containing - the data sent from the simulator + + + Role manager for a group + - - Thread sync lock object + + Key of the group - - The event subscribers, null of no subscribers + + Key of Role - - Raises the ObjectPropertiesFamily Event - A ObjectPropertiesFamilyEventArgs object containing - the data sent from the simulator + + Name of Role - - Thread sync lock object + + Group Title associated with Role - - The event subscribers, null of no subscribers + + Description of Role - - Raises the AvatarUpdate Event - A AvatarUpdateEventArgs object containing - the data sent from the simulator + + Abilities Associated with Role - - Thread sync lock object + + Returns the role's title + The role's title - - The event subscribers, null of no subscribers + + + Class to represent Group Title + - - Thread sync lock object + + Key of the group - - The event subscribers, null of no subscribers + + ID of the role title belongs to - - Raises the ObjectDataBlockUpdate Event - A ObjectDataBlockUpdateEventArgs object containing - the data sent from the simulator + + Group Title - - Thread sync lock object + + Whether title is Active - - The event subscribers, null of no subscribers + + Returns group title - - Raises the KillObject Event - A KillObjectEventArgs object containing - the data sent from the simulator + + + Represents a group on the grid + - - Thread sync lock object + + Key of Group - - The event subscribers, null of no subscribers + + Key of Group Insignia - - Raises the KillObjects Event - A KillObjectsEventArgs object containing - the data sent from the simulator + + Key of Group Founder - - Thread sync lock object + + Key of Group Role for Owners - - The event subscribers, null of no subscribers + + Name of Group - - Raises the AvatarSitChanged Event - A AvatarSitChangedEventArgs object containing - the data sent from the simulator + + Text of Group Charter - - Thread sync lock object + + Title of "everyone" role - - The event subscribers, null of no subscribers + + Is the group open for enrolement to everyone - - Raises the PayPriceReply Event - A PayPriceReplyEventArgs object containing - the data sent from the simulator + + Will group show up in search - - Thread sync lock object + + - - The event subscribers, null of no subscribers + + - - Raises the PhysicsProperties Event - A PhysicsPropertiesEventArgs object containing - the data sent from the simulator + + - - Thread sync lock object + + Is the group Mature - - Reference to the GridClient object + + Cost of group membership - - Does periodic dead reckoning calculation to convert - velocity and acceleration to new positions for objects + + - - - Construct a new instance of the ObjectManager class - - A reference to the instance + + - - - Request information for a single object from a - you are currently connected to - - The the object is located - The Local ID of the object + + The total number of current members this group has - - - Request information for multiple objects contained in - the same simulator - - The the objects are located - An array containing the Local IDs of the objects + + The number of roles this group has configured - - - Attempt to purchase an original object, a copy, or the contents of - an object - - The the object is located - The Local ID of the object - Whether the original, a copy, or the object - contents are on sale. This is used for verification, if the this - sale type is not valid for the object the purchase will fail - Price of the object. This is used for - verification, if it does not match the actual price the purchase - will fail - Group ID that will be associated with the new - purchase - Inventory folder UUID where the object or objects - purchased should be placed - - - BuyObject(Client.Network.CurrentSim, 500, SaleType.Copy, - 100, UUID.Zero, Client.Self.InventoryRootFolderUUID); - - + + Show this group in agent's profile - - - Request prices that should be displayed in pay dialog. This will triggger the simulator - to send us back a PayPriceReply which can be handled by OnPayPriceReply event - - The the object is located - The ID of the object - The result is raised in the event + + Returns the name of the group + A string containing the name of the group - + - Select a single object. This will cause the to send us - an which will raise the event + A group Vote - The the object is located - The Local ID of the object - - - - Select a single object. This will cause the to send us - an which will raise the event - - The the object is located - The Local ID of the object - if true, a call to is - made immediately following the request - + + Key of Avatar who created Vote - - - Select multiple objects. This will cause the to send us - an which will raise the event - - The the objects are located - An array containing the Local IDs of the objects - Should objects be deselected immediately after selection - + + Text of the Vote proposal - - - Select multiple objects. This will cause the to send us - an which will raise the event - - The the objects are located - An array containing the Local IDs of the objects - + + Total number of votes - + - Update the properties of an object + A group proposal - The the object is located - The Local ID of the object - true to turn the objects physical property on - true to turn the objects temporary property on - true to turn the objects phantom property on - true to turn the objects cast shadows property on - - - Update the properties of an object - - The the object is located - The Local ID of the object - true to turn the objects physical property on - true to turn the objects temporary property on - true to turn the objects phantom property on - true to turn the objects cast shadows property on - Type of the represetnation prim will have in the physics engine - Density - normal value 1000 - Friction - normal value 0.6 - Restitution - standard value 0.5 - Gravity multiplier - standar value 1.0 + + The Text of the proposal - - - Sets the sale properties of a single object - - The the object is located - The Local ID of the object - One of the options from the enum - The price of the object + + The minimum number of members that must vote before proposal passes or failes - - - Sets the sale properties of multiple objects - - The the objects are located - An array containing the Local IDs of the objects - One of the options from the enum - The price of the object + + The required ration of yes/no votes required for vote to pass + The three options are Simple Majority, 2/3 Majority, and Unanimous + TODO: this should be an enum - - - Deselect a single object - - The the object is located - The Local ID of the object + + The duration in days votes are accepted - + - Deselect multiple objects. + - The the objects are located - An array containing the Local IDs of the objects - - - Perform a click action on an object - - The the object is located - The Local ID of the object + + - - - Perform a click action (Grab) on a single object - - The the object is located - The Local ID of the object - The texture coordinates to touch - The surface coordinates to touch - The face of the position to touch - The region coordinates of the position to touch - The surface normal of the position to touch (A normal is a vector perpindicular to the surface) - The surface binormal of the position to touch (A binormal is a vector tangen to the surface - pointing along the U direction of the tangent space + + - - - Create (rez) a new prim object in a simulator - - A reference to the object to place the object in - Data describing the prim object to rez - Group ID that this prim will be set to, or UUID.Zero if you - do not want the object to be associated with a specific group - An approximation of the position at which to rez the prim - Scale vector to size this prim - Rotation quaternion to rotate this prim - Due to the way client prim rezzing is done on the server, - the requested position for an object is only close to where the prim - actually ends up. If you desire exact placement you'll need to - follow up by moving the object after it has been created. This - function will not set textures, light and flexible data, or other - extended primitive properties + + - - - Create (rez) a new prim object in a simulator - - A reference to the object to place the object in - Data describing the prim object to rez - Group ID that this prim will be set to, or UUID.Zero if you - do not want the object to be associated with a specific group - An approximation of the position at which to rez the prim - Scale vector to size this prim - Rotation quaternion to rotate this prim - Specify the - Due to the way client prim rezzing is done on the server, - the requested position for an object is only close to where the prim - actually ends up. If you desire exact placement you'll need to - follow up by moving the object after it has been created. This - function will not set textures, light and flexible data, or other - extended primitive properties + + - - - Rez a Linden tree - - A reference to the object where the object resides - The size of the tree - The rotation of the tree - The position of the tree - The Type of tree - The of the group to set the tree to, - or UUID.Zero if no group is to be set - true to use the "new" Linden trees, false to use the old + + - - - Rez grass and ground cover - - A reference to the object where the object resides - The size of the grass - The rotation of the grass - The position of the grass - The type of grass from the enum - The of the group to set the tree to, - or UUID.Zero if no group is to be set + + - - - Set the textures to apply to the faces of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The texture data to apply + + - - - Set the textures to apply to the faces of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The texture data to apply - A media URL (not used) + + - - - Set the Light data on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A object containing the data to set + + - - - Set the flexible data on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A object containing the data to set + + - - - Set the sculptie texture and data on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A object containing the data to set + + - - - Unset additional primitive parameters on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The extra parameters to set + + - - - Link multiple prims into a linkset - - A reference to the object where the objects reside - An array which contains the IDs of the objects to link - The last object in the array will be the root object of the linkset TODO: Is this true? + + - - - Delink/Unlink multiple prims from a linkset - - A reference to the object where the objects reside - An array which contains the IDs of the objects to delink + + - - - Change the rotation of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new rotation of the object + + - - - Set the name of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A string containing the new name of the object + + - - - Set the name of multiple objects - - A reference to the object where the objects reside - An array which contains the IDs of the objects to change the name of - An array which contains the new names of the objects + + - - - Set the description of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A string containing the new description of the object + + - - - Set the descriptions of multiple objects - - A reference to the object where the objects reside - An array which contains the IDs of the objects to change the description of - An array which contains the new descriptions of the objects + + - + - Attach an object to this avatar + Struct representing a group notice - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The point on the avatar the object will be attached - The rotation of the attached object - - - Drop an attached object from this avatar - - A reference to the - object where the objects reside. This will always be the simulator the avatar is currently in - - The object's ID which is local to the simulator the object is in + + - - - Detach an object from yourself - - A reference to the - object where the objects reside - - This will always be the simulator the avatar is currently in - - An array which contains the IDs of the objects to detach + + - - - Change the position of an object, Will change position of entire linkset - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new position of the object + + - - - Change the position of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new position of the object - if true, will change position of (this) child prim only, not entire linkset + + - + - Change the Scale (size) of an object + - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new scale of the object - If true, will change scale of this prim only, not entire linkset - True to resize prims uniformly + - + - Change the Rotation of an object that is either a child or a whole linkset + Struct representing a group notice list entry - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new scale of the object - If true, will change rotation of this prim only, not entire linkset - - - Send a Multiple Object Update packet to change the size, scale or rotation of a primitive - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new rotation, size, or position of the target object - The flags from the Enum + + Notice ID - - - Deed an object (prim) to a group, Object must be shared with group which - can be accomplished with SetPermissions() - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The of the group to deed the object to + + Creation timestamp of notice - - - Deed multiple objects (prims) to a group, Objects must be shared with group which - can be accomplished with SetPermissions() - - A reference to the object where the object resides - An array which contains the IDs of the objects to deed - The of the group to deed the object to + + Agent name who created notice - - - Set the permissions on multiple objects - - A reference to the object where the objects reside - An array which contains the IDs of the objects to set the permissions on - The new Who mask to set - Which permission to modify - The new state of permission + + Notice subject - - - Request additional properties for an object - - A reference to the object where the object resides - + + Is there an attachment? - - - Request additional properties for an object - - A reference to the object where the object resides - Absolute UUID of the object - Whether to require server acknowledgement of this request + + Attachment Type - + - Set the ownership of a list of objects to the specified group + Struct representing a member of a group chat session and their settings - A reference to the object where the objects reside - An array which contains the IDs of the objects to set the group id on - The Groups ID - - - Update current URL of the previously set prim media - - UUID of the prim - Set current URL to this - Prim face number - Simulator in which prim is located + + The of the Avatar - - - Set object media - - UUID of the prim - Array the length of prims number of faces. Null on face indexes where there is - no media, on faces which contain the media - Simulatior in which prim is located + + True if user has voice chat enabled - - - Retrieve information about object media - - UUID of the primitive - Simulator where prim is located - Call this callback when done + + True of Avatar has moderator abilities - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + True if a moderator has muted this avatars chat - + + True if a moderator has muted this avatars voice + + - A terse object update, used when a transformation matrix or - velocity/acceleration for an object changes but nothing else - (scale/position/rotation/acceleration/velocity) + Role update flags - The sender - The EventArgs object containing the packet data - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + - - - - - - - + + - - - Setup construction data for a basic primitive shape - - Primitive shape to construct - Construction data that can be plugged into a + + Can send invitations to groups default role - - - - - - - - + + Can eject members from group - - - - - - + + Can toggle 'Open Enrollment' and change 'Signup fee' - - - Set the Shape data of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - Data describing the prim shape + + Member is visible in the public member list - - - Set the Material data of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new material of the object + + Can create new roles - - - - - - - - + + Can delete existing roles - - - - - - - - - + + Can change Role names, titles and descriptions - - - - - - - - + + Can assign other members to assigners role - - Raised when the simulator sends us data containing - A , Foliage or Attachment - - + + Can assign other members to any role - - Raised when the simulator sends us data containing - additional information - - + + Can remove members from roles - - Raised when the simulator sends us data containing - Primitive.ObjectProperties for an object we are currently tracking + + Can assign and remove abilities in roles - - Raised when the simulator sends us data containing - additional and details - + + Can change group Charter, Insignia, 'Publish on the web' and which + members are publicly visible in group member listings - - Raised when the simulator sends us data containing - updated information for an + + Can buy land or deed land to group - - Raised when the simulator sends us data containing - and movement changes + + Can abandon group owned land to Governor Linden on mainland, or Estate owner for + private estates - - Raised when the simulator sends us data containing - updates to an Objects DataBlock + + Can set land for-sale information on group owned parcels - - Raised when the simulator informs us an - or is no longer within view + + Can subdivide and join parcels - - Raised when the simulator informs us when a group of - or is no longer within view + + Can change music and media settings - - Raised when the simulator sends us data containing - updated sit information for our + + Can toggle 'Edit Terrain' option in Land settings - - Raised when the simulator sends us data containing - purchase price information for a + + Can toggle various About Land > Options settings - - Raised when the simulator sends us data containing - additional information - - + + Can toggle "Show in Find Places" and set search category - - - Callback for getting object media data via CAP - - Indicates if the operation was succesfull - Object media version string - Array indexed on prim face of media entry data + + Can change parcel name, description, and 'Publish on web' settings - - Provides data for the event - The event occurs when the simulator sends - an containing a Primitive, Foliage or Attachment data - Note 1: The event will not be raised when the object is an Avatar - Note 2: It is possible for the to be - raised twice for the same object if for example the primitive moved to a new simulator, then returned to the current simulator or - if an Avatar crosses the border into a new simulator and returns to the current simulator - - - The following code example uses the , , and - properties to display new Primitives and Attachments on the window. - - // Subscribe to the event that gives us prim and foliage information - Client.Objects.ObjectUpdate += Objects_ObjectUpdate; - - - private void Objects_ObjectUpdate(object sender, PrimEventArgs e) - { - Console.WriteLine("Primitive {0} {1} in {2} is an attachment {3}", e.Prim.ID, e.Prim.LocalID, e.Simulator.Name, e.IsAttachment); - } - - - - - + + Can set the landing point and teleport routing on group land - - - Construct a new instance of the PrimEventArgs class - - The simulator the object originated from - The Primitive - The simulator time dilation - The prim was not in the dictionary before this update - true if the primitive represents an attachment to an agent + + Can always terraform land, even if parcel settings have it turned off - - Get the simulator the originated from + + Can always fly while over group owned land - - Get the details + + Can always rez objects on group owned land - - true if the did not exist in the dictionary before this update (always true if object tracking has been disabled) + + Can always create landmarks for group owned parcels - - true if the is attached to an + + Can set home location on any group owned parcel - - Get the simulator Time Dilation + + Allowed to hold events on group-owned land - - Provides data for the event - The event occurs when the simulator sends - an containing Avatar data - Note 1: The event will not be raised when the object is an Avatar - Note 2: It is possible for the to be - raised twice for the same avatar if for example the avatar moved to a new simulator, then returned to the current simulator - - - The following code example uses the property to make a request for the top picks - using the method in the class to display the names - of our own agents picks listings on the window. - - // subscribe to the AvatarUpdate event to get our information - Client.Objects.AvatarUpdate += Objects_AvatarUpdate; - Client.Avatars.AvatarPicksReply += Avatars_AvatarPicksReply; - - private void Objects_AvatarUpdate(object sender, AvatarUpdateEventArgs e) - { - // we only want our own data - if (e.Avatar.LocalID == Client.Self.LocalID) - { - // Unsubscribe from the avatar update event to prevent a loop - // where we continually request the picks every time we get an update for ourselves - Client.Objects.AvatarUpdate -= Objects_AvatarUpdate; - // make the top picks request through AvatarManager - Client.Avatars.RequestAvatarPicks(e.Avatar.ID); - } - } - - private void Avatars_AvatarPicksReply(object sender, AvatarPicksReplyEventArgs e) - { - // we'll unsubscribe from the AvatarPicksReply event since we now have the data - // we were looking for - Client.Avatars.AvatarPicksReply -= Avatars_AvatarPicksReply; - // loop through the dictionary and extract the names of the top picks from our profile - foreach (var pickName in e.Picks.Values) - { - Console.WriteLine(pickName); - } - } - - - - + + Can modify public access settings for group owned parcels + + + Can manager parcel ban lists on group owned land + + + Can manage pass list sales information + + + Can eject and freeze other avatars on group owned land + + + Can return objects set to group + + + Can return non-group owned/set objects + + + Can return group owned objects + + + Can landscape using Linden plants + + + Can deed objects to group - - - Construct a new instance of the AvatarUpdateEventArgs class - - The simulator the packet originated from - The data - The simulator time dilation - The avatar was not in the dictionary before this update + + Can move group owned objects - - Get the simulator the object originated from + + Can set group owned objects for-sale - - Get the data + + Pay group liabilities and receive group dividends - - Get the simulator time dilation + + Can send group notices - - true if the did not exist in the dictionary before this update (always true if avatar tracking has been disabled) + + Can receive group notices - - Provides additional primitive data for the event - The event occurs when the simulator sends - an containing additional details for a Primitive, Foliage data or Attachment data - The event is also raised when a request is - made. - - - The following code example uses the , and - - properties to display new attachments and send a request for additional properties containing the name of the - attachment then display it on the window. - - // Subscribe to the event that provides additional primitive details - Client.Objects.ObjectProperties += Objects_ObjectProperties; - - // handle the properties data that arrives - private void Objects_ObjectProperties(object sender, ObjectPropertiesEventArgs e) - { - Console.WriteLine("Primitive Properties: {0} Name is {1}", e.Properties.ObjectID, e.Properties.Name); - } - - + + Can create group proposals - + + Can vote on group proposals + + + Can join group chat sessions + + + Can use voice chat in Group Chat sessions + + + Can moderate group chat sessions + + + Has admin rights to any experiences owned by this group + + + Can sign scripts for experiences owned by this group + + + Allows access to ban / un-ban agents from a group + + - Construct a new instance of the ObjectPropertiesEventArgs class + Ban actions available for group members - The simulator the object is located - The primitive Properties - - - Get the simulator the object is located - - Get the primitive properties + + Ban agent from joining a group - - Provides additional primitive data for the event - The event occurs when the simulator sends - an containing additional details for a Primitive or Foliage data that is currently - being tracked in the dictionary - The event is also raised when a request is - made and is enabled - + + Remove restriction on agent jointing a group - + - Construct a new instance of the ObjectPropertiesUpdatedEvenrArgs class - - The simulator the object is located - The Primitive - The primitive Properties + Handles all network traffic related to reading and writing group + information + - - Get the primitive details + + The event subscribers. null if no subcribers - - Provides additional primitive data, permissions and sale info for the event - The event occurs when the simulator sends - an containing additional details for a Primitive, Foliage data or Attachment. This includes - Permissions, Sale info, and other basic details on an object - The event is also raised when a request is - made, the viewer equivalent is hovering the mouse cursor over an object - + + Raises the CurrentGroups event + A CurrentGroupsEventArgs object containing the + data sent from the simulator - - Get the simulator the object is located + + Thread sync lock object - - + + Raised when the simulator sends us data containing + our current group membership - - + + The event subscribers. null if no subcribers - - Provides primitive data containing updated location, velocity, rotation, textures for the event - The event occurs when the simulator sends updated location, velocity, rotation, etc - + + Raises the GroupNamesReply event + A GroupNamesEventArgs object containing the + data response from the simulator - - Get the simulator the object is located + + Thread sync lock object - - Get the primitive details + + Raised when the simulator responds to a RequestGroupName + or RequestGroupNames request - - + + The event subscribers. null if no subcribers - - + + Raises the GroupProfile event + An GroupProfileEventArgs object containing the + data returned from the simulator - - - - + + Thread sync lock object - - Get the simulator the object is located + + Raised when the simulator responds to a request - - Get the primitive details + + The event subscribers. null if no subcribers - - + + Raises the GroupMembers event + A GroupMembersEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the - event + + Raises the GroupRolesDataReply event + A GroupRolesDataReplyEventArgs object containing the + data returned from the simulator - - Get the simulator the object is located + + Thread sync lock object - - The LocalID of the object + + Raised when the simulator responds to a request - - Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the - event + + The event subscribers. null if no subcribers - - Get the simulator the object is located + + Raises the GroupRoleMembersReply event + A GroupRolesRoleMembersReplyEventArgs object containing the + data returned from the simulator - - The LocalID of the object + + Thread sync lock object - - - Provides updates sit position data - + + Raised when the simulator responds to a request - - Get the simulator the object is located + + The event subscribers. null if no subcribers - - + + Raises the GroupTitlesReply event + A GroupTitlesReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - - - + + The event subscribers. null if no subcribers - - Get the simulator the object is located + + Raises the GroupAccountSummary event + A GroupAccountSummaryReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when a response to a RequestGroupAccountSummary is returned + by the simulator - - + + The event subscribers. null if no subcribers - - - Indicates if the operation was successful - + + Raises the GroupCreated event + An GroupCreatedEventArgs object containing the + data returned from the simulator - - - Media version string - + + Thread sync lock object - - - Array of media entries indexed by face number - + + Raised when a request to create a group is successful - - - Set when simulator sends us infomation on primitive's physical properties - + + The event subscribers. null if no subcribers - - Simulator where the message originated + + Raises the GroupJoined event + A GroupOperationEventArgs object containing the + result of the operation returned from the simulator - - Updated physical properties + + Thread sync lock object - - - Constructor - - Simulator where the message originated - Updated physical properties + + Raised when a request to join a group either + fails or succeeds - - Size of the byte array used to store raw packet data + + The event subscribers. null if no subcribers - - Raw packet data buffer + + Raises the GroupLeft event + A GroupOperationEventArgs object containing the + result of the operation returned from the simulator - - Length of the data to transmit + + Thread sync lock object - - EndPoint of the remote host + + Raised when a request to leave a group either + fails or succeeds - - - Create an allocated UDP packet buffer for receiving a packet - + + The event subscribers. null if no subcribers - - - Create an allocated UDP packet buffer for sending a packet - - EndPoint of the remote host + + Raises the GroupDropped event + An GroupDroppedEventArgs object containing the + the group your agent left - - - Create an allocated UDP packet buffer for sending a packet - - EndPoint of the remote host - Size of the buffer to allocate for packet data + + Thread sync lock object - - - Object pool for packet buffers. This is used to allocate memory for all - incoming and outgoing packets, and zerocoding buffers for those packets - + + Raised when A group is removed from the group server - - - Creates a new instance of the ObjectPoolBase class. Initialize MUST be called - after using this constructor. - + + The event subscribers. null if no subcribers - - - Creates a new instance of the ObjectPool Base class. - - The object pool is composed of segments, which - are allocated whenever the size of the pool is exceeded. The number of items - in a segment should be large enough that allocating a new segmeng is a rare - thing. For example, on a server that will have 10k people logged in at once, - the receive buffer object pool should have segment sizes of at least 1000 - byte arrays per segment. - - The minimun number of segments that may exist. - Perform a full GC.Collect whenever a segment is allocated, and then again after allocation to compact the heap. - The frequency which segments are checked to see if they're eligible for cleanup. + + Raises the GroupMemberEjected event + An GroupMemberEjectedEventArgs object containing the + data returned from the simulator - - - Forces the segment cleanup algorithm to be run. This method is intended - primarly for use from the Unit Test libraries. - + + Thread sync lock object - - - Responsible for allocate 1 instance of an object that will be stored in a segment. - - An instance of whatever objec the pool is pooling. + + Raised when a request to eject a member from a group either + fails or succeeds - - - Checks in an instance of T owned by the object pool. This method is only intended to be called - by the WrappedObject class. - - The segment from which the instance is checked out. - The instance of T to check back into the segment. + + The event subscribers. null if no subcribers - - - Checks an instance of T from the pool. If the pool is not sufficient to - allow the checkout, a new segment is created. - - A WrappedObject around the instance of T. To check - the instance back into the segment, be sureto dispose the WrappedObject - when finished. + + Raises the GroupNoticesListReply event + An GroupNoticesListReplyEventArgs object containing the + data returned from the simulator - - - The total number of segments created. Intended to be used by the Unit Tests. - + + Thread sync lock object - - - The number of items that are in a segment. Items in a segment - are all allocated at the same time, and are hopefully close to - each other in the managed heap. - + + Raised when the simulator sends us group notices + - - - The minimum number of segments. When segments are reclaimed, - this number of segments will always be left alone. These - segments are allocated at startup. - + + The event subscribers. null if no subcribers - - - The age a segment must be before it's eligible for cleanup. - This is used to prevent thrash, and typical values are in - the 5 minute range. - + + Raises the GroupInvitation event + An GroupInvitationEventArgs object containing the + data returned from the simulator - - - The frequence which the cleanup thread runs. This is typically - expected to be in the 5 minute range. - + + Thread sync lock object - - - Initialize the object pool in client mode - - Server to connect to - - + + Raised when another agent invites our avatar to join a group - - - Initialize the object pool in server mode - - - + + The event subscribers. null if no subcribers + + + Raises the BannedAgents event + An BannedAgentsEventArgs object containing the + data returned from the simulator + + + Thread sync lock object + + + Raised when another agent invites our avatar to join a group + + + A reference to the current instance + + + Currently-active group members requests + + + Currently-active group roles requests + + + Currently-active group role-member requests + + + Dictionary keeping group members while request is in progress + + + Dictionary keeping mebmer/role mapping while request is in progress + + + Dictionary keeping GroupRole information while request is in progress - - - Returns a packet buffer with EndPoint set if the buffer is in - client mode, or with EndPoint set to null in server mode - - Initialized UDPPacketBuffer object + + Caches group name lookups - + - Default constructor + Construct a new instance of the GroupManager class + A reference to the current instance - + - Check a packet buffer out of the pool + Request a current list of groups the avatar is a member of. - A packet buffer object + CAPS Event Queue must be running for this to work since the results + come across CAPS. - + - Checks the instance back into the object pool + Lookup name of group based on groupID + groupID of group to lookup name for. - + - Returns an instance of the class that has been checked out of the Object Pool. + Request lookup of multiple group names + List of group IDs to request. - - - - + + Lookup group profile data such as name, enrollment, founder, logo, etc + Subscribe to OnGroupProfile event to receive the results. + group ID (UUID) - - - - + + Request a list of group members. + Subscribe to OnGroupMembers event to receive the results. + group ID (UUID) + UUID of the request, use to index into cache - - - - + + Request group roles + Subscribe to OnGroupRoles event to receive the results. + group ID (UUID) + UUID of the request, use to index into cache - - - - + + Request members (members,role) role mapping for a group. + Subscribe to OnGroupRolesMembers event to receive the results. + group ID (UUID) + UUID of the request, use to index into cache - - - - - - + + Request a groups Titles + Subscribe to OnGroupTitles event to receive the results. + group ID (UUID) + UUID of the request, use to index into cache - - - The ObservableDictionary class is used for storing key/value pairs. It has methods for firing - events to subscribers when items are added, removed, or changed. - - Key - Value + + Begin to get the group account summary + Subscribe to the OnGroupAccountSummary event to receive the results. + group ID (UUID) + How long of an interval + Which interval (0 for current, 1 for last) - - - A dictionary of callbacks to fire when specified action occurs - + + Invites a user to a group + The group to invite to + A list of roles to invite a person to + Key of person to invite - - - Register a callback to be fired when an action occurs - - The action - The callback to fire + + Set a group as the current active group + group ID (UUID) - - - Unregister a callback - - The action - The callback to fire + + Change the role that determines your active title + Group ID to use + Role ID to change to - + + Set this avatar's tier contribution + Group ID to change tier in + amount of tier to donate + + - + Save wheather agent wants to accept group notices and list this group in their profile - - + Group + Accept notices from this group + List this group in the profile - - Internal dictionary that this class wraps around. Do not - modify or enumerate the contents of this dictionary without locking + + Request to join a group + Subscribe to OnGroupJoined event for confirmation. + group ID (UUID) to join. - + - Initializes a new instance of the Class - with the specified key/value, has the default initial capacity. + Request to create a new group. If the group is successfully + created, L$100 will automatically be deducted - - - // initialize a new ObservableDictionary named testDict with a string as the key and an int as the value. - public ObservableDictionary<string, int> testDict = new ObservableDictionary<string, int>(); - - + Subscribe to OnGroupCreated event to receive confirmation. + Group struct containing the new group info - - - Initializes a new instance of the Class - with the specified key/value, With its initial capacity specified. - - Initial size of dictionary - - - // initialize a new ObservableDictionary named testDict with a string as the key and an int as the value, - // initially allocated room for 10 entries. - public ObservableDictionary<string, int> testDict = new ObservableDictionary<string, int>(10); - - + + Update a group's profile and other information + Groups ID (UUID) to update. + Group struct to update. - - - Try to get entry from the with specified key - - Key to use for lookup - Value returned - if specified key exists, if not found - - - // find your avatar using the Simulator.ObjectsAvatars ObservableDictionary: - Avatar av; - if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) - Console.WriteLine("Found Avatar {0}", av.Name); - - - + + Eject a user from a group + Group ID to eject the user from + Avatar's key to eject - - - Finds the specified match. - - The match. - Matched value - - - // use a delegate to find a prim in the ObjectsPrimitives ObservableDictionary - // with the ID 95683496 - uint findID = 95683496; - Primitive findPrim = sim.ObjectsPrimitives.Find( - delegate(Primitive prim) { return prim.ID == findID; }); - - + + Update role information + Modified role to be updated - - Find All items in an - return matching items. - a containing found items. - - Find All prims within 20 meters and store them in a List - - int radius = 20; - List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( - delegate(Primitive prim) { - Vector3 pos = prim.Position; - return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); - } - ); - - + + Create a new group role + Group ID to update + Role to create - - Find All items in an - return matching keys. - a containing found keys. - - Find All keys which also exist in another dictionary - - List<UUID> matches = myDict.FindAll( - delegate(UUID id) { - return myOtherDict.ContainsKey(id); - } - ); - - + + Delete a group role + Group ID to update + Role to delete - - Check if Key exists in Dictionary - Key to check for - if found, otherwise + + Remove an avatar from a role + Group ID to update + Role ID to be removed from + Avatar's Key to remove - - Check if Value exists in Dictionary - Value to check for - if found, otherwise + + Assign an avatar to a role + Group ID to update + Role ID to assign to + Avatar's ID to assign to role - - - Adds the specified key to the dictionary, dictionary locking is not performed, - - - The key - The value + + Request the group notices list + Group ID to fetch notices for - - - Removes the specified key, dictionary locking is not performed - - The key. - if successful, otherwise + + Request a group notice by key + ID of group notice - - - Clear the contents of the dictionary - + + Send out a group notice + Group ID to update + GroupNotice structure containing notice data - - - Enumerator for iterating dictionary entries - - + + Start a group proposal (vote) + The Group ID to send proposal to + GroupProposal structure containing the proposal - - - Gets the number of Key/Value pairs contained in the - + + Request to leave a group + Subscribe to OnGroupLeft event to receive confirmation + The group to leave - + - Indexer for the dictionary + Gets the URI of the cpability for handling group bans - The key - The value + Group ID + null, if the feature is not supported, or URI of the capability - + - Add a custom decoder callback + Request a list of residents banned from joining a group - The key of the field to decode - The custom decode handler + UUID of the group - + - Remove a custom decoder callback + Request a list of residents banned from joining a group - The key of the field to decode - The custom decode handler + UUID of the group + Callback on request completition - + - Creates a formatted string containing the values of a Packet + Request that group of agents be banned or unbanned from the group - The Packet - A formatted string of values of the nested items in the Packet object + Group ID + Ban/Unban action + Array of agents UUIDs to ban - + - Decode an IMessage object into a beautifully formatted string + Request that group of agents be banned or unbanned from the group - The IMessage object - Recursion level (used for indenting) - A formatted string containing the names and values of the source object + Group ID + Ban/Unban action + Array of agents UUIDs to ban + Callback - - - A custom decoder callback - - The key of the object - the data to decode - A string represending the fieldData + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Provides helper methods for parallelizing loops - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Executes a for loop in which iterations may run in parallel - - The loop will be started at this index - The loop will be terminated before this index is reached - Method body to run for each iteration of the loop + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Executes a for loop in which iterations may run in parallel - - The number of concurrent execution threads to run - The loop will be started at this index - The loop will be terminated before this index is reached - Method body to run for each iteration of the loop + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Executes a foreach loop in which iterations may run in parallel - - Object type that the collection wraps - An enumerable collection to iterate over - Method body to run for each object in the collection + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Executes a foreach loop in which iterations may run in parallel - - Object type that the collection wraps - The number of concurrent execution threads to run - An enumerable collection to iterate over - Method body to run for each object in the collection + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Executes a series of tasks in parallel - - A series of method bodies to execute + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Executes a series of tasks in parallel - - The number of concurrent execution threads to run - A series of method bodies to execute + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Type of return to use when returning objects from a parcel - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Return objects owned by parcel owner + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Return objects set to group + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Return objects not owned by parcel owner or set to group + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Return a specific list of objects on parcel + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Return objects that are marked for-sale + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - + + Contains the current groups your agent is a member of + + + Get the current groups your agent is a member of + + + Construct a new instance of the CurrentGroupsEventArgs class + The current groups your agent is a member of + + + A Dictionary of group names, where the Key is the groups ID and the value is the groups name + + + Get the Group Names dictionary + + + Construct a new instance of the GroupNamesEventArgs class + The Group names dictionary + + + Represents the members of a group + + + Get the ID as returned by the request to correlate + this result set and the request + + + Get the ID of the group + + + Get the dictionary of members + + - Blacklist/Whitelist flags used in parcels Access List + Construct a new instance of the GroupMembersReplyEventArgs class + The ID of the request + The ID of the group + The membership list of the group - - Agent is denied access + + Represents the roles associated with a group - - Agent is granted access + + Get the ID as returned by the request to correlate + this result set and the request - - - The result of a request for parcel properties - + + Get the ID of the group - - No matches were found for the request + + Get the dictionary containing the roles - - Request matched a single parcel + + Construct a new instance of the GroupRolesDataReplyEventArgs class + The ID as returned by the request to correlate + this result set and the request + The ID of the group + The dictionary containing the roles - - Request matched multiple parcels + + Represents the Role to Member mappings for a group - - - Flags used in the ParcelAccessListRequest packet to specify whether - we want the access list (whitelist), ban list (blacklist), or both - + + Get the ID as returned by the request to correlate + this result set and the request - - Request the access list + + Get the ID of the group - - Request the ban list + + Get the member to roles map - - Request both White and Black lists + + Construct a new instance of the GroupRolesMembersReplyEventArgs class + The ID as returned by the request to correlate + this result set and the request + The ID of the group + The member to roles map - - - Sequence ID in ParcelPropertiesReply packets (sent when avatar - tries to cross a parcel border) - + + Represents the titles for a group - - Parcel is currently selected + + Get the ID as returned by the request to correlate + this result set and the request - - Parcel restricted to a group the avatar is not a - member of + + Get the ID of the group - - Avatar is banned from the parcel + + Get the titles - - Parcel is restricted to an access list that the - avatar is not on + + Construct a new instance of the GroupTitlesReplyEventArgs class + The ID as returned by the request to correlate + this result set and the request + The ID of the group + The titles - - Response to hovering over a parcel + + Represents the summary data for a group - - - The tool to use when modifying terrain levels - + + Get the ID of the group - - Level the terrain + + Get the summary data - - Raise the terrain + + Construct a new instance of the GroupAccountSummaryReplyEventArgs class + The ID of the group + The summary data - - Lower the terrain + + A response to a group create request - - Smooth the terrain + + Get the ID of the group - - Add random noise to the terrain + + true of the group was created successfully - - Revert terrain to simulator default + + A string containing the message - - - The tool size to use when changing terrain levels - + + Construct a new instance of the GroupCreatedReplyEventArgs class + The ID of the group + the success or faulure of the request + A string containing additional information - - Small + + Represents a response to a request - - Medium + + Get the ID of the group - - Large + + true of the request was successful - - - Reasons agent is denied access to a parcel on the simulator - + + Construct a new instance of the GroupOperationEventArgs class + The ID of the group + true of the request was successful - - Agent is not denied, access is granted + + Represents your agent leaving a group - - Agent is not a member of the group set for the parcel, or which owns the parcel + + Get the ID of the group - - Agent is not on the parcels specific allow list + + Construct a new instance of the GroupDroppedEventArgs class + The ID of the group - - Agent is on the parcels ban list + + Represents a list of active group notices - - Unknown + + Get the ID of the group - - Agent is not age verified and parcel settings deny access to non age verified avatars + + Get the notices list - - - Parcel overlay type. This is used primarily for highlighting and - coloring which is why it is a single integer instead of a set of - flags - - These values seem to be poorly thought out. The first three - bits represent a single value, not flags. For example Auction (0x05) is - not a combination of OwnedByOther (0x01) and ForSale(0x04). However, - the BorderWest and BorderSouth values are bit flags that get attached - to the value stored in the first three bits. Bits four, five, and six - are unused + + Construct a new instance of the GroupNoticesListReplyEventArgs class + The ID of the group + The list containing active notices - - Public land + + Represents the profile of a group - - Land is owned by another avatar + + Get the group profile - - Land is owned by a group + + Construct a new instance of the GroupProfileEventArgs class + The group profile - - Land is owned by the current avatar + + + Provides notification of a group invitation request sent by another Avatar + + The invitation is raised when another avatar makes an offer for our avatar + to join a group. - - Land is for sale + + The ID of the Avatar sending the group invitation - - Land is being auctioned + + The name of the Avatar sending the group invitation - - Land is private + + A message containing the request information which includes + the name of the group, the groups charter and the fee to join details - - To the west of this area is a parcel border + + The Simulator - - To the south of this area is a parcel border + + Set to true to accept invitation, false to decline - + - Various parcel properties + Result of the request for list of agents banned from a group - - No flags set + + Indicates if list of banned agents for a group was successfully retrieved - - Allow avatars to fly (a client-side only restriction) + + Indicates if list of banned agents for a group was successfully retrieved - - Allow foreign scripts to run + + Array containing a list of UUIDs of the agents banned from a group - - This parcel is for sale + + + Static helper functions and global variables + - - Allow avatars to create a landmark on this parcel + + This header flag signals that ACKs are appended to the packet - - Allows all avatars to edit the terrain on this parcel + + This header flag signals that this packet has been sent before - - Avatars have health and can take damage on this parcel. - If set, avatars can be killed and sent home here + + This header flags signals that an ACK is expected for this packet - - Foreign avatars can create objects here + + This header flag signals that the message is compressed using zerocoding - - All objects on this parcel can be purchased + + + Passed to Logger.Log() to identify the severity of a log entry + - - Access is restricted to a group + + No logging information will be output - - Access is restricted to a whitelist + + Non-noisy useful information, may be helpful in + debugging a problem - - Ban blacklist is enabled + + A non-critical error occurred. A warning will not + prevent the rest of the library from operating as usual, + although it may be indicative of an underlying issue - - Unknown + + A critical error has occurred. Generally this will + be followed by the network layer shutting down, although the + stability of the library after an error is uncertain - - List this parcel in the search directory + + Used for internal testing, this logging level can + generate very noisy (long and/or repetitive) messages. Don't + pass this to the Log() function, use DebugLog() instead. + - - Allow personally owned parcels to be deeded to group + + + + + + - - If Deeded, owner contributes required tier to group parcel is deeded to + + + + + + + - - Restrict sounds originating on this parcel to the - parcel boundaries + + + + + + - - Objects on this parcel are sold when the land is - purchsaed + + + + + + + - - Allow this parcel to be published on the web + + + Given an X/Y location in absolute (grid-relative) terms, a region + handle is returned along with the local X/Y location in that region + + The absolute X location, a number such as + 255360.35 + The absolute Y location, a number such as + 255360.35 + The sim-local X position of the global X + position, a value from 0.0 to 256.0 + The sim-local Y position of the global Y + position, a value from 0.0 to 256.0 + A 64-bit region handle that can be used to teleport to - - The information for this parcel is mature content + + + Converts a floating point number to a terse string format used for + transmitting numbers in wearable asset files + + Floating point number to convert to a string + A terse string representation of the input number - - The media URL is an HTML page + + + Convert a variable length field (byte array) to a string, with a + field name prepended to each line of the output + + If the byte array has unprintable characters in it, a + hex dump will be written instead + The StringBuilder object to write to + The byte array to convert to a string + A field name to prepend to each line of output - - The media URL is a raw HTML string + + + Decode a zerocoded byte array, used to decompress packets marked + with the zerocoded flag + + Any time a zero is encountered, the next byte is a count + of how many zeroes to expand. One zero is encoded with 0x00 0x01, + two zeroes is 0x00 0x02, three zeroes is 0x00 0x03, etc. The + first four bytes are copied directly to the output buffer. + + The byte array to decode + The length of the byte array to decode. This + would be the length of the packet up to (but not including) any + appended ACKs + The output byte array to decode to + The length of the output buffer - - Restrict foreign object pushes + + + Encode a byte array with zerocoding. Used to compress packets marked + with the zerocoded flag. Any zeroes in the array are compressed down + to a single zero byte followed by a count of how many zeroes to expand + out. A single zero becomes 0x00 0x01, two zeroes becomes 0x00 0x02, + three zeroes becomes 0x00 0x03, etc. The first four bytes are copied + directly to the output buffer. + + The byte array to encode + The length of the byte array to encode + The output byte array to encode to + The length of the output buffer - - Ban all non identified/transacted avatars + + + Calculates the CRC (cyclic redundancy check) needed to upload inventory. + + Creation date + Sale type + Inventory type + Type + Asset ID + Group ID + Sale price + Owner ID + Creator ID + Item ID + Folder ID + Everyone mask (permissions) + Flags + Next owner mask (permissions) + Group mask (permissions) + Owner mask (permissions) + The calculated CRC - - Allow group-owned scripts to run + + + Attempts to load a file embedded in the assembly + + The filename of the resource to load + A Stream for the requested file, or null if the resource + was not successfully loaded - - Allow object creation by group members or group - objects + + + Attempts to load a file either embedded in the assembly or found in + a given search path + + The filename of the resource to load + An optional path that will be searched if + the asset is not found embedded in the assembly + A Stream for the requested file, or null if the resource + was not successfully loaded - - Allow all objects to enter this parcel + + + Converts a list of primitives to an object that can be serialized + with the LLSD system + + Primitives to convert to a serializable object + An object that can be serialized with LLSD - - Only allow group and owner objects to enter this parcel + + + Deserializes OSD in to a list of primitives + + Structure holding the serialized primitive list, + must be of the SDMap type + A list of deserialized primitives - - Voice Enabled on this parcel + + + Converts a struct or class object containing fields only into a key value separated string + + The struct object + A string containing the struct fields as the keys, and the field value as the value separated + + + // Add the following code to any struct or class containing only fields to override the ToString() + // method to display the values of the passed object + + /// Print the struct data as a string + ///A string containing the field name, and field value + public override string ToString() + { + return Helpers.StructToString(this); + } + + - - Use Estate Voice channel for Voice on this parcel + + + The InternalDictionary class is used through the library for storing key/value pairs. + It is intended to be a replacement for the generic Dictionary class and should + be used in its place. It contains several methods for allowing access to the data from + outside the library that are read only and thread safe. + + + Key + Value - - Deny Age Unverified Users + + Internal dictionary that this class wraps around. Do not + modify or enumerate the contents of this dictionary without locking + on this member - + - Parcel ownership status + Gets the number of Key/Value pairs contained in the - - Placeholder - - - Parcel is leased (owned) by an avatar or group - - - Parcel is in process of being leased (purchased) by an avatar or group - - - Parcel has been abandoned back to Governor Linden - - + - Category parcel is listed in under search + Initializes a new instance of the Class + with the specified key/value, has the default initial capacity. + + + // initialize a new InternalDictionary named testDict with a string as the key and an int as the value. + public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(); + + - - No assigned category - - - Linden Infohub or public area - - - Adult themed area - - - Arts and Culture - - - Business + + + Initializes a new instance of the Class + with the specified key/value, has its initial valies copied from the specified + + + + to copy initial values from + + + // initialize a new InternalDictionary named testAvName with a UUID as the key and an string as the value. + // populates with copied values from example KeyNameCache Dictionary. + + // create source dictionary + Dictionary<UUID, string> KeyNameCache = new Dictionary<UUID, string>(); + KeyNameCache.Add("8300f94a-7970-7810-cf2c-fc9aa6cdda24", "Jack Avatar"); + KeyNameCache.Add("27ba1e40-13f7-0708-3e98-5819d780bd62", "Jill Avatar"); + + // Initialize new dictionary. + public InternalDictionary<UUID, string> testAvName = new InternalDictionary<UUID, string>(KeyNameCache); + + - - Educational + + + Initializes a new instance of the Class + with the specified key/value, With its initial capacity specified. + + Initial size of dictionary + + + // initialize a new InternalDictionary named testDict with a string as the key and an int as the value, + // initially allocated room for 10 entries. + public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(10); + + - - Gaming + + + Try to get entry from with specified key + + Key to use for lookup + Value returned + if specified key exists, if not found + + + // find your avatar using the Simulator.ObjectsAvatars InternalDictionary: + Avatar av; + if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) + Console.WriteLine("Found Avatar {0}", av.Name); + + + - - Hangout or Club + + + Finds the specified match. + + The match. + Matched value + + + // use a delegate to find a prim in the ObjectsPrimitives InternalDictionary + // with the ID 95683496 + uint findID = 95683496; + Primitive findPrim = sim.ObjectsPrimitives.Find( + delegate(Primitive prim) { return prim.ID == findID; }); + + - - Newcomer friendly + + Find All items in an + return matching items. + a containing found items. + + Find All prims within 20 meters and store them in a List + + int radius = 20; + List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( + delegate(Primitive prim) { + Vector3 pos = prim.Position; + return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); + } + ); + + - - Parks and Nature + + Find All items in an + return matching keys. + a containing found keys. + + Find All keys which also exist in another dictionary + + List<UUID> matches = myDict.FindAll( + delegate(UUID id) { + return myOtherDict.ContainsKey(id); + } + ); + + - - Residential + + Perform an on each entry in an + to perform + + + // Iterates over the ObjectsPrimitives InternalDictionary and prints out some information. + Client.Network.CurrentSim.ObjectsPrimitives.ForEach( + delegate(Primitive prim) + { + if (prim.Text != null) + { + Console.WriteLine("NAME={0} ID = {1} TEXT = '{2}'", + prim.PropertiesFamily.Name, prim.ID, prim.Text); + } + }); + + - - Shopping + + Perform an on each key of an + to perform - - Not Used? + + + Perform an on each KeyValuePair of an + + to perform - - Other + + Check if Key exists in Dictionary + Key to check for + if found, otherwise - - Not an actual category, only used for queries + + Check if Value exists in Dictionary + Value to check for + if found, otherwise - + - Type of teleport landing for a parcel + Adds the specified key to the dictionary, dictionary locking is not performed, + + The key + The value - - Unset, simulator default - - - Specific landing point set for this parcel + + + Removes the specified key, dictionary locking is not performed + + The key. + if successful, otherwise - - No landing point set, direct teleports enabled for - this parcel + + + Indexer for the dictionary + + The key + The value - + - Parcel Media Command used in ParcelMediaCommandMessage + Exception class to identify inventory exceptions - - Stop the media stream and go back to the first frame + + + Responsible for maintaining inventory structure. Inventory constructs nodes + and manages node children as is necessary to maintain a coherant hirarchy. + Other classes should not manipulate or create InventoryNodes explicitly. When + A node's parent changes (when a folder is moved, for example) simply pass + Inventory the updated InventoryFolder and it will make the appropriate changes + to its internal representation. + - - Pause the media stream (stop playing but stay on current frame) + + The event subscribers, null of no subscribers - - Start the current media stream playing and stop when the end is reached + + Raises the InventoryObjectUpdated Event + A InventoryObjectUpdatedEventArgs object containing + the data sent from the simulator - - Start the current media stream playing, - loop to the beginning when the end is reached and continue to play + + Thread sync lock object - - Specifies the texture to replace with video - If passing the key of a texture, it must be explicitly typecast as a key, - not just passed within double quotes. + + Raised when the simulator sends us data containing + ... - - Specifies the movie URL (254 characters max) + + The event subscribers, null of no subscribers - - Specifies the time index at which to begin playing + + Raises the InventoryObjectRemoved Event + A InventoryObjectRemovedEventArgs object containing + the data sent from the simulator - - Specifies a single agent to apply the media command to + + Thread sync lock object - - Unloads the stream. While the stop command sets the texture to the first frame of the movie, - unload resets it to the real texture that the movie was replacing. + + Raised when the simulator sends us data containing + ... - - Turn on/off the auto align feature, similar to the auto align checkbox in the parcel media properties - (NOT to be confused with the "align" function in the textures view of the editor!) Takes TRUE or FALSE as parameter. + + The event subscribers, null of no subscribers - - Allows a Web page or image to be placed on a prim (1.19.1 RC0 and later only). - Use "text/html" for HTML. + + Raises the InventoryObjectAdded Event + A InventoryObjectAddedEventArgs object containing + the data sent from the simulator - - Resizes a Web page to fit on x, y pixels (1.19.1 RC0 and later only). - This might still not be working + + Thread sync lock object - - Sets a description for the media being displayed (1.19.1 RC0 and later only). + + Raised when the simulator sends us data containing + ... - + - Some information about a parcel of land returned from a DirectoryManager search + The root folder of this avatars inventory - - Global Key of record - - - Parcel Owners + + + The default shared library folder + - - Name field of parcel, limited to 128 characters + + + The root node of the avatars inventory + - - Description field of parcel, limited to 256 characters + + + The root node of the default shared library + - - Total Square meters of parcel + + + Returns the contents of the specified folder + + A folder's UUID + The contents of the folder corresponding to folder + When folder does not exist in the inventory - - Total area billable as Tier, for group owned land this will be 10% less than ActualArea + + + Updates the state of the InventoryNode and inventory data structure that + is responsible for the InventoryObject. If the item was previously not added to inventory, + it adds the item, and updates structure accordingly. If it was, it updates the + InventoryNode, changing the parent node if item.parentUUID does + not match node.Parent.Data.UUID. + + You can not set the inventory root folder using this method + + The InventoryObject to store - - True of parcel is in Mature simulator + + + Removes the InventoryObject and all related node data from Inventory. + + The InventoryObject to remove. - - Grid global X position of parcel + + + Used to find out if Inventory contains the InventoryObject + specified by uuid. + + The UUID to check. + true if inventory contains uuid, false otherwise - - Grid global Y position of parcel + + + Saves the current inventory structure to a cache file + + Name of the cache file to save to - - Grid global Z position of parcel (not used) + + + Loads in inventory cache file into the inventory structure. Note only valid to call after login has been successful. + + Name of the cache file to load + The number of inventory items sucessfully reconstructed into the inventory node tree - - Name of simulator parcel is located in + + + By using the bracket operator on this class, the program can get the + InventoryObject designated by the specified uuid. If the value for the corresponding + UUID is null, the call is equivelant to a call to RemoveNodeFor(this[uuid]). + If the value is non-null, it is equivelant to a call to UpdateNodeFor(value), + the uuid parameter is ignored. + + The UUID of the InventoryObject to get or set, ignored if set to non-null value. + The InventoryObject corresponding to uuid. - - Texture of parcels display picture + + Sort by name - - Float representing calculated traffic based on time spent on parcel by avatars + + Sort by date - - Sale price of parcel (not used) + + Sort folders by name, regardless of whether items are + sorted by name or date - - Auction ID of parcel + + Place system folders at the top - + - Parcel Media Information + Possible destinations for DeRezObject request - - A byte, if 0x1 viewer should auto scale media to fit object + + - - A boolean, if true the viewer should loop the media + + Copy from in-world to agent inventory - - The Asset UUID of the Texture which when applied to a - primitive will display the media + + Derez to TaskInventory - - A URL which points to any Quicktime supported media type + + - - A description of the media + + Take Object - - An Integer which represents the height of the media + + - - An integer which represents the width of the media + + Delete Object - - A string which contains the mime type of the media + + Put an avatar attachment into agent inventory - + + + + + Return an object back to the owner's inventory + + + Return a deeded object back to the last owner's inventory + + - Parcel of land, a portion of virtual real estate in a simulator + Upper half of the Flags field for inventory items - - The total number of contiguous 4x4 meter blocks your agent owns within this parcel + + Indicates that the NextOwner permission will be set to the + most restrictive set of permissions found in the object set + (including linkset items and object inventory items) on next rez - - The total number of contiguous 4x4 meter blocks contained in this parcel owned by a group or agent other than your own + + Indicates that the object sale information has been + changed - - Deprecated, Value appears to always be 0 + + If set, and a slam bit is set, indicates BaseMask will be overwritten on Rez - - Simulator-local ID of this parcel + + If set, and a slam bit is set, indicates OwnerMask will be overwritten on Rez - - UUID of the owner of this parcel + + If set, and a slam bit is set, indicates GroupMask will be overwritten on Rez - - Whether the land is deeded to a group or not + + If set, and a slam bit is set, indicates EveryoneMask will be overwritten on Rez - - + + If set, and a slam bit is set, indicates NextOwnerMask will be overwritten on Rez - - Date land was claimed + + Indicates whether this object is composed of multiple + items or not - - Appears to always be zero + + Indicates that the asset is only referenced by this + inventory item. If this item is deleted or updated to reference a + new assetID, the asset can be deleted - - This field is no longer used + + + Base Class for Inventory Items + - - Minimum corner of the axis-aligned bounding box for this - parcel + + of item/folder - - Maximum corner of the axis-aligned bounding box for this - parcel + + of parent folder - - Bitmap describing land layout in 4x4m squares across the - entire region + + Name of item/folder - - Total parcel land area + + Item/Folder Owners - - + + + Constructor, takes an itemID as a parameter + + The of the item - - Maximum primitives across the entire simulator owned by the same agent or group that owns this parcel that can be used + + + + + - - Total primitives across the entire simulator calculated by combining the allowed prim counts for each parcel - owned by the agent or group that owns this parcel + + + + + - - Maximum number of primitives this parcel supports + + + Generates a number corresponding to the value of the object to support the use of a hash table, + suitable for use in hashing algorithms and data structures such as a hash table + + A Hashcode of all the combined InventoryBase fields - - Total number of primitives on this parcel + + + Determine whether the specified object is equal to the current object + + InventoryBase object to compare against + true if objects are the same - - For group-owned parcels this indicates the total number of prims deeded to the group, - for parcels owned by an individual this inicates the number of prims owned by the individual + + + Determine whether the specified object is equal to the current object + + InventoryBase object to compare against + true if objects are the same - - Total number of primitives owned by the parcel group on - this parcel, or for parcels owned by an individual with a group set the - total number of prims set to that group. + + + Convert inventory to OSD + + OSD representation - - Total number of prims owned by other avatars that are not set to group, or not the parcel owner + + + An Item in Inventory + - - A bonus multiplier which allows parcel prim counts to go over times this amount, this does not affect - the max prims per simulator. e.g: 117 prim parcel limit x 1.5 bonus = 175 allowed + + The of this item - - Autoreturn value in minutes for others' objects + + The combined of this item - - + + The type of item from - - Sale price of the parcel, only useful if ForSale is set - The SalePrice will remain the same after an ownership - transfer (sale), so it can be used to see the purchase price after - a sale if the new owner has not changed it + + The type of item from the enum - - Parcel Name + + The of the creator of this item - - Parcel Description + + A Description of this item - - URL For Music Stream + + The s this item is set to or owned by - - + + If true, item is owned by a group - - Price for a temporary pass + + The price this item can be purchased for - - How long is pass valid for + + The type of sale from the enum - - + + Combined flags from - - Key of authorized buyer + + Time and date this inventory item was created, stored as + UTC (Coordinated Universal Time) - - Key of parcel snapshot + + Used to update the AssetID in requests sent to the server - - The landing point location + + The of the previous owner of the item - - The landing point LookAt + + + Construct a new InventoryItem object + + The of the item - - The type of landing enforced from the enum + + + Construct a new InventoryItem object of a specific Type + + The type of item from + of the item - - + + + Indicates inventory item is a link + + True if inventory item is a link to another inventory item - - + + + + + - - + + + + + - - Access list of who is whitelisted on this - parcel + + + Generates a number corresponding to the value of the object to support the use of a hash table. + Suitable for use in hashing algorithms and data structures such as a hash table + + A Hashcode of all the combined InventoryItem fields - - Access list of who is blacklisted on this - parcel + + + Compares an object + + The object to compare + true if comparison object matches - - TRUE of region denies access to age unverified users + + + Determine whether the specified object is equal to the current object + + The object to compare against + true if objects are the same - - true to obscure (hide) media url + + + Determine whether the specified object is equal to the current object + + The object to compare against + true if objects are the same - - true to obscure (hide) music url + + + Create InventoryItem from OSD + + OSD Data that makes up InventoryItem + Inventory item created - - A struct containing media details + + + Convert InventoryItem to OSD + + OSD representation of InventoryItem - + - Displays a parcel object in string format + InventoryTexture Class representing a graphical image - string containing key=value pairs of a parcel object + - + - Defalt constructor + Construct an InventoryTexture object - Local ID of this parcel + A which becomes the + objects AssetUUID - + - Update the simulator with any local changes to this Parcel object + Construct an InventoryTexture object from a serialization stream - Simulator to send updates to - Whether we want the simulator to confirm - the update with a reply packet or not - + - Set Autoreturn time + InventorySound Class representing a playable sound - Simulator to send the update to - + - Parcel (subdivided simulator lots) subsystem + Construct an InventorySound object + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventorySound object from a serialization stream + - - Raises the ParcelDwellReply event - A ParcelDwellReplyEventArgs object containing the - data returned from the simulator + + + InventoryCallingCard Class, contains information on another avatar + - - Thread sync lock object + + + Construct an InventoryCallingCard object + + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventoryCallingCard object from a serialization stream + - - Raises the ParcelInfoReply event - A ParcelInfoReplyEventArgs object containing the - data returned from the simulator + + + InventoryLandmark Class, contains details on a specific location + - - Thread sync lock object + + + Construct an InventoryLandmark object + + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventoryLandmark object from a serialization stream + - - Raises the ParcelProperties event - A ParcelPropertiesEventArgs object containing the - data returned from the simulator + + + Landmarks use the InventoryItemFlags struct and will have a flag of 1 set if they have been visited + - - Thread sync lock object + + + InventoryObject Class contains details on a primitive or coalesced set of primitives + - - The event subscribers. null if no subcribers + + + Construct an InventoryObject object + + A which becomes the + objects AssetUUID - - Raises the ParcelAccessListReply event - A ParcelAccessListReplyEventArgs object containing the - data returned from the simulator + + + Construct an InventoryObject object from a serialization stream + - - Thread sync lock object + + + Gets or sets the upper byte of the Flags value + - - The event subscribers. null if no subcribers + + + Gets or sets the object attachment point, the lower byte of the Flags value + - - Raises the ParcelObjectOwnersReply event - A ParcelObjectOwnersReplyEventArgs object containing the - data returned from the simulator + + + InventoryNotecard Class, contains details on an encoded text document + - - Thread sync lock object + + + Construct an InventoryNotecard object + + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventoryNotecard object from a serialization stream + - - Raises the SimParcelsDownloaded event - A SimParcelsDownloadedEventArgs object containing the - data returned from the simulator + + + InventoryCategory Class + + TODO: Is this even used for anything? - - Thread sync lock object + + + Construct an InventoryCategory object + + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventoryCategory object from a serialization stream + - - Raises the ForceSelectObjectsReply event - A ForceSelectObjectsReplyEventArgs object containing the - data returned from the simulator + + + InventoryLSL Class, represents a Linden Scripting Language object + - - Thread sync lock object + + + Construct an InventoryLSL object + + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventoryLSL object from a serialization stream + - - Raises the ParcelMediaUpdateReply event - A ParcelMediaUpdateReplyEventArgs object containing the - data returned from the simulator + + + InventorySnapshot Class, an image taken with the viewer + - - Thread sync lock object + + + Construct an InventorySnapshot object + + A which becomes the + objects AssetUUID - - The event subscribers. null if no subcribers + + + Construct an InventorySnapshot object from a serialization stream + - - Raises the ParcelMediaCommand event - A ParcelMediaCommandEventArgs object containing the - data returned from the simulator + + + InventoryAttachment Class, contains details on an attachable object + - - Thread sync lock object + + + Construct an InventoryAttachment object + + A which becomes the + objects AssetUUID - + - Default constructor + Construct an InventoryAttachment object from a serialization stream - A reference to the GridClient object - + - Request basic information for a single parcel + Get the last AttachmentPoint this object was attached to - Simulator-local ID of the parcel - + - Request properties of a single parcel + InventoryWearable Class, details on a clothing item or body part - Simulator containing the parcel - Simulator-local ID of the parcel - An arbitrary integer that will be returned - with the ParcelProperties reply, useful for distinguishing between - multiple simultaneous requests - + - Request the access list for a single parcel + Construct an InventoryWearable object - Simulator containing the parcel - Simulator-local ID of the parcel - An arbitrary integer that will be returned - with the ParcelAccessList reply, useful for distinguishing between - multiple simultaneous requests - + A which becomes the + objects AssetUUID - + - Request properties of parcels using a bounding box selection + Construct an InventoryWearable object from a serialization stream - Simulator containing the parcel - Northern boundary of the parcel selection - Eastern boundary of the parcel selection - Southern boundary of the parcel selection - Western boundary of the parcel selection - An arbitrary integer that will be returned - with the ParcelProperties reply, useful for distinguishing between - different types of parcel property requests - A boolean that is returned with the - ParcelProperties reply, useful for snapping focus to a single - parcel - + - Request all simulator parcel properties (used for populating the Simulator.Parcels - dictionary) + The , Skin, Shape, Skirt, Etc - Simulator to request parcels from (must be connected) - + - Request all simulator parcel properties (used for populating the Simulator.Parcels - dictionary) + InventoryAnimation Class, A bvh encoded object which animates an avatar - Simulator to request parcels from (must be connected) - If TRUE, will force a full refresh - Number of milliseconds to pause in between each request - + - Request the dwell value for a parcel + Construct an InventoryAnimation object - Simulator containing the parcel - Simulator-local ID of the parcel + A which becomes the + objects AssetUUID - + - Send a request to Purchase a parcel of land + Construct an InventoryAnimation object from a serialization stream - The Simulator the parcel is located in - The parcels region specific local ID - true if this parcel is being purchased by a group - The groups - true to remove tier contribution if purchase is successful - The parcels size - The purchase price of the parcel - - + - Reclaim a parcel of land + InventoryGesture Class, details on a series of animations, sounds, and actions - The simulator the parcel is in - The parcels region specific local ID - + - Deed a parcel to a group + Construct an InventoryGesture object - The simulator the parcel is in - The parcels region specific local ID - The groups + A which becomes the + objects AssetUUID - + - Request prim owners of a parcel of land. + Construct an InventoryGesture object from a serialization stream - Simulator parcel is in - The parcels region specific local ID - + - Return objects from a parcel + A folder contains s and has certain attributes specific + to itself - Simulator parcel is in - The parcels region specific local ID - the type of objects to return, - A list containing object owners s to return - + + The Preferred for a folder. + + + The Version of this folder + + + Number of child items this folder contains. + + - Subdivide (split) a parcel + Constructor - - - - - + UUID of the folder - + - Join two parcels of land creating a single parcel + - - - - - + - + - Get a parcels LocalID + Get Serilization data for this InventoryFolder object - Simulator parcel is in - Vector3 position in simulator (Z not used) - 0 on failure, or parcel LocalID on success. - A call to Parcels.RequestAllSimParcels is required to populate map and - dictionary. - + - Terraform (raise, lower, etc) an area or whole parcel of land + Construct an InventoryFolder object from a serialization stream - Simulator land area is in. - LocalID of parcel, or -1 if using bounding box - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - true on successful request sent. - Settings.STORE_LAND_PATCHES must be true, - Parcel information must be downloaded using RequestAllSimParcels() - + - Terraform (raise, lower, etc) an area or whole parcel of land + - Simulator land area is in. - west border of area to modify - south border of area to modify - east border of area to modify - north border of area to modify - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - true on successful request sent. - Settings.STORE_LAND_PATCHES must be true, - Parcel information must be downloaded using RequestAllSimParcels() + - + - Terraform (raise, lower, etc) an area or whole parcel of land + - Simulator land area is in. - LocalID of parcel, or -1 if using bounding box - west border of area to modify - south border of area to modify - east border of area to modify - north border of area to modify - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - How many meters + or - to lower, 1 = 1 meter - true on successful request sent. - Settings.STORE_LAND_PATCHES must be true, - Parcel information must be downloaded using RequestAllSimParcels() + + - + - Terraform (raise, lower, etc) an area or whole parcel of land + - Simulator land area is in. - LocalID of parcel, or -1 if using bounding box - west border of area to modify - south border of area to modify - east border of area to modify - north border of area to modify - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - How many meters + or - to lower, 1 = 1 meter - Height at which the terraform operation is acting at + + - + - Sends a request to the simulator to return a list of objects owned by specific owners + - Simulator local ID of parcel - Owners, Others, Etc - List containing keys of avatars objects to select; - if List is null will return Objects of type selectType - Response data is returned in the event + + - + - Eject and optionally ban a user from a parcel + Create InventoryFolder from OSD - target key of avatar to eject - true to also ban target + OSD Data that makes up InventoryFolder + Inventory folder created - + - Freeze or unfreeze an avatar over your land + Convert InventoryItem to OSD - target key to freeze - true to freeze, false to unfreeze + OSD representation of InventoryItem - + - Abandon a parcel of land + Tools for dealing with agents inventory - Simulator parcel is in - Simulator local ID of parcel - + + Used for converting shadow_id to asset_id + + - Requests the UUID of the parcel in a remote region at a specified location + Callback for inventory item creation finishing - Location of the parcel in the remote region - Remote region handle - Remote region UUID - If successful UUID of the remote parcel, UUID.Zero otherwise + Whether the request to create an inventory + item succeeded or not + Inventory item being created. If success is + false this will be null - + - Retrieves information on resources used by the parcel + Callback for an inventory item being create from an uploaded asset - UUID of the parcel - Should per object resource usage be requested - Callback invoked when the request is complete - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event + true if inventory item creation was successful + + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event + + + + + - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event + + The event subscribers, null of no subscribers - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event + + Raises the ItemReceived Event + A ItemReceivedEventArgs object containing + the data sent from the simulator - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event + + Thread sync lock object - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Raised when the simulator sends us data containing + ... - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event + + The event subscribers, null of no subscribers - - Raised when the simulator responds to a request + + Raises the FolderUpdated Event + A FolderUpdatedEventArgs object containing + the data sent from the simulator - - Raised when the simulator responds to a request + + Thread sync lock object - - Raised when the simulator responds to a request + + Raised when the simulator sends us data containing + ... - - Raised when the simulator responds to a request + + The event subscribers, null of no subscribers - - Raised when the simulator responds to a request + + Raises the InventoryObjectOffered Event + A InventoryObjectOfferedEventArgs object containing + the data sent from the simulator - - Raised when the simulator responds to a request + + Thread sync lock object - - Raised when the simulator responds to a request + + Raised when the simulator sends us data containing + an inventory object sent by another avatar or primitive - - Raised when the simulator responds to a Parcel Update request + + The event subscribers, null of no subscribers - - Raised when the parcel your agent is located sends a ParcelMediaCommand + + Raises the TaskItemReceived Event + A TaskItemReceivedEventArgs object containing + the data sent from the simulator - - - Parcel Accesslist - + + Thread sync lock object - - Agents + + Raised when the simulator sends us data containing + ... - - + + The event subscribers, null of no subscribers - - Flags for specific entry in white/black lists + + Raises the FindObjectByPath Event + A FindObjectByPathEventArgs object containing + the data sent from the simulator - - - Owners of primitives on parcel - + + Thread sync lock object - - Prim Owners + + Raised when the simulator sends us data containing + ... - - True of owner is group + + The event subscribers, null of no subscribers - - Total count of prims owned by OwnerID + + Raises the TaskInventoryReply Event + A TaskInventoryReplyEventArgs object containing + the data sent from the simulator - - true of OwnerID is currently online and is not a group + + Thread sync lock object - - The date of the most recent prim left by OwnerID + + Raised when the simulator sends us data containing + ... - + - Called once parcel resource usage information has been collected + Reply received when uploading an inventory asset - Indicates if operation was successfull - Parcel resource usage information + Has upload been successful + Error message if upload failed + Inventory asset UUID + New asset UUID - - Contains a parcels dwell data returned from the simulator in response to an + + The event subscribers, null of no subscribers - + + Raises the SaveAssetToInventory Event + A SaveAssetToInventoryEventArgs object containing + the data sent from the simulator + + + Thread sync lock object + + + Raised when the simulator sends us data containing + ... + + - Construct a new instance of the ParcelDwellReplyEventArgs class + Delegate that is invoked when script upload is completed - The global ID of the parcel - The simulator specific ID of the parcel - The calculated dwell for the parcel + Has upload succeded (note, there still might be compile errors) + Upload status message + Is compilation successful + If compilation failed, list of error messages, null on compilation success + Script inventory UUID + Script's new asset UUID - - Get the global ID of the parcel + + The event subscribers, null of no subscribers - - Get the simulator specific ID of the parcel + + Raises the ScriptRunningReply Event + A ScriptRunningReplyEventArgs object containing + the data sent from the simulator - - Get the calculated dwell + + Thread sync lock object - - Contains basic parcel information data returned from the - simulator in response to an request + + Raised when the simulator sends us data containing + ... - + + Partial mapping of FolderTypes to folder names + + - Construct a new instance of the ParcelInfoReplyEventArgs class + Get this agents Inventory data - The object containing basic parcel info - - - Get the object containing basic parcel info - - - Contains basic parcel information data returned from the simulator in response to an request - + - Construct a new instance of the ParcelPropertiesEventArgs class + Default constructor - The object containing the details - The object containing the details - The result of the request - The number of primitieves your agent is - currently selecting and or sitting on in this parcel - The user assigned ID used to correlate a request with - these results - TODO: - - - Get the simulator the parcel is located in + Reference to the GridClient object - - Get the object containing the details - If Result is NoData, this object will not contain valid data + + + Fetch an inventory item from the dataserver + + The items + The item Owners + a integer representing the number of milliseconds to wait for results + An object on success, or null if no item was found + Items will also be sent to the event - - Get the result of the request + + + Request A single inventory item + + The items + The item Owners + - - Get the number of primitieves your agent is - currently selecting and or sitting on in this parcel + + + Request inventory items + + Inventory items to request + Owners of the inventory items + - - Get the user assigned ID used to correlate a request with - these results + + + Request inventory items via Capabilities + + Inventory items to request + Owners of the inventory items + - - TODO: + + + Get contents of a folder + + The of the folder to search + The of the folders owner + true to retrieve folders + true to retrieve items + sort order to return results in + a integer representing the number of milliseconds to wait for results + A list of inventory items matching search criteria within folder + + InventoryFolder.DescendentCount will only be accurate if both folders and items are + requested - - Contains blacklist and whitelist data returned from the simulator in response to an request + + + Request the contents of an inventory folder + + The folder to search + The folder owners + true to return s contained in folder + true to return s containd in folder + the sort order to return items in + - + - Construct a new instance of the ParcelAccessListReplyEventArgs class + Request the contents of an inventory folder using HTTP capabilities - The simulator the parcel is located in - The user assigned ID used to correlate a request with - these results - The simulator specific ID of the parcel - TODO: - The list containing the white/blacklisted agents for the parcel - - - Get the simulator the parcel is located in + The folder to search + The folder owners + true to return s contained in folder + true to return s containd in folder + the sort order to return items in + - - Get the user assigned ID used to correlate a request with - these results + + + Returns the UUID of the folder (category) that defaults to + containing 'type'. The folder is not necessarily only for that + type + + This will return the root folder if one does not exist + + The UUID of the desired folder if found, the UUID of the RootFolder + if not found, or UUID.Zero on failure - - Get the simulator specific ID of the parcel + + + Find an object in inventory using a specific path to search + + The folder to begin the search in + The object owners + A string path to search + milliseconds to wait for a reply + Found items or if + timeout occurs or item is not found - - TODO: + + + Find inventory items by path + + The folder to begin the search in + The object owners + A string path to search, folders/objects separated by a '/' + Results are sent to the event - - Get the list containing the white/blacklisted agents for the parcel + + + Search inventory Store object for an item or folder + + The folder to begin the search in + An array which creates a path to search + Number of levels below baseFolder to conduct searches + if True, will stop searching after first match is found + A list of inventory items found - - Contains blacklist and whitelist data returned from the - simulator in response to an request + + + Move an inventory item or folder to a new location + + The item or folder to move + The to move item or folder to - + - Construct a new instance of the ParcelObjectOwnersReplyEventArgs class + Move an inventory item or folder to a new location and change its name - The simulator the parcel is located in - The list containing prim ownership counts + The item or folder to move + The to move item or folder to + The name to change the item or folder to - - Get the simulator the parcel is located in + + + Move and rename a folder + + The source folders + The destination folders + The name to change the folder to - - Get the list containing prim ownership counts + + + Update folder properties + + of the folder to update + Sets folder's parent to + Folder name + Folder type - - Contains the data returned when all parcel data has been retrieved from a simulator + + + Move a folder + + The source folders + The destination folders - + - Construct a new instance of the SimParcelsDownloadedEventArgs class + Move multiple folders, the keys in the Dictionary parameter, + to a new parents, the value of that folder's key. - The simulator the parcel data was retrieved from - The dictionary containing the parcel data - The multidimensional array containing a x,y grid mapped - to each 64x64 parcel's LocalID. + A Dictionary containing the + of the source as the key, and the + of the destination as the value - - Get the simulator the parcel data was retrieved from + + + Move an inventory item to a new folder + + The of the source item to move + The of the destination folder - - A dictionary containing the parcel data where the key correlates to the ParcelMap entry + + + Move and rename an inventory item + + The of the source item to move + The of the destination folder + The name to change the folder to - - Get the multidimensional array containing a x,y grid mapped - to each 64x64 parcel's LocalID. + + + Move multiple inventory items to new locations + + A Dictionary containing the + of the source item as the key, and the + of the destination folder as the value - - Contains the data returned when a request + + + Remove descendants of a folder + + The of the folder - + - Construct a new instance of the ForceSelectObjectsReplyEventArgs class + Remove a single item from inventory - The simulator the parcel data was retrieved from - The list of primitive IDs - true if the list is clean and contains the information - only for a given request + The of the inventory item to remove - - Get the simulator the parcel data was retrieved from + + + Remove a folder from inventory + + The of the folder to remove - - Get the list of primitive IDs + + + Remove multiple items or folders from inventory + + A List containing the s of items to remove + A List containing the s of the folders to remove - - true if the list is clean and contains the information - only for a given request + + + Empty the Lost and Found folder + - - Contains data when the media data for a parcel the avatar is on changes + + + Empty the Trash folder + - + - Construct a new instance of the ParcelMediaUpdateReplyEventArgs class + - the simulator the parcel media data was updated in - The updated media information + + + + + Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here. + + + - - Get the simulator the parcel media data was updated in + + + + + + + + + Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here. + + + + - - Get the updated media information + + + Creates a new inventory folder + + ID of the folder to put this folder in + Name of the folder to create + The UUID of the newly created folder - - Contains the media command for a parcel the agent is currently on + + + Creates a new inventory folder + + ID of the folder to put this folder in + Name of the folder to create + Sets this folder as the default folder + for new assets of the specified type. Use FolderType.None + to create a normal folder, otherwise it will likely create a + duplicate of an existing folder type + The UUID of the newly created folder + If you specify a preferred type of AsseType.Folder + it will create a new root folder which may likely cause all sorts + of strange problems - + - Construct a new instance of the ParcelMediaCommandEventArgs class + Create an inventory item and upload asset data - The simulator the parcel media command was issued in - - - The media command that was sent - + Asset data + Inventory item name + Inventory item description + Asset type + Inventory type + Put newly created inventory in this folder + Delegate that will receive feedback on success or failure - - Get the simulator the parcel media command was issued in + + + Create an inventory item and upload asset data + + Asset data + Inventory item name + Inventory item description + Asset type + Inventory type + Put newly created inventory in this folder + Permission of the newly created item + (EveryoneMask, GroupMask, and NextOwnerMask of Permissions struct are supported) + Delegate that will receive feedback on success or failure - - + + + Creates inventory link to another inventory item or folder + + Put newly created link in folder with this UUID + Inventory item or folder + Method to call upon creation of the link - - + + + Creates inventory link to another inventory item + + Put newly created link in folder with this UUID + Original inventory item + Method to call upon creation of the link - - Get the media command that was sent + + + Creates inventory link to another inventory folder + + Put newly created link in folder with this UUID + Original inventory folder + Method to call upon creation of the link - - + + + Creates inventory link to another inventory item or folder + + Put newly created link in folder with this UUID + Original item's UUID + Name + Description + Asset Type + Inventory Type + Transaction UUID + Method to call upon creation of the link - + + + + + - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + - - + + + Request a copy of an asset embedded within a notecard + + Usually UUID.Zero for copying an asset from a notecard + UUID of the notecard to request an asset from + Target folder for asset to go to in your inventory + UUID of the embedded asset + callback to run when item is copied to inventory - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + + + + + + - - + + + Save changes to notecard embedded in object contents + + Encoded notecard asset data + Notecard UUID + Object's UUID + Called upon finish of the upload with status information - - + + + Upload new gesture asset for an inventory gesture item + + Encoded gesture asset + Gesture inventory UUID + Callback whick will be called when upload is complete - - + + + Update an existing script in an agents Inventory + + A byte[] array containing the encoded scripts contents + the itemID of the script + if true, sets the script content to run on the mono interpreter + - - + + + Update an existing script in an task Inventory + + A byte[] array containing the encoded scripts contents + the itemID of the script + UUID of the prim containting the script + if true, sets the script content to run on the mono interpreter + if true, sets the script to running + - - + + + Rez an object from inventory + + Simulator to place object in + Rotation of the object when rezzed + Vector of where to place object + InventoryItem object containing item details - - + + + Rez an object from inventory + + Simulator to place object in + Rotation of the object when rezzed + Vector of where to place object + InventoryItem object containing item details + UUID of group to own the object - - + + + Rez an object from inventory + + Simulator to place object in + Rotation of the object when rezzed + Vector of where to place object + InventoryItem object containing item details + UUID of group to own the object + User defined queryID to correlate replies + If set to true, the CreateSelected flag + will be set on the rezzed object - - + + + Rez an object from inventory + + Simulator to place object in + TaskID object when rezzed + Rotation of the object when rezzed + Vector of where to place object + InventoryItem object containing item details + UUID of group to own the object + User defined queryID to correlate replies + If set to true, the CreateSelected flag + will be set on the rezzed object - - + + + DeRez an object from the simulator to the agents Objects folder in the agents Inventory + + The simulator Local ID of the object + If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed - + - + DeRez an object from the simulator and return to inventory + The simulator Local ID of the object + The type of destination from the enum + The destination inventory folders -or- + if DeRezzing object to a tasks Inventory, the Tasks + The transaction ID for this request which + can be used to correlate this request with other packets + If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed - - - - - - - - - - - - - + - + Rez an item from inventory to its previous simulator location - + + + - + - + Give an inventory item to another avatar + The of the item to give + The name of the item + The type of the item from the enum + The of the recipient + true to generate a beameffect during transfer - - - - - - - - - - - + + + Give an inventory Folder with contents to another avatar + + The of the Folder to give + The name of the folder + The type of the item from the enum + The of the recipient + true to generate a beameffect during transfer - + - + Copy or move an from agent inventory to a task (primitive) inventory - + The target object + The item to copy or move from inventory + For items with copy permissions a copy of the item is placed in the tasks inventory, + for no-copy items the object is moved to the tasks inventory - + - + Retrieve a listing of the items contained in a task (Primitive) + The tasks + The tasks simulator local ID + milliseconds to wait for reply from simulator + A list containing the inventory items inside the task or null + if a timeout occurs + This request blocks until the response from the simulator arrives + or timeoutMS is exceeded - - - - - - - - - - - - - - - - - - - + - + Request the contents of a tasks (primitives) inventory from the + current simulator + The LocalID of the object + - - - - - - - - - - - - - - - - + - + Request the contents of a tasks (primitives) inventory - - + The simulator Local ID of the object + A reference to the simulator object that contains the object + - + - + Move an item from a tasks (Primitive) inventory to the specified folder in the avatars inventory - - + LocalID of the object in the simulator + UUID of the task item to move + The ID of the destination folder in this agents inventory + Simulator Object + Raises the event - + - + Remove an item from an objects (Prim) Inventory - - + LocalID of the object in the simulator + UUID of the task item to remove + Simulator Object + You can confirm the removal by comparing the tasks inventory serial before and after the + request with the request combined with + the event - - + + + Copy an InventoryScript item from the Agents Inventory into a primitives task inventory + + An unsigned integer representing a primitive being simulated + An which represents a script object from the agents inventory + true to set the scripts running state to enabled + A Unique Transaction ID + + The following example shows the basic steps necessary to copy a script from the agents inventory into a tasks inventory + and assumes the script exists in the agents inventory. + + uint primID = 95899503; // Fake prim ID + UUID scriptID = UUID.Parse("92a7fe8a-e949-dd39-a8d8-1681d8673232"); // Fake Script UUID in Inventory - - - - + Client.Inventory.FolderContents(Client.Inventory.FindFolderForType(AssetType.LSLText), Client.Self.AgentID, + false, true, InventorySortOrder.ByName, 10000); + + Client.Inventory.RezScript(primID, (InventoryItem)Client.Inventory.Store[scriptID]); + + - + - + Request the running status of a script contained in a task (primitive) inventory + The ID of the primitive containing the script + The ID of the script + The event can be used to obtain the results of the + request + - + - + Send a request to set the running state of a script contained in a task (primitive) inventory - - + The ID of the primitive containing the script + The ID of the script + true to set the script running, false to stop a running script + To verify the change you can use the method combined + with the event - + - + Create a CRC from an InventoryItem - - + The source InventoryItem + A uint representing the source InventoryItem as a CRC - + - + Reverses a cheesy XORing with a fixed UUID to convert a shadow_id to an asset_id - + Obfuscated shadow_id value + Deobfuscated asset_id value - + - Class for controlling various system settings. + Does a cheesy XORing with a fixed UUID to convert an asset_id to a shadow_id - Some values are readonly because they affect things that - happen when the GridClient object is initialized, so changing them at - runtime won't do any good. Non-readonly values may affect things that - happen at login or dynamically - - - Main grid login server - - - Beta grid login server + asset_id value to obfuscate + Obfuscated shadow_id value - + - InventoryManager requests inventory information on login, - GridClient initializes an Inventory store for main inventory. + Wrapper for creating a new object + The type of item from the enum + The of the newly created object + An object with the type and id passed - + - InventoryManager requests library information on login, - GridClient initializes an Inventory store for the library. + Parse the results of a RequestTaskInventory() response + A string which contains the data from the task reply + A List containing the items contained within the tasks inventory - - Number of milliseconds between sending pings to each sim - - - Number of milliseconds between sending camera updates - - - Number of milliseconds between updating the current - positions of moving, non-accelerating and non-colliding objects - - - Millisecond interval between ticks, where all ACKs are - sent out and the age of unACKed packets is checked - - - The initial size of the packet inbox, where packets are - stored before processing - - - Maximum size of packet that we want to send over the wire - - - The maximum value of a packet sequence number before it - rolls over back to one - - - The relative directory where external resources are kept - - - Login server to connect to - - - IP Address the client will bind to + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Use XML-RPC Login or LLSD Login, default is XML-RPC Login + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - + - Maximum number of HTTP connections to open to a particular endpoint. + UpdateCreateInventoryItem packets are received when a new inventory item + is created. This may occur when an object that's rezzed in world is + taken into inventory, when an item is created using the CreateInventoryItem + packet, or when an object is purchased - - An endpoint is defined as a commbination of network address and port. This is used for Caps. - This is a static variable which applies to all instances. - + The sender + The EventArgs object containing the packet data - - - Use Caps for fetching inventory where available - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Number of milliseconds before an asset transfer will time - out + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Number of milliseconds before a teleport attempt will time - out + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Number of milliseconds before NetworkManager.Logout() will - time out + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Number of milliseconds before a CAPS call will time out - Setting this too low will cause web requests time out and - possibly retry repeatedly + + Set to true to accept offer, false to decline it - - Number of milliseconds for xml-rpc to timeout + + The folder to accept the inventory into, if null default folder for will be used - - Milliseconds before a packet is assumed lost and resent + + + Callback when an inventory object is accepted and received from a + task inventory. This is the callback in which you actually get + the ItemID, as in ObjectOfferedCallback it is null when received + from a task. + - - Milliseconds without receiving a packet before the - connection to a simulator is assumed lost + + - - Milliseconds to wait for a simulator info request through - the grid interface + + User data - - The maximum size of the sequence number archive, used to - check for resent and/or duplicate packets + + - - Maximum number of queued ACKs to be sent before SendAcks() - is forced + + - - Network stats queue length (seconds) + + - + - Primitives will be reused when falling in/out of interest list (and shared between clients) - prims returning to interest list do not need re-requested - Helps also in not re-requesting prim.Properties for code that checks for a Properties == null per client + For inventory folder nodes specifies weather the folder needs to be + refreshed from the server - + - Pool parcel data between clients (saves on requesting multiple times when all clients may need it) + - + - How long to preserve cached data when no client is connected to a simulator - The reason for setting it to something like 2 minutes is in case a client - is running back and forth between region edges or a sim is comming and going + + - - Enable/disable storing terrain heightmaps in the - TerrainManager - - - Enable/disable sending periodic camera updates - - - Enable/disable automatically setting agent appearance at - login and after sim crossing - - - Enable/disable automatically setting the bandwidth throttle - after connecting to each simulator - The default throttle uses the equivalent of the maximum - bandwidth setting in the official client. If you do not set a - throttle your connection will by default be throttled well below - the minimum values and you may experience connection problems - - - Enable/disable the sending of pings to monitor lag and - packet loss + + + De-serialization constructor for the InventoryNode Class + - - Should we connect to multiple sims? This will allow - viewing in to neighboring simulators and sim crossings - (Experimental) + + + Serialization handler for the InventoryNode Class + - - If true, all object update packets will be decoded in to - native objects. If false, only updates for our own agent will be - decoded. Registering an event handler will force objects for that - type to always be decoded. If this is disabled the object tracking - will have missing or partial prim and avatar information + + + De-serialization handler for the InventoryNode Class + - - If true, when a cached object check is received from the - server the full object info will automatically be requested + + + + + - - Whether to establish connections to HTTP capabilities - servers for simulators + + + Singleton logging class for the entire library + - - Whether to decode sim stats + + + Callback used for client apps to receive log messages from + the library + + Data being logged + The severity of the log entry from - - The capabilities servers are currently designed to - periodically return a 502 error which signals for the client to - re-establish a connection. Set this to true to log those 502 errors + + Triggered whenever a message is logged. If this is left + null, log messages will go to the console - - If true, any reference received for a folder or item - the library is not aware of will automatically be fetched + + log4net logging engine - - If true, and SEND_AGENT_UPDATES is true, - AgentUpdate packets will continuously be sent out to give the bot - smoother movement and autopiloting + + + Default constructor + - - If true, currently visible avatars will be stored - in dictionaries inside Simulator.ObjectAvatars. - If false, a new Avatar or Primitive object will be created - each time an object update packet is received + + + Send a log message to the logging engine + + The log message + The severity of the log entry - - If true, currently visible avatars will be stored - in dictionaries inside Simulator.ObjectPrimitives. - If false, a new Avatar or Primitive object will be created - each time an object update packet is received + + + Send a log message to the logging engine + + The log message + The severity of the log entry + Instance of the client - - If true, position and velocity will periodically be - interpolated (extrapolated, technically) for objects and - avatars that are being tracked by the library. This is - necessary to increase the accuracy of speed and position - estimates for simulated objects + + + Send a log message to the logging engine + + The log message + The severity of the log entry + Exception that was raised - + - If true, utilization statistics will be tracked. There is a minor penalty - in CPU time for enabling this option. + Send a log message to the logging engine + The log message + The severity of the log entry + Instance of the client + Exception that was raised - - If true, parcel details will be stored in the - Simulator.Parcels dictionary as they are received - - + - If true, an incoming parcel properties reply will automatically send - a request for the parcel access list + If the library is compiled with DEBUG defined, an event will be + fired if an OnLogMessage handler is registered and the + message will be sent to the logging engine + The message to log at the DEBUG level to the + current logging engine - + - if true, an incoming parcel properties reply will automatically send - a request for the traffic count. + If the library is compiled with DEBUG defined and + GridClient.Settings.DEBUG is true, an event will be + fired if an OnLogMessage handler is registered and the + message will be sent to the logging engine + The message to log at the DEBUG level to the + current logging engine + Instance of the client - + - If true, images, and other assets downloaded from the server - will be cached in a local directory + - - Path to store cached texture data + + - - Maximum size cached files are allowed to take on disk (bytes) + + - - Default color used for viewer particle effects + + - - Maximum number of times to resend a failed packet + + - - Throttle outgoing packet rate + + - - UUID of a texture used by some viewers to indentify type of client used + + - + + + + - Download textures using GetTexture capability when available + Status of the last application run. + Used for error reporting to the grid login service for statistical purposes. - - The maximum number of concurrent texture downloads allowed - Increasing this number will not necessarily increase texture retrieval times due to - simulator throttles + + Application exited normally - - - The Refresh timer inteval is used to set the delay between checks for stalled texture downloads - - This is a static variable which applies to all instances + + Application froze - - - Textures taking longer than this value will be flagged as timed out and removed from the pipeline - + + Application detected error and exited abnormally - + + Other crash + + + Application froze during logout + + + Application crashed during logout + + - Get or set the minimum log level to output to the console by default - - If the library is not compiled with DEBUG defined and this level is set to DEBUG - You will get no output on the console. This behavior can be overriden by creating - a logger configuration file for log4net + Login Request Parameters - - Attach avatar names to log messages + + The URL of the Login Server - - Log packet retransmission info + + The number of milliseconds to wait before a login is considered + failed due to timeout - - Log disk cache misses and other info + + The request method + login_to_simulator is currently the only supported method - - Constructor - Reference to a GridClient object + + The Agents First name - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + The Agents Last name - - Cost of uploading an asset - Read-only since this value is dynamically fetched at login + + A md5 hashed password + plaintext password will be automatically hashed - - - Simulator (region) properties - + + The agents starting location once logged in + Either "last", "home", or a string encoded URI + containing the simulator name and x/y/z coordinates e.g: uri:hooper&128&152&17 - - No flags set + + A string containing the client software channel information + Second Life Release - - Agents can take damage and be killed + + The client software version information + The official viewer uses: Second Life Release n.n.n.n + where n is replaced with the current version of the viewer - - Landmarks can be created here + + A string containing the platform information the agent is running on - - Home position can be set in this sim + + A string containing version number for OS the agent is running on - - Home position is reset when an agent teleports away + + A string hash of the network cards Mac Address - - Sun does not move + + Unknown or deprecated - - No object, land, etc. taxes + + A string hash of the first disk drives ID used to identify this clients uniqueness - - Disable heightmap alterations (agents can still plant - foliage) + + A string containing the viewers Software, this is not directly sent to the login server but + instead is used to generate the Version string - - Land cannot be released, sold, or purchased + + A string representing the software creator. This is not directly sent to the login server but + is used by the library to generate the Version information - - All content is wiped nightly + + If true, this agent agrees to the Terms of Service of the grid its connecting to - - Unknown: Related to the availability of an overview world map tile.(Think mainland images when zoomed out.) + + Unknown - - Unknown: Related to region debug flags. Possibly to skip processing of agent interaction with world. + + Status of the last application run sent to the grid login server for statistical purposes - - Region does not update agent prim interest lists. Internal debugging option. + + An array of string sent to the login server to enable various options - - No collision detection for non-agent objects + + A randomly generated ID to distinguish between login attempts. This value is only used + internally in the library and is never sent over the wire - - No scripts are ran + + + Default constuctor, initializes sane default values + - - All physics processing is turned off + + + Instantiates new LoginParams object and fills in the values + + Instance of GridClient to read settings from + Login first name + Login last name + Password + Login channnel (application name) + Client version, should be application name + version number - - Region can be seen from other regions on world map. (Legacy world map option?) + + + Instantiates new LoginParams object and fills in the values + + Instance of GridClient to read settings from + Login first name + Login last name + Password + Login channnel (application name) + Client version, should be application name + version number + URI of the login server - - Region can be seen from mainland on world map. (Legacy world map option?) + + + The decoded data returned from the login server after a successful login + - - Agents not explicitly on the access list can visit the region. + + true, false, indeterminate - - Traffic calculations are not run across entire region, overrides parcel settings. + + Login message of the day - - Flight is disabled (not currently enforced by the sim) + + M or PG, also agent_region_access and agent_access_max - - Allow direct (p2p) teleporting + + + Parse LLSD Login Reply Data + + An + contaning the login response data + XML-RPC logins do not require this as XML-RPC.NET + automatically populates the struct properly using attributes - - Estate owner has temporarily disabled scripting + + + Login Routines + + + NetworkManager is responsible for managing the network layer of + OpenMetaverse. It tracks all the server connections, serializes + outgoing traffic and deserializes incoming traffic, and provides + instances of delegates for network-related events. + - - Restricts the usage of the LSL llPushObject function, applies to whole region. + + The event subscribers, null of no subscribers - - Deny agents with no payment info on file + + Raises the LoginProgress Event + A LoginProgressEventArgs object containing + the data sent from the simulator - - Deny agents with payment info on file + + Thread sync lock object - - Deny agents who have made a monetary transaction + + Raised when the simulator sends us data containing + ... - - Parcels within the region may be joined or divided by anyone, not just estate owners/managers. + + + + + + + + + - - Abuse reports sent from within this region are sent to the estate owner defined email. + + Called when a reply is received from the login server, the + login sequence will block until this event returns - - Region is Voice Enabled + + Seed CAPS URL returned from the login server - - Removes the ability from parcel owners to set their parcels to show in search. + + Current state of logging in - - Deny agents who have not been age verified from entering the region. + + Upon login failure, contains a short string key for the + type of login error that occurred - - - Region protocol flags - + + The raw XML-RPC reply from the login server, exactly as it + was received (minus the HTTP header) - - Nothing special + + During login this contains a descriptive version of + LoginStatusCode. After a successful login this will contain the + message of the day, and after a failed login a descriptive error + message will be returned - - Region supports Server side Appearance + + Maximum number of groups an agent can belong to, -1 for unlimited - - Viewer supports Server side Appearance + + Server side baking service URL - - - Access level for a simulator - + + Parsed login response data - - Unknown or invalid access level + + A list of packets obtained during the login process which + networkmanager will log but not process - - Trial accounts allowed + + + Generate sane default values for a login request + + Account first name + Account last name + Account password + Client application name (channel) + Client application name + version + A populated struct containing + sane defaults - - PG rating + + + Simplified login that takes the most common and required fields + + Account first name + Account last name + Account password + Client application name (channel) + Client application name + version + Whether the login was successful or not. On failure the + LoginErrorKey string will contain the error code and LoginMessage + will contain a description of the error - - Mature rating + + + Simplified login that takes the most common fields along with a + starting location URI, and can accept an MD5 string instead of a + plaintext password + + Account first name + Account last name + Account password or MD5 hash of the password + such as $1$1682a1e45e9f957dcdf0bb56eb43319c + Client application name (channel) + Starting location URI that can be built with + StartLocation() + Client application name + version + Whether the login was successful or not. On failure the + LoginErrorKey string will contain the error code and LoginMessage + will contain a description of the error - - Adult rating + + + Login that takes a struct of all the values that will be passed to + the login server + + The values that will be passed to the login + server, all fields must be set even if they are String.Empty + Whether the login was successful or not. On failure the + LoginErrorKey string will contain the error code and LoginMessage + will contain a description of the error - - Simulator is offline + + + Build a start location URI for passing to the Login function + + Name of the simulator to start in + X coordinate to start at + Y coordinate to start at + Z coordinate to start at + String with a URI that can be used to login to a specified + location - - Simulator does not exist + + + LoginParams and the initial login XmlRpcRequest were made on a remote machine. + This method now initializes libomv with the results. + - + - + Handles response from XML-RPC login replies - + - + Handles response from XML-RPC login replies with already parsed LoginResponseData - + - Initialize the UDP packet handler in server mode + Handle response from LLSD login replies - Port to listening for incoming UDP packets on + + + - + - Initialize the UDP packet handler in client mode + Get current OS - Remote UDP server to connect to + Either "Win" or "Linux" - + - + Gets the current OS version number + The platform version. - + - + Get clients default Mac Address + A string containing the first found Mac Address - + - + Explains why a simulator or the grid disconnected from us - - A public reference to the client that this Simulator object - is attached to + + The client requested the logout or simulator disconnect - - A Unique Cache identifier for this simulator + + The server notified us that it is disconnecting - - The capabilities for this simulator + + Either a socket was closed or network traffic timed out - - + + The last active simulator shut down - - The current version of software this simulator is running + + + Holds a simulator reference and a decoded packet, these structs are put in + the packet inbox for event handling + - - + + Reference to the simulator that this packet came from + + + Packet that needs to be processed + + + + Holds a simulator reference and a serialized packet, these structs are put in + the packet outbox for sending + + + + Reference to the simulator this packet is destined for + + + Packet that needs to be sent - - A 64x64 grid of parcel coloring values. The values stored - in this array are of the type + + Sequence number of the wrapped packet - - + + Number of times this packet has been resent - - + + Environment.TickCount when this packet was last sent over the wire - - + + Type of the packet - - + + The event subscribers, null of no subscribers - - + + Raises the PacketSent Event + A PacketSentEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - + + The event subscribers, null of no subscribers - - + + Raises the LoggedOut Event + A LoggedOutEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - + + The event subscribers, null of no subscribers - - + + Raises the SimConnecting Event + A SimConnectingEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - + + The event subscribers, null of no subscribers - - + + Raises the SimConnected Event + A SimConnectedEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - true if your agent has Estate Manager rights on this region + + The event subscribers, null of no subscribers - - + + Raises the SimDisconnected Event + A SimDisconnectedEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - Statistics information for this simulator and the - connection to the simulator, calculated by the simulator itself - and the library + + The event subscribers, null of no subscribers - - The regions Unique ID + + Raises the Disconnected Event + A DisconnectedEventArgs object containing + the data sent from the simulator - - The physical data center the simulator is located - Known values are: - - Dallas - Chandler - SF - - + + Thread sync lock object - - The CPU Class of the simulator - Most full mainland/estate sims appear to be 5, - Homesteads and Openspace appear to be 501 + + Raised when the simulator sends us data containing + ... - - The number of regions sharing the same CPU as this one - "Full Sims" appear to be 1, Homesteads appear to be 4 + + The event subscribers, null of no subscribers - - The billing product name - Known values are: - - Mainland / Full Region (Sku: 023) - Estate / Full Region (Sku: 024) - Estate / Openspace (Sku: 027) - Estate / Homestead (Sku: 029) - Mainland / Homestead (Sku: 129) (Linden Owned) - Mainland / Linden Homes (Sku: 131) - - + + Raises the SimChanged Event + A SimChangedEventArgs object containing + the data sent from the simulator - - The billing product SKU - Known values are: - - 023 Mainland / Full Region - 024 Estate / Full Region - 027 Estate / Openspace - 029 Estate / Homestead - 129 Mainland / Homestead (Linden Owned) - 131 Linden Homes / Full Region - - + + Thread sync lock object - - - Flags indicating which protocols this region supports - + + Raised when the simulator sends us data containing + ... - - The current sequence number for packets sent to this - simulator. Must be Interlocked before modifying. Only - useful for applications manipulating sequence numbers + + The event subscribers, null of no subscribers - - - A thread-safe dictionary containing avatars in a simulator - + + Raises the EventQueueRunning Event + A EventQueueRunningEventArgs object containing + the data sent from the simulator - - - A thread-safe dictionary containing primitives in a simulator - + + Thread sync lock object - - - Checks simulator parcel map to make sure it has downloaded all data successfully - - true if map is full (contains no 0's) + + Raised when the simulator sends us data containing + ... - - - Is it safe to send agent updates to this sim - AgentMovementComplete message received - + + Unique identifier associated with our connections to + simulators - - Used internally to track sim disconnections + + The simulator that the logged in avatar is currently + occupying - - Event that is triggered when the simulator successfully - establishes a connection + + Shows whether the network layer is logged in to the + grid or not - - Whether this sim is currently connected or not. Hooked up - to the property Connected + + Number of packets in the incoming queue - - Coarse locations of avatars in this simulator + + Number of packets in the outgoing queue - - AvatarPositions key representing TrackAgent target + + All of the simulators we are currently connected to - - Sequence numbers of packets we've received - (for duplicate checking) + + Handlers for incoming capability events - - Packets we sent out that need ACKs from the simulator + + Handlers for incoming packets - - Sequence number for pause/resume + + Incoming packets that are awaiting handling - - Indicates if UDP connection to the sim is fully established + + Outgoing packets that are awaiting handling - + - + Default constructor Reference to the GridClient object - IPEndPoint of the simulator - handle of the simulator - + - Called when this Simulator object is being destroyed + Register an event handler for a packet. This is a low level event + interface and should only be used if you are doing something not + supported in the library + Packet type to trigger events for + Callback to fire when a packet of this type + is received - + - Attempt to connect to this simulator + Register an event handler for a packet. This is a low level event + interface and should only be used if you are doing something not + supported in the library - Whether to move our agent in to this sim or not - True if the connection succeeded or connection status is - unknown, false if there was a failure + Packet type to trigger events for + Callback to fire when a packet of this type + is received + True if the callback should be ran + asynchronously. Only set this to false (synchronous for callbacks + that will always complete quickly) + If any callback for a packet type is marked as + asynchronous, all callbacks for that packet type will be fired + asynchronously - + - Initiates connection to the simulator + Unregister an event handler for a packet. This is a low level event + interface and should only be used if you are doing something not + supported in the library - Should we block until ack for this packet is recieved + Packet type this callback is registered with + Callback to stop firing events for - + - Disconnect from this simulator + Register a CAPS event handler. This is a low level event interface + and should only be used if you are doing something not supported in + the library + Name of the CAPS event to register a handler for + Callback to fire when a CAPS event is received - + - Instructs the simulator to stop sending update (and possibly other) packets + Unregister a CAPS event handler. This is a low level event interface + and should only be used if you are doing something not supported in + the library + Name of the CAPS event this callback is + registered with + Callback to stop firing events for - + - Instructs the simulator to resume sending update packets (unpause) + Send a packet to the simulator the avatar is currently occupying + Packet to send - + - Retrieve the terrain height at a given coordinate + Send a packet to a specified simulator - Sim X coordinate, valid range is from 0 to 255 - Sim Y coordinate, valid range is from 0 to 255 - The terrain height at the given point if the - lookup was successful, otherwise 0.0f - True if the lookup was successful, otherwise false + Packet to send + Simulator to send the packet to - + - Sends a packet + Connect to a simulator - Packet to be sent + IP address to connect to + Port to connect to + Handle for this simulator, to identify its + location in the grid + Whether to set CurrentSim to this new + connection, use this if the avatar is moving in to this simulator + URL of the capabilities server to use for + this sim connection + A Simulator object on success, otherwise null - + - + Connect to a simulator + IP address and port to connect to + Handle for this simulator, to identify its + location in the grid + Whether to set CurrentSim to this new + connection, use this if the avatar is moving in to this simulator + URL of the capabilities server to use for + this sim connection + A Simulator object on success, otherwise null - + - Returns Simulator Name as a String + Begins the non-blocking logout. Makes sure that the LoggedOut event is + called even if the server does not send a logout reply, and Shutdown() + is properly called. - - + - + Initiate a blocking logout request. This will return when the logout + handshake has completed or when Settings.LOGOUT_TIMEOUT + has expired and the network layer is manually shut down - - + - + Initiate the logout process. The Shutdown() function + needs to be manually called. - - - + - Sends out pending acknowledgements + Close a connection to the given simulator - Number of ACKs sent + + - + - Resend unacknowledged packets + Shutdown will disconnect all the sims except for the current sim + first, and then kill the connection to CurrentSim. This should only + be called if the logout process times out on RequestLogout + Type of shutdown - + - Provides access to an internal thread-safe dictionary containing parcel - information found in this simulator + Shutdown will disconnect all the sims except for the current sim + first, and then kill the connection to CurrentSim. This should only + be called if the logout process times out on RequestLogout + Type of shutdown + Shutdown message - + - Provides access to an internal thread-safe multidimensional array containing a x,y grid mapped - to each 64x64 parcel's LocalID. + Searches through the list of currently connected simulators to find + one attached to the given IPEndPoint + IPEndPoint of the Simulator to search for + A Simulator reference on success, otherwise null - - The IP address and port of the server - - - Whether there is a working connection to the simulator or - not - - - Coarse locations of avatars in this simulator - - - AvatarPositions key representing TrackAgent target - - - Indicates if UDP connection to the sim is fully established - - + - Simulator Statistics + Fire an event when an event queue connects for capabilities + Simulator the event queue is attached to - - Total number of packets sent by this simulator to this agent - - - Total number of packets received by this simulator to this agent - - - Total number of bytes sent by this simulator to this agent - - - Total number of bytes received by this simulator to this agent + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Time in seconds agent has been connected to simulator + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Total number of packets that have been resent + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Total number of resent packets recieved + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Total number of pings sent to this simulator by this agent + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - Total number of ping replies sent to this agent by this simulator + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - - Incoming bytes per second - - It would be nice to have this claculated on the fly, but - this is far, far easier + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - + - Outgoing bytes per second + A Name Value pair with additional settings, used in the protocol + primarily to transmit avatar names and active group in object packets - It would be nice to have this claculated on the fly, but - this is far, far easier - - - Time last ping was sent - - ID of last Ping sent - - - - - - - - - Current time dilation of this simulator + + Type of the value - - Current Frames per second of simulator + + Unknown - - Current Physics frames per second of simulator + + String value - + - + - + - + - - + + Deprecated - - + + String value, but designated as an asset - + - - + + + + - - Total number of objects Simulator is simulating + + - - Total number of Active (Scripted) objects running + + - - Number of agents currently in this simulator + + - - Number of agents in neighbor simulators + + - - Number of Active scripts running in this simulator + + + + - + - + - + - - Number of downloads pending - - - Number of uploads pending - - + - + - - Number of local uploads pending + + - - Unacknowledged bytes in queue + + - - - Simulator handle - + + - - - Number of GridClients using this datapool - + + - - - Time that the last client disconnected from the simulator - + + - + - The cache of prims used and unused in this simulator + Constructor that takes all the fields as parameters + + + + + - + - Shared parcel info only when POOL_PARCEL_DATA == true + Constructor that takes a single line from a NameValue field + - + - - The event subscribers, null of no subscribers - - - Raises the AttachedSound Event - A AttachedSoundEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - The event subscribers, null of no subscribers - - - Raises the AttachedSoundGainChange Event - A AttachedSoundGainChangeEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - The event subscribers, null of no subscribers - - - Raises the SoundTrigger Event - A SoundTriggerEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - The event subscribers, null of no subscribers - - - Raises the PreloadSound Event - A PreloadSoundEventArgs object containing - the data sent from the simulator - - - Thread sync lock object + + No report - - - Construct a new instance of the SoundManager class, used for playing and receiving - sound assets - - A reference to the current GridClient instance + + Unknown report type - - - Plays a sound in the current region at full volume from avatar position - - UUID of the sound to be played + + Bug report - - - Plays a sound in the current region at full volume - - UUID of the sound to be played. - position for the sound to be played at. Normally the avatar. + + Complaint report - - - Plays a sound in the current region - - UUID of the sound to be played. - position for the sound to be played at. Normally the avatar. - volume of the sound, from 0.0 to 1.0 + + Customer service report - + - Plays a sound in the specified sim + Bitflag field for ObjectUpdateCompressed data blocks, describing + which options are present for each object - UUID of the sound to be played. - UUID of the sound to be played. - position for the sound to be played at. Normally the avatar. - volume of the sound, from 0.0 to 1.0 - - - Play a sound asset - - UUID of the sound to be played. - handle id for the sim to be played in. - position for the sound to be played at. Normally the avatar. - volume of the sound, from 0.0 to 1.0 + + Unknown - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Whether the object has a TreeSpecies - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Whether the object has floating text ala llSetText - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Whether the object has an active particle system - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data + + Whether the object has sound attached to it - - Raised when the simulator sends us data containing - sound + + Whether the object is attached to a root object or not - - Raised when the simulator sends us data containing - ... + + Whether the object has texture animation settings - - Raised when the simulator sends us data containing - ... + + Whether the object has an angular velocity - - Raised when the simulator sends us data containing - ... + + Whether the object has a name value pairs string - - Provides data for the event - The event occurs when the simulator sends - the sound data which emits from an agents attachment - - The following code example shows the process to subscribe to the event - and a stub to handle the data passed from the simulator - - // Subscribe to the AttachedSound event - Client.Sound.AttachedSound += Sound_AttachedSound; - - // process the data raised in the event here - private void Sound_AttachedSound(object sender, AttachedSoundEventArgs e) - { - // ... Process AttachedSoundEventArgs here ... - } - - + + Whether the object has a Media URL set - + - Construct a new instance of the SoundTriggerEventArgs class + Specific Flags for MultipleObjectUpdate requests - Simulator where the event originated - The sound asset id - The ID of the owner - The ID of the object - The volume level - The - - - Simulator where the event originated - - Get the sound asset id + + None - - Get the ID of the owner + + Change position of prims - - Get the ID of the Object + + Change rotation of prims - - Get the volume level + + Change size of prims - - Get the + + Perform operation on link set - - Provides data for the event - The event occurs when an attached sound - changes its volume level + + Scale prims uniformly, same as selecing ctrl+shift in the + viewer. Used in conjunction with Scale - + - Construct a new instance of the AttachedSoundGainChangedEventArgs class + Special values in PayPriceReply. If the price is not one of these + literal value of the price should be use - Simulator where the event originated - The ID of the Object - The new volume level - - - Simulator where the event originated - - Get the ID of the Object - - - Get the volume level - - - Provides data for the event - The event occurs when the simulator forwards - a request made by yourself or another agent to play either an asset sound or a built in sound - - Requests to play sounds where the is not one of the built-in - will require sending a request to download the sound asset before it can be played - - - The following code example uses the , - and - properties to display some information on a sound request on the window. - - // subscribe to the event - Client.Sound.SoundTrigger += Sound_SoundTrigger; - - // play the pre-defined BELL_TING sound - Client.Sound.SendSoundTrigger(Sounds.BELL_TING); - - // handle the response data - private void Sound_SoundTrigger(object sender, SoundTriggerEventArgs e) - { - Console.WriteLine("{0} played the sound {1} at volume {2}", - e.OwnerID, e.SoundID, e.Gain); - } - - - - + - Construct a new instance of the SoundTriggerEventArgs class + Indicates that this pay option should be hidden - Simulator where the event originated - The sound asset id - The ID of the owner - The ID of the object - The ID of the objects parent - The volume level - The regionhandle - The source position - - - Simulator where the event originated - - - Get the sound asset id - - - Get the ID of the owner - - - Get the ID of the Object - - - Get the ID of the objects parent - - - Get the volume level - - Get the regionhandle - - - Get the source position - - - Provides data for the event - The event occurs when the simulator sends - the appearance data for an avatar - - The following code example uses the and - properties to display the selected shape of an avatar on the window. - - // subscribe to the event - Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; - - // handle the data when the event is raised - void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) - { - Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") - } - - - - + - Construct a new instance of the PreloadSoundEventArgs class + Indicates that this pay option should have the default value - Simulator where the event originated - The sound asset id - The ID of the owner - The ID of the object - - - Simulator where the event originated - - - Get the sound asset id - - - Get the ID of the owner - - - Get the ID of the Object - + - pre-defined built in sounds + Contains the variables sent in an object update packet for objects. + Used to track position and movement of prims and avatars - + - + - + - + - + - + - + - + - - coins - - - cash register bell - - + - + - - rubber + + + Handles all network traffic related to prims and avatar positions and + movement. + - - plastic + + The event subscribers, null of no subscribers + + + Thread sync lock object + + + Raised when the simulator sends us data containing + A , Foliage or Attachment + + + + + The event subscribers, null of no subscribers + + + Raises the ObjectProperties Event + A ObjectPropertiesEventArgs object containing + the data sent from the simulator + + + Thread sync lock object + + + Raised when the simulator sends us data containing + additional information + + + + + The event subscribers, null of no subscribers + + + Raises the ObjectPropertiesUpdated Event + A ObjectPropertiesUpdatedEventArgs object containing + the data sent from the simulator + + + Thread sync lock object + + + Raised when the simulator sends us data containing + Primitive.ObjectProperties for an object we are currently tracking - - flesh + + The event subscribers, null of no subscribers - - wood splintering? + + Raises the ObjectPropertiesFamily Event + A ObjectPropertiesFamilyEventArgs object containing + the data sent from the simulator - - glass break + + Thread sync lock object - - metal clunk + + Raised when the simulator sends us data containing + additional and details + - - whoosh + + The event subscribers, null of no subscribers - - shake + + Raises the AvatarUpdate Event + A AvatarUpdateEventArgs object containing + the data sent from the simulator - - + + + Raises the ParticleUpdate Event + + A ParticleUpdateEventArgs object containing + the data sent from the simulator - - ding + + Thread sync lock object - - + + Raised when the simulator sends us data containing + updated information for an - - + + The event subscribers, null of no subscribers - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + and movement changes - - + + The event subscribers, null of no subscribers - - + + Raises the ObjectDataBlockUpdate Event + A ObjectDataBlockUpdateEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + updates to an Objects DataBlock - - + + The event subscribers, null of no subscribers - - + + Raises the KillObject Event + A KillObjectEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator informs us an + or is no longer within view - - + + The event subscribers, null of no subscribers - - + + Raises the KillObjects Event + A KillObjectsEventArgs object containing + the data sent from the simulator - - - A dictionary containing all pre-defined sounds - - A dictionary containing the pre-defined sounds, - where the key is the sounds ID, and the value is a string - containing a name to identify the purpose of the sound + + Thread sync lock object - - X position of this patch + + Raised when the simulator informs us when a group of + or is no longer within view - - Y position of this patch + + The event subscribers, null of no subscribers - - A 16x16 array of floats holding decompressed layer data + + Raises the AvatarSitChanged Event + A AvatarSitChangedEventArgs object containing + the data sent from the simulator - - - Creates a LayerData packet for compressed land data given a full - simulator heightmap and an array of indices of patches to compress - - A 256 * 256 array of floating point values - specifying the height at each meter in the simulator - Array of indexes in the 16x16 grid of patches - for this simulator. For example if 1 and 17 are specified, patches - x=1,y=0 and x=1,y=1 are sent - + + Thread sync lock object - - - Add a patch of terrain to a BitPacker - - BitPacker to write the patch to - Heightmap of the simulator, must be a 256 * - 256 float array - X offset of the patch to create, valid values are - from 0 to 15 - Y offset of the patch to create, valid values are - from 0 to 15 + + Raised when the simulator sends us data containing + updated sit information for our - - The event subscribers. null if no subcribers + + The event subscribers, null of no subscribers - - Raises the LandPatchReceived event - A LandPatchReceivedEventArgs object containing the - data returned from the simulator + + Raises the PayPriceReply Event + A PayPriceReplyEventArgs object containing + the data sent from the simulator - + Thread sync lock object - + + Raised when the simulator sends us data containing + purchase price information for a + + - Default constructor + Callback for getting object media data via CAP - + Indicates if the operation was succesfull + Object media version string + Array indexed on prim face of media entry data - - Raised when the simulator responds sends + + The event subscribers, null of no subscribers - - Simulator from that sent tha data + + Raises the PhysicsProperties Event + A PhysicsPropertiesEventArgs object containing + the data sent from the simulator - - Sim coordinate of the patch + + Thread sync lock object - - Sim coordinate of the patch + + Raised when the simulator sends us data containing + additional information + + - - Size of tha patch + + Reference to the GridClient object - - Heightmap for the patch + + Does periodic dead reckoning calculation to convert + velocity and acceleration to new positions for objects - + - The current status of a texture request as it moves through the pipeline or final result of a texture request. + Construct a new instance of the ObjectManager class + A reference to the instance - - The initial state given to a request. Requests in this state - are waiting for an available slot in the pipeline - - - A request that has been added to the pipeline and the request packet - has been sent to the simulator - - - A request that has received one or more packets back from the simulator - - - A request that has received all packets back from the simulator + + + Request information for a single object from a + you are currently connected to + + The the object is located + The Local ID of the object - - A request that has taken longer than - to download OR the initial packet containing the packet information was never received + + + Request information for multiple objects contained in + the same simulator + + The the objects are located + An array containing the Local IDs of the objects - - The texture request was aborted by request of the agent + + + Attempt to purchase an original object, a copy, or the contents of + an object + + The the object is located + The Local ID of the object + Whether the original, a copy, or the object + contents are on sale. This is used for verification, if the this + sale type is not valid for the object the purchase will fail + Price of the object. This is used for + verification, if it does not match the actual price the purchase + will fail + Group ID that will be associated with the new + purchase + Inventory folder UUID where the object or objects + purchased should be placed + + + BuyObject(Client.Network.CurrentSim, 500, SaleType.Copy, + 100, UUID.Zero, Client.Self.InventoryRootFolderUUID); + + - - The simulator replied to the request that it was not able to find the requested texture + + + Request prices that should be displayed in pay dialog. This will triggger the simulator + to send us back a PayPriceReply which can be handled by OnPayPriceReply event + + The the object is located + The ID of the object + The result is raised in the event - + - A callback fired to indicate the status or final state of the requested texture. For progressive - downloads this will fire each time new asset data is returned from the simulator. + Select a single object. This will cause the to send us + an which will raise the event - The indicating either Progress for textures not fully downloaded, - or the final result of the request after it has been processed through the TexturePipeline - The object containing the Assets ID, raw data - and other information. For progressive rendering the will contain - the data from the beginning of the file. For failed, aborted and timed out requests it will contain - an empty byte array. + The the object is located + The Local ID of the object + - + - Texture request download handler, allows a configurable number of download slots which manage multiple - concurrent texture downloads from the + Select a single object. This will cause the to send us + an which will raise the event - This class makes full use of the internal - system for full texture downloads. + The the object is located + The Local ID of the object + if true, a call to is + made immediately following the request + - - A dictionary containing all pending and in-process transfer requests where the Key is both the RequestID - and also the Asset Texture ID, and the value is an object containing the current state of the request and also - the asset data as it is being re-assembled + + + Select multiple objects. This will cause the to send us + an which will raise the event + + The the objects are located + An array containing the Local IDs of the objects + Should objects be deselected immediately after selection + - - Holds the reference to the client object + + + Select multiple objects. This will cause the to send us + an which will raise the event + + The the objects are located + An array containing the Local IDs of the objects + - - Maximum concurrent texture requests allowed at a time + + + Update the properties of an object + + The the object is located + The Local ID of the object + true to turn the objects physical property on + true to turn the objects temporary property on + true to turn the objects phantom property on + true to turn the objects cast shadows property on - - An array of objects used to manage worker request threads + + + Update the properties of an object + + The the object is located + The Local ID of the object + true to turn the objects physical property on + true to turn the objects temporary property on + true to turn the objects phantom property on + true to turn the objects cast shadows property on + Type of the represetnation prim will have in the physics engine + Density - normal value 1000 + Friction - normal value 0.6 + Restitution - standard value 0.5 + Gravity multiplier - standar value 1.0 - - An array of worker slots which shows the availablity status of the slot + + + Sets the sale properties of a single object + + The the object is located + The Local ID of the object + One of the options from the enum + The price of the object - - The primary thread which manages the requests. + + + Sets the sale properties of multiple objects + + The the objects are located + An array containing the Local IDs of the objects + One of the options from the enum + The price of the object - - true if the TexturePipeline is currently running + + + Deselect a single object + + The the object is located + The Local ID of the object - - A synchronization object used by the primary thread + + + Deselect multiple objects. + + The the objects are located + An array containing the Local IDs of the objects - - A refresh timer used to increase the priority of stalled requests + + + Perform a click action on an object + + The the object is located + The Local ID of the object - + - Default constructor, Instantiates a new copy of the TexturePipeline class + Perform a click action (Grab) on a single object - Reference to the instantiated object + The the object is located + The Local ID of the object + The texture coordinates to touch + The surface coordinates to touch + The face of the position to touch + The region coordinates of the position to touch + The surface normal of the position to touch (A normal is a vector perpindicular to the surface) + The surface binormal of the position to touch (A binormal is a vector tangen to the surface + pointing along the U direction of the tangent space - + - Initialize callbacks required for the TexturePipeline to operate + Create (rez) a new prim object in a simulator + A reference to the object to place the object in + Data describing the prim object to rez + Group ID that this prim will be set to, or UUID.Zero if you + do not want the object to be associated with a specific group + An approximation of the position at which to rez the prim + Scale vector to size this prim + Rotation quaternion to rotate this prim + Due to the way client prim rezzing is done on the server, + the requested position for an object is only close to where the prim + actually ends up. If you desire exact placement you'll need to + follow up by moving the object after it has been created. This + function will not set textures, light and flexible data, or other + extended primitive properties - + - Shutdown the TexturePipeline and cleanup any callbacks or transfers + Create (rez) a new prim object in a simulator + + A reference to the object to place the object in + Data describing the prim object to rez + Group ID that this prim will be set to, or UUID.Zero if you + do not want the object to be associated with a specific group + An approximation of the position at which to rez the prim + Scale vector to size this prim + Rotation quaternion to rotate this prim + Specify the + Due to the way client prim rezzing is done on the server, + the requested position for an object is only close to where the prim + actually ends up. If you desire exact placement you'll need to + follow up by moving the object after it has been created. This + function will not set textures, light and flexible data, or other + extended primitive properties + + + + Rez a Linden tree + A reference to the object where the object resides + The size of the tree + The rotation of the tree + The position of the tree + The Type of tree + The of the group to set the tree to, + or UUID.Zero if no group is to be set + true to use the "new" Linden trees, false to use the old - + - Request a texture asset from the simulator using the system to - manage the requests and re-assemble the image from the packets received from the simulator + Rez grass and ground cover - The of the texture asset to download - The of the texture asset. - Use for most textures, or for baked layer texture assets - A float indicating the requested priority for the transfer. Higher priority values tell the simulator - to prioritize the request before lower valued requests. An image already being transferred using the can have - its priority changed by resending the request with the new priority value - Number of quality layers to discard. - This controls the end marker of the data sent - The packet number to begin the request at. A value of 0 begins the request - from the start of the asset texture - The callback to fire when the image is retrieved. The callback - will contain the result of the request and the texture asset data - If true, the callback will be fired for each chunk of the downloaded image. - The callback asset parameter will contain all previously received chunks of the texture asset starting - from the beginning of the request + A reference to the object where the object resides + The size of the grass + The rotation of the grass + The position of the grass + The type of grass from the enum + The of the group to set the tree to, + or UUID.Zero if no group is to be set - + - Sends the actual request packet to the simulator + Set the textures to apply to the faces of an object - The image to download - Type of the image to download, either a baked - avatar texture or a normal texture - Priority level of the download. Default is - 1,013,000.0f - Number of quality layers to discard. - This controls the end marker of the data sent - Packet number to start the download at. - This controls the start marker of the data sent - Sending a priority of 0 and a discardlevel of -1 aborts - download + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The texture data to apply - + - Cancel a pending or in process texture request + Set the textures to apply to the faces of an object - The texture assets unique ID + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The texture data to apply + A media URL (not used) - + - Master Download Thread, Queues up downloads in the threadpool + Set the Light data on an object + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + A object containing the data to set - + - The worker thread that sends the request and handles timeouts + Set the flexible data on an object - A object containing the request details + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + A object containing the data to set - + - Handle responses from the simulator that tell us a texture we have requested is unable to be located - or no longer exists. This will remove the request from the pipeline and free up a slot if one is in use + Set the sculptie texture and data on an object - The sender - The EventArgs object containing the packet data + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + A object containing the data to set - + - Handles the remaining Image data that did not fit in the initial ImageData packet + Unset additional primitive parameters on an object - The sender - The EventArgs object containing the packet data + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The extra parameters to set - + - Handle the initial ImageDataPacket sent from the simulator + Link multiple prims into a linkset - The sender - The EventArgs object containing the packet data - - - Current number of pending and in-process transfers + A reference to the object where the objects reside + An array which contains the IDs of the objects to link + The last object in the array will be the root object of the linkset TODO: Is this true? - + - A request task containing information and status of a request as it is processed through the + Delink/Unlink multiple prims from a linkset + A reference to the object where the objects reside + An array which contains the IDs of the objects to delink - - The current which identifies the current status of the request - - - The Unique Request ID, This is also the Asset ID of the texture being requested - - - The slot this request is occupying in the threadpoolSlots array - - - The ImageType of the request. - - - The callback to fire when the request is complete, will include - the and the - object containing the result data - - - If true, indicates the callback will be fired whenever new data is returned from the simulator. - This is used to progressively render textures as portions of the texture are received. - - - An object that maintains the data of an request thats in-process. - - + - + Change the rotation of an object + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new rotation of the object - + - An instance of DelegateWrapper which calls InvokeWrappedDelegate, - which in turn calls the DynamicInvoke method of the wrapped - delegate + Set the name of an object + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + A string containing the new name of the object - + - Callback used to call EndInvoke on the asynchronously - invoked DelegateWrapper + Set the name of multiple objects + A reference to the object where the objects reside + An array which contains the IDs of the objects to change the name of + An array which contains the new names of the objects - + - Executes the specified delegate with the specified arguments - asynchronously on a thread pool thread + Set the description of an object - - + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + A string containing the new description of the object - + - Invokes the wrapped delegate synchronously + Set the descriptions of multiple objects - - + A reference to the object where the objects reside + An array which contains the IDs of the objects to change the description of + An array which contains the new descriptions of the objects - + - Calls EndInvoke on the wrapper and Close on the resulting WaitHandle - to prevent resource leaks + Attach an object to this avatar - + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The point on the avatar the object will be attached + The rotation of the attached object - + - Delegate to wrap another delegate and its arguments + Drop an attached object from this avatar - - + A reference to the + object where the objects reside. This will always be the simulator the avatar is currently in + + The object's ID which is local to the simulator the object is in - + - + Detach an object from yourself + A reference to the + object where the objects reside + + This will always be the simulator the avatar is currently in + + An array which contains the IDs of the objects to detach - - - - - - - - - - + - Thrown when a packet could not be successfully deserialized + Change the position of an object, Will change position of entire linkset + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new position of the object - + - Default constructor + Change the position of an object + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new position of the object + if true, will change position of (this) child prim only, not entire linkset - + - Constructor that takes an additional error message + Change the Scale (size) of an object - An error message to attach to this exception + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new scale of the object + If true, will change scale of this prim only, not entire linkset + True to resize prims uniformly - + - The header of a message template packet. Holds packet flags, sequence - number, packet ID, and any ACKs that will be appended at the end of - the packet + Change the Rotation of an object that is either a child or a whole linkset + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new scale of the object + If true, will change rotation of this prim only, not entire linkset - + - Convert the AckList to a byte array, used for packet serializing + Send a Multiple Object Update packet to change the size, scale or rotation of a primitive - Reference to the target byte array - Beginning position to start writing to in the byte - array, will be updated with the ending position of the ACK list + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new rotation, size, or position of the target object + The flags from the Enum - + - + Deed an object (prim) to a group, Object must be shared with group which + can be accomplished with SetPermissions() - - - - + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The of the group to deed the object to - + - + Deed multiple objects (prims) to a group, Objects must be shared with group which + can be accomplished with SetPermissions() - - - + A reference to the object where the object resides + An array which contains the IDs of the objects to deed + The of the group to deed the object to - + - A block of data in a packet. Packets are composed of one or more blocks, - each block containing one or more fields + Set the permissions on multiple objects + A reference to the object where the objects reside + An array which contains the IDs of the objects to set the permissions on + The new Who mask to set + Which permission to modify + The new state of permission - + - Create a block from a byte array + Request additional properties for an object - Byte array containing the serialized block - Starting position of the block in the byte array. - This will point to the data after the end of the block when the - call returns + A reference to the object where the object resides + - + - Serialize this block into a byte array + Request additional properties for an object - Byte array to serialize this block into - Starting position in the byte array to serialize to. - This will point to the position directly after the end of the - serialized block when the call returns - - - Current length of the data in this packet - - - A generic value, not an actual packet type - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + A reference to the object where the object resides + Absolute UUID of the object + Whether to require server acknowledgement of this request - - + + + Set the ownership of a list of objects to the specified group + + A reference to the object where the objects reside + An array which contains the IDs of the objects to set the group id on + The Groups ID - - + + + Update current URL of the previously set prim media + + UUID of the prim + Set current URL to this + Prim face number + Simulator in which prim is located - - + + + Set object media + + UUID of the prim + Array the length of prims number of faces. Null on face indexes where there is + no media, on faces which contain the media + Simulatior in which prim is located - - + + + Retrieve information about object media + + UUID of the primitive + Simulator where prim is located + Call this callback when done - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + + A terse object update, used when a transformation matrix or + velocity/acceleration for an object changes but nothing else + (scale/position/rotation/acceleration/velocity) + + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + + + + + + - - + + + Setup construction data for a basic primitive shape + + Primitive shape to construct + Construction data that can be plugged into a - - + + + + + + + + - - + + + + + + - - + + + Set the Shape data of an object + + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + Data describing the prim shape - - + + + Set the Material data of an object + + A reference to the object where the object resides + The objects ID which is local to the simulator the object is in + The new material of the object - - + + + + + + + + - - + + + + + + + + + - - + + + + + + + + - - + + Provides data for the event + The event occurs when the simulator sends + an containing a Primitive, Foliage or Attachment data + Note 1: The event will not be raised when the object is an Avatar + Note 2: It is possible for the to be + raised twice for the same object if for example the primitive moved to a new simulator, then returned to the current simulator or + if an Avatar crosses the border into a new simulator and returns to the current simulator + + + The following code example uses the , , and + properties to display new Primitives and Attachments on the window. + + // Subscribe to the event that gives us prim and foliage information + Client.Objects.ObjectUpdate += Objects_ObjectUpdate; + + + private void Objects_ObjectUpdate(object sender, PrimEventArgs e) + { + Console.WriteLine("Primitive {0} {1} in {2} is an attachment {3}", e.Prim.ID, e.Prim.LocalID, e.Simulator.Name, e.IsAttachment); + } + + + + + - - + + Get the simulator the originated from - - + + Get the details - - + + true if the did not exist in the dictionary before this update (always true if object tracking has been disabled) - - + + true if the is attached to an - - + + Get the simulator Time Dilation - - + + + Construct a new instance of the PrimEventArgs class + + The simulator the object originated from + The Primitive + The simulator time dilation + The prim was not in the dictionary before this update + true if the primitive represents an attachment to an agent - - + + Provides data for the event + The event occurs when the simulator sends + an containing Avatar data + Note 1: The event will not be raised when the object is an Avatar + Note 2: It is possible for the to be + raised twice for the same avatar if for example the avatar moved to a new simulator, then returned to the current simulator + + + The following code example uses the property to make a request for the top picks + using the method in the class to display the names + of our own agents picks listings on the window. + + // subscribe to the AvatarUpdate event to get our information + Client.Objects.AvatarUpdate += Objects_AvatarUpdate; + Client.Avatars.AvatarPicksReply += Avatars_AvatarPicksReply; + + private void Objects_AvatarUpdate(object sender, AvatarUpdateEventArgs e) + { + // we only want our own data + if (e.Avatar.LocalID == Client.Self.LocalID) + { + // Unsubscribe from the avatar update event to prevent a loop + // where we continually request the picks every time we get an update for ourselves + Client.Objects.AvatarUpdate -= Objects_AvatarUpdate; + // make the top picks request through AvatarManager + Client.Avatars.RequestAvatarPicks(e.Avatar.ID); + } + } + + private void Avatars_AvatarPicksReply(object sender, AvatarPicksReplyEventArgs e) + { + // we'll unsubscribe from the AvatarPicksReply event since we now have the data + // we were looking for + Client.Avatars.AvatarPicksReply -= Avatars_AvatarPicksReply; + // loop through the dictionary and extract the names of the top picks from our profile + foreach (var pickName in e.Picks.Values) + { + Console.WriteLine(pickName); + } + } + + + + - - + + Get the simulator the object originated from - - + + Get the data - - + + Get the simulator time dilation - - + + true if the did not exist in the dictionary before this update (always true if avatar tracking has been disabled) - - + + + Construct a new instance of the AvatarUpdateEventArgs class + + The simulator the packet originated from + The data + The simulator time dilation + The avatar was not in the dictionary before this update - - + + Get the simulator the object originated from - - + + Get the data - - + + Get source - - + + + Construct a new instance of the ParticleUpdateEventArgs class + + The simulator the packet originated from + The ParticleSystem data + The Primitive source - - + + Provides additional primitive data for the event + The event occurs when the simulator sends + an containing additional details for a Primitive, Foliage data or Attachment data + The event is also raised when a request is + made. + + + The following code example uses the , and + + properties to display new attachments and send a request for additional properties containing the name of the + attachment then display it on the window. + + // Subscribe to the event that provides additional primitive details + Client.Objects.ObjectProperties += Objects_ObjectProperties; + + // handle the properties data that arrives + private void Objects_ObjectProperties(object sender, ObjectPropertiesEventArgs e) + { + Console.WriteLine("Primitive Properties: {0} Name is {1}", e.Properties.ObjectID, e.Properties.Name); + } + + - - + + Get the simulator the object is located - - + + Get the primitive properties - - + + + Construct a new instance of the ObjectPropertiesEventArgs class + + The simulator the object is located + The primitive Properties - - + + Provides additional primitive data for the event + The event occurs when the simulator sends + an containing additional details for a Primitive or Foliage data that is currently + being tracked in the dictionary + The event is also raised when a request is + made and is enabled + - - + + Get the primitive details - - + + + Construct a new instance of the ObjectPropertiesUpdatedEvenrArgs class + + The simulator the object is located + The Primitive + The primitive Properties - - + + Provides additional primitive data, permissions and sale info for the event + The event occurs when the simulator sends + an containing additional details for a Primitive, Foliage data or Attachment. This includes + Permissions, Sale info, and other basic details on an object + The event is also raised when a request is + made, the viewer equivalent is hovering the mouse cursor over an object + - - + + Get the simulator the object is located - - + + - - + + - - + + Provides primitive data containing updated location, velocity, rotation, textures for the event + The event occurs when the simulator sends updated location, velocity, rotation, etc + - - + + Get the simulator the object is located - - + + Get the primitive details - - + + - - + + - - + + + + - - + + Get the simulator the object is located - - + + Get the primitive details - - + + - - + + - - + + - - + + - - + + Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the + event - - + + Get the simulator the object is located - - + + The LocalID of the object - - + + Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the + event - - + + Get the simulator the object is located - - + + The LocalID of the object - - + + + Provides updates sit position data + - - + + Get the simulator the object is located - - + + - - + + - - + + - - + + + + - - + + Get the simulator the object is located - - + + - - + + - - + + - - + + + Indicates if the operation was successful + - - + + + Media version string + - - + + + Array of media entries indexed by face number + - - + + + Set when simulator sends us infomation on primitive's physical properties + - - + + Simulator where the message originated - - + + Updated physical properties - - + + + Constructor + + Simulator where the message originated + Updated physical properties - - + + Size of the byte array used to store raw packet data - - + + Raw packet data buffer - - + + Length of the data to transmit - - + + EndPoint of the remote host - - + + + Create an allocated UDP packet buffer for receiving a packet + - - + + + Create an allocated UDP packet buffer for sending a packet + + EndPoint of the remote host - - + + + Create an allocated UDP packet buffer for sending a packet + + EndPoint of the remote host + Size of the buffer to allocate for packet data - - + + + Object pool for packet buffers. This is used to allocate memory for all + incoming and outgoing packets, and zerocoding buffers for those packets + - - + + + Initialize the object pool in client mode + + Server to connect to + + - - + + + Initialize the object pool in server mode + + + - - + + + Returns a packet buffer with EndPoint set if the buffer is in + client mode, or with EndPoint set to null in server mode + + Initialized UDPPacketBuffer object - - + + + Default constructor + - - + + + Check a packet buffer out of the pool + + A packet buffer object - - + + + Returns an instance of the class that has been checked out of the Object Pool. + - - + + + Checks the instance back into the object pool + - - + + + Creates a new instance of the ObjectPoolBase class. Initialize MUST be called + after using this constructor. + - - + + + Creates a new instance of the ObjectPool Base class. + + The object pool is composed of segments, which + are allocated whenever the size of the pool is exceeded. The number of items + in a segment should be large enough that allocating a new segmeng is a rare + thing. For example, on a server that will have 10k people logged in at once, + the receive buffer object pool should have segment sizes of at least 1000 + byte arrays per segment. + + The minimun number of segments that may exist. + Perform a full GC.Collect whenever a segment is allocated, and then again after allocation to compact the heap. + The frequency which segments are checked to see if they're eligible for cleanup. - - + + + Forces the segment cleanup algorithm to be run. This method is intended + primarly for use from the Unit Test libraries. + - - + + + Responsible for allocate 1 instance of an object that will be stored in a segment. + + An instance of whatever objec the pool is pooling. - - + + + Checks in an instance of T owned by the object pool. This method is only intended to be called + by the WrappedObject class. + + The segment from which the instance is checked out. + The instance of T to check back into the segment. - - + + + Checks an instance of T from the pool. If the pool is not sufficient to + allow the checkout, a new segment is created. + + A WrappedObject around the instance of T. To check + the instance back into the segment, be sureto dispose the WrappedObject + when finished. - - + + + The total number of segments created. Intended to be used by the Unit Tests. + - - + + + The number of items that are in a segment. Items in a segment + are all allocated at the same time, and are hopefully close to + each other in the managed heap. + - - + + + The minimum number of segments. When segments are reclaimed, + this number of segments will always be left alone. These + segments are allocated at startup. + - - + + + The age a segment must be before it's eligible for cleanup. + This is used to prevent thrash, and typical values are in + the 5 minute range. + - - + + + The frequence which the cleanup thread runs. This is typically + expected to be in the 5 minute range. + - - + + + + - - + + + + - - + + + + - - + + + + - - + + + + + + - - + + + The ObservableDictionary class is used for storing key/value pairs. It has methods for firing + events to subscribers when items are added, removed, or changed. + + Key + Value - - + + + A dictionary of callbacks to fire when specified action occurs + - - + + + Register a callback to be fired when an action occurs + + The action + The callback to fire - - + + + Unregister a callback + + The action + The callback to fire - - + + + + + + - - + + Internal dictionary that this class wraps around. Do not + modify or enumerate the contents of this dictionary without locking - - + + + Gets the number of Key/Value pairs contained in the + - - + + + Initializes a new instance of the Class + with the specified key/value, has the default initial capacity. + + + + // initialize a new ObservableDictionary named testDict with a string as the key and an int as the value. + public ObservableDictionary<string, int> testDict = new ObservableDictionary<string, int>(); + + - - + + + Initializes a new instance of the Class + with the specified key/value, With its initial capacity specified. + + Initial size of dictionary + + + // initialize a new ObservableDictionary named testDict with a string as the key and an int as the value, + // initially allocated room for 10 entries. + public ObservableDictionary<string, int> testDict = new ObservableDictionary<string, int>(10); + + - - + + + Try to get entry from the with specified key + + Key to use for lookup + Value returned + if specified key exists, if not found + + + // find your avatar using the Simulator.ObjectsAvatars ObservableDictionary: + Avatar av; + if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) + Console.WriteLine("Found Avatar {0}", av.Name); + + + - - + + + Finds the specified match. + + The match. + Matched value + + + // use a delegate to find a prim in the ObjectsPrimitives ObservableDictionary + // with the ID 95683496 + uint findID = 95683496; + Primitive findPrim = sim.ObjectsPrimitives.Find( + delegate(Primitive prim) { return prim.ID == findID; }); + + - - + + Find All items in an + return matching items. + a containing found items. + + Find All prims within 20 meters and store them in a List + + int radius = 20; + List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( + delegate(Primitive prim) { + Vector3 pos = prim.Position; + return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); + } + ); + + - - + + Find All items in an + return matching keys. + a containing found keys. + + Find All keys which also exist in another dictionary + + List<UUID> matches = myDict.FindAll( + delegate(UUID id) { + return myOtherDict.ContainsKey(id); + } + ); + + - - + + Check if Key exists in Dictionary + Key to check for + if found, otherwise - - + + Check if Value exists in Dictionary + Value to check for + if found, otherwise - - + + + Adds the specified key to the dictionary, dictionary locking is not performed, + + + The key + The value - - + + + Removes the specified key, dictionary locking is not performed + + The key. + if successful, otherwise - - + + + Indexer for the dictionary + + The key + The value - - + + + Clear the contents of the dictionary + - - + + + Enumerator for iterating dictionary entries + + - - + + + Provides helper methods for parallelizing loops + - - + + + Executes a for loop in which iterations may run in parallel + + The loop will be started at this index + The loop will be terminated before this index is reached + Method body to run for each iteration of the loop - - + + + Executes a for loop in which iterations may run in parallel + + The number of concurrent execution threads to run + The loop will be started at this index + The loop will be terminated before this index is reached + Method body to run for each iteration of the loop - - + + + Executes a foreach loop in which iterations may run in parallel + + Object type that the collection wraps + An enumerable collection to iterate over + Method body to run for each object in the collection - - + + + Executes a foreach loop in which iterations may run in parallel + + Object type that the collection wraps + The number of concurrent execution threads to run + An enumerable collection to iterate over + Method body to run for each object in the collection - - + + + Executes a series of tasks in parallel + + A series of method bodies to execute - - + + + Executes a series of tasks in parallel + + The number of concurrent execution threads to run + A series of method bodies to execute - - + + + Type of return to use when returning objects from a parcel + - - + + - - + + Return objects owned by parcel owner - - + + Return objects set to group - - + + Return objects not owned by parcel owner or set to group - - + + Return a specific list of objects on parcel - - + + Return objects that are marked for-sale - - + + + Blacklist/Whitelist flags used in parcels Access List + - - + + Agent is denied access - - + + Agent is granted access - - + + + The result of a request for parcel properties + - - + + No matches were found for the request - - + + Request matched a single parcel - - + + Request matched multiple parcels - - + + + Flags used in the ParcelAccessListRequest packet to specify whether + we want the access list (whitelist), ban list (blacklist), or both + - - + + Request the access list - - + + Request the ban list - - + + Request both White and Black lists - - + + + Sequence ID in ParcelPropertiesReply packets (sent when avatar + tries to cross a parcel border) + - - + + Parcel is currently selected - - + + Parcel restricted to a group the avatar is not a + member of - - + + Avatar is banned from the parcel - - + + Parcel is restricted to an access list that the + avatar is not on - - + + Response to hovering over a parcel - - + + + The tool to use when modifying terrain levels + - - + + Level the terrain - - + + Raise the terrain - - + + Lower the terrain - - + + Smooth the terrain - - + + Add random noise to the terrain - - + + Revert terrain to simulator default - - + + + The tool size to use when changing terrain levels + - - + + Small - - + + Medium - - + + Large - - + + + Reasons agent is denied access to a parcel on the simulator + - - + + Agent is not denied, access is granted - - + + Agent is not a member of the group set for the parcel, or which owns the parcel - - + + Agent is not on the parcels specific allow list - - + + Agent is on the parcels ban list - - + + Unknown - - + + Agent is not age verified and parcel settings deny access to non age verified avatars - - + + + Parcel overlay type. This is used primarily for highlighting and + coloring which is why it is a single integer instead of a set of + flags + + These values seem to be poorly thought out. The first three + bits represent a single value, not flags. For example Auction (0x05) is + not a combination of OwnedByOther (0x01) and ForSale(0x04). However, + the BorderWest and BorderSouth values are bit flags that get attached + to the value stored in the first three bits. Bits four, five, and six + are unused - - + + Public land - - + + Land is owned by another avatar - - + + Land is owned by a group - - + + Land is owned by the current avatar - - + + Land is for sale - - + + Land is being auctioned - - + + Land is private - - + + To the west of this area is a parcel border - - + + To the south of this area is a parcel border - - + + + Various parcel properties + - - + + No flags set - - + + Allow avatars to fly (a client-side only restriction) - - + + Allow foreign scripts to run - - + + This parcel is for sale - - + + Allow avatars to create a landmark on this parcel - - + + Allows all avatars to edit the terrain on this parcel - - + + Avatars have health and can take damage on this parcel. + If set, avatars can be killed and sent home here - - + + Foreign avatars can create objects here - - + + All objects on this parcel can be purchased - - + + Access is restricted to a group - - + + Access is restricted to a whitelist - - + + Ban blacklist is enabled - - + + Unknown - - + + List this parcel in the search directory - - + + Allow personally owned parcels to be deeded to group - - + + If Deeded, owner contributes required tier to group parcel is deeded to - - + + Restrict sounds originating on this parcel to the + parcel boundaries - - + + Objects on this parcel are sold when the land is + purchsaed - - + + Allow this parcel to be published on the web - - + + The information for this parcel is mature content - - + + The media URL is an HTML page - - + + The media URL is a raw HTML string - - + + Restrict foreign object pushes - - + + Ban all non identified/transacted avatars - - + + Allow group-owned scripts to run - - + + Allow object creation by group members or group + objects - - + + Allow all objects to enter this parcel - - + + Only allow group and owner objects to enter this parcel - - + + Voice Enabled on this parcel - - + + Use Estate Voice channel for Voice on this parcel - - + + Deny Age Unverified Users - - + + + Parcel ownership status + - - + + Placeholder - - + + Parcel is leased (owned) by an avatar or group - - + + Parcel is in process of being leased (purchased) by an avatar or group - - + + Parcel has been abandoned back to Governor Linden - - + + + Category parcel is listed in under search + - - + + No assigned category - - + + Linden Infohub or public area - - + + Adult themed area - - + + Arts and Culture - - + + Business - - + + Educational - - + + Gaming - - + + Hangout or Club - - + + Newcomer friendly - - + + Parks and Nature - - + + Residential - - + + Shopping - - + + Not Used? - - + + Other - - + + Not an actual category, only used for queries - - + + + Type of teleport landing for a parcel + - - + + Unset, simulator default - - + + Specific landing point set for this parcel - - + + No landing point set, direct teleports enabled for + this parcel - - + + + Parcel Media Command used in ParcelMediaCommandMessage + - - + + Stop the media stream and go back to the first frame - - + + Pause the media stream (stop playing but stay on current frame) - - + + Start the current media stream playing and stop when the end is reached - - + + Start the current media stream playing, + loop to the beginning when the end is reached and continue to play - - + + Specifies the texture to replace with video + If passing the key of a texture, it must be explicitly typecast as a key, + not just passed within double quotes. - - + + Specifies the movie URL (254 characters max) - - + + Specifies the time index at which to begin playing - - + + Specifies a single agent to apply the media command to - - + + Unloads the stream. While the stop command sets the texture to the first frame of the movie, + unload resets it to the real texture that the movie was replacing. - - + + Turn on/off the auto align feature, similar to the auto align checkbox in the parcel media properties + (NOT to be confused with the "align" function in the textures view of the editor!) Takes TRUE or FALSE as parameter. - - + + Allows a Web page or image to be placed on a prim (1.19.1 RC0 and later only). + Use "text/html" for HTML. - - + + Resizes a Web page to fit on x, y pixels (1.19.1 RC0 and later only). + This might still not be working - - + + Sets a description for the media being displayed (1.19.1 RC0 and later only). - - + + + Some information about a parcel of land returned from a DirectoryManager search + - - + + Global Key of record - - + + Parcel Owners - - + + Name field of parcel, limited to 128 characters - - + + Description field of parcel, limited to 256 characters - - + + Total Square meters of parcel - - + + Total area billable as Tier, for group owned land this will be 10% less than ActualArea - - + + True of parcel is in Mature simulator - - + + Grid global X position of parcel - - + + Grid global Y position of parcel - - + + Grid global Z position of parcel (not used) - - + + Name of simulator parcel is located in - - + + Texture of parcels display picture - - + + Float representing calculated traffic based on time spent on parcel by avatars - - + + Sale price of parcel (not used) - - + + Auction ID of parcel - - + + + Parcel Media Information + - - + + A byte, if 0x1 viewer should auto scale media to fit object - - + + A boolean, if true the viewer should loop the media - - + + The Asset UUID of the Texture which when applied to a + primitive will display the media - - + + A URL which points to any Quicktime supported media type - - + + A description of the media - - + + An Integer which represents the height of the media - - + + An integer which represents the width of the media - - + + A string which contains the mime type of the media - - + + + Parcel of land, a portion of virtual real estate in a simulator + - - + + The total number of contiguous 4x4 meter blocks your agent owns within this parcel - - + + The total number of contiguous 4x4 meter blocks contained in this parcel owned by a group or agent other than your own - - + + Deprecated, Value appears to always be 0 - - + + Simulator-local ID of this parcel - - + + UUID of the owner of this parcel - - + + Whether the land is deeded to a group or not - - + + - - + + Date land was claimed - - + + Appears to always be zero - - + + This field is no longer used - - + + Minimum corner of the axis-aligned bounding box for this + parcel - - + + Maximum corner of the axis-aligned bounding box for this + parcel - - + + Bitmap describing land layout in 4x4m squares across the + entire region - - + + Total parcel land area - - + + - - + + Maximum primitives across the entire simulator owned by the same agent or group that owns this parcel that can be used - - + + Total primitives across the entire simulator calculated by combining the allowed prim counts for each parcel + owned by the agent or group that owns this parcel - - + + Maximum number of primitives this parcel supports - - + + Total number of primitives on this parcel - - + + For group-owned parcels this indicates the total number of prims deeded to the group, + for parcels owned by an individual this inicates the number of prims owned by the individual - - + + Total number of primitives owned by the parcel group on + this parcel, or for parcels owned by an individual with a group set the + total number of prims set to that group. - - + + Total number of prims owned by other avatars that are not set to group, or not the parcel owner - - + + A bonus multiplier which allows parcel prim counts to go over times this amount, this does not affect + the max prims per simulator. e.g: 117 prim parcel limit x 1.5 bonus = 175 allowed - - + + Autoreturn value in minutes for others' objects - - + + - - + + Sale price of the parcel, only useful if ForSale is set + The SalePrice will remain the same after an ownership + transfer (sale), so it can be used to see the purchase price after + a sale if the new owner has not changed it - - + + Parcel Name - - + + Parcel Description - - + + URL For Music Stream - - + + - - + + Price for a temporary pass - - + + How long is pass valid for - - + + - - + + Key of authorized buyer - - + + Key of parcel snapshot - - + + The landing point location - - + + The landing point LookAt - - + + The type of landing enforced from the enum - - + + - - + + - - + + - - + + Access list of who is whitelisted on this + parcel - - + + Access list of who is blacklisted on this + parcel - - + + TRUE of region denies access to age unverified users - - + + true to obscure (hide) media url - - + + true to obscure (hide) music url - - + + A struct containing media details - - + + + Displays a parcel object in string format + + string containing key=value pairs of a parcel object - - + + + Defalt constructor + + Local ID of this parcel - - + + + Update the simulator with any local changes to this Parcel object + + Simulator to send updates to + Whether we want the simulator to confirm + the update with a reply packet or not - - + + + Set Autoreturn time + + Simulator to send the update to - - + + + Parcel (subdivided simulator lots) subsystem + - - + + + Parcel Accesslist + - - + + Agents - - + + - - + + Flags for specific entry in white/black lists - - + + + Owners of primitives on parcel + - - + + Prim Owners - - + + True of owner is group - - + + Total count of prims owned by OwnerID - - + + true of OwnerID is currently online and is not a group - - + + The date of the most recent prim left by OwnerID - - + + + Called once parcel resource usage information has been collected + + Indicates if operation was successfull + Parcel resource usage information - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelDwellReply event + A ParcelDwellReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelInfoReply event + A ParcelInfoReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelProperties event + A ParcelPropertiesEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelAccessListReply event + A ParcelAccessListReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelObjectOwnersReply event + A ParcelObjectOwnersReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the SimParcelsDownloaded event + A SimParcelsDownloadedEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the ForceSelectObjectsReply event + A ForceSelectObjectsReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a request - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelMediaUpdateReply event + A ParcelMediaUpdateReplyEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds to a Parcel Update request - - + + The event subscribers. null if no subcribers - - + + Raises the ParcelMediaCommand event + A ParcelMediaCommandEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the parcel your agent is located sends a ParcelMediaCommand - - + + + Default constructor + + A reference to the GridClient object - - + + + Request basic information for a single parcel + + Simulator-local ID of the parcel - - + + + Request properties of a single parcel + + Simulator containing the parcel + Simulator-local ID of the parcel + An arbitrary integer that will be returned + with the ParcelProperties reply, useful for distinguishing between + multiple simultaneous requests - - + + + Request the access list for a single parcel + + Simulator containing the parcel + Simulator-local ID of the parcel + An arbitrary integer that will be returned + with the ParcelAccessList reply, useful for distinguishing between + multiple simultaneous requests + - - + + + Request properties of parcels using a bounding box selection + + Simulator containing the parcel + Northern boundary of the parcel selection + Eastern boundary of the parcel selection + Southern boundary of the parcel selection + Western boundary of the parcel selection + An arbitrary integer that will be returned + with the ParcelProperties reply, useful for distinguishing between + different types of parcel property requests + A boolean that is returned with the + ParcelProperties reply, useful for snapping focus to a single + parcel - - + + + Request all simulator parcel properties (used for populating the Simulator.Parcels + dictionary) + + Simulator to request parcels from (must be connected) - - + + + Request all simulator parcel properties (used for populating the Simulator.Parcels + dictionary) + + Simulator to request parcels from (must be connected) + If TRUE, will force a full refresh + Number of milliseconds to pause in between each request - - + + + Request the dwell value for a parcel + + Simulator containing the parcel + Simulator-local ID of the parcel - - + + + Send a request to Purchase a parcel of land + + The Simulator the parcel is located in + The parcels region specific local ID + true if this parcel is being purchased by a group + The groups + true to remove tier contribution if purchase is successful + The parcels size + The purchase price of the parcel + - - + + + Reclaim a parcel of land + + The simulator the parcel is in + The parcels region specific local ID - - + + + Deed a parcel to a group + + The simulator the parcel is in + The parcels region specific local ID + The groups - - + + + Request prim owners of a parcel of land. + + Simulator parcel is in + The parcels region specific local ID - - + + + Return objects from a parcel + + Simulator parcel is in + The parcels region specific local ID + the type of objects to return, + A list containing object owners s to return - - + + + Subdivide (split) a parcel + + + + + + - - + + + Join two parcels of land creating a single parcel + + + + + + - - + + + Get a parcels LocalID + + Simulator parcel is in + Vector3 position in simulator (Z not used) + 0 on failure, or parcel LocalID on success. + A call to Parcels.RequestAllSimParcels is required to populate map and + dictionary. - - + + + Terraform (raise, lower, etc) an area or whole parcel of land + + Simulator land area is in. + LocalID of parcel, or -1 if using bounding box + From Enum, Raise, Lower, Level, Smooth, Etc. + Size of area to modify + true on successful request sent. + Settings.STORE_LAND_PATCHES must be true, + Parcel information must be downloaded using RequestAllSimParcels() - - + + + Terraform (raise, lower, etc) an area or whole parcel of land + + Simulator land area is in. + west border of area to modify + south border of area to modify + east border of area to modify + north border of area to modify + From Enum, Raise, Lower, Level, Smooth, Etc. + Size of area to modify + true on successful request sent. + Settings.STORE_LAND_PATCHES must be true, + Parcel information must be downloaded using RequestAllSimParcels() - - + + + Terraform (raise, lower, etc) an area or whole parcel of land + + Simulator land area is in. + LocalID of parcel, or -1 if using bounding box + west border of area to modify + south border of area to modify + east border of area to modify + north border of area to modify + From Enum, Raise, Lower, Level, Smooth, Etc. + Size of area to modify + How many meters + or - to lower, 1 = 1 meter + true on successful request sent. + Settings.STORE_LAND_PATCHES must be true, + Parcel information must be downloaded using RequestAllSimParcels() - - + + + Terraform (raise, lower, etc) an area or whole parcel of land + + Simulator land area is in. + LocalID of parcel, or -1 if using bounding box + west border of area to modify + south border of area to modify + east border of area to modify + north border of area to modify + From Enum, Raise, Lower, Level, Smooth, Etc. + Size of area to modify + How many meters + or - to lower, 1 = 1 meter + Height at which the terraform operation is acting at - - + + + Sends a request to the simulator to return a list of objects owned by specific owners + + Simulator local ID of parcel + Owners, Others, Etc + List containing keys of avatars objects to select; + if List is null will return Objects of type selectType + Response data is returned in the event - - + + + Eject and optionally ban a user from a parcel + + target key of avatar to eject + true to also ban target - - + + + Freeze or unfreeze an avatar over your land + + target key to freeze + true to freeze, false to unfreeze - - + + + Abandon a parcel of land + + Simulator parcel is in + Simulator local ID of parcel - - + + + Requests the UUID of the parcel in a remote region at a specified location + + Location of the parcel in the remote region + Remote region handle + Remote region UUID + If successful UUID of the remote parcel, UUID.Zero otherwise - - + + + Retrieves information on resources used by the parcel + + UUID of the parcel + Should per object resource usage be requested + Callback invoked when the request is complete - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + Raises the event - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + Raises the event - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + Raises the event - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + Raises the event - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + Raises the event - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data + Raises the event - - + + Contains a parcels dwell data returned from the simulator in response to an - - + + Get the global ID of the parcel - - + + Get the simulator specific ID of the parcel - - + + Get the calculated dwell - - + + + Construct a new instance of the ParcelDwellReplyEventArgs class + + The global ID of the parcel + The simulator specific ID of the parcel + The calculated dwell for the parcel - - + + Contains basic parcel information data returned from the + simulator in response to an request - - + + Get the object containing basic parcel info - - + + + Construct a new instance of the ParcelInfoReplyEventArgs class + + The object containing basic parcel info - - + + Contains basic parcel information data returned from the simulator in response to an request - - + + Get the simulator the parcel is located in - - + + Get the object containing the details + If Result is NoData, this object will not contain valid data - - + + Get the result of the request - - + + Get the number of primitieves your agent is + currently selecting and or sitting on in this parcel - - + + Get the user assigned ID used to correlate a request with + these results - - + + TODO: - - + + + Construct a new instance of the ParcelPropertiesEventArgs class + + The object containing the details + The object containing the details + The result of the request + The number of primitieves your agent is + currently selecting and or sitting on in this parcel + The user assigned ID used to correlate a request with + these results + TODO: - - + + Contains blacklist and whitelist data returned from the simulator in response to an request - - + + Get the simulator the parcel is located in - - + + Get the user assigned ID used to correlate a request with + these results - - + + Get the simulator specific ID of the parcel - - + + TODO: - - + + Get the list containing the white/blacklisted agents for the parcel - - + + + Construct a new instance of the ParcelAccessListReplyEventArgs class + + The simulator the parcel is located in + The user assigned ID used to correlate a request with + these results + The simulator specific ID of the parcel + TODO: + The list containing the white/blacklisted agents for the parcel - - + + Contains blacklist and whitelist data returned from the + simulator in response to an request - - + + Get the simulator the parcel is located in - - + + Get the list containing prim ownership counts - - + + + Construct a new instance of the ParcelObjectOwnersReplyEventArgs class + + The simulator the parcel is located in + The list containing prim ownership counts - - + + Contains the data returned when all parcel data has been retrieved from a simulator - - + + Get the simulator the parcel data was retrieved from - - + + A dictionary containing the parcel data where the key correlates to the ParcelMap entry - - + + Get the multidimensional array containing a x,y grid mapped + to each 64x64 parcel's LocalID. - - + + + Construct a new instance of the SimParcelsDownloadedEventArgs class + + The simulator the parcel data was retrieved from + The dictionary containing the parcel data + The multidimensional array containing a x,y grid mapped + to each 64x64 parcel's LocalID. - - + + Contains the data returned when a request - - + + Get the simulator the parcel data was retrieved from - - + + Get the list of primitive IDs - - + + true if the list is clean and contains the information + only for a given request - - + + + Construct a new instance of the ForceSelectObjectsReplyEventArgs class + + The simulator the parcel data was retrieved from + The list of primitive IDs + true if the list is clean and contains the information + only for a given request - - + + Contains data when the media data for a parcel the avatar is on changes - - + + Get the simulator the parcel media data was updated in - - + + Get the updated media information - - + + + Construct a new instance of the ParcelMediaUpdateReplyEventArgs class + + the simulator the parcel media data was updated in + The updated media information - - + + Contains the media command for a parcel the agent is currently on - - + + Get the simulator the parcel media command was issued in - - + + - - + + - - + + Get the media command that was sent - - + + - - + + + Construct a new instance of the ParcelMediaCommandEventArgs class + + The simulator the parcel media command was issued in + + + The media command that was sent + - - + + + + - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + - - + + - - + + - - + + - - + + - - + + + + + + - - + + + + - - + + - - + + - - + + - - + + - - + + + + + + - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + - - + + + + + + - - + + + + + + - - + + + + + + + - - + + + + - - + + + + + + - - + + + + + + - - + + + + + - - + + + Class for controlling various system settings. + + Some values are readonly because they affect things that + happen when the GridClient object is initialized, so changing them at + runtime won't do any good. Non-readonly values may affect things that + happen at login or dynamically - - + + Main grid login server - - + + Beta grid login server - - + + The relative directory where external resources are kept - - + + Login server to connect to - - + + IP Address the client will bind to - - + + Use XML-RPC Login or LLSD Login, default is XML-RPC Login - - + + + Maximum number of HTTP connections to open to a particular endpoint. + + + An endpoint is defined as a commbination of network address and port. This is used for Caps. + This is a static variable which applies to all instances. + - - + + + InventoryManager requests inventory information on login, + GridClient initializes an Inventory store for main inventory. + - - + + + InventoryManager requests library information on login, + GridClient initializes an Inventory store for the library. + - - + + + Use Caps for fetching inventory where available + - - + + Number of milliseconds before an asset transfer will time + out - - + + Number of milliseconds before a teleport attempt will time + out - - + + Number of milliseconds before NetworkManager.Logout() will + time out - - + + Number of milliseconds before a CAPS call will time out + Setting this too low will cause web requests time out and + possibly retry repeatedly - - + + Number of milliseconds for xml-rpc to timeout - - + + Milliseconds before a packet is assumed lost and resent - - + + Milliseconds without receiving a packet before the + connection to a simulator is assumed lost - - + + Milliseconds to wait for a simulator info request through + the grid interface - - + + Number of milliseconds between sending pings to each sim - - + + Number of milliseconds between sending camera updates - - + + Number of milliseconds between updating the current + positions of moving, non-accelerating and non-colliding objects - - + + Millisecond interval between ticks, where all ACKs are + sent out and the age of unACKed packets is checked - - + + The initial size of the packet inbox, where packets are + stored before processing - - + + Maximum size of packet that we want to send over the wire - - + + The maximum value of a packet sequence number before it + rolls over back to one - - + + The maximum size of the sequence number archive, used to + check for resent and/or duplicate packets - - + + Maximum number of queued ACKs to be sent before SendAcks() + is forced - - + + Network stats queue length (seconds) - - + + + Primitives will be reused when falling in/out of interest list (and shared between clients) + prims returning to interest list do not need re-requested + Helps also in not re-requesting prim.Properties for code that checks for a Properties == null per client + - - + + + Pool parcel data between clients (saves on requesting multiple times when all clients may need it) + - - + + + How long to preserve cached data when no client is connected to a simulator + The reason for setting it to something like 2 minutes is in case a client + is running back and forth between region edges or a sim is comming and going + + + + Enable/disable storing terrain heightmaps in the + TerrainManager - - + + Enable/disable sending periodic camera updates - - + + Enable/disable automatically setting agent appearance at + login and after sim crossing - - + + Enable/disable automatically setting the bandwidth throttle + after connecting to each simulator + The default throttle uses the equivalent of the maximum + bandwidth setting in the official client. If you do not set a + throttle your connection will by default be throttled well below + the minimum values and you may experience connection problems - - + + Enable/disable the sending of pings to monitor lag and + packet loss - - + + Should we connect to multiple sims? This will allow + viewing in to neighboring simulators and sim crossings + (Experimental) - - + + If true, all object update packets will be decoded in to + native objects. If false, only updates for our own agent will be + decoded. Registering an event handler will force objects for that + type to always be decoded. If this is disabled the object tracking + will have missing or partial prim and avatar information - - + + If true, when a cached object check is received from the + server the full object info will automatically be requested - - + + Whether to establish connections to HTTP capabilities + servers for simulators - - + + Whether to decode sim stats - - + + The capabilities servers are currently designed to + periodically return a 502 error which signals for the client to + re-establish a connection. Set this to true to log those 502 errors - - + + If true, any reference received for a folder or item + the library is not aware of will automatically be fetched - - + + If true, and SEND_AGENT_UPDATES is true, + AgentUpdate packets will continuously be sent out to give the bot + smoother movement and autopiloting - - + + If true, currently visible avatars will be stored + in dictionaries inside Simulator.ObjectAvatars. + If false, a new Avatar or Primitive object will be created + each time an object update packet is received - - + + If true, currently visible avatars will be stored + in dictionaries inside Simulator.ObjectPrimitives. + If false, a new Avatar or Primitive object will be created + each time an object update packet is received - - + + If true, position and velocity will periodically be + interpolated (extrapolated, technically) for objects and + avatars that are being tracked by the library. This is + necessary to increase the accuracy of speed and position + estimates for simulated objects - - + + + If true, utilization statistics will be tracked. There is a minor penalty + in CPU time for enabling this option. + - - + + If true, parcel details will be stored in the + Simulator.Parcels dictionary as they are received - - + + + If true, an incoming parcel properties reply will automatically send + a request for the parcel access list + - - + + + if true, an incoming parcel properties reply will automatically send + a request for the traffic count. + - - + + + If true, images, and other assets downloaded from the server + will be cached in a local directory + - - + + Path to store cached texture data - - + + Maximum size cached files are allowed to take on disk (bytes) - - + + Default color used for viewer particle effects - - + + Cost of uploading an asset + Read-only since this value is dynamically fetched at login - - + + Maximum number of times to resend a failed packet - - + + Throttle outgoing packet rate - - + + UUID of a texture used by some viewers to indentify type of client used - - + + + Download textures using GetTexture capability when available + - - + + The maximum number of concurrent texture downloads allowed + Increasing this number will not necessarily increase texture retrieval times due to + simulator throttles - - + + + The Refresh timer inteval is used to set the delay between checks for stalled texture downloads + + This is a static variable which applies to all instances - - + + + Textures taking longer than this value will be flagged as timed out and removed from the pipeline + - - + + + Get or set the minimum log level to output to the console by default + + If the library is not compiled with DEBUG defined and this level is set to DEBUG + You will get no output on the console. This behavior can be overriden by creating + a logger configuration file for log4net + - - + + Attach avatar names to log messages - - + + Log packet retransmission info - - + + Log disk cache misses and other info - - + + Constructor + Reference to a GridClient object - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + + Simulator (region) properties + - - + + No flags set - - + + Agents can take damage and be killed - - + + Landmarks can be created here - - + + Home position can be set in this sim - - + + Home position is reset when an agent teleports away - - + + Sun does not move - - + + No object, land, etc. taxes - - + + Disable heightmap alterations (agents can still plant + foliage) - - + + Land cannot be released, sold, or purchased - - + + All content is wiped nightly - - + + Unknown: Related to the availability of an overview world map tile.(Think mainland images when zoomed out.) - - + + Unknown: Related to region debug flags. Possibly to skip processing of agent interaction with world. - - + + Region does not update agent prim interest lists. Internal debugging option. - - + + No collision detection for non-agent objects - - + + No scripts are ran - - + + All physics processing is turned off - - + + Region can be seen from other regions on world map. (Legacy world map option?) - - + + Region can be seen from mainland on world map. (Legacy world map option?) - - + + Agents not explicitly on the access list can visit the region. - - + + Traffic calculations are not run across entire region, overrides parcel settings. - - + + Flight is disabled (not currently enforced by the sim) - - + + Allow direct (p2p) teleporting - - + + Estate owner has temporarily disabled scripting - - + + Restricts the usage of the LSL llPushObject function, applies to whole region. - - + + Deny agents with no payment info on file - - + + Deny agents with payment info on file - - + + Deny agents who have made a monetary transaction - - + + Parcels within the region may be joined or divided by anyone, not just estate owners/managers. - - + + Abuse reports sent from within this region are sent to the estate owner defined email. - - + + Region is Voice Enabled - - + + Removes the ability from parcel owners to set their parcels to show in search. - - + + Deny agents who have not been age verified from entering the region. - - + + + Region protocol flags + - - + + Nothing special - - + + Region supports Server side Appearance - - + + Viewer supports Server side Appearance - - + + + Access level for a simulator + - - + + Unknown or invalid access level - - + + Trial accounts allowed - - + + PG rating - - + + Mature rating - - + + Adult rating - - + + Simulator is offline - - + + Simulator does not exist - - + + + + - - + + + Simulator Statistics + - - + + Total number of packets sent by this simulator to this agent - - + + Total number of packets received by this simulator to this agent - - + + Total number of bytes sent by this simulator to this agent - - + + Total number of bytes received by this simulator to this agent - - + + Time in seconds agent has been connected to simulator - - + + Total number of packets that have been resent - - + + Total number of resent packets recieved - - + + Total number of pings sent to this simulator by this agent - - + + Total number of ping replies sent to this agent by this simulator - - + + + Incoming bytes per second + + It would be nice to have this claculated on the fly, but + this is far, far easier - - + + + Outgoing bytes per second + + It would be nice to have this claculated on the fly, but + this is far, far easier - - + + Time last ping was sent - - + + ID of last Ping sent - - + + - - + + - - + + Current time dilation of this simulator - - + + Current Frames per second of simulator - - + + Current Physics frames per second of simulator - - + + - - + + - - + + - - + + - - + + + + + - - + + - - + + - - + + Total number of objects Simulator is simulating - - + + Total number of Active (Scripted) objects running - - + + Number of agents currently in this simulator - - + + Number of agents in neighbor simulators - - + + Number of Active scripts running in this simulator - - + + - - + + - - + + - - + + Number of downloads pending - - + + Number of uploads pending - - + + - - + + - - + + Number of local uploads pending - - + + Unacknowledged bytes in queue - - + + A public reference to the client that this Simulator object + is attached to - - + + A Unique Cache identifier for this simulator - - + + The capabilities for this simulator - - + + - - + + The current version of software this simulator is running - - + + - - + + A 64x64 grid of parcel coloring values. The values stored + in this array are of the type - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + true if your agent has Estate Manager rights on this region - - + + - - + + - - + + - - + + Statistics information for this simulator and the + connection to the simulator, calculated by the simulator itself + and the library - - + + The regions Unique ID - - + + The physical data center the simulator is located + Known values are: + + Dallas + Chandler + SF + + - - + + The CPU Class of the simulator + Most full mainland/estate sims appear to be 5, + Homesteads and Openspace appear to be 501 - - + + The number of regions sharing the same CPU as this one + "Full Sims" appear to be 1, Homesteads appear to be 4 - - + + The billing product name + Known values are: + + Mainland / Full Region (Sku: 023) + Estate / Full Region (Sku: 024) + Estate / Openspace (Sku: 027) + Estate / Homestead (Sku: 029) + Mainland / Homestead (Sku: 129) (Linden Owned) + Mainland / Linden Homes (Sku: 131) + + - - + + The billing product SKU + Known values are: + + 023 Mainland / Full Region + 024 Estate / Full Region + 027 Estate / Openspace + 029 Estate / Homestead + 129 Mainland / Homestead (Linden Owned) + 131 Linden Homes / Full Region + + - - + + + Flags indicating which protocols this region supports + - - + + The current sequence number for packets sent to this + simulator. Must be Interlocked before modifying. Only + useful for applications manipulating sequence numbers - - + + + A thread-safe dictionary containing avatars in a simulator + - - + + + A thread-safe dictionary containing primitives in a simulator + - - + + + Provides access to an internal thread-safe dictionary containing parcel + information found in this simulator + - - + + + Provides access to an internal thread-safe multidimensional array containing a x,y grid mapped + to each 64x64 parcel's LocalID. + - - + + + Checks simulator parcel map to make sure it has downloaded all data successfully + + true if map is full (contains no 0's) - - + + + Is it safe to send agent updates to this sim + AgentMovementComplete message received + - - + + The IP address and port of the server - - + + Whether there is a working connection to the simulator or + not - - + + Coarse locations of avatars in this simulator - - + + AvatarPositions key representing TrackAgent target - - + + Indicates if UDP connection to the sim is fully established - - + + Used internally to track sim disconnections - - + + Event that is triggered when the simulator successfully + establishes a connection - - + + Whether this sim is currently connected or not. Hooked up + to the property Connected - - + + Coarse locations of avatars in this simulator - - + + AvatarPositions key representing TrackAgent target - - + + Sequence numbers of packets we've received + (for duplicate checking) - - + + Packets we sent out that need ACKs from the simulator - - + + Sequence number for pause/resume - - + + Indicates if UDP connection to the sim is fully established - - + + + + + Reference to the GridClient object + IPEndPoint of the simulator + handle of the simulator - - + + + Called when this Simulator object is being destroyed + - - + + + Attempt to connect to this simulator + + Whether to move our agent in to this sim or not + True if the connection succeeded or connection status is + unknown, false if there was a failure - - + + + Initiates connection to the simulator + + Should we block until ack for this packet is recieved - - + + + Disconnect from this simulator + - - + + + Instructs the simulator to stop sending update (and possibly other) packets + - - + + + Instructs the simulator to resume sending update packets (unpause) + - - + + + Retrieve the terrain height at a given coordinate + + Sim X coordinate, valid range is from 0 to 255 + Sim Y coordinate, valid range is from 0 to 255 + The terrain height at the given point if the + lookup was successful, otherwise 0.0f + True if the lookup was successful, otherwise false - - + + + Sends a packet + + Packet to be sent - - + + + + - - + + + Returns Simulator Name as a String + + - - + + + + + - - + + + + + + - - + + + Sends out pending acknowledgements + + Number of ACKs sent - - + + + Resend unacknowledged packets + - - + + + Simulator handle + - - + + + Number of GridClients using this datapool + - - + + + Time that the last client disconnected from the simulator + - - + + + The cache of prims used and unused in this simulator + - - + + + Shared parcel info only when POOL_PARCEL_DATA == true + - - + + + + - - + + The event subscribers, null of no subscribers - - + + Raises the AttachedSound Event + A AttachedSoundEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + sound - - + + The event subscribers, null of no subscribers - - + + Raises the AttachedSoundGainChange Event + A AttachedSoundGainChangeEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - + + The event subscribers, null of no subscribers - - + + Raises the SoundTrigger Event + A SoundTriggerEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - + + The event subscribers, null of no subscribers - - + + Raises the PreloadSound Event + A PreloadSoundEventArgs object containing + the data sent from the simulator - - + + Thread sync lock object - - + + Raised when the simulator sends us data containing + ... - - + + + Construct a new instance of the SoundManager class, used for playing and receiving + sound assets + + A reference to the current GridClient instance - - + + + Plays a sound in the current region at full volume from avatar position + + UUID of the sound to be played - - + + + Plays a sound in the current region at full volume + + UUID of the sound to be played. + position for the sound to be played at. Normally the avatar. - - + + + Plays a sound in the current region + + UUID of the sound to be played. + position for the sound to be played at. Normally the avatar. + volume of the sound, from 0.0 to 1.0 - - + + + Plays a sound in the specified sim + + UUID of the sound to be played. + UUID of the sound to be played. + position for the sound to be played at. Normally the avatar. + volume of the sound, from 0.0 to 1.0 - - + + + Play a sound asset + + UUID of the sound to be played. + handle id for the sim to be played in. + position for the sound to be played at. Normally the avatar. + volume of the sound, from 0.0 to 1.0 - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Process an incoming packet and raise the appropriate events + The sender + The EventArgs object containing the packet data - - + + Provides data for the event + The event occurs when the simulator sends + the sound data which emits from an agents attachment + + The following code example shows the process to subscribe to the event + and a stub to handle the data passed from the simulator + + // Subscribe to the AttachedSound event + Client.Sound.AttachedSound += Sound_AttachedSound; + + // process the data raised in the event here + private void Sound_AttachedSound(object sender, AttachedSoundEventArgs e) + { + // ... Process AttachedSoundEventArgs here ... + } + + - - + + Simulator where the event originated - - + + Get the sound asset id - - + + Get the ID of the owner - - + + Get the ID of the Object - - + + Get the volume level - - + + Get the - - + + + Construct a new instance of the SoundTriggerEventArgs class + + Simulator where the event originated + The sound asset id + The ID of the owner + The ID of the object + The volume level + The - - + + Provides data for the event + The event occurs when an attached sound + changes its volume level - - + + Simulator where the event originated - - + + Get the ID of the Object - - + + Get the volume level - - + + + Construct a new instance of the AttachedSoundGainChangedEventArgs class + + Simulator where the event originated + The ID of the Object + The new volume level - - + + Provides data for the event + The event occurs when the simulator forwards + a request made by yourself or another agent to play either an asset sound or a built in sound + + Requests to play sounds where the is not one of the built-in + will require sending a request to download the sound asset before it can be played + + + The following code example uses the , + and + properties to display some information on a sound request on the window. + + // subscribe to the event + Client.Sound.SoundTrigger += Sound_SoundTrigger; + + // play the pre-defined BELL_TING sound + Client.Sound.SendSoundTrigger(Sounds.BELL_TING); + + // handle the response data + private void Sound_SoundTrigger(object sender, SoundTriggerEventArgs e) + { + Console.WriteLine("{0} played the sound {1} at volume {2}", + e.OwnerID, e.SoundID, e.Gain); + } + + - - + + Simulator where the event originated - - + + Get the sound asset id - - + + Get the ID of the owner - - + + Get the ID of the Object - - + + Get the ID of the objects parent - - + + Get the volume level - - + + Get the regionhandle - - + + Get the source position - - + + + Construct a new instance of the SoundTriggerEventArgs class + + Simulator where the event originated + The sound asset id + The ID of the owner + The ID of the object + The ID of the objects parent + The volume level + The regionhandle + The source position - - + + Provides data for the event + The event occurs when the simulator sends + the appearance data for an avatar + + The following code example uses the and + properties to display the selected shape of an avatar on the window. + + // subscribe to the event + Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; + + // handle the data when the event is raised + void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) + { + Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") + } + + - - + + Simulator where the event originated - - + + Get the sound asset id - - + + Get the ID of the owner - - + + Get the ID of the Object - - + + + Construct a new instance of the PreloadSoundEventArgs class + + Simulator where the event originated + The sound asset id + The ID of the owner + The ID of the object - - + + + pre-defined built in sounds + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + coins - - + + cash register bell - - + + - - + + - - + + rubber - - + + plastic - - + + flesh - - + + wood splintering? - - + + glass break - - + + metal clunk - - + + whoosh - - + + shake - - + + - - + + ding - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + A dictionary containing all pre-defined sounds + + A dictionary containing the pre-defined sounds, + where the key is the sounds ID, and the value is a string + containing a name to identify the purpose of the sound - - + + X position of this patch + + + Y position of this patch - - + + A 16x16 array of floats holding decompressed layer data - - + + + Creates a LayerData packet for compressed land data given a full + simulator heightmap and an array of indices of patches to compress + + A 256 * 256 array of floating point values + specifying the height at each meter in the simulator + Array of indexes in the 16x16 grid of patches + for this simulator. For example if 1 and 17 are specified, patches + x=1,y=0 and x=1,y=1 are sent + - - + + + Add a patch of terrain to a BitPacker + + BitPacker to write the patch to + Heightmap of the simulator, must be a 256 * + 256 float array + X offset of the patch to create, valid values are + from 0 to 15 + Y offset of the patch to create, valid values are + from 0 to 15 - - + + The event subscribers. null if no subcribers - - + + Raises the LandPatchReceived event + A LandPatchReceivedEventArgs object containing the + data returned from the simulator - - + + Thread sync lock object - - + + Raised when the simulator responds sends - - + + + Default constructor + + - - + + Simulator from that sent tha data - - + + Sim coordinate of the patch - - + + Sim coordinate of the patch - - + + Size of tha patch - - + + Heightmap for the patch - - + + + The current status of a texture request as it moves through the pipeline or final result of a texture request. + - - + + The initial state given to a request. Requests in this state + are waiting for an available slot in the pipeline - - + + A request that has been added to the pipeline and the request packet + has been sent to the simulator - - + + A request that has received one or more packets back from the simulator - - + + A request that has received all packets back from the simulator - - + + A request that has taken longer than + to download OR the initial packet containing the packet information was never received - - + + The texture request was aborted by request of the agent - - + + The simulator replied to the request that it was not able to find the requested texture - - + + + A callback fired to indicate the status or final state of the requested texture. For progressive + downloads this will fire each time new asset data is returned from the simulator. + + The indicating either Progress for textures not fully downloaded, + or the final result of the request after it has been processed through the TexturePipeline + The object containing the Assets ID, raw data + and other information. For progressive rendering the will contain + the data from the beginning of the file. For failed, aborted and timed out requests it will contain + an empty byte array. - - + + + Texture request download handler, allows a configurable number of download slots which manage multiple + concurrent texture downloads from the + + This class makes full use of the internal + system for full texture downloads. - - + + + A request task containing information and status of a request as it is processed through the + - - + + The current which identifies the current status of the request - - + + The Unique Request ID, This is also the Asset ID of the texture being requested - - + + The slot this request is occupying in the threadpoolSlots array - - + + The ImageType of the request. - - + + The callback to fire when the request is complete, will include + the and the + object containing the result data - - + + If true, indicates the callback will be fired whenever new data is returned from the simulator. + This is used to progressively render textures as portions of the texture are received. - - + + An object that maintains the data of an request thats in-process. - - + + A dictionary containing all pending and in-process transfer requests where the Key is both the RequestID + and also the Asset Texture ID, and the value is an object containing the current state of the request and also + the asset data as it is being re-assembled - - + + Holds the reference to the client object - - + + Maximum concurrent texture requests allowed at a time - - + + An array of objects used to manage worker request threads - - + + An array of worker slots which shows the availablity status of the slot - - + + The primary thread which manages the requests. - - + + true if the TexturePipeline is currently running - - + + A synchronization object used by the primary thread - - + + A refresh timer used to increase the priority of stalled requests - - + + Current number of pending and in-process transfers - - + + + Default constructor, Instantiates a new copy of the TexturePipeline class + + Reference to the instantiated object - - + + + Initialize callbacks required for the TexturePipeline to operate + - - + + + Shutdown the TexturePipeline and cleanup any callbacks or transfers + - - + + + Request a texture asset from the simulator using the system to + manage the requests and re-assemble the image from the packets received from the simulator + + The of the texture asset to download + The of the texture asset. + Use for most textures, or for baked layer texture assets + A float indicating the requested priority for the transfer. Higher priority values tell the simulator + to prioritize the request before lower valued requests. An image already being transferred using the can have + its priority changed by resending the request with the new priority value + Number of quality layers to discard. + This controls the end marker of the data sent + The packet number to begin the request at. A value of 0 begins the request + from the start of the asset texture + The callback to fire when the image is retrieved. The callback + will contain the result of the request and the texture asset data + If true, the callback will be fired for each chunk of the downloaded image. + The callback asset parameter will contain all previously received chunks of the texture asset starting + from the beginning of the request - - + + + Sends the actual request packet to the simulator + + The image to download + Type of the image to download, either a baked + avatar texture or a normal texture + Priority level of the download. Default is + 1,013,000.0f + Number of quality layers to discard. + This controls the end marker of the data sent + Packet number to start the download at. + This controls the start marker of the data sent + Sending a priority of 0 and a discardlevel of -1 aborts + download - - + + + Cancel a pending or in process texture request + + The texture assets unique ID - - + + + Master Download Thread, Queues up downloads in the threadpool + - - + + + The worker thread that sends the request and handles timeouts + + A object containing the request details - - + + + Handle responses from the simulator that tell us a texture we have requested is unable to be located + or no longer exists. This will remove the request from the pipeline and free up a slot if one is in use + + The sender + The EventArgs object containing the packet data - - + + + Handles the remaining Image data that did not fit in the initial ImageData packet + + The sender + The EventArgs object containing the packet data - - + + + Handle the initial ImageDataPacket sent from the simulator + + The sender + The EventArgs object containing the packet data - - + + + + - - + + + Initialize the UDP packet handler in server mode + + Port to listening for incoming UDP packets on - - + + + Initialize the UDP packet handler in client mode + + Remote UDP server to connect to - - + + + + - - + + + + - - + + + + - - + + + + - - + + - - + + - - + + - - + + + Operation to apply when applying color to texture + - - + + + Information needed to translate visual param value to RGBA color + - - + + + Construct VisualColorParam + + Operation to apply when applying color to texture + Colors - - + + + Represents alpha blending and bump infor for a visual parameter + such as sleive length + - - + + Stregth of the alpha to apply - - + + File containing the alpha channel - - + + Skip blending if parameter value is 0 - - + + Use miltiply insted of alpha blending - - + + + Create new alhpa information for a visual param + + Stregth of the alpha to apply + File containing the alpha channel + Skip blending if parameter value is 0 + Use miltiply insted of alpha blending - - + + + A single visual characteristic of an avatar mesh, such as eyebrow height + - - + + Index of this visual param - - + + Internal name - - + + Group ID this parameter belongs to - - + + Name of the wearable this parameter belongs to - - + + Displayable label of this characteristic - - + + Displayable label for the minimum value of this characteristic - - + + Displayable label for the maximum value of this characteristic - - + + Default value - - + + Minimum value - - + + Maximum value - - + + Is this param used for creation of bump layer? - - + + Alpha blending/bump info - - + + Color information - - + + Array of param IDs that are drivers for this parameter - - + + + Set all the values through the constructor + + Index of this visual param + Internal name + + + Displayable label of this characteristic + Displayable label for the minimum value of this characteristic + Displayable label for the maximum value of this characteristic + Default value + Minimum value + Maximum value + Is this param used for creation of bump layer? + Array of param IDs that are drivers for this parameter + Alpha blending/bump info + Color information - - + + + Holds the Params array of all the avatar appearance parameters + - - + + + Base class for all Asset types + - - + + A byte array containing the raw asset data - - + + True if the asset it only stored on the server temporarily - - + + A unique ID - - + + The assets unique ID - - + + + The "type" of asset, Notecard, Animation, etc + - - + + + Construct a new Asset object + - - + + + Construct a new Asset object + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Regenerates the AssetData byte array from the properties + of the derived class. + - - + + + Decodes the AssetData, placing it in appropriate properties of the derived + class. + + True if the asset decoding succeeded, otherwise false - - + + + Constants for the archiving module + - - + + + The location of the archive control file + - - + + + Path for the assets held in an archive + - - + + + Path for the prims file + - - + + + Path for terrains. Technically these may be assets, but I think it's quite nice to split them out. + - - + + + Path for region settings. + - - + + + Path for region settings. + - - + + + The character the separates the uuid from extension information in an archived asset filename + - - + + + Extensions used for asset types in the archive + - - + + + Archives assets + - - + + + Archive assets + - - + + + Archive the assets given to this archiver to the given archive. + + - - + + + Write an assets metadata file to the given archive + + - - + + + Write asset data files to the given archive + + - - + + + Temporary code to do the bare minimum required to read a tar archive for our purposes + - - + + + Binary reader for the underlying stream + - - + + + Used to trim off null chars + - - + + + Used to trim off space chars + - - + + + Generate a tar reader which reads from the given stream. + + - - + + + Read the next entry in the tar file. + + + + the data for the entry. Returns null if there are no more entries - - + + + Read the next 512 byte chunk of data as a tar header. + + A tar header struct. null if we have reached the end of the archive. - - + + + Read data following a header + + + - - + + + Convert octal bytes to a decimal representation + + + + + - - + + + Temporary code to produce a tar archive in tar v7 format + - - + + + Binary writer for the underlying stream + - - + + + Write a directory entry to the tar archive. We can only handle one path level right now! + + - - + + + Write a file to the tar archive + + + - - + + + Write a file to the tar archive + + + - - + + + Finish writing the raw tar archive data to a stream. The stream will be closed on completion. + - - + + + Write a particular entry + + + + - - + + + Represents an Animation + - - + + Override the base classes AssetType - - + + Default Constructor - - + + + Construct an Asset object of type Animation + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Represents an that represents an avatars body ie: Hair, Etc. + - - + + Override the base classes AssetType - - + + Initializes a new instance of an AssetBodyPart object - - + + Initializes a new instance of an AssetBodyPart object with parameters + A unique specific to this asset + A byte array containing the raw asset data - - + + + Represents a Callingcard with AvatarID and Position vector + - - + + Override the base classes AssetType - - + + UUID of the Callingcard target avatar - - + + Construct an Asset of type Callingcard - - + + + Construct an Asset object of type Callingcard + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Constuct an asset of type Callingcard + + UUID of the target avatar - - + + + Encode the raw contents of a string with the specific Callingcard format + - - + + + Decode the raw asset data, populating the AvatarID and Position + + true if the AssetData was successfully decoded to a UUID and Vector - - + + + Represents an that can be worn on an avatar + such as a Shirt, Pants, etc. + - - + + Override the base classes AssetType - - + + Initializes a new instance of an AssetScriptBinary object - - + + Initializes a new instance of an AssetScriptBinary object with parameters + A unique specific to this asset + A byte array containing the raw asset data - - + + + Type of gesture step + - - + + + Base class for gesture steps + - - + + + Retururns what kind of gesture step this is + - - + + + Describes animation step of a gesture + - - + + + Returns what kind of gesture step this is + - - + + + If true, this step represents start of animation, otherwise animation stop + - - + + + Animation asset + - - + + + Animation inventory name + - - + + + Describes sound step of a gesture + - - + + + Returns what kind of gesture step this is + - - + + + Sound asset + - - + + + Sound inventory name + - - + + + Describes sound step of a gesture + - - + + + Returns what kind of gesture step this is + - - + + + Text to output in chat + - - + + + Describes sound step of a gesture + - - + + + Returns what kind of gesture step this is + - - + + + If true in this step we wait for all animations to finish + - - + + + If true gesture player should wait for the specified amount of time + - - + + + Time in seconds to wait if WaitForAnimation is false + - - + + + Describes the final step of a gesture + - - + + + Returns what kind of gesture step this is + - - + + + Represents a sequence of animations, sounds, and chat actions + - - + + + Returns asset type + - - + + + Keyboard key that triggers the gestyre + - - + + + Modifier to the trigger key + - - + + + String that triggers playing of the gesture sequence + - - + + + Text that replaces trigger in chat once gesture is triggered + - - + + + Sequence of gesture steps + - - + + + Constructs guesture asset + - - + + + Constructs guesture asset + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Encodes gesture asset suitable for uplaod + - - + + + Decodes gesture assset into play sequence + + true if the asset data was decoded successfully - - + + + Represents a Landmark with RegionID and Position vector + - - + + Override the base classes AssetType - - + + UUID of the Landmark target region - - + + Local position of the target - - + + Construct an Asset of type Landmark - - + + + Construct an Asset object of type Landmark + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Encode the raw contents of a string with the specific Landmark format + - - + + + Decode the raw asset data, populating the RegionID and Position + + true if the AssetData was successfully decoded to a UUID and Vector - - + + + Represents Mesh asset + - - + + Override the base classes AssetType - - + + + Decoded mesh data + - - + + Initializes a new instance of an AssetMesh object - - + + Initializes a new instance of an AssetMesh object with parameters + A unique specific to this asset + A byte array containing the raw asset data - - + + + TODO: Encodes Collada file into LLMesh format + - - + + + Decodes mesh asset. See + to furter decode it for rendering + true - - + + + Represents an Animation + - - + + Override the base classes AssetType - - + + Default Constructor - - + + + Construct an Asset object of type Animation + + Asset type + A unique specific to this asset + A byte array containing the raw asset data - - + + + Represents a string of characters encoded with specific formatting properties + - - + + Override the base classes AssetType - - + + A text string containing main text of the notecard - - + + List of s embedded on the notecard - - + + Construct an Asset of type Notecard - - + + + Construct an Asset object of type Notecard + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Encode the raw contents of a string with the specific Linden Text properties + - - + + + Decode the raw asset data including the Linden Text properties + + true if the AssetData was successfully decoded - - + + + A linkset asset, containing a parent primitive and zero or more children + - - + + + Only used internally for XML serialization/deserialization + - - + + Override the base classes AssetType - - + + Initializes a new instance of an AssetPrim object - - + + + Initializes a new instance of an AssetPrim object + + A unique specific to this asset + A byte array containing the raw asset data - - + + + + - - + + + + + - - + + + The deserialized form of a single primitive in a linkset asset + - - + + + Represents an AssetScriptBinary object containing the + LSO compiled bytecode of an LSL script + - - + + Override the base classes AssetType - - + + Initializes a new instance of an AssetScriptBinary object - - + + Initializes a new instance of an AssetScriptBinary object with parameters + A unique specific to this asset + A byte array containing the raw asset data - - + + + TODO: Encodes a scripts contents into a LSO Bytecode file + - - + + + TODO: Decode LSO Bytecode into a string + + true - - + + + Represents an LSL Text object containing a string of UTF encoded characters + - - + + Override the base classes AssetType - - + + A string of characters represting the script contents - - + + Initializes a new AssetScriptText object - - + + + Initializes a new AssetScriptText object with parameters + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Encode a string containing the scripts contents into byte encoded AssetData + - - + + + Decode a byte array containing the scripts contents into a string + + true if decoding is successful - - + + + Represents a Sound Asset + - - + + Override the base classes AssetType - - + + Initializes a new instance of an AssetSound object - - + + Initializes a new instance of an AssetSound object with parameters + A unique specific to this asset + A byte array containing the raw asset data - - + + + TODO: Encodes a sound file + - - + + + TODO: Decode a sound file + + true - - + + + Represents a texture + - - + + Override the base classes AssetType - - + + A object containing image data - - + + - - + + - - + + Initializes a new instance of an AssetTexture object - - + + + Initializes a new instance of an AssetTexture object + + A unique specific to this asset + A byte array containing the raw asset data - - + + + Initializes a new instance of an AssetTexture object + + A object containing texture data - + - Operation to apply when applying color to texture + Populates the byte array with a JPEG2000 + encoded image created from the data in - + - Information needed to translate visual param value to RGBA color + Decodes the JPEG2000 data in AssetData to the + object + True if the decoding was successful, otherwise false - + - Construct VisualColorParam + Decodes the begin and end byte positions for each quality layer in + the image - Operation to apply when applying color to texture - Colors + - + - Represents alpha blending and bump infor for a visual parameter - such as sleive length + Represents a Wearable Asset, Clothing, Hair, Skin, Etc - - Stregth of the alpha to apply + + A string containing the name of the asset - - File containing the alpha channel + + A string containing a short description of the asset - - Skip blending if parameter value is 0 + + The Assets WearableType - - Use miltiply insted of alpha blending + + The For-Sale status of the object - + + An Integer representing the purchase price of the asset + + + The of the assets creator + + + The of the assets current owner + + + The of the assets prior owner + + + The of the Group this asset is set to + + + True if the asset is owned by a + + + The Permissions mask of the asset + + + A Dictionary containing Key/Value pairs of the objects parameters + + + A Dictionary containing Key/Value pairs where the Key is the textures Index and the Value is the Textures + + + Initializes a new instance of an AssetWearable object + + + Initializes a new instance of an AssetWearable object with parameters + A unique specific to this asset + A byte array containing the raw asset data + + - Create new alhpa information for a visual param + Decode an assets byte encoded data to a string - Stregth of the alpha to apply - File containing the alpha channel - Skip blending if parameter value is 0 - Use miltiply insted of alpha blending + true if the asset data was decoded successfully - + - A single visual characteristic of an avatar mesh, such as eyebrow height + Encode the assets string represantion into a format consumable by the asset server - - Index of this visual param + + = - - Internal name + + Number of times we've received an unknown CAPS exception in series. - - Group ID this parameter belongs to + + For exponential backoff on error. - - Name of the wearable this parameter belongs to + + + A set of textures that are layered on texture of each other and "baked" + in to a single texture, for avatar appearances + - - Displayable label of this characteristic + + Final baked texture + + + Component layers - - Displayable label for the minimum value of this characteristic + + Width of the final baked image and scratchpad - - Displayable label for the maximum value of this characteristic + + Height of the final baked image and scratchpad - - Default value + + Bake type - - Minimum value + + Is this one of the 3 skin bakes - - Maximum value + + Final baked texture - - Is this param used for creation of bump layer? + + Component layers - - Alpha blending/bump info + + Width of the final baked image and scratchpad - - Color information + + Height of the final baked image and scratchpad - - Array of param IDs that are drivers for this parameter + + Bake type - + - Set all the values through the constructor + Default constructor - Index of this visual param - Internal name - - - Displayable label of this characteristic - Displayable label for the minimum value of this characteristic - Displayable label for the maximum value of this characteristic - Default value - Minimum value - Maximum value - Is this param used for creation of bump layer? - Array of param IDs that are drivers for this parameter - Alpha blending/bump info - Color information + Bake type - + - Holds the Params array of all the avatar appearance parameters + Adds layer for baking + TexturaData struct that contains texture and its params - + - Base class for all Asset types + Converts avatar texture index (face) to Bake type + Face number (AvatarTextureIndex) + BakeType, layer to which this texture belongs to - - A byte array containing the raw asset data - - - True if the asset it only stored on the server temporarily - - - A unique ID - - + - Construct a new Asset object + Make sure images exist, resize source if needed to match the destination + Destination image + Source image + Sanitization was succefull - + - Construct a new Asset object + Fills a baked layer as a solid *appearing* color. The colors are + subtly dithered on a 16x16 grid to prevent the JPEG2000 stage from + compressing it too far since it seems to cause upload failures if + the image is a pure solid color - A unique specific to this asset - A byte array containing the raw asset data + Color of the base of this layer - + - Regenerates the AssetData byte array from the properties - of the derived class. + Fills a baked layer as a solid *appearing* color. The colors are + subtly dithered on a 16x16 grid to prevent the JPEG2000 stage from + compressing it too far since it seems to cause upload failures if + the image is a pure solid color + Red value + Green value + Blue value - + - Decodes the AssetData, placing it in appropriate properties of the derived - class. + Image width - True if the asset decoding succeeded, otherwise false - - - The assets unique ID - + - The "type" of asset, Notecard, Animation, etc + Image height - + - Constants for the archiving module + Image channel flags - - - Path for region settings. - - - + - The location of the archive control file + Red channel data - + - Path for the assets held in an archive + Green channel data - + - Path for the prims file + Blue channel data - + - Path for terrains. Technically these may be assets, but I think it's quite nice to split them out. + Alpha channel data - + - Path for region settings. + Bump channel data - + - The character the separates the uuid from extension information in an archived asset filename + Create a new blank image + width + height + channel flags - + - Extensions used for asset types in the archive + + - + - Archives assets + Convert the channels in the image. Channels are created or destroyed as required. + new channel flags - + - Archive assets + Resize or stretch the image using nearest neighbor (ugly) resampling + new width + new height - + - Archive the assets given to this archiver to the given archive. + Create a byte array containing 32-bit RGBA data with a bottom-left + origin, suitable for feeding directly into OpenGL - + A byte array containing raw texture data - + - Write an assets metadata file to the given archive + Create a byte array containing 32-bit RGBA data with a bottom-left + origin, suitable for feeding directly into OpenGL - + A byte array containing raw texture data - + - Write asset data files to the given archive + A Wrapper around openjpeg to encode and decode images to and from byte arrays - - - - Temporary code to do the bare minimum required to read a tar archive for our purposes - + + TGA Header size - + - Binary reader for the underlying stream + Defines the beginning and ending file positions of a layer in an + LRCP-progression JPEG2000 file - + - Used to trim off null chars + This structure is used to marshal both encoded and decoded images. + MUST MATCH THE STRUCT IN dotnet.h! - + - Used to trim off space chars + Information about a single packet in a JPEG2000 stream - + + Packet start position + + + Packet header end position + + + Packet end position + + + OpenJPEG is not threadsafe, so this object is used to lock + during calls into unmanaged code + + - Generate a tar reader which reads from the given stream. + Encode a object into a byte array - + The object to encode + true to enable lossless conversion, only useful for small images ie: sculptmaps + A byte array containing the encoded Image object - + - Read the next entry in the tar file. + Encode a object into a byte array - - - the data for the entry. Returns null if there are no more entries + The object to encode + a byte array of the encoded image - + - Read the next 512 byte chunk of data as a tar header. + Decode JPEG2000 data to an and + - A tar header struct. null if we have reached the end of the archive. + JPEG2000 encoded data + ManagedImage object to decode to + Image object to decode to + True if the decode succeeds, otherwise false - + - Read data following a header + - + + - + - Convert octal bytes to a decimal representation + - - - + + + - + - Temporary code to produce a tar archive in tar v7 format + Encode a object into a byte array + The source object to encode + true to enable lossless decoding + A byte array containing the source Bitmap object - + - Binary writer for the underlying stream + Capability to load TGAs to Bitmap - - - Write a directory entry to the tar archive. We can only handle one path level right now! - - + + - - - Write a file to the tar archive - - - + + - - - Write a file to the tar archive - - - + + - - - Finish writing the raw tar archive data to a stream. The stream will be closed on completion. - + + - - - Write a particular entry - - - - + + - - - Represents an Animation - + + - - Default Constructor + + - - - Construct an Asset object of type Animation - - A unique specific to this asset - A byte array containing the raw asset data + + - - Override the base classes AssetType + + - - - Represents an that represents an avatars body ie: Hair, Etc. - + + - - - Represents a Wearable Asset, Clothing, Hair, Skin, Etc - + + - - A string containing the name of the asset + + - - A string containing a short description of the asset + + - - The Assets WearableType + + - - The For-Sale status of the object + + - - An Integer representing the purchase price of the asset + + - - The of the assets creator + + - - The of the assets current owner + + - - The of the assets prior owner + + - - The of the Group this asset is set to + + - - True if the asset is owned by a + + - - The Permissions mask of the asset + + - - A Dictionary containing Key/Value pairs of the objects parameters + + - - A Dictionary containing Key/Value pairs where the Key is the textures Index and the Value is the Textures + + - - Initializes a new instance of an AssetWearable object + + - - Initializes a new instance of an AssetWearable object with parameters - A unique specific to this asset - A byte array containing the raw asset data + + - - - Decode an assets byte encoded data to a string - - true if the asset data was decoded successfully + + - - - Encode the assets string represantion into a format consumable by the asset server - + + - - Initializes a new instance of an AssetBodyPart object + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Initializes a new instance of an AssetBodyPart object with parameters - A unique specific to this asset - A byte array containing the raw asset data + + - - Override the base classes AssetType + + - - - Represents a Callingcard with AvatarID and Position vector - + + - - UUID of the Callingcard target avatar + + - - Construct an Asset of type Callingcard + + - - - Construct an Asset object of type Callingcard - - A unique specific to this asset - A byte array containing the raw asset data + + - - - Constuct an asset of type Callingcard - - UUID of the target avatar + + - - - Encode the raw contents of a string with the specific Callingcard format - + + - - - Decode the raw asset data, populating the AvatarID and Position - - true if the AssetData was successfully decoded to a UUID and Vector + + - - Override the base classes AssetType + + - - - Represents an that can be worn on an avatar - such as a Shirt, Pants, etc. - + + - - Initializes a new instance of an AssetScriptBinary object + + - - Initializes a new instance of an AssetScriptBinary object with parameters - A unique specific to this asset - A byte array containing the raw asset data + + - - Override the base classes AssetType + + - - - Type of gesture step - + + - - - Base class for gesture steps - + + - - - Retururns what kind of gesture step this is - + + - - - Describes animation step of a gesture - + + - - - If true, this step represents start of animation, otherwise animation stop - + + - - - Animation asset - + + - - - Animation inventory name - + + - - - Returns what kind of gesture step this is - + + - - - Describes sound step of a gesture - + + - - - Sound asset - + + - - - Sound inventory name - + + - - - Returns what kind of gesture step this is - + + - - - Describes sound step of a gesture - + + - - - Text to output in chat - + + - - - Returns what kind of gesture step this is - + + - - - Describes sound step of a gesture - + + - - - If true in this step we wait for all animations to finish - + + - - - If true gesture player should wait for the specified amount of time - + + - - - Time in seconds to wait if WaitForAnimation is false - + + - - - Returns what kind of gesture step this is - + + - - - Describes the final step of a gesture - + + - - - Returns what kind of gesture step this is - + + - - - Represents a sequence of animations, sounds, and chat actions - + + - - - Keyboard key that triggers the gestyre - + + - - - Modifier to the trigger key - + + - - - String that triggers playing of the gesture sequence - + + - - - Text that replaces trigger in chat once gesture is triggered - + + - - - Sequence of gesture steps - + + - - - Constructs guesture asset - + + - - - Constructs guesture asset - - A unique specific to this asset - A byte array containing the raw asset data + + - - - Encodes gesture asset suitable for uplaod - + + - - - Decodes gesture assset into play sequence - - true if the asset data was decoded successfully + + - - - Returns asset type - + + - - - Represents a Landmark with RegionID and Position vector - + + - - UUID of the Landmark target region + + - - Local position of the target + + - - Construct an Asset of type Landmark + + - - - Construct an Asset object of type Landmark - - A unique specific to this asset - A byte array containing the raw asset data + + - - - Encode the raw contents of a string with the specific Landmark format - + + - - - Decode the raw asset data, populating the RegionID and Position - - true if the AssetData was successfully decoded to a UUID and Vector + + - - Override the base classes AssetType + + - - - Represents Mesh asset - + + - - - Decoded mesh data - + + - - Initializes a new instance of an AssetMesh object + + - - Initializes a new instance of an AssetMesh object with parameters - A unique specific to this asset - A byte array containing the raw asset data + + - - - TODO: Encodes Collada file into LLMesh format - + + - - - Decodes mesh asset. See - to furter decode it for rendering - true + + - - Override the base classes AssetType + + - - - Represents an Animation - + + - - Default Constructor + + - - - Construct an Asset object of type Animation - - Asset type - A unique specific to this asset - A byte array containing the raw asset data + + - - Override the base classes AssetType + + - - - Represents a string of characters encoded with specific formatting properties - + + - - A text string containing main text of the notecard + + - - List of s embedded on the notecard + + - - Construct an Asset of type Notecard + + - - - Construct an Asset object of type Notecard - - A unique specific to this asset - A byte array containing the raw asset data + + - - - Encode the raw contents of a string with the specific Linden Text properties - + + - - - Decode the raw asset data including the Linden Text properties - - true if the AssetData was successfully decoded + + - - Override the base classes AssetType + + - - - A linkset asset, containing a parent primitive and zero or more children - + + - - Initializes a new instance of an AssetPrim object + + - - - Initializes a new instance of an AssetPrim object - - A unique specific to this asset - A byte array containing the raw asset data + + - - - - + + - - - - - + + - - Override the base classes AssetType + + - - - Only used internally for XML serialization/deserialization - + + - - - The deserialized form of a single primitive in a linkset asset - + + - - - Represents an AssetScriptBinary object containing the - LSO compiled bytecode of an LSL script - + + - - Initializes a new instance of an AssetScriptBinary object + + - - Initializes a new instance of an AssetScriptBinary object with parameters - A unique specific to this asset - A byte array containing the raw asset data + + - - - TODO: Encodes a scripts contents into a LSO Bytecode file - + + - - - TODO: Decode LSO Bytecode into a string - - true + + - - Override the base classes AssetType + + - - - Represents an LSL Text object containing a string of UTF encoded characters - + + - - A string of characters represting the script contents + + - - Initializes a new AssetScriptText object + + - - - Initializes a new AssetScriptText object with parameters - - A unique specific to this asset - A byte array containing the raw asset data + + - - - Encode a string containing the scripts contents into byte encoded AssetData - + + - - - Decode a byte array containing the scripts contents into a string - - true if decoding is successful + + - - Override the base classes AssetType + + - - - Represents a Sound Asset - + + - - Initializes a new instance of an AssetSound object + + - - Initializes a new instance of an AssetSound object with parameters - A unique specific to this asset - A byte array containing the raw asset data + + - - - TODO: Encodes a sound file - + + - - - TODO: Decode a sound file - - true + + - - Override the base classes AssetType + + - - - Represents a texture - + + - - A object containing image data + + - - + + - - + + - - Initializes a new instance of an AssetTexture object + + - - - Initializes a new instance of an AssetTexture object - - A unique specific to this asset - A byte array containing the raw asset data + + - - - Initializes a new instance of an AssetTexture object - - A object containing texture data + + - - - Populates the byte array with a JPEG2000 - encoded image created from the data in - + + - - - Decodes the JPEG2000 data in AssetData to the - object - - True if the decoding was successful, otherwise false + + - - - Decodes the begin and end byte positions for each quality layer in - the image - - + + - - Override the base classes AssetType + + - - = + + - - Number of times we've received an unknown CAPS exception in series. + + - - For exponential backoff on error. + + - - - A set of textures that are layered on texture of each other and "baked" - in to a single texture, for avatar appearances - + + - - Final baked texture + + - - Component layers + + - - Width of the final baked image and scratchpad + + - - Height of the final baked image and scratchpad + + - - Bake type + + - - - Default constructor - - Bake type + + - - - Adds layer for baking - - TexturaData struct that contains texture and its params + + - - - Converts avatar texture index (face) to Bake type - - Face number (AvatarTextureIndex) - BakeType, layer to which this texture belongs to + + - - - Make sure images exist, resize source if needed to match the destination - - Destination image - Source image - Sanitization was succefull + + - - - Fills a baked layer as a solid *appearing* color. The colors are - subtly dithered on a 16x16 grid to prevent the JPEG2000 stage from - compressing it too far since it seems to cause upload failures if - the image is a pure solid color - - Color of the base of this layer + + - - - Fills a baked layer as a solid *appearing* color. The colors are - subtly dithered on a 16x16 grid to prevent the JPEG2000 stage from - compressing it too far since it seems to cause upload failures if - the image is a pure solid color - - Red value - Green value - Blue value + + - - Final baked texture + + - - Component layers + + - - Width of the final baked image and scratchpad + + - - Height of the final baked image and scratchpad + + - - Bake type + + - - Is this one of the 3 skin bakes + + - - - Image width - + + - - - Image height - + + - - - Image channel flags - + + - - - Red channel data - + + - - - Green channel data - + + - - - Blue channel data - + + - - - Alpha channel data - + + - - - Bump channel data - + + - - - Create a new blank image - - width - height - channel flags + + - - - - - + + - - - Convert the channels in the image. Channels are created or destroyed as required. - - new channel flags + + - - - Resize or stretch the image using nearest neighbor (ugly) resampling - - new width - new height + + - - - Create a byte array containing 32-bit RGBA data with a bottom-left - origin, suitable for feeding directly into OpenGL - - A byte array containing raw texture data + + - - - Create a byte array containing 32-bit RGBA data with a bottom-left - origin, suitable for feeding directly into OpenGL - - A byte array containing raw texture data + + - - - A Wrapper around openjpeg to encode and decode images to and from byte arrays - + + - - TGA Header size + + - - OpenJPEG is not threadsafe, so this object is used to lock - during calls into unmanaged code + + - - - Encode a object into a byte array - - The object to encode - true to enable lossless conversion, only useful for small images ie: sculptmaps - A byte array containing the encoded Image object + + - - - Encode a object into a byte array - - The object to encode - a byte array of the encoded image + + - - - Decode JPEG2000 data to an and - - - JPEG2000 encoded data - ManagedImage object to decode to - Image object to decode to - True if the decode succeeds, otherwise false + + - - - - - - - + + - - - - - - - - + + - - - Encode a object into a byte array - - The source object to encode - true to enable lossless decoding - A byte array containing the source Bitmap object + + - - - Defines the beginning and ending file positions of a layer in an - LRCP-progression JPEG2000 file - + + - - - This structure is used to marshal both encoded and decoded images. - MUST MATCH THE STRUCT IN dotnet.h! - + + - - - Information about a single packet in a JPEG2000 stream - + + - - Packet start position + + - - Packet header end position + + - - Packet end position + + - - - Capability to load TGAs to Bitmap - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + + Parsing Collada model files into data structures + + + + + Parses Collada document + + Load .dae model from this file + Load and decode images for uploading with model + A list of mesh prims that were parsed from the collada file + + + + Implements mesh upload communications with the simulator + + + + + Inlcude stub convex hull physics, required for uploading to Second Life + + + + + Use the same mesh used for geometry as the physical mesh upload + + + + + Callback for mesh upload operations + + null on failure, result from server on success + + + + Creates instance of the mesh uploader + + GridClient instance to communicate with the simulator + List of ModelPrimitive objects to upload as a linkset + Inventory name for newly uploaded object + Inventory description for newly upload object + + + + Performs model upload in one go, without first checking for the price + + + + + Performs model upload in one go, without first checking for the price + + Callback that will be invoke upon completion of the upload. Null is sent on request failure + + + + Ask server for details of cost and impact of the mesh upload + + Callback that will be invoke upon completion of the upload. Null is sent on request failure + + + + Performas actual mesh and image upload + + Uri recieved in the upload prepare stage + Callback that will be invoke upon completion of the upload. Null is sent on request failure + + + + Interface requirements for Messaging system + + + + + Abstract base for rendering plugins + + + + + Generates a basic mesh structure from a primitive + + Primitive to generate the mesh from + Level of detail to generate the mesh at + The generated mesh + + + + Generates a basic mesh structure from a sculpted primitive and + texture + + Sculpted primitive to generate the mesh from + Sculpt texture + Level of detail to generate the mesh at + The generated mesh + + + + Generates a series of faces, each face containing a mesh and + metadata + + Primitive to generate the mesh from + Level of detail to generate the mesh at + The generated mesh + + + + Generates a series of faces for a sculpted prim, each face + containing a mesh and metadata + + Sculpted primitive to generate the mesh from + Sculpt texture + Level of detail to generate the mesh at + The generated mesh + + + + Apply texture coordinate modifications from a + to a list of vertices + + Vertex list to modify texture coordinates for + Center-point of the face + Face texture parameters + Scale of the prim + + + + Binary reader, which is endian aware + + + + What is the format of the source file + + + + Construct a reader from a stream + + The stream to read from + + + + Construct a reader from a stream + + The stream to read from + What is the format of the file, assumes PC and similar architecture + + + + Read a 32 bit integer + + A 32 bit integer in the system's endianness - - + + + Read a 16 bit integer + + A 16 bit integer in the system's endianness - - + + + Read a 64 bit integer + + A 64 bit integer in the system's endianness - - + + + Read an unsigned 32 bit integer + + A 32 bit unsigned integer in the system's endianness - - + + + Read a single precision floating point value + + A single precision floating point value in the system's endianness - - + + + Read a double precision floating point value + + A double precision floating point value in the system's endianness - - + + + Read a UTF-8 string + + A standard system string - - + + + Read a UTF-8 string + + length of string to read + A standard system string - - + + + Load and handle Linden Lab binary meshes. + + + The exact definition of this file is a bit sketchy, especially concerning skin weights. + A good starting point is on the + second life wiki + - - + + + Defines a polygon + - - + + + Structure of a vertex, No surprises there, except for the Detail tex coord + + + The skinweights are a tad unconventional. The best explanation found is: + >Each weight actually contains two pieces of information. The number to the + >left of the decimal point is the index of the joint and also implicitly + >indexes to the following joint. The actual weight is to the right of the + >decimal point and interpolates between these two joints. The index is into + >an "expanded" list of joints, not just a linear array of the joints as + >defined in the skeleton file. In particular, any joint that has more than + >one child will be repeated in the list for each of its children. + + Maybe I'm dense, but that description seems to be a bit hard to build an + algorithm on. + + Esentially the weights are compressed into one floating point value. + 1. The whole number part is an index into an array of joints + 2. The fractional part is the weight that joint has + 3. If the fractional part is 0 (x.0000) then the vertex is 100% influenced by the specified joint + - - + + + Provide a nice format for debugging + + Vertex definition as a string - - + + + Describes deltas to apply to a vertex in order to morph a vertex + - - + + + Provide a nice format for debugging + + MorphVertex definition as a string - - + + + Describes a named mesh morph, essentially a named list of MorphVertices + - - + + + Provide a nice format for debugging + + The name of the morph - - + + + Don't really know what this does + - - + + + Provide a nice format for debugging + + Human friendly format - - + + + A reference mesh is one way to implement level of detail + + + Reference meshes are supplemental meshes to full meshes. For all practical + purposes almost all lod meshes are implemented as reference meshes, except for + 'avatar_eye_1.llm' which for some reason is implemented as a full mesh. + - - + + + Load a mesh from a stream + + Filename and path of the file containing the reference mesh - - + + + Level of Detail mesh + - - + + + Construct a linden mesh with the given name + + the name of the mesh - - + + + Construct a linden mesh with the given name + + the name of the mesh + The skeleton governing mesh deformation - - + + + Load the mesh from a stream + + The filename and path of the file containing the mesh data - - + + + Layout of one skinweight element + - - + + List of skinweights, in the same order as the mesh vertices - - + + + Decompress the skinweights + + the expanded joint list, used to index which bones should influece the vertex - - + + + Load a reference mesh from a given stream + + The lod level of this reference mesh + the name and path of the file containing the mesh data + the loaded reference mesh - - + + + Trim a string at the first occurence of NUL + + + The llm file uses null terminated strings (C/C++ style), this is where + the conversion is made. + + The string to trim + A standard .Net string - + + + load the 'avatar_skeleton.xml' + + + Partial class which extends the auto-generated 'LindenSkeleton.Xsd.cs'.eton.xsd + - - + + + Load a skeleton from a given file. + + + We use xml scema validation on top of the xml de-serializer, since the schema has + some stricter checks than the de-serializer provides. E.g. the vector attributes + are guaranteed to hold only 3 float values. This reduces the need for error checking + while working with the loaded skeleton. + + A valid recursive skeleton - - + + + Load a skeleton from a given file. + + + We use xml scema validation on top of the xml de-serializer, since the schema has + some stricter checks than the de-serializer provides. E.g. the vector attributes + are guaranteed to hold only 3 float values. This reduces the need for error checking + while working with the loaded skeleton. + + The path to the skeleton definition file + A valid recursive skeleton - - + + + Build and "expanded" list of joints + + + The algorithm is based on this description: + + >An "expanded" list of joints, not just a + >linear array of the joints as defined in the skeleton file. + >In particular, any joint that has more than one child will + >be repeated in the list for each of its children. + + The list should only take these joint names in consideration + An "expanded" joints list as a flat list of bone names - - + + + Expand one joint + + The parent of the joint we are operating on + The joint we are supposed to expand + Joint list that we will extend upon + The expanded list should only contain these joints - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + + Contains all mesh faces that belong to a prim + - - + + List of primitive faces - - + + + Decodes mesh asset into FacetedMesh + + Mesh primitive + Asset retrieved from the asset server + Level of detail + Resulting decoded FacetedMesh + True if mesh asset decoding was successful - - + + + Sent to the client to indicate a teleport request has completed + - - + + The of the agent - - + + - - + + The simulators handle the agent teleported to - - + + A Uri which contains a list of Capabilities the simulator supports - - + + Indicates the level of access required + to access the simulator, or the content rating, or the simulators + map status - - + + The IP Address of the simulator - - + + The UDP Port the simulator will listen for UDP traffic on - - + + Status flags indicating the state of the Agent upon arrival, Flying, etc. - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Sent to the viewer when a neighboring simulator is requesting the agent make a connection to it. + - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + A message sent to the client which indicates a teleport request has failed + and contains some information on why it failed + - - + + - - + + A string key of the reason the teleport failed e.g. CouldntTPCloser + Which could be used to look up a value in a dictionary or enum - - + + The of the Agent - - + + A string human readable message containing the reason + An example: Could not teleport closer to destination - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Contains a list of prim owner information for a specific parcel in a simulator + + + A Simulator will always return at least 1 entry + If agent does not have proper permission the OwnerID will be UUID.Zero + If agent does not have proper permission OR there are no primitives on parcel + the DataBlocksExtended map will not be sent from the simulator + - - + + + Prim ownership information for a specified owner on a single parcel + - - + + The of the prim owner, + UUID.Zero if agent has no permission to view prim owner information - - + + The total number of prims - - + + True if the OwnerID is a - - + + True if the owner is online + This is no longer used by the LL Simulators - - + + The date the most recent prim was rezzed - - + + An Array of objects - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + The details of a single parcel in a region, also contains some regionwide globals + - - + + Simulator-local ID of this parcel - - + + Maximum corner of the axis-aligned bounding box for this + parcel - - + + Minimum corner of the axis-aligned bounding box for this + parcel - - + + Total parcel land area - - + + - - + + Key of authorized buyer - - + + Bitmap describing land layout in 4x4m squares across the + entire region - - + + - - + + Date land was claimed - - + + Appears to always be zero - - + + Parcel Description - - + + - - + + - - + + Total number of primitives owned by the parcel group on + this parcel - - + + Whether the land is deeded to a group or not - - + + - - + + Maximum number of primitives this parcel supports - - + + The Asset UUID of the Texture which when applied to a + primitive will display the media - - + + A URL which points to any Quicktime supported media type - - + + A byte, if 0x1 viewer should auto scale media to fit object - - + + URL For Music Stream - - + + Parcel Name - - + + Autoreturn value in minutes for others' objects - - + + + + + Total number of other primitives on this parcel - - + + UUID of the owner of this parcel - - + + Total number of primitives owned by the parcel owner on + this parcel - - + + - - + + How long is pass valid for - - + + Price for a temporary pass - - + + - - + + Disallows people outside the parcel from being able to see in - - + + - - + + - - + + - - + + True if the region denies access to age unverified users - - + + - - + + This field is no longer used - - + + The result of a request for parcel properties - - + + Sale price of the parcel, only useful if ForSale is set + The SalePrice will remain the same after an ownership + transfer (sale), so it can be used to see the purchase price after + a sale if the new owner has not changed it - - + + + Number of primitives your avatar is currently + selecting and sitting on in this parcel + - - + + - - + + + A number which increments by 1, starting at 0 for each ParcelProperties request. + Can be overriden by specifying the sequenceID with the ParcelPropertiesRequest being sent. + a Negative number indicates the action in has occurred. + - - + + Maximum primitives across the entire simulator - - + + Total primitives across the entire simulator - - + + - - + + Key of parcel snapshot - - + + Parcel ownership status - - + + Total number of primitives on this parcel - - + + - - + + - - + + A description of the media - - + + An Integer which represents the height of the media - - + + An integer which represents the width of the media - - + + A boolean, if true the viewer should loop the media - - + + A string which contains the mime type of the media - - + + true to obscure (hide) media url - - + + true to obscure (hide) music url - - + + true if avatars in this parcel should be invisible to people outside - - + + true if avatars outside can hear any sounds avatars inside play - - + + true if group members outside can hear any sounds avatars inside play - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + A message sent from the viewer to the simulator to updated a specific parcels settings - - + + The of the agent authorized to purchase this + parcel of land or a NULL if the sale is authorized to anyone - - + + true to enable auto scaling of the parcel media - - + + The category of this parcel used when search is enabled to restrict + search results - - + + A string containing the description to set - - + + The of the which allows for additional + powers and restrictions. - - + + The which specifies how avatars which teleport + to this parcel are handled - - + + The LocalID of the parcel to update settings on - - + + A string containing the description of the media which can be played + to visitors - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + true if avatars in this parcel should be invisible to people outside - - + + true if avatars outside can hear any sounds avatars inside play - - + + true if group members outside can hear any sounds avatars inside play - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + Base class used for the RemoteParcelRequest message - - + + + A message sent from the viewer to the simulator to request information + on a remote parcel + - - + + Local sim position of the parcel we are looking up - - + + Region handle of the parcel we are looking up - - + + Region of the parcel we are looking up - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + A message sent from the simulator to the viewer in response to a + which will contain parcel information + - - + + The grid-wide unique parcel ID - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + A message containing a request for a remote parcel from a viewer, or a response + from the simulator to that request + - - + + The request or response details block - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + A message sent from the simulator to an agent which contains + the groups the agent is in + - - + + The Agent receiving the message - - + + Group Details specific to the agent - - + + true of the agent accepts group notices - - + + The agents tier contribution to the group - - + + The Groups - - + + The of the groups insignia - - + + The name of the group - - + + The aggregate permissions the agent has in the group for all roles the agent + is assigned - - + + An optional block containing additional agent specific information - - + + true of the agent allows this group to be + listed in their profile - - + + An array containing information + for each the agent is a member of - - + + An array containing information + for each the agent is a member of - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + A message sent from the viewer to the simulator which + specifies the language and permissions for others to detect + the language specified + - - + + A string containng the default language + to use for the agent - - + + true of others are allowed to + know the language setting - + - Parsing Collada model files into data structures + Serialize the object + An containing the objects data - + - Parses Collada document + Deserialize the message - Load .dae model from this file - Load and decode images for uploading with model - A list of mesh prims that were parsed from the collada file + An containing the data - + - Implements mesh upload communications with the simulator + An EventQueue message sent from the simulator to an agent when the agent + leaves a group - - - Inlcude stub convex hull physics, required for uploading to Second Life - + + An object containing the Agents UUID, and the Groups UUID - + + The ID of the Agent leaving the group + + + The GroupID the Agent is leaving + + - Use the same mesh used for geometry as the physical mesh upload + An Array containing the AgentID and GroupID - + - Creates instance of the mesh uploader + Serialize the object - GridClient instance to communicate with the simulator - List of ModelPrimitive objects to upload as a linkset - Inventory name for newly uploaded object - Inventory description for newly upload object + An containing the objects data - + - Performs model upload in one go, without first checking for the price + Deserialize the message + An containing the data - + + Base class for Asset uploads/results via Capabilities + + - Performs model upload in one go, without first checking for the price + The request state - Callback that will be invoke upon completion of the upload. Null is sent on request failure - + - Ask server for details of cost and impact of the mesh upload + Serialize the object - Callback that will be invoke upon completion of the upload. Null is sent on request failure + An containing the objects data - + - Performas actual mesh and image upload + Deserialize the message - Uri recieved in the upload prepare stage - Callback that will be invoke upon completion of the upload. Null is sent on request failure + An containing the data - + - Callback for mesh upload operations + A message sent from the viewer to the simulator to request a temporary upload capability + which allows an asset to be uploaded - null on failure, result from server on success - + + The Capability URL sent by the simulator to upload the baked texture to + + - Interface requirements for Messaging system + A message sent from the simulator that will inform the agent the upload is complete, + and the UUID of the uploaded asset - + + The uploaded texture asset ID + + - Abstract base for rendering plugins + A message sent from the viewer to the simulator to request a temporary + capability URI which is used to upload an agents baked appearance textures - + + Object containing request or response + + - Generates a basic mesh structure from a primitive + Serialize the object - Primitive to generate the mesh from - Level of detail to generate the mesh at - The generated mesh + An containing the objects data - + - Generates a basic mesh structure from a sculpted primitive and - texture + Deserialize the message - Sculpted primitive to generate the mesh from - Sculpt texture - Level of detail to generate the mesh at - The generated mesh + An containing the data - + - Generates a series of faces, each face containing a mesh and - metadata + A message sent from the simulator which indicates the minimum version required for + using voice chat - Primitive to generate the mesh from - Level of detail to generate the mesh at - The generated mesh - + + Major Version Required + + + Minor version required + + + The name of the region sending the version requrements + + - Generates a series of faces for a sculpted prim, each face - containing a mesh and metadata + Serialize the object - Sculpted primitive to generate the mesh from - Sculpt texture - Level of detail to generate the mesh at - The generated mesh + An containing the objects data - + - Apply texture coordinate modifications from a - to a list of vertices + Deserialize the message - Vertex list to modify texture coordinates for - Center-point of the face - Face texture parameters - Scale of the prim + An containing the data - + - Sent to the client to indicate a teleport request has completed + A message sent from the simulator to the viewer containing the + voice server URI - - The of the agent + + The Parcel ID which the voice server URI applies - - + + The name of the region - - The simulators handle the agent teleported to + + A uri containing the server/channel information + which the viewer can utilize to participate in voice conversations - - A Uri which contains a list of Capabilities the simulator supports + + + Serialize the object + + An containing the objects data - - Indicates the level of access required - to access the simulator, or the content rating, or the simulators - map status + + + Deserialize the message + + An containing the data - - The IP Address of the simulator + + + + - - The UDP Port the simulator will listen for UDP traffic on + + - - Status flags indicating the state of the Agent upon arrival, Flying, etc. + + - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + - Sent to the viewer when a neighboring simulator is requesting the agent make a connection to it. + A message sent by the viewer to the simulator to request a temporary + capability for a script contained with in a Tasks inventory to be updated - + + Object containing request or response + + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + + + A message sent from the simulator to the viewer to indicate + a Tasks scripts status. + + + + The Asset ID of the script + + + True of the script is compiled/ran using the mono interpreter, false indicates it + uses the older less efficient lsl2 interprter + + + The Task containing the scripts + + + true of the script is in a running state + + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + + + A message containing the request/response used for updating a gesture + contained with an agents inventory + + + + Object containing request or response + + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + - A message sent to the client which indicates a teleport request has failed - and contains some information on why it failed + A message request/response which is used to update a notecard contained within + a tasks inventory - - - - - A string key of the reason the teleport failed e.g. CouldntTPCloser - Which could be used to look up a value in a dictionary or enum - - - The of the Agent + + The of the Task containing the notecard asset to update - - A string human readable message containing the reason - An example: Could not teleport closer to destination + + The notecard assets contained in the tasks inventory - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + + + A reusable class containing a message sent from the viewer to the simulator to request a temporary uploader capability + which is used to update an asset in an agents inventory + + + + + The Notecard AssetID to replace + + + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + - Contains a list of prim owner information for a specific parcel in a simulator + A message containing the request/response used for updating a notecard + contained with an agents inventory - - A Simulator will always return at least 1 entry - If agent does not have proper permission the OwnerID will be UUID.Zero - If agent does not have proper permission OR there are no primitives on parcel - the DataBlocksExtended map will not be sent from the simulator - - - An Array of objects + + Object containing request or response - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + - Prim ownership information for a specified owner on a single parcel + Serialize the object + An containing the objects data - - The of the prim owner, - UUID.Zero if agent has no permission to view prim owner information + + + Deserialize the message + + An containing the data - - The total number of prims + + + A message sent from the simulator to the viewer which indicates + an error occurred while attempting to update a script in an agents or tasks + inventory + - - True if the OwnerID is a + + true of the script was successfully compiled by the simulator - - True if the owner is online - This is no longer used by the LL Simulators + + A string containing the error which occured while trying + to update the script - - The date the most recent prim was rezzed + + A new AssetID assigned to the script - + - The details of a single parcel in a region, also contains some regionwide globals + A message sent from the viewer to the simulator + requesting the update of an existing script contained + within a tasks inventory - - Simulator-local ID of this parcel - - - Maximum corner of the axis-aligned bounding box for this - parcel - - - Minimum corner of the axis-aligned bounding box for this - parcel + + if true, set the script mode to running - - Total parcel land area + + The scripts InventoryItem ItemID to update - - + + A lowercase string containing either "mono" or "lsl2" which + specifies the script is compiled and ran on the mono runtime, or the older + lsl runtime - - Key of authorized buyer + + The tasks which contains the script to update - - Bitmap describing land layout in 4x4m squares across the - entire region + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - Date land was claimed + + + A message containing either the request or response used in updating a script inside + a tasks inventory + - - Appears to always be zero + + Object containing request or response - - Parcel Description + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Response from the simulator to notify the viewer the upload is completed, and + the UUID of the script asset and its compiled status + - - Total number of primitives owned by the parcel group on - this parcel + + The uploaded texture asset ID - - Whether the land is deeded to a group or not + + true of the script was compiled successfully - - + + + A message sent from a viewer to the simulator requesting a temporary uploader capability + used to update a script contained in an agents inventory + - - Maximum number of primitives this parcel supports + + The existing asset if of the script in the agents inventory to replace - - The Asset UUID of the Texture which when applied to a - primitive will display the media + + The language of the script + Defaults to lsl version 2, "mono" might be another possible option - - A URL which points to any Quicktime supported media type + + + Serialize the object + + An containing the objects data - - A byte, if 0x1 viewer should auto scale media to fit object + + + Deserialize the message + + An containing the data - - URL For Music Stream + + + A message containing either the request or response used in updating a script inside + an agents inventory + - - Parcel Name + + Object containing request or response - - Autoreturn value in minutes for others' objects + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - Total number of other primitives on this parcel + + + Serialize the object + + An containing the objects data - - UUID of the owner of this parcel + + + Deserialize the message + + An containing the data - - Total number of primitives owned by the parcel owner on - this parcel + + Base class for Map Layers via Capabilities - + - - How long is pass valid for + + + Serialize the object + + An containing the objects data - - Price for a temporary pass + + + Deserialize the message + + An containing the data - - + + + Sent by an agent to the capabilities server to request map layers + - - Disallows people outside the parcel from being able to see in + + + A message sent from the simulator to the viewer which contains an array of map images and their grid coordinates + - - + + + An object containing map location details + - - + + The Asset ID of the regions tile overlay - - + + The grid location of the southern border of the map tile - - True if the region denies access to age unverified users + + The grid location of the western border of the map tile - - + + The grid location of the eastern border of the map tile - - This field is no longer used + + The grid location of the northern border of the map tile - - The result of a request for parcel properties + + An array containing LayerData items - - Sale price of the parcel, only useful if ForSale is set - The SalePrice will remain the same after an ownership - transfer (sale), so it can be used to see the purchase price after - a sale if the new owner has not changed it + + + Serialize the object + + An containing the objects data - + - Number of primitives your avatar is currently - selecting and sitting on in this parcel + Deserialize the message + An containing the data - - + + Object containing request or response - + - A number which increments by 1, starting at 0 for each ParcelProperties request. - Can be overriden by specifying the sequenceID with the ParcelPropertiesRequest being sent. - a Negative number indicates the action in has occurred. + Serialize the object + An containing the objects data - - Maximum primitives across the entire simulator - - - Total primitives across the entire simulator + + + Deserialize the message + + An containing the data - - + + + New as of 1.23 RC1, no details yet. + - - Key of parcel snapshot + + + Serialize the object + + An containing the objects data - - Parcel ownership status + + + Deserialize the message + + An containing the data - - Total number of primitives on this parcel + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + A string containing the method used - - A description of the media + + + A request sent from an agent to the Simulator to begin a new conference. + Contains a list of Agents which will be included in the conference + - - An Integer which represents the height of the media + + An array containing the of the agents invited to this conference - - An integer which represents the width of the media + + The conferences Session ID - - A boolean, if true the viewer should loop the media + + + Serialize the object + + An containing the objects data - - A string which contains the mime type of the media + + + Deserialize the message + + An containing the data - - true to obscure (hide) media url + + + A moderation request sent from a conference moderator + Contains an agent and an optional action to take + - - true to obscure (hide) music url + + The Session ID - - true if avatars in this parcel should be invisible to people outside + + - - true if avatars outside can hear any sounds avatars inside play + + A list containing Key/Value pairs, known valid values: + key: text value: true/false - allow/disallow specified agents ability to use text in session + key: voice value: true/false - allow/disallow specified agents ability to use voice in session + + "text" or "voice" - - true if group members outside can hear any sounds avatars inside play + + - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - - A message sent from the viewer to the simulator to updated a specific parcels settings - - - The of the agent authorized to purchase this - parcel of land or a NULL if the sale is authorized to anyone - - - true to enable auto scaling of the parcel media - - - The category of this parcel used when search is enabled to restrict - search results - - - A string containing the description to set - - - The of the which allows for additional - powers and restrictions. + + + A message sent from the agent to the simulator which tells the + simulator we've accepted a conference invitation + - - The which specifies how avatars which teleport - to this parcel are handled + + The conference SessionID - - The LocalID of the parcel to update settings on + + + Serialize the object + + An containing the objects data - - A string containing the description of the media which can be played - to visitors + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + + Serialize the object + + An containing the objects data - - + + + Deserialize the message + + An containing the data - - + + Key of sender - - + + Name of sender - - + + Key of destination avatar - - + + ID of originating estate - - + + Key of originating region - - + + Coordinates in originating region - - + + Instant message type - - + + Group IM session toggle - - + + Key of IM session, for Group Messages, the groups UUID - - + + Timestamp of the instant message - - + + Instant message text - - + + Whether this message is held for offline avatars - - true if avatars in this parcel should be invisible to people outside + + Context specific packed data - - true if avatars outside can hear any sounds avatars inside play + + Is this invitation for voice group/conference chat - - true if group members outside can hear any sounds avatars inside play + + + Serialize the object + + An containing the objects data - + Deserialize the message An containing the data - + + + Sent from the simulator to the viewer. + + When an agent initially joins a session the AgentUpdatesBlock object will contain a list of session members including + a boolean indicating they can use voice chat in this session, a boolean indicating they are allowed to moderate + this session, and lastly a string which indicates another agent is entering the session with the Transition set to "ENTER" + + During the session lifetime updates on individuals are sent. During the update the booleans sent during the initial join are + excluded with the exception of the Transition field. This indicates a new user entering or exiting the session with + the string "ENTER" or "LEAVE" respectively. + + + Serialize the object An containing the objects data - - Base class used for the RemoteParcelRequest message - - + - A message sent from the viewer to the simulator to request information - on a remote parcel + Deserialize the message + An containing the data - - Local sim position of the parcel we are looking up + + + An EventQueue message sent when the agent is forcibly removed from a chatterbox session + - - Region handle of the parcel we are looking up + + + A string containing the reason the agent was removed + - - Region of the parcel we are looking up + + + The ChatterBoxSession's SessionID + - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - - - A message sent from the simulator to the viewer in response to a - which will contain parcel information - - - - The grid-wide unique parcel ID - - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + - A message containing a request for a remote parcel from a viewer, or a response - from the simulator to that request + Serialize the object + An containing the objects data - - The request or response details block + + + Deserialize the message + + An containing the data - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + + + + + + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + - A message sent from the simulator to an agent which contains - the groups the agent is in + Serialize the object + An containing the objects data - - The Agent receiving the message - - - An array containing information - for each the agent is a member of - - - An array containing information - for each the agent is a member of + + + Deserialize the message + + An containing the data - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - - Group Details specific to the agent + + + Event Queue message describing physics engine attributes of a list of objects + Sim sends these when object is selected + - - true of the agent accepts group notices + + Array with the list of physics properties - - The agents tier contribution to the group + + + Serializes the message + + Serialized OSD - - The Groups + + + Deserializes the message + + Incoming data to deserialize - - The of the groups insignia + + + Deserializes the message + + Incoming data to deserialize - - The name of the group + + + Serializes the message + + Serialized OSD - - The aggregate permissions the agent has in the group for all roles the agent - is assigned + + + + Deserializes the message + + Incoming data to deserialize - - An optional block containing additional agent specific information + + + Serializes the message + + Serialized OSD + + + + Deserializes the message + + Incoming data to deserialize + + + + Serializes the message + + Serialized OSD - - true of the agent allows this group to be - listed in their profile + + + Detects which class handles deserialization of this message + + An containing the data + Object capable of decoding this message - + A message sent from the viewer to the simulator which - specifies the language and permissions for others to detect - the language specified + specifies that the user has changed current URL + of the specific media on a prim face - - A string containng the default language - to use for the agent + + + New URL + - - true of others are allowed to - know the language setting + + + Prim UUID where navigation occured + - + + + Face index + + + Serialize the object An containing the objects data - + Deserialize the message An containing the data - + + Base class used for the ObjectMedia message + + - An EventQueue message sent from the simulator to an agent when the agent - leaves a group + Message used to retrive prim media data - + - An Array containing the AgentID and GroupID + Prim UUID - + - Serialize the object + Requested operation, either GET or UPDATE - An containing the objects data - + + + Serialize object + + Serialized object as OSDMap + + Deserialize the message An containing the data - - An object containing the Agents UUID, and the Groups UUID - - - The ID of the Agent leaving the group + + + Message used to update prim media data + - - The GroupID the Agent is leaving + + + Prim UUID + - - Base class for Asset uploads/results via Capabilities + + + Array of media entries indexed by face number + - + - The request state + Media version string - + - Serialize the object + Serialize object - An containing the objects data + Serialized object as OSDMap - + Deserialize the message An containing the data - + - A message sent from the viewer to the simulator to request a temporary upload capability - which allows an asset to be uploaded + Message used to update prim media data - - The Capability URL sent by the simulator to upload the baked texture to - - + - A message sent from the simulator that will inform the agent the upload is complete, - and the UUID of the uploaded asset + Prim UUID - - The uploaded texture asset ID - - + - A message sent from the viewer to the simulator to request a temporary - capability URI which is used to upload an agents baked appearance textures + Array of media entries indexed by face number - - Object containing request or response + + + Requested operation, either GET or UPDATE + - + - Serialize the object + Serialize object - An containing the objects data + Serialized object as OSDMap - + Deserialize the message An containing the data - + - A message sent from the simulator which indicates the minimum version required for - using voice chat + Message for setting or getting per face MediaEntry - - Major Version Required - - - Minor version required - - - The name of the region sending the version requrements + + The request or response details block - + Serialize the object An containing the objects data - + Deserialize the message An containing the data - - - A message sent from the simulator to the viewer containing the - voice server URI - + + Details about object resource usage - - The Parcel ID which the voice server URI applies + + Object UUID - - The name of the region + + Object name - - A uri containing the server/channel information - which the viewer can utilize to participate in voice conversations + + Indicates if object is group owned - + + Locatio of the object + + + Object owner + + + Resource usage, keys are resource names, values are resource usage for that specific resource + + - Serialize the object + Deserializes object from OSD - An containing the objects data + An containing the data - + - Deserialize the message + Makes an instance based on deserialized data + + serialized data + Instance containg deserialized data + + + Details about parcel resource usage + + + Parcel UUID + + + Parcel local ID + + + Parcel name + + + Indicates if parcel is group owned + + + Parcel owner + + + Array of containing per object resource usage + + + + Deserializes object from OSD An containing the data - + - + Makes an instance based on deserialized data + serialized data + Instance containg deserialized data - - + + Resource usage base class, both agent and parcel resource + usage contains summary information - - + + Summary of available resources, keys are resource names, + values are resource usage for that specific resource - + + Summary resource usage, keys are resource names, + values are resource usage for that specific resource + + - Serialize the object + Serializes object - An containing the objects data + serialized data - + - Deserialize the message + Deserializes object from OSD An containing the data - + + Agent resource usage + + + Per attachment point object resource usage + + - A message sent by the viewer to the simulator to request a temporary - capability for a script contained with in a Tasks inventory to be updated + Deserializes object from OSD + An containing the data - - Object containing request or response - - + - Serialize the object + Makes an instance based on deserialized data - An containing the objects data + serialized data + Instance containg deserialized data - + - Deserialize the message + Detects which class handles deserialization of this message An containing the data + Object capable of decoding this message - + + Request message for parcel resource usage + + + UUID of the parel to request resource usage info + + - A message sent from the simulator to the viewer to indicate - a Tasks scripts status. + Serializes object + serialized data - - The Asset ID of the script + + + Deserializes object from OSD + + An containing the data - - True of the script is compiled/ran using the mono interpreter, false indicates it - uses the older less efficient lsl2 interprter + + Response message for parcel resource usage - - The Task containing the scripts + + URL where parcel resource usage details can be retrieved - - true of the script is in a running state + + URL where parcel resource usage summary can be retrieved - + - Serialize the object + Serializes object - An containing the objects data + serialized data - + - Deserialize the message + Deserializes object from OSD An containing the data - + - A message containing the request/response used for updating a gesture - contained with an agents inventory + Detects which class handles deserialization of this message + An containing the data + Object capable of decoding this message - - Object containing request or response + + Parcel resource usage - - - Serialize the object - - An containing the objects data + + Array of containing per percal resource usage - + - Deserialize the message + Deserializes object from OSD An containing the data - + - A message request/response which is used to update a notecard contained within - a tasks inventory + Reply to request for bunch if display names - - The of the Task containing the notecard asset to update + + Current display name - - The notecard assets contained in the tasks inventory + + Following UUIDs failed to return a valid display name - + - Serialize the object + Serializes the message - An containing the objects data + OSD containting the messaage - + - Deserialize the message + Message sent when requesting change of the display name - An containing the data - - - A reusable class containing a message sent from the viewer to the simulator to request a temporary uploader capability - which is used to update an asset in an agents inventory - + + Current display name - + + Desired new display name + + - The Notecard AssetID to replace + Serializes the message + OSD containting the messaage - + - Serialize the object + Message recieved in response to request to change display name - An containing the objects data - + + New display name + + + String message indicating the result of the operation + + + Numerical code of the result, 200 indicates success + + - Deserialize the message + Serializes the message - An containing the data + OSD containting the messaage - + - A message containing the request/response used for updating a notecard - contained with an agents inventory + Message recieved when someone nearby changes their display name - - Object containing request or response + + Previous display name, empty string if default - + + New display name + + - Serialize the object + Serializes the message - An containing the objects data + OSD containting the messaage - + - Deserialize the message + Return a decoded capabilities message as a strongly typed object - An containing the data + A string containing the name of the capabilities message key + An to decode + A strongly typed object containing the decoded information from the capabilities message, or null + if no existing Message object exists for the specified event - + - Serialize the object + Permissions for control of object media - An containing the objects data - + - Deserialize the message + Style of cotrols that shold be displayed to the user - An containing the data - + - A message sent from the simulator to the viewer which indicates - an error occurred while attempting to update a script in an agents or tasks - inventory + Class representing media data for a single face - - true of the script was successfully compiled by the simulator + + Is display of the alternative image enabled - - A string containing the error which occured while trying - to update the script + + Should media auto loop - - A new AssetID assigned to the script + + Shoule media be auto played - - - A message sent from the viewer to the simulator - requesting the update of an existing script contained - within a tasks inventory - + + Auto scale media to prim face - - if true, set the script mode to running + + Should viewer automatically zoom in on the face when clicked - - The scripts InventoryItem ItemID to update + + Should viewer interpret first click as interaction with the media + or when false should the first click be treated as zoom in commadn - - A lowercase string containing either "mono" or "lsl2" which - specifies the script is compiled and ran on the mono runtime, or the older - lsl runtime + + Style of controls viewer should display when + viewer media on this face - - The tasks which contains the script to update + + Starting URL for the media - + + Currently navigated URL + + + Media height in pixes + + + Media width in pixels + + + Who can controls the media + + + Who can interact with the media + + + Is URL whitelist enabled + + + Array of URLs that are whitelisted + + - Serialize the object + Serialize to OSD + + OSDMap with the serialized data + + + + Deserialize from OSD data - An containing the objects data + Serialized OSD data + Deserialized object - + - Deserialize the message + Particle system specific enumerators, flags and methods. - An containing the data - + - A message containing either the request or response used in updating a script inside - a tasks inventory + Current version of the media data for the prim - - Object containing request or response - - + - Serialize the object + Array of media entries indexed by face number - An containing the objects data - + - Deserialize the message + Complete structure for the particle system - An containing the data - + - Response from the simulator to notify the viewer the upload is completed, and - the UUID of the script asset and its compiled status + Particle source pattern - - The uploaded texture asset ID + + None - - true of the script was compiled successfully + + Drop particles from source position with no force - - - A message sent from a viewer to the simulator requesting a temporary uploader capability - used to update a script contained in an agents inventory - + + "Explode" particles in all directions - - The existing asset if of the script in the agents inventory to replace + + Particles shoot across a 2D area - - The language of the script - Defaults to lsl version 2, "mono" might be another possible option + + Particles shoot across a 3D Cone - - - Serialize the object - - An containing the objects data + + Inverse of AngleCone (shoot particles everywhere except the 3D cone defined - + - Deserialize the message + Particle Data Flags - An containing the data - - - A message containing either the request or response used in updating a script inside - an agents inventory - + + None - - Object containing request or response + + Interpolate color and alpha from start to end - - - Serialize the object - - An containing the objects data + + Interpolate scale from start to end - - - Deserialize the message - - An containing the data + + Bounce particles off particle sources Z height - - - Serialize the object - - An containing the objects data + + velocity of particles is dampened toward the simulators wind - - - Deserialize the message - - An containing the data + + Particles follow the source - - Base class for Map Layers via Capabilities + + Particles point towards the direction of source's velocity - - + + Target of the particles - - - Serialize the object - - An containing the objects data + + Particles are sent in a straight line - - - Deserialize the message - - An containing the data + + Particles emit a glow - - - Sent by an agent to the capabilities server to request map layers - + + used for point/grab/touch - - - A message sent from the simulator to the viewer which contains an array of map images and their grid coordinates - + + continuous ribbon particle - - An array containing LayerData items + + particle data contains glow - - - Serialize the object - - An containing the objects data + + particle data contains blend functions - + - Deserialize the message + Particle Flags Enum - An containing the data - - - An object containing map location details - + + None - - The Asset ID of the regions tile overlay + + Acceleration and velocity for particles are + relative to the object rotation - - The grid location of the southern border of the map tile + + Particles use new 'correct' angle parameters - - The grid location of the western border of the map tile + + Particle Flags + There appears to be more data packed in to this area + for many particle systems. It doesn't appear to be flag values + and serialization breaks unless there is a flag for every + possible bit so it is left as an unsigned integer - - The grid location of the eastern border of the map tile + + pattern of particles - - The grid location of the northern border of the map tile + + A representing the maximimum age (in seconds) particle will be displayed + Maximum value is 30 seconds - - Object containing request or response + + A representing the number of seconds, + from when the particle source comes into view, + or the particle system's creation, that the object will emits particles; + after this time period no more particles are emitted - - - Serialize the object - - An containing the objects data + + A in radians that specifies where particles will not be created - - - Deserialize the message - - An containing the data + + A in radians that specifies where particles will be created - - - New as of 1.23 RC1, no details yet. - + + A representing the number of seconds between burts. - - - Serialize the object - - An containing the objects data + + A representing the number of meters + around the center of the source where particles will be created. - - - Deserialize the message - - An containing the data + + A representing in seconds, the minimum speed between bursts of new particles + being emitted - - - Serialize the object - - An containing the objects data + + A representing in seconds the maximum speed of new particles being emitted. - - - Deserialize the message - - An containing the data + + A representing the maximum number of particles emitted per burst - - A string containing the method used + + A which represents the velocity (speed) from the source which particles are emitted - - - A request sent from an agent to the Simulator to begin a new conference. - Contains a list of Agents which will be included in the conference - + + A which represents the Acceleration from the source which particles are emitted - - An array containing the of the agents invited to this conference + + The Key of the texture displayed on the particle - - The conferences Session ID + + The Key of the specified target object or avatar particles will follow - - - Serialize the object - - An containing the objects data + + Flags of particle from - - - Deserialize the message - - An containing the data + + Max Age particle system will emit particles for - - - A moderation request sent from a conference moderator - Contains an agent and an optional action to take - + + The the particle has at the beginning of its lifecycle - - The Session ID + + The the particle has at the ending of its lifecycle - - + + A that represents the starting X size of the particle + Minimum value is 0, maximum value is 4 - - A list containing Key/Value pairs, known valid values: - key: text value: true/false - allow/disallow specified agents ability to use text in session - key: voice value: true/false - allow/disallow specified agents ability to use voice in session - - "text" or "voice" + + A that represents the starting Y size of the particle + Minimum value is 0, maximum value is 4 - - + + A that represents the ending X size of the particle + Minimum value is 0, maximum value is 4 - - - Serialize the object - - An containing the objects data + + A that represents the ending Y size of the particle + Minimum value is 0, maximum value is 4 - - - Deserialize the message - - An containing the data + + A that represents the start glow value + Minimum value is 0, maximum value is 1 - - - A message sent from the agent to the simulator which tells the - simulator we've accepted a conference invitation - + + A that represents the end glow value + Minimum value is 0, maximum value is 1 - - The conference SessionID + + OpenGL blend function to use at particle source - - - Serialize the object - - An containing the objects data + + OpenGL blend function to use at particle destination - + - Deserialize the message + Can this particle system be packed in a legacy compatible way - An containing the data + True if the particle system doesn't use new particle system features - + - Serialize the object + Decodes a byte[] array into a ParticleSystem Object - An containing the objects data + ParticleSystem object + Start position for BitPacker - + - Deserialize the message + Generate byte[] array from particle data - An containing the data + Byte array - - - Serialize the object - - An containing the objects data + + - + - Deserialize the message + Parameters used to construct a visual representation of a primitive - An containing the data - - - Serialize the object - - An containing the objects data + + - - - Deserialize the message - - An containing the data + + - - Key of sender + + - - Name of sender + + - - Key of destination avatar + + - - ID of originating estate + + - - Key of originating region + + - - Coordinates in originating region + + - - Instant message type + + - - Group IM session toggle + + - - Key of IM session, for Group Messages, the groups UUID + + - - Timestamp of the instant message + + - - Instant message text + + - - Whether this message is held for offline avatars + + - - Context specific packed data + + - - Is this invitation for voice group/conference chat + + - - - Serialize the object - - An containing the objects data + + - + + + + + + + + + + + + + + Attachment point to an avatar + + + + + + + + + + + + + + - Deserialize the message + Calculdates hash code for prim construction data - An containing the data + The has - + - Sent from the simulator to the viewer. - - When an agent initially joins a session the AgentUpdatesBlock object will contain a list of session members including - a boolean indicating they can use voice chat in this session, a boolean indicating they are allowed to moderate - this session, and lastly a string which indicates another agent is entering the session with the Transition set to "ENTER" - - During the session lifetime updates on individuals are sent. During the update the booleans sent during the initial join are - excluded with the exception of the Transition field. This indicates a new user entering or exiting the session with - the string "ENTER" or "LEAVE" respectively. + Information on the flexible properties of a primitive - + + + + + + + + + + + + + + + + + + + - Serialize the object + Default constructor - An containing the objects data - + - Deserialize the message + - An containing the data + + - + - An EventQueue message sent when the agent is forcibly removed from a chatterbox session + + - + - A string containing the reason the agent was removed + + - + - The ChatterBoxSession's SessionID + Information on the light properties of a primitive - - - Serialize the object - - An containing the objects data + + - - - Deserialize the message - - An containing the data + + - - - Serialize the object - - An containing the objects data + + - + + + + + + + - Deserialize the message + Default constructor - An containing the data - + - Serialize the object + - An containing the objects data + + - + - Deserialize the message + - An containing the data + - + - Serialize the object + - An containing the objects data + - + - Deserialize the message + Information on the light properties of a primitive as texture map - An containing the data - + + + + + + + - Serialize the object + Default constructor - An containing the objects data - + - Deserialize the message + - An containing the data + + - + + - + - Serialize the object + - An containing the objects data + - + - Deserialize the message + Information on the sculpt properties of a sculpted primitive - An containing the data - + - Serialize the object + Render inside out (inverts the normals). - An containing the objects data - + - Deserialize the message + Render an X axis mirror of the sculpty. - An containing the data - + - Serialize the object + Default constructor - An containing the objects data - + - Deserialize the message + - An containing the data + + - + - Event Queue message describing physics engine attributes of a list of objects - Sim sends these when object is selected + Extended properties to describe an object - - Array with the list of physics properties + + - - - Serializes the message - - Serialized OSD + + - - - Deseializes the message - - Incoming data to deserialize + + - - - A message sent from the viewer to the simulator which - specifies that the user has changed current URL - of the specific media on a prim face - + + - - - New URL - + + - - - Prim UUID where navigation occured - + + - - - Face index - + + - - - Serialize the object - - An containing the objects data + + - - - Deserialize the message - - An containing the data + + - - Base class used for the ObjectMedia message + + - - - Message used to retrive prim media data - + + - - - Prim UUID - + + - - - Requested operation, either GET or UPDATE - + + - - - Serialize object - - Serialized object as OSDMap + + - - - Deserialize the message - - An containing the data + + - - - Message used to update prim media data - + + - - - Prim UUID - + + - - - Array of media entries indexed by face number - + + - - - Media version string - + + - - - Serialize object - - Serialized object as OSDMap + + - - - Deserialize the message - - An containing the data + + - - - Message used to update prim media data - + + - - - Prim UUID - + + - + - Array of media entries indexed by face number + Default constructor - + - Requested operation, either GET or UPDATE + Set the properties that are set in an ObjectPropertiesFamily packet + that has + been partially filled by an ObjectPropertiesFamily packet - + - Serialize object + Describes physics attributes of the prim - Serialized object as OSDMap - - - Deserialize the message - - An containing the data + + Primitive's local ID - - - Message for setting or getting per face MediaEntry - + + Density (1000 for normal density) - - The request or response details block + + Friction - + + Gravity multiplier (1 for normal gravity) + + + Type of physics representation of this primitive in the simulator + + + Restitution + + - Serialize the object + Creates PhysicsProperties from OSD - An containing the objects data + OSDMap with incoming data + Deserialized PhysicsProperties object - + - Deserialize the message + Serializes PhysicsProperties to OSD - An containing the data + OSDMap with serialized PhysicsProperties data - - Details about object resource usage + + - - Object UUID + + - - Object name + + - - Indicates if object is group owned + + - - Locatio of the object + + - - Object owner + + - - Resource usage, keys are resource names, values are resource usage for that specific resource + + Foliage type for this primitive. Only applicable if this + primitive is foliage - - - Deserializes object from OSD - - An containing the data + + Unknown - - - Makes an instance based on deserialized data - - serialized data - Instance containg deserialized data + + - - Details about parcel resource usage + + - - Parcel UUID + + - - Parcel local ID + + - - Parcel name + + - - Indicates if parcel is group owned + + - - Parcel owner + + - - Array of containing per object resource usage + + - - - Deserializes object from OSD - - An containing the data + + - - - Makes an instance based on deserialized data - - serialized data - Instance containg deserialized data + + - - Resource usage base class, both agent and parcel resource - usage contains summary information + + - - Summary of available resources, keys are resource names, - values are resource usage for that specific resource + + - - Summary resource usage, keys are resource names, - values are resource usage for that specific resource + + - - - Serializes object - - serialized data + + Identifies the owner if audio or a particle system is + active - - - Deserializes object from OSD - - An containing the data + + - - Agent resource usage + + - - Per attachment point object resource usage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Objects physics engine propertis + + + Extra data about primitive + + + Indicates if prim is attached to an avatar + + + Number of clients referencing this prim + + + Uses basic heuristics to estimate the primitive shape + + + + Default constructor + - + - Deserializes object from OSD + Packs PathTwist, PathTwistBegin, PathRadiusOffset, and PathSkew + parameters in to signed eight bit values - An containing the data + Floating point parameter to pack + Signed eight bit value containing the packed parameter - + - Makes an instance based on deserialized data + Unpacks PathTwist, PathTwistBegin, PathRadiusOffset, and PathSkew + parameters from signed eight bit integers to floating point values - serialized data - Instance containg deserialized data + Signed eight bit value to unpack + Unpacked floating point value - + - Detects which class handles deserialization of this message + Texture animation mode - An containing the data - Object capable of decoding this message - - Request message for parcel resource usage + + Disable texture animation - - UUID of the parel to request resource usage info + + Enable texture animation - - - Serializes object - - serialized data + + Loop when animating textures - - - Deserializes object from OSD - - An containing the data + + Animate in reverse direction - - Response message for parcel resource usage + + Animate forward then reverse - - URL where parcel resource usage details can be retrieved + + Slide texture smoothly instead of frame-stepping - - URL where parcel resource usage summary can be retrieved + + Rotate texture instead of using frames - - - Serializes object - - serialized data + + Scale texture instead of using frames - + - Deserializes object from OSD + A single textured face. Don't instantiate this class yourself, use the + methods in TextureEntry - An containing the data - - - Detects which class handles deserialization of this message - - An containing the data - Object capable of decoding this message + + - - Parcel resource usage + + - - Array of containing per percal resource usage + + - - - Deserializes object from OSD - - An containing the data + + - - - Reply to request for bunch if display names - + + - - Current display name + + - - Following UUIDs failed to return a valid display name + + - - - Serializes the message - - OSD containting the messaage + + - - - Message sent when requesting change of the display name - + + - - Current display name + + - - Desired new display name + + In the future this will specify whether a webpage is + attached to this face - + + + + + + + - Serializes the message + Contains the definition for individual faces - OSD containting the messaage + - + - Message recieved in response to request to change display name + + - - New display name + + + Represents all of the texturable faces for an object + + Grid objects have infinite faces, with each face + using the properties of the default face unless set otherwise. So if + you have a TextureEntry with a default texture uuid of X, and face 18 + has a texture UUID of Y, every face would be textured with X except for + face 18 that uses Y. In practice however, primitives utilize a maximum + of nine faces - - String message indicating the result of the operation + + - - Numerical code of the result, 200 indicates success + + - + - Serializes the message + Constructor that takes a default texture UUID - OSD containting the messaage + Texture UUID to use as the default texture - + - Message recieved when someone nearby changes their display name + Constructor that takes a TextureEntryFace for the + default face + Face to use as the default face - - Previous display name, empty string if default - - - New display name - - + - Serializes the message + Constructor that creates the TextureEntry class from a byte array - OSD containting the messaage + Byte array containing the TextureEntry field + Starting position of the TextureEntry field in + the byte array + Length of the TextureEntry field, in bytes - + - Return a decoded capabilities message as a strongly typed object + This will either create a new face if a custom face for the given + index is not defined, or return the custom face for that index if + it already exists - A string containing the name of the capabilities message key - An to decode - A strongly typed object containing the decoded information from the capabilities message, or null - if no existing Message object exists for the specified event + The index number of the face to create or + retrieve + A TextureEntryFace containing all the properties for that + face - + - Permissions for control of object media + + + - + - Style of cotrols that shold be displayed to the user + + - + - Class representing media data for a single face + + - - Is display of the alternative image enabled - - - Should media auto loop - - - Shoule media be auto played - - - Auto scale media to prim face - - - Should viewer automatically zoom in on the face when clicked - - - Should viewer interpret first click as interaction with the media - or when false should the first click be treated as zoom in commadn - - - Style of controls viewer should display when - viewer media on this face + + + + + - - Starting URL for the media + + + Controls the texture animation of a particular prim + - - Currently navigated URL + + - - Media height in pixes + + - - Media width in pixels + + - - Who can controls the media + + - - Who can interact with the media + + - - Is URL whitelist enabled + + - - Array of URLs that are whitelisted + + - + - Serialize to OSD + - OSDMap with the serialized data + + - + - Deserialize from OSD data + - Serialized OSD data - Deserialized object + + + + + + + @@ -35768,29 +36160,6 @@ - - - Level of Detail mesh - - - - - Contains all mesh faces that belong to a prim - - - - List of primitive faces - - - - Decodes mesh asset into FacetedMesh - - Mesh primitive - Asset retrieved from the asset server - Level of detail - Resulting decoded FacetedMesh - True if mesh asset decoding was successful - This is used to login a specific user account(s). It may only be called after @@ -35930,6 +36299,16 @@ The level of the audio, a number between -100 and 100 where 0 represents ‘normal’ speaking volume + + + List of audio input devices + + + + + List of audio output devices + + Start up the Voice service. @@ -36003,6 +36382,11 @@ Handle response to audio input device query + + + Set audio test mode + + Set voice channel for new parcel @@ -36035,6 +36419,60 @@ + + Enable logging + + + The folder where any logs will be created + + + This will be prepended to beginning of each log file + + + The suffix or extension to be appended to each log file + + + + 0: NONE - No logging + 1: ERROR - Log errors only + 2: WARNING - Log errors and warnings + 3: INFO - Log errors, warnings and info + 4: DEBUG - Log errors, warnings, info and debug + + + + + Constructor for default logging settings + + + + Audio Properties Events are sent after audio capture is started. These events are used to display a microphone VU meter + + + + Event for most mundane request reposnses. + + + + Response to Connector.Create request + + + Response to Aux.GetCaptureDevices request + + + Response to Aux.GetRenderDevices request + + + Audio Properties Events are sent after audio capture is started. + These events are used to display a microphone VU meter + + + Response to Account.Login request + + + This event message is sent whenever the login state of the + particular Account has transitioned from one value to another + Starts a thread that keeps the daemon running @@ -36128,75 +36566,6 @@ The level of the audio, a number between -100 and 100 where 0 represents ‘normal’ speaking volume - - - List of audio input devices - - - - - List of audio output devices - - - - - Set audio test mode - - - - - Event for most mundane request reposnses. - - - - Response to Connector.Create request - - - Response to Aux.GetCaptureDevices request - - - Response to Aux.GetRenderDevices request - - - Audio Properties Events are sent after audio capture is started. - These events are used to display a microphone VU meter - - - Response to Account.Login request - - - This event message is sent whenever the login state of the - particular Account has transitioned from one value to another - - - Enable logging - - - The folder where any logs will be created - - - This will be prepended to beginning of each log file - - - The suffix or extension to be appended to each log file - - - - 0: NONE - No logging - 1: ERROR - Log errors only - 2: WARNING - Log errors and warnings - 3: INFO - Log errors, warnings and info - 4: DEBUG - Log errors, warnings, info and debug - - - - - Constructor for default logging settings - - - - Audio Properties Events are sent after audio capture is started. These events are used to display a microphone VU meter - Positional vector of the users position @@ -36236,5 +36605,52 @@ + + + + + + + + Delegate to wrap another delegate and its arguments + + + + + + + An instance of DelegateWrapper which calls InvokeWrappedDelegate, + which in turn calls the DynamicInvoke method of the wrapped + delegate + + + + + Callback used to call EndInvoke on the asynchronously + invoked DelegateWrapper + + + + + Executes the specified delegate with the specified arguments + asynchronously on a thread pool thread + + + + + + + Invokes the wrapped delegate synchronously + + + + + + + Calls EndInvoke on the wrapper and Close on the resulting WaitHandle + to prevent resource leaks + + + diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index 7a1bc0b..5c576a7 100755 Binary files a/bin/OpenMetaverse.dll and b/bin/OpenMetaverse.dll differ diff --git a/bin/OpenMetaverseTypes.XML b/bin/OpenMetaverseTypes.XML index a0c9135..3da5955 100644 --- a/bin/OpenMetaverseTypes.XML +++ b/bin/OpenMetaverseTypes.XML @@ -252,8 +252,7 @@ Link to a location in world - Collection of textures and parameters that can be - worn by an avatar + Collection of textures and parameters that can be worn by an avatar Primitive that can contain textures, sounds, @@ -263,10 +262,7 @@ Notecard asset - Holds a collection of inventory items - - - Root inventory folder + Holds a collection of inventory items. "Category" in the Linden viewer Linden scripting language script @@ -278,17 +274,7 @@ Uncompressed TGA texture - Collection of textures and shape parameters that can - be worn - - - Trash folder - - - Snapshot folder - - - Lost and found folder + Collection of textures and shape parameters that can be worn Uncompressed sound @@ -310,44 +296,109 @@ Simstate file - - Contains landmarks for favorites - Asset is a link to another inventory item Asset is a link to another inventory folder - - Beginning of the range reserved for ensembles + + Marketplace Folder. Same as an Category but different display methods. - - End of the range reserved for ensembles + + Linden mesh format - - Folder containing inventory links to wearables and attachments - that are part of the current outfit + + + The different types of folder. + - - Folder containing inventory items or links to - inventory items of wearables and attachments - together make a full outfit + + None folder type - - Root folder for the folders of type OutfitFolder + + Texture folder type - - Linden mesh format + + Sound folder type + + + Calling card folder type + + + Landmark folder type + + + Clothing folder type + + + Object folder type + + + Notecard folder type + + + The root folder type + + + LSLText folder + + + Bodyparts folder + + + Trash folder + + + Snapshot folder + + + Lost And Found folder - + + Animation folder + + + Gesture folder + + + Favorites folder + + + Ensemble beginning range + + + Ensemble ending range + + + Current outfit folder + + + Outfit folder + + + My outfits folder + + + Mesh folder + + Marketplace direct delivery inbox ("Received Items") - + Marketplace direct delivery outbox - - + + Basic root folder + + + Marketplace listings folder + + + Marketplace stock folder + + + Hypergrid Suitcase folder @@ -1071,6 +1122,27 @@ multiple writers + + + Provides a node container for data in a singly linked list + + + + Pointer to the next node in list + + + The data contained by the node + + + + Constructor + + + + + Constructor + + Queue head @@ -1080,6 +1152,11 @@ Queue item count + + Gets the current number of items in the queue. Since this + is a lockless collection this value should be treated as a close + estimate + Constructor @@ -1098,32 +1175,6 @@ Dequeued item if the dequeue was successful True if an item was successfully deqeued, otherwise false - - Gets the current number of items in the queue. Since this - is a lockless collection this value should be treated as a close - estimate - - - - Provides a node container for data in a singly linked list - - - - Pointer to the next node in list - - - The data contained by the node - - - - Constructor - - - - - Constructor - - Convert this matrix to euler rotations @@ -1334,6 +1385,37 @@ Time of the last drip, in system ticks + + + The parent bucket of this bucket, or null if this bucket has no + parent. The parent bucket will limit the aggregate bandwidth of all + of its children buckets + + + + + Maximum burst rate in bytes per second. This is the maximum number + of tokens that can accumulate in the bucket at any one time + + + + + The speed limit of this bucket in bytes per second. This is the + number of tokens that are added to the bucket per second + + Tokens are added to the bucket any time + is called, at the granularity of + the system tick interval (typically around 15-22ms) + + + + The number of bytes that can be sent at this moment. This is the + current number of tokens in the bucket + If this bucket has a parent bucket that does not have + enough tokens for a request, will + return false regardless of the content of this bucket + + Default constructor @@ -1371,37 +1453,37 @@ True if tokens were added to the bucket, otherwise false - + - The parent bucket of this bucket, or null if this bucket has no - parent. The parent bucket will limit the aggregate bandwidth of all - of its children buckets + Operating system - - - Maximum burst rate in bytes per second. This is the maximum number - of tokens that can accumulate in the bucket at any one time - + + Unknown - - - The speed limit of this bucket in bytes per second. This is the - number of tokens that are added to the bucket per second - - Tokens are added to the bucket any time - is called, at the granularity of - the system tick interval (typically around 15-22ms) + + Microsoft Windows - + + Microsoft Windows CE + + + Linux + + + Apple OSX + + - The number of bytes that can be sent at this moment. This is the - current number of tokens in the bucket - If this bucket has a parent bucket that does not have - enough tokens for a request, will - return false regardless of the content of this bucket + Runtime platform + + .NET runtime + + + Mono runtime: http://www.mono-project.com/ + Used for converting degrees to radians @@ -1842,6 +1924,20 @@ A string containing the AssetType name The AssetType which matches the string name, or AssetType.Unknown if no match was found + + + Takes a FolderType and returns the string representation + + The source + The string version of the FolderType + + + + Translate a string name of an FolderType into the proper Type + + A string containing the FolderType name + The FolderType which matches the string name, or FolderType. None if no match was found + Convert an InventoryType to a string @@ -1972,37 +2068,6 @@ Converted IP address object, or null if the conversion failed - - - Operating system - - - - Unknown - - - Microsoft Windows - - - Microsoft Windows CE - - - Linux - - - Apple OSX - - - - Runtime platform - - - - .NET runtime - - - Mono runtime: http://www.mono-project.com/ - A 128-bit Universally Unique Identifier, used throughout the Second diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index dd1ea6c..a07cc1d 100755 Binary files a/bin/OpenMetaverseTypes.dll and b/bin/OpenMetaverseTypes.dll differ diff --git a/bin/openmetaverse_data/avatar_skeleton.xml b/bin/openmetaverse_data/avatar_skeleton.xml new file mode 100644 index 0000000..6b07bbc --- /dev/null +++ b/bin/openmetaverse_data/avatar_skeleton.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.1 From f03a6bbc616c3c9ce8dadce6059cf7899ef91b9b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 2 Jan 2017 17:47:20 +0000 Subject: Create a generic way for passing constructor args to plugins The old syntax didn't allow for any parameters except for services listed in the ServiceList. Now, services loaded by other services can also be made to use different ini sections or have additional paramters. Syntax is: [@]...[:] --- OpenSim/Server/Base/ServerUtils.cs | 12 ++++++++++++ .../Connectors/Inventory/XInventoryServicesConnector.cs | 12 ++++++++++-- OpenSim/Services/LLLoginService/LLLoginService.cs | 9 +++++++-- bin/Robust.HG.ini.example | 5 +++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 18a4266..57d0a8d 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -242,6 +242,18 @@ namespace OpenSim.Server.Base className = parts[2]; } + // Handle extra string arguments in a more generic way + if (dllName.Contains("@")) + { + string[] dllNameParts = dllName.Split(new char[] {'@'}); + dllName = dllNameParts[dllNameParts.Length - 1]; + List argList = new List(args); + for (int i = 0 ; i < dllNameParts.Length - 1 ; ++i) + argList.Add(dllNameParts[i]); + + args = argList.ToArray(); + } + return LoadPlugin(dllName, className, args); } diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs index 2ddd7a2..bd5841b 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs @@ -63,6 +63,7 @@ namespace OpenSim.Services.Connectors /// In this case, -1 is default timeout (100 seconds), not infinite. /// private int m_requestTimeoutSecs = -1; + private string m_configName = "InventoryService"; private const double CACHE_EXPIRATION_SECONDS = 20.0; private static ExpiringCache m_ItemCache = new ExpiringCache(); @@ -76,6 +77,13 @@ namespace OpenSim.Services.Connectors m_ServerURI = serverURI.TrimEnd('/'); } + public XInventoryServicesConnector(IConfigSource source, string configName) + : base(source, configName) + { + m_configName = configName; + Initialise(source); + } + public XInventoryServicesConnector(IConfigSource source) : base(source, "InventoryService") { @@ -84,10 +92,10 @@ namespace OpenSim.Services.Connectors public virtual void Initialise(IConfigSource source) { - IConfig config = source.Configs["InventoryService"]; + IConfig config = source.Configs[m_configName]; if (config == null) { - m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + m_log.ErrorFormat("[INVENTORY CONNECTOR]: {0} missing from OpenSim.ini", m_configName); throw new Exception("Inventory connector init error"); } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 6d63959..5d69705 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -180,9 +180,14 @@ namespace OpenSim.Services.LLLoginService string hgInvServicePlugin = m_LoginServerConfig.GetString("HGInventoryServicePlugin", String.Empty); if (hgInvServicePlugin != string.Empty) { + // TODO: Remove HGInventoryServiceConstructorArg after 0.9 release string hgInvServiceArg = m_LoginServerConfig.GetString("HGInventoryServiceConstructorArg", String.Empty); - Object[] args2 = new Object[] { config, hgInvServiceArg }; - m_HGInventoryService = ServerUtils.LoadPlugin(hgInvServicePlugin, args2); + if (hgInvServiceArg != String.Empty) + { + m_log.Warn("[LLOGIN SERVICE]: You are using HGInventoryServiceConstructorArg, which is deprecated. See example file for correct syntax."); + hgInvServicePlugin = hgInvServiceArg + "@" + hgInvServicePlugin; + } + m_HGInventoryService = ServerUtils.LoadPlugin(hgInvServicePlugin, args); } // diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 20c0804..7d13d43 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -488,8 +488,9 @@ UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" ; This inventory service will be used to initialize the user's inventory - HGInventoryServicePlugin = "OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService" - HGInventoryServiceConstructorArg = "HGInventoryService" + HGInventoryServicePlugin = "HGInventoryService@OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService" + ; NOTE: HGInventoryServiceConstructorArg is deprecated. For now it will work, but see above + ; for the correct method if passing additional arguments. ;; end hypergrid ; Ask co-operative viewers to use a different currency name -- cgit v1.1 From 966e50d90c9ef9b5fde9830b6b0e90290eb2ea47 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 2 Jan 2017 19:30:40 +0000 Subject: Add the HGRemoteAssetService. Allows to use any asset service with HG --- .../HypergridService/HGRemoteAssetService.cs | 240 +++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 OpenSim/Services/HypergridService/HGRemoteAssetService.cs diff --git a/OpenSim/Services/HypergridService/HGRemoteAssetService.cs b/OpenSim/Services/HypergridService/HGRemoteAssetService.cs new file mode 100644 index 0000000..a53435b --- /dev/null +++ b/OpenSim/Services/HypergridService/HGRemoteAssetService.cs @@ -0,0 +1,240 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Xml; + +using Nini.Config; +using log4net; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Framework.Serialization.External; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Services.AssetService; + +namespace OpenSim.Services.HypergridService +{ + /// + /// Hypergrid asset service. It serves the IAssetService interface, + /// but implements it in ways that are appropriate for inter-grid + /// asset exchanges. + /// + public class HGRemoteAssetService : IAssetService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_HomeURL; + private IUserAccountService m_UserAccountService; + private IAssetService m_assetConnector; + + private UserAccountCache m_Cache; + + private AssetPermissions m_AssetPerms; + + public HGRemoteAssetService(IConfigSource config, string configName) + { + m_log.Debug("[HGRemoteAsset Service]: Starting"); + IConfig assetConfig = config.Configs[configName]; + if (assetConfig == null) + throw new Exception("No HGAssetService configuration"); + + Object[] args = new Object[] { config }; + + string assetConnectorDll = assetConfig.GetString("AssetConnector", String.Empty); + if (assetConnectorDll == String.Empty) + throw new Exception("Please specify AssetConnector in HGAssetService configuration"); + + m_assetConnector = ServerUtils.LoadPlugin(assetConnectorDll, args); + if (m_assetConnector == null) + throw new Exception(String.Format("Unable to create AssetConnector from {0}", assetConnectorDll)); + + string userAccountsDll = assetConfig.GetString("UserAccountsService", string.Empty); + if (userAccountsDll == string.Empty) + throw new Exception("Please specify UserAccountsService in HGAssetService configuration"); + + m_UserAccountService = ServerUtils.LoadPlugin(userAccountsDll, args); + if (m_UserAccountService == null) + throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); + + m_HomeURL = Util.GetConfigVarFromSections(config, "HomeURI", + new string[] { "Startup", "Hypergrid", configName }, string.Empty); + if (m_HomeURL == string.Empty) + throw new Exception("[HGAssetService] No HomeURI specified"); + + m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); + + // Permissions + m_AssetPerms = new AssetPermissions(assetConfig); + + } + + #region IAssetService overrides + public AssetBase Get(string id) + { + AssetBase asset = m_assetConnector.Get(id); + + if (asset == null) + return null; + + if (!m_AssetPerms.AllowedExport(asset.Type)) + return null; + + if (asset.Metadata.Type == (sbyte)AssetType.Object) + asset.Data = AdjustIdentifiers(asset.Data); + + AdjustIdentifiers(asset.Metadata); + + return asset; + } + + public AssetMetadata GetMetadata(string id) + { + AssetMetadata meta = m_assetConnector.GetMetadata(id); + + if (meta == null) + return null; + + AdjustIdentifiers(meta); + + return meta; + } + + public byte[] GetData(string id) + { + AssetBase asset = Get(id); + + if (asset == null) + return null; + + if (!m_AssetPerms.AllowedExport(asset.Type)) + return null; + + // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8) + // Fix bad assets before sending them elsewhere + if (asset.Type == (int)AssetType.Object && asset.Data != null) + { + string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data)); + asset.Data = Utils.StringToBytes(xml); + } + + return asset.Data; + } + + // public delegate void AssetRetrieved(string id, Object sender, AssetBase asset); + public virtual bool Get(string id, Object sender, AssetRetrieved handler) + { + return m_assetConnector.Get(id, sender, (i, s, asset) => + { + if (asset != null) + { + if (!m_AssetPerms.AllowedExport(asset.Type)) + { + asset = null; + } + else + { + if (asset.Metadata.Type == (sbyte)AssetType.Object) + asset.Data = AdjustIdentifiers(asset.Data); + + AdjustIdentifiers(asset.Metadata); + } + } + + handler(i, s, asset); + }); + } + + public string Store(AssetBase asset) + { + if (!m_AssetPerms.AllowedImport(asset.Type)) + return string.Empty; + + // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8) + // Fix bad assets before storing on this server + if (asset.Type == (int)AssetType.Object && asset.Data != null) + { + string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data)); + asset.Data = Utils.StringToBytes(xml); + } + + return m_assetConnector.Store(asset); + } + + public bool Delete(string id) + { + // NOGO + return false; + } + + #endregion + + protected void AdjustIdentifiers(AssetMetadata meta) + { + if (meta == null || m_Cache == null) + return; + + UserAccount creator = m_Cache.GetUser(meta.CreatorID); + if (creator != null) + meta.CreatorID = meta.CreatorID + ";" + m_HomeURL + "/" + creator.FirstName + " " + creator.LastName; + } + + // Only for Object + protected byte[] AdjustIdentifiers(byte[] data) + { + string xml = Utils.BytesToString(data); + + // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8) + // Fix bad assets before sending them elsewhere + xml = ExternalRepresentationUtils.SanitizeXml(xml); + + return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, "HGAssetService", m_HomeURL, m_Cache, UUID.Zero)); + } + + public AssetBase GetCached(string id) + { + return Get(id); + } + + public bool[] AssetsExist(string[] ids) + { + return m_assetConnector.AssetsExist(ids); + } + + public bool UpdateContent(string id, byte[] data) + { + // SO not happening!! + return false; + } + } + +} -- cgit v1.1