Esempio n. 1
0
        /// <summary>
        /// Overridden to write the point cloud indices.
        /// </summary>
        /// <param name="packet">Packet to write to.</param>
        /// <param name="progressMarker">Number of indices written so far.</param>
        /// <returns>0 when complete, 1 to call again.</returns>
        public override int WriteData(PacketBuffer packet, ref uint progressMarker)
        {
            // Max items based on packet size of 0xffff, minus some overhead divide by index size.
            DataMessage msg      = new DataMessage();
            const uint  MaxItems = (uint)((0xffff - 256) / 4);

            packet.Reset(RoutingID, DataMessage.MessageID);

            msg.ObjectID = ID;
            msg.Write(packet);

            // Write indices for this view into the cloud.
            uint offset = progressMarker;
            uint count  = IndexCount - progressMarker;

            if (count > MaxItems)
            {
                count = MaxItems;
            }

            // Use 32-bits for both values though count will never need greater than 16-bit.
            packet.WriteBytes(BitConverter.GetBytes(offset), true);
            packet.WriteBytes(BitConverter.GetBytes(count), true);

            if (count != 0)
            {
                for (uint i = offset; i < offset + count; ++i)
                {
                    packet.WriteBytes(BitConverter.GetBytes(Index(i)), true);
                }
            }

            progressMarker += count;
            return((progressMarker < IndexCount) ? 1 : 0);
        }
Esempio n. 2
0
        public override int WriteData(PacketBuffer packet, ref uint progressMarker)
        {
            if (_shapes.Length <= BlockCountLimit)
            {
                // Nothing more to write. Creation packet was enough.
                return(0);
            }

            DataMessage msg = new DataMessage();

            msg.ObjectID = ID;
            packet.Reset(RoutingID, DataMessage.MessageID);
            msg.Write(packet);

            UInt32 itemOffset     = (progressMarker + (uint)BlockCountLimit);
            UInt32 remainingItems = (uint)_shapes.Length - itemOffset;
            UInt16 blockCount     = (UInt16)(Math.Min(remainingItems, BlockCountLimit));

            packet.WriteBytes(BitConverter.GetBytes(blockCount), true);

            for (uint i = 0; i < blockCount; ++i)
            {
                if (!_shapes[itemOffset + i].GetAttributes().Write(packet))
                {
                    return(-1);
                }
            }

            progressMarker += blockCount;

            if (remainingItems > blockCount)
            {
                // More to come.
                return(1);
            }

            // All done.
            return(0);
        }
Esempio n. 3
0
        /// <summary>
        /// A helper function for writing as many <see cref="DataMessage"/> messsages as required.
        /// </summary>
        /// <param name="routingID">Routing id for the message being composed.</param>
        /// <param name="objectID">ID of the object to which the data belong.</param>
        /// <param name="packet">Data packet to compose in.</param>
        /// <param name="progressMarker">Progress or pagination marker.</param>
        /// <param name="vertices">Mesh vertex array.</param>
        /// <param name="normals">Mesh normal array. One per vertex or just a single normal to apply to all vertices.</param>
        /// <param name="indices">Mesh indices.</param>
        /// <param name="colours">Per vertex colours. See <see cref="Colour"/> for format details.</param>
        /// <remarks>Call recursively until zero is returned. Packet does not get finalised here.</remarks>
        public static int WriteData(ushort routingID, uint objectID,
                                    PacketBuffer packet, ref uint progressMarker,
                                    Vector3[] vertices, Vector3[] normals, int[] indices, UInt32[] colours)
        {
            DataMessage msg = new DataMessage();
            // Local byte overhead needs to account for the size of sendType, offset and itemCount.
            // Use a larger value as I haven't got the edge cases quite right yet.
            const int localByteOverhead = 100;

            msg.ObjectID = objectID;
            packet.Reset(routingID, DataMessage.MessageID);
            msg.Write(packet);

            uint   offset;
            uint   itemCount;
            ushort sendType;

            int verticesLength = (vertices != null) ? vertices.Length : 0;
            int normalsLength  = (normals != null) ? normals.Length : 0;
            int coloursLength  = (colours != null) ? colours.Length : 0;
            int indicesLength  = (indices != null) ? indices.Length : 0;

            DataPhase[] phases = new DataPhase[]
            {
                new DataPhase((normalsLength == 1) ? SendDataType.UniformNormal : SendDataType.Normals, normalsLength,
                              (uint index) => {
                    Vector3 n = normals[index];
                    packet.WriteBytes(BitConverter.GetBytes(n.X), true);
                    packet.WriteBytes(BitConverter.GetBytes(n.Y), true);
                    packet.WriteBytes(BitConverter.GetBytes(n.Z), true);
                },
                              4, 3),
                new DataPhase(SendDataType.Colours, coloursLength,
                              (uint index) => { packet.WriteBytes(BitConverter.GetBytes(colours[index]), true); },
                              4),
                new DataPhase(SendDataType.Vertices, verticesLength,
                              (uint index) => {
                    Vector3 v = vertices[index];
                    packet.WriteBytes(BitConverter.GetBytes(v.X), true);
                    packet.WriteBytes(BitConverter.GetBytes(v.Y), true);
                    packet.WriteBytes(BitConverter.GetBytes(v.Z), true);
                },
                              4, 3),
                new DataPhase(SendDataType.Indices, indicesLength,
                              (uint index) => { packet.WriteBytes(BitConverter.GetBytes(indices[index]), true); },
                              4),
            };

            int  phaseIndex          = 0;
            uint previousPhaseOffset = 0u;

            // While progressMarker is greater than or equal to the sum of the previous phase counts and the current phase count.
            // Also terminate of out of phases.
            while (phaseIndex < phases.Length &&
                   progressMarker >= previousPhaseOffset + phases[phaseIndex].ItemCount)
            {
                previousPhaseOffset += phases[phaseIndex].ItemCount;
                ++phaseIndex;
            }

            bool done = false;

            // Check if we have anything to send.
            if (phaseIndex < phases.Length)
            {
                DataPhase phase = phases[phaseIndex];
                // Send part of current phase.
                // Estimate element count limit.
                int maxItemCount = MeshBase.EstimateTransferCount(phase.DataSizeBytes * phase.TupleSize, 0, DataMessage.Size + localByteOverhead);
                offset    = progressMarker - previousPhaseOffset;
                itemCount = (uint)Math.Min(phase.ItemCount - offset, maxItemCount);

                sendType = (ushort)((int)phase.Type | (int)SendDataType.ExpectEnd);

                packet.WriteBytes(BitConverter.GetBytes(sendType), true);
                packet.WriteBytes(BitConverter.GetBytes(offset), true);
                packet.WriteBytes(BitConverter.GetBytes(itemCount), true);

                for (uint i = offset; i < offset + itemCount; ++i)
                {
                    phase.WriteElement(i);
                }

                progressMarker += itemCount;
            }
            else
            {
                // Either all done or no data to send.
                // In the latter case, we need to populate the message anyway.
                offset   = itemCount = 0;
                sendType = (int)SendDataType.ExpectEnd | (int)SendDataType.End;
                packet.WriteBytes(BitConverter.GetBytes(sendType), true);
                packet.WriteBytes(BitConverter.GetBytes(offset), true);
                packet.WriteBytes(BitConverter.GetBytes(itemCount), true);
                done = true;
            }

            // Return 1 while there is more data to process.
            return((!done) ? 1 : 0);
        }