/// <summary> /// Overridden to read optional point cloud indices. /// </summary> /// <param name="msg">Message header.</param> /// <param name="packet">Data packet.</param> /// <param name="reader">Data packet reader.</param> /// <returns></returns> protected override Error HandleMessage(DataMessage msg, PacketBuffer packet, BinaryReader reader) { ShapeCache cache = (msg.ObjectID == 0) ? _transientCache : _shapeCache; int shapeIndex = (msg.ObjectID == 0) ? _lastTransientIndex : cache.GetShapeIndex(msg.ObjectID); if (shapeIndex < 0) { return(new Error(ErrorCode.InvalidObjectID, msg.ObjectID)); } PointsComponent pointsComp = cache.GetShapeDataByIndex <PointsComponent>(shapeIndex); // Read index offset and count. uint offset = reader.ReadUInt32(); uint count = reader.ReadUInt32(); int[] indices = pointsComp.Indices; for (uint i = 0; i < count; ++i) { indices[i + offset] = reader.ReadInt32(); } pointsComp.IndicesDirty = true; if (pointsComp.IndexCount != 0 && offset + count >= pointsComp.IndexCount) { // Done. Register for the mesh. RegisterForMesh(pointsComp); } return(new Error()); }
/// <summary> /// Overridden to handle triangle data in the <paramref name="msg"/> /// </summary> /// <param name="msg"></param> /// <param name="packet"></param> /// <param name="reader"></param> /// <returns></returns> protected override Error HandleMessage(DataMessage msg, PacketBuffer packet, BinaryReader reader) { ShapeCache cache = (msg.ObjectID == 0) ? _transientCache : _shapeCache; int shapeIndex = (msg.ObjectID == 0) ? _lastTransientIndex : cache.GetShapeIndex(msg.ObjectID); if (shapeIndex < 0) { return(new Error(ErrorCode.InvalidObjectID, msg.ObjectID)); } // Naive support for multiple packets. Assume: // - In order. MeshEntry meshEntry = cache.GetShapeDataByIndex <MeshEntry>(shapeIndex); // Well, this is confusing indirection... int readComponent = MeshShape.ReadDataComponentDeferred( reader, (uint)meshEntry.Mesh.VertexCount, (uint)meshEntry.Mesh.IndexCount, // Vertex handler. new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadMeshVector3Data(reader2, offset, count, (Vector3[] buffer, int writeOffset, int writeCount) => { meshEntry.Mesh.SetVertices(buffer, 0, writeOffset, writeCount, true); })); }), // Index handler new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadIndexComponent(reader2, offset, count, meshEntry.Mesh)); }), // Normals handler. new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadMeshVector3Data(reader2, offset, count, (Vector3[] buffer, int writeOffset, int writeCount) => { if (dataType == MeshShape.SendDataType.UniformNormal) { // Only one normal for the whole mesh. // Fill the buffer and write in chunks. for (int i = 1; i < buffer.Length; ++i) { buffer[i] = buffer[0]; } int localOffset = 0; for (int i = 0; i < meshEntry.Mesh.VertexCount; i += buffer.Length) { int blockCount = Math.Min(buffer.Length, meshEntry.Mesh.VertexCount - localOffset); meshEntry.Mesh.SetNormals(buffer, 0, localOffset, blockCount); writeOffset += blockCount; } } else { meshEntry.Mesh.SetNormals(buffer, 0, writeOffset, writeCount); } })); }), // Colours handler. new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadColourComponent(reader2, offset, count, meshEntry.Mesh)); }) ); if (readComponent == -1) { return(new Error(ErrorCode.MalformedMessage, DataMessage.MessageID)); } if (readComponent == (int)(MeshShape.SendDataType.Vertices | MeshShape.SendDataType.End)) { // Finalise the material. meshEntry.Material = CreateMaterial(cache.GetShapeByIndex(shapeIndex), meshEntry); cache.SetShapeDataByIndex(shapeIndex, meshEntry); } return(new Error()); }