예제 #1
0
        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());
        }