diff --git a/libsecondlife/ObjectManager.cs b/libsecondlife/ObjectManager.cs index 4c20327a..5cee185a 100644 --- a/libsecondlife/ObjectManager.cs +++ b/libsecondlife/ObjectManager.cs @@ -879,7 +879,15 @@ namespace libsecondlife extra.ObjectData[0] = new ObjectExtraParamsPacket.ObjectDataBlock(); extra.ObjectData[0].ObjectLocalID = localID; extra.ObjectData[0].ParamType = (byte)Primitive.ExtraParamType.Light; - extra.ObjectData[0].ParamInUse = true; + if (light.Intensity == 0.0f) + { + // Disables the light if intensity is 0 + extra.ObjectData[0].ParamInUse = false; + } + else + { + extra.ObjectData[0].ParamInUse = true; + } extra.ObjectData[0].ParamData = light.GetBytes(); extra.ObjectData[0].ParamSize = (uint)extra.ObjectData[0].ParamData.Length; diff --git a/libsecondlife/TextureEntry.cs b/libsecondlife/TextureEntry.cs index 5f4e32df..a7ed093f 100644 --- a/libsecondlife/TextureEntry.cs +++ b/libsecondlife/TextureEntry.cs @@ -672,12 +672,12 @@ namespace libsecondlife #endregion Texture #region Color - DefaultTexture.RGBA = new LLColor(data, i, true); + DefaultTexture.RGBA = new LLColor(data, i, false); i += 4; while (ReadFaceBitfield(data, ref i, ref faceBits, ref bitfieldSize)) { - LLColor tmpColor = new LLColor(data, i, true); + LLColor tmpColor = new LLColor(data, i, false); i += 4; for (uint face = 0, bit = 1; face < bitfieldSize; face++, bit <<= 1) @@ -914,13 +914,15 @@ namespace libsecondlife #endregion Texture #region Color - binWriter.Write(DefaultTexture.RGBA.GetBytes()); + // Serialize the color bytes inverted to optimize for zerocoding + binWriter.Write(DefaultTexture.RGBA.GetBytes(true)); for (int i = 0; i < rgbas.Length; i++) { if (rgbas[i] != UInt32.MaxValue) { binWriter.Write(GetFaceBitfieldBytes(rgbas[i])); - binWriter.Write(FaceTextures[i].RGBA.GetBytes()); + // Serialize the color bytes inverted to optimize for zerocoding + binWriter.Write(FaceTextures[i].RGBA.GetBytes(true)); } } binWriter.Write((byte)0); diff --git a/libsecondlife/Types.cs b/libsecondlife/Types.cs index 51b2f393..73d7095c 100644 --- a/libsecondlife/Types.cs +++ b/libsecondlife/Types.cs @@ -87,6 +87,15 @@ namespace libsecondlife UUID = new Guid(0, 0, 0, BitConverter.GetBytes(val)); } + /// + /// Copy constructor + /// + /// UUID to copy + public LLUUID(LLUUID val) + { + UUID = val.UUID; + } + #endregion Constructors #region Public Methods @@ -335,6 +344,7 @@ namespace libsecondlife /// /// A two-dimensional vector with floating-point values /// + [Serializable] public struct LLVector2 { /// X value @@ -342,18 +352,64 @@ namespace libsecondlife /// Y value public float Y; - #region Constructors + // Used for little to big endian conversion on big endian architectures + private byte[] conversionBuffer; + + #region Public Methods /// - /// Constructor, copies a single-precision vector + /// Builds a vector from a byte array /// - /// Single-precision vector to copy - public LLVector2(LLVector2 vector) + /// Byte array containing two four-byte floats + /// Beginning position in the byte array + public void FromBytes(byte[] byteArray, int pos) { - X = vector.X; - Y = vector.Y; + if (!BitConverter.IsLittleEndian) + { + // Big endian architecture + if (conversionBuffer == null) + conversionBuffer = new byte[8]; + + Buffer.BlockCopy(byteArray, pos, conversionBuffer, 0, 8); + + Array.Reverse(conversionBuffer, 0, 4); + Array.Reverse(conversionBuffer, 4, 4); + + X = BitConverter.ToSingle(conversionBuffer, 0); + Y = BitConverter.ToSingle(conversionBuffer, 4); + } + else + { + // Little endian architecture + X = BitConverter.ToSingle(byteArray, pos); + Y = BitConverter.ToSingle(byteArray, pos + 4); + } } + /// + /// Returns the raw bytes for this vector + /// + /// An eight-byte array containing X and Y + public byte[] GetBytes() + { + byte[] byteArray = new byte[8]; + + Buffer.BlockCopy(BitConverter.GetBytes(X), 0, byteArray, 0, 4); + Buffer.BlockCopy(BitConverter.GetBytes(Y), 0, byteArray, 4, 4); + + if (!BitConverter.IsLittleEndian) + { + Array.Reverse(byteArray, 0, 4); + Array.Reverse(byteArray, 4, 4); + } + + return byteArray; + } + + #endregion Public Methods + + #region Constructors + /// /// Constructor, builds a vector for individual float values /// @@ -361,10 +417,22 @@ namespace libsecondlife /// Y value public LLVector2(float x, float y) { + conversionBuffer = null; X = x; Y = y; } + /// + /// Copy constructor + /// + /// Vector to copy + public LLVector2(LLVector2 vector) + { + conversionBuffer = null; + X = vector.X; + Y = vector.Y; + } + #endregion Constructors #region Overrides @@ -496,6 +564,7 @@ namespace libsecondlife /// /// A three-dimensional vector with floating-point values /// + [Serializable] public struct LLVector3 { /// X value @@ -510,35 +579,10 @@ namespace libsecondlife #region Constructors - /// - /// Constructor, copies a single-precision vector - /// - /// Single-precision vector to copy - public LLVector3(LLVector3 vector) - { - conversionBuffer = null; - X = vector.X; - Y = vector.Y; - Z = vector.Z; - } - - /// - /// Constructor, builds a single-precision vector from a - /// double-precision one - /// - /// A double-precision vector - public LLVector3(LLVector3d vector) - { - conversionBuffer = null; - X = (float)vector.X; - Y = (float)vector.Y; - Z = (float)vector.Z; - } - /// /// Constructor, builds a vector from a byte array /// - /// Byte array containing a 12 byte vector + /// Byte array containing three four-byte floats /// Beginning position in the byte array public LLVector3(byte[] byteArray, int pos) { @@ -561,6 +605,18 @@ namespace libsecondlife Z = z; } + /// + /// Copy constructor + /// + /// Vector to copy + public LLVector3(LLVector3 vector) + { + conversionBuffer = null; + X = (float)vector.X; + Y = (float)vector.Y; + Z = (float)vector.Z; + } + #endregion Constructors #region Public Methods @@ -936,7 +992,8 @@ namespace libsecondlife /// /// A double-precision three-dimensional vector /// - public struct LLVector3d + [Serializable] + public struct LLVector3d { /// X value public double X; @@ -988,6 +1045,18 @@ namespace libsecondlife FromBytes(byteArray, pos); } + /// + /// Copy constructor + /// + /// Vector to copy + public LLVector3d(LLVector3d vector) + { + conversionBuffer = null; + X = vector.X; + Y = vector.Y; + Z = vector.Z; + } + #endregion Constructors #region Public Methods @@ -1160,7 +1229,8 @@ namespace libsecondlife /// /// A four-dimensional vector /// - public struct LLVector4 + [Serializable] + public struct LLVector4 { /// public float X; @@ -1204,6 +1274,19 @@ namespace libsecondlife FromBytes(byteArray, pos); } + /// + /// Copy constructor + /// + /// Vector to copy + public LLVector4(LLVector4 vector) + { + conversionBuffer = null; + X = vector.X; + Y = vector.Y; + Z = vector.Z; + S = vector.S; + } + #endregion Constructors #region Public Methods @@ -1428,6 +1511,7 @@ namespace libsecondlife /// /// An 8-bit color structure including an alpha channel /// + [Serializable] public struct LLColor { /// Red @@ -1484,6 +1568,18 @@ namespace libsecondlife FromBytes(byteArray, pos, inverted, alphaInverted); } + /// + /// Copy constructor + /// + /// Color to copy + public LLColor(LLColor color) + { + R = color.R; + G = color.G; + B = color.B; + A = color.A; + } + #endregion Constructors #region Public Methods @@ -1675,7 +1771,8 @@ namespace libsecondlife /// /// A quaternion, used for rotations /// - public struct LLQuaternion + [Serializable] + public struct LLQuaternion { /// X value public float X; @@ -1694,7 +1791,7 @@ namespace libsecondlife /// /// Constructor, builds a quaternion object from a byte array /// - /// The source byte array + /// Byte array containing four four-byte floats /// Offset in the byte array to start reading at /// Whether the source data is normalized or /// not. If this is true 12 bytes will be read, otherwise 16 bytes will @@ -1751,6 +1848,19 @@ namespace libsecondlife SetQuaternion(angle, vec); } + /// + /// Copy constructor + /// + /// Quaternion to copy + public LLQuaternion(LLQuaternion quaternion) + { + conversionBuffer = null; + X = quaternion.X; + Y = quaternion.Y; + Z = quaternion.Z; + W = quaternion.W; + } + #endregion Constructors #region Public Methods @@ -2136,8 +2246,9 @@ namespace libsecondlife } /// - /// + /// A 3x3 matrix /// + [Serializable] public struct LLMatrix3 { public float M11, M12, M13; @@ -2180,6 +2291,22 @@ namespace libsecondlife M33 = m33; } + public LLMatrix3(LLQuaternion q) + { + this = q.ToMatrix(); + } + + //FIXME: + //public LLMatrix3(float roll, float pitch, float yaw) + //{ + // M11 = M12 = M13 = M21 = M22 = M23 = M31 = M32 = M33 = 0f; + // FromEulers(roll, pitch, yaw); + //} + + /// + /// Copy constructor + /// + /// Matrix to copy public LLMatrix3(LLMatrix3 m) { M11 = m.M11; @@ -2193,18 +2320,6 @@ namespace libsecondlife M33 = m.M33; } - public LLMatrix3(LLQuaternion q) - { - this = q.ToMatrix(); - } - - //FIXME: - //public LLMatrix3(float roll, float pitch, float yaw) - //{ - // M11 = M12 = M13 = M21 = M22 = M23 = M31 = M32 = M33 = 0f; - // FromEulers(roll, pitch, yaw); - //} - #endregion Constructors #region Public Methods