/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal { using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using static NRKernal.NativeMeshing; public interface IMeshInfoProcessor { void UpdateMeshInfo(ulong identifier, NRMeshingBlockState meshingBlockState, Mesh mesh); void ClearMeshInfo(); } public class NRMeshingManager : SingletonBehaviour { /// The size of the bounding box [SerializeField] private Vector3 m_BoundingBoxSize; [SerializeField] private float m_MeshRequestInterval; IMeshInfoProcessor[] m_MeshInfoProcessors; private NativeMeshing m_NativeMeshing; Coroutine m_MeshingCoroutine; float m_MeshUpdateTime = 0; Func, bool> m_Predicate = new Func, bool>( p => p.Value.blockState != NRMeshingBlockState.NR_MESHING_BLOCK_STATE_UNCHANGED); /// Starts this object. private void Start() { if (isDirty) return; NRDebugger.Info("[NRMeshingManager] Start"); m_NativeMeshing = new NativeMeshing(); m_NativeMeshing.Create(); m_NativeMeshing.Start(); m_NativeMeshing.SetMeshingFlags(NRMeshingFlags.NR_MESHING_FLAGS_COMPUTE_NORMAL); m_MeshInfoProcessors = GetComponents(); } void Update() { if (m_MeshingCoroutine == null) { m_MeshUpdateTime += Time.deltaTime; if (m_MeshUpdateTime >= m_MeshRequestInterval) { RequestMeshing(); m_MeshUpdateTime = 0; } } } void RequestMeshing() { if (m_MeshingCoroutine != null) StopCoroutine(m_MeshingCoroutine); m_MeshingCoroutine = StartCoroutine(RequestMeshingCoroutine()); } IEnumerator RequestMeshingCoroutine() { yield return RequestMeshInfoCoroutine(); yield return RequestMeshDetailCoroutine(); m_MeshingCoroutine = null; } IEnumerator RequestMeshInfoCoroutine() { NRDebugger.Info("[NRMeshingManager] Start RequestMeshInfoCoroutine"); if (m_NativeMeshing.RequestMeshInfo(m_BoundingBoxSize, NRFrame.HeadPose)) { while (!m_NativeMeshing.GetMeshInfoResult()) { NRDebugger.Debug("[NRMeshingManager] Wait GetMeshInfoResult"); yield return null; } var timestamp = m_NativeMeshing.GetMeshInfoTimestamp(); NRDebugger.Info("[NRMeshingManager] GetMeshInfoTimestamp: {0}", timestamp); m_NativeMeshing.GetBlockInfoData(); m_NativeMeshing.DestroyMeshInfo(); m_NativeMeshing.DestroyMeshInfoRequest(); } } IEnumerator RequestMeshDetailCoroutine() { NRDebugger.Info("[NRMeshingManager] Start RequestMeshDetailCoroutine"); if (m_NativeMeshing.RequestMeshDetail(m_Predicate)) { while (!m_NativeMeshing.GetMeshDetailResult()) { NRDebugger.Debug("[NRMeshingManager] Wait GetMeshDetailResult"); yield return null; } var timestamp = m_NativeMeshing.GetMeshDetailTimestamp(); NRDebugger.Info("[NRMeshingManager] GetMeshDetailTimestamp: {0}", timestamp); yield return m_NativeMeshing.GetMeshDetailData(ProcessMeshDetail); m_NativeMeshing.DestroyMeshDetail(); m_NativeMeshing.DestroyMeshDetailRequest(); } } void ProcessMeshDetail(ulong identifier, NRMeshingBlockState meshingBlockState, Mesh mesh) { foreach (var processor in m_MeshInfoProcessors) { processor.UpdateMeshInfo(identifier, meshingBlockState, mesh); } } /// Executes the 'application pause' action. /// True to pause. private void OnApplicationPause(bool pause) { NRDebugger.Info("[NRMeshingManager] OnApplicationPause: {0}", pause); if (m_NativeMeshing != null) { if (pause) { m_NativeMeshing.Pause(); } else { m_NativeMeshing.Resume(); } } } protected override void OnDestroy() { NRDebugger.Info("[NRMeshingManager] OnDestroy"); base.OnDestroy(); if (m_NativeMeshing != null) { m_NativeMeshing.Stop(); m_NativeMeshing.Destroy(); } } } }