//Creating the mesh void CreateShape(DllFunctions.Mesh mesh) { // Marshaling for the faces int[] faces = new int[mesh.numFaces * 3]; Marshal.Copy(mesh.faces, faces, 0, mesh.numFaces * 3); for (int i = 0; i < faces.Length; i += 3) { var temp = faces[i + 1]; faces[i + 1] = faces[i + 2]; faces[i + 2] = temp; } // Marshaling for the vertices float[] vertexArray = new float[mesh.numVertices * 3]; Vector3[] vertices = new Vector3[mesh.numVertices]; Marshal.Copy(mesh.vertices, vertexArray, 0, mesh.numVertices * 3); for (int i = 0; i < mesh.numVertices; i++) { vertices[i] = (new Vector3(vertexArray[3 * i], vertexArray[3 * i + 1], vertexArray[3 * i + 2])); } // Lock the arrays in order to feed the game object lock (m_lockobj) { m_vertices.AddRange(vertices); m_faces.AddRange(faces); } }
// Defining textures of the shader void DefineTexture(DllFunctions.Mesh mesh) { //Marshaling for the texture images IntPtr[] texturePtr = new IntPtr[mesh.numDevices]; byte[][] textures = new byte[mesh.numDevices][]; Marshal.Copy(mesh.textures, texturePtr, 0, mesh.numDevices); for (int i = 0; i < mesh.numDevices; i++) { textures[i] = new byte[mesh.width * mesh.height * 3]; Marshal.Copy(texturePtr[i], textures[i], 0, mesh.width * mesh.height * 3); } // Lock the byte arrays to feed the game object lock (m_lockobj) { m_textures = textures; } }
// Defining the rest of the shader 's parameters void DefineShaderParams(DllFunctions.Mesh mesh) { // Marshaling for the weigths of each of the cameras defining a vertex 's texture float[] camWeights = new float[mesh.numVertices]; Marshal.Copy(mesh.weights, camWeights, 0, mesh.numVertices); // Marshaling for the ids of the cameras participating to a vertex 's texture int[] cam1 = new int[mesh.numVertices]; int[] cam2 = new int[mesh.numVertices]; Vector4[] camParticipation = new Vector4[mesh.numVertices]; Marshal.Copy(mesh.id1, cam1, 0, mesh.numVertices); Marshal.Copy(mesh.id2, cam2, 0, mesh.numVertices); // Assigning vertices to a Vector3 array in order to feed the shader for (int i = 0; i < mesh.numVertices; i++) { camParticipation[i] = (new Vector4((float)cam1[i], (float)cam2[i], camWeights[i], 1 - camWeights[i])); } // Marshaling for the color extrinsics float[] colorExtrinsics = new float[mesh.numDevices * 16]; Marshal.Copy(mesh.colorExts, colorExtrinsics, 0, mesh.numDevices * 16); // Marshaling for the color intrinsics float[] colorIntrinsics = new float[mesh.numDevices * 9]; Marshal.Copy(mesh.colorInts, colorIntrinsics, 0, mesh.numDevices * 9); // Lock the arrays in order to feed the game object lock (m_lockobj) { m_numDevs = mesh.numDevices; m_width = mesh.width; m_height = mesh.height; m_participatingCams.AddRange(camParticipation); m_colorExts.AddRange(colorExtrinsics); m_colorInts.AddRange(colorIntrinsics); } }
// Updating the mesh every time a new buffer is received from the network private void DataProvider_OnNewData(object sender, EventArgs <byte[]> e) { // Starting the stopwatch which counts the time needed to process a buffer until the mesh is rendered stopWatch = System.Diagnostics.Stopwatch.StartNew(); lock (e) { if (e.Value != null && received_new_frame == false) { //// Storing the received buffer to a .bin file //File.WriteAllBytes(@"C:\VCL_User_Prod\RealSenzBinsCorto\RealSenzBin_" + ind + ".bin", e.Value); //Debug.Log("file saved"); stopWatch = System.Diagnostics.Stopwatch.StartNew(); stopWatch.Start(); // Flaging that a new buffer is received int size = Marshal.SizeOf(e.Value[0]) * e.Value.Length; // Buffer 's size var buffer = e.Value; // Buffer 's data var gcRes = GCHandle.Alloc(buffer, GCHandleType.Pinned); // GCHandler for the buffer var pnt = gcRes.AddrOfPinnedObject(); // Buffer 's address IntPtr meshPtr = DllFunctions.callTVMFrameDLL(pnt, buffer.Length, mesh_id); // Pointer of the returned structure DllFunctions.Mesh currentMesh = (DllFunctions.Mesh)Marshal.PtrToStructure(meshPtr, typeof(DllFunctions.Mesh)); // C# struct equivalent of the one produced by the native C++ DLL // Clearing the lists of the deserialiazed buffer 's data m_vertices.Clear(); m_faces.Clear(); m_participatingCams.Clear(); m_colorExts.Clear(); m_colorInts.Clear(); try { // Defining the textures from the returned struct DefineTexture(currentMesh); // Defining the mesh data from the returned struct CreateShape(currentMesh); // Defining the shader 's parameters from the returned struct DefineShaderParams(currentMesh); // Freeing the GCHandler gcRes.Free(); received_new_frame = true; } catch (UnityException ex) { Debug.Log(ex.Message); } stopWatch.Stop(); deserializeTime.Add(stopWatch.ElapsedMilliseconds); if (deserializeTime.Count == 1000) { Debug.Log("Deserialization time for 1000 frames -> Mean: " + deserializeTime.Average() + ", " + "Std: " + CalculateStdDev(deserializeTime)); } } } }