/* * Copyright (c) 2007, Second Life Reverse Engineering Team * 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. * - Neither the name of the Second Life Reverse Engineering Team nor the names * of its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE 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; using System.Collections.Generic; using libsecondlife.Packets; namespace libsecondlife { /// /// Base class for primitives and avatars /// public abstract partial class LLObject { #region Enumerations /// /// Primary parameters for primitives such as Physics Enabled or Phantom /// [Flags] public enum ObjectFlags : uint { /// None of the primary flags are enabled None = 0, /// Whether physics are enabled for this object Physics = 0x00000001, /// CreateSelected = 0x00000002, /// ObjectModify = 0x00000004, /// ObjectCopy = 0x00000008, /// ObjectAnyOwner = 0x00000010, /// ObjectYouOwner = 0x00000020, /// Scripted = 0x00000040, /// Whether this object contains an active touch script Touch = 0x00000080, /// ObjectMove = 0x00000100, /// Whether this object can receive payments Money = 0x00000200, /// Whether this object is phantom (no collisions) Phantom = 0x00000400, /// InventoryEmpty = 0x00000800, /// JointHinge = 0x00001000, /// JointP2P = 0x00002000, /// JointLP2P = 0x00004000, /// Deprecated JointWheel = 0x00008000, /// AllowInventoryDrop = 0x00010000, /// ObjectTransfer = 0x00020000, /// ObjectGroupOwned = 0x00040000, /// Deprecated ObjectYouOfficer = 0x00080000, /// CameraDecoupled = 0x00100000, /// AnimSource = 0x00200000, /// CameraSource = 0x00400000, /// CastShadows = 0x00800000, /// ObjectOwnerModify = 0x10000000, /// TemporaryOnRez = 0x20000000, /// Temporary = 0x40000000, /// ZlibCompressed = 0x80000000 } [Flags] public enum ProfileCurve : byte { ProfileCircle = 0x00, ProfileSquare = 0x01, ProfileIsoTriangle = 0x02, ProfileEqualTriangle = 0x03, ProfileRightTriangle = 0x04, ProfileHalfCircle = 0x05, HoleCircle = 0x10, HoleSquare = 0x20, HoleTriangle = 0x30 } public enum PathCurve : byte { Line = 0x10, Circle = 0x20, Circle2 = 0x30, Test = 0x40, Flexible = 0x80 } /// /// Material type for a primitive /// public enum MaterialType : byte { /// Stone = 0, /// Metal, /// Glass, /// Wood, /// Flesh, /// Plastic, /// Rubber, /// Light } #endregion Enumerations #region Structs /// /// /// public struct ObjectData { /// public int PathTwistBegin; /// public float PathEnd; /// public float ProfileBegin; /// public float PathRadiusOffset; /// public float PathSkew; /// public ProfileCurve ProfileCurve; /// public float PathScaleX; /// public float PathScaleY; /// public MaterialType Material; /// public float PathShearX; /// public float PathShearY; /// public float PathTaperX; /// public float PathTaperY; /// public float ProfileEnd; /// public float PathBegin; /// public PathCurve PathCurve; /// public int PathTwist; /// public float ProfileHollow; /// public float PathRevolutions; /// public uint State; /// public ObjectManager.PCode PCode; } /// /// /// public struct ObjectProperties { /// public LLUUID ObjectID; /// public LLUUID CreatorID; /// public LLUUID OwnerID; /// public LLUUID GroupID; /// public ulong CreationDate; /// public Permissions Permissions; /// public int OwnershipCost; /// public byte SaleType; /// public int SalePrice; /// public byte AggregatePerms; /// public byte AggregatePermTextures; /// public byte AggregatePermTexturesOwner; /// public uint Category; /// public short InventorySerial; /// public LLUUID ItemID; /// public LLUUID FolderID; /// public LLUUID FromTaskID; /// public LLUUID LastOwnerID; /// public string Name; /// public string Description; /// public string TouchName; /// public string SitName; /// public LLUUID[] TextureIDs; } /// /// /// public struct ObjectPropertiesFamily { /// /// /// public enum RequestFlagsType { /// None = 0, /// BugReportRequest = 1, /// ComplaintReportRequest = 2 } /// public RequestFlagsType RequestFlags; /// public LLUUID ObjectID; /// public LLUUID OwnerID; /// public LLUUID GroupID; /// public Permissions Permissions; /// public int OwnershipCost; /// public byte SaleType; /// public int SalePrice; /// public uint Category; /// public LLUUID LastOwnerID; /// public string Name; /// public string Description; //public bool IsOwnedBy(SecondLife client) //{ // if (GroupID != LLUUID.Zero) // { // // Group owned, iterate through all of this clients groups // // and see if it is a member // //client.Groups. // // FIXME: Current groups should be stored in GroupManager and auto-requested (with a setting to turn off) // } // else // { // // Avatar owned // } //} } #endregion Structs #region Public Members /// public LLUUID ID; /// public LLUUID GroupID; /// public uint LocalID; /// public uint ParentID; /// public ulong RegionHandle; /// public ObjectFlags Flags; /// Unknown public byte[] GenericData; /// public LLVector3 Position; /// public LLVector3 Scale; /// public LLQuaternion Rotation; /// public LLVector3 Velocity; /// public LLVector3 AngularVelocity; /// public LLVector3 Acceleration; /// public LLVector4 CollisionPlane; /// public TextureEntry Textures; /// public ObjectProperties Properties; /// public ObjectPropertiesFamily PropertiesFamily; /// public NameValue[] NameValues; /// public ObjectData Data; #endregion Public Members /// /// /// /// /// public override bool Equals(object obj) { LLObject llobj = obj as LLObject; if (llobj == null) return false; return ID.Equals(llobj.ID); } /// /// /// /// public override int GetHashCode() { return ID.GetHashCode(); } #region Static Methods /// /// /// /// /// public static byte PathScaleByte(float pathScale) { // Y = 100 + 100X int scale = (int)Math.Round(100.0f * pathScale); return (byte)(100 + scale); } /// /// /// /// /// public static float PathScaleFloat(byte pathScale) { // Y = -1 + 0.01X return (float)Math.Round((double)pathScale * 0.01d - 1.0d, 6); } /// /// /// /// /// public static byte PathShearByte(float pathShear) { // Y = 256 + 100X int shear = (int)Math.Round(100.0f * pathShear); shear += 256; return (byte)(shear % 256); } /// /// /// /// /// public static float PathShearFloat(byte pathShear) { if (pathShear == 0) return 0.0f; if (pathShear > 150) { // Negative value return ((float)pathShear - 256.0f) / 100.0f; } else { // Positive value return (float)pathShear / 100.0f; } } /// /// /// /// /// public static ushort ProfileBeginUInt16(float profileBegin) { return Convert.ToUInt16(profileBegin / 0.00002f); } /// /// /// /// /// public static float ProfileBeginFloat(ushort profileBegin) { return (float)Math.Round((double)profileBegin * 0.00002d, 6); } /// /// /// /// /// public static ushort ProfileEndUInt16(float profileEnd) { return (ushort)(50000 - Convert.ToInt32(profileEnd / 0.00002f)); } /// /// /// /// /// public static float ProfileEndFloat(ushort profileEnd) { float temp = (float)Math.Round(profileEnd * 0.00002f, 6); if (temp > 1.0f) temp = 1.0f; return 1.0f - temp; } /// /// /// /// /// public static ushort ProfileHollowUInt16(float profileHollow) { return Convert.ToUInt16(profileHollow / 0.002f); } /// /// /// /// /// public static float ProfileHollowFloat(ushort profileHollow) { float temp = profileHollow * 0.002f; if (temp > 100.0f) temp = 0.0f; return temp; } /// /// /// /// /// public static ushort PathBeginUInt16(float pathBegin) { return Convert.ToUInt16(pathBegin / 0.00002f); } /// /// /// /// /// public static float PathBeginFloat(ushort pathBegin) { return (float)pathBegin * 0.00002f; } /// /// /// /// /// public static ushort PathEndUInt16(float pathEnd) { return (ushort)(50000 - Convert.ToInt32(pathEnd / 0.00002f)); } /// /// /// /// /// public static float PathEndFloat(ushort pathEnd) { return (float)(50000 - pathEnd) * 0.00002f; } /// /// /// /// /// public static sbyte PathRadiusOffsetByte(float pathRadiusOffset) { // Y = 256 + 100X return (sbyte)PathShearByte(pathRadiusOffset); } /// /// /// /// /// public static float PathRadiusOffsetFloat(sbyte pathRadiusOffset) { // Y = X / 100 return (float)pathRadiusOffset / 100.0f; } /// /// /// /// /// public static byte PathRevolutionsByte(float pathRevolutions) { // Y = 66.5X - 66 int revolutions = (int)Math.Round(66.5d * (double)pathRevolutions); return (byte)(revolutions - 66); } /// /// /// /// /// public static float PathRevolutionsFloat(byte pathRevolutions) { // Y = 1 + 0.015X return (float)Math.Round(1.0d + (double)pathRevolutions * 0.015d, 6); } /// /// /// /// /// public static sbyte PathSkewByte(float pathSkew) { return PathTaperByte(pathSkew); } /// /// /// /// /// public static float PathSkewFloat(sbyte pathSkew) { return PathTaperFloat(pathSkew); } /// /// /// /// /// public static sbyte PathTaperByte(float pathTaper) { // Y = 256 + 100X return (sbyte)PathShearByte(pathTaper); } /// /// /// /// /// public static float PathTaperFloat(sbyte pathTaper) { return (float)pathTaper / 100.0f; } #endregion Static Methods } }