Ejemplo n.º 1
0
        /// <summary>
        /// Message handler for <see cref="CreateMessage"/>
        /// </summary>
        /// <param name="msg">The incoming message.</param>
        /// <param name="packet">The buffer containing the message.</param>
        /// <param name="reader">The reader from which the message came.</param>
        /// <returns>An error code on failure.</returns>
        /// <remarks>
        /// Creates either a persistent or transient object depending on the incoming
        /// message ObjectID. An ID of zero signifies a transient object.
        /// Solid or wire shapes are assigned according to the message flags.
        /// </remarks>
        protected virtual Error HandleMessage(CreateMessage msg, PacketBuffer packet, BinaryReader reader)
        {
            GameObject obj = null;

            if (msg.ObjectID == 0)
            {
                // Transient object.
                obj = CreateTransient();
            }
            else
            {
                obj = CreateObject(msg.ObjectID);
                if (!obj)
                {
                    // Object already exists.
                    return(new Error(ErrorCode.DuplicateShape, msg.ObjectID));
                }
            }

            ShapeComponent shapeComp = obj.GetComponent <ShapeComponent>();

            shapeComp.Category    = msg.Category;
            shapeComp.ObjectFlags = msg.Flags;
            shapeComp.Colour      = ShapeComponent.ConvertColour(msg.Attributes.Colour);

            obj.transform.SetParent(_root.transform, false);
            DecodeTransform(msg.Attributes, obj.transform);

            InitialiseVisual(shapeComp, ShapeComponent.ConvertColour(msg.Attributes.Colour));

            return(PostHandleMessage(obj, msg, packet, reader));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Message handler for <see cref="UpdateMessage"/>
        /// </summary>
        /// <param name="msg">The incoming message.</param>
        /// <param name="packet">The buffer containing the message.</param>
        /// <param name="reader">The reader from which the message came.</param>
        /// <returns>An error code on failure.</returns>
        /// <remarks>
        /// Decodes the message transform and colour, updating the existing shape
        /// matching the message ObjectID. Only relevant for persistent shapes.
        /// </remarks>
        protected virtual Error HandleMessage(UpdateMessage msg, PacketBuffer packet, BinaryReader reader)
        {
            GameObject obj = FindObject(msg.ObjectID);

            if (obj == null)
            {
                return(new Error(ErrorCode.InvalidObjectID, msg.ObjectID));
            }

            ushort flags = msg.Flags;

            DecodeTransform(msg.Attributes, obj.transform, flags);

            if ((flags & (ushort)UpdateFlag.UpdateMode) == 0 || (flags & (ushort)UpdateFlag.Colour) != 0)
            {
                ShapeComponent shapeComp = obj.GetComponent <ShapeComponent>();
                if (shapeComp != null)
                {
                    shapeComp.Colour = ShapeComponent.ConvertColour(msg.Attributes.Colour);
                }

                SetColour(obj, ShapeComponent.ConvertColour(msg.Attributes.Colour));
            }

            return(new Error());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Handles <see cref="MeshRedefineMessage"/>
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        /// <remarks>
        /// The associated mesh is invalidated until another <see cref="MeshFinaliseMessage"/> arrives.
        /// </remarks>
        protected Error RedefineMesh(PacketBuffer packet, BinaryReader reader)
        {
            MeshRedefineMessage msg = new MeshRedefineMessage();

            if (!msg.Read(reader))
            {
                return(new Error(ErrorCode.MalformedMessage, MeshRedefineMessage.MessageID));
            }

            MeshDetails meshDetails;

            if (!_meshes.TryGetValue(msg.MeshID, out meshDetails))
            {
                return(new Error(ErrorCode.InvalidObjectID, msg.MeshID));
            }

            meshDetails.Finalised = false;
            if (msg.VertexCount != meshDetails.VertexCount)
            {
                meshDetails.VertexCount = (int)msg.VertexCount;
            }
            if (msg.IndexCount != 0)
            {
                meshDetails.IndexCount = (int)msg.IndexCount;
            }

            meshDetails.ID            = msg.MeshID;
            meshDetails.LocalPosition = new Vector3(msg.Attributes.X, msg.Attributes.Y, msg.Attributes.Z);
            meshDetails.LocalRotation = new Quaternion(msg.Attributes.RotationX, msg.Attributes.RotationY, msg.Attributes.RotationZ, msg.Attributes.RotationW);
            meshDetails.LocalScale    = new Vector3(msg.Attributes.ScaleX, msg.Attributes.ScaleY, msg.Attributes.ScaleZ);
            meshDetails.Tint          = ShapeComponent.ConvertColour(msg.Attributes.Colour);

            return(new Error());
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Handles <see cref="MeshCreateMessage"/>
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        /// <remarks>
        /// Emits <see cref="OnMeshAdded"/>.
        /// </remarks>
        protected Error CreateMesh(PacketBuffer packet, BinaryReader reader)
        {
            MeshCreateMessage msg = new MeshCreateMessage();

            if (!msg.Read(reader))
            {
                return(new Error(ErrorCode.MalformedMessage, MeshCreateMessage.MessageID));
            }

            if (_meshes.ContainsKey(msg.MeshID))
            {
                return(new Error(ErrorCode.DuplicateShape, msg.MeshID));
            }

            MeshDetails meshDetails = new MeshDetails();

            meshDetails.VertexCount = (int)msg.VertexCount;
            meshDetails.IndexCount  = (int)msg.IndexCount;
            meshDetails.DrawType    = msg.DrawType;
            switch (msg.DrawType)
            {
            case (byte)MeshDrawType.Points:
            // No break.
            case (byte)MeshDrawType.Voxels:
                meshDetails.Builder.Topology = MeshTopology.Points;
                break;

            case (byte)MeshDrawType.Lines:
                meshDetails.Builder.Topology = MeshTopology.Lines;
                break;

            case (byte)MeshDrawType.Triangles:
                meshDetails.Builder.Topology = MeshTopology.Triangles;
                break;

            default:
                return(new Error(ErrorCode.UnsupportedFeature, msg.DrawType));
            }

            meshDetails.ID            = msg.MeshID;
            meshDetails.LocalPosition = new Vector3(msg.Attributes.X, msg.Attributes.Y, msg.Attributes.Z);
            meshDetails.LocalRotation = new Quaternion(msg.Attributes.RotationX, msg.Attributes.RotationY, msg.Attributes.RotationZ, msg.Attributes.RotationW);
            meshDetails.LocalScale    = new Vector3(msg.Attributes.ScaleX, msg.Attributes.ScaleY, msg.Attributes.ScaleZ);
            meshDetails.Tint          = ShapeComponent.ConvertColour(msg.Attributes.Colour);
            meshDetails.Finalised     = false;
            _meshes.Add(meshDetails.ID, meshDetails);

            NotifyMeshAdded(meshDetails);

            return(new Error());
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Serialise messages to generate <paramref name="mesh"/>.
        /// </summary>
        /// <param name="mesh">The mesh of interest.</param>
        /// <param name="packet">Packet buffer to compose messages in</param>
        /// <param name="writer">Writer to export completed message packets to.</param>
        /// <returns></returns>
        /// <remarks>
        /// Writes:
        /// <list type="bullet">
        /// <item><see cref="MeshCreateMessage"/></item>
        /// <item><see cref="MeshComponentMessage"/> for each component type from
        /// <see cref="MeshMessageType"/></item>
        /// <item><see cref="MeshFinaliseMessage"/> only when <paramref name="mesh"/> is already
        /// finalised.</item>
        /// </list>
        /// </remarks>
        protected Error Serialise(MeshDetails mesh, PacketBuffer packet, BinaryWriter writer)
        {
            // First write a create message.
            MeshCreateMessage msg = new MeshCreateMessage();

            packet.Reset((ushort)RoutingID, (ushort)MeshCreateMessage.MessageID);

            msg.MeshID      = mesh.ID;
            msg.VertexCount = (uint)mesh.Builder.VertexCount;
            msg.IndexCount  = (uint)(mesh.Builder.ExplicitIndices ? mesh.Builder.IndexCount : 0);
            msg.DrawType    = mesh.DrawType;

            msg.Attributes.X = mesh.LocalPosition.x;
            msg.Attributes.Y = mesh.LocalPosition.y;
            msg.Attributes.Z = mesh.LocalPosition.z;

            msg.Attributes.RotationX = mesh.LocalRotation.x;
            msg.Attributes.RotationY = mesh.LocalRotation.y;
            msg.Attributes.RotationZ = mesh.LocalRotation.z;
            msg.Attributes.RotationW = mesh.LocalRotation.w;

            msg.Attributes.ScaleX = mesh.LocalScale.x;
            msg.Attributes.ScaleY = mesh.LocalScale.y;
            msg.Attributes.ScaleZ = mesh.LocalScale.z;

            msg.Attributes.Colour = ShapeComponent.ConvertColour(mesh.Tint);

            msg.Write(packet);
            if (!packet.FinalisePacket())
            {
                return(new Error(ErrorCode.SerialisationFailure));
            }
            packet.ExportTo(writer);

            // Now use the MeshResource methods to complete serialisation.
            MeshSerialiser   serialiser = new MeshSerialiser(mesh);
            TransferProgress prog       = new TransferProgress();

            prog.Reset();
            while (!prog.Complete)
            {
                serialiser.Transfer(packet, 0, ref prog);
                if (!packet.FinalisePacket())
                {
                    return(new Error(ErrorCode.SerialisationFailure));
                }
                packet.ExportTo(writer);
            }

            return(new Error());
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Handles <see cref="MeshComponentMessage"/> of type <see cref="MeshMessageType.VertexColour"/>.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="reader"></param>
        /// <returns></returns>
        protected Error AddVertexColours(PacketBuffer packet, BinaryReader reader)
        {
            MeshComponentMessage msg = new MeshComponentMessage();

            if (!msg.Read(reader))
            {
                return(new Error(ErrorCode.MalformedMessage, (ushort)MeshMessageType.VertexColour));
            }

            MeshDetails meshDetails;

            if (!_meshes.TryGetValue(msg.MeshID, out meshDetails))
            {
                return(new Error(ErrorCode.InvalidObjectID, msg.MeshID));
            }

            if (msg.Count == 0)
            {
                return(new Error());
            }

            int voffset = (int)msg.Offset;
            // Bounds check.
            int vertexCount = (int)meshDetails.VertexCount;

            if (voffset >= vertexCount || voffset + msg.Count > vertexCount)
            {
                return(new Error(ErrorCode.IndexingOutOfRange, (ushort)MeshMessageType.VertexColour));
            }

            // Check for settings initial bounds.
            bool ok = true;
            uint colour;

            for (int vInd = 0; ok && vInd < msg.Count; ++vInd)
            {
                colour = reader.ReadUInt32();
                meshDetails.Builder.UpdateColour(vInd + voffset, ShapeComponent.ConvertColour(colour));
            }

            if (!ok)
            {
                return(new Error(ErrorCode.MalformedMessage, (ushort)MeshMessageType.VertexColour));
            }

            return(new Error());
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Called to extract the current object attributes from an existing object.
        /// </summary>
        /// <param name="attr">Modified to reflect the current state of <paramref name="obj"/></param>
        /// <param name="obj">The object to encode attributes for.</param>
        /// <param name="comp">The <see cref="ShapeComponent"/> of <paramref name="obj"/></param>
        /// <remarks>
        /// This extracts colour and performs the inverse operation of <see cref="DecodeTransform"/>
        /// This method must be overridden whenever <see cref="DecodeTransform"/> is overridden.
        /// </remarks>
        protected virtual void EncodeAttributes(ref ObjectAttributes attr, GameObject obj, ShapeComponent comp)
        {
            Transform transform = obj.transform;

            attr.X         = transform.localPosition.x;
            attr.Y         = transform.localPosition.y;
            attr.Z         = transform.localPosition.z;
            attr.RotationX = transform.localRotation.x;
            attr.RotationY = transform.localRotation.y;
            attr.RotationZ = transform.localRotation.z;
            attr.RotationW = transform.localRotation.w;
            attr.ScaleX    = transform.localScale.x;
            attr.ScaleY    = transform.localScale.y;
            attr.ScaleZ    = transform.localScale.z;
            if (comp != null)
            {
                attr.Colour = ShapeComponent.ConvertColour(comp.Colour);
            }
            else
            {
                attr.Colour = 0xffffffu;
            }
        }