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

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

            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.Normal));
            }

            // Check for settings initial bounds.
            bool    ok = true;
            Vector3 n  = Vector3.zero;

            for (int vInd = 0; ok && vInd < (int)msg.Count; ++vInd)
            {
                n.x = reader.ReadSingle();
                n.y = reader.ReadSingle();
                n.z = reader.ReadSingle();
                meshDetails.Builder.UpdateNormal(vInd + voffset, n);
                meshDetails.Builder.BoundsPadding.x = Mathf.Max(meshDetails.Builder.BoundsPadding.x, Mathf.Abs(n.x));
                meshDetails.Builder.BoundsPadding.y = Mathf.Max(meshDetails.Builder.BoundsPadding.y, Mathf.Abs(n.y));
                meshDetails.Builder.BoundsPadding.z = Mathf.Max(meshDetails.Builder.BoundsPadding.z, Mathf.Abs(n.z));
            }

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

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

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

            MeshDetails meshEntry;

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

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

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

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

            // Check for settings initial bounds.
            bool    ok = true;
            Vector2 uv = Vector2.zero;

            for (int vInd = 0; ok && vInd < msg.Count; ++vInd)
            {
                uv.x = reader.ReadSingle();
                uv.y = reader.ReadSingle();
                _v2Buffer.Add(uv);
            }
            meshEntry.Mesh.SetUVs(_v2Buffer, 0, voffset, _v2Buffer.Count);
            _v2Buffer.Clear();

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

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

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

            MeshDetails meshEntry;

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

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

            int ioffset = (int)msg.Offset;
            // Bounds check.
            int indexCount = (int)meshEntry.Mesh.IndexCount;

            if (ioffset >= indexCount || ioffset + msg.Count > indexCount)
            {
                return(new Error(ErrorCode.IndexingOutOfRange, (ushort)MeshMessageType.Index));
            }

            // Check for settings initial bounds.
            bool ok = true;
            int  index;

            _intBuffer.Clear();
            for (int iInd = 0; ok && iInd < msg.Count; ++iInd)
            {
                index = reader.ReadInt32();
                _intBuffer.Add(index);
            }
            meshEntry.Mesh.SetIndices(_intBuffer, 0, ioffset, _intBuffer.Count);
            _intBuffer.Clear();

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

            return(new Error());
        }
Ejemplo n.º 4
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.º 5
0
        /// <summary>
        /// Read and handle a <see cref="MeshComponentMessage"/> message.
        /// </summary>
        /// <param name="messageType">The <see cref="MeshMessageType"/> identifying the mesh component being read.</param>
        /// <param name="reader">Stream to read from.</param>
        /// <returns>True on success.</returns>
        /// <remarks>
        /// Handling is deferred to one of the process methods which subclasses should implement.
        ///
        /// The <paramref name="messageType"/> identifies the mesh component being read, from the following set;
        /// <list type="bullet">
        /// <item><see cref="MeshMessageType.Vertex"/></item>
        /// <item><see cref="MeshMessageType.Index"/></item>
        /// <item><see cref="MeshMessageType.VertexColour"/></item>
        /// <item><see cref="MeshMessageType.Normal"/></item>
        /// <item><see cref="MeshMessageType.UV"/></item>
        /// </list>
        /// </remarks>
        public bool ReadTransfer(int messageType, BinaryReader reader)
        {
            MeshComponentMessage msg = new MeshComponentMessage();

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

            switch (messageType)
            {
            case (int)MeshMessageType.Vertex:
                Vector3[] newVertices = new Vector3[msg.Count];
                for (int i = 0; i < msg.Count; ++i)
                {
                    newVertices[i] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                }
                return(ProcessVertices(msg, newVertices));

            case (int)MeshMessageType.Index:
                if (IndexSize == 2)
                {
                    ushort[] newInds = new ushort[msg.Count];
                    for (int i = 0; i < msg.Count; ++i)
                    {
                        newInds[i] = reader.ReadUInt16();
                    }
                    return(ProcessIndices(msg, newInds));
                }
                else if (IndexSize == 4)
                {
                    int[] newInds = new int[msg.Count];
                    for (int i = 0; i < msg.Count; ++i)
                    {
                        newInds[i] = reader.ReadInt32();
                    }
                    return(ProcessIndices(msg, newInds));
                }
                // Unknown index size.
                return(false);

            case (int)MeshMessageType.VertexColour:
                uint[] newColours = new uint[msg.Count];
                for (int i = 0; i < msg.Count; ++i)
                {
                    newColours[i] = reader.ReadUInt32();
                }
                return(ProcessColours(msg, newColours));

            case (int)MeshMessageType.Normal:
                Vector3[] newNormals = new Vector3[msg.Count];
                for (int i = 0; i < msg.Count; ++i)
                {
                    newNormals[i] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                }
                return(ProcessNormals(msg, newNormals));

            case (int)MeshMessageType.UV:
                Vector2[] newUVs = new Vector2[msg.Count];
                for (int i = 0; i < msg.Count; ++i)
                {
                    newUVs[i] = new Vector2(reader.ReadSingle());
                }
                return(ProcessUVs(msg, newUVs));

            default:
                // Unknown message type.
                break;
            }

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

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

            MeshDetails meshEntry;

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

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

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

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

            // Check for settings initial bounds.
            bool    ok = true;
            Vector3 n  = Vector3.zero;

            _v3Buffer.Clear();
            Vector3 boundsPadding = Vector3.zero;

            for (int vInd = 0; ok && vInd < (int)msg.Count; ++vInd)
            {
                n.x = reader.ReadSingle();
                n.y = reader.ReadSingle();
                n.z = reader.ReadSingle();
                _v3Buffer.Add(n);
                // Bounds padding used to cater for voxel rendering.
                boundsPadding.x = Mathf.Max(boundsPadding.x, Mathf.Abs(n.x));
                boundsPadding.y = Mathf.Max(boundsPadding.y, Mathf.Abs(n.y));
                boundsPadding.z = Mathf.Max(boundsPadding.z, Mathf.Abs(n.z));
            }
            meshEntry.Mesh.SetNormals(_v3Buffer, 0, voffset, _v3Buffer.Count);
            _v3Buffer.Clear();

            // Pad the bounds by largest the normal for voxels.
            if (meshEntry.Mesh.DrawType == MeshDrawType.Voxels)
            {
                boundsPadding.x = Mathf.Max(boundsPadding.x, Mathf.Abs(meshEntry.Mesh.BoundsPadding.x));
                boundsPadding.y = Mathf.Max(boundsPadding.y, Mathf.Abs(meshEntry.Mesh.BoundsPadding.y));
                boundsPadding.z = Mathf.Max(boundsPadding.z, Mathf.Abs(meshEntry.Mesh.BoundsPadding.z));
                meshEntry.Mesh.BoundsPadding = boundsPadding;
            }

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

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

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

            MeshDetails meshEntry;

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

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

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

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

            // Check for settings initial bounds.
            bool    ok = true;
            Vector3 v  = Vector3.zero;

            _v3Buffer.Clear();
            Vector3 minBounds = Vector3.zero;
            Vector3 maxBounds = Vector3.zero;

            for (int vInd = 0; ok && vInd < msg.Count; ++vInd)
            {
                v.x = reader.ReadSingle();
                v.y = reader.ReadSingle();
                v.z = reader.ReadSingle();
                if (vInd > 0)
                {
                    minBounds.x = Mathf.Min(minBounds.x, v.x);
                    minBounds.y = Mathf.Min(minBounds.y, v.z);
                    minBounds.z = Mathf.Min(minBounds.z, v.y);
                    maxBounds.x = Mathf.Max(maxBounds.x, v.x);
                    maxBounds.y = Mathf.Max(maxBounds.y, v.z);
                    maxBounds.z = Mathf.Max(maxBounds.z, v.y);
                }
                else
                {
                    minBounds = maxBounds = v;
                }
                _v3Buffer.Add(v);
            }
            meshEntry.Mesh.SetVertices(_v3Buffer, 0, voffset, _v3Buffer.Count);
            _v3Buffer.Clear();

            // Update bounds.
            if (meshEntry.Mesh.BoundsSet)
            {
                minBounds.x = Mathf.Min(minBounds.x, meshEntry.Mesh.MinBounds.x);
                minBounds.y = Mathf.Min(minBounds.y, meshEntry.Mesh.MinBounds.z);
                minBounds.z = Mathf.Min(minBounds.z, meshEntry.Mesh.MinBounds.y);
                maxBounds.x = Mathf.Max(maxBounds.x, meshEntry.Mesh.MaxBounds.x);
                maxBounds.y = Mathf.Max(maxBounds.y, meshEntry.Mesh.MaxBounds.z);
                maxBounds.z = Mathf.Max(maxBounds.z, meshEntry.Mesh.MaxBounds.y);
            }

            meshEntry.Mesh.MinBounds = minBounds;
            meshEntry.Mesh.MaxBounds = maxBounds;

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

            return(new Error());
        }