void LateUpdate() { if (!Application.isPlaying || !EditorApplication.isPlayingOrWillChangePlaymode || !startRecord) { return; } currentTime += Time.deltaTime; if (currentTime > frameInterval) { currentTime -= frameInterval; } else { return; } bool isIframe = frameCnt == 0 ? true : false; if (isIframe) { tiling.SetInt("packSize", packageSize); tiling.SetInt("range", containerSize); } if (renderers != null) { Dictionary <int, TilePacker> dicPacks = new Dictionary <int, TilePacker>(); List <FragmentVertex[]> frag = new List <FragmentVertex[]>(); for (int i = 0; i < renderers.Count; i++) { SkinnedMeshRenderer smr = renderers[i]; if (smr != null) { //convert to tiled vertices Mesh tempMesh = new Mesh(); smr.BakeMesh(tempMesh); //calculate shader threads and dipatch size; int alignedNum = 16; string kernelName = "cs_main8"; int verts = tempMesh.vertices.Length; int dispatch = 2; for (int k = 0; k < alignedVerts.Length; k++) { int aligned = alignedVerts[k]; if (verts - aligned <= 0) { alignedNum = aligned; kernelName = kernelNames[k]; dispatch = dispatches[k]; break; } } Vector3[] src = new Vector3[alignedNum]; tempMesh.vertices.CopyTo(src, 0); DestroyImmediate(tempMesh); Quaternion quat = smr.transform.rotation; Vector3 pos = smr.transform.position - targetGameObject.transform.position; Vector3 scale = new Vector3(1, 1, 1); Matrix4x4 wrd = Matrix4x4.TRS(pos, quat, scale); float[] wrdMatrix = { wrd.m00, wrd.m01, wrd.m02, wrd.m03, wrd.m10, wrd.m11, wrd.m12, wrd.m13, wrd.m20, wrd.m21, wrd.m22, wrd.m23, wrd.m30, wrd.m31, wrd.m32, wrd.m33 }; if (isIframe) { tiling.SetFloats("wrdMatrix", wrdMatrix); tiling.SetInt("modelGroup", i); ComputeBuffer srcBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(TiledVertex))); srcBuf.SetData(src); int kernelNum = tiling.FindKernel(kernelName); tiling.SetBuffer(kernelNum, "srcBuf", srcBuf); tiling.SetBuffer(kernelNum, "destBuf", destBuf); tiling.Dispatch(kernelNum, dispatch, 1, 1); TiledVertex[] data = new TiledVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); destBuf.Release(); for (int j = 0; j < verts; j++) { TiledVertex vert = data[j]; int tx = (vert.tileID & 0xFF); int ty = (vert.tileID & 0xFF00) >> 8; int tz = (vert.tileID & 0xFF0000) >> 16; int tileID = tx + ty * packageSize + tz * (packageSize * packageSize); if (tx == 255 && ty == 255 && tz == 255) { continue; } TilePacker tile; if (!dicPacks.TryGetValue(tileID, out tile)) { tile = new TilePacker(tx, ty, tz); dicPacks.Add(tileID, tile); } ByteCoord coord = new ByteCoord(); coord.p1 = (byte)((vert.polyIndex & 0xFF)); coord.p2 = (byte)((vert.polyIndex & 0xFF00) >> 8); coord.p3 = (byte)((vert.polyIndex & 0xFF0000) >> 16); coord.x = (byte)vert.x; coord.y = (byte)vert.y; coord.z = (byte)vert.z; dicPacks[tileID].AddVertex(coord); } } else { diff.SetFloats("wrdMatrix", wrdMatrix); diff.SetFloats("oldMatrix", oldMatrix[i]); ComputeBuffer srcBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer oldBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(FragmentVertex))); srcBuf.SetData(src); oldBuf.SetData(oldVertsBuf[i]); int kernelNum = diff.FindKernel(kernelName); diff.SetBuffer(kernelNum, "srcBuf", srcBuf); diff.SetBuffer(kernelNum, "oldBuf", oldBuf); diff.SetBuffer(kernelNum, "destBuf", destBuf); diff.Dispatch(kernelNum, dispatch, 1, 1); FragmentVertex[] data = new FragmentVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); oldBuf.Release(); destBuf.Release(); frag.Add(data); } oldVertsBuf[i] = src; oldMatrix[i] = wrdMatrix; } } int packages = 0; List <byte> lPacks = new List <byte>(); if (isIframe) { linedIndices.Clear(); foreach (KeyValuePair <int, TilePacker> p in dicPacks) { packages++; TilePacker pack = p.Value; lPacks.AddRange(pack.PackToByteArray(packageSize)); linedIndices.AddRange(pack.getIndices()); } } else { for (int i = 0; i < linedIndices.Count; i++) { int meshIndex = (linedIndices[i] >> 16) & 0xFF; int vertIndex = linedIndices[i] & 0xFFFF; FragmentVertex f = frag[meshIndex][vertIndex]; byte[] val = new byte[3]; val[0] = (byte)(f.x); val[1] = (byte)(f.y); val[2] = (byte)(f.z); lPacks.AddRange(val); } } int currentBinaryLength = combinedBinary.Count; if (currentBinaryLength == 0) { tempStartTicks = DateTime.Now.Ticks; } byte[] streamData = AddHeader(lPacks.ToArray(), targetGameObject.transform.position, packages, isIframe, timeStamp); byteSize.Add(streamData.Length); combinedBinary.AddRange(streamData); timeStamp++; if (timeStamp % combinedFrames == 0 && timeStamp > 0) { long tick = timeStamp / combinedFrames - 1; long startTicks = tempStartTicks - recordStartTicks; long endTicks = DateTime.Now.Ticks - recordStartTicks; StreamInfo streamInfo = serializer.CreateStreamInfo(tick, startTicks, endTicks); serializer.Send(streamInfo, tick); string fileName = tick.ToString("000000") + ".stmv"; byte[] buffer = new byte[(byteSize.Count + 1) * sizeof(int) + combinedBinary.Count]; byteSize.Insert(0, byteSize.Count); Buffer.BlockCopy(byteSize.ToArray(), 0, buffer, 0, byteSize.Count * sizeof(int)); Buffer.BlockCopy(combinedBinary.ToArray(), 0, buffer, byteSize.Count * sizeof(int), combinedBinary.Count); //serializer.Send(ExternalTools.Compress(combinedBinary.ToArray()), "stream", fileName); serializer.Send(Lib.ExternalTools.Compress(buffer), "stream", fileName); byteSize.Clear(); combinedBinary.Clear(); } } frameCnt = (frameCnt + 1) % (subframesPerKeyframe + 1); }
void LateUpdate() { if (!isConnected || webRtcManager.connections == 0) { return; } currentTime += Time.deltaTime; if (currentTime > frameInterval) { currentTime -= frameInterval; } else { return; } bool isIframe = frameCnt == 0 ? true : false; if (isIframe) { tiling.SetInt("packSize", packageSize); tiling.SetInt("range", areaRange); } if (renderers != null) { Dictionary <int, TilePacker> dicPacks = new Dictionary <int, TilePacker>(); List <FragmentVertex[]> frag = new List <FragmentVertex[]>(); for (int i = 0; i < renderers.Length; i++) { SkinnedMeshRenderer smr = renderers[i]; if (smr != null) { //convert to tiled vertices Mesh tempMesh = new Mesh(); smr.BakeMesh(tempMesh); //calculate shader threads and dipatch size; int alignedNum = 16; string kernelName = "cs_main8"; int verts = tempMesh.vertices.Length; int dispatch = 2; for (int k = 0; k < alignedVerts.Length; k++) { int aligned = alignedVerts[k]; if (verts - aligned <= 0) { alignedNum = aligned; kernelName = kernelNames[k]; dispatch = dispatches[k]; break; } } Vector3[] src = new Vector3[alignedNum]; tempMesh.vertices.CopyTo(src, 0); DestroyImmediate(tempMesh); Quaternion quat = smr.transform.rotation; Vector3 pos = smr.transform.position - targetGameObject.transform.position; Vector3 scale = new Vector3(1, 1, 1); Matrix4x4 wrd = Matrix4x4.TRS(pos, quat, scale); float[] wrdMatrix = { wrd.m00, wrd.m01, wrd.m02, wrd.m03, wrd.m10, wrd.m11, wrd.m12, wrd.m13, wrd.m20, wrd.m21, wrd.m22, wrd.m23, wrd.m30, wrd.m31, wrd.m32, wrd.m33 }; if (isIframe) { tiling.SetFloats("wrdMatrix", wrdMatrix); tiling.SetInt("modelGroup", i); ComputeBuffer srcBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(TiledVertex))); srcBuf.SetData(src); int kernelNum = tiling.FindKernel(kernelName); tiling.SetBuffer(kernelNum, "srcBuf", srcBuf); tiling.SetBuffer(kernelNum, "destBuf", destBuf); tiling.Dispatch(kernelNum, dispatch, 1, 1); TiledVertex[] data = new TiledVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); destBuf.Release(); for (int j = 0; j < verts; j++) { TiledVertex vert = data[j]; int tx = (vert.tileID & 0xFF); int ty = (vert.tileID & 0xFF00) >> 8; int tz = (vert.tileID & 0xFF0000) >> 16; int tileID = tx + ty * packageSize + tz * (packageSize * packageSize); if (tx == 255 && ty == 255 && tz == 255) { continue; } TilePacker tile; if (!dicPacks.TryGetValue(tileID, out tile)) { tile = new TilePacker(tx, ty, tz); dicPacks.Add(tileID, tile); } ByteCoord coord = new ByteCoord(); coord.p1 = (byte)((vert.polyIndex & 0xFF)); coord.p2 = (byte)((vert.polyIndex & 0xFF00) >> 8); coord.p3 = (byte)((vert.polyIndex & 0xFF0000) >> 16); coord.x = (byte)vert.x; coord.y = (byte)vert.y; coord.z = (byte)vert.z; dicPacks[tileID].AddVertex(coord); } } else { diff.SetFloats("wrdMatrix", wrdMatrix); diff.SetFloats("oldMatrix", oldMatrix[i]); ComputeBuffer srcBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer oldBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(FragmentVertex))); srcBuf.SetData(src); oldBuf.SetData(oldVertsBuf[i]); int kernelNum = diff.FindKernel(kernelName); diff.SetBuffer(kernelNum, "srcBuf", srcBuf); diff.SetBuffer(kernelNum, "oldBuf", oldBuf); diff.SetBuffer(kernelNum, "destBuf", destBuf); diff.Dispatch(kernelNum, dispatch, 1, 1); FragmentVertex[] data = new FragmentVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); oldBuf.Release(); destBuf.Release(); frag.Add(data); } oldVertsBuf[i] = src; oldMatrix[i] = wrdMatrix; } } int byteCnt = 0; int packages = 0; List <byte> lPacks = new List <byte>(); if (isIframe) { linedIndices.Clear(); foreach (KeyValuePair <int, TilePacker> p in dicPacks) { packages++; TilePacker pack = p.Value; lPacks.AddRange(pack.PackToByteArray(packageSize)); linedIndices.AddRange(pack.getIndices()); } } else { for (int i = 0; i < linedIndices.Count; i++) { int meshIndex = (linedIndices[i] >> 16) & 0xFF; int vertIndex = linedIndices[i] & 0xFFFF; FragmentVertex f = frag[meshIndex][vertIndex]; byte[] val = new byte[3]; val[0] = (byte)(f.x); val[1] = (byte)(f.y); val[2] = (byte)(f.z); lPacks.AddRange(val); } } byteCnt += lPacks.Count; byte[] rawBuf = lPacks.ToArray(); byte[] compressedBuf = null; int[] prog = new int[1]; #if UNITY_WEBGL || BROTLI_NO_COMPRESS #else if (!brotli.compressBuffer(lPacks.ToArray(), ref compressedBuf, prog, quality: 8)) { Debug.Log("compress failed!"); return; } #endif webRtcManager.SendVertexStream(rawBuf, compressedBuf, targetGameObject.transform.position, packages, isIframe, timeStamp, true); timeStamp++; } frameCnt = (frameCnt + 1) % (subframesPerKeyframe + 1); }