Ejemplo n.º 1
0
        protected override void DeSerialise(byte[] buf, ref int o, int length)
        {
            SenderId      = BinarySerializer.DeSerializeGuid(buf, ref o, length);
            SenderIsTrial = BinarySerializer.DeSerializeBool(buf, ref o, length);

            TextureEntry = BinarySerializer.DeSerializeTextureEntry(buf, ref o, length);

            int len = buf[o++];

            // TODO: Decode visual params: Each byte appears to be a weight that needs to be scaled between the min and max values of the parameter identified by the index
            VisualParam = new byte[len];
            Array.Copy(buf, o, VisualParam, 0, len);
            o += len;

            len = buf[o++];
            for (int i = 0; i < len; i++)
            {
                AppearanceDatas.Add(new AppearanceData()
                {
                    AppearanceVersion = buf[o++],
                    CofVersion        = BinarySerializer.DeSerializeInt32_Le(buf, ref o, length),
                    Flags             = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length)
                });
            }

            len = buf[o++];
            for (int i = 0; i < len; i++)
            {
                HoverHeights.Add(BinarySerializer.DeSerializeVector3(buf, ref o, length));
            }
        }
Ejemplo n.º 2
0
 protected override void DeSerialise(byte[] buf, ref int o, int length)
 {
     SoundId  = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     OwnerId  = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     ObjectId = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     ParentId = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     Handle   = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length));
     Position = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length);
 }
Ejemplo n.º 3
0
 protected override void DeSerialise(byte[] buf, ref int o, int length)
 {
     UsecSinceStart = BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length);
     SecPerDay      = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
     SecPerYear     = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
     SunDirection   = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length);
     SunPhase       = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length);
     SunAngVelocity = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length);
 }
Ejemplo n.º 4
0
 protected override void DeSerialise(byte[] buf, ref int o, int length)
 {
     AgentId        = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     SessionId      = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     Position       = BinarySerializer.DeSerializeVector3(buf, ref o, length);
     LookAt         = BinarySerializer.DeSerializeVector3(buf, ref o, length);
     RegionHandle   = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length));
     TimeStamp      = BinarySerializer.DeSerializeDateTime(buf, ref o, length);
     ChannelVersion = BinarySerializer.DeSerializeString(buf, ref o, length, 2);
 }
Ejemplo n.º 5
0
 protected override void DeSerialise(byte[] buf, ref int o, int length)
 {
     FromName     = BinarySerializer.DeSerializeString(buf, ref o, length, 1);
     SourceId     = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     OwnerId      = BinarySerializer.DeSerializeGuid(buf, ref o, length);
     SourceType   = (ChatSourceType)buf[o++];
     ChatType     = (ChatType)buf[o++];
     AudibleLevel = (ChatAudibleLevel)buf[o++];
     Position     = BinarySerializer.DeSerializeVector3(buf, ref o, length);
     Message      = BinarySerializer.DeSerializeString(buf, ref o, length, 2);
 }
        protected override void DeSerialise(byte[] buf, ref int o, int length)
        {
            AgentId        = BinarySerializer.DeSerializeGuid(buf, ref o, length);
            SessionId      = BinarySerializer.DeSerializeGuid(buf, ref o, length);
            IsFromGroup    = buf[o++] != 0; // TODO: Put this in BinarySerializer to make sure that it is consistent
            ToAgentId      = BinarySerializer.DeSerializeGuid(buf, ref o, length);
            ParentEstateId = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
            RegionId       = BinarySerializer.DeSerializeGuid(buf, ref o, length);
            Position       = BinarySerializer.DeSerializeVector3(buf, ref o, length);
            OnlineMode     = (OnlineMode)buf[o++];
            DialogType     = (DialogType)buf[o++];
            Id             = BinarySerializer.DeSerializeGuid(buf, ref o, length);
            Timestamp      = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
            FromAgentName  = BinarySerializer.DeSerializeString(buf, ref o, length, 1);
            MessageText    = BinarySerializer.DeSerializeString(buf, ref o, length, 2);
            UInt16 len = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);

            BinaryBucket = new byte[len];
            Array.Copy(buf, o, BinaryBucket, 0, len);
            o += len;
        }
Ejemplo n.º 7
0
        public static PolyMorphData DeSerializePolyMorphData(byte[] buffer, ref int offset, int length)
        {
            PolyMorphData data = new PolyMorphData();

            Int32 nVertices = BinarySerializer.DeSerializeInt32_Le(buffer, ref offset, length);

            for (int i = 0; i < nVertices; i++)
            {
                UInt32 vertexIndex = BinarySerializer.DeSerializeUInt32_Le(buffer, ref offset, length);
                if (vertexIndex > 10000)
                {
                    throw new Exception($"Bad morph index: {vertexIndex}");
                }

                Vector3 coordinate = BinarySerializer.DeSerializeVector3(buffer, ref offset, length);
                Vector3 normal     = BinarySerializer.DeSerializeVector3(buffer, ref offset, length);
                Vector3 biNormal   = BinarySerializer.DeSerializeVector3(buffer, ref offset, length);
                Vector2 texCoord   = BinarySerializer.DeSerializeVector2(buffer, ref offset, length);
            }

            return(data);
        }
Ejemplo n.º 8
0
        public static PolyMesh DeSerializePolyMesh(byte[] buffer, ref int o, int length, bool isLod)
        {
            if (length < 128)
            {
                throw new Exception("Not enough bytes in file for header.");
            }

            PolyMesh mesh = new PolyMesh {
                IsLod = isLod, SharedData = new PolyMeshSharedData()
            };

            string identifier = BinarySerializer.DeSerializeString(buffer, ref o, 24, -1);

            if (identifier.Trim() != ExpectedBinaryIdentifier)
            {
                throw new Exception($"Invalid mesh file header.");
            }

            string logMessage = "";

            mesh.SharedData.HasWeights         = BinarySerializer.DeSerializeBool(buffer, ref o, length);
            mesh.SharedData.HasDetailTexCoords = BinarySerializer.DeSerializeBool(buffer, ref o, length);
            mesh.SharedData.Position           = BinarySerializer.DeSerializeVector3(buffer, ref o, length);

            Vector3 rotationAngles = BinarySerializer.DeSerializeVector3(buffer, ref o, length);
            byte    rotationOrder  = BinarySerializer.DeSerializeUInt8(buffer, ref o, length);

            rotationOrder            = 0; // NOTE: This is what the LL code does
            mesh.SharedData.Rotation = Quaternion.Euler(rotationAngles);

            mesh.SharedData.Scale = BinarySerializer.DeSerializeVector3(buffer, ref o, length);

            logMessage = $"\n"
                         + $"    identifier:         \"{identifier}\"\n"
                         + $"    hasWeights:         {mesh.SharedData.HasWeights}\n"
                         + $"    hasDetailTexCoords: {mesh.SharedData.HasDetailTexCoords}\n"
                         + $"    position:           {mesh.SharedData.Position}\n"
                         + $"    rotationAngles:     {rotationAngles}\n"
                         + $"    rotationOrder:      {rotationOrder}\n"
                         + $"    scale:              {mesh.SharedData.Scale}\n"
            ;

            if (isLod == false)
            {
                UInt32 numVertices = BinarySerializer.DeSerializeUInt16_Le(buffer, ref o, length);
                logMessage += $"    nVertices:          0x{numVertices:x4}\n";
                mesh.SharedData.AllocateVertexData(numVertices);

                #region Vertices
                if (length - o < mesh.SharedData.NumVertices * 12)
                {
                    throw new Exception($"Not enough bytes to read vertices.");
                }

                for (int i = 0; i < mesh.SharedData.NumVertices; i++)
                {
                    mesh.SharedData.BaseCoords[i] = BinarySerializer.DeSerializeVector3(buffer, ref o, length);
                }
                #endregion Vertices
                #region Normals
                if (length - o < mesh.SharedData.NumVertices * 12)
                {
                    throw new Exception($"Not enough bytes to read normals.");
                }

                for (int i = 0; i < mesh.SharedData.NumVertices; i++)
                {
                    mesh.SharedData.BaseNormals[i] = BinarySerializer.DeSerializeVector3(buffer, ref o, length);
                }
                #endregion Normals
                #region BiNormals
                if (length - o < mesh.SharedData.NumVertices * 12)
                {
                    throw new Exception($"Not enough bytes to read bi-normals.");
                }

                for (int i = 0; i < mesh.SharedData.NumVertices; i++)
                {
                    mesh.SharedData.BaseBiNormals[i] = BinarySerializer.DeSerializeVector3(buffer, ref o, length);
                }
                #endregion BiNormals
                #region TexCoords
                if (length - o < mesh.SharedData.NumVertices * 8)
                {
                    throw new Exception($"Not enough bytes to read tex-coords.");
                }

                for (int i = 0; i < mesh.SharedData.NumVertices; i++)
                {
                    mesh.SharedData.TexCoords[i] = BinarySerializer.DeSerializeVector2(buffer, ref o, length);
                }
                #endregion TexCoords
                #region DetailedTexCoords
                if (mesh.SharedData.HasDetailTexCoords)
                {
                    if (length - o < mesh.SharedData.NumVertices * 8)
                    {
                        throw new Exception($"Not enough bytes to read detailed tex-coords.");
                    }

                    for (int i = 0; i < mesh.SharedData.NumVertices; i++)
                    {
                        mesh.SharedData.DetailTexCoords[i] = BinarySerializer.DeSerializeVector2(buffer, ref o, length);
                    }
                }
                #endregion DetailedTexCoords
                #region Weights
                if (mesh.SharedData.HasWeights)
                {
                    if (length - o < mesh.SharedData.NumVertices * 4)
                    {
                        throw new Exception($"Not enough bytes to read weights.");
                    }

                    for (int i = 0; i < mesh.SharedData.NumVertices; i++)
                    {
                        mesh.SharedData.Weights[i] = BinarySerializer.DeSerializeFloat_Le(buffer, ref o, length);
                    }
                }
                #endregion Weights
            }

            #region Faces
            UInt16 nFaces = BinarySerializer.DeSerializeUInt16_Le(buffer, ref o, length);
            logMessage += $"    nFaces:               0x{nFaces:x4}\n";
            mesh.SharedData.AllocateFaceData(nFaces);

            int numTris = 0;
            if (length - o < nFaces * 3 * 2)
            {
                throw new Exception($"Not enough bytes to read faces.");
            }

            for (int i = 0; i < nFaces; i++)
            {
                Int16 a = BinarySerializer.DeSerializeInt16_Le(buffer, ref o, length);
                Int16 b = BinarySerializer.DeSerializeInt16_Le(buffer, ref o, length);
                Int16 c = BinarySerializer.DeSerializeInt16_Le(buffer, ref o, length);
                if (mesh.SharedData.ReferenceData != null &&
                    (
                        a >= mesh.SharedData.ReferenceData.NumVertices ||
                        b >= mesh.SharedData.ReferenceData.NumVertices ||
                        c >= mesh.SharedData.ReferenceData.NumVertices
                    ))
                {
                    throw new Exception("DeSerializePolyMesh: Face index is out of range of the reference mesh.");
                }

                PolyFace face = new PolyFace(a, c, b); // Swizzled order for Unity
                if (isLod)
                {
                    // Store largest index in case of LODs
                    for (int j = 0; j < 3; j++)
                    {
                        if (face[j] > mesh.SharedData.NumVertices - 1)
                        {
                            mesh.SharedData.NumVertices = (UInt32)face[j] + 1;
                        }
                    }
                }

                mesh.SharedData.Faces[i] = face;
                numTris++;
            }

            logMessage += $"    NumTriangles: {numTris}\n";
            #endregion Faces

            if (isLod == false)
            {
                UInt16 nSkinJoints = 0;
                if (mesh.SharedData.HasWeights)
                {
                    nSkinJoints = BinarySerializer.DeSerializeUInt16_Le(buffer, ref o, length);
                    logMessage += $"    nSkinJoints:        0x{nSkinJoints:x4}\n";
                    mesh.SharedData.AllocateJointNames(nSkinJoints);
                }

                #region SkinJoints
                for (int i = 0; i < nSkinJoints; i++)
                {
                    mesh.SharedData.JointNames[i] = BinarySerializer.DeSerializeString(buffer, ref o, 64, -1);
                    logMessage += $"        jointName: {mesh.SharedData.JointNames[i]}\n";
                }
                #endregion SkinJoints
                #region MorphSections
                while (true)
                {
                    string morphName = BinarySerializer.DeSerializeString(buffer, ref o, 64, -1);
                    if (morphName == "End Morphs")
                    {
                        break;
                    }

                    PolyMorphData morphData = DeSerializePolyMorphData(buffer, ref o, length);
                    morphData.Name = morphName;
                    logMessage    += $"        Morph name: {morphName}\n";

                    mesh.SharedData.MorphData.Add(morphData);

                    // Insert jiggle physics morphs:
                    switch (morphName)
                    {
                    case "Breast_Female_Cleavage":
                        //mesh.SharedData.MorphData.Add(CloneMorphParamCleavage (morphData, 0.75f, "Breast_Physics_LeftRight_Driven"));
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDuplicate(morphData,        "Breast_Physics_InOut_Driven"));
                        break;

                    case "Breast_Gravity":
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDuplicate(morphData, "Breast_Physics_UpDown_Driven"));
                        break;

                    case "Big_Belly_Torso":
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDirection(morphData, new Vector3(0f, 0.05f, 0f), "Belly_Physics_Torso_UpDown_Driven"));
                        break;

                    case "Big_Belly_Legs":
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDirection(morphData, new Vector3(0f, 0.05f, 0f), "Belly_Physics_Legs_UpDown_Driven"));
                        break;

                    case "skirt_belly":
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDirection(morphData, new Vector3(0f, 0.05f, 0f), "Belly_Physics_Skirt_UpDown_Driven"));
                        break;

                    case "Small_Butt":
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDirection(morphData, new Vector3(0f, 0.05f, 0f), "Butt_Physics_UpDown_Driven"));
                        //mesh.SharedData.MorphData.Add(CloneMorphParamDirection(morphData, new Vector3(0f, 0.03f, 0f), "Butt_Physics_LeftRight_Driven"));
                        break;
                    }
                }
                #endregion MorphSections
                #region Remaps
                Int32 nRemaps = BinarySerializer.DeSerializeInt32_Le(buffer, ref o, length);
                for (int i = 0; i < nRemaps; i++)
                {
                    Int32 src = BinarySerializer.DeSerializeInt32_Le(buffer, ref o, length);
                    Int32 dst = BinarySerializer.DeSerializeInt32_Le(buffer, ref o, length);
                    mesh.SharedData.SharedVertices[src] = dst;
                }
                #endregion Remaps
            }

            if (mesh.SharedData.NumJointNames == 0)
            {
                mesh.SharedData.AllocateJointNames(1);
            }

            logMessage += $"{length - o} bytes left in buffer.";
            Logger.LogDebug("PolyMesh.DeSerializePolyMesh", logMessage);

            return(mesh);
        }
Ejemplo n.º 9
0
        public MovementUpdate DeSerializeMovementUpdate(byte[] buffer, ref int offset, int length)
        {
            float size      = 256;     // TODO: This should be fetched from the Region.WidthInMetres of the region this message is for.
            float minHeight = -256;    // TODO: I don't know where this should come from
            float maxHeight = 3 * 256; // TODO: I don't know where this should come from

            MovementUpdate update = new MovementUpdate();

            int len   = buffer[offset++];
            int limit = offset + len;

            switch (len)
            {
            case 60 + 16:
                // pull out collision normal for avatar
                update.FootPlane = BinarySerializer.DeSerializeVector4(buffer, ref offset, limit);
                goto case 60;

            case 60:
                update.Position        = BinarySerializer.DeSerializeVector3(buffer, ref offset, limit);
                update.Velocity        = BinarySerializer.DeSerializeVector3(buffer, ref offset, limit);
                update.Acceleration    = BinarySerializer.DeSerializeVector3(buffer, ref offset, limit);
                update.Rotation        = BinarySerializer.DeSerializeQuaternion(buffer, ref offset, limit);  // Theta
                update.AngularVelocity = BinarySerializer.DeSerializeVector3(buffer, ref offset, limit);     // Omega
                break;

            case 32 + 16:
                // pull out collision normal for avatar
                update.FootPlane = BinarySerializer.DeSerializeVector4(buffer, ref offset, limit);

                goto case 32;

            case 32:     // Values are UInt16 and needs to be quantized to floats
                update.Position = new Vector3(
                    x: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-0.5f * size, 1.5f * size),
                    z: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(minHeight, maxHeight),    // Handedness
                    y: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-0.5f * size, 1.5f * size));
                update.Velocity = new Vector3(
                    x: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size),
                    z: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size),    // Handedness
                    y: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size));
                update.Acceleration = new Vector3(
                    x: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size),
                    z: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size),     // Handedness
                    y: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size));
                update.Rotation = new Quaternion(
                    x: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-1f, 1f),
                    z: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-1f, 1f),     // Handedness
                    y: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-1f, 1f),
                    w: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-1f, 1f));
                update.AngularVelocity = new Vector3(
                    x: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size),
                    z: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size),     // Handedness
                    y: BinarySerializer.DeSerializeUInt16_Le(buffer, ref offset, limit).ToFloat(-size, size));
                break;

            case 16:    // Values are UInt8 and needs to be quantized to floats
                update.Position = new Vector3(
                    x: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-0.5f * size, 1.5f * size),
                    z: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(minHeight, maxHeight),     // Handedness
                    y: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-0.5f * size, 1.5f * size));
                update.Velocity = new Vector3(
                    x: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size),
                    z: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size),     // Handedness
                    y: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size));
                update.Acceleration = new Vector3(
                    x: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size),
                    z: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size),     // Handedness
                    y: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size));
                update.Rotation = new Quaternion(
                    x: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-1f, 1f),
                    z: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-1f, 1f),     // Handedness
                    y: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-1f, 1f),
                    w: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-1f, 1f));
                update.AngularVelocity = new Vector3(
                    x: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size),
                    z: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size),     // Handedness
                    y: BinarySerializer.DeSerializeUInt8(buffer, ref offset, limit).ToFloat(-size, size));
                break;
            }
            return(update);
        }
Ejemplo n.º 10
0
        protected override void DeSerialise(byte[] buf, ref int o, int length)
        {
            RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length));
            TimeDilation = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);

            int nObjects = buf[o++];

            for (int i = 0; i < nObjects; i++)
            {
                int len;
                ObjectUpdateMessage.ObjectData data = new ObjectUpdateMessage.ObjectData();
                Objects.Add(data);

                data.LocalId = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
                data.State   = buf[o++];

                data.FullId         = BinarySerializer.DeSerializeGuid(buf, ref o, length);
                data.Crc            = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
                data.PCode          = (PCode)buf[o++];
                data.Material       = (MaterialType)buf[o++];
                data.ClickAction    = (ClickAction)buf[o++];
                data.Scale          = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length);
                data.MovementUpdate = DeSerializeMovementUpdate(buf, ref o, buf.Length);

                data.ParentId    = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);
                data.UpdateFlags = (ObjectUpdateFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);

                data.PathCurve        = (PathType)buf[o++];
                data.ProfileCurve     = (ProfileType)buf[o++];
                data.PathBegin        = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA;
                data.PathEnd          = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA;
                data.PathScaleX       = buf[o++] * SCALE_QUANTA;
                data.PathScaleY       = buf[o++] * SCALE_QUANTA;
                data.PathShearX       = buf[o++] * SHEAR_QUANTA;
                data.PathShearY       = buf[o++] * SHEAR_QUANTA;
                data.PathTwist        = (sbyte)buf[o++] * SCALE_QUANTA;
                data.PathTwistBegin   = (sbyte)buf[o++] * SCALE_QUANTA;
                data.PathRadiusOffset = (sbyte)buf[o++] * SCALE_QUANTA;
                data.PathTaperX       = (sbyte)buf[o++] * TAPER_QUANTA;
                data.PathTaperY       = (sbyte)buf[o++] * TAPER_QUANTA;
                data.PathRevolutions  = buf[o++] * REV_QUANTA;
                data.PathSkew         = (sbyte)buf[o++] * SCALE_QUANTA;
                data.ProfileBegin     = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA;
                data.ProfileEnd       = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * CUT_QUANTA;
                data.ProfileHollow    = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length) * HOLLOW_QUANTA;

                data.TextureEntry     = BinarySerializer.DeSerializeTextureEntry(buf, ref o, length);
                data.TextureAnimation = BinarySerializer.DeSerializeTextureAnimation(buf, ref o, length);

                data.NameValue = BinarySerializer.DeSerializeString(buf, ref o, length, 2);
                len            = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);
                data.Data2     = new byte[len];
                Array.Copy(buf, o, data.Data2, 0, len);
                o              += len;
                data.Text       = BinarySerializer.DeSerializeString(buf, ref o, length, 1);
                data.TextColour = BinarySerializer.DeSerializeColor(buf, ref o, length);
                data.MediaUrl   = BinarySerializer.DeSerializeString(buf, ref o, length, 1);

                len = buf[o++];
                data.ParticleSystemData = new byte[len];
                Array.Copy(buf, o, data.ParticleSystemData, 0, len);
                o += len;

                len = buf[o++];
                data.ExtraParameters = BinarySerializer.DeSerializeExtraParameters(buf, ref o, o + len);

                data.SoundId    = BinarySerializer.DeSerializeGuid(buf, ref o, length);
                data.OwnerId    = BinarySerializer.DeSerializeGuid(buf, ref o, length);
                data.Gain       = BinarySerializer.DeSerializeUInt32_Le(buf, ref o, buf.Length);
                data.SoundFlags = (SoundFlags)buf[o++];
                data.Radius     = BinarySerializer.DeSerializeFloat_Le(buf, ref o, length);

                data.JointType         = (JointType)buf[o++];
                data.JointPivot        = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length);
                data.JointAxisOrAnchor = BinarySerializer.DeSerializeVector3(buf, ref o, buf.Length);

                //Logger.LogDebug("ObjectUpdateMessage.DeSerialise", ToString());
            }
        }
        protected override void DeSerialise(byte[] buf, ref int o, int length)
        {
            RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length));
            TimeDilation = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);

            string logMessage = $"ObjectUpdateCompressed: RegionHandle={RegionHandle}, TimeDilation={TimeDilation}";
            int    nObjects   = buf[o++];

            for (int i = 0; i < nObjects; i++)
            {
                UInt32 len;
                ObjectUpdateMessage.ObjectData data = new ObjectUpdateMessage.ObjectData();
                Objects.Add(data);

                data.UpdateFlags = (ObjectUpdateFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);

                int    compressedLength = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);
                byte[] compressedData   = new byte[compressedLength];
                Array.Copy(buf, o, compressedData, 0, compressedLength);
                o += compressedLength;
                int compressedOffset = 0;

                logMessage      += $"\n  Object {i}: UpdateFlags={data.UpdateFlags}, Data({compressedData.Length})={BitConverter.ToString(compressedData)}";
                data.FullId      = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength);
                data.LocalId     = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
                data.PCode       = (PCode)compressedData[compressedOffset++];
                data.State       = compressedData[compressedOffset++];
                data.Crc         = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
                data.Material    = (MaterialType)compressedData[compressedOffset++];
                data.ClickAction = (ClickAction)compressedData[compressedOffset++];
                data.Scale       = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength);
                data.Position    = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength);
                data.Rotation    = BinarySerializer.DeSerializeQuaternion(compressedData, ref compressedOffset, compressedLength);
                CompressedFlags compressedFlags = (CompressedFlags)BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);

                data.OwnerId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength);

                logMessage += $"\n    FullId={data.FullId}, LocalId={data.LocalId}, PCode={data.PCode}, State={data.State}, Crc={data.Crc}, Material={data.Material}, ClickAction={data.ClickAction}, Scale={data.Scale}, Position={data.Position}, Rotation={data.Rotation}, CompressedFlags=({compressedFlags})";

                if ((compressedFlags & CompressedFlags.HasAngularVelocity) != 0)
                {
                    data.AngularVelocity = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength);
                    logMessage          += $", AngularVelocity={data.AngularVelocity}";
                }

                data.ParentId = (compressedFlags & CompressedFlags.HasParent) != 0 ? BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength) : (uint)0;
                logMessage   += $", ParentId={data.ParentId}";

                if ((compressedFlags & CompressedFlags.Tree) != 0)
                {
                    byte treeSpecies = compressedData[compressedOffset++];
                    logMessage += $", TreeSpecies={treeSpecies}";
                }

                if ((compressedFlags & CompressedFlags.ScratchPad) != 0)
                {
                    len = compressedData[compressedOffset++];
                    compressedOffset += (int)len; // TODO: These offsets and length should all be UInt32
                    logMessage       += $", Scratchpad({len})";
                }

                if ((compressedFlags & CompressedFlags.HasText) != 0)
                {
                    data.Text       = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0);
                    data.TextColour = BinarySerializer.DeSerializeColor(compressedData, ref compressedOffset, compressedLength);
                    logMessage     += $", Text={data.Text}, TextColour={data.TextColour}";
                }

                if ((compressedFlags & CompressedFlags.MediaURL) != 0)
                {
                    data.MediaUrl = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0);
                    logMessage   += $", MediaUrl={data.MediaUrl}";
                }

                if ((compressedFlags & CompressedFlags.HasParticles) != 0)
                {
                    // TODO: Parse the particle system data. OpenMetaverse says that this is a BitPack of 86 bytes.
                    len = 86;
                    compressedOffset += (int)len;
                    logMessage       += $", ParticleSystem({len})";
                }

                data.ExtraParameters = BinarySerializer.DeSerializeExtraParameters(compressedData, ref compressedOffset, compressedOffset + compressedLength);

                if ((compressedFlags & CompressedFlags.HasSound) != 0)
                {
                    data.SoundId    = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength);
                    data.Gain       = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
                    data.SoundFlags = (SoundFlags)compressedData[compressedOffset++];
                    data.Radius     = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, compressedLength);
                    logMessage     += $", SoundId={data.SoundId}, Gain={data.Gain}, SoundFlags={data.SoundFlags}, Radius={data.Radius}";
                }

                if ((compressedFlags & CompressedFlags.HasNameValues) != 0)
                {
                    data.NameValue = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0);
                    logMessage    += $", NameValue={data.NameValue}";
                }

                data.PathCurve        = (PathType)compressedData[compressedOffset++];
                data.PathBegin        = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
                data.PathEnd          = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
                data.PathScaleX       = compressedData[compressedOffset++] * SCALE_QUANTA;
                data.PathScaleY       = compressedData[compressedOffset++] * SCALE_QUANTA;
                data.PathShearX       = compressedData[compressedOffset++] * SHEAR_QUANTA;
                data.PathShearY       = compressedData[compressedOffset++] * SHEAR_QUANTA;
                data.PathTwist        = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;
                data.PathTwistBegin   = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;
                data.PathRadiusOffset = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;
                data.PathTaperX       = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA;
                data.PathTaperY       = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA;
                data.PathRevolutions  = compressedData[compressedOffset++] * REV_QUANTA;
                data.PathSkew         = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;

                data.ProfileCurve  = (ProfileType)compressedData[compressedOffset++];
                data.ProfileBegin  = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
                data.ProfileEnd    = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
                data.ProfileHollow = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * HOLLOW_QUANTA;

                data.TextureEntry = BinarySerializer.DeSerializeTextureEntry(compressedData, ref compressedOffset, compressedLength, true);
                logMessage       += $", TextureEntry={data.TextureEntry}";

                if ((compressedFlags & CompressedFlags.TextureAnimation) != 0)
                {
                    data.TextureAnimation = BinarySerializer.DeSerializeTextureAnimation(compressedData, ref compressedOffset, compressedLength);
                    logMessage           += ", TextureAnimation";
                }

                data.IsAttachment = (compressedFlags & CompressedFlags.HasNameValues) != 0 && data.ParentId != 0;
            }
            //Logger.LogDebug("ObjectUpdateCompressedMessage.DeSerialise", logMessage);
        }
Ejemplo n.º 12
0
    protected override void DeSerialise(byte[] buf, ref int o, int length)
    {
        RegionHandle = new RegionHandle(BinarySerializer.DeSerializeUInt64_Le(buf, ref o, length));
        TimeDilation = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);

        string logMessage = $"ObjectUpdateCompressed: RegionHandle={RegionHandle}, TimeDilation={TimeDilation}";
        int    nObjects   = buf[o++];

        for (int i = 0; i < nObjects; i++)
        {
            UInt32 len;
            ObjectUpdateMessage.ObjectData data = new ObjectUpdateMessage.ObjectData();
            Objects.Add(data);

            data.UpdateFlags = (ObjectUpdateFlags)BinarySerializer.DeSerializeUInt32_Le(buf, ref o, length);

            int    compressedLength = BinarySerializer.DeSerializeUInt16_Le(buf, ref o, length);
            byte[] compressedData   = new byte[compressedLength];
            Array.Copy(buf, o, compressedData, 0, compressedLength);
            o += compressedLength;
            int compressedOffset = 0;

            logMessage      += $"\n  Object {i}: UpdateFlags={data.UpdateFlags}, Data({compressedData.Length})={BitConverter.ToString(compressedData)}";
            data.FullId      = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength);
            data.LocalId     = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
            data.PCode       = (PCode)compressedData[compressedOffset++];
            data.State       = compressedData[compressedOffset++];
            data.Crc         = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
            data.Material    = (MaterialType)compressedData[compressedOffset++];
            data.ClickAction = (ClickAction)compressedData[compressedOffset++];
            data.Scale       = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength);
            data.Position    = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength);
            data.Rotation    = BinarySerializer.DeSerializeQuaternion(compressedData, ref compressedOffset, compressedLength);
            CompressedFlags compressedFlags = (CompressedFlags)BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);

            data.OwnerId = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength);

            logMessage += $"\n    FullId={data.FullId}, LocalId={data.LocalId}, PCode={data.PCode}, State={data.State}, Crc={data.Crc}, Material={data.Material}, ClickAction={data.ClickAction}, Scale={data.Scale}, Position={data.Position}, Rotation={data.Rotation}, CompressedFlags=({compressedFlags})";

            if ((compressedFlags & CompressedFlags.HasAngularVelocity) != 0)
            {
                data.AngularVelocity = BinarySerializer.DeSerializeVector3(compressedData, ref compressedOffset, compressedLength);
                logMessage          += $", AngularVelocity={data.AngularVelocity}";
            }

            data.ParentId = (compressedFlags & CompressedFlags.HasParent) != 0 ? BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength) : (uint)0;
            logMessage   += $", ParentId={data.ParentId}";

            if ((compressedFlags & CompressedFlags.Tree) != 0)
            {
                byte treeSpecies = compressedData[compressedOffset++];
                logMessage += $", TreeSpecies={treeSpecies}";
            }

            if ((compressedFlags & CompressedFlags.ScratchPad) != 0)
            {
                len = compressedData[compressedOffset++];
                compressedOffset += (int)len; // TODO: These offsets and length should all be UInt32
                logMessage       += $", Scratchpad({len})";
            }

            if ((compressedFlags & CompressedFlags.HasText) != 0)
            {
                data.Text       = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0);
                data.TextColour = BinarySerializer.DeSerializeColor(compressedData, ref compressedOffset, compressedLength);
                logMessage     += $", Text={data.Text}, TextColour={data.TextColour}";
            }

            if ((compressedFlags & CompressedFlags.MediaURL) != 0)
            {
                data.MediaUrl = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0);
                logMessage   += $", MediaUrl={data.MediaUrl}";
            }

            if ((compressedFlags & CompressedFlags.HasParticles) != 0)
            {
                len         = 86;
                logMessage += $", ParticleSystem({len})";
            }

            byte nExtraParameters = compressedData[compressedOffset++];
            for (int j = 0; j < nExtraParameters; j++)
            {
                if (j == 0)
                {
                    logMessage += ", ExtraParameters=(";
                }
                ExtraParamType type = (ExtraParamType)BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, compressedLength);
                len = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
                switch (type)
                {
                case ExtraParamType.Flexible:
                    break;

                case ExtraParamType.Light:
                    break;

                case ExtraParamType.Sculpt:
                    break;

                case ExtraParamType.LightImage:
                    break;

                case ExtraParamType.Mesh:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                logMessage += $"{type}, ";

                compressedOffset += (int)len; // TODO: These offsets and length should all be UInt32

                if (j == nExtraParameters - 1)
                {
                    logMessage += ")";
                }
            }

            if ((compressedFlags & CompressedFlags.HasSound) != 0)
            {
                data.SoundId    = BinarySerializer.DeSerializeGuid(compressedData, ref compressedOffset, compressedLength);
                data.Gain       = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, compressedLength);
                data.SoundFlags = (SoundFlags)compressedData[compressedOffset++];
                data.Radius     = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, compressedLength);
                logMessage     += $", SoundId={data.SoundId}, Gain={data.Gain}, SoundFlags={data.SoundFlags}, Radius={data.Radius}";
            }

            if ((compressedFlags & CompressedFlags.HasNameValues) != 0)
            {
                data.NameValue = BinarySerializer.DeSerializeString(compressedData, ref compressedOffset, compressedLength, 0);
                logMessage    += $", NameValue={data.NameValue}";
            }

            data.PathCurve        = (PathType)compressedData[compressedOffset++];
            data.PathBegin        = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
            data.PathEnd          = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
            data.PathScaleX       = compressedData[compressedOffset++] * SCALE_QUANTA;
            data.PathScaleY       = compressedData[compressedOffset++] * SCALE_QUANTA;
            data.PathShearX       = compressedData[compressedOffset++] * SHEAR_QUANTA;
            data.PathShearY       = compressedData[compressedOffset++] * SHEAR_QUANTA;
            data.PathTwist        = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;
            data.PathTwistBegin   = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;
            data.PathRadiusOffset = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;
            data.PathTaperX       = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA;
            data.PathTaperY       = (sbyte)compressedData[compressedOffset++] * TAPER_QUANTA;
            data.PathRevolutions  = compressedData[compressedOffset++] * REV_QUANTA;
            data.PathSkew         = (sbyte)compressedData[compressedOffset++] * SCALE_QUANTA;

            data.ProfileCurve  = (ProfileType)compressedData[compressedOffset++];
            data.ProfileBegin  = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
            data.ProfileEnd    = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * CUT_QUANTA;
            data.ProfileHollow = BinarySerializer.DeSerializeUInt16_Le(compressedData, ref compressedOffset, length) * HOLLOW_QUANTA;

            UInt32 textureEntryLength = BinarySerializer.DeSerializeUInt32_Le(compressedData, ref compressedOffset, length);
            logMessage       += $", textures({textureEntryLength})";
            compressedOffset += (int)textureEntryLength;

            if ((compressedFlags & CompressedFlags.TextureAnimation) != 0)
            {
                TextureAnimation textureAnimation = new TextureAnimation()
                {
                    Mode   = (TextureAnimationMode)compressedData[compressedOffset++],
                    Face   = compressedData[compressedOffset++],
                    SizeX  = compressedData[compressedOffset++],
                    SizeY  = compressedData[compressedOffset++],
                    Start  = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, length),
                    Length = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, length),
                    Rate   = BinarySerializer.DeSerializeFloat_Le(compressedData, ref compressedOffset, length)
                };
                logMessage += ", TextureAnimation";
            }

            data.IsAttachment = (compressedFlags & CompressedFlags.HasNameValues) != 0 && data.ParentId != 0;
        }
        //Logger.LogDebug(logMessage);
    }