private byte[] SerialzeWorkloadRequest(BackgroundWorkerArgs args) { int bufferSize = 10; // A bit of slack bufferSize += (4 * 3 * 3); // Light-Position, Forward-Dir, UpwardDir bufferSize += args.Indices.Count * 4; bufferSize += args.Vertices.Count * 4 * 3; bufferSize += args.ObjectData.Count * ((4 * 4 * 4) // Matrix 4x4 + (4 * 3) // Offsets (and count) + (2 * 3 * 4)); // Bounds bufferSize += 13 * 4; // A quick quess at the size of the rest of what goes into the WorkRequest bufferSize += 2 * 4; // A quick guess at the size of the root message. // With the way that flatbuffers (that's a singular proper-noun that uses a lowercase starting letter, // don't ask me why, I didn't name the thing) works, it encodes the data as a byte-array. Only, it does // this piece by piece, return offsets objects that tells you the location with-in the byte-array. // Then, when you create the larger pieces (tables), you feed it the offsets of the child data that has // already been encoded. For more complicated data where you know that a value or child object gets // shared, you can use the same offset to cutdown on the overall size of the byte-array. This also lets // you do things like decreasing the size of the byte-array by leaving out values. var builder = new FlatBufferBuilder(bufferSize); var indicesVectorOffset = WorkloadRequest.CreateIndicesVector(builder, args.Indices.ToArray()); WorkloadRequest.StartVerticesVector(builder, args.Vertices.Count); foreach (var vert in args.Vertices) { Vec3.CreateVec3(builder, vert.x, vert.y, vert.z); } var vertsVectorOffset = builder.EndVector(); WorkloadRequest.StartObjectDataVector(builder, args.ObjectData.Count); foreach (var objectDatum in args.ObjectData) { // I wasn't expecting the constructor of a struct with embedded structs to rollout the embedded // structs, but it does make sense. How else would we created the embedded structs without adding them // to the builder first and then setting their offset into the parent struct? Doing it this way cuts // down on the size of the byte-array, but it really is a bit of a pain to type this out without any // mistakes. // -FCT MeshObject.CreateMeshObject(builder, objectDatum.LocalToWorldMatrix.m00, objectDatum.LocalToWorldMatrix.m01, objectDatum.LocalToWorldMatrix.m02, objectDatum.LocalToWorldMatrix.m03, objectDatum.LocalToWorldMatrix.m10, objectDatum.LocalToWorldMatrix.m11, objectDatum.LocalToWorldMatrix.m12, objectDatum.LocalToWorldMatrix.m13, objectDatum.LocalToWorldMatrix.m20, objectDatum.LocalToWorldMatrix.m21, objectDatum.LocalToWorldMatrix.m22, objectDatum.LocalToWorldMatrix.m23, objectDatum.LocalToWorldMatrix.m30, objectDatum.LocalToWorldMatrix.m31, objectDatum.LocalToWorldMatrix.m32, objectDatum.LocalToWorldMatrix.m33, objectDatum.IndicesOffset, objectDatum.IndicesCount, objectDatum.VerticesOffset, objectDatum.Bounds.Center.x, objectDatum.Bounds.Center.y, objectDatum.Bounds.Center.z, objectDatum.Bounds.Extent.x, objectDatum.Bounds.Extent.y, objectDatum.Bounds.Extent.z); } var objectDataVectorOffset = builder.EndVector(); WorkloadRequest.StartWorkloadRequest(builder); // While I'm able to create an array of structs well before I'm going to use them, it seems that when // it comes to the structs themselves, I need to create them as I use them. WorkloadRequest.AddLightSourceForwardDir(builder, Vec3.CreateVec3(builder, args.LightForward.x, args.LightForward.y, args.LightForward.z)); WorkloadRequest.AddLightSourceUpwardDir(builder, Vec3.CreateVec3(builder, args.LightUpward.x, args.LightUpward.y, args.LightUpward.z)); WorkloadRequest.AddLightSourcePosition(builder, Vec3.CreateVec3(builder, args.LightPosition.x, args.LightPosition.y, args.LightPosition.z)); WorkloadRequest.AddBounceCount(builder, s_maxBounceCount); WorkloadRequest.AddMaxRange(builder, s_outerRadius); WorkloadRequest.AddMinRange(builder, s_innerRadius); WorkloadRequest.AddSampleCount(builder, s_sampleCount); WorkloadRequest.AddShadowFocusPlane(builder, s_shadowFocusDistance); WorkloadRequest.AddWorkloadID(builder, 25); WorkloadRequest.AddResolution(builder, s_resolutionOptions[s_selectedCookieResolution]); WorkloadRequest.AddIndices(builder, indicesVectorOffset); WorkloadRequest.AddVertices(builder, vertsVectorOffset); WorkloadRequest.AddObjectData(builder, objectDataVectorOffset); var workloadRequestOffset = WorkloadRequest.EndWorkloadRequest(builder); Message.StartMessage(builder); Message.AddData(builder, workloadRequestOffset.Value); Message.AddDataType(builder, MessageDatum.WorkloadRequest); var messageOffset = Message.EndMessage(builder); builder.Finish(messageOffset.Value); return(builder.SizedByteArray()); }