2006-10-21 02:52:28 +00:00
/ *
2015-11-06 19:40:28 +01:00
* Copyright ( c ) 2006 - 2016 , openmetaverse . co
2006-10-21 02:52:28 +00:00
* All rights reserved .
*
* - 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 .
2015-11-06 19:00:05 +01:00
* - Neither the name of the openmetaverse . co nor the names
2006-10-21 02:52:28 +00:00
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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 ;
2006-10-21 05:53:58 +00:00
using System.Collections.Generic ;
2022-10-10 16:08:14 -05:00
using System.Linq ;
2007-11-06 09:26:10 +00:00
using System.Threading ;
2022-11-04 07:13:09 -05:00
using System.Threading.Tasks ;
2008-07-21 21:12:59 +00:00
using OpenMetaverse.Packets ;
2010-03-07 19:58:06 +00:00
using OpenMetaverse.Http ;
using OpenMetaverse.StructuredData ;
2011-05-20 09:26:13 +00:00
using OpenMetaverse.Interfaces ;
2010-03-07 19:58:06 +00:00
using OpenMetaverse.Messages.Linden ;
2006-10-21 02:52:28 +00:00
2008-07-21 21:12:59 +00:00
namespace OpenMetaverse
2006-10-21 02:52:28 +00:00
{
2007-11-30 00:25:08 +00:00
#region Enums
/// <summary>
2008-08-24 05:06:51 +00:00
///
2007-11-30 00:25:08 +00:00
/// </summary>
2008-08-28 02:38:32 +00:00
public enum ReportType : uint
2007-11-30 00:25:08 +00:00
{
2008-08-28 02:38:32 +00:00
/// <summary>No report</summary>
2007-11-30 00:25:08 +00:00
None = 0 ,
2008-08-28 02:38:32 +00:00
/// <summary>Unknown report type</summary>
Unknown = 1 ,
/// <summary>Bug report</summary>
Bug = 2 ,
/// <summary>Complaint report</summary>
Complaint = 3 ,
/// <summary>Customer service report</summary>
CustomerServiceRequest = 4
2007-11-30 00:25:08 +00:00
}
/// <summary>
/// Bitflag field for ObjectUpdateCompressed data blocks, describing
/// which options are present for each object
/// </summary>
[Flags]
public enum CompressedFlags : uint
{
2009-05-25 19:00:28 +00:00
None = 0x00 ,
2009-03-10 18:40:11 +00:00
/// <summary>Unknown</summary>
2007-11-30 00:25:08 +00:00
ScratchPad = 0x01 ,
2009-03-10 18:40:11 +00:00
/// <summary>Whether the object has a TreeSpecies</summary>
2007-11-30 00:25:08 +00:00
Tree = 0x02 ,
/// <summary>Whether the object has floating text ala llSetText</summary>
HasText = 0x04 ,
/// <summary>Whether the object has an active particle system</summary>
HasParticles = 0x08 ,
/// <summary>Whether the object has sound attached to it</summary>
HasSound = 0x10 ,
/// <summary>Whether the object is attached to a root object or not</summary>
HasParent = 0x20 ,
/// <summary>Whether the object has texture animation settings</summary>
TextureAnimation = 0x40 ,
/// <summary>Whether the object has an angular velocity</summary>
HasAngularVelocity = 0x80 ,
/// <summary>Whether the object has a name value pairs string</summary>
HasNameValues = 0x100 ,
/// <summary>Whether the object has a Media URL set</summary>
2019-10-04 08:46:12 -05:00
MediaURL = 0x200 ,
/// <summary>Whether the object has, you guessed it, new particles</summary>
HasParticlesNew = 0x400
2007-11-30 00:25:08 +00:00
}
2008-07-18 05:31:57 +00:00
/// <summary>
/// Specific Flags for MultipleObjectUpdate requests
/// </summary>
[Flags]
public enum UpdateType : uint
{
/// <summary>None</summary>
None = 0x00 ,
2008-08-28 02:38:32 +00:00
/// <summary>Change position of prims</summary>
2008-07-18 05:31:57 +00:00
Position = 0x01 ,
2008-08-28 02:38:32 +00:00
/// <summary>Change rotation of prims</summary>
2008-07-18 05:31:57 +00:00
Rotation = 0x02 ,
2008-08-28 02:38:32 +00:00
/// <summary>Change size of prims</summary>
2008-07-18 05:31:57 +00:00
Scale = 0x04 ,
/// <summary>Perform operation on link set</summary>
Linked = 0x08 ,
2008-08-28 02:38:32 +00:00
/// <summary>Scale prims uniformly, same as selecing ctrl+shift in the
/// viewer. Used in conjunction with Scale</summary>
2008-07-18 05:31:57 +00:00
Uniform = 0x10
}
2009-06-08 09:59:30 +00:00
/// <summary>
/// Special values in PayPriceReply. If the price is not one of these
/// literal value of the price should be use
/// </summary>
public enum PayPriceType : int
{
/// <summary>
/// Indicates that this pay option should be hidden
/// </summary>
Hide = - 1 ,
2010-03-08 10:57:01 +00:00
2009-06-08 09:59:30 +00:00
/// <summary>
/// Indicates that this pay option should have the default value
/// </summary>
Default = - 2
}
2007-11-30 00:25:08 +00:00
#endregion Enums
#region Structs
2006-10-21 02:52:28 +00:00
/// <summary>
2007-01-30 12:47:47 +00:00
/// Contains the variables sent in an object update packet for objects.
/// Used to track position and movement of prims and avatars
2006-10-21 02:52:28 +00:00
/// </summary>
2009-10-27 07:01:48 +00:00
public struct ObjectMovementUpdate
2006-10-21 02:52:28 +00:00
{
/// <summary></summary>
2007-01-30 12:47:47 +00:00
public bool Avatar ;
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public Vector4 CollisionPlane ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
public byte State ;
/// <summary></summary>
2007-01-30 12:47:47 +00:00
public uint LocalID ;
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public Vector3 Position ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public Vector3 Velocity ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public Vector3 Acceleration ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public Quaternion Rotation ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public Vector3 AngularVelocity ;
2006-11-13 07:46:22 +00:00
/// <summary></summary>
2008-08-24 05:06:51 +00:00
public Primitive . TextureEntry Textures ;
2007-01-29 22:20:12 +00:00
}
2007-11-30 00:25:08 +00:00
#endregion Structs
2006-11-12 11:33:42 +00:00
/// <summary>
/// Handles all network traffic related to prims and avatar positions and
2006-10-21 02:52:28 +00:00
/// movement.
2006-11-12 11:33:42 +00:00
/// </summary>
public class ObjectManager
2006-10-21 02:52:28 +00:00
{
2007-11-06 09:26:10 +00:00
public const float HAVOK_TIMESTEP = 1.0f / 45.0f ;
2007-11-30 00:25:08 +00:00
#region Delegates
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region ObjectUpdate event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-27 07:01:48 +00:00
private EventHandler < PrimEventArgs > m_ObjectUpdate ;
2007-11-30 00:25:08 +00:00
2009-10-26 06:03:26 +00:00
/// <summary>Thread sync lock object</summary>
2009-10-27 07:01:48 +00:00
private readonly object m_ObjectUpdateLock = new object ( ) ;
2009-06-08 09:59:30 +00:00
2009-10-26 06:03:26 +00:00
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// A <see cref="Primitive"/>, Foliage or Attachment</summary>
/// <seealso cref="RequestObject"/>
/// <seealso cref="RequestObjects"/>
2009-10-27 07:01:48 +00:00
public event EventHandler < PrimEventArgs > ObjectUpdate
2009-10-26 06:03:26 +00:00
{
2009-10-27 07:01:48 +00:00
add { lock ( m_ObjectUpdateLock ) { m_ObjectUpdate + = value ; } }
remove { lock ( m_ObjectUpdateLock ) { m_ObjectUpdate - = value ; } }
2009-10-26 06:03:26 +00:00
}
2013-03-04 08:33:08 +01:00
#endregion ObjectUpdate event
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region ObjectProperties event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < ObjectPropertiesEventArgs > m_ObjectProperties ;
2007-01-29 22:20:12 +00:00
2009-10-26 06:03:26 +00:00
///<summary>Raises the ObjectProperties Event</summary>
/// <param name="e">A ObjectPropertiesEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnObjectProperties ( ObjectPropertiesEventArgs e )
{
EventHandler < ObjectPropertiesEventArgs > handler = m_ObjectProperties ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
2009-06-08 09:59:30 +00:00
2009-10-26 06:03:26 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ObjectPropertiesLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// additional <seea cref="Primitive"/> information</summary>
/// <seealso cref="SelectObject"/>
/// <seealso cref="SelectObjects"/>
2009-10-26 06:03:26 +00:00
public event EventHandler < ObjectPropertiesEventArgs > ObjectProperties
{
add { lock ( m_ObjectPropertiesLock ) { m_ObjectProperties + = value ; } }
remove { lock ( m_ObjectPropertiesLock ) { m_ObjectProperties - = value ; } }
}
2010-03-08 10:57:01 +00:00
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < ObjectPropertiesUpdatedEventArgs > m_ObjectPropertiesUpdated ;
///<summary>Raises the ObjectPropertiesUpdated Event</summary>
/// <param name="e">A ObjectPropertiesUpdatedEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnObjectPropertiesUpdated ( ObjectPropertiesUpdatedEventArgs e )
{
EventHandler < ObjectPropertiesUpdatedEventArgs > handler = m_ObjectPropertiesUpdated ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ObjectPropertiesUpdatedLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
2009-10-27 07:01:48 +00:00
/// Primitive.ObjectProperties for an object we are currently tracking</summary>
2009-10-26 06:03:26 +00:00
public event EventHandler < ObjectPropertiesUpdatedEventArgs > ObjectPropertiesUpdated
{
add { lock ( m_ObjectPropertiesUpdatedLock ) { m_ObjectPropertiesUpdated + = value ; } }
remove { lock ( m_ObjectPropertiesUpdatedLock ) { m_ObjectPropertiesUpdated - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion ObjectProperties event
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region ObjectPropertiesFamily event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < ObjectPropertiesFamilyEventArgs > m_ObjectPropertiesFamily ;
///<summary>Raises the ObjectPropertiesFamily Event</summary>
/// <param name="e">A ObjectPropertiesFamilyEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnObjectPropertiesFamily ( ObjectPropertiesFamilyEventArgs e )
{
EventHandler < ObjectPropertiesFamilyEventArgs > handler = m_ObjectPropertiesFamily ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ObjectPropertiesFamilyLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// additional <seea cref="Primitive"/> and <see cref="Avatar"/> details</summary>
/// <seealso cref="RequestObjectPropertiesFamily"/>
2009-10-26 06:03:26 +00:00
public event EventHandler < ObjectPropertiesFamilyEventArgs > ObjectPropertiesFamily
{
add { lock ( m_ObjectPropertiesFamilyLock ) { m_ObjectPropertiesFamily + = value ; } }
remove { lock ( m_ObjectPropertiesFamilyLock ) { m_ObjectPropertiesFamily - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion ObjectPropertiesFamily
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region AvatarUpdate event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-27 07:01:48 +00:00
private EventHandler < AvatarUpdateEventArgs > m_AvatarUpdate ;
2015-06-11 00:02:57 +02:00
private EventHandler < ParticleUpdateEventArgs > m_ParticleUpdate ;
2009-10-26 06:03:26 +00:00
2009-10-27 07:01:48 +00:00
///<summary>Raises the AvatarUpdate Event</summary>
/// <param name="e">A AvatarUpdateEventArgs object containing
2009-10-26 06:03:26 +00:00
/// the data sent from the simulator</param>
2009-10-27 07:01:48 +00:00
protected virtual void OnAvatarUpdate ( AvatarUpdateEventArgs e )
2009-10-26 06:03:26 +00:00
{
2009-10-27 07:01:48 +00:00
EventHandler < AvatarUpdateEventArgs > handler = m_AvatarUpdate ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
2015-06-11 00:02:57 +02:00
/// <summary>
/// Raises the ParticleUpdate Event
/// </summary>
/// <param name="e">A ParticleUpdateEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnParticleUpdate ( ParticleUpdateEventArgs e ) {
EventHandler < ParticleUpdateEventArgs > handler = m_ParticleUpdate ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2015-06-11 00:02:57 +02:00
}
2009-10-26 06:03:26 +00:00
/// <summary>Thread sync lock object</summary>
2009-10-27 07:01:48 +00:00
private readonly object m_AvatarUpdateLock = new object ( ) ;
2009-10-26 06:03:26 +00:00
2015-06-11 00:02:57 +02:00
private readonly object m_ParticleUpdateLock = new object ( ) ;
2009-10-26 06:03:26 +00:00
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// updated information for an <see cref="Avatar"/></summary>
2009-10-27 07:01:48 +00:00
public event EventHandler < AvatarUpdateEventArgs > AvatarUpdate
2009-10-26 06:03:26 +00:00
{
2009-10-27 07:01:48 +00:00
add { lock ( m_AvatarUpdateLock ) { m_AvatarUpdate + = value ; } }
remove { lock ( m_AvatarUpdateLock ) { m_AvatarUpdate - = value ; } }
2009-10-26 06:03:26 +00:00
}
2013-03-04 08:33:08 +01:00
#endregion AvatarUpdate event
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region TerseObjectUpdate event
2015-06-11 00:02:57 +02:00
public event EventHandler < ParticleUpdateEventArgs > ParticleUpdate {
add { lock ( m_ParticleUpdateLock ) { m_ParticleUpdate + = value ; } }
remove { lock ( m_ParticleUpdateLock ) { m_ParticleUpdate - = value ; } }
}
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-27 07:01:48 +00:00
private EventHandler < TerseObjectUpdateEventArgs > m_TerseObjectUpdate ;
2009-10-26 06:03:26 +00:00
/// <summary>Thread sync lock object</summary>
2009-10-27 07:01:48 +00:00
private readonly object m_TerseObjectUpdateLock = new object ( ) ;
2009-10-26 06:03:26 +00:00
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// <see cref="Primitive"/> and <see cref="Avatar"/> movement changes</summary>
2009-10-27 07:01:48 +00:00
public event EventHandler < TerseObjectUpdateEventArgs > TerseObjectUpdate
2009-10-26 06:03:26 +00:00
{
2009-10-27 07:01:48 +00:00
add { lock ( m_TerseObjectUpdateLock ) { m_TerseObjectUpdate + = value ; } }
remove { lock ( m_TerseObjectUpdateLock ) { m_TerseObjectUpdate - = value ; } }
2009-10-26 06:03:26 +00:00
}
2013-03-04 08:33:08 +01:00
#endregion TerseObjectUpdate event
2009-10-26 06:03:26 +00:00
2013-03-04 08:33:08 +01:00
#region ObjectDataBlockUpdate event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < ObjectDataBlockUpdateEventArgs > m_ObjectDataBlockUpdate ;
///<summary>Raises the ObjectDataBlockUpdate Event</summary>
/// <param name="e">A ObjectDataBlockUpdateEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnObjectDataBlockUpdate ( ObjectDataBlockUpdateEventArgs e )
{
EventHandler < ObjectDataBlockUpdateEventArgs > handler = m_ObjectDataBlockUpdate ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ObjectDataBlockUpdateLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// updates to an Objects DataBlock</summary>
2009-10-26 06:03:26 +00:00
public event EventHandler < ObjectDataBlockUpdateEventArgs > ObjectDataBlockUpdate
{
add { lock ( m_ObjectDataBlockUpdateLock ) { m_ObjectDataBlockUpdate + = value ; } }
remove { lock ( m_ObjectDataBlockUpdateLock ) { m_ObjectDataBlockUpdate - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion ObjectDataBlockUpdate event
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region KillObject event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < KillObjectEventArgs > m_KillObject ;
///<summary>Raises the KillObject Event</summary>
/// <param name="e">A KillObjectEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnKillObject ( KillObjectEventArgs e )
{
EventHandler < KillObjectEventArgs > handler = m_KillObject ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_KillObjectLock = new object ( ) ;
2009-10-30 00:53:19 +00:00
/// <summary>Raised when the simulator informs us an <see cref="Primitive"/>
/// or <see cref="Avatar"/> is no longer within view</summary>
2009-10-26 06:03:26 +00:00
public event EventHandler < KillObjectEventArgs > KillObject
{
add { lock ( m_KillObjectLock ) { m_KillObject + = value ; } }
remove { lock ( m_KillObjectLock ) { m_KillObject - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion KillObject event
2009-10-26 06:03:26 +00:00
2013-03-04 08:33:08 +01:00
#region KillObjects event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2013-03-04 08:33:08 +01:00
private EventHandler < KillObjectsEventArgs > m_KillObjects ;
///<summary>Raises the KillObjects Event</summary>
/// <param name="e">A KillObjectsEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnKillObjects ( KillObjectsEventArgs e )
{
EventHandler < KillObjectsEventArgs > handler = m_KillObjects ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2013-03-04 08:33:08 +01:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_KillObjectsLock = new object ( ) ;
/// <summary>Raised when the simulator informs us when a group of <see cref="Primitive"/>
/// or <see cref="Avatar"/> is no longer within view</summary>
public event EventHandler < KillObjectsEventArgs > KillObjects
{
add { lock ( m_KillObjectsLock ) { m_KillObjects + = value ; } }
remove { lock ( m_KillObjectsLock ) { m_KillObjects - = value ; } }
}
#endregion KillObjects event
#region AvatarSitChanged event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < AvatarSitChangedEventArgs > m_AvatarSitChanged ;
///<summary>Raises the AvatarSitChanged Event</summary>
/// <param name="e">A AvatarSitChangedEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnAvatarSitChanged ( AvatarSitChangedEventArgs e )
{
EventHandler < AvatarSitChangedEventArgs > handler = m_AvatarSitChanged ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_AvatarSitChangedLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// updated sit information for our <see cref="Avatar"/></summary>
2009-10-26 06:03:26 +00:00
public event EventHandler < AvatarSitChangedEventArgs > AvatarSitChanged
{
add { lock ( m_AvatarSitChangedLock ) { m_AvatarSitChanged + = value ; } }
remove { lock ( m_AvatarSitChangedLock ) { m_AvatarSitChanged - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion AvatarSitChanged event
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
#region PayPriceReply event
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2009-10-26 06:03:26 +00:00
private EventHandler < PayPriceReplyEventArgs > m_PayPriceReply ;
///<summary>Raises the PayPriceReply Event</summary>
/// <param name="e">A PayPriceReplyEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnPayPriceReply ( PayPriceReplyEventArgs e )
{
EventHandler < PayPriceReplyEventArgs > handler = m_PayPriceReply ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-26 06:03:26 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_PayPriceReplyLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
2009-10-30 00:53:19 +00:00
/// purchase price information for a <see cref="Primitive"/></summary>
2009-10-26 06:03:26 +00:00
public event EventHandler < PayPriceReplyEventArgs > PayPriceReply
{
add { lock ( m_PayPriceReplyLock ) { m_PayPriceReply + = value ; } }
remove { lock ( m_PayPriceReplyLock ) { m_PayPriceReply - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion PayPriceReply
2009-10-26 06:03:26 +00:00
2013-03-04 08:33:08 +01:00
#region PhysicsProperties event
2010-03-07 19:58:06 +00:00
/// <summary>
/// Callback for getting object media data via CAP
/// </summary>
/// <param name="success">Indicates if the operation was succesfull</param>
/// <param name="version">Object media version string</param>
/// <param name="faceMedia">Array indexed on prim face of media entry data</param>
public delegate void ObjectMediaCallback ( bool success , string version , MediaEntry [ ] faceMedia ) ;
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2011-05-20 09:26:13 +00:00
private EventHandler < PhysicsPropertiesEventArgs > m_PhysicsProperties ;
///<summary>Raises the PhysicsProperties Event</summary>
/// <param name="e">A PhysicsPropertiesEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnPhysicsProperties ( PhysicsPropertiesEventArgs e )
{
EventHandler < PhysicsPropertiesEventArgs > handler = m_PhysicsProperties ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2011-05-20 09:26:13 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_PhysicsPropertiesLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// additional <seea cref="Primitive"/> information</summary>
/// <seealso cref="SelectObject"/>
/// <seealso cref="SelectObjects"/>
public event EventHandler < PhysicsPropertiesEventArgs > PhysicsProperties
{
add { lock ( m_PhysicsPropertiesLock ) { m_PhysicsProperties + = value ; } }
remove { lock ( m_PhysicsPropertiesLock ) { m_PhysicsProperties - = value ; } }
}
2013-03-04 08:33:08 +01:00
#endregion PhysicsProperties event
2011-05-20 09:26:13 +00:00
2009-10-26 06:03:26 +00:00
#endregion Delegates
2007-01-29 22:20:12 +00:00
2008-07-21 21:12:59 +00:00
/// <summary>Reference to the GridClient object</summary>
protected GridClient Client ;
2007-11-06 09:26:10 +00:00
/// <summary>Does periodic dead reckoning calculation to convert
/// velocity and acceleration to new positions for objects</summary>
private Timer InterpolationTimer ;
2007-04-09 08:03:12 +00:00
2006-10-21 02:52:28 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Construct a new instance of the ObjectManager class
2006-10-21 02:52:28 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="client">A reference to the <see cref="GridClient"/> instance</param>
2009-10-26 06:03:26 +00:00
public ObjectManager ( GridClient client )
2006-10-21 02:52:28 +00:00
{
Client = client ;
2009-10-29 23:53:17 +00:00
2010-08-12 22:37:27 +00:00
Client . Network . RegisterCallback ( PacketType . ObjectUpdate , ObjectUpdateHandler , false ) ;
Client . Network . RegisterCallback ( PacketType . ImprovedTerseObjectUpdate , ImprovedTerseObjectUpdateHandler , false ) ;
2009-10-26 06:03:26 +00:00
Client . Network . RegisterCallback ( PacketType . ObjectUpdateCompressed , ObjectUpdateCompressedHandler ) ;
Client . Network . RegisterCallback ( PacketType . ObjectUpdateCached , ObjectUpdateCachedHandler ) ;
Client . Network . RegisterCallback ( PacketType . KillObject , KillObjectHandler ) ;
Client . Network . RegisterCallback ( PacketType . ObjectPropertiesFamily , ObjectPropertiesFamilyHandler ) ;
Client . Network . RegisterCallback ( PacketType . ObjectProperties , ObjectPropertiesHandler ) ;
Client . Network . RegisterCallback ( PacketType . PayPriceReply , PayPriceReplyHandler ) ;
2011-05-20 09:26:13 +00:00
Client . Network . RegisterEventCallback ( "ObjectPhysicsProperties" , ObjectPhysicsPropertiesHandler ) ;
2007-01-19 20:53:05 +00:00
}
2009-10-29 23:53:17 +00:00
#region Internal event handlers
2009-10-26 06:03:26 +00:00
private void Network_OnDisconnected ( NetworkManager . DisconnectType reason , string message )
2009-07-17 16:54:45 +00:00
{
if ( InterpolationTimer ! = null )
{
InterpolationTimer . Dispose ( ) ;
InterpolationTimer = null ;
}
}
2009-10-26 06:03:26 +00:00
private void Network_OnConnected ( object sender )
2009-07-17 16:54:45 +00:00
{
2009-07-22 00:47:53 +00:00
if ( Client . Settings . USE_INTERPOLATION_TIMER )
2009-07-17 16:54:45 +00:00
{
2024-08-28 16:19:39 -05:00
InterpolationTimer = new Timer ( InterpolationTimer_Elapsed , null , Client . Settings . INTERPOLATION_INTERVAL , Timeout . Infinite ) ;
2009-07-17 16:54:45 +00:00
}
}
2009-10-29 23:53:17 +00:00
#endregion Internal event handlers
#region Public Methods
2007-01-19 20:53:05 +00:00
2006-11-22 13:21:21 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Request information for a single object from a <see cref="Simulator"/>
/// you are currently connected to
2006-11-22 13:21:21 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
2006-10-21 02:52:28 +00:00
public void RequestObject ( Simulator simulator , uint localID )
{
RequestMultipleObjectsPacket request = new RequestMultipleObjectsPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2006-10-21 02:52:28 +00:00
request . ObjectData = new RequestMultipleObjectsPacket . ObjectDataBlock [ 1 ] ;
2006-10-27 10:40:04 +00:00
request . ObjectData [ 0 ] = new RequestMultipleObjectsPacket . ObjectDataBlock ( ) ;
2006-10-21 02:52:28 +00:00
request . ObjectData [ 0 ] . ID = localID ;
request . ObjectData [ 0 ] . CacheMissType = 0 ;
Client . Network . SendPacket ( request , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Request information for multiple objects contained in
/// the same simulator
2006-11-22 13:21:21 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the objects are located</param>
/// <param name="localIDs">An array containing the Local IDs of the objects</param>
2006-10-27 12:35:57 +00:00
public void RequestObjects ( Simulator simulator , List < uint > localIDs )
{
RequestMultipleObjectsPacket request = new RequestMultipleObjectsPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2006-10-27 12:35:57 +00:00
request . ObjectData = new RequestMultipleObjectsPacket . ObjectDataBlock [ localIDs . Count ] ;
2009-10-29 23:53:17 +00:00
for ( int i = 0 ; i < localIDs . Count ; i + + )
2006-10-27 12:35:57 +00:00
{
request . ObjectData [ i ] = new RequestMultipleObjectsPacket . ObjectDataBlock ( ) ;
2009-10-29 23:53:17 +00:00
request . ObjectData [ i ] . ID = localIDs [ i ] ;
2006-10-27 12:35:57 +00:00
request . ObjectData [ i ] . CacheMissType = 0 ;
}
Client . Network . SendPacket ( request , simulator ) ;
}
2007-02-15 22:13:44 +00:00
/// <summary>
/// Attempt to purchase an original object, a copy, or the contents of
/// an object
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
2007-02-15 22:13:44 +00:00
/// <param name="saleType">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</param>
/// <param name="price">Price of the object. This is used for
/// verification, if it does not match the actual price the purchase
/// will fail</param>
/// <param name="groupID">Group ID that will be associated with the new
/// purchase</param>
2008-05-04 11:01:48 +00:00
/// <param name="categoryID">Inventory folder UUID where the object or objects
/// purchased should be placed</param>
/// <example>
/// <code>
2009-10-29 23:53:17 +00:00
/// BuyObject(Client.Network.CurrentSim, 500, SaleType.Copy,
/// 100, UUID.Zero, Client.Self.InventoryRootFolderUUID);
2008-05-04 11:01:48 +00:00
/// </code>
///</example>
2009-03-18 19:31:39 +00:00
public void BuyObject ( Simulator simulator , uint localID , SaleType saleType , int price , UUID groupID ,
2008-07-25 05:15:05 +00:00
UUID categoryID )
2007-02-15 22:13:44 +00:00
{
ObjectBuyPacket buy = new ObjectBuyPacket ( ) ;
2007-11-06 09:26:10 +00:00
buy . AgentData . AgentID = Client . Self . AgentID ;
buy . AgentData . SessionID = Client . Self . SessionID ;
2007-02-15 22:13:44 +00:00
buy . AgentData . GroupID = groupID ;
buy . AgentData . CategoryID = categoryID ;
buy . ObjectData = new ObjectBuyPacket . ObjectDataBlock [ 1 ] ;
buy . ObjectData [ 0 ] = new ObjectBuyPacket . ObjectDataBlock ( ) ;
buy . ObjectData [ 0 ] . ObjectLocalID = localID ;
buy . ObjectData [ 0 ] . SaleType = ( byte ) saleType ;
buy . ObjectData [ 0 ] . SalePrice = price ;
Client . Network . SendPacket ( buy , simulator ) ;
}
2009-06-08 09:59:30 +00:00
/// <summary>
/// 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
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="objectID">The ID of the object</param>
/// <remarks>The result is raised in the <see cref="PayPriceReply"/> event</remarks>
2009-06-08 09:59:30 +00:00
public void RequestPayPrice ( Simulator simulator , UUID objectID )
{
RequestPayPricePacket payPriceRequest = new RequestPayPricePacket ( ) ;
2010-03-08 10:57:01 +00:00
2009-06-08 09:59:30 +00:00
payPriceRequest . ObjectData = new RequestPayPricePacket . ObjectDataBlock ( ) ;
payPriceRequest . ObjectData . ObjectID = objectID ;
Client . Network . SendPacket ( payPriceRequest , simulator ) ;
}
2009-10-29 23:53:17 +00:00
/// <summary>
/// Select a single object. This will cause the <see cref="Simulator"/> to send us
/// an <see cref="ObjectPropertiesPacket"/> which will raise the <see cref="ObjectProperties"/> event
/// </summary>
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
/// <seealso cref="ObjectPropertiesFamilyEventArgs"/>
public void SelectObject ( Simulator simulator , uint localID )
{
SelectObject ( simulator , localID , true ) ;
}
2009-06-08 09:59:30 +00:00
2007-02-15 22:13:44 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Select a single object. This will cause the <see cref="Simulator"/> to send us
/// an <see cref="ObjectPropertiesPacket"/> which will raise the <see cref="ObjectProperties"/> event
2007-02-15 22:13:44 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
/// <param name="automaticDeselect">if true, a call to <see cref="DeselectObject"/> is
/// made immediately following the request</param>
/// <seealso cref="ObjectPropertiesFamilyEventArgs"/>
2009-04-21 23:45:14 +00:00
public void SelectObject ( Simulator simulator , uint localID , bool automaticDeselect )
2007-02-15 22:13:44 +00:00
{
ObjectSelectPacket select = new ObjectSelectPacket ( ) ;
2007-11-06 09:26:10 +00:00
select . AgentData . AgentID = Client . Self . AgentID ;
select . AgentData . SessionID = Client . Self . SessionID ;
2007-02-15 22:13:44 +00:00
select . ObjectData = new ObjectSelectPacket . ObjectDataBlock [ 1 ] ;
select . ObjectData [ 0 ] = new ObjectSelectPacket . ObjectDataBlock ( ) ;
select . ObjectData [ 0 ] . ObjectLocalID = localID ;
Client . Network . SendPacket ( select , simulator ) ;
2009-10-29 23:53:17 +00:00
2009-04-21 23:45:14 +00:00
if ( automaticDeselect )
{
DeselectObject ( simulator , localID ) ;
}
}
/// <summary>
2009-10-29 23:53:17 +00:00
/// Select multiple objects. This will cause the <see cref="Simulator"/> to send us
/// an <see cref="ObjectPropertiesPacket"/> which will raise the <see cref="ObjectProperties"/> event
/// </summary>
/// <param name="simulator">The <see cref="Simulator"/> the objects are located</param>
/// <param name="localIDs">An array containing the Local IDs of the objects</param>
2009-04-21 23:45:14 +00:00
/// <param name="automaticDeselect">Should objects be deselected immediately after selection</param>
2009-10-29 23:53:17 +00:00
/// <seealso cref="ObjectPropertiesFamilyEventArgs"/>
2009-04-21 23:45:14 +00:00
public void SelectObjects ( Simulator simulator , uint [ ] localIDs , bool automaticDeselect )
2007-04-22 14:14:32 +00:00
{
ObjectSelectPacket select = new ObjectSelectPacket ( ) ;
2007-11-06 09:26:10 +00:00
select . AgentData . AgentID = Client . Self . AgentID ;
select . AgentData . SessionID = Client . Self . SessionID ;
2007-04-22 14:14:32 +00:00
select . ObjectData = new ObjectSelectPacket . ObjectDataBlock [ localIDs . Length ] ;
for ( int i = 0 ; i < localIDs . Length ; i + + )
{
select . ObjectData [ i ] = new ObjectSelectPacket . ObjectDataBlock ( ) ;
select . ObjectData [ i ] . ObjectLocalID = localIDs [ i ] ;
}
Client . Network . SendPacket ( select , simulator ) ;
2009-10-29 23:53:17 +00:00
2009-04-21 23:45:14 +00:00
if ( automaticDeselect )
{
DeselectObjects ( simulator , localIDs ) ;
}
}
/// <summary>
2009-10-29 23:53:17 +00:00
/// Select multiple objects. This will cause the <see cref="Simulator"/> to send us
/// an <see cref="ObjectPropertiesPacket"/> which will raise the <see cref="ObjectProperties"/> event
/// </summary>
/// <param name="simulator">The <see cref="Simulator"/> the objects are located</param>
/// <param name="localIDs">An array containing the Local IDs of the objects</param>
/// <seealso cref="ObjectPropertiesFamilyEventArgs"/>
2009-04-21 23:45:14 +00:00
public void SelectObjects ( Simulator simulator , uint [ ] localIDs )
{
SelectObjects ( simulator , localIDs , true ) ;
2007-04-22 14:14:32 +00:00
}
2008-11-09 20:29:04 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Update the properties of an object
2008-11-09 20:29:04 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
/// <param name="physical">true to turn the objects physical property on</param>
/// <param name="temporary">true to turn the objects temporary property on</param>
/// <param name="phantom">true to turn the objects phantom property on</param>
/// <param name="castsShadow">true to turn the objects cast shadows property on</param>
public void SetFlags ( Simulator simulator , uint localID , bool physical , bool temporary , bool phantom , bool castsShadow )
2011-05-20 17:21:45 +00:00
{
SetFlags ( simulator , localID , physical , temporary , phantom , castsShadow , PhysicsShapeType . Prim , 1000f , 0.6f , 0.5f , 1f ) ;
}
/// <summary>
/// Update the properties of an object
/// </summary>
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
/// <param name="physical">true to turn the objects physical property on</param>
/// <param name="temporary">true to turn the objects temporary property on</param>
/// <param name="phantom">true to turn the objects phantom property on</param>
/// <param name="castsShadow">true to turn the objects cast shadows property on</param>
/// <param name="physicsType">Type of the represetnation prim will have in the physics engine</param>
/// <param name="density">Density - normal value 1000</param>
/// <param name="friction">Friction - normal value 0.6</param>
/// <param name="restitution">Restitution - standard value 0.5</param>
/// <param name="gravityMultiplier">Gravity multiplier - standar value 1.0</param>
public void SetFlags ( Simulator simulator , uint localID , bool physical , bool temporary , bool phantom , bool castsShadow ,
PhysicsShapeType physicsType , float density , float friction , float restitution , float gravityMultiplier )
2008-11-09 20:29:04 +00:00
{
ObjectFlagUpdatePacket flags = new ObjectFlagUpdatePacket ( ) ;
flags . AgentData . AgentID = Client . Self . AgentID ;
flags . AgentData . SessionID = Client . Self . SessionID ;
flags . AgentData . ObjectLocalID = localID ;
flags . AgentData . UsePhysics = physical ;
flags . AgentData . IsTemporary = temporary ;
flags . AgentData . IsPhantom = phantom ;
flags . AgentData . CastsShadows = castsShadow ;
2010-03-08 10:57:01 +00:00
2011-05-20 17:21:45 +00:00
flags . ExtraPhysics = new ObjectFlagUpdatePacket . ExtraPhysicsBlock [ 1 ] ;
flags . ExtraPhysics [ 0 ] = new ObjectFlagUpdatePacket . ExtraPhysicsBlock ( ) ;
flags . ExtraPhysics [ 0 ] . PhysicsShapeType = ( byte ) physicsType ;
flags . ExtraPhysics [ 0 ] . Density = density ;
flags . ExtraPhysics [ 0 ] . Friction = friction ;
flags . ExtraPhysics [ 0 ] . Restitution = restitution ;
flags . ExtraPhysics [ 0 ] . GravityMultiplier = gravityMultiplier ;
2009-10-29 23:53:17 +00:00
Client . Network . SendPacket ( flags , simulator ) ;
2008-11-09 20:29:04 +00:00
}
2008-11-09 18:51:38 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Sets the sale properties of a single object
2008-11-09 18:51:38 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
/// <param name="saleType">One of the options from the <see cref="SaleType"/> enum</param>
/// <param name="price">The price of the object</param>
public void SetSaleInfo ( Simulator simulator , uint localID , SaleType saleType , int price )
2008-11-09 18:51:38 +00:00
{
ObjectSaleInfoPacket sale = new ObjectSaleInfoPacket ( ) ;
sale . AgentData . AgentID = Client . Self . AgentID ;
sale . AgentData . SessionID = Client . Self . SessionID ;
sale . ObjectData = new ObjectSaleInfoPacket . ObjectDataBlock [ 1 ] ;
sale . ObjectData [ 0 ] = new ObjectSaleInfoPacket . ObjectDataBlock ( ) ;
sale . ObjectData [ 0 ] . LocalID = localID ;
sale . ObjectData [ 0 ] . SalePrice = price ;
sale . ObjectData [ 0 ] . SaleType = ( byte ) saleType ;
2009-10-29 23:53:17 +00:00
Client . Network . SendPacket ( sale , simulator ) ;
2008-11-09 18:51:38 +00:00
}
/// <summary>
2009-10-29 23:53:17 +00:00
/// Sets the sale properties of multiple objects
/// </summary>
/// <param name="simulator">The <see cref="Simulator"/> the objects are located</param>
/// <param name="localIDs">An array containing the Local IDs of the objects</param>
/// <param name="saleType">One of the options from the <see cref="SaleType"/> enum</param>
/// <param name="price">The price of the object</param>
public void SetSaleInfo ( Simulator simulator , List < uint > localIDs , SaleType saleType , int price )
2008-11-09 18:51:38 +00:00
{
ObjectSaleInfoPacket sale = new ObjectSaleInfoPacket ( ) ;
sale . AgentData . AgentID = Client . Self . AgentID ;
sale . AgentData . SessionID = Client . Self . SessionID ;
sale . ObjectData = new ObjectSaleInfoPacket . ObjectDataBlock [ localIDs . Count ] ;
2009-10-29 23:53:17 +00:00
2008-11-09 18:51:38 +00:00
for ( int i = 0 ; i < localIDs . Count ; i + + )
{
sale . ObjectData [ i ] = new ObjectSaleInfoPacket . ObjectDataBlock ( ) ;
sale . ObjectData [ i ] . LocalID = localIDs [ i ] ;
sale . ObjectData [ i ] . SalePrice = price ;
sale . ObjectData [ i ] . SaleType = ( byte ) saleType ;
}
2009-10-29 23:53:17 +00:00
Client . Network . SendPacket ( sale , simulator ) ;
2008-11-09 18:51:38 +00:00
}
2008-05-04 11:01:48 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Deselect a single object
2008-05-04 11:01:48 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
2007-07-08 04:35:04 +00:00
public void DeselectObject ( Simulator simulator , uint localID )
{
ObjectDeselectPacket deselect = new ObjectDeselectPacket ( ) ;
2007-11-06 09:26:10 +00:00
deselect . AgentData . AgentID = Client . Self . AgentID ;
deselect . AgentData . SessionID = Client . Self . SessionID ;
2007-07-08 04:35:04 +00:00
deselect . ObjectData = new ObjectDeselectPacket . ObjectDataBlock [ 1 ] ;
deselect . ObjectData [ 0 ] = new ObjectDeselectPacket . ObjectDataBlock ( ) ;
deselect . ObjectData [ 0 ] . ObjectLocalID = localID ;
Client . Network . SendPacket ( deselect , simulator ) ;
}
2008-07-26 09:18:52 +00:00
/// <summary>
/// Deselect multiple objects.
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the objects are located</param>
/// <param name="localIDs">An array containing the Local IDs of the objects</param>
2008-07-26 09:18:52 +00:00
public void DeselectObjects ( Simulator simulator , uint [ ] localIDs )
{
ObjectDeselectPacket deselect = new ObjectDeselectPacket ( ) ;
deselect . AgentData . AgentID = Client . Self . AgentID ;
deselect . AgentData . SessionID = Client . Self . SessionID ;
deselect . ObjectData = new ObjectDeselectPacket . ObjectDataBlock [ localIDs . Length ] ;
for ( int i = 0 ; i < localIDs . Length ; i + + )
{
deselect . ObjectData [ i ] = new ObjectDeselectPacket . ObjectDataBlock ( ) ;
deselect . ObjectData [ i ] . ObjectLocalID = localIDs [ i ] ;
}
Client . Network . SendPacket ( deselect , simulator ) ;
}
2007-02-17 01:41:12 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Perform a click action on an object
2007-02-17 01:41:12 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
2007-02-17 01:41:12 +00:00
public void ClickObject ( Simulator simulator , uint localID )
2009-06-27 22:37:17 +00:00
{
ClickObject ( simulator , localID , Vector3 . Zero , Vector3 . Zero , 0 , Vector3 . Zero , Vector3 . Zero , Vector3 . Zero ) ;
}
/// <summary>
2009-10-29 23:53:17 +00:00
/// Perform a click action (Grab) on a single object
2009-06-27 22:37:17 +00:00
/// </summary>
2009-10-29 23:53:17 +00:00
/// <param name="simulator">The <see cref="Simulator"/> the object is located</param>
/// <param name="localID">The Local ID of the object</param>
2009-11-03 05:32:49 +00:00
/// <param name="uvCoord">The texture coordinates to touch</param>
/// <param name="stCoord">The surface coordinates to touch</param>
/// <param name="faceIndex">The face of the position to touch</param>
/// <param name="position">The region coordinates of the position to touch</param>
/// <param name="normal">The surface normal of the position to touch (A normal is a vector perpindicular to the surface)</param>
/// <param name="binormal">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</param>
2009-06-27 22:37:17 +00:00
public void ClickObject ( Simulator simulator , uint localID , Vector3 uvCoord , Vector3 stCoord , int faceIndex , Vector3 position ,
Vector3 normal , Vector3 binormal )
2007-02-17 01:41:12 +00:00
{
ObjectGrabPacket grab = new ObjectGrabPacket ( ) ;
2007-11-06 09:26:10 +00:00
grab . AgentData . AgentID = Client . Self . AgentID ;
grab . AgentData . SessionID = Client . Self . SessionID ;
2008-07-25 05:15:05 +00:00
grab . ObjectData . GrabOffset = Vector3 . Zero ;
2007-02-17 01:41:12 +00:00
grab . ObjectData . LocalID = localID ;
2009-06-27 22:37:17 +00:00
grab . SurfaceInfo = new ObjectGrabPacket . SurfaceInfoBlock [ 1 ] ;
grab . SurfaceInfo [ 0 ] = new ObjectGrabPacket . SurfaceInfoBlock ( ) ;
grab . SurfaceInfo [ 0 ] . UVCoord = uvCoord ;
grab . SurfaceInfo [ 0 ] . STCoord = stCoord ;
grab . SurfaceInfo [ 0 ] . FaceIndex = faceIndex ;
grab . SurfaceInfo [ 0 ] . Position = position ;
grab . SurfaceInfo [ 0 ] . Normal = normal ;
grab . SurfaceInfo [ 0 ] . Binormal = binormal ;
2007-02-17 01:41:12 +00:00
Client . Network . SendPacket ( grab , simulator ) ;
// TODO: If these hit the server out of order the click will fail
// and we'll be grabbing the object
2009-06-27 22:37:17 +00:00
Thread . Sleep ( 50 ) ;
2007-02-17 01:41:12 +00:00
ObjectDeGrabPacket degrab = new ObjectDeGrabPacket ( ) ;
2007-11-06 09:26:10 +00:00
degrab . AgentData . AgentID = Client . Self . AgentID ;
degrab . AgentData . SessionID = Client . Self . SessionID ;
2007-02-17 01:41:12 +00:00
degrab . ObjectData . LocalID = localID ;
2009-06-27 22:37:17 +00:00
degrab . SurfaceInfo = new ObjectDeGrabPacket . SurfaceInfoBlock [ 1 ] ;
degrab . SurfaceInfo [ 0 ] = new ObjectDeGrabPacket . SurfaceInfoBlock ( ) ;
degrab . SurfaceInfo [ 0 ] . UVCoord = uvCoord ;
degrab . SurfaceInfo [ 0 ] . STCoord = stCoord ;
degrab . SurfaceInfo [ 0 ] . FaceIndex = faceIndex ;
degrab . SurfaceInfo [ 0 ] . Position = position ;
degrab . SurfaceInfo [ 0 ] . Normal = normal ;
degrab . SurfaceInfo [ 0 ] . Binormal = binormal ;
2007-02-17 01:41:12 +00:00
Client . Network . SendPacket ( degrab , simulator ) ;
}
2009-10-29 23:53:17 +00:00
/// <summary>
/// Create (rez) a new prim object in a simulator
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object to place the object in</param>
2007-01-30 12:47:47 +00:00
/// <param name="prim">Data describing the prim object to rez</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupID">Group ID that this prim will be set to, or UUID.Zero if you
2008-05-04 11:01:48 +00:00
/// do not want the object to be associated with a specific group</param>
2006-12-11 09:36:52 +00:00
/// <param name="position">An approximation of the position at which to rez the prim</param>
2007-01-30 12:47:47 +00:00
/// <param name="scale">Scale vector to size this prim</param>
/// <param name="rotation">Rotation quaternion to rotate this prim</param>
2006-11-22 13:21:21 +00:00
/// <remarks>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
2007-04-25 19:58:58 +00:00
/// 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</remarks>
2009-03-18 19:31:39 +00:00
public void AddPrim ( Simulator simulator , Primitive . ConstructionData prim , UUID groupID , Vector3 position ,
2008-07-25 05:15:05 +00:00
Vector3 scale , Quaternion rotation )
2009-03-31 19:23:27 +00:00
{
AddPrim ( simulator , prim , groupID , position , scale , rotation , PrimFlags . CreateSelected ) ;
}
/// <summary>
2009-10-29 23:53:17 +00:00
/// Create (rez) a new prim object in a simulator
2009-03-31 19:23:27 +00:00
/// </summary>
2009-11-03 05:32:49 +00:00
/// <param name="simulator">A reference to the <seealso cref="Simulator"/> object to place the object in</param>
2009-03-31 19:23:27 +00:00
/// <param name="prim">Data describing the prim object to rez</param>
/// <param name="groupID">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</param>
/// <param name="position">An approximation of the position at which to rez the prim</param>
/// <param name="scale">Scale vector to size this prim</param>
/// <param name="rotation">Rotation quaternion to rotate this prim</param>
/// <param name="createFlags">Specify the <seealso cref="PrimFlags"/></param>
/// <remarks>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</remarks>
public void AddPrim ( Simulator simulator , Primitive . ConstructionData prim , UUID groupID , Vector3 position ,
Vector3 scale , Quaternion rotation , PrimFlags createFlags )
2006-11-10 09:50:54 +00:00
{
ObjectAddPacket packet = new ObjectAddPacket ( ) ;
2007-11-06 09:26:10 +00:00
packet . AgentData . AgentID = Client . Self . AgentID ;
packet . AgentData . SessionID = Client . Self . SessionID ;
2007-01-30 12:47:47 +00:00
packet . AgentData . GroupID = groupID ;
2006-11-10 09:50:54 +00:00
2007-11-30 00:25:08 +00:00
packet . ObjectData . State = prim . State ;
2009-03-31 19:23:27 +00:00
packet . ObjectData . AddFlags = ( uint ) createFlags ;
2006-11-10 09:50:54 +00:00
packet . ObjectData . PCode = ( byte ) PCode . Prim ;
packet . ObjectData . Material = ( byte ) prim . Material ;
2007-01-30 12:47:47 +00:00
packet . ObjectData . Scale = scale ;
packet . ObjectData . Rotation = rotation ;
2006-11-10 09:50:54 +00:00
packet . ObjectData . PathCurve = ( byte ) prim . PathCurve ;
2008-08-24 05:06:51 +00:00
packet . ObjectData . PathBegin = Primitive . PackBeginCut ( prim . PathBegin ) ;
packet . ObjectData . PathEnd = Primitive . PackEndCut ( prim . PathEnd ) ;
packet . ObjectData . PathRadiusOffset = Primitive . PackPathTwist ( prim . PathRadiusOffset ) ;
packet . ObjectData . PathRevolutions = Primitive . PackPathRevolutions ( prim . PathRevolutions ) ;
packet . ObjectData . PathScaleX = Primitive . PackPathScale ( prim . PathScaleX ) ;
packet . ObjectData . PathScaleY = Primitive . PackPathScale ( prim . PathScaleY ) ;
packet . ObjectData . PathShearX = ( byte ) Primitive . PackPathShear ( prim . PathShearX ) ;
packet . ObjectData . PathShearY = ( byte ) Primitive . PackPathShear ( prim . PathShearY ) ;
packet . ObjectData . PathSkew = Primitive . PackPathTwist ( prim . PathSkew ) ;
packet . ObjectData . PathTaperX = Primitive . PackPathTaper ( prim . PathTaperX ) ;
packet . ObjectData . PathTaperY = Primitive . PackPathTaper ( prim . PathTaperY ) ;
packet . ObjectData . PathTwist = Primitive . PackPathTwist ( prim . PathTwist ) ;
packet . ObjectData . PathTwistBegin = Primitive . PackPathTwist ( prim . PathTwistBegin ) ;
2006-11-10 09:50:54 +00:00
2007-12-30 00:06:25 +00:00
packet . ObjectData . ProfileCurve = prim . profileCurve ;
2008-08-24 05:06:51 +00:00
packet . ObjectData . ProfileBegin = Primitive . PackBeginCut ( prim . ProfileBegin ) ;
packet . ObjectData . ProfileEnd = Primitive . PackEndCut ( prim . ProfileEnd ) ;
packet . ObjectData . ProfileHollow = Primitive . PackProfileHollow ( prim . ProfileHollow ) ;
2006-11-10 09:50:54 +00:00
2006-11-22 13:21:21 +00:00
packet . ObjectData . RayStart = position ;
packet . ObjectData . RayEnd = position ;
2006-11-10 09:50:54 +00:00
packet . ObjectData . RayEndIsIntersection = 0 ;
2008-07-25 05:15:05 +00:00
packet . ObjectData . RayTargetID = UUID . Zero ;
2006-11-10 09:50:54 +00:00
packet . ObjectData . BypassRaycast = 1 ;
Client . Network . SendPacket ( packet , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Rez a Linden tree
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="scale">The size of the tree</param>
/// <param name="rotation">The rotation of the tree</param>
/// <param name="position">The position of the tree</param>
/// <param name="treeType">The Type of tree</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupOwner">The <seealso cref="UUID"/> of the group to set the tree to,
/// or UUID.Zero if no group is to be set</param>
2008-05-04 11:01:48 +00:00
/// <param name="newTree">true to use the "new" Linden trees, false to use the old</param>
2009-03-18 19:31:39 +00:00
public void AddTree ( Simulator simulator , Vector3 scale , Quaternion rotation , Vector3 position ,
2008-07-25 05:15:05 +00:00
Tree treeType , UUID groupOwner , bool newTree )
2006-11-13 05:36:52 +00:00
{
ObjectAddPacket add = new ObjectAddPacket ( ) ;
2007-11-06 09:26:10 +00:00
add . AgentData . AgentID = Client . Self . AgentID ;
add . AgentData . SessionID = Client . Self . SessionID ;
2006-11-13 05:36:52 +00:00
add . AgentData . GroupID = groupOwner ;
add . ObjectData . BypassRaycast = 1 ;
add . ObjectData . Material = 3 ;
add . ObjectData . PathCurve = 16 ;
add . ObjectData . PCode = newTree ? ( byte ) PCode . NewTree : ( byte ) PCode . Tree ;
add . ObjectData . RayEnd = position ;
add . ObjectData . RayStart = position ;
2008-07-25 05:15:05 +00:00
add . ObjectData . RayTargetID = UUID . Zero ;
2006-11-13 05:36:52 +00:00
add . ObjectData . Rotation = rotation ;
add . ObjectData . Scale = scale ;
add . ObjectData . State = ( byte ) treeType ;
Client . Network . SendPacket ( add , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Rez grass and ground cover
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="scale">The size of the grass</param>
/// <param name="rotation">The rotation of the grass</param>
/// <param name="position">The position of the grass</param>
/// <param name="grassType">The type of grass from the <seealso cref="Grass"/> enum</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupOwner">The <seealso cref="UUID"/> of the group to set the tree to,
/// or UUID.Zero if no group is to be set</param>
2008-07-25 05:15:05 +00:00
public void AddGrass ( Simulator simulator , Vector3 scale , Quaternion rotation , Vector3 position ,
Grass grassType , UUID groupOwner )
2006-11-13 05:36:52 +00:00
{
ObjectAddPacket add = new ObjectAddPacket ( ) ;
2007-11-06 09:26:10 +00:00
add . AgentData . AgentID = Client . Self . AgentID ;
add . AgentData . SessionID = Client . Self . SessionID ;
2006-11-13 05:36:52 +00:00
add . AgentData . GroupID = groupOwner ;
add . ObjectData . BypassRaycast = 1 ;
add . ObjectData . Material = 3 ;
add . ObjectData . PathCurve = 16 ;
add . ObjectData . PCode = ( byte ) PCode . Grass ;
add . ObjectData . RayEnd = position ;
add . ObjectData . RayStart = position ;
2008-07-25 05:15:05 +00:00
add . ObjectData . RayTargetID = UUID . Zero ;
2006-11-13 05:36:52 +00:00
add . ObjectData . Rotation = rotation ;
add . ObjectData . Scale = scale ;
add . ObjectData . State = ( byte ) grassType ;
Client . Network . SendPacket ( add , simulator ) ;
}
2006-12-09 07:55:46 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the textures to apply to the faces of an object
2006-12-09 07:55:46 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="textures">The texture data to apply</param>
2008-08-24 05:06:51 +00:00
public void SetTextures ( Simulator simulator , uint localID , Primitive . TextureEntry textures )
2006-12-09 14:39:17 +00:00
{
2024-06-30 17:47:14 -05:00
SetTextures ( simulator , localID , textures , string . Empty ) ;
2006-12-09 14:39:17 +00:00
}
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the textures to apply to the faces of an object
2006-12-09 14:39:17 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="textures">The texture data to apply</param>
/// <param name="mediaUrl">A media URL (not used)</param>
2008-08-24 05:06:51 +00:00
public void SetTextures ( Simulator simulator , uint localID , Primitive . TextureEntry textures , string mediaUrl )
2006-12-09 07:55:46 +00:00
{
ObjectImagePacket image = new ObjectImagePacket ( ) ;
2006-12-09 14:39:17 +00:00
2007-11-06 09:26:10 +00:00
image . AgentData . AgentID = Client . Self . AgentID ;
image . AgentData . SessionID = Client . Self . SessionID ;
2006-12-09 07:55:46 +00:00
image . ObjectData = new ObjectImagePacket . ObjectDataBlock [ 1 ] ;
image . ObjectData [ 0 ] = new ObjectImagePacket . ObjectDataBlock ( ) ;
image . ObjectData [ 0 ] . ObjectLocalID = localID ;
2009-03-10 01:54:45 +00:00
image . ObjectData [ 0 ] . TextureEntry = textures . GetBytes ( ) ;
2008-08-12 22:38:02 +00:00
image . ObjectData [ 0 ] . MediaURL = Utils . StringToBytes ( mediaUrl ) ;
2006-12-09 07:55:46 +00:00
Client . Network . SendPacket ( image , simulator ) ;
}
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the Light data on an object
2006-12-09 07:55:46 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="light">A <seealso cref="Primitive.LightData"/> object containing the data to set</param>
2007-01-29 22:20:12 +00:00
public void SetLight ( Simulator simulator , uint localID , Primitive . LightData light )
2006-12-09 07:55:46 +00:00
{
ObjectExtraParamsPacket extra = new ObjectExtraParamsPacket ( ) ;
2007-11-06 09:26:10 +00:00
extra . AgentData . AgentID = Client . Self . AgentID ;
extra . AgentData . SessionID = Client . Self . SessionID ;
2006-12-09 07:55:46 +00:00
extra . ObjectData = new ObjectExtraParamsPacket . ObjectDataBlock [ 1 ] ;
extra . ObjectData [ 0 ] = new ObjectExtraParamsPacket . ObjectDataBlock ( ) ;
extra . ObjectData [ 0 ] . ObjectLocalID = localID ;
2008-08-24 05:06:51 +00:00
extra . ObjectData [ 0 ] . ParamType = ( byte ) ExtraParamType . Light ;
2009-03-18 19:31:39 +00:00
if ( light . Intensity = = 0.0f )
2008-07-20 23:22:39 +00:00
{
// Disables the light if intensity is 0
extra . ObjectData [ 0 ] . ParamInUse = false ;
2009-03-18 19:31:39 +00:00
}
else
2008-07-20 23:22:39 +00:00
{
extra . ObjectData [ 0 ] . ParamInUse = true ;
}
2007-07-08 04:35:04 +00:00
extra . ObjectData [ 0 ] . ParamData = light . GetBytes ( ) ;
2006-12-09 07:55:46 +00:00
extra . ObjectData [ 0 ] . ParamSize = ( uint ) extra . ObjectData [ 0 ] . ParamData . Length ;
Client . Network . SendPacket ( extra , simulator ) ;
}
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the flexible data on an object
2006-12-09 07:55:46 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="flexible">A <seealso cref="Primitive.FlexibleData"/> object containing the data to set</param>
2007-01-29 22:20:12 +00:00
public void SetFlexible ( Simulator simulator , uint localID , Primitive . FlexibleData flexible )
2006-12-09 07:55:46 +00:00
{
ObjectExtraParamsPacket extra = new ObjectExtraParamsPacket ( ) ;
2007-11-06 09:26:10 +00:00
extra . AgentData . AgentID = Client . Self . AgentID ;
extra . AgentData . SessionID = Client . Self . SessionID ;
2006-12-09 07:55:46 +00:00
extra . ObjectData = new ObjectExtraParamsPacket . ObjectDataBlock [ 1 ] ;
extra . ObjectData [ 0 ] = new ObjectExtraParamsPacket . ObjectDataBlock ( ) ;
extra . ObjectData [ 0 ] . ObjectLocalID = localID ;
2008-08-24 05:06:51 +00:00
extra . ObjectData [ 0 ] . ParamType = ( byte ) ExtraParamType . Flexible ;
2007-07-08 04:35:04 +00:00
extra . ObjectData [ 0 ] . ParamInUse = true ;
extra . ObjectData [ 0 ] . ParamData = flexible . GetBytes ( ) ;
extra . ObjectData [ 0 ] . ParamSize = ( uint ) extra . ObjectData [ 0 ] . ParamData . Length ;
Client . Network . SendPacket ( extra , simulator ) ;
}
2008-05-04 11:01:48 +00:00
/// <summary>
/// Set the sculptie texture and data on an object
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="sculpt">A <seealso cref="Primitive.SculptData"/> object containing the data to set</param>
2007-07-08 04:35:04 +00:00
public void SetSculpt ( Simulator simulator , uint localID , Primitive . SculptData sculpt )
{
ObjectExtraParamsPacket extra = new ObjectExtraParamsPacket ( ) ;
2007-11-06 09:26:10 +00:00
extra . AgentData . AgentID = Client . Self . AgentID ;
extra . AgentData . SessionID = Client . Self . SessionID ;
2007-07-08 04:35:04 +00:00
extra . ObjectData = new ObjectExtraParamsPacket . ObjectDataBlock [ 1 ] ;
extra . ObjectData [ 0 ] = new ObjectExtraParamsPacket . ObjectDataBlock ( ) ;
extra . ObjectData [ 0 ] . ObjectLocalID = localID ;
2008-08-24 05:06:51 +00:00
extra . ObjectData [ 0 ] . ParamType = ( byte ) ExtraParamType . Sculpt ;
2007-07-08 04:35:04 +00:00
extra . ObjectData [ 0 ] . ParamInUse = true ;
extra . ObjectData [ 0 ] . ParamData = sculpt . GetBytes ( ) ;
2006-12-09 07:55:46 +00:00
extra . ObjectData [ 0 ] . ParamSize = ( uint ) extra . ObjectData [ 0 ] . ParamData . Length ;
Client . Network . SendPacket ( extra , simulator ) ;
2007-07-08 04:35:04 +00:00
// Not sure why, but if you don't send this the sculpted prim disappears
ObjectShapePacket shape = new ObjectShapePacket ( ) ;
2007-11-06 09:26:10 +00:00
shape . AgentData . AgentID = Client . Self . AgentID ;
shape . AgentData . SessionID = Client . Self . SessionID ;
2007-07-08 04:35:04 +00:00
2008-07-21 21:12:59 +00:00
shape . ObjectData = new OpenMetaverse . Packets . ObjectShapePacket . ObjectDataBlock [ 1 ] ;
shape . ObjectData [ 0 ] = new OpenMetaverse . Packets . ObjectShapePacket . ObjectDataBlock ( ) ;
2007-07-08 04:35:04 +00:00
shape . ObjectData [ 0 ] . ObjectLocalID = localID ;
shape . ObjectData [ 0 ] . PathScaleX = 100 ;
shape . ObjectData [ 0 ] . PathScaleY = 150 ;
shape . ObjectData [ 0 ] . PathCurve = 32 ;
Client . Network . SendPacket ( shape , simulator ) ;
}
2008-05-04 11:01:48 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Unset additional primitive parameters on an object
2008-05-04 11:01:48 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="type">The extra parameters to set</param>
2008-08-24 05:06:51 +00:00
public void SetExtraParamOff ( Simulator simulator , uint localID , ExtraParamType type )
2007-07-08 04:35:04 +00:00
{
ObjectExtraParamsPacket extra = new ObjectExtraParamsPacket ( ) ;
2007-11-06 09:26:10 +00:00
extra . AgentData . AgentID = Client . Self . AgentID ;
extra . AgentData . SessionID = Client . Self . SessionID ;
2007-07-08 04:35:04 +00:00
extra . ObjectData = new ObjectExtraParamsPacket . ObjectDataBlock [ 1 ] ;
extra . ObjectData [ 0 ] = new ObjectExtraParamsPacket . ObjectDataBlock ( ) ;
extra . ObjectData [ 0 ] . ObjectLocalID = localID ;
extra . ObjectData [ 0 ] . ParamType = ( byte ) type ;
extra . ObjectData [ 0 ] . ParamInUse = false ;
2009-03-06 01:32:02 +00:00
extra . ObjectData [ 0 ] . ParamData = Utils . EmptyBytes ;
2007-07-08 04:35:04 +00:00
extra . ObjectData [ 0 ] . ParamSize = 0 ;
Client . Network . SendPacket ( extra , simulator ) ;
2006-12-09 07:55:46 +00:00
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Link multiple prims into a linkset
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the objects reside</param>
2008-05-04 11:01:48 +00:00
/// <param name="localIDs">An array which contains the IDs of the objects to link</param>
/// <remarks>The last object in the array will be the root object of the linkset TODO: Is this true?</remarks>
2006-11-10 09:50:54 +00:00
public void LinkPrims ( Simulator simulator , List < uint > localIDs )
{
ObjectLinkPacket packet = new ObjectLinkPacket ( ) ;
2007-11-06 09:26:10 +00:00
packet . AgentData . AgentID = Client . Self . AgentID ;
packet . AgentData . SessionID = Client . Self . SessionID ;
2006-11-10 09:50:54 +00:00
packet . ObjectData = new ObjectLinkPacket . ObjectDataBlock [ localIDs . Count ] ;
2009-10-29 23:53:17 +00:00
for ( int i = 0 ; i < localIDs . Count ; i + + )
2006-11-10 09:50:54 +00:00
{
packet . ObjectData [ i ] = new ObjectLinkPacket . ObjectDataBlock ( ) ;
2009-10-29 23:53:17 +00:00
packet . ObjectData [ i ] . ObjectLocalID = localIDs [ i ] ;
2010-03-08 10:57:01 +00:00
}
2006-11-10 09:50:54 +00:00
Client . Network . SendPacket ( packet , simulator ) ;
}
2010-05-05 07:29:21 +00:00
/// <summary>
/// Delink/Unlink multiple prims from a linkset
/// </summary>
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the objects reside</param>
/// <param name="localIDs">An array which contains the IDs of the objects to delink</param>
public void DelinkPrims ( Simulator simulator , List < uint > localIDs )
{
ObjectDelinkPacket packet = new ObjectDelinkPacket ( ) ;
packet . AgentData . AgentID = Client . Self . AgentID ;
packet . AgentData . SessionID = Client . Self . SessionID ;
packet . ObjectData = new ObjectDelinkPacket . ObjectDataBlock [ localIDs . Count ] ;
int i = 0 ;
foreach ( uint localID in localIDs )
{
packet . ObjectData [ i ] = new ObjectDelinkPacket . ObjectDataBlock ( ) ;
packet . ObjectData [ i ] . ObjectLocalID = localID ;
i + + ;
}
Client . Network . SendPacket ( packet , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Change the rotation of an object
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="rotation">The new rotation of the object</param>
2008-07-25 05:15:05 +00:00
public void SetRotation ( Simulator simulator , uint localID , Quaternion rotation )
2006-11-13 08:52:41 +00:00
{
ObjectRotationPacket objRotPacket = new ObjectRotationPacket ( ) ;
2007-11-06 09:26:10 +00:00
objRotPacket . AgentData . AgentID = Client . Self . AgentID ;
objRotPacket . AgentData . SessionID = Client . Self . SessionID ;
2006-11-13 08:52:41 +00:00
objRotPacket . ObjectData = new ObjectRotationPacket . ObjectDataBlock [ 1 ] ;
objRotPacket . ObjectData [ 0 ] = new ObjectRotationPacket . ObjectDataBlock ( ) ;
objRotPacket . ObjectData [ 0 ] . ObjectLocalID = localID ;
objRotPacket . ObjectData [ 0 ] . Rotation = rotation ;
Client . Network . SendPacket ( objRotPacket , simulator ) ;
}
2007-02-03 20:34:49 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the name of an object
2007-02-03 20:34:49 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="name">A string containing the new name of the object</param>
2007-02-03 20:34:49 +00:00
public void SetName ( Simulator simulator , uint localID , string name )
{
SetNames ( simulator , new uint [ ] { localID } , new string [ ] { name } ) ;
}
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the name of multiple objects
2007-02-03 20:34:49 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the objects reside</param>
2008-05-04 11:01:48 +00:00
/// <param name="localIDs">An array which contains the IDs of the objects to change the name of</param>
/// <param name="names">An array which contains the new names of the objects</param>
2007-02-03 20:34:49 +00:00
public void SetNames ( Simulator simulator , uint [ ] localIDs , string [ ] names )
{
ObjectNamePacket namePacket = new ObjectNamePacket ( ) ;
2007-11-06 09:26:10 +00:00
namePacket . AgentData . AgentID = Client . Self . AgentID ;
namePacket . AgentData . SessionID = Client . Self . SessionID ;
2007-02-03 20:34:49 +00:00
namePacket . ObjectData = new ObjectNamePacket . ObjectDataBlock [ localIDs . Length ] ;
for ( int i = 0 ; i < localIDs . Length ; + + i )
{
namePacket . ObjectData [ i ] = new ObjectNamePacket . ObjectDataBlock ( ) ;
namePacket . ObjectData [ i ] . LocalID = localIDs [ i ] ;
2008-08-12 22:38:02 +00:00
namePacket . ObjectData [ i ] . Name = Utils . StringToBytes ( names [ i ] ) ;
2007-02-03 20:34:49 +00:00
}
Client . Network . SendPacket ( namePacket , simulator ) ;
}
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the description of an object
2007-02-03 20:34:49 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="description">A string containing the new description of the object</param>
2007-02-03 20:34:49 +00:00
public void SetDescription ( Simulator simulator , uint localID , string description )
{
SetDescriptions ( simulator , new uint [ ] { localID } , new string [ ] { description } ) ;
}
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the descriptions of multiple objects
2007-02-03 20:34:49 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the objects reside</param>
2008-05-04 11:01:48 +00:00
/// <param name="localIDs">An array which contains the IDs of the objects to change the description of</param>
/// <param name="descriptions">An array which contains the new descriptions of the objects</param>
2007-02-03 20:34:49 +00:00
public void SetDescriptions ( Simulator simulator , uint [ ] localIDs , string [ ] descriptions )
{
ObjectDescriptionPacket descPacket = new ObjectDescriptionPacket ( ) ;
2007-11-06 09:26:10 +00:00
descPacket . AgentData . AgentID = Client . Self . AgentID ;
descPacket . AgentData . SessionID = Client . Self . SessionID ;
2007-02-03 20:34:49 +00:00
descPacket . ObjectData = new ObjectDescriptionPacket . ObjectDataBlock [ localIDs . Length ] ;
for ( int i = 0 ; i < localIDs . Length ; + + i )
{
descPacket . ObjectData [ i ] = new ObjectDescriptionPacket . ObjectDataBlock ( ) ;
descPacket . ObjectData [ i ] . LocalID = localIDs [ i ] ;
2008-08-12 22:38:02 +00:00
descPacket . ObjectData [ i ] . Description = Utils . StringToBytes ( descriptions [ i ] ) ;
2007-02-03 20:34:49 +00:00
}
Client . Network . SendPacket ( descPacket , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Attach an object to this avatar
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="attachPoint">The point on the avatar the object will be attached</param>
/// <param name="rotation">The rotation of the attached object</param>
2008-07-25 05:15:05 +00:00
public void AttachObject ( Simulator simulator , uint localID , AttachmentPoint attachPoint , Quaternion rotation )
2006-11-13 08:52:41 +00:00
{
ObjectAttachPacket attach = new ObjectAttachPacket ( ) ;
2007-11-06 09:26:10 +00:00
attach . AgentData . AgentID = Client . Self . AgentID ;
attach . AgentData . SessionID = Client . Self . SessionID ;
2006-11-13 08:52:41 +00:00
attach . AgentData . AttachmentPoint = ( byte ) attachPoint ;
attach . ObjectData = new ObjectAttachPacket . ObjectDataBlock [ 1 ] ;
attach . ObjectData [ 0 ] = new ObjectAttachPacket . ObjectDataBlock ( ) ;
attach . ObjectData [ 0 ] . ObjectLocalID = localID ;
attach . ObjectData [ 0 ] . Rotation = rotation ;
Client . Network . SendPacket ( attach , simulator ) ;
}
2009-02-17 18:48:33 +00:00
/// <summary>
/// Drop an attached object from this avatar
/// </summary>
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/>
/// object where the objects reside. This will always be the simulator the avatar is currently in
/// </param>
/// <param name="localID">The object's ID which is local to the simulator the object is in</param>
public void DropObject ( Simulator simulator , uint localID )
{
ObjectDropPacket dropit = new ObjectDropPacket ( ) ;
dropit . AgentData . AgentID = Client . Self . AgentID ;
dropit . AgentData . SessionID = Client . Self . SessionID ;
dropit . ObjectData = new ObjectDropPacket . ObjectDataBlock [ 1 ] ;
dropit . ObjectData [ 0 ] = new ObjectDropPacket . ObjectDataBlock ( ) ;
dropit . ObjectData [ 0 ] . ObjectLocalID = localID ;
Client . Network . SendPacket ( dropit , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Detach an object from yourself
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/>
2008-05-04 11:01:48 +00:00
/// object where the objects reside
///
/// This will always be the simulator the avatar is currently in
/// </param>
/// <param name="localIDs">An array which contains the IDs of the objects to detach</param>
2006-11-13 08:52:41 +00:00
public void DetachObjects ( Simulator simulator , List < uint > localIDs )
{
ObjectDetachPacket detach = new ObjectDetachPacket ( ) ;
2007-11-06 09:26:10 +00:00
detach . AgentData . AgentID = Client . Self . AgentID ;
detach . AgentData . SessionID = Client . Self . SessionID ;
2006-11-13 08:52:41 +00:00
detach . ObjectData = new ObjectDetachPacket . ObjectDataBlock [ localIDs . Count ] ;
2009-10-29 23:53:17 +00:00
for ( int i = 0 ; i < localIDs . Count ; i + + )
2006-11-13 08:52:41 +00:00
{
detach . ObjectData [ i ] = new ObjectDetachPacket . ObjectDataBlock ( ) ;
2009-10-29 23:53:17 +00:00
detach . ObjectData [ i ] . ObjectLocalID = localIDs [ i ] ;
2010-03-08 10:57:01 +00:00
}
2006-11-13 08:52:41 +00:00
Client . Network . SendPacket ( detach , simulator ) ;
}
2006-11-22 13:21:21 +00:00
/// <summary>
2008-07-18 05:31:57 +00:00
/// Change the position of an object, Will change position of entire linkset
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="position">The new position of the object</param>
2008-07-25 05:15:05 +00:00
public void SetPosition ( Simulator simulator , uint localID , Vector3 position )
2008-07-18 05:31:57 +00:00
{
UpdateObject ( simulator , localID , position , UpdateType . Position | UpdateType . Linked ) ;
}
/// <summary>
/// Change the position of an object
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-07-18 05:31:57 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="position">The new position of the object</param>
/// <param name="childOnly">if true, will change position of (this) child prim only, not entire linkset</param>
2008-07-25 05:15:05 +00:00
public void SetPosition ( Simulator simulator , uint localID , Vector3 position , bool childOnly )
2008-07-18 05:31:57 +00:00
{
UpdateType type = UpdateType . Position ;
if ( ! childOnly )
type | = UpdateType . Linked ;
UpdateObject ( simulator , localID , position , type ) ;
}
/// <summary>
/// Change the Scale (size) of an object
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-07-18 05:31:57 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="scale">The new scale of the object</param>
/// <param name="childOnly">If true, will change scale of this prim only, not entire linkset</param>
/// <param name="uniform">True to resize prims uniformly</param>
2008-07-25 05:15:05 +00:00
public void SetScale ( Simulator simulator , uint localID , Vector3 scale , bool childOnly , bool uniform )
2008-07-18 05:31:57 +00:00
{
UpdateType type = UpdateType . Scale ;
if ( ! childOnly )
type | = UpdateType . Linked ;
if ( uniform )
type | = UpdateType . Uniform ;
UpdateObject ( simulator , localID , scale , type ) ;
}
/// <summary>
2008-07-20 03:48:34 +00:00
/// Change the Rotation of an object that is either a child or a whole linkset
2008-07-18 05:31:57 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-07-18 05:31:57 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
2008-07-20 03:48:34 +00:00
/// <param name="quat">The new scale of the object</param>
2008-07-18 05:31:57 +00:00
/// <param name="childOnly">If true, will change rotation of this prim only, not entire linkset</param>
2008-07-25 05:15:05 +00:00
public void SetRotation ( Simulator simulator , uint localID , Quaternion quat , bool childOnly )
2008-07-18 05:31:57 +00:00
{
UpdateType type = UpdateType . Rotation ;
if ( ! childOnly )
type | = UpdateType . Linked ;
2008-07-20 03:48:34 +00:00
MultipleObjectUpdatePacket multiObjectUpdate = new MultipleObjectUpdatePacket ( ) ;
multiObjectUpdate . AgentData . AgentID = Client . Self . AgentID ;
multiObjectUpdate . AgentData . SessionID = Client . Self . SessionID ;
multiObjectUpdate . ObjectData = new MultipleObjectUpdatePacket . ObjectDataBlock [ 1 ] ;
multiObjectUpdate . ObjectData [ 0 ] = new MultipleObjectUpdatePacket . ObjectDataBlock ( ) ;
multiObjectUpdate . ObjectData [ 0 ] . Type = ( byte ) type ;
multiObjectUpdate . ObjectData [ 0 ] . ObjectLocalID = localID ;
multiObjectUpdate . ObjectData [ 0 ] . Data = quat . GetBytes ( ) ;
Client . Network . SendPacket ( multiObjectUpdate , simulator ) ;
2008-07-18 05:31:57 +00:00
}
/// <summary>
/// Send a Multiple Object Update packet to change the size, scale or rotation of a primitive
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-07-18 05:31:57 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="data">The new rotation, size, or position of the target object</param>
/// <param name="type">The flags from the <seealso cref="UpdateType"/> Enum</param>
2008-07-25 05:15:05 +00:00
public void UpdateObject ( Simulator simulator , uint localID , Vector3 data , UpdateType type )
2006-11-13 08:52:41 +00:00
{
2008-04-04 21:35:31 +00:00
MultipleObjectUpdatePacket multiObjectUpdate = new MultipleObjectUpdatePacket ( ) ;
multiObjectUpdate . AgentData . AgentID = Client . Self . AgentID ;
multiObjectUpdate . AgentData . SessionID = Client . Self . SessionID ;
2006-11-13 08:52:41 +00:00
2008-04-04 21:35:31 +00:00
multiObjectUpdate . ObjectData = new MultipleObjectUpdatePacket . ObjectDataBlock [ 1 ] ;
2006-11-13 08:52:41 +00:00
2008-04-04 21:35:31 +00:00
multiObjectUpdate . ObjectData [ 0 ] = new MultipleObjectUpdatePacket . ObjectDataBlock ( ) ;
2008-07-18 05:31:57 +00:00
multiObjectUpdate . ObjectData [ 0 ] . Type = ( byte ) type ;
2008-04-04 21:35:31 +00:00
multiObjectUpdate . ObjectData [ 0 ] . ObjectLocalID = localID ;
2008-07-18 05:31:57 +00:00
multiObjectUpdate . ObjectData [ 0 ] . Data = data . GetBytes ( ) ;
2006-11-13 08:52:41 +00:00
2008-04-04 21:35:31 +00:00
Client . Network . SendPacket ( multiObjectUpdate , simulator ) ;
2006-11-13 08:52:41 +00:00
}
2007-08-30 18:28:59 +00:00
/// <summary>
2007-09-01 07:52:55 +00:00
/// Deed an object (prim) to a group, Object must be shared with group which
/// can be accomplished with SetPermissions()
2007-08-30 18:28:59 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupOwner">The <seealso cref="UUID"/> of the group to deed the object to</param>
2008-07-25 05:15:05 +00:00
public void DeedObject ( Simulator simulator , uint localID , UUID groupOwner )
2007-08-30 18:28:59 +00:00
{
2007-09-01 07:52:55 +00:00
ObjectOwnerPacket objDeedPacket = new ObjectOwnerPacket ( ) ;
2007-11-06 09:26:10 +00:00
objDeedPacket . AgentData . AgentID = Client . Self . AgentID ;
objDeedPacket . AgentData . SessionID = Client . Self . SessionID ;
2007-08-30 18:28:59 +00:00
// Can only be use in God mode
2007-09-01 07:52:55 +00:00
objDeedPacket . HeaderData . Override = false ;
2008-07-25 05:15:05 +00:00
objDeedPacket . HeaderData . OwnerID = UUID . Zero ;
2008-05-04 11:01:48 +00:00
objDeedPacket . HeaderData . GroupID = groupOwner ;
2007-08-30 18:28:59 +00:00
2007-09-01 07:52:55 +00:00
objDeedPacket . ObjectData = new ObjectOwnerPacket . ObjectDataBlock [ 1 ] ;
objDeedPacket . ObjectData [ 0 ] = new ObjectOwnerPacket . ObjectDataBlock ( ) ;
2009-03-18 19:31:39 +00:00
2007-09-01 07:52:55 +00:00
objDeedPacket . ObjectData [ 0 ] . ObjectLocalID = localID ;
2009-03-18 19:31:39 +00:00
2007-09-01 07:52:55 +00:00
Client . Network . SendPacket ( objDeedPacket , simulator ) ;
2007-08-30 18:28:59 +00:00
}
/// <summary>
2007-09-01 07:52:55 +00:00
/// Deed multiple objects (prims) to a group, Objects must be shared with group which
/// can be accomplished with SetPermissions()
2007-08-30 18:28:59 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2008-05-04 11:01:48 +00:00
/// <param name="localIDs">An array which contains the IDs of the objects to deed</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupOwner">The <seealso cref="UUID"/> of the group to deed the object to</param>
2008-07-25 05:15:05 +00:00
public void DeedObjects ( Simulator simulator , List < uint > localIDs , UUID groupOwner )
2007-08-30 18:28:59 +00:00
{
ObjectOwnerPacket packet = new ObjectOwnerPacket ( ) ;
2007-11-06 09:26:10 +00:00
packet . AgentData . AgentID = Client . Self . AgentID ;
packet . AgentData . SessionID = Client . Self . SessionID ;
2007-08-30 18:28:59 +00:00
// Can only be use in God mode
packet . HeaderData . Override = false ;
2008-07-25 05:15:05 +00:00
packet . HeaderData . OwnerID = UUID . Zero ;
2008-05-04 11:01:48 +00:00
packet . HeaderData . GroupID = groupOwner ;
2007-08-30 18:28:59 +00:00
2007-09-01 07:52:55 +00:00
packet . ObjectData = new ObjectOwnerPacket . ObjectDataBlock [ localIDs . Count ] ;
2007-08-30 18:28:59 +00:00
for ( int i = 0 ; i < localIDs . Count ; i + + )
{
packet . ObjectData [ i ] = new ObjectOwnerPacket . ObjectDataBlock ( ) ;
packet . ObjectData [ i ] . ObjectLocalID = localIDs [ i ] ;
}
Client . Network . SendPacket ( packet , simulator ) ;
}
2009-03-18 19:31:39 +00:00
2006-11-22 13:21:21 +00:00
/// <summary>
2008-05-04 11:01:48 +00:00
/// Set the permissions on multiple objects
2006-11-22 13:21:21 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the objects reside</param>
2008-05-04 11:01:48 +00:00
/// <param name="localIDs">An array which contains the IDs of the objects to set the permissions on</param>
/// <param name="who">The new Who mask to set</param>
2011-05-15 21:25:55 +00:00
/// <param name="permissions">Which permission to modify</param>
/// <param name="set">The new state of permission</param>
2009-03-18 19:31:39 +00:00
public void SetPermissions ( Simulator simulator , List < uint > localIDs , PermissionWho who ,
2007-07-08 04:35:04 +00:00
PermissionMask permissions , bool set )
2006-11-10 09:50:54 +00:00
{
ObjectPermissionsPacket packet = new ObjectPermissionsPacket ( ) ;
2007-11-06 09:26:10 +00:00
packet . AgentData . AgentID = Client . Self . AgentID ;
packet . AgentData . SessionID = Client . Self . SessionID ;
2006-11-10 09:50:54 +00:00
2007-07-08 04:35:04 +00:00
// Override can only be used by gods
2006-11-10 09:50:54 +00:00
packet . HeaderData . Override = false ;
packet . ObjectData = new ObjectPermissionsPacket . ObjectDataBlock [ localIDs . Count ] ;
2007-07-08 04:35:04 +00:00
for ( int i = 0 ; i < localIDs . Count ; i + + )
2006-11-10 09:50:54 +00:00
{
packet . ObjectData [ i ] = new ObjectPermissionsPacket . ObjectDataBlock ( ) ;
2007-07-08 04:35:04 +00:00
packet . ObjectData [ i ] . ObjectLocalID = localIDs [ i ] ;
2006-11-10 09:50:54 +00:00
packet . ObjectData [ i ] . Field = ( byte ) who ;
packet . ObjectData [ i ] . Mask = ( uint ) permissions ;
packet . ObjectData [ i ] . Set = Convert . ToByte ( set ) ;
}
Client . Network . SendPacket ( packet , simulator ) ;
}
2010-03-08 10:57:01 +00:00
2006-12-10 11:27:28 +00:00
/// <summary>
/// Request additional properties for an object
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2006-12-10 11:27:28 +00:00
/// <param name="objectID"></param>
2008-07-25 05:15:05 +00:00
public void RequestObjectPropertiesFamily ( Simulator simulator , UUID objectID )
2006-12-10 11:27:28 +00:00
{
2007-02-03 20:34:49 +00:00
RequestObjectPropertiesFamily ( simulator , objectID , true ) ;
2006-12-10 11:27:28 +00:00
}
2007-01-31 00:09:22 +00:00
/// <summary>
/// Request additional properties for an object
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
2007-02-16 00:50:19 +00:00
/// <param name="objectID">Absolute UUID of the object</param>
/// <param name="reliable">Whether to require server acknowledgement of this request</param>
2008-07-25 05:15:05 +00:00
public void RequestObjectPropertiesFamily ( Simulator simulator , UUID objectID , bool reliable )
2007-01-31 00:09:22 +00:00
{
RequestObjectPropertiesFamilyPacket properties = new RequestObjectPropertiesFamilyPacket ( ) ;
2007-11-06 09:26:10 +00:00
properties . AgentData . AgentID = Client . Self . AgentID ;
properties . AgentData . SessionID = Client . Self . SessionID ;
2007-01-31 00:09:22 +00:00
properties . ObjectData . ObjectID = objectID ;
2007-02-03 20:34:49 +00:00
// TODO: RequestFlags is typically only for bug report submissions, but we might be able to
// use it to pass an arbitrary uint back to the callback
2007-01-31 00:09:22 +00:00
properties . ObjectData . RequestFlags = 0 ;
properties . Header . Reliable = reliable ;
Client . Network . SendPacket ( properties , simulator ) ;
}
2009-08-23 22:35:02 +00:00
/// <summary>
/// Set the ownership of a list of objects to the specified group
/// </summary>
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the objects reside</param>
2009-10-08 14:52:56 +00:00
/// <param name="localIds">An array which contains the IDs of the objects to set the group id on</param>
2009-08-23 22:35:02 +00:00
/// <param name="groupID">The Groups ID</param>
public void SetObjectsGroup ( Simulator simulator , List < uint > localIds , UUID groupID )
{
ObjectGroupPacket packet = new ObjectGroupPacket ( ) ;
packet . AgentData . AgentID = Client . Self . AgentID ;
packet . AgentData . GroupID = groupID ;
packet . AgentData . SessionID = Client . Self . SessionID ;
packet . ObjectData = new ObjectGroupPacket . ObjectDataBlock [ localIds . Count ] ;
for ( int i = 0 ; i < localIds . Count ; i + + )
{
packet . ObjectData [ i ] = new ObjectGroupPacket . ObjectDataBlock ( ) ;
packet . ObjectData [ i ] . ObjectLocalID = localIds [ i ] ;
}
Client . Network . SendPacket ( packet , simulator ) ;
}
2010-03-07 19:58:06 +00:00
2010-03-08 10:57:01 +00:00
/// <summary>
/// Update current URL of the previously set prim media
/// </summary>
/// <param name="primID">UUID of the prim</param>
/// <param name="newURL">Set current URL to this</param>
/// <param name="face">Prim face number</param>
/// <param name="sim">Simulator in which prim is located</param>
public void NavigateObjectMedia ( UUID primID , int face , string newURL , Simulator sim )
{
2022-11-03 14:19:56 -05:00
Uri cap ;
if ( sim . Caps = = null | | ( cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ObjectMediaNavigate" ) ) = = null )
2010-03-08 10:57:01 +00:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "ObjectMediaNavigate capability not available" , Helpers . LogLevel . Error , Client ) ;
return ;
}
2010-03-08 10:57:01 +00:00
2022-11-04 07:13:09 -05:00
ObjectMediaNavigateMessage payload = new ObjectMediaNavigateMessage
2022-11-03 14:19:56 -05:00
{
PrimID = primID , URL = newURL , Face = face
} ;
2010-03-08 10:57:01 +00:00
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , payload . Serialize ( ) ,
CancellationToken . None , ( response , data , error ) = >
2010-03-08 10:57:01 +00:00
{
2022-11-03 14:19:56 -05:00
if ( error ! = null )
{
Logger . Log ( $"ObjectMediaNavigate: {error.Message}" , Helpers . LogLevel . Error , Client , error ) ;
}
2022-11-04 07:13:09 -05:00
} ) ;
2010-03-08 10:57:01 +00:00
}
/// <summary>
/// Set object media
/// </summary>
/// <param name="primID">UUID of the prim</param>
/// <param name="faceMedia">Array the length of prims number of faces. Null on face indexes where there is
/// no media, <seealso cref="MediaEntry"/> on faces which contain the media</param>
/// <param name="sim">Simulatior in which prim is located</param>
public void UpdateObjectMedia ( UUID primID , MediaEntry [ ] faceMedia , Simulator sim )
{
2022-11-03 14:19:56 -05:00
Uri cap ;
if ( sim . Caps = = null | | ( cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ObjectMedia" ) ) = = null )
2010-03-08 10:57:01 +00:00
{
Logger . Log ( "ObjectMedia capability not available" , Helpers . LogLevel . Error , Client ) ;
2022-11-03 14:19:56 -05:00
return ;
2010-03-08 10:57:01 +00:00
}
2022-11-03 14:19:56 -05:00
2022-11-04 07:13:09 -05:00
ObjectMediaUpdate payload = new ObjectMediaUpdate { PrimID = primID , FaceMedia = faceMedia , Verb = "UPDATE" } ;
2022-11-03 14:19:56 -05:00
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , payload . Serialize ( ) ,
CancellationToken . None , ( response , data , error ) = >
2022-11-03 14:19:56 -05:00
{
if ( error ! = null )
{
Logger . Log ( $"ObjectMediaUpdate: {error.Message}" , Helpers . LogLevel . Error , Client , error ) ;
}
2022-11-04 07:13:09 -05:00
} ) ;
2022-11-03 14:19:56 -05:00
2010-03-08 10:57:01 +00:00
}
/// <summary>
/// Retrieve information about object media
/// </summary>
/// <param name="primID">UUID of the primitive</param>
/// <param name="sim">Simulator where prim is located</param>
/// <param name="callback">Call this callback when done</param>
2010-03-07 19:58:06 +00:00
public void RequestObjectMedia ( UUID primID , Simulator sim , ObjectMediaCallback callback )
{
2022-11-03 14:19:56 -05:00
Uri cap ;
if ( sim . Caps ! = null & & ( cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ObjectMedia" ) ) ! = null )
2010-03-07 19:58:06 +00:00
{
2022-11-04 07:13:09 -05:00
ObjectMediaRequest payload = new ObjectMediaRequest { PrimID = primID , Verb = "GET" } ;
2010-03-07 19:58:06 +00:00
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , payload . Serialize ( ) ,
CancellationToken . None , ( httpResponse , data , error ) = >
2022-11-03 14:19:56 -05:00
{
if ( error ! = null )
2010-03-07 19:58:06 +00:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "Failed retrieving ObjectMedia data" , Helpers . LogLevel . Error , Client , error ) ;
try { callback ( false , string . Empty , null ) ; }
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client ) ; }
return ;
}
2010-03-07 19:58:06 +00:00
2022-11-03 14:19:56 -05:00
ObjectMediaMessage msg = new ObjectMediaMessage ( ) ;
OSD result = OSDParser . Deserialize ( data ) ;
msg . Deserialize ( ( OSDMap ) result ) ;
2010-03-07 19:58:06 +00:00
2022-11-03 14:19:56 -05:00
if ( msg . Request is ObjectMediaResponse response )
{
if ( Client . Settings . OBJECT_TRACKING )
2010-03-07 19:58:06 +00:00
{
2024-06-30 17:35:07 -05:00
Primitive prim = sim . ObjectsPrimitives . Find ( p = > p . ID = = primID ) ;
2022-11-03 14:19:56 -05:00
if ( prim ! = null )
2010-03-08 10:57:01 +00:00
{
2022-11-03 14:19:56 -05:00
prim . MediaVersion = response . Version ;
prim . FaceMedia = response . FaceMedia ;
2010-03-08 10:57:01 +00:00
}
2010-03-07 19:58:06 +00:00
}
2022-11-03 14:19:56 -05:00
try { callback ( true , response . Version , response . FaceMedia ) ; }
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client ) ; }
}
else
{
try { callback ( false , string . Empty , null ) ; }
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client ) ; }
}
2022-11-04 07:13:09 -05:00
} ) ;
2010-03-07 19:58:06 +00:00
}
else
{
2010-03-08 10:57:01 +00:00
Logger . Log ( "ObjectMedia capability not available" , Helpers . LogLevel . Error , Client ) ;
2010-03-07 19:58:06 +00:00
try { callback ( false , string . Empty , null ) ; }
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client ) ; }
}
}
2007-01-19 20:53:05 +00:00
#endregion
2009-03-18 19:31:39 +00:00
2007-01-19 20:53:05 +00:00
#region Packet Handlers
2006-10-21 02:52:28 +00:00
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ObjectUpdateHandler ( object sender , PacketReceivedEventArgs e )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-04-20 16:03:24 +00:00
ObjectUpdatePacket update = ( ObjectUpdatePacket ) packet ;
2009-10-28 08:01:52 +00:00
UpdateDilation ( e . Simulator , update . RegionData . TimeDilation ) ;
2010-03-08 10:57:01 +00:00
2022-10-10 16:08:14 -05:00
foreach ( var block in update . ObjectData )
2007-04-20 16:03:24 +00:00
{
2009-10-27 07:01:48 +00:00
ObjectMovementUpdate objectupdate = new ObjectMovementUpdate ( ) ;
2009-06-27 22:53:48 +00:00
//Vector4 collisionPlane = Vector4.Zero;
//Vector3 position;
//Vector3 velocity;
//Vector3 acceleration;
//Quaternion rotation;
//Vector3 angularVelocity;
2007-04-20 16:03:24 +00:00
NameValue [ ] nameValues ;
bool attachment = false ;
PCode pcode = ( PCode ) block . PCode ;
#region Relevance check
// Check if we are interested in this object
if ( ! Client . Settings . ALWAYS_DECODE_OBJECTS )
2006-10-21 02:52:28 +00:00
{
2007-04-20 16:03:24 +00:00
switch ( pcode )
2007-02-02 00:19:45 +00:00
{
2007-04-20 16:03:24 +00:00
case PCode . Grass :
case PCode . Tree :
case PCode . NewTree :
case PCode . Prim :
2009-10-27 07:01:48 +00:00
if ( m_ObjectUpdate = = null ) continue ;
2007-04-20 16:03:24 +00:00
break ;
case PCode . Avatar :
// Make an exception for updates about our own agent
2009-10-27 07:01:48 +00:00
if ( block . FullID ! = Client . Self . AgentID & & m_AvatarUpdate = = null ) continue ;
2007-04-20 16:03:24 +00:00
break ;
case PCode . ParticleSystem :
continue ; // TODO: Do something with these
2007-02-02 00:19:45 +00:00
}
2007-04-20 16:03:24 +00:00
}
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
#endregion Relevance check
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
#region NameValue parsing
2007-01-30 12:47:47 +00:00
2008-08-12 22:38:02 +00:00
string nameValue = Utils . BytesToString ( block . NameValue ) ;
2007-04-20 16:03:24 +00:00
if ( nameValue . Length > 0 )
{
2007-11-06 09:26:10 +00:00
string [ ] lines = nameValue . Split ( '\n' ) ;
2007-04-20 16:03:24 +00:00
nameValues = new NameValue [ lines . Length ] ;
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
for ( int i = 0 ; i < lines . Length ; i + + )
{
2024-06-30 17:47:14 -05:00
if ( ! string . IsNullOrEmpty ( lines [ i ] ) )
2007-04-20 16:03:24 +00:00
{
NameValue nv = new NameValue ( lines [ i ] ) ;
if ( nv . Name = = "AttachItemID" ) attachment = true ;
nameValues [ i ] = nv ;
}
}
}
else
{
2022-04-19 18:22:05 -05:00
nameValues = Array . Empty < NameValue > ( ) ;
2007-04-20 16:03:24 +00:00
}
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
#endregion NameValue parsing
#region Decode Object ( primitive ) parameters
2008-08-24 05:06:51 +00:00
Primitive . ConstructionData data = new Primitive . ConstructionData ( ) ;
2007-04-20 16:03:24 +00:00
data . State = block . State ;
2008-08-24 05:06:51 +00:00
data . Material = ( Material ) block . Material ;
data . PathCurve = ( PathCurve ) block . PathCurve ;
2007-12-18 19:23:46 +00:00
data . profileCurve = block . ProfileCurve ;
2008-08-24 05:06:51 +00:00
data . PathBegin = Primitive . UnpackBeginCut ( block . PathBegin ) ;
data . PathEnd = Primitive . UnpackEndCut ( block . PathEnd ) ;
data . PathScaleX = Primitive . UnpackPathScale ( block . PathScaleX ) ;
data . PathScaleY = Primitive . UnpackPathScale ( block . PathScaleY ) ;
data . PathShearX = Primitive . UnpackPathShear ( ( sbyte ) block . PathShearX ) ;
data . PathShearY = Primitive . UnpackPathShear ( ( sbyte ) block . PathShearY ) ;
data . PathTwist = Primitive . UnpackPathTwist ( block . PathTwist ) ;
data . PathTwistBegin = Primitive . UnpackPathTwist ( block . PathTwistBegin ) ;
data . PathRadiusOffset = Primitive . UnpackPathTwist ( block . PathRadiusOffset ) ;
data . PathTaperX = Primitive . UnpackPathTaper ( block . PathTaperX ) ;
data . PathTaperY = Primitive . UnpackPathTaper ( block . PathTaperY ) ;
data . PathRevolutions = Primitive . UnpackPathRevolutions ( block . PathRevolutions ) ;
data . PathSkew = Primitive . UnpackPathTwist ( block . PathSkew ) ;
data . ProfileBegin = Primitive . UnpackBeginCut ( block . ProfileBegin ) ;
data . ProfileEnd = Primitive . UnpackEndCut ( block . ProfileEnd ) ;
data . ProfileHollow = Primitive . UnpackProfileHollow ( block . ProfileHollow ) ;
2007-04-22 14:14:32 +00:00
data . PCode = pcode ;
2007-04-20 16:03:24 +00:00
#endregion
#region Decode Additional packed parameters in ObjectData
int pos = 0 ;
switch ( block . ObjectData . Length )
{
case 76 :
// Collision normal for avatar
2009-06-27 22:53:48 +00:00
objectupdate . CollisionPlane = new Vector4 ( block . ObjectData , pos ) ;
2007-04-20 16:03:24 +00:00
pos + = 16 ;
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
goto case 60 ;
case 60 :
// Position
2009-06-27 22:53:48 +00:00
objectupdate . Position = new Vector3 ( block . ObjectData , pos ) ;
2007-04-20 16:03:24 +00:00
pos + = 12 ;
// Velocity
2009-06-27 22:53:48 +00:00
objectupdate . Velocity = new Vector3 ( block . ObjectData , pos ) ;
2007-04-20 16:03:24 +00:00
pos + = 12 ;
// Acceleration
2009-06-27 22:53:48 +00:00
objectupdate . Acceleration = new Vector3 ( block . ObjectData , pos ) ;
2007-04-20 16:03:24 +00:00
pos + = 12 ;
// Rotation (theta)
2009-06-27 22:53:48 +00:00
objectupdate . Rotation = new Quaternion ( block . ObjectData , pos , true ) ;
2007-04-20 16:03:24 +00:00
pos + = 12 ;
// Angular velocity (omega)
2009-06-27 22:53:48 +00:00
objectupdate . AngularVelocity = new Vector3 ( block . ObjectData , pos ) ;
2007-04-20 16:03:24 +00:00
pos + = 12 ;
break ;
case 48 :
// Collision normal for avatar
2009-06-27 22:53:48 +00:00
objectupdate . CollisionPlane = new Vector4 ( block . ObjectData , pos ) ;
2007-04-20 16:03:24 +00:00
pos + = 16 ;
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
goto case 32 ;
case 32 :
// The data is an array of unsigned shorts
// Position
2009-06-27 22:53:48 +00:00
objectupdate . Position = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . ObjectData , pos , - 0.5f * 256.0f , 1.5f * 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 2 , - 0.5f * 256.0f , 1.5f * 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 4 , - 256.0f , 3.0f * 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 6 ;
// Velocity
2009-06-27 22:53:48 +00:00
objectupdate . Velocity = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 4 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 6 ;
// Acceleration
2009-06-27 22:53:48 +00:00
objectupdate . Acceleration = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 4 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 6 ;
// Rotation (theta)
2009-06-27 22:53:48 +00:00
objectupdate . Rotation = new Quaternion (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . ObjectData , pos , - 1.0f , 1.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 2 , - 1.0f , 1.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 4 , - 1.0f , 1.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 6 , - 1.0f , 1.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 8 ;
// Angular velocity (omega)
2009-06-27 22:53:48 +00:00
objectupdate . AngularVelocity = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ,
Utils . UInt16ToFloat ( block . ObjectData , pos + 4 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 6 ;
break ;
case 16 :
// The data is an array of single bytes (8-bit numbers)
// Position
2009-06-27 22:53:48 +00:00
objectupdate . Position = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . ByteToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 1 , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 3 ;
// Velocity
2009-06-27 22:53:48 +00:00
objectupdate . Velocity = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . ByteToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 1 , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 3 ;
// Accleration
2009-06-27 22:53:48 +00:00
objectupdate . Acceleration = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . ByteToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 1 , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 3 ;
// Rotation
2009-06-27 22:53:48 +00:00
objectupdate . Rotation = new Quaternion (
2008-10-06 22:34:38 +00:00
Utils . ByteToFloat ( block . ObjectData , pos , - 1.0f , 1.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 1 , - 1.0f , 1.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 2 , - 1.0f , 1.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 3 , - 1.0f , 1.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 4 ;
// Angular Velocity
2009-06-27 22:53:48 +00:00
objectupdate . AngularVelocity = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . ByteToFloat ( block . ObjectData , pos , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 1 , - 256.0f , 256.0f ) ,
Utils . ByteToFloat ( block . ObjectData , pos + 2 , - 256.0f , 256.0f ) ) ;
2007-04-20 16:03:24 +00:00
pos + = 3 ;
break ;
default :
2008-05-06 23:57:26 +00:00
Logger . Log ( "Got an ObjectUpdate block with ObjectUpdate field length of " +
2022-10-10 16:08:14 -05:00
block . ObjectData . Length , Helpers . LogLevel . Warning , Client ) ;
2007-04-20 16:03:24 +00:00
continue ;
}
#endregion
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
// Determine the object type and create the appropriate class
switch ( pcode )
{
#region Prim and Foliage
case PCode . Grass :
case PCode . Tree :
case PCode . NewTree :
case PCode . Prim :
2009-11-16 06:36:26 +00:00
2009-12-01 06:52:09 +00:00
bool isNewObject ;
2009-11-16 06:36:26 +00:00
lock ( simulator . ObjectsPrimitives . Dictionary )
2009-12-01 06:52:09 +00:00
isNewObject = ! simulator . ObjectsPrimitives . ContainsKey ( block . ID ) ;
2009-11-16 06:36:26 +00:00
2007-04-20 16:03:24 +00:00
Primitive prim = GetPrimitive ( simulator , block . ID , block . FullID ) ;
2009-06-27 22:53:48 +00:00
// Textures
objectupdate . Textures = new Primitive . TextureEntry ( block . TextureEntry , 0 ,
block . TextureEntry . Length ) ;
2010-03-08 10:57:01 +00:00
2009-10-26 06:03:26 +00:00
OnObjectDataBlockUpdate ( new ObjectDataBlockUpdateEventArgs ( simulator , prim , data , block , objectupdate , nameValues ) ) ;
2009-06-27 22:53:48 +00:00
2009-03-18 19:31:39 +00:00
#region Update Prim Info with decoded data
2008-08-24 05:06:51 +00:00
prim . Flags = ( PrimFlags ) block . UpdateFlags ;
2007-01-30 12:47:47 +00:00
2008-08-24 05:06:51 +00:00
if ( ( prim . Flags & PrimFlags . ZlibCompressed ) ! = 0 )
2007-04-20 16:03:24 +00:00
{
2009-03-18 19:31:39 +00:00
Logger . Log ( "Got a ZlibCompressed ObjectUpdate, implement me!" ,
2008-05-06 23:57:26 +00:00
Helpers . LogLevel . Warning , Client ) ;
2007-01-30 12:47:47 +00:00
continue ;
2007-04-20 16:03:24 +00:00
}
2006-11-22 13:21:21 +00:00
2009-07-21 23:53:01 +00:00
// Automatically request ObjectProperties for prim if it was rezzed selected.
if ( ( prim . Flags & PrimFlags . CreateSelected ) ! = 0 )
{
SelectObject ( simulator , prim . LocalID ) ;
}
2007-04-20 16:03:24 +00:00
prim . NameValues = nameValues ;
prim . LocalID = block . ID ;
prim . ID = block . FullID ;
prim . ParentID = block . ParentID ;
2009-03-18 19:31:39 +00:00
prim . RegionHandle = update . RegionData . RegionHandle ;
2007-04-20 16:03:24 +00:00
prim . Scale = block . Scale ;
prim . ClickAction = ( ClickAction ) block . ClickAction ;
prim . OwnerID = block . OwnerID ;
2008-08-12 22:38:02 +00:00
prim . MediaURL = Utils . BytesToString ( block . MediaURL ) ;
prim . Text = Utils . BytesToString ( block . Text ) ;
2008-07-25 05:15:05 +00:00
prim . TextColor = new Color4 ( block . TextColor , 0 , false , true ) ;
2011-08-08 21:36:24 +00:00
prim . IsAttachment = attachment ;
2007-04-20 16:03:24 +00:00
// Sound information
prim . Sound = block . Sound ;
2009-03-10 01:54:45 +00:00
prim . SoundFlags = ( SoundFlags ) block . Flags ;
2007-04-20 16:03:24 +00:00
prim . SoundGain = block . Gain ;
prim . SoundRadius = block . Radius ;
// Joint information
2008-08-24 05:06:51 +00:00
prim . Joint = ( JointType ) block . JointType ;
2007-04-20 16:03:24 +00:00
prim . JointPivot = block . JointPivot ;
prim . JointAxisOrAnchor = block . JointAxisOrAnchor ;
2009-03-18 19:31:39 +00:00
2007-04-20 16:03:24 +00:00
// Object parameters
2008-08-24 05:06:51 +00:00
prim . PrimData = data ;
2007-04-20 16:03:24 +00:00
// Textures, texture animations, particle system, and extra params
2009-06-27 22:53:48 +00:00
prim . Textures = objectupdate . Textures ;
2007-05-12 01:42:28 +00:00
2007-07-08 04:35:04 +00:00
prim . TextureAnim = new Primitive . TextureAnimation ( block . TextureAnim , 0 ) ;
2007-04-20 16:03:24 +00:00
prim . ParticleSys = new Primitive . ParticleSystem ( block . PSBlock , 0 ) ;
prim . SetExtraParamsFromBytes ( block . ExtraParams , 0 ) ;
// PCode-specific data
2009-03-10 01:54:45 +00:00
switch ( pcode )
{
case PCode . Grass :
case PCode . Tree :
case PCode . NewTree :
if ( block . Data . Length = = 1 )
prim . TreeSpecies = ( Tree ) block . Data [ 0 ] ;
else
Logger . Log ( "Got a foliage update with an invalid TreeSpecies field" , Helpers . LogLevel . Warning ) ;
2011-05-20 09:26:13 +00:00
// prim.ScratchPad = Utils.EmptyBytes;
// break;
//default:
// prim.ScratchPad = new byte[block.Data.Length];
// if (block.Data.Length > 0)
// Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length);
2009-03-10 01:54:45 +00:00
break ;
}
2010-04-20 21:58:23 +00:00
prim . ScratchPad = Utils . EmptyBytes ;
2009-03-18 19:31:39 +00:00
2007-04-20 16:03:24 +00:00
// Packed parameters
2009-06-27 22:53:48 +00:00
prim . CollisionPlane = objectupdate . CollisionPlane ;
prim . Position = objectupdate . Position ;
prim . Velocity = objectupdate . Velocity ;
prim . Acceleration = objectupdate . Acceleration ;
prim . Rotation = objectupdate . Rotation ;
prim . AngularVelocity = objectupdate . AngularVelocity ;
2007-04-20 16:03:24 +00:00
#endregion
2015-06-11 00:02:57 +02:00
2010-08-12 22:37:27 +00:00
EventHandler < PrimEventArgs > handler = m_ObjectUpdate ;
if ( handler ! = null )
{
2019-10-20 21:22:13 -05:00
ThreadPool . QueueUserWorkItem ( delegate ( object o )
2022-10-10 16:08:14 -05:00
{ handler ( this , new PrimEventArgs ( simulator , prim , update . RegionData . TimeDilation , isNewObject , attachment ) ) ; } ) ;
2010-08-12 22:37:27 +00:00
}
2015-06-11 00:02:57 +02:00
//OnParticleUpdate handler replacing decode particles, PCode.Particle system appears to be deprecated this is a fix
if ( prim . ParticleSys . PartMaxAge ! = 0 ) {
OnParticleUpdate ( new ParticleUpdateEventArgs ( simulator , prim . ParticleSys , prim ) ) ;
}
2007-04-20 16:03:24 +00:00
break ;
#endregion Prim and Foliage
#region Avatar
case PCode . Avatar :
2009-12-01 06:52:09 +00:00
bool isNewAvatar ;
lock ( simulator . ObjectsAvatars . Dictionary )
isNewAvatar = ! simulator . ObjectsAvatars . ContainsKey ( block . ID ) ;
2007-04-20 16:03:24 +00:00
// Update some internals if this is our avatar
2009-10-06 00:09:53 +00:00
if ( block . FullID = = Client . Self . AgentID & & simulator = = Client . Network . CurrentSim )
2007-04-20 16:03:24 +00:00
{
#region Update Client . Self
2009-03-18 19:31:39 +00:00
2007-04-20 16:03:24 +00:00
// We need the local ID to recognize terse updates for our agent
2007-11-06 09:26:10 +00:00
Client . Self . localID = block . ID ;
2009-03-18 19:31:39 +00:00
2007-01-30 12:47:47 +00:00
// Packed parameters
2009-06-27 22:53:48 +00:00
Client . Self . collisionPlane = objectupdate . CollisionPlane ;
Client . Self . relativePosition = objectupdate . Position ;
Client . Self . velocity = objectupdate . Velocity ;
Client . Self . acceleration = objectupdate . Acceleration ;
Client . Self . relativeRotation = objectupdate . Rotation ;
Client . Self . angularVelocity = objectupdate . AngularVelocity ;
2006-12-12 00:44:39 +00:00
2007-04-20 16:03:24 +00:00
#endregion
}
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
#region Create an Avatar from the decoded data
Avatar avatar = GetAvatar ( simulator , block . ID , block . FullID ) ;
2009-06-27 22:53:48 +00:00
objectupdate . Avatar = true ;
// Textures
2010-03-08 10:57:01 +00:00
objectupdate . Textures = new Primitive . TextureEntry ( block . TextureEntry , 0 ,
2009-06-27 22:53:48 +00:00
block . TextureEntry . Length ) ;
2009-10-26 06:03:26 +00:00
OnObjectDataBlockUpdate ( new ObjectDataBlockUpdateEventArgs ( simulator , avatar , data , block , objectupdate , nameValues ) ) ;
2009-06-27 22:53:48 +00:00
2008-08-24 05:06:51 +00:00
uint oldSeatID = avatar . ParentID ;
2007-04-20 16:03:24 +00:00
avatar . ID = block . FullID ;
avatar . LocalID = block . ID ;
2010-06-28 20:43:53 +00:00
avatar . Scale = block . Scale ;
2009-06-27 22:53:48 +00:00
avatar . CollisionPlane = objectupdate . CollisionPlane ;
avatar . Position = objectupdate . Position ;
avatar . Velocity = objectupdate . Velocity ;
avatar . Acceleration = objectupdate . Acceleration ;
avatar . Rotation = objectupdate . Rotation ;
avatar . AngularVelocity = objectupdate . AngularVelocity ;
2007-04-20 16:03:24 +00:00
avatar . NameValues = nameValues ;
2008-08-24 05:06:51 +00:00
avatar . PrimData = data ;
2009-10-26 06:03:26 +00:00
if ( block . Data . Length > 0 )
{
Logger . Log ( "Unexpected Data field for an avatar update, length " + block . Data . Length , Helpers . LogLevel . Warning ) ;
}
2008-08-24 05:06:51 +00:00
avatar . ParentID = block . ParentID ;
2009-03-06 01:58:58 +00:00
avatar . RegionHandle = update . RegionData . RegionHandle ;
2007-04-20 16:03:24 +00:00
2007-11-06 09:26:10 +00:00
SetAvatarSittingOn ( simulator , avatar , block . ParentID , oldSeatID ) ;
2007-04-20 16:03:24 +00:00
// Textures
2009-06-27 22:53:48 +00:00
avatar . Textures = objectupdate . Textures ;
2007-04-20 16:03:24 +00:00
#endregion Create an Avatar from the decoded data
2009-12-01 06:52:09 +00:00
OnAvatarUpdate ( new AvatarUpdateEventArgs ( simulator , avatar , update . RegionData . TimeDilation , isNewAvatar ) ) ;
2007-04-20 16:03:24 +00:00
break ;
#endregion Avatar
case PCode . ParticleSystem :
DecodeParticleUpdate ( block ) ;
break ;
default :
2022-04-23 10:38:11 -05:00
Logger . DebugLog ( "Got an ObjectUpdate block with an unrecognized PCode " + pcode , Client ) ;
2007-04-20 16:03:24 +00:00
break ;
2006-10-21 02:52:28 +00:00
}
}
}
2007-02-27 10:07:50 +00:00
protected void DecodeParticleUpdate ( ObjectUpdatePacket . ObjectDataBlock block )
{
// TODO: Handle ParticleSystem ObjectUpdate blocks
// float bounce_b
2008-07-28 22:23:48 +00:00
// Vector4 scale_range
// Vector4 alpha_range
// Vector3 vel_offset
2007-02-27 10:07:50 +00:00
// float dist_begin_fadeout
// float dist_end_fadeout
2008-07-28 22:23:48 +00:00
// UUID image_uuid
2007-02-27 10:07:50 +00:00
// long flags
// byte createme
2008-07-28 22:23:48 +00:00
// Vector3 diff_eq_alpha
// Vector3 diff_eq_scale
2007-02-27 10:07:50 +00:00
// byte max_particles
// byte initial_particles
// float kill_plane_z
2008-07-28 22:23:48 +00:00
// Vector3 kill_plane_normal
2007-02-27 10:07:50 +00:00
// float bounce_plane_z
2008-07-28 22:23:48 +00:00
// Vector3 bounce_plane_normal
2007-02-27 10:07:50 +00:00
// float spawn_range
// float spawn_frequency
// float spawn_frequency_range
2008-07-28 22:23:48 +00:00
// Vector3 spawn_direction
2007-02-27 10:07:50 +00:00
// float spawn_direction_range
// float spawn_velocity
// float spawn_velocity_range
// float speed_limit
// float wind_weight
2008-07-28 22:23:48 +00:00
// Vector3 current_gravity
2007-02-27 10:07:50 +00:00
// float gravity_weight
// float global_lifetime
// float individual_lifetime
// float individual_lifetime_range
// float alpha_decay
// float scale_decay
// float distance_death
// float damp_motion_factor
2008-07-28 22:23:48 +00:00
// Vector3 wind_diffusion_factor
2007-02-27 10:07:50 +00:00
}
2007-01-19 20:53:05 +00:00
/// <summary>
2007-08-20 09:26:21 +00:00
/// A terse object update, used when a transformation matrix or
/// velocity/acceleration for an object changes but nothing else
/// (scale/position/rotation/acceleration/velocity)
2007-01-19 20:53:05 +00:00
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ImprovedTerseObjectUpdateHandler ( object sender , PacketReceivedEventArgs e )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-01-30 12:47:47 +00:00
ImprovedTerseObjectUpdatePacket terse = ( ImprovedTerseObjectUpdatePacket ) packet ;
2009-03-18 19:31:39 +00:00
UpdateDilation ( simulator , terse . RegionData . TimeDilation ) ;
2022-10-10 16:08:14 -05:00
foreach ( var block in terse . ObjectData )
2006-10-21 02:52:28 +00:00
{
2007-01-30 12:47:47 +00:00
try
2006-10-21 02:52:28 +00:00
{
2007-04-20 16:03:24 +00:00
int pos = 4 ;
2008-10-06 22:34:38 +00:00
uint localid = Utils . BytesToUInt ( block . Data , 0 ) ;
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
// Check if we are interested in this update
2009-10-26 06:03:26 +00:00
if ( ! Client . Settings . ALWAYS_DECODE_OBJECTS
& & localid ! = Client . Self . localID
2009-10-27 07:01:48 +00:00
& & m_TerseObjectUpdate = = null )
2009-10-26 06:03:26 +00:00
{
2007-04-20 16:03:24 +00:00
continue ;
2009-10-26 06:03:26 +00:00
}
2007-02-28 03:47:46 +00:00
2007-04-20 16:03:24 +00:00
#region Decode update data
2009-10-27 07:01:48 +00:00
ObjectMovementUpdate update = new ObjectMovementUpdate ( ) ;
2007-04-20 16:03:24 +00:00
// LocalID
update . LocalID = localid ;
2007-01-30 12:47:47 +00:00
// State
update . State = block . Data [ pos + + ] ;
// Avatar boolean
update . Avatar = ( block . Data [ pos + + ] ! = 0 ) ;
// Collision normal for avatar
if ( update . Avatar )
2006-10-21 02:52:28 +00:00
{
2008-07-25 05:15:05 +00:00
update . CollisionPlane = new Vector4 ( block . Data , pos ) ;
2007-01-30 12:47:47 +00:00
pos + = 16 ;
2006-10-21 02:52:28 +00:00
}
2007-01-30 12:47:47 +00:00
// Position
2008-07-25 05:15:05 +00:00
update . Position = new Vector3 ( block . Data , pos ) ;
2007-01-30 12:47:47 +00:00
pos + = 12 ;
// Velocity
2008-07-25 05:15:05 +00:00
update . Velocity = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . Data , pos , - 128.0f , 128.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 2 , - 128.0f , 128.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 4 , - 128.0f , 128.0f ) ) ;
2007-01-30 12:47:47 +00:00
pos + = 6 ;
// Acceleration
2008-07-25 05:15:05 +00:00
update . Acceleration = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . Data , pos , - 64.0f , 64.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 2 , - 64.0f , 64.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 4 , - 64.0f , 64.0f ) ) ;
2007-01-30 12:47:47 +00:00
pos + = 6 ;
// Rotation (theta)
2008-07-25 05:15:05 +00:00
update . Rotation = new Quaternion (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . Data , pos , - 1.0f , 1.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 2 , - 1.0f , 1.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 4 , - 1.0f , 1.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 6 , - 1.0f , 1.0f ) ) ;
2007-01-30 12:47:47 +00:00
pos + = 8 ;
2009-03-10 01:54:45 +00:00
// Angular velocity (omega)
2008-07-25 05:15:05 +00:00
update . AngularVelocity = new Vector3 (
2008-10-06 22:34:38 +00:00
Utils . UInt16ToFloat ( block . Data , pos , - 64.0f , 64.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 2 , - 64.0f , 64.0f ) ,
Utils . UInt16ToFloat ( block . Data , pos + 4 , - 64.0f , 64.0f ) ) ;
2007-01-30 12:47:47 +00:00
pos + = 6 ;
// Textures
// FIXME: Why are we ignoring the first four bytes here?
2007-11-30 13:15:31 +00:00
if ( block . TextureEntry . Length ! = 0 )
2008-08-24 05:06:51 +00:00
update . Textures = new Primitive . TextureEntry ( block . TextureEntry , 4 , block . TextureEntry . Length - 4 ) ;
2007-01-30 12:47:47 +00:00
2007-04-20 16:03:24 +00:00
#endregion Decode update data
2007-04-06 21:02:20 +00:00
2009-11-03 07:56:34 +00:00
Primitive obj = ! Client . Settings . OBJECT_TRACKING ? null : ( update . Avatar ) ?
2009-03-18 19:31:39 +00:00
( Primitive ) GetAvatar ( simulator , update . LocalID , UUID . Zero ) :
2008-09-10 18:42:11 +00:00
( Primitive ) GetPrimitive ( simulator , update . LocalID , UUID . Zero ) ;
2007-04-06 21:02:20 +00:00
2009-06-27 22:53:48 +00:00
// Fire the pre-emptive notice (before we stomp the object)
2010-08-12 22:37:27 +00:00
EventHandler < TerseObjectUpdateEventArgs > handler = m_TerseObjectUpdate ;
if ( handler ! = null )
{
2019-10-20 21:22:13 -05:00
ThreadPool . QueueUserWorkItem ( delegate ( object o )
2022-10-10 16:08:14 -05:00
{ handler ( this , new TerseObjectUpdateEventArgs ( simulator , obj , update , terse . RegionData . TimeDilation ) ) ; } ) ;
2010-08-12 22:37:27 +00:00
}
2009-06-27 22:53:48 +00:00
2007-04-20 16:03:24 +00:00
#region Update Client . Self
2007-11-06 09:26:10 +00:00
if ( update . LocalID = = Client . Self . localID )
2007-04-20 16:03:24 +00:00
{
2007-11-06 09:26:10 +00:00
Client . Self . collisionPlane = update . CollisionPlane ;
Client . Self . relativePosition = update . Position ;
Client . Self . velocity = update . Velocity ;
Client . Self . acceleration = update . Acceleration ;
Client . Self . relativeRotation = update . Rotation ;
Client . Self . angularVelocity = update . AngularVelocity ;
2007-04-20 16:03:24 +00:00
}
2010-03-08 10:57:01 +00:00
#endregion Update Client . Self
if ( Client . Settings . OBJECT_TRACKING & & obj ! = null )
{
obj . Position = update . Position ;
obj . Rotation = update . Rotation ;
obj . Velocity = update . Velocity ;
obj . CollisionPlane = update . CollisionPlane ;
obj . Acceleration = update . Acceleration ;
obj . AngularVelocity = update . AngularVelocity ;
obj . PrimData . State = update . State ;
2010-08-20 11:49:43 +00:00
if ( update . Textures ! = null )
obj . Textures = update . Textures ;
2010-03-08 10:57:01 +00:00
}
2009-11-03 07:56:34 +00:00
2006-10-21 02:52:28 +00:00
}
2009-10-28 08:01:52 +00:00
catch ( Exception ex )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Logger . Log ( ex . Message , Helpers . LogLevel . Warning , Client , ex ) ;
2006-10-21 02:52:28 +00:00
}
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ObjectUpdateCompressedHandler ( object sender , PacketReceivedEventArgs e )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-04-20 16:03:24 +00:00
ObjectUpdateCompressedPacket update = ( ObjectUpdateCompressedPacket ) packet ;
2022-10-10 16:08:14 -05:00
foreach ( var block in update . ObjectData )
2006-10-21 02:52:28 +00:00
{
2007-04-20 16:03:24 +00:00
int i = 0 ;
2006-11-10 09:50:54 +00:00
2007-04-20 16:03:24 +00:00
try
2006-11-01 08:31:26 +00:00
{
2007-04-20 16:03:24 +00:00
// UUID
2008-07-25 05:15:05 +00:00
UUID FullID = new UUID ( block . Data , 0 ) ;
2007-04-20 16:03:24 +00:00
i + = 16 ;
// Local ID
uint LocalID = ( uint ) ( block . Data [ i + + ] + ( block . Data [ i + + ] < < 8 ) +
2022-10-10 16:08:14 -05:00
( block . Data [ i + + ] < < 16 ) + ( block . Data [ i + + ] < < 24 ) ) ;
2007-04-20 16:03:24 +00:00
// PCode
PCode pcode = ( PCode ) block . Data [ i + + ] ;
2006-11-02 12:40:44 +00:00
2007-04-20 16:03:24 +00:00
#region Relevance check
2008-12-18 21:45:38 +00:00
2007-04-20 16:03:24 +00:00
if ( ! Client . Settings . ALWAYS_DECODE_OBJECTS )
2006-11-02 12:40:44 +00:00
{
2007-01-30 23:13:02 +00:00
switch ( pcode )
2006-11-06 05:42:10 +00:00
{
2007-04-20 16:03:24 +00:00
case PCode . Grass :
case PCode . Tree :
case PCode . NewTree :
2007-01-30 23:13:02 +00:00
case PCode . Prim :
2009-10-27 07:01:48 +00:00
if ( m_ObjectUpdate = = null ) continue ;
2007-04-20 16:03:24 +00:00
break ;
}
}
2008-12-18 21:45:38 +00:00
2007-04-20 16:03:24 +00:00
#endregion Relevance check
2009-11-16 06:36:26 +00:00
bool isNew ;
lock ( simulator . ObjectsPrimitives . Dictionary )
2012-02-04 00:24:17 +00:00
isNew = ! simulator . ObjectsPrimitives . ContainsKey ( LocalID ) ;
2009-11-16 06:36:26 +00:00
2007-04-20 16:03:24 +00:00
Primitive prim = GetPrimitive ( simulator , LocalID , FullID ) ;
prim . LocalID = LocalID ;
prim . ID = FullID ;
2008-08-24 05:06:51 +00:00
prim . Flags = ( PrimFlags ) block . UpdateFlags ;
prim . PrimData . PCode = pcode ;
2007-04-20 16:03:24 +00:00
2008-12-18 21:45:38 +00:00
#region Decode block and update Prim
// State
prim . PrimData . State = block . Data [ i + + ] ;
// CRC
i + = 4 ;
// Material
prim . PrimData . Material = ( Material ) block . Data [ i + + ] ;
// Click action
prim . ClickAction = ( ClickAction ) block . Data [ i + + ] ;
// Scale
prim . Scale = new Vector3 ( block . Data , i ) ;
i + = 12 ;
// Position
prim . Position = new Vector3 ( block . Data , i ) ;
i + = 12 ;
// Rotation
prim . Rotation = new Quaternion ( block . Data , i , true ) ;
i + = 12 ;
// Compressed flags
CompressedFlags flags = ( CompressedFlags ) Utils . BytesToUInt ( block . Data , i ) ;
i + = 4 ;
prim . OwnerID = new UUID ( block . Data , i ) ;
i + = 16 ;
// Angular velocity
if ( ( flags & CompressedFlags . HasAngularVelocity ) ! = 0 )
2007-04-20 16:03:24 +00:00
{
2008-12-18 21:45:38 +00:00
prim . AngularVelocity = new Vector3 ( block . Data , i ) ;
i + = 12 ;
}
2007-04-20 16:03:24 +00:00
2008-12-18 21:45:38 +00:00
// Parent ID
if ( ( flags & CompressedFlags . HasParent ) ! = 0 )
{
prim . ParentID = ( uint ) ( block . Data [ i + + ] + ( block . Data [ i + + ] < < 8 ) +
2022-10-10 16:08:14 -05:00
( block . Data [ i + + ] < < 16 ) + ( block . Data [ i + + ] < < 24 ) ) ;
2008-12-18 21:45:38 +00:00
}
else
{
prim . ParentID = 0 ;
}
2006-11-25 20:25:02 +00:00
2008-12-18 21:45:38 +00:00
// Tree data
if ( ( flags & CompressedFlags . Tree ) ! = 0 )
{
2009-03-10 01:54:45 +00:00
prim . TreeSpecies = ( Tree ) block . Data [ i + + ] ;
2010-04-20 21:58:23 +00:00
//prim.ScratchPad = Utils.EmptyBytes;
2008-12-18 21:45:38 +00:00
}
// Scratch pad
else if ( ( flags & CompressedFlags . ScratchPad ) ! = 0 )
{
2009-03-10 01:54:45 +00:00
prim . TreeSpecies = ( Tree ) 0 ;
2008-12-18 21:45:38 +00:00
int size = block . Data [ i + + ] ;
2010-04-20 21:58:23 +00:00
//prim.ScratchPad = new byte[size];
//Buffer.BlockCopy(block.Data, i, prim.ScratchPad, 0, size);
2008-12-18 21:45:38 +00:00
i + = size ;
}
2010-04-20 21:58:23 +00:00
prim . ScratchPad = Utils . EmptyBytes ;
2006-10-27 10:40:04 +00:00
2008-12-18 21:45:38 +00:00
// Floating text
if ( ( flags & CompressedFlags . HasText ) ! = 0 )
{
2016-03-26 17:21:04 +09:00
int idx = i ;
2008-12-18 21:45:38 +00:00
while ( block . Data [ i ] ! = 0 )
{
i + + ;
}
2006-11-01 08:31:26 +00:00
2008-12-18 21:45:38 +00:00
// Floating text
2016-03-26 17:21:04 +09:00
prim . Text = Utils . BytesToString ( block . Data , idx , i - idx ) ;
i + + ;
2007-04-20 16:03:24 +00:00
2008-12-18 21:45:38 +00:00
// Text color
2016-03-26 17:21:04 +09:00
prim . TextColor = new Color4 ( block . Data , i , false , true ) ;
2008-12-18 21:45:38 +00:00
i + = 4 ;
}
else
{
2024-06-30 17:47:14 -05:00
prim . Text = string . Empty ;
2008-12-18 21:45:38 +00:00
}
2006-11-22 13:21:21 +00:00
2008-12-18 21:45:38 +00:00
// Media URL
if ( ( flags & CompressedFlags . MediaURL ) ! = 0 )
{
2016-03-26 17:21:04 +09:00
int idx = i ;
2008-12-18 21:45:38 +00:00
while ( block . Data [ i ] ! = 0 )
{
i + + ;
}
2006-10-27 10:40:04 +00:00
2016-03-26 17:21:04 +09:00
prim . MediaURL = Utils . BytesToString ( block . Data , idx , i - idx ) ;
i + + ;
2008-12-18 21:45:38 +00:00
}
2006-11-03 19:28:07 +00:00
2008-12-18 21:45:38 +00:00
// Particle system
if ( ( flags & CompressedFlags . HasParticles ) ! = 0 )
{
prim . ParticleSys = new Primitive . ParticleSystem ( block . Data , i ) ;
i + = 86 ;
}
2007-02-02 00:19:45 +00:00
2008-12-18 21:45:38 +00:00
// Extra parameters
i + = prim . SetExtraParamsFromBytes ( block . Data , i ) ;
2007-02-02 00:19:45 +00:00
2008-12-18 21:45:38 +00:00
//Sound data
if ( ( flags & CompressedFlags . HasSound ) ! = 0 )
{
prim . Sound = new UUID ( block . Data , i ) ;
i + = 16 ;
prim . SoundGain = Utils . BytesToFloat ( block . Data , i ) ;
i + = 4 ;
2009-03-10 01:54:45 +00:00
prim . SoundFlags = ( SoundFlags ) block . Data [ i + + ] ;
2008-12-18 21:45:38 +00:00
prim . SoundRadius = Utils . BytesToFloat ( block . Data , i ) ;
i + = 4 ;
}
2006-10-27 10:40:04 +00:00
2008-12-18 21:45:38 +00:00
// Name values
if ( ( flags & CompressedFlags . HasNameValues ) ! = 0 )
{
2024-06-30 17:47:14 -05:00
string text = string . Empty ;
2008-12-18 21:45:38 +00:00
while ( block . Data [ i ] ! = 0 )
{
text + = ( char ) block . Data [ i ] ;
i + + ;
}
i + + ;
2007-01-30 23:13:02 +00:00
2008-12-18 21:45:38 +00:00
// Parse the name values
if ( text . Length > 0 )
{
string [ ] lines = text . Split ( '\n' ) ;
prim . NameValues = new NameValue [ lines . Length ] ;
2006-11-22 13:21:21 +00:00
2008-12-18 21:45:38 +00:00
for ( int j = 0 ; j < lines . Length ; j + + )
{
2024-06-30 17:47:14 -05:00
if ( ! string . IsNullOrEmpty ( lines [ j ] ) )
2006-11-22 13:21:21 +00:00
{
2008-12-18 21:45:38 +00:00
NameValue nv = new NameValue ( lines [ j ] ) ;
prim . NameValues [ j ] = nv ;
2007-01-30 23:13:02 +00:00
}
2007-04-20 16:03:24 +00:00
}
2008-12-18 21:45:38 +00:00
}
}
2006-11-06 05:42:10 +00:00
2008-12-18 21:45:38 +00:00
prim . PrimData . PathCurve = ( PathCurve ) block . Data [ i + + ] ;
ushort pathBegin = Utils . BytesToUInt16 ( block . Data , i ) ; i + = 2 ;
prim . PrimData . PathBegin = Primitive . UnpackBeginCut ( pathBegin ) ;
ushort pathEnd = Utils . BytesToUInt16 ( block . Data , i ) ; i + = 2 ;
prim . PrimData . PathEnd = Primitive . UnpackEndCut ( pathEnd ) ;
prim . PrimData . PathScaleX = Primitive . UnpackPathScale ( block . Data [ i + + ] ) ;
prim . PrimData . PathScaleY = Primitive . UnpackPathScale ( block . Data [ i + + ] ) ;
prim . PrimData . PathShearX = Primitive . UnpackPathShear ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathShearY = Primitive . UnpackPathShear ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathTwist = Primitive . UnpackPathTwist ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathTwistBegin = Primitive . UnpackPathTwist ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathRadiusOffset = Primitive . UnpackPathTwist ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathTaperX = Primitive . UnpackPathTaper ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathTaperY = Primitive . UnpackPathTaper ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . PathRevolutions = Primitive . UnpackPathRevolutions ( block . Data [ i + + ] ) ;
prim . PrimData . PathSkew = Primitive . UnpackPathTwist ( ( sbyte ) block . Data [ i + + ] ) ;
prim . PrimData . profileCurve = block . Data [ i + + ] ;
ushort profileBegin = Utils . BytesToUInt16 ( block . Data , i ) ; i + = 2 ;
prim . PrimData . ProfileBegin = Primitive . UnpackBeginCut ( profileBegin ) ;
ushort profileEnd = Utils . BytesToUInt16 ( block . Data , i ) ; i + = 2 ;
prim . PrimData . ProfileEnd = Primitive . UnpackEndCut ( profileEnd ) ;
ushort profileHollow = Utils . BytesToUInt16 ( block . Data , i ) ; i + = 2 ;
prim . PrimData . ProfileHollow = Primitive . UnpackProfileHollow ( profileHollow ) ;
// TextureEntry
int textureEntryLength = ( int ) Utils . BytesToUInt ( block . Data , i ) ;
i + = 4 ;
prim . Textures = new Primitive . TextureEntry ( block . Data , i , textureEntryLength ) ;
i + = textureEntryLength ;
// Texture animation
if ( ( flags & CompressedFlags . TextureAnimation ) ! = 0 )
{
//int textureAnimLength = (int)Utils.BytesToUIntBig(block.Data, i);
i + = 4 ;
prim . TextureAnim = new Primitive . TextureAnimation ( block . Data , i ) ;
}
2007-04-13 20:02:21 +00:00
2008-12-18 21:45:38 +00:00
#endregion
2007-04-13 20:02:21 +00:00
2011-08-08 21:36:24 +00:00
prim . IsAttachment = ( flags & CompressedFlags . HasNameValues ) ! = 0 & & prim . ParentID ! = 0 ;
2007-01-31 00:09:22 +00:00
2011-08-08 21:36:24 +00:00
#region Raise Events
2009-11-16 06:36:26 +00:00
2010-08-12 22:37:27 +00:00
EventHandler < PrimEventArgs > handler = m_ObjectUpdate ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , new PrimEventArgs ( simulator , prim , update . RegionData . TimeDilation , isNew , prim . IsAttachment ) ) ;
2007-04-20 16:03:24 +00:00
2008-12-18 21:45:38 +00:00
#endregion
2007-04-20 16:03:24 +00:00
}
2009-10-28 08:01:52 +00:00
catch ( IndexOutOfRangeException ex )
2007-04-20 16:03:24 +00:00
{
2009-10-28 08:01:52 +00:00
Logger . Log ( "Error decoding an ObjectUpdateCompressed packet" , Helpers . LogLevel . Warning , Client , ex ) ;
2008-05-06 23:57:26 +00:00
Logger . Log ( block , Helpers . LogLevel . Warning ) ;
2006-11-01 08:31:26 +00:00
}
2006-10-21 02:52:28 +00:00
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ObjectUpdateCachedHandler ( object sender , PacketReceivedEventArgs e )
2006-10-21 02:52:28 +00:00
{
2007-04-01 09:52:13 +00:00
if ( Client . Settings . ALWAYS_REQUEST_OBJECTS )
2006-10-21 02:52:28 +00:00
{
2012-06-05 14:09:33 -07:00
bool cachedPrimitives = Client . Settings . CACHE_PRIMITIVES ;
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2006-11-06 05:42:10 +00:00
ObjectUpdateCachedPacket update = ( ObjectUpdateCachedPacket ) packet ;
2007-08-20 09:26:21 +00:00
List < uint > ids = new List < uint > ( update . ObjectData . Length ) ;
2006-10-21 02:52:28 +00:00
2012-06-05 14:09:33 -07:00
// Object caching is implemented when Client.Settings.PRIMITIVES_FACTORY is True, otherwise request updates for all of these objects
2022-10-10 16:08:14 -05:00
foreach ( var odb in update . ObjectData )
2006-11-06 05:42:10 +00:00
{
2022-10-10 16:08:14 -05:00
uint localID = odb . ID ;
2006-11-06 05:42:10 +00:00
2012-06-05 14:09:33 -07:00
if ( cachedPrimitives )
{
if ( ! simulator . DataPool . NeedsRequest ( localID ) )
{
continue ;
}
}
ids . Add ( localID ) ;
}
2006-11-06 05:42:10 +00:00
RequestObjects ( simulator , ids ) ;
}
2006-10-21 02:52:28 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void KillObjectHandler ( object sender , PacketReceivedEventArgs e )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-08-20 09:26:21 +00:00
KillObjectPacket kill = ( KillObjectPacket ) packet ;
2008-03-12 19:07:41 +00:00
// Notify first, so that handler has a chance to get a
// reference from the ObjectTracker to the object being killed
2013-03-04 08:33:08 +01:00
uint [ ] killed = new uint [ kill . ObjectData . Length ] ;
2008-03-12 19:07:41 +00:00
for ( int i = 0 ; i < kill . ObjectData . Length ; i + + )
2009-10-26 06:03:26 +00:00
{
OnKillObject ( new KillObjectEventArgs ( simulator , kill . ObjectData [ i ] . ID ) ) ;
2013-03-04 08:33:08 +01:00
killed [ i ] = kill . ObjectData [ i ] . ID ;
2009-10-26 06:03:26 +00:00
}
2013-03-04 08:33:08 +01:00
OnKillObjects ( new KillObjectsEventArgs ( e . Simulator , killed ) ) ;
2010-03-08 10:57:01 +00:00
2008-03-12 19:07:41 +00:00
2008-06-09 23:14:04 +00:00
lock ( simulator . ObjectsPrimitives . Dictionary )
2006-10-21 02:52:28 +00:00
{
2008-10-25 16:19:15 +00:00
List < uint > removeAvatars = new List < uint > ( ) ;
2008-06-09 23:14:04 +00:00
List < uint > removePrims = new List < uint > ( ) ;
if ( Client . Settings . OBJECT_TRACKING )
2008-01-03 21:55:49 +00:00
{
2008-06-05 20:25:59 +00:00
uint localID ;
2022-10-10 16:08:14 -05:00
foreach ( var odb in kill . ObjectData )
2007-08-23 18:54:43 +00:00
{
2022-10-10 16:08:14 -05:00
localID = odb . ID ;
2008-01-03 21:55:49 +00:00
2008-10-25 16:19:15 +00:00
if ( simulator . ObjectsPrimitives . Dictionary . ContainsKey ( localID ) )
removePrims . Add ( localID ) ;
2008-05-21 03:51:03 +00:00
2008-06-09 23:14:04 +00:00
foreach ( KeyValuePair < uint , Primitive > prim in simulator . ObjectsPrimitives . Dictionary )
2008-05-21 03:51:03 +00:00
{
2008-06-09 23:14:04 +00:00
if ( prim . Value . ParentID = = localID )
2008-05-21 03:51:03 +00:00
{
2010-03-08 10:57:01 +00:00
OnKillObject ( new KillObjectEventArgs ( simulator , prim . Key ) ) ;
2008-06-09 23:14:04 +00:00
removePrims . Add ( prim . Key ) ;
2008-05-21 03:51:03 +00:00
}
2008-06-09 23:14:04 +00:00
}
2007-08-23 18:54:43 +00:00
}
2008-01-03 21:55:49 +00:00
}
2008-06-05 20:25:59 +00:00
2008-06-09 23:14:04 +00:00
if ( Client . Settings . AVATAR_TRACKING )
2008-01-03 21:55:49 +00:00
{
2008-10-25 16:19:15 +00:00
lock ( simulator . ObjectsAvatars . Dictionary )
2007-08-23 18:54:43 +00:00
{
2008-10-25 16:19:15 +00:00
uint localID ;
2022-10-10 16:08:14 -05:00
foreach ( var odb in kill . ObjectData )
2008-10-25 16:19:15 +00:00
{
2022-10-10 16:08:14 -05:00
localID = odb . ID ;
2007-08-20 09:26:21 +00:00
2008-10-25 16:19:15 +00:00
if ( simulator . ObjectsAvatars . Dictionary . ContainsKey ( localID ) )
removeAvatars . Add ( localID ) ;
2008-05-21 03:51:03 +00:00
2008-10-25 16:19:15 +00:00
List < uint > rootPrims = new List < uint > ( ) ;
2008-06-05 20:25:59 +00:00
2022-10-10 16:08:14 -05:00
foreach ( var prim in simulator . ObjectsPrimitives . Dictionary . Where ( prim = > prim . Value . ParentID = = localID ) )
2008-05-21 03:51:03 +00:00
{
2022-10-10 16:08:14 -05:00
OnKillObject ( new KillObjectEventArgs ( simulator , prim . Key ) ) ;
removePrims . Add ( prim . Key ) ;
rootPrims . Add ( prim . Key ) ;
2008-06-09 23:14:04 +00:00
}
2008-06-05 20:25:59 +00:00
2022-10-10 16:08:14 -05:00
foreach ( var prim in simulator . ObjectsPrimitives . Dictionary . Where ( prim = > rootPrims . Contains ( prim . Value . ParentID ) ) )
2008-05-21 03:51:03 +00:00
{
2022-10-10 16:08:14 -05:00
OnKillObject ( new KillObjectEventArgs ( simulator , prim . Key ) ) ;
removePrims . Add ( prim . Key ) ;
2008-06-09 23:14:04 +00:00
}
2008-05-21 03:51:03 +00:00
}
2008-11-09 18:51:38 +00:00
//Do the actual removing outside of the loops but still inside the lock.
//This safely prevents the collection from being modified during a loop.
foreach ( uint removeID in removeAvatars )
simulator . ObjectsAvatars . Dictionary . Remove ( removeID ) ;
2008-01-03 21:55:49 +00:00
}
2007-08-23 18:54:43 +00:00
}
2008-06-09 23:14:04 +00:00
2012-06-05 14:09:33 -07:00
if ( Client . Settings . CACHE_PRIMITIVES )
{
simulator . DataPool . ReleasePrims ( removePrims ) ;
}
2008-06-09 23:14:04 +00:00
foreach ( uint removeID in removePrims )
2008-11-09 18:51:38 +00:00
simulator . ObjectsPrimitives . Dictionary . Remove ( removeID ) ;
2007-08-23 18:54:43 +00:00
}
2007-01-19 20:53:05 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ObjectPropertiesHandler ( object sender , PacketReceivedEventArgs e )
2007-02-03 20:34:49 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-10-26 06:03:26 +00:00
ObjectPropertiesPacket op = ( ObjectPropertiesPacket ) packet ;
2007-02-03 20:34:49 +00:00
ObjectPropertiesPacket . ObjectDataBlock [ ] datablocks = op . ObjectData ;
2022-10-10 16:08:14 -05:00
foreach ( var objectData in datablocks )
2007-02-03 20:34:49 +00:00
{
2022-10-10 16:08:14 -05:00
Primitive . ObjectProperties props = new Primitive . ObjectProperties
{
ObjectID = objectData . ObjectID ,
AggregatePerms = objectData . AggregatePerms ,
AggregatePermTextures = objectData . AggregatePermTextures ,
AggregatePermTexturesOwner = objectData . AggregatePermTexturesOwner ,
Permissions = new Permissions ( objectData . BaseMask , objectData . EveryoneMask , objectData . GroupMask ,
objectData . NextOwnerMask , objectData . OwnerMask ) ,
Category = ( ObjectCategory ) objectData . Category ,
CreationDate = Utils . UnixTimeToDateTime ( ( uint ) objectData . CreationDate ) ,
CreatorID = objectData . CreatorID ,
Description = Utils . BytesToString ( objectData . Description ) ,
FolderID = objectData . FolderID ,
FromTaskID = objectData . FromTaskID ,
GroupID = objectData . GroupID ,
InventorySerial = objectData . InventorySerial ,
ItemID = objectData . ItemID ,
LastOwnerID = objectData . LastOwnerID ,
Name = Utils . BytesToString ( objectData . Name ) ,
OwnerID = objectData . OwnerID ,
OwnershipCost = objectData . OwnershipCost ,
SalePrice = objectData . SalePrice ,
SaleType = ( SaleType ) objectData . SaleType ,
SitName = Utils . BytesToString ( objectData . SitName ) ,
TouchName = Utils . BytesToString ( objectData . TouchName )
} ;
2007-02-03 20:34:49 +00:00
int numTextures = objectData . TextureID . Length / 16 ;
2008-07-25 05:15:05 +00:00
props . TextureIDs = new UUID [ numTextures ] ;
2007-02-03 20:34:49 +00:00
for ( int j = 0 ; j < numTextures ; + + j )
2008-07-25 05:15:05 +00:00
props . TextureIDs [ j ] = new UUID ( objectData . TextureID , j * 16 ) ;
2007-02-03 20:34:49 +00:00
2007-11-20 05:52:30 +00:00
if ( Client . Settings . OBJECT_TRACKING )
2007-11-06 09:26:10 +00:00
{
2009-10-26 06:03:26 +00:00
Primitive findPrim = simulator . ObjectsPrimitives . Find (
2020-05-09 12:59:06 -05:00
prim = > prim . ID = = props . ObjectID ) ;
2007-11-20 05:52:30 +00:00
if ( findPrim ! = null )
2007-11-06 09:26:10 +00:00
{
2009-10-26 06:03:26 +00:00
OnObjectPropertiesUpdated ( new ObjectPropertiesUpdatedEventArgs ( simulator , findPrim , props ) ) ;
lock ( simulator . ObjectsPrimitives . Dictionary )
2007-11-20 05:52:30 +00:00
{
2009-10-26 06:03:26 +00:00
if ( simulator . ObjectsPrimitives . Dictionary . ContainsKey ( findPrim . LocalID ) )
simulator . ObjectsPrimitives . Dictionary [ findPrim . LocalID ] . Properties = props ;
2007-11-20 05:52:30 +00:00
}
2007-11-06 09:26:10 +00:00
}
2007-11-20 05:52:30 +00:00
}
2007-11-29 19:44:34 +00:00
2009-10-26 06:03:26 +00:00
OnObjectProperties ( new ObjectPropertiesEventArgs ( simulator , props ) ) ;
2007-02-03 20:34:49 +00:00
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ObjectPropertiesFamilyHandler ( object sender , PacketReceivedEventArgs e )
2007-01-19 20:53:05 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
ObjectPropertiesFamilyPacket op = ( ObjectPropertiesFamilyPacket ) packet ;
2008-08-24 05:06:51 +00:00
Primitive . ObjectProperties props = new Primitive . ObjectProperties ( ) ;
2008-08-28 02:38:32 +00:00
ReportType requestType = ( ReportType ) op . ObjectData . RequestFlags ;
2007-01-19 20:53:05 +00:00
2008-08-24 05:06:51 +00:00
props . ObjectID = op . ObjectData . ObjectID ;
props . Category = ( ObjectCategory ) op . ObjectData . Category ;
2008-08-12 22:38:02 +00:00
props . Description = Utils . BytesToString ( op . ObjectData . Description ) ;
2007-01-19 20:53:05 +00:00
props . GroupID = op . ObjectData . GroupID ;
props . LastOwnerID = op . ObjectData . LastOwnerID ;
2008-08-12 22:38:02 +00:00
props . Name = Utils . BytesToString ( op . ObjectData . Name ) ;
2007-01-19 20:53:05 +00:00
props . OwnerID = op . ObjectData . OwnerID ;
props . OwnershipCost = op . ObjectData . OwnershipCost ;
props . SalePrice = op . ObjectData . SalePrice ;
2008-08-24 05:06:51 +00:00
props . SaleType = ( SaleType ) op . ObjectData . SaleType ;
2007-09-01 07:52:55 +00:00
props . Permissions . BaseMask = ( PermissionMask ) op . ObjectData . BaseMask ;
props . Permissions . EveryoneMask = ( PermissionMask ) op . ObjectData . EveryoneMask ;
props . Permissions . GroupMask = ( PermissionMask ) op . ObjectData . GroupMask ;
props . Permissions . NextOwnerMask = ( PermissionMask ) op . ObjectData . NextOwnerMask ;
props . Permissions . OwnerMask = ( PermissionMask ) op . ObjectData . OwnerMask ;
2007-01-19 20:53:05 +00:00
2007-11-20 05:52:30 +00:00
if ( Client . Settings . OBJECT_TRACKING )
{
2009-10-28 08:01:52 +00:00
Primitive findPrim = simulator . ObjectsPrimitives . Find (
2020-05-09 12:59:06 -05:00
prim = > prim . ID = = op . ObjectData . ObjectID ) ;
2007-11-20 05:52:30 +00:00
if ( findPrim ! = null )
{
2009-10-28 08:01:52 +00:00
lock ( simulator . ObjectsPrimitives . Dictionary )
2007-11-20 05:52:30 +00:00
{
2009-10-28 08:01:52 +00:00
if ( simulator . ObjectsPrimitives . Dictionary . ContainsKey ( findPrim . LocalID ) )
2009-01-05 18:01:37 +00:00
{
2022-11-20 00:08:33 -06:00
if ( simulator . ObjectsPrimitives . Dictionary [ findPrim . LocalID ] . Properties = = null )
simulator . ObjectsPrimitives . Dictionary [ findPrim . LocalID ] . Properties = new Primitive . ObjectProperties ( ) ;
2009-10-28 08:01:52 +00:00
simulator . ObjectsPrimitives . Dictionary [ findPrim . LocalID ] . Properties . SetFamilyProperties ( props ) ;
2009-01-05 18:01:37 +00:00
}
2007-11-20 05:52:30 +00:00
}
}
}
2009-10-28 08:01:52 +00:00
OnObjectPropertiesFamily ( new ObjectPropertiesFamilyEventArgs ( simulator , props , requestType ) ) ;
2007-01-19 20:53:05 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void PayPriceReplyHandler ( object sender , PacketReceivedEventArgs e )
2009-06-08 09:59:30 +00:00
{
2009-10-26 06:03:26 +00:00
if ( m_PayPriceReply ! = null )
2009-06-08 09:59:30 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-06-08 09:59:30 +00:00
PayPriceReplyPacket p = ( PayPriceReplyPacket ) packet ;
UUID objectID = p . ObjectData . ObjectID ;
int defaultPrice = p . ObjectData . DefaultPayPrice ;
int [ ] buttonPrices = new int [ p . ButtonData . Length ] ;
for ( int i = 0 ; i < p . ButtonData . Length ; i + + )
{
buttonPrices [ i ] = p . ButtonData [ i ] . PayButton ;
}
2009-10-26 06:03:26 +00:00
OnPayPriceReply ( new PayPriceReplyEventArgs ( simulator , objectID , defaultPrice , buttonPrices ) ) ;
2009-06-08 09:59:30 +00:00
}
}
2011-05-20 09:26:13 +00:00
/// <summary>
2022-11-20 00:08:33 -06:00
///
2011-05-20 09:26:13 +00:00
/// </summary>
/// <param name="capsKey"></param>
/// <param name="message"></param>
/// <param name="simulator"></param>
protected void ObjectPhysicsPropertiesHandler ( string capsKey , IMessage message , Simulator simulator )
{
ObjectPhysicsPropertiesMessage msg = ( ObjectPhysicsPropertiesMessage ) message ;
if ( Client . Settings . OBJECT_TRACKING )
{
2022-10-10 16:08:14 -05:00
foreach ( var prop in msg . ObjectPhysicsProperties )
2011-05-20 09:26:13 +00:00
{
lock ( simulator . ObjectsPrimitives . Dictionary )
{
2022-10-10 16:08:14 -05:00
if ( simulator . ObjectsPrimitives . Dictionary . ContainsKey ( prop . LocalID ) )
2011-05-20 09:26:13 +00:00
{
2022-10-10 16:08:14 -05:00
simulator . ObjectsPrimitives . Dictionary [ prop . LocalID ] . PhysicsProps = prop ;
2011-05-20 09:26:13 +00:00
}
}
}
}
2011-05-20 10:05:00 +00:00
if ( m_PhysicsProperties ! = null )
{
2022-10-10 16:08:14 -05:00
foreach ( var prop in msg . ObjectPhysicsProperties )
2011-05-20 10:05:00 +00:00
{
2022-10-10 16:08:14 -05:00
OnPhysicsProperties ( new PhysicsPropertiesEventArgs ( simulator , prop ) ) ;
2011-05-20 10:05:00 +00:00
}
}
2011-05-20 09:26:13 +00:00
}
2007-08-20 09:26:21 +00:00
#endregion Packet Handlers
2007-01-19 20:53:05 +00:00
#region Utility Functions
2007-01-29 22:20:12 +00:00
2007-07-08 04:35:04 +00:00
/// <summary>
2008-08-30 23:52:00 +00:00
/// Setup construction data for a basic primitive shape
2007-07-08 04:35:04 +00:00
/// </summary>
2008-08-30 23:52:00 +00:00
/// <param name="type">Primitive shape to construct</param>
/// <returns>Construction data that can be plugged into a <seealso cref="Primitive"/></returns>
public static Primitive . ConstructionData BuildBasicShape ( PrimType type )
2007-07-08 04:35:04 +00:00
{
2008-08-24 05:06:51 +00:00
Primitive . ConstructionData prim = new Primitive . ConstructionData ( ) ;
2007-11-30 00:25:08 +00:00
prim . PCode = PCode . Prim ;
2008-08-24 05:06:51 +00:00
prim . Material = Material . Wood ;
2008-08-30 23:52:00 +00:00
switch ( type )
{
case PrimType . Box :
prim . ProfileCurve = ProfileCurve . Square ;
prim . PathCurve = PathCurve . Line ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 1f ;
prim . PathRevolutions = 1f ;
break ;
case PrimType . Cylinder :
prim . ProfileCurve = ProfileCurve . Circle ;
prim . PathCurve = PathCurve . Line ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 1f ;
prim . PathRevolutions = 1f ;
break ;
case PrimType . Prism :
2012-05-21 19:59:34 +00:00
prim . ProfileCurve = ProfileCurve . EqualTriangle ;
2008-08-30 23:52:00 +00:00
prim . PathCurve = PathCurve . Line ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 0f ;
prim . PathScaleY = 0f ;
prim . PathRevolutions = 1f ;
break ;
case PrimType . Ring :
prim . ProfileCurve = ProfileCurve . EqualTriangle ;
prim . PathCurve = PathCurve . Circle ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 0.25f ;
prim . PathRevolutions = 1f ;
break ;
case PrimType . Sphere :
prim . ProfileCurve = ProfileCurve . HalfCircle ;
prim . PathCurve = PathCurve . Circle ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 1f ;
prim . PathRevolutions = 1f ;
break ;
case PrimType . Torus :
prim . ProfileCurve = ProfileCurve . Circle ;
prim . PathCurve = PathCurve . Circle ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 0.25f ;
prim . PathRevolutions = 1f ;
break ;
case PrimType . Tube :
prim . ProfileCurve = ProfileCurve . Square ;
prim . PathCurve = PathCurve . Circle ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 0.25f ;
prim . PathRevolutions = 1f ;
break ;
2010-08-16 17:59:01 +00:00
case PrimType . Sculpt :
prim . ProfileCurve = ProfileCurve . Circle ;
prim . PathCurve = PathCurve . Circle ;
prim . ProfileEnd = 1f ;
prim . PathEnd = 1f ;
prim . PathScaleX = 1f ;
prim . PathScaleY = 0.5f ;
prim . PathRevolutions = 1f ;
break ;
2008-08-30 23:52:00 +00:00
default :
2022-04-23 10:38:11 -05:00
throw new NotSupportedException ( "Unsupported shape: " + type ) ;
2008-08-30 23:52:00 +00:00
}
2007-07-08 04:35:04 +00:00
return prim ;
}
2008-05-04 11:01:48 +00:00
/// <summary>
///
/// </summary>
/// <param name="sim"></param>
/// <param name="av"></param>
/// <param name="localid"></param>
/// <param name="oldSeatID"></param>
2007-11-06 09:26:10 +00:00
protected void SetAvatarSittingOn ( Simulator sim , Avatar av , uint localid , uint oldSeatID )
2007-01-19 20:53:05 +00:00
{
2009-10-06 00:09:53 +00:00
if ( Client . Network . CurrentSim = = sim & & av . LocalID = = Client . Self . localID )
{
Client . Self . sittingOn = localid ;
}
2010-03-08 10:57:01 +00:00
2008-08-24 05:06:51 +00:00
av . ParentID = localid ;
2010-03-08 10:57:01 +00:00
2009-03-18 19:31:39 +00:00
2009-10-26 06:03:26 +00:00
if ( m_AvatarSitChanged ! = null & & oldSeatID ! = localid )
2007-11-06 09:26:10 +00:00
{
2009-10-26 06:03:26 +00:00
OnAvatarSitChanged ( new AvatarSitChangedEventArgs ( sim , av , localid , oldSeatID ) ) ;
2007-11-06 09:26:10 +00:00
}
2007-01-19 20:53:05 +00:00
}
2007-01-29 22:20:12 +00:00
2008-05-04 11:01:48 +00:00
/// <summary>
///
/// </summary>
/// <param name="s"></param>
/// <param name="dilation"></param>
2009-03-18 19:31:39 +00:00
protected void UpdateDilation ( Simulator s , uint dilation )
{
2007-08-20 09:26:21 +00:00
s . Stats . Dilation = ( float ) dilation / 65535.0f ;
2007-04-09 08:03:12 +00:00
}
2009-03-18 19:31:39 +00:00
/// <summary>
/// Set the Shape data of an object
/// </summary>
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="prim">Data describing the prim shape</param>
public void SetShape ( Simulator simulator , uint localID , Primitive . ConstructionData prim )
{
ObjectShapePacket shape = new ObjectShapePacket ( ) ;
shape . AgentData . AgentID = Client . Self . AgentID ;
shape . AgentData . SessionID = Client . Self . SessionID ;
shape . ObjectData = new OpenMetaverse . Packets . ObjectShapePacket . ObjectDataBlock [ 1 ] ;
shape . ObjectData [ 0 ] = new OpenMetaverse . Packets . ObjectShapePacket . ObjectDataBlock ( ) ;
shape . ObjectData [ 0 ] . ObjectLocalID = localID ;
shape . ObjectData [ 0 ] . PathCurve = ( byte ) prim . PathCurve ;
shape . ObjectData [ 0 ] . PathBegin = Primitive . PackBeginCut ( prim . PathBegin ) ;
shape . ObjectData [ 0 ] . PathEnd = Primitive . PackEndCut ( prim . PathEnd ) ;
shape . ObjectData [ 0 ] . PathScaleX = Primitive . PackPathScale ( prim . PathScaleX ) ;
shape . ObjectData [ 0 ] . PathScaleY = Primitive . PackPathScale ( prim . PathScaleY ) ;
shape . ObjectData [ 0 ] . PathShearX = ( byte ) Primitive . PackPathShear ( prim . PathShearX ) ;
shape . ObjectData [ 0 ] . PathShearY = ( byte ) Primitive . PackPathShear ( prim . PathShearY ) ;
shape . ObjectData [ 0 ] . PathTwist = Primitive . PackPathTwist ( prim . PathTwist ) ;
shape . ObjectData [ 0 ] . PathTwistBegin = Primitive . PackPathTwist ( prim . PathTwistBegin ) ;
shape . ObjectData [ 0 ] . PathRadiusOffset = Primitive . PackPathTwist ( prim . PathRadiusOffset ) ;
shape . ObjectData [ 0 ] . PathTaperX = Primitive . PackPathTaper ( prim . PathTaperX ) ;
shape . ObjectData [ 0 ] . PathTaperY = Primitive . PackPathTaper ( prim . PathTaperY ) ;
shape . ObjectData [ 0 ] . PathRevolutions = Primitive . PackPathRevolutions ( prim . PathRevolutions ) ;
shape . ObjectData [ 0 ] . PathSkew = Primitive . PackPathTwist ( prim . PathSkew ) ;
shape . ObjectData [ 0 ] . ProfileCurve = prim . profileCurve ;
shape . ObjectData [ 0 ] . ProfileBegin = Primitive . PackBeginCut ( prim . ProfileBegin ) ;
shape . ObjectData [ 0 ] . ProfileEnd = Primitive . PackEndCut ( prim . ProfileEnd ) ;
shape . ObjectData [ 0 ] . ProfileHollow = Primitive . PackProfileHollow ( prim . ProfileHollow ) ;
Client . Network . SendPacket ( shape , simulator ) ;
}
/// <summary>
/// Set the Material data of an object
/// </summary>
/// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
/// <param name="localID">The objects ID which is local to the simulator the object is in</param>
/// <param name="material">The new material of the object</param>
public void SetMaterial ( Simulator simulator , uint localID , Material material )
{
ObjectMaterialPacket matPacket = new ObjectMaterialPacket ( ) ;
matPacket . AgentData . AgentID = Client . Self . AgentID ;
matPacket . AgentData . SessionID = Client . Self . SessionID ;
matPacket . ObjectData = new ObjectMaterialPacket . ObjectDataBlock [ 1 ] ;
matPacket . ObjectData [ 0 ] = new ObjectMaterialPacket . ObjectDataBlock ( ) ;
matPacket . ObjectData [ 0 ] . ObjectLocalID = localID ;
matPacket . ObjectData [ 0 ] . Material = ( byte ) material ;
Client . Network . SendPacket ( matPacket , simulator ) ;
}
2007-08-20 09:26:21 +00:00
#endregion Utility Functions
2010-03-08 10:57:01 +00:00
2007-08-20 09:26:21 +00:00
#region Object Tracking Link
2007-01-31 00:09:22 +00:00
2012-05-30 16:01:46 -07:00
/// <summary>
2008-05-04 11:01:48 +00:00
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="localID"></param>
/// <param name="fullID"></param>
/// <returns></returns>
2012-06-05 14:09:33 -07:00
protected Primitive GetPrimitive ( Simulator simulator , uint localID , UUID fullID )
{
return GetPrimitive ( simulator , localID , fullID , true ) ;
}
2012-05-30 16:01:46 -07:00
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
2012-06-05 14:09:33 -07:00
/// <param name="localID"></param>
/// <param name="fullID"></param>
2012-05-30 16:01:46 -07:00
/// <param name="createIfMissing"></param>
2012-06-05 14:09:33 -07:00
/// <returns></returns>
2012-05-30 16:01:46 -07:00
public Primitive GetPrimitive ( Simulator simulator , uint localID , UUID fullID , bool createIfMissing )
2007-01-31 00:09:22 +00:00
{
2007-08-23 17:41:57 +00:00
if ( Client . Settings . OBJECT_TRACKING )
2007-08-20 09:26:21 +00:00
{
2009-05-24 02:42:07 +00:00
lock ( simulator . ObjectsPrimitives . Dictionary )
2007-08-23 17:41:57 +00:00
{
2009-05-24 02:42:07 +00:00
Primitive prim ;
if ( simulator . ObjectsPrimitives . Dictionary . TryGetValue ( localID , out prim ) )
{
return prim ;
}
else
2012-06-05 14:09:33 -07:00
{
if ( ! createIfMissing ) return null ;
if ( Client . Settings . CACHE_PRIMITIVES )
{
prim = simulator . DataPool . MakePrimitive ( localID ) ;
}
else
{
prim = new Primitive ( ) ;
prim . LocalID = localID ;
prim . RegionHandle = simulator . Handle ;
}
prim . ActiveClients + + ;
2009-05-24 02:42:07 +00:00
prim . ID = fullID ;
2008-01-03 21:55:49 +00:00
simulator . ObjectsPrimitives . Dictionary [ localID ] = prim ;
2007-08-23 17:41:57 +00:00
2009-05-24 02:42:07 +00:00
return prim ;
}
2007-08-23 17:41:57 +00:00
}
2007-08-20 09:26:21 +00:00
}
else
{
2007-08-23 17:41:57 +00:00
return new Primitive ( ) ;
2007-08-20 09:26:21 +00:00
}
2007-01-31 00:09:22 +00:00
}
2008-05-04 11:01:48 +00:00
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="localID"></param>
/// <param name="fullID"></param>
/// <returns></returns>
2008-07-25 05:15:05 +00:00
protected Avatar GetAvatar ( Simulator simulator , uint localID , UUID fullID )
2007-01-31 00:47:33 +00:00
{
2008-05-13 22:34:09 +00:00
if ( Client . Settings . AVATAR_TRACKING )
2007-08-20 09:26:21 +00:00
{
2009-05-24 02:42:07 +00:00
lock ( simulator . ObjectsAvatars . Dictionary )
2007-08-23 17:41:57 +00:00
{
2009-05-24 02:42:07 +00:00
Avatar avatar ;
if ( simulator . ObjectsAvatars . Dictionary . TryGetValue ( localID , out avatar ) )
{
return avatar ;
}
else
{
avatar = new Avatar ( ) ;
avatar . LocalID = localID ;
avatar . ID = fullID ;
2009-07-25 20:03:37 +00:00
avatar . RegionHandle = simulator . Handle ;
2009-05-24 02:42:07 +00:00
2008-01-03 21:55:49 +00:00
simulator . ObjectsAvatars . Dictionary [ localID ] = avatar ;
2007-08-23 17:41:57 +00:00
2009-05-24 02:42:07 +00:00
return avatar ;
}
2007-08-23 17:41:57 +00:00
}
2007-08-20 09:26:21 +00:00
}
else
{
2007-08-23 17:41:57 +00:00
return new Avatar ( ) ;
2007-08-20 09:26:21 +00:00
}
2007-01-31 00:47:33 +00:00
}
2007-08-20 09:26:21 +00:00
#endregion Object Tracking Link
2007-11-06 09:26:10 +00:00
protected void InterpolationTimer_Elapsed ( object obj )
2007-01-31 00:09:22 +00:00
{
2009-06-15 18:10:01 +00:00
int elapsed = 0 ;
2007-08-20 09:26:21 +00:00
if ( Client . Network . Connected )
{
2009-06-15 18:10:01 +00:00
int start = Environment . TickCount ;
2007-11-06 09:26:10 +00:00
int interval = Environment . TickCount - Client . Self . lastInterpolation ;
float seconds = ( float ) interval / 1000f ;
2007-01-31 00:09:22 +00:00
2007-08-20 09:26:21 +00:00
// Iterate through all of the simulators
2009-06-15 18:10:01 +00:00
Simulator [ ] sims = Client . Network . Simulators . ToArray ( ) ;
2022-10-10 16:08:14 -05:00
foreach ( var sim in sims )
2007-08-20 09:26:21 +00:00
{
2009-06-15 18:10:01 +00:00
float adjSeconds = seconds * sim . Stats . Dilation ;
// Iterate through all of this sims avatars
sim . ObjectsAvatars . ForEach (
delegate ( Avatar avatar )
{
#region Linear Motion
// Only do movement interpolation (extrapolation) when there is a non-zero velocity but
// no acceleration
if ( avatar . Acceleration ! = Vector3 . Zero & & avatar . Velocity = = Vector3 . Zero )
{
avatar . Position + = ( avatar . Velocity + avatar . Acceleration *
( 0.5f * ( adjSeconds - HAVOK_TIMESTEP ) ) ) * adjSeconds ;
avatar . Velocity + = avatar . Acceleration * adjSeconds ;
}
#endregion Linear Motion
}
) ;
2007-08-20 09:26:21 +00:00
2009-06-15 18:10:01 +00:00
// Iterate through all of this sims primitives
sim . ObjectsPrimitives . ForEach (
delegate ( Primitive prim )
{
if ( prim . Joint = = JointType . Invalid )
2007-08-20 09:26:21 +00:00
{
2009-06-15 18:10:01 +00:00
#region Angular Velocity
Vector3 angVel = prim . AngularVelocity ;
float omega = angVel . LengthSquared ( ) ;
if ( omega > 0.00001f )
{
omega = ( float ) Math . Sqrt ( omega ) ;
float angle = omega * adjSeconds ;
angVel * = 1.0f / omega ;
Quaternion dQ = Quaternion . CreateFromAxisAngle ( angVel , angle ) ;
prim . Rotation * = dQ ;
}
#endregion Angular Velocity
2007-08-20 09:26:21 +00:00
#region Linear Motion
// Only do movement interpolation (extrapolation) when there is a non-zero velocity but
// no acceleration
2009-06-15 18:10:01 +00:00
if ( prim . Acceleration ! = Vector3 . Zero & & prim . Velocity = = Vector3 . Zero )
2007-08-20 09:26:21 +00:00
{
2009-06-15 18:10:01 +00:00
prim . Position + = ( prim . Velocity + prim . Acceleration *
2008-08-01 20:22:22 +00:00
( 0.5f * ( adjSeconds - HAVOK_TIMESTEP ) ) ) * adjSeconds ;
2009-06-15 18:10:01 +00:00
prim . Velocity + = prim . Acceleration * adjSeconds ;
2007-08-20 09:26:21 +00:00
}
#endregion Linear Motion
}
2009-06-15 18:10:01 +00:00
else if ( prim . Joint = = JointType . Hinge )
2007-08-20 09:26:21 +00:00
{
2009-06-15 18:10:01 +00:00
//FIXME: Hinge movement extrapolation
2007-08-20 09:26:21 +00:00
}
2009-06-15 18:10:01 +00:00
else if ( prim . Joint = = JointType . Point )
{
//FIXME: Point movement extrapolation
}
else
{
Logger . Log ( "Unhandled joint type " + prim . Joint , Helpers . LogLevel . Warning , Client ) ;
}
}
) ;
2007-08-20 09:26:21 +00:00
}
// Make sure the last interpolated time is always updated
2007-11-06 09:26:10 +00:00
Client . Self . lastInterpolation = Environment . TickCount ;
2009-06-15 18:10:01 +00:00
elapsed = Client . Self . lastInterpolation - start ;
2007-08-20 09:26:21 +00:00
}
2009-06-15 18:10:01 +00:00
// Start the timer again. Use a minimum of a 50ms pause in between calculations
2024-08-28 16:19:39 -05:00
int delay = Math . Max ( 50 , Client . Settings . INTERPOLATION_INTERVAL - elapsed ) ;
2023-01-27 21:07:39 -06:00
InterpolationTimer ? . Change ( delay , Timeout . Infinite ) ;
2010-03-08 10:57:01 +00:00
}
2009-10-26 06:03:26 +00:00
}
#region EventArgs classes
2010-03-08 10:57:01 +00:00
2009-10-27 07:38:46 +00:00
/// <summary>Provides data for the <see cref="ObjectManager.ObjectUpdate"/> event</summary>
2009-10-27 07:01:48 +00:00
/// <remarks><para>The <see cref="ObjectManager.ObjectUpdate"/> event occurs when the simulator sends
2009-10-27 07:38:46 +00:00
/// an <see cref="ObjectUpdatePacket"/> containing a Primitive, Foliage or Attachment data</para>
2009-10-27 07:01:48 +00:00
/// <para>Note 1: The <see cref="ObjectManager.ObjectUpdate"/> event will not be raised when the object is an Avatar</para>
2009-11-03 05:32:49 +00:00
/// <para>Note 2: It is possible for the <see cref="ObjectManager.ObjectUpdate"/> to be
2009-10-26 06:03:26 +00:00
/// 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</para>
/// </remarks>
/// <example>
2009-10-27 07:38:46 +00:00
/// The following code example uses the <see cref="PrimEventArgs.Prim"/>, <see cref="PrimEventArgs.Simulator"/>, and <see cref="PrimEventArgs.IsAttachment"/>
2009-10-26 06:03:26 +00:00
/// properties to display new Primitives and Attachments on the <see cref="Console"/> window.
/// <code>
2009-11-03 05:32:49 +00:00
/// // Subscribe to the event that gives us prim and foliage information
2009-10-27 07:01:48 +00:00
/// Client.Objects.ObjectUpdate += Objects_ObjectUpdate;
2009-10-26 06:03:26 +00:00
///
///
2009-10-27 07:01:48 +00:00
/// private void Objects_ObjectUpdate(object sender, PrimEventArgs e)
2009-10-26 06:03:26 +00:00
/// {
2009-10-27 07:38:46 +00:00
/// Console.WriteLine("Primitive {0} {1} in {2} is an attachment {3}", e.Prim.ID, e.Prim.LocalID, e.Simulator.Name, e.IsAttachment);
2009-10-26 06:03:26 +00:00
/// }
/// </code>
/// </example>
2009-11-03 05:32:49 +00:00
/// <seealso cref="ObjectManager.ObjectUpdate"/>
2009-10-27 07:01:48 +00:00
/// <seealso cref="ObjectManager.AvatarUpdate"/>
/// <seealso cref="AvatarUpdateEventArgs"/>
2009-10-26 06:03:26 +00:00
public class PrimEventArgs : EventArgs
{
2009-11-03 05:32:49 +00:00
/// <summary>Get the simulator the <see cref="Primitive"/> originated from</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-11-03 05:32:49 +00:00
/// <summary>Get the <see cref="Primitive"/> details</summary>
2021-12-09 14:21:48 -06:00
public Primitive Prim { get ; }
2009-11-16 06:43:53 +00:00
/// <summary>true if the <see cref="Primitive"/> did not exist in the dictionary before this update (always true if object tracking has been disabled)</summary>
2021-12-09 14:21:48 -06:00
public bool IsNew { get ; }
2009-11-03 05:32:49 +00:00
/// <summary>true if the <see cref="Primitive"/> is attached to an <see cref="Avatar"/></summary>
2021-12-09 14:21:48 -06:00
public bool IsAttachment { get ; }
2009-10-26 06:03:26 +00:00
/// <summary>Get the simulator Time Dilation</summary>
2021-12-09 14:21:48 -06:00
public ushort TimeDilation { get ; }
2009-10-26 06:03:26 +00:00
/// <summary>
/// Construct a new instance of the PrimEventArgs class
/// </summary>
/// <param name="simulator">The simulator the object originated from</param>
/// <param name="prim">The Primitive</param>
/// <param name="timeDilation">The simulator time dilation</param>
2009-12-01 06:52:09 +00:00
/// <param name="isNew">The prim was not in the dictionary before this update</param>
2009-12-01 06:57:01 +00:00
/// <param name="isAttachment">true if the primitive represents an attachment to an agent</param>
2009-11-16 06:36:26 +00:00
public PrimEventArgs ( Simulator simulator , Primitive prim , ushort timeDilation , bool isNew , bool isAttachment )
2009-10-26 06:03:26 +00:00
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . IsNew = isNew ;
this . IsAttachment = isAttachment ;
this . Prim = prim ;
this . TimeDilation = timeDilation ;
2009-10-26 06:03:26 +00:00
}
}
2009-10-27 07:01:48 +00:00
/// <summary>Provides data for the <see cref="ObjectManager.AvatarUpdate"/> event</summary>
/// <remarks><para>The <see cref="ObjectManager.AvatarUpdate"/> event occurs when the simulator sends
/// an <see cref="ObjectUpdatePacket"/> containing Avatar data</para>
/// <para>Note 1: The <see cref="ObjectManager.AvatarUpdate"/> event will not be raised when the object is an Avatar</para>
/// <para>Note 2: It is possible for the <see cref="ObjectManager.AvatarUpdate"/> to be
/// raised twice for the same avatar if for example the avatar moved to a new simulator, then returned to the current simulator</para>
/// </remarks>
/// <example>
/// The following code example uses the <see cref="AvatarUpdateEventArgs.Avatar"/> property to make a request for the top picks
/// using the <see cref="AvatarManager.RequestAvatarPicks"/> method in the <see cref="AvatarManager"/> class to display the names
/// of our own agents picks listings on the <see cref="Console"/> window.
/// <code>
/// // 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);
/// }
/// }
/// </code>
/// </example>
/// <seealso cref="ObjectManager.ObjectUpdate"/>
/// <seealso cref="PrimEventArgs"/>
public class AvatarUpdateEventArgs : EventArgs
{
/// <summary>Get the simulator the object originated from</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-27 07:01:48 +00:00
/// <summary>Get the <see cref="Avatar"/> data</summary>
2021-12-09 14:21:48 -06:00
public Avatar Avatar { get ; }
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator time dilation</summary>
2021-12-09 14:21:48 -06:00
public ushort TimeDilation { get ; }
2009-12-01 06:52:09 +00:00
/// <summary>true if the <see cref="Avatar"/> did not exist in the dictionary before this update (always true if avatar tracking has been disabled)</summary>
2021-12-09 14:21:48 -06:00
public bool IsNew { get ; }
2009-10-27 07:01:48 +00:00
/// <summary>
/// Construct a new instance of the AvatarUpdateEventArgs class
/// </summary>
/// <param name="simulator">The simulator the packet originated from</param>
/// <param name="avatar">The <see cref="Avatar"/> data</param>
/// <param name="timeDilation">The simulator time dilation</param>
2009-12-01 06:52:09 +00:00
/// <param name="isNew">The avatar was not in the dictionary before this update</param>
public AvatarUpdateEventArgs ( Simulator simulator , Avatar avatar , ushort timeDilation , bool isNew )
2009-10-27 07:01:48 +00:00
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . Avatar = avatar ;
this . TimeDilation = timeDilation ;
this . IsNew = isNew ;
2009-10-27 07:01:48 +00:00
}
}
2009-10-26 06:03:26 +00:00
2015-06-11 00:02:57 +02:00
public class ParticleUpdateEventArgs : EventArgs {
/// <summary>Get the simulator the object originated from</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2015-06-11 00:02:57 +02:00
/// <summary>Get the <see cref="ParticleSystem"/> data</summary>
2021-12-09 14:21:48 -06:00
public Primitive . ParticleSystem ParticleSystem { get ; }
2015-06-11 00:02:57 +02:00
/// <summary>Get <see cref="Primitive"/> source</summary>
2021-12-09 14:21:48 -06:00
public Primitive Source { get ; }
2015-06-11 00:02:57 +02:00
/// <summary>
/// Construct a new instance of the ParticleUpdateEventArgs class
/// </summary>
/// <param name="simulator">The simulator the packet originated from</param>
/// <param name="particlesystem">The ParticleSystem data</param>
/// <param name="source">The Primitive source</param>
public ParticleUpdateEventArgs ( Simulator simulator , Primitive . ParticleSystem particlesystem , Primitive source ) {
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . ParticleSystem = particlesystem ;
this . Source = source ;
2015-06-11 00:02:57 +02:00
}
}
2009-10-26 06:03:26 +00:00
/// <summary>Provides additional primitive data for the <see cref="ObjectManager.ObjectProperties"/> event</summary>
/// <remarks><para>The <see cref="ObjectManager.ObjectProperties"/> event occurs when the simulator sends
/// an <see cref="ObjectPropertiesPacket"/> containing additional details for a Primitive, Foliage data or Attachment data</para>
/// <para>The <see cref="ObjectManager.ObjectProperties"/> event is also raised when a <see cref="ObjectManager.SelectObject"/> request is
/// made.</para>
/// </remarks>
/// <example>
/// The following code example uses the <see cref="PrimEventArgs.Prim"/>, <see cref="PrimEventArgs.Simulator"/> and
/// <see cref="ObjectPropertiesEventArgs.Properties"/>
/// properties to display new attachments and send a request for additional properties containing the name of the
/// attachment then display it on the <see cref="Console"/> window.
2009-11-03 05:32:49 +00:00
/// <code>
2009-10-26 06:03:26 +00:00
/// // 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);
/// }
/// </code>
/// </example>
public class ObjectPropertiesEventArgs : EventArgs
{
2012-05-30 12:38:38 +00:00
protected readonly Simulator m_Simulator ;
protected readonly Primitive . ObjectProperties m_Properties ;
2009-10-26 06:03:26 +00:00
/// <summary>Get the simulator the object is located</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>Get the primitive properties</summary>
public Primitive . ObjectProperties Properties { get { return m_Properties ; } }
/// <summary>
/// Construct a new instance of the ObjectPropertiesEventArgs class
/// </summary>
/// <param name="simulator">The simulator the object is located</param>
/// <param name="props">The primitive Properties</param>
public ObjectPropertiesEventArgs ( Simulator simulator , Primitive . ObjectProperties props )
{
this . m_Simulator = simulator ;
this . m_Properties = props ;
}
}
/// <summary>Provides additional primitive data for the <see cref="ObjectManager.ObjectPropertiesUpdated"/> event</summary>
/// <remarks><para>The <see cref="ObjectManager.ObjectPropertiesUpdated"/> event occurs when the simulator sends
/// an <see cref="ObjectPropertiesPacket"/> containing additional details for a Primitive or Foliage data that is currently
/// being tracked in the <see cref="Simulator.ObjectsPrimitives"/> dictionary</para>
/// <para>The <see cref="ObjectManager.ObjectPropertiesUpdated"/> event is also raised when a <see cref="ObjectManager.SelectObject"/> request is
/// made and <see cref="Settings.OBJECT_TRACKING"/> is enabled</para>
/// </remarks>
2012-05-30 12:38:38 +00:00
public class ObjectPropertiesUpdatedEventArgs : ObjectPropertiesEventArgs
2009-10-26 06:03:26 +00:00
{
/// <summary>Get the primitive details</summary>
2021-12-09 14:21:48 -06:00
public Primitive Prim { get ; }
2009-10-26 06:03:26 +00:00
/// <summary>
/// Construct a new instance of the ObjectPropertiesUpdatedEvenrArgs class
/// </summary>
/// <param name="simulator">The simulator the object is located</param>
/// <param name="prim">The Primitive</param>
/// <param name="props">The primitive Properties</param>
2012-05-30 12:38:38 +00:00
public ObjectPropertiesUpdatedEventArgs ( Simulator simulator , Primitive prim , Primitive . ObjectProperties props ) : base ( simulator , props )
2009-10-26 06:03:26 +00:00
{
2021-12-09 14:21:48 -06:00
this . Prim = prim ;
2009-10-26 06:03:26 +00:00
}
}
2009-10-27 07:01:48 +00:00
/// <summary>Provides additional primitive data, permissions and sale info for the <see cref="ObjectManager.ObjectPropertiesFamily"/> event</summary>
/// <remarks><para>The <see cref="ObjectManager.ObjectPropertiesFamily"/> event occurs when the simulator sends
/// an <see cref="ObjectPropertiesPacket"/> containing additional details for a Primitive, Foliage data or Attachment. This includes
/// Permissions, Sale info, and other basic details on an object</para>
/// <para>The <see cref="ObjectManager.ObjectProperties"/> event is also raised when a <see cref="ObjectManager.RequestObjectPropertiesFamily"/> request is
/// made, the viewer equivalent is hovering the mouse cursor over an object</para>
/// </remarks>
2009-10-26 06:03:26 +00:00
public class ObjectPropertiesFamilyEventArgs : EventArgs
{
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public Primitive . ObjectProperties Properties { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public ReportType Type { get ; }
2009-10-26 06:03:26 +00:00
public ObjectPropertiesFamilyEventArgs ( Simulator simulator , Primitive . ObjectProperties props , ReportType type )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . Properties = props ;
this . Type = type ;
2009-10-26 06:03:26 +00:00
}
}
2009-10-27 07:01:48 +00:00
/// <summary>Provides primitive data containing updated location, velocity, rotation, textures for the <see cref="ObjectManager.TerseObjectUpdate"/> event</summary>
/// <remarks><para>The <see cref="ObjectManager.TerseObjectUpdate"/> event occurs when the simulator sends updated location, velocity, rotation, etc</para>
/// </remarks>
public class TerseObjectUpdateEventArgs : EventArgs
2009-10-26 06:03:26 +00:00
{
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-27 07:01:48 +00:00
/// <summary>Get the primitive details</summary>
2021-12-09 14:21:48 -06:00
public Primitive Prim { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public ObjectMovementUpdate Update { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public ushort TimeDilation { get ; }
2009-10-26 06:03:26 +00:00
2009-10-27 07:01:48 +00:00
public TerseObjectUpdateEventArgs ( Simulator simulator , Primitive prim , ObjectMovementUpdate update , ushort timeDilation )
2009-10-26 06:03:26 +00:00
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . Prim = prim ;
this . Update = update ;
this . TimeDilation = timeDilation ;
2009-10-26 06:03:26 +00:00
}
}
2010-03-08 10:57:01 +00:00
2009-10-27 07:01:48 +00:00
/// <summary>
///
/// </summary>
2009-10-26 06:03:26 +00:00
public class ObjectDataBlockUpdateEventArgs : EventArgs
{
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-27 07:01:48 +00:00
/// <summary>Get the primitive details</summary>
2021-12-09 14:21:48 -06:00
public Primitive Prim { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public Primitive . ConstructionData ConstructionData { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public ObjectUpdatePacket . ObjectDataBlock Block { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public ObjectMovementUpdate Update { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public NameValue [ ] NameValues { get ; }
2009-10-26 06:03:26 +00:00
2010-03-08 10:57:01 +00:00
public ObjectDataBlockUpdateEventArgs ( Simulator simulator , Primitive prim , Primitive . ConstructionData constructionData ,
2009-10-27 07:01:48 +00:00
ObjectUpdatePacket . ObjectDataBlock block , ObjectMovementUpdate objectupdate , NameValue [ ] nameValues )
2009-10-26 06:03:26 +00:00
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . Prim = prim ;
this . ConstructionData = constructionData ;
this . Block = block ;
this . Update = objectupdate ;
this . NameValues = nameValues ;
2009-10-26 06:03:26 +00:00
}
}
2009-10-29 23:53:17 +00:00
/// <summary>Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the
/// <see cref="ObjectManager.KillObject"/> event</summary>
2009-10-26 06:03:26 +00:00
public class KillObjectEventArgs : EventArgs
{
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-29 23:53:17 +00:00
/// <summary>The LocalID of the object</summary>
2021-12-09 14:21:48 -06:00
public uint ObjectLocalID { get ; }
2009-10-26 06:03:26 +00:00
public KillObjectEventArgs ( Simulator simulator , uint objectID )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . ObjectLocalID = objectID ;
2009-10-26 06:03:26 +00:00
}
}
2010-03-08 10:57:01 +00:00
2013-03-04 08:33:08 +01:00
/// <summary>Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the
/// <see cref="ObjectManager.KillObjects"/> event</summary>
public class KillObjectsEventArgs : EventArgs
{
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2013-03-04 08:33:08 +01:00
/// <summary>The LocalID of the object</summary>
2021-12-09 14:21:48 -06:00
public uint [ ] ObjectLocalIDs { get ; }
2013-03-04 08:33:08 +01:00
public KillObjectsEventArgs ( Simulator simulator , uint [ ] objectIDs )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . ObjectLocalIDs = objectIDs ;
2013-03-04 08:33:08 +01:00
}
}
2009-10-27 07:01:48 +00:00
/// <summary>
2009-10-29 23:53:17 +00:00
/// Provides updates sit position data
2009-10-27 07:01:48 +00:00
/// </summary>
2009-10-26 06:03:26 +00:00
public class AvatarSitChangedEventArgs : EventArgs
{
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public Avatar Avatar { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public uint SittingOn { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public uint OldSeat { get ; }
2009-10-26 06:03:26 +00:00
public AvatarSitChangedEventArgs ( Simulator simulator , Avatar avatar , uint sittingOn , uint oldSeat )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . Avatar = avatar ;
this . SittingOn = sittingOn ;
this . OldSeat = oldSeat ;
2009-10-26 06:03:26 +00:00
}
}
2010-03-08 10:57:01 +00:00
2009-10-27 07:01:48 +00:00
/// <summary>
///
/// </summary>
2009-10-26 06:03:26 +00:00
public class PayPriceReplyEventArgs : EventArgs
{
2009-10-27 07:01:48 +00:00
/// <summary>Get the simulator the object is located</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public UUID ObjectID { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public int DefaultPrice { get ; }
2009-10-27 07:01:48 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public int [ ] ButtonPrices { get ; }
2009-10-26 06:03:26 +00:00
public PayPriceReplyEventArgs ( Simulator simulator , UUID objectID , int defaultPrice , int [ ] buttonPrices )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . ObjectID = objectID ;
this . DefaultPrice = defaultPrice ;
this . ButtonPrices = buttonPrices ;
2007-08-20 09:26:21 +00:00
}
2006-10-21 02:52:28 +00:00
}
2010-03-07 19:58:06 +00:00
public class ObjectMediaEventArgs : EventArgs
{
/// <summary>
/// Indicates if the operation was successful
/// </summary>
public bool Success { get ; set ; }
/// <summary>
/// Media version string
/// </summary>
public string Version { get ; set ; }
/// <summary>
/// Array of media entries indexed by face number
/// </summary>
public MediaEntry [ ] FaceMedia { get ; set ; }
public ObjectMediaEventArgs ( bool success , string version , MediaEntry [ ] faceMedia )
{
this . Success = success ;
this . Version = version ;
this . FaceMedia = faceMedia ;
}
}
2011-05-20 09:26:13 +00:00
/// <summary>
/// Set when simulator sends us infomation on primitive's physical properties
/// </summary>
public class PhysicsPropertiesEventArgs : EventArgs
{
/// <summary>Simulator where the message originated</summary>
public Simulator Simulator ;
/// <summary>Updated physical properties</summary>
public Primitive . PhysicsProperties PhysicsProperties ;
/// <summary>
/// Constructor
/// </summary>
/// <param name="sim">Simulator where the message originated</param>
/// <param name="props">Updated physical properties</param>
public PhysicsPropertiesEventArgs ( Simulator sim , Primitive . PhysicsProperties props )
{
Simulator = sim ;
PhysicsProperties = props ;
}
}
2009-10-26 06:03:26 +00:00
#endregion
2007-02-01 18:29:40 +00:00
}