123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- using AOT;
- using EZXR.Glass.Core;
- using EZXR.Glass.Device;
- using EZXR.Glass.Recording;
- using EZXR.Glass.SixDof;
- using System;
- using System.Collections;
- using System.IO;
- using System.Runtime.InteropServices;
- using UnityEngine;
- namespace EZXR.Glass.Projection
- {
- public class ProjectionManager : MonoBehaviour
- {
- private static ProjectionManager instance;
- public static ProjectionManager Instance
- {
- get
- {
- return instance;
- }
- }
- public Camera projectionCamera;
- RenderTexture renderTexture;
- /// <summary>
- /// 0是不做任何操作,1是开始,2是正在执行投录屏,-1是被停止
- /// </summary>
- int startProjection;
- /// <summary> Renders the event delegate described by eventID. </summary>
- /// <param name="eventID"> Identifier for the event.</param>
- private delegate void RenderEventDelegate(int eventID);
- /// <summary> Handle of the render thread. </summary>
- private static RenderEventDelegate RenderThreadHandle = new RenderEventDelegate(RunOnRenderThread);
- /// <summary> The render thread handle pointer. </summary>
- private static IntPtr RenderThreadHandlePtr = Marshal.GetFunctionPointerForDelegate(RenderThreadHandle);
- /// <summary>
- /// 测试用,保存一张渲染的图
- /// </summary>
- bool justSaveOnePic;
- private GameObject cameraRigObj;
- private void Awake()
- {
- instance = this;
- ProjectionAPI.Init(OnStart, OnStop);
- NativeLib.CallBack_OnProjectionDetected += OnProjectionDetected;
- NativeLib.Resume();
- projectionCamera.GetComponent<PhonePoseTrackerRGB>().enabled = false;
- }
- // Start is called before the first frame update
- void Start()
- {
- Debug.Log("ProjectionManager ==> Init Start");
- StartCoroutine(Init());
- DontDestroyOnLoad(this.gameObject);
- }
- IEnumerator Init()
- {
- yield return new WaitForEndOfFrame();
- yield return new WaitForEndOfFrame();
- yield return new WaitForEndOfFrame();
- Debug.Log("ProjectionManager ==> Init 0");
- while (!NativeTracking.GetIsARSessionInited())
- {
- yield return new WaitForEndOfFrame();
- }
- Debug.Log("ProjectionManager ==> Init 1");
- CameraResolution cameraResolution = new CameraResolution();
- #if UNITY_EDITOR
- cameraResolution.width = 1280;
- cameraResolution.height = 960;
- StartCoroutine(WaitEndOfFrame());
- #else
- Debug.Log("ProjectionManager ==> Init 2");
- NormalRGBCameraDevice rgbCameraDevice = new NormalRGBCameraDevice();
- int[] sizeRgbCamera = rgbCameraDevice.getCameraSize();
- cameraResolution.width = sizeRgbCamera[0];
- cameraResolution.height = sizeRgbCamera[1];
- #endif
- Debug.Log("ProjectionManager ==> Init 3");
- renderTexture = new RenderTexture(cameraResolution.width, cameraResolution.height, 24, RenderTextureFormat.DefaultHDR);
- projectionCamera.targetTexture = renderTexture;
- Debug.Log("ProjectionManager ==> Init renderTexture size: " + renderTexture.width + "," + renderTexture.height + "; GetNativeTexturePtr: " + renderTexture.GetNativeTexturePtr().ToInt32());
- }
- // Update is called once per frame
- void Update()
- {
- //if (Input.GetKeyDown(KeyCode.Escape))
- //{
- // Debug.Log("ProjectionManager ==> justSaveOnePic: true");
- // justSaveOnePic = true;
- //}
- if (NativeTracking.GetIsARSessionInited())
- {
- if (startProjection == 1)
- {
- if (renderTexture != null)
- {
- startProjection = 2;
- Debug.Log("ProjectionManager ==> Start: " + renderTexture.GetNativeTexturePtr().ToInt32());
- projectionCamera.enabled = true;
- projectionCamera.GetComponent<PhonePoseTrackerRGB>().enabled = true;
- ProjectionAPI.Start(renderTexture.GetNativeTexturePtr().ToInt32(), 1280, 960);
- StartCoroutine(WaitEndOfFrame());
- }
- }
- else if (startProjection == -1)
- {
- StopProjection();
- }
- }
- if (cameraRigObj == null) {
- cameraRigObj = HMDPoseTracker.Instance.gameObject;
- }
-
- if (cameraRigObj != null && cameraRigObj.transform.parent != null)
- {
- Transform bodyRig = cameraRigObj.transform.parent;
-
- if (cameraRigObj.transform.parent != null && bodyRig.name != "XRMan")
- {
- this.transform.position = bodyRig.position;
- this.transform.rotation = bodyRig.rotation;
- }
- }
- else
- {
- this.transform.position = Vector3.zero;
- this.transform.rotation = Quaternion.identity;
- }
- }
- void StopProjection()
- {
- Debug.Log("ProjectionManager ==> StopProjection");
- projectionCamera.enabled = false;
- projectionCamera.GetComponent<PhonePoseTrackerRGB>().enabled = false;
- startProjection = 0;
- StopAllCoroutines();
- }
- private void OnDestroy()
- {
- Debug.Log("ProjectionManager ==> OnDestroy startProjection=" + startProjection);
- ProjectionAPI.DeInit();
- }
- private void OnApplicationPause(bool pause)
- {
- if (pause)
- {
- Debug.Log("ProjectionManager OnApplicationPause 0");
- if (startProjection == 2)
- {
- Debug.Log("ProjectionManager OnApplicationPause 1");
- StopProjection();
- Debug.Log("ProjectionManager OnApplicationPause 2");
- NativeLib.Pause();
- ProjectionAPI.Stop();
- }
- }
- else
- {
- Debug.Log("ProjectionManager OnApplicationPause 3");
- NativeLib.Resume();
- Debug.Log("ProjectionManager OnApplicationPause 4");
- }
- }
- /// <summary>
- /// 开始投屏或录屏
- /// </summary>
- /// <param name="type">0投屏 1录屏 2截屏</param>
- void OnStart(int type)
- {
- Debug.Log("ProjectionManager ==> OnStart: " + type);
- startProjection = 1;
- }
- /// <summary>
- /// 投屏或录屏结束了(是一个被动通知,应用收到后只需要处理好自身停止录屏的逻辑不需要调用stop接口。整个投录屏功能结束才会回调此处,应用退出或者到后台都不会回调这里)
- /// </summary>
- void OnStop()
- {
- Debug.Log("ProjectionManager ==> OnStop");
- startProjection = -1;
- }
- void OnProjectionDetected()
- {
- Debug.Log("ProjectionManager ==> OnProjectionDetected");
- startProjection = 1;
- }
- IEnumerator WaitEndOfFrame()
- {
- //camera刚开启的当前帧是不渲染的
- yield return new WaitForEndOfFrame();
- while (true)
- {
- yield return new WaitForEndOfFrame();
- if (justSaveOnePic)
- {
- Debug.Log("ProjectionManager ==> SaveRenderTexture");
- justSaveOnePic = false;
- SaveRenderTexture();
- }
- #if !UNITY_EDITOR
- GL.IssuePluginEvent(RenderThreadHandlePtr, 0);
- #endif
- }
- }
- void SaveRenderTexture()
- {
- Debug.Log("ProjectionManager ==> SaveRenderTexture 0");
- RenderTexture.active = renderTexture;
- Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
- texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
- texture.Apply();
- Debug.Log("ProjectionManager ==> SaveRenderTexture 1");
- byte[] bytes = texture.EncodeToPNG();
- Debug.Log("ProjectionManager ==> SaveRenderTexture size: " + bytes.Length);
- string path = Path.Combine(Application.persistentDataPath, "saved.png");
- Debug.Log("ProjectionManager ==> SaveRenderTexture path: " + path);
- File.WriteAllBytes(path, bytes);
- Debug.Log("ProjectionManager ==> SaveRenderTexture 2");
- }
- /// <summary> Executes the 'on render thread' operation. </summary>
- /// <param name="eventID"> Identifier for the event.</param>
- [MonoPInvokeCallback(typeof(RenderEventDelegate))]
- private static void RunOnRenderThread(int eventID)
- {
- long timeStamp = (long)(ARFrame.HeadPoseRgbTimestamp * 1e9);
- //Debug.Log("ProjectionManager ==> RunOnRenderThread HeadPoseRgbTimestamp: " + timeStamp);
- ProjectionAPI.NotifyNewFrame(timeStamp);
- }
- }
- }
|