예제 #1
0
        /// <summary>
        /// Read and handle the <see cref="MeshCreateMessage"/>.
        /// </summary>
        /// <param name="reader">Stream to read from.</param>
        /// <returns>True on success.</returns>
        /// <remarks>
        /// Handling is deferred to <see cref="ProcessCreate(MeshCreateMessage)"/> which subclasses
        /// should implement.
        /// </remarks>
        public bool ReadCreate(BinaryReader reader)
        {
            MeshCreateMessage msg = new MeshCreateMessage();

            if (!msg.Read(reader))
            {
                return(false);
            }

            return(ProcessCreate(msg));
        }
예제 #2
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());
        }
예제 #3
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());
        }
예제 #4
0
        /// <summary>
        /// Send initial mesh creation message.
        /// </summary>
        /// <param name="packet">Packet to populate with the create message.</param>
        /// <returns>Zero on success.</returns>
        public int Create(PacketBuffer packet)
        {
            MeshCreateMessage msg = new MeshCreateMessage();

            msg.Attributes.SetFromTransform(Transform);
            msg.Attributes.Colour = Tint;

            msg.MeshID      = ID;
            msg.VertexCount = VertexCount();
            msg.IndexCount  = IndexCount();
            msg.DrawType    = DrawType;

            packet.Reset((ushort)RoutingID.Mesh, MeshCreateMessage.MessageID);
            msg.Write(packet);
            return(0);
        }
예제 #5
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));
            }

            if (msg.DrawType < 0 || msg.DrawType > Enum.GetValues(typeof(MeshDrawType)).Length)
            {
                return(new Error(ErrorCode.UnsupportedFeature, msg.DrawType));
            }

            MeshDetails meshEntry  = new MeshDetails();
            RenderMesh  renderMesh = new RenderMesh((MeshDrawType)msg.DrawType, (int)msg.VertexCount, (int)msg.IndexCount);

            meshEntry.Mesh = renderMesh;

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

            NotifyMeshAdded(meshEntry);

            return(new Error());
        }
예제 #6
0
 /// <summary>
 /// Process the <see cref="MeshCreateMessage"/>.
 /// </summary>
 /// <param name="msg">The message to process.</param>
 /// <returns>True on success</returns>
 /// <remarks>
 /// Called from <see cref="ReadCreate(BinaryReader)"/> for subclasses to implement.
 /// </remarks>
 protected virtual bool ProcessCreate(MeshCreateMessage msg)
 {
     return(false);
 }
예제 #7
0
        /// <summary>
        /// Process the <see cref="MeshCreateMessage"/>.
        /// </summary>
        /// <param name="msg">The message to read.</param>
        /// <returns>True on success</returns>
        ///
        protected override bool ProcessCreate(MeshCreateMessage msg)
        {
            if (ID != msg.MeshID)
            {
                return(false);
            }

            // Presize vertex list.
            if (_vertices == null)
            {
                _vertices = new List <Vector3>((int)msg.VertexCount);
            }

            if (_vertices.Count < msg.VertexCount)
            {
                for (int i = _vertices.Count; i < msg.VertexCount; ++i)
                {
                    _vertices.Add(Vector3.Zero);
                }
            }
            else
            {
                if (msg.VertexCount > 0)
                {
                    while (_vertices.Count > msg.VertexCount)
                    {
                        _vertices.RemoveAt(_vertices.Count - 1);
                    }
                }
                else
                {
                    _vertices.Clear();
                }
            }

            // Presize index list.
            if (_indices == null)
            {
                _indices = new List <int>((int)msg.IndexCount);
            }

            if (_indices.Count < msg.IndexCount)
            {
                for (int i = _indices.Count; i < msg.IndexCount; ++i)
                {
                    _indices.Add(0);
                }
            }
            else
            {
                if (msg.IndexCount > 0)
                {
                    while (_indices.Count > msg.IndexCount)
                    {
                        _indices.RemoveAt(_indices.Count - 1);
                    }
                }
                else
                {
                    _indices.Clear();
                }
            }

            _normals = null;
            _colours = null;
            _uvs     = null;

            DrawType  = msg.DrawType;
            Transform = msg.Attributes.GetTransform();
            Tint      = msg.Attributes.Colour;
            return(true);
        }