/// <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)); }
/// <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()); }
/// <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()); }
/// <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); }
/// <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()); }
/// <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); }
/// <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); }