diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NRCamTextureToMatHelperExample/NRCamTextureToMatHelperExample.unity b/Assets/NrealLightWithOpenCVForUnityExample/NRCamTextureToMatHelperExample/NRCamTextureToMatHelperExample.unity index cfb1dd2..f687a50 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NRCamTextureToMatHelperExample/NRCamTextureToMatHelperExample.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NRCamTextureToMatHelperExample/NRCamTextureToMatHelperExample.unity @@ -666,6 +666,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 114491031132128258, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} + propertyPath: m_PresetInfoIsWorld + value: 1 + objectReference: {fileID: 0} - target: {fileID: 224453369079705500, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} propertyPath: m_Pivot.x value: 0.5 @@ -2976,7 +2980,6 @@ MonoBehaviour: flipHorizontalToggle: {fileID: 1530880838} applyComicFilter: 0 applyComicFilterToggle: {fileID: 446566292} - mainCamera: {fileID: 2088836769} --- !u!114 &1709852089 MonoBehaviour: m_ObjectHideFlags: 0 @@ -3410,8 +3413,3 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 665d8158924bd2648a94fb3f87691bbb, type: 3} ---- !u!20 &2088836769 stripped -Camera: - m_CorrespondingSourceObject: {fileID: 20880588574554076, guid: 665d8158924bd2648a94fb3f87691bbb, type: 3} - m_PrefabInstance: {fileID: 2088836768} - m_PrefabAsset: {fileID: 0} diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealDnnObjectDetectionExample.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealDnnObjectDetectionExample.cs deleted file mode 100644 index 1460d95..0000000 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealDnnObjectDetectionExample.cs +++ /dev/null @@ -1,822 +0,0 @@ -#if !(PLATFORM_LUMIN && !UNITY_EDITOR) - -#if !UNITY_WSA_10_0 - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.SceneManagement; -using OpenCVForUnity.CoreModule; -using OpenCVForUnity.DnnModule; -using OpenCVForUnity.ImgprocModule; -using OpenCVForUnity.UnityUtils; -using OpenCVForUnity.UnityUtils.Helper; -using NrealLightWithOpenCVForUnity.UnityUtils.Helper; -using NRKernal; - -namespace NrealLightWithOpenCVForUnityExample -{ - /// - /// Nreal Dnn ObjectDetection Example - /// Referring to https://github.com/opencv/opencv/blob/master/samples/dnn/object_detection.cpp. - /// - [RequireComponent(typeof(NRCamTextureToMatHelper))] - public class NrealDnnObjectDetectionExample : MonoBehaviour - { - - [HeaderAttribute("DNN")] - - [TooltipAttribute("Path to a binary file of model contains trained weights. It could be a file with extensions .caffemodel (Caffe), .pb (TensorFlow), .t7 or .net (Torch), .weights (Darknet).")] - public string model; - - [TooltipAttribute("Path to a text file of model contains network configuration. It could be a file with extensions .prototxt (Caffe), .pbtxt (TensorFlow), .cfg (Darknet).")] - public string config; - - [TooltipAttribute("Optional path to a text file with names of classes to label detected objects.")] - public string classes; - - [TooltipAttribute("Optional list of classes to label detected objects.")] - public List classesList; - - [TooltipAttribute("Confidence threshold.")] - public float confThreshold = 0.5f; - - [TooltipAttribute("Non-maximum suppression threshold.")] - public float nmsThreshold = 0.4f; - - [TooltipAttribute("Preprocess input image by multiplying on a scale factor.")] - public float scale = 1.0f; - - [TooltipAttribute("Preprocess input image by subtracting mean values. Mean values should be in BGR order and delimited by spaces.")] - public Scalar mean = new Scalar(0, 0, 0, 0); - - [TooltipAttribute("Indicate that model works with RGB input images instead BGR ones.")] - public bool swapRB = false; - - [TooltipAttribute("Preprocess input image by resizing to a specific width.")] - public int inpWidth = 320; - - [TooltipAttribute("Preprocess input image by resizing to a specific height.")] - public int inpHeight = 320; - - - /// - /// The texture. - /// - protected Texture2D texture; - - /// - /// The webcam texture to mat helper. - /// - protected NRCamTextureToMatHelper webCamTextureToMatHelper; - - /// - /// The image optimization helper. - /// - ImageOptimizationHelper imageOptimizationHelper; - - /// - /// The bgr mat. - /// - protected Mat bgrMat; - - /// - /// The net. - /// - protected Net net; - - protected List classNames; - protected List outBlobNames; - protected List outBlobTypes; - - protected string classes_filepath; - protected string config_filepath; - protected string model_filepath; - -#if UNITY_WEBGL - protected IEnumerator getFilePath_Coroutine; -#endif - - - [HeaderAttribute("UI")] - - /// - /// Determines if frame skip. - /// - public bool enableFrameSkip; - - /// - /// The enable frame skip toggle. - /// - public Toggle enableFrameSkipToggle; - - /// - /// Determines if displays camera image. - /// - public bool displayCameraImage = false; - - /// - /// The display camera image toggle. - /// - public Toggle displayCameraImageToggle; - - /// - /// the main camera. - /// - Camera mainCamera; - - /// - /// The quad renderer. - /// - Renderer quad_renderer; - - - // Use this for initialization - protected virtual void Start() - { - enableFrameSkipToggle.isOn = enableFrameSkip; - displayCameraImageToggle.isOn = displayCameraImage; - - imageOptimizationHelper = gameObject.GetComponent(); - webCamTextureToMatHelper = gameObject.GetComponent(); - - -#if UNITY_WEBGL - getFilePath_Coroutine = GetFilePath(); - StartCoroutine(getFilePath_Coroutine); -#else - if (!string.IsNullOrEmpty(classes)) - { - classes_filepath = Utils.getFilePath("OpenCVForUnity/dnn/" + classes); - if (string.IsNullOrEmpty(classes_filepath)) Debug.Log("The file:" + classes + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); - } - if (!string.IsNullOrEmpty(config)) - { - config_filepath = Utils.getFilePath("OpenCVForUnity/dnn/" + config); - if (string.IsNullOrEmpty(config_filepath)) Debug.Log("The file:" + config + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); - } - if (!string.IsNullOrEmpty(model)) - { - model_filepath = Utils.getFilePath("OpenCVForUnity/dnn/" + model); - if (string.IsNullOrEmpty(model_filepath)) Debug.Log("The file:" + model + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); - } - Run(); -#endif - } - -#if UNITY_WEBGL - protected virtual IEnumerator GetFilePath() - { - if (!string.IsNullOrEmpty(classes)) - { - var getFilePathAsync_0_Coroutine = Utils.getFilePathAsync("OpenCVForUnity/dnn/" + classes, (result) => - { - classes_filepath = result; - }); - yield return getFilePathAsync_0_Coroutine; - - if (string.IsNullOrEmpty(classes_filepath)) Debug.Log("The file:" + classes + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); - } - - if (!string.IsNullOrEmpty(config)) - { - var getFilePathAsync_1_Coroutine = Utils.getFilePathAsync("OpenCVForUnity/dnn/" + config, (result) => - { - config_filepath = result; - }); - yield return getFilePathAsync_1_Coroutine; - - if (string.IsNullOrEmpty(config_filepath)) Debug.Log("The file:" + config + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); - } - - if (!string.IsNullOrEmpty(model)) - { - var getFilePathAsync_2_Coroutine = Utils.getFilePathAsync("OpenCVForUnity/dnn/" + model, (result) => - { - model_filepath = result; - }); - yield return getFilePathAsync_2_Coroutine; - - if (string.IsNullOrEmpty(model_filepath)) Debug.Log("The file:" + model + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); - } - - getFilePath_Coroutine = null; - - Run(); - } -#endif - - // Use this for initialization - protected virtual void Run() - { - //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console. - Utils.setDebugMode(true); - - if (!string.IsNullOrEmpty(classes)) - { - classNames = readClassNames(classes_filepath); - if (classNames == null) - { - Debug.LogError(classes + " is not loaded. Please see “Assets/StreamingAssets/OpenCVForUnity/dnn/setup_dnn_module.pdf”. "); - } - } - else if (classesList.Count > 0) - { - classNames = classesList; - } - - if (string.IsNullOrEmpty(model_filepath)) - { - Debug.LogError(model + " is not loaded. Please see “Assets/StreamingAssets/OpenCVForUnity/dnn/setup_dnn_module.pdf”. "); - } - else - { - //! [Initialize network] - net = Dnn.readNet(model_filepath, config_filepath); - //! [Initialize network] - - outBlobNames = getOutputsNames(net); - //for (int i = 0; i < outBlobNames.Count; i++) - //{ - // Debug.Log("names [" + i + "] " + outBlobNames[i]); - //} - - outBlobTypes = getOutputsTypes(net); - //for (int i = 0; i < outBlobTypes.Count; i++) - //{ - // Debug.Log("types [" + i + "] " + outBlobTypes[i]); - //} - } - - webCamTextureToMatHelper.outputColorFormat = WebCamTextureToMatHelper.ColorFormat.RGB; - webCamTextureToMatHelper.Initialize(); - } - - /// - /// Raises the webcam texture to mat helper initialized event. - /// - public virtual void OnWebCamTextureToMatHelperInitialized() - { - Debug.Log("OnWebCamTextureToMatHelperInitialized"); - - Mat webCamTextureMat = webCamTextureToMatHelper.GetMat(); - - - texture = new Texture2D(webCamTextureMat.cols(), webCamTextureMat.rows(), TextureFormat.RGB24, false); - - gameObject.GetComponent().material.mainTexture = texture; - - quad_renderer = gameObject.GetComponent() as Renderer; - quad_renderer.sharedMaterial.SetTexture("_MainTex", texture); - quad_renderer.sharedMaterial.SetVector("_VignetteOffset", new Vector4(0, 0)); - quad_renderer.sharedMaterial.SetFloat("_VignetteScale", 0.0f); - -#if !UNITY_EDITOR - quad_renderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", webCamTextureToMatHelper.GetProjectionMatrix()); -#else - mainCamera = NRSessionManager.Instance.NRHMDPoseTracker.centerCamera; - quad_renderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", mainCamera.projectionMatrix); -#endif - - bgrMat = new Mat(webCamTextureMat.rows(), webCamTextureMat.cols(), CvType.CV_8UC3); - } - - /// - /// Raises the webcam texture to mat helper disposed event. - /// - public virtual void OnWebCamTextureToMatHelperDisposed() - { - Debug.Log("OnWebCamTextureToMatHelperDisposed"); - - if (bgrMat != null) - bgrMat.Dispose(); - - if (texture != null) - { - Texture2D.Destroy(texture); - texture = null; - } - } - - /// - /// Raises the webcam texture to mat helper error occurred event. - /// - /// Error code. - public virtual void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode) - { - Debug.Log("OnWebCamTextureToMatHelperErrorOccurred " + errorCode); - } - - // Update is called once per frame - protected virtual void Update() - { - if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame()) - { - - if (enableFrameSkip && imageOptimizationHelper.IsCurrentFrameSkipped()) - return; - - - Mat rgbMat = webCamTextureToMatHelper.GetMat(); - - if (net == null) - { - Imgproc.putText(rgbMat, "model file is not loaded.", new Point(5, rgbMat.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); - Imgproc.putText(rgbMat, "Please read console message.", new Point(5, rgbMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); - } - else - { - - Imgproc.cvtColor(rgbMat, bgrMat, Imgproc.COLOR_RGB2BGR); - - // Create a 4D blob from a frame. - Size inpSize = new Size(inpWidth > 0 ? inpWidth : bgrMat.cols(), - inpHeight > 0 ? inpHeight : bgrMat.rows()); - Mat blob = Dnn.blobFromImage(bgrMat, scale, inpSize, mean, swapRB, false); - - - // Run a model. - net.setInput(blob); - - if (net.getLayer(0).outputNameToIndex("im_info") != -1) - { // Faster-RCNN or R-FCN - Imgproc.resize(bgrMat, bgrMat, inpSize); - Mat imInfo = new Mat(1, 3, CvType.CV_32FC1); - imInfo.put(0, 0, new float[] { - (float)inpSize.height, - (float)inpSize.width, - 1.6f - }); - net.setInput(imInfo, "im_info"); - } - - //TickMeter tm = new TickMeter(); - //tm.start(); - - List outs = new List(); - net.forward(outs, outBlobNames); - - //tm.stop(); - //Debug.Log("Inference time, ms: " + tm.getTimeMilli()); - - postprocess(rgbMat, outs, net, Dnn.DNN_BACKEND_OPENCV); - - for (int i = 0; i < outs.Count; i++) - { - outs[i].Dispose(); - } - blob.Dispose(); - } - - Utils.matToTexture2D(rgbMat, texture); - } - - if (webCamTextureToMatHelper.IsPlaying()) - { -#if UNITY_ANDROID && !UNITY_EDITOR - Matrix4x4 cameraToWorldMatrix = webCamTextureToMatHelper.GetCameraToWorldMatrix(); -#else - Matrix4x4 cameraToWorldMatrix = mainCamera.cameraToWorldMatrix; -#endif - - Matrix4x4 worldToCameraMatrix = cameraToWorldMatrix.inverse; - - quad_renderer.sharedMaterial.SetMatrix("_WorldToCameraMatrix", worldToCameraMatrix); - - /* - // Position the canvas object slightly in front - // of the real world web camera. - Vector3 position = cameraToWorldMatrix.GetColumn(3) - cameraToWorldMatrix.GetColumn(2); - position *= 1.5f; - - // Rotate the canvas object so that it faces the user. - Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1)); - - gameObject.transform.position = position; - gameObject.transform.rotation = rotation; - */ - - // - // Adjusting the position and scale of the display screen - // to counteract the phenomenon of texture margins (transparent areas in MR space) being displayed as black when recording video using NRVideoCapture. - // - // Position the canvas object slightly in front - // of the real world web camera. - float overlayDistance = 1.5f; - Vector3 ccCameraSpacePos = UnProjectVector(webCamTextureToMatHelper.GetProjectionMatrix(), new Vector3(0.0f, 0.0f, overlayDistance)); - Vector3 tlCameraSpacePos = UnProjectVector(webCamTextureToMatHelper.GetProjectionMatrix(), new Vector3(-overlayDistance, overlayDistance, overlayDistance)); - - //position - Vector3 position = cameraToWorldMatrix.MultiplyPoint3x4(ccCameraSpacePos); - gameObject.transform.position = position; - - //scale - Vector3 scale = new Vector3(Mathf.Abs(tlCameraSpacePos.x - ccCameraSpacePos.x) * 2, Mathf.Abs(tlCameraSpacePos.y - ccCameraSpacePos.y) * 2, 1); - gameObject.transform.localScale = scale; - - // Rotate the canvas object so that it faces the user. - Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1)); - gameObject.transform.rotation = rotation; - // - } - } - - // - private Vector3 UnProjectVector(Matrix4x4 proj, Vector3 to) - { - Vector3 from = new Vector3(0, 0, 0); - var axsX = proj.GetRow(0); - var axsY = proj.GetRow(1); - var axsZ = proj.GetRow(2); - from.z = to.z / axsZ.z; - from.y = (to.y - (from.z * axsY.z)) / axsY.y; - from.x = (to.x - (from.z * axsX.z)) / axsX.x; - return from; - } - // - - /// - /// Raises the destroy event. - /// - protected virtual void OnDestroy() - { - webCamTextureToMatHelper.Dispose(); - imageOptimizationHelper.Dispose(); - - if (net != null) - net.Dispose(); - - Utils.setDebugMode(false); - -#if UNITY_WEBGL - if (getFilePath_Coroutine != null) - { - StopCoroutine(getFilePath_Coroutine); - ((IDisposable)getFilePath_Coroutine).Dispose(); - } -#endif - } - - /// - /// Raises the back button click event. - /// - public virtual void OnBackButtonClick() - { - SceneManager.LoadScene("NrealLightWithOpenCVForUnityExample"); - } - - /// - /// Raises the play button click event. - /// - public virtual void OnPlayButtonClick() - { - webCamTextureToMatHelper.Play(); - } - - /// - /// Raises the pause button click event. - /// - public virtual void OnPauseButtonClick() - { - webCamTextureToMatHelper.Pause(); - } - - /// - /// Raises the stop button click event. - /// - public virtual void OnStopButtonClick() - { - webCamTextureToMatHelper.Stop(); - } - - /// - /// Raises the change camera button click event. - /// - public virtual void OnChangeCameraButtonClick() - { - webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.requestedIsFrontFacing; - } - - /// - /// Raises the enable frame skip toggle value changed event. - /// - public void OnEnableFrameSkipToggleValueChanged() - { - enableFrameSkip = enableFrameSkipToggle.isOn; - } - - /// - /// Raises the display camera image toggle value changed event. - /// - public void OnDisplayCameraImageToggleValueChanged() - { - displayCameraImage = displayCameraImageToggle.isOn; - } - - /// - /// Reads the class names. - /// - /// The class names. - /// Filename. - protected virtual List readClassNames(string filename) - { - List classNames = new List(); - - System.IO.StreamReader cReader = null; - try - { - cReader = new System.IO.StreamReader(filename, System.Text.Encoding.Default); - - while (cReader.Peek() >= 0) - { - string name = cReader.ReadLine(); - classNames.Add(name); - } - } - catch (System.Exception ex) - { - Debug.LogError(ex.Message); - return null; - } - finally - { - if (cReader != null) - cReader.Close(); - } - - return classNames; - } - - /// - /// Postprocess the specified frame, outs and net. - /// - /// Frame. - /// Outs. - /// Net. - /// Backend. - protected virtual void postprocess(Mat frame, List outs, Net net, int backend = Dnn.DNN_BACKEND_OPENCV) - { - MatOfInt outLayers = net.getUnconnectedOutLayers(); - string outLayerType = outBlobTypes[0]; - - List classIdsList = new List(); - List confidencesList = new List(); - List boxesList = new List(); - - if (net.getLayer(0).outputNameToIndex("im_info") != -1) - { - // Faster-RCNN or R-FCN - // Network produces output blob with a shape 1x1xNx7 where N is a number of - // detections and an every detection is a vector of values - // [batchId, classId, confidence, left, top, right, bottom] - - if (outs.Count == 1) - { - outs[0] = outs[0].reshape(1, (int)outs[0].total() / 7); - - //Debug.Log ("outs[i].ToString() " + outs [0].ToString ()); - - float[] data = new float[7]; - - for (int i = 0; i < outs[0].rows(); i++) - { - outs[0].get(i, 0, data); - - float confidence = data[2]; - if (confidence > confThreshold) - { - int class_id = (int)(data[1]); - - float left = data[3] * frame.cols(); - float top = data[4] * frame.rows(); - float right = data[5] * frame.cols(); - float bottom = data[6] * frame.rows(); - float width = right - left + 1f; - float height = bottom - top + 1f; - - classIdsList.Add((int)(class_id) - 1); // Skip 0th background class id. - confidencesList.Add((float)confidence); - boxesList.Add(new Rect2d(left, top, width, height)); - } - } - } - } - else if (outLayerType == "DetectionOutput") - { - // Network produces output blob with a shape 1x1xNx7 where N is a number of - // detections and an every detection is a vector of values - // [batchId, classId, confidence, left, top, right, bottom] - - if (outs.Count == 1) - { - outs[0] = outs[0].reshape(1, (int)outs[0].total() / 7); - - //Debug.Log ("outs[i].ToString() " + outs [0].ToString ()); - - float[] data = new float[7]; - for (int i = 0; i < outs[0].rows(); i++) - { - outs[0].get(i, 0, data); - - float confidence = data[2]; - if (confidence > confThreshold) - { - int class_id = (int)(data[1]); - - float left = data[3] * frame.cols(); - float top = data[4] * frame.rows(); - float right = data[5] * frame.cols(); - float bottom = data[6] * frame.rows(); - float width = right - left + 1f; - float height = bottom - top + 1f; - - classIdsList.Add((int)(class_id) - 1); // Skip 0th background class id. - confidencesList.Add((float)confidence); - boxesList.Add(new Rect2d(left, top, width, height)); - } - } - } - } - else if (outLayerType == "Region") - { - for (int i = 0; i < outs.Count; ++i) - { - // Network produces output blob with a shape NxC where N is a number of - // detected objects and C is a number of classes + 4 where the first 4 - // numbers are [center_x, center_y, width, height] - - //Debug.Log ("outs[i].ToString() "+outs[i].ToString()); - - float[] positionData = new float[5]; - float[] confidenceData = new float[outs[i].cols() - 5]; - for (int p = 0; p < outs[i].rows(); p++) - { - outs[i].get(p, 0, positionData); - outs[i].get(p, 5, confidenceData); - - int maxIdx = confidenceData.Select((val, idx) => new { V = val, I = idx }).Aggregate((max, working) => (max.V > working.V) ? max : working).I; - float confidence = confidenceData[maxIdx]; - if (confidence > confThreshold) - { - float centerX = positionData[0] * frame.cols(); - float centerY = positionData[1] * frame.rows(); - float width = positionData[2] * frame.cols(); - float height = positionData[3] * frame.rows(); - float left = centerX - width / 2; - float top = centerY - height / 2; - - classIdsList.Add(maxIdx); - confidencesList.Add((float)confidence); - boxesList.Add(new Rect2d(left, top, width, height)); - } - } - } - } - else - { - Debug.Log("Unknown output layer type: " + outLayerType); - } - - // NMS is used inside Region layer only on DNN_BACKEND_OPENCV for another backends we need NMS in sample - // or NMS is required if number of outputs > 1 - if (outLayers.total() > 1 || (outLayerType == "Region" && backend != Dnn.DNN_BACKEND_OPENCV)) - { - Dictionary> class2indices = new Dictionary>(); - for (int i = 0; i < classIdsList.Count; i++) - { - if (confidencesList[i] >= confThreshold) - { - if (!class2indices.ContainsKey(classIdsList[i])) - class2indices.Add(classIdsList[i], new List()); - - class2indices[classIdsList[i]].Add(i); - } - } - - List nmsBoxesList = new List(); - List nmsConfidencesList = new List(); - List nmsClassIdsList = new List(); - foreach (int key in class2indices.Keys) - { - List localBoxesList = new List(); - List localConfidencesList = new List(); - List classIndicesList = class2indices[key]; - for (int i = 0; i < classIndicesList.Count; i++) - { - localBoxesList.Add(boxesList[classIndicesList[i]]); - localConfidencesList.Add(confidencesList[classIndicesList[i]]); - } - - using (MatOfRect2d localBoxes = new MatOfRect2d(localBoxesList.ToArray())) - using (MatOfFloat localConfidences = new MatOfFloat(localConfidencesList.ToArray())) - using (MatOfInt nmsIndices = new MatOfInt()) - { - Dnn.NMSBoxes(localBoxes, localConfidences, confThreshold, nmsThreshold, nmsIndices); - for (int i = 0; i < nmsIndices.total(); i++) - { - int idx = (int)nmsIndices.get(i, 0)[0]; - nmsBoxesList.Add(localBoxesList[idx]); - nmsConfidencesList.Add(localConfidencesList[idx]); - nmsClassIdsList.Add(key); - } - } - } - - boxesList = nmsBoxesList; - classIdsList = nmsClassIdsList; - confidencesList = nmsConfidencesList; - } - - if (!displayCameraImage) - { - // fill all black. - Imgproc.rectangle(frame, new Point(0, 0), new Point(frame.width(), frame.height()), new Scalar(0, 0, 0, 0), -1); - } - - for (int idx = 0; idx < boxesList.Count; ++idx) - { - Rect2d box = boxesList[idx]; - drawPred(classIdsList[idx], confidencesList[idx], box.x, box.y, - box.x + box.width, box.y + box.height, frame); - } - } - - /// - /// Draws the pred. - /// - /// Class identifier. - /// Conf. - /// Left. - /// Top. - /// Right. - /// Bottom. - /// Frame. - protected virtual void drawPred(int classId, float conf, double left, double top, double right, double bottom, Mat frame) - { - Imgproc.rectangle(frame, new Point(left, top), new Point(right, bottom), new Scalar(0, 255, 0, 255), 2); - - string label = conf.ToString(); - if (classNames != null && classNames.Count != 0) - { - if (classId < (int)classNames.Count) - { - label = classNames[classId] + ": " + label; - } - } - - int[] baseLine = new int[1]; - Size labelSize = Imgproc.getTextSize(label, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine); - - top = Mathf.Max((float)top, (float)labelSize.height); - Imgproc.rectangle(frame, new Point(left, top - labelSize.height), - new Point(left + labelSize.width, top + baseLine[0]), Scalar.all(255), Core.FILLED); - Imgproc.putText(frame, label, new Point(left, top), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0, 255)); - } - - /// - /// Gets the outputs names. - /// - /// The outputs names. - /// Net. - protected virtual List getOutputsNames(Net net) - { - List names = new List(); - - - MatOfInt outLayers = net.getUnconnectedOutLayers(); - for (int i = 0; i < outLayers.total(); ++i) - { - names.Add(net.getLayer((int)outLayers.get(i, 0)[0]).get_name()); - } - outLayers.Dispose(); - - return names; - } - - /// - /// Gets the outputs types. - /// - /// The outputs types. - /// Net. - protected virtual List getOutputsTypes(Net net) - { - List types = new List(); - - - MatOfInt outLayers = net.getUnconnectedOutLayers(); - for (int i = 0; i < outLayers.total(); ++i) - { - types.Add(net.getLayer((int)outLayers.get(i, 0)[0]).get_type()); - } - outLayers.Dispose(); - - return types; - } - } -} -#endif - -#endif \ No newline at end of file diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.cs index d22e7df..8ebd738 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.cs +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.cs @@ -20,7 +20,7 @@ namespace NrealLightWithOpenCVForUnityExample /// /// Nreal Face Detection Example /// An example of detecting face using OpenCVForUnity on Nreal Light. - /// Referring to https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/detection_based_tracker.cpp. + /// Referring to https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/detection_based_tracker.cpp /// [RequireComponent(typeof(NRCamTextureToMatHelper), typeof(ImageOptimizationHelper))] public class NrealFaceDetectionExample : MonoBehaviour diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.unity b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.unity index 419c817..5a58085 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectionExample/NrealFaceDetectionExample.unity @@ -697,6 +697,10 @@ PrefabInstance: propertyPath: m_Name value: FPSCanvas objectReference: {fileID: 0} + - target: {fileID: 114491031132128258, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} + propertyPath: m_PresetInfoIsWorld + value: 1 + objectReference: {fileID: 0} - target: {fileID: 224453369079705500, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} propertyPath: m_Pivot.x value: 0.5 diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample.meta similarity index 77% rename from Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample.meta rename to Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample.meta index 8e8cc0b..f973b9a 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample.meta +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ee679646a28106045a273ff651b85ef0 +guid: 00a168fdf8f704a42b811505e35019c8 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.cs new file mode 100644 index 0000000..7e77de8 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.cs @@ -0,0 +1,523 @@ +#if !(PLATFORM_LUMIN && !UNITY_EDITOR) + +#if !UNITY_WSA_10_0 + +using NrealLightWithOpenCVForUnity.UnityUtils.Helper; +using NRKernal; +using OpenCVForUnity.CoreModule; +using OpenCVForUnity.ImgprocModule; +using OpenCVForUnity.ObjdetectModule; +using OpenCVForUnity.UnityUtils; +using OpenCVForUnity.UnityUtils.Helper; +using System.Runtime.InteropServices; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +namespace NrealLightWithOpenCVForUnityExample +{ + /// + /// Nreal FaceDetectorYN Example + /// An example of detecting human face in Nreal Light RGB camera using the FaceDetectorYN class. + /// Referring to https://github.com/opencv/opencv/blob/master/samples/dnn/face_detect.cpp + /// https://docs.opencv.org/4.5.4/d0/dd4/tutorial_dnn_face.html + /// + [RequireComponent(typeof(NRCamTextureToMatHelper))] + public class NrealFaceDetectorYNExample : MonoBehaviour + { + /// + /// The FaceDetectorYN. + /// + FaceDetectorYN faceDetector; + + /// + /// The size for the network input. + /// + int inputSizeW = 320; + int inputSizeH = 320; + + /// + /// Filter out faces of score < score_threshold. + /// + float scoreThreshold = 0.5f; //0.9f; + + /// + /// Suppress bounding boxes of iou >= nms_threshold + /// + float nmsThreshold = 0.3f; + + /// + /// Keep top_k bounding boxes before NMS. + /// + int topK = 5000; + + /// + /// The bgr mat. + /// + Mat bgrMat; + + /// + /// The input mat. + /// + Mat inputMat; + + /// + /// The texture. + /// + Texture2D texture; + + /// + /// The webcam texture to mat helper. + /// + NRCamTextureToMatHelper webCamTextureToMatHelper; + + /// + /// The image optimization helper. + /// + ImageOptimizationHelper imageOptimizationHelper; + + /// + /// MODEL_FILENAME + /// + protected static readonly string MODEL_FILENAME = "OpenCVForUnity/objdetect/face_detection_yunet_2023mar.onnx"; + + protected Scalar bBoxColor = new Scalar(255, 255, 0, 255); + + protected Scalar[] keyPointsColors = new Scalar[] { + new Scalar(0, 0, 255, 255), // # right eye + new Scalar(255, 0, 0, 255), // # left eye + new Scalar(255, 255, 0, 255), // # nose tip + new Scalar(0, 255, 255, 255), // # mouth right + new Scalar(0, 255, 0, 255), // # mouth left + new Scalar(255, 255, 255, 255) }; + + + [HeaderAttribute("UI")] + + /// + /// Determines if frame skip. + /// + public bool enableFrameSkip; + + /// + /// The enable frame skip toggle. + /// + public Toggle enableFrameSkipToggle; + + /// + /// Determines if displays camera image. + /// + public bool displayCameraImage = false; + + /// + /// The display camera image toggle. + /// + public Toggle displayCameraImageToggle; + + /// + /// the main camera. + /// + Camera mainCamera; + + /// + /// The quad renderer. + /// + Renderer quad_renderer; + + + // Use this for initialization + protected virtual void Start() + { + //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console. + Utils.setDebugMode(true); + + + enableFrameSkipToggle.isOn = enableFrameSkip; + displayCameraImageToggle.isOn = displayCameraImage; + + imageOptimizationHelper = gameObject.GetComponent(); + webCamTextureToMatHelper = gameObject.GetComponent(); + + + string fd_modelPath = Utils.getFilePath(MODEL_FILENAME); + if (string.IsNullOrEmpty(fd_modelPath)) + { + Debug.LogError(MODEL_FILENAME + " is not loaded. Please read “StreamingAssets/OpenCVForUnity/objdetect/setup_objdetect_module.pdf” to make the necessary setup."); + } + else + { + faceDetector = FaceDetectorYN.create(fd_modelPath, "", new Size(inputSizeW, inputSizeH), scoreThreshold, nmsThreshold, topK); + } + + webCamTextureToMatHelper.outputColorFormat = WebCamTextureToMatHelper.ColorFormat.RGB; + webCamTextureToMatHelper.Initialize(); + } + + + /// + /// Raises the webcam texture to mat helper initialized event. + /// + public virtual void OnWebCamTextureToMatHelperInitialized() + { + Debug.Log("OnWebCamTextureToMatHelperInitialized"); + + Mat webCamTextureMat = webCamTextureToMatHelper.GetMat(); + + + texture = new Texture2D(webCamTextureMat.cols(), webCamTextureMat.rows(), TextureFormat.RGB24, false); + + gameObject.GetComponent().material.mainTexture = texture; + + quad_renderer = gameObject.GetComponent() as Renderer; + quad_renderer.sharedMaterial.SetTexture("_MainTex", texture); + quad_renderer.sharedMaterial.SetVector("_VignetteOffset", new Vector4(0, 0)); + quad_renderer.sharedMaterial.SetFloat("_VignetteScale", 0.0f); + +#if !UNITY_EDITOR + quad_renderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", webCamTextureToMatHelper.GetProjectionMatrix()); +#else + mainCamera = NRSessionManager.Instance.NRHMDPoseTracker.centerCamera; + quad_renderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", mainCamera.projectionMatrix); +#endif + + bgrMat = new Mat(webCamTextureMat.rows(), webCamTextureMat.cols(), CvType.CV_8UC3); + inputMat = new Mat(new Size(inputSizeW, inputSizeH), CvType.CV_8UC3); + } + + /// + /// Raises the webcam texture to mat helper disposed event. + /// + public virtual void OnWebCamTextureToMatHelperDisposed() + { + Debug.Log("OnWebCamTextureToMatHelperDisposed"); + + if (texture != null) + { + Texture2D.Destroy(texture); + texture = null; + } + + if (bgrMat != null) + bgrMat.Dispose(); + + if (inputMat != null) + inputMat.Dispose(); + } + + /// + /// Raises the webcam texture to mat helper error occurred event. + /// + /// Error code. + public virtual void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode) + { + Debug.Log("OnWebCamTextureToMatHelperErrorOccurred " + errorCode); + } + + // Update is called once per frame + protected virtual void Update() + { + if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame()) + { + + if (enableFrameSkip && imageOptimizationHelper.IsCurrentFrameSkipped()) + return; + + /* + Mat rgbMat = webCamTextureToMatHelper.GetMat(); + + if (net == null) + { + Imgproc.putText(rgbMat, "model file is not loaded.", new Point(5, rgbMat.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + Imgproc.putText(rgbMat, "Please read console message.", new Point(5, rgbMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + } + else + { + Mat blob = Dnn.blobFromImage(rgbMat, 1.0 / 255.0, new Size(192, 192), new Scalar(0.5, 0.5, 0.5), false, false, CvType.CV_32F); + // Divide blob by std. + Core.divide(blob, new Scalar(0.5, 0.5, 0.5), blob); + + net.setInput(blob); + + Mat prob = net.forward("save_infer_model/scale_0.tmp_1"); + + Mat result = new Mat(); + Core.reduceArgMax(prob, result, 1); + + result.convertTo(result, CvType.CV_8U); + + Mat mask192x192 = new Mat(192, 192, CvType.CV_8UC1, (IntPtr)result.dataAddr()); + Imgproc.resize(mask192x192, maskMat, rgbMat.size(), Imgproc.INTER_NEAREST); + + if (!displayCameraImage) + { + // fill all black. + Imgproc.rectangle(rgbMat, new Point(0, 0), new Point(rgbMat.width(), rgbMat.height()), new Scalar(0, 0, 0, 0), -1); + } + + rgbMat.setTo(new Scalar(255, 255, 255, 255), maskMat); + + mask192x192.Dispose(); + result.Dispose(); + + prob.Dispose(); + blob.Dispose(); + } + + Utils.matToTexture2D(rgbMat, texture); + */ + + + Mat rgbMat = webCamTextureToMatHelper.GetMat(); + + if (faceDetector == null) + { + Imgproc.putText(rgbMat, "model file is not loaded.", new Point(5, rgbMat.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + Imgproc.putText(rgbMat, "Please read console message.", new Point(5, rgbMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + + Utils.matToTexture2D(rgbMat, texture); + return; + } + + Imgproc.cvtColor(rgbMat, bgrMat, Imgproc.COLOR_RGB2BGR); + + Detection[] detections = Detect(bgrMat); + + if (!displayCameraImage) + { + // fill all black. + Imgproc.rectangle(rgbMat, new Point(0, 0), new Point(rgbMat.width(), rgbMat.height()), new Scalar(0, 0, 0, 0), -1); + } + + foreach (var d in detections) + { + DrawDetection(d, rgbMat); + } + + Utils.matToTexture2D(rgbMat, texture); + } + + if (webCamTextureToMatHelper.IsPlaying()) + { +#if UNITY_ANDROID && !UNITY_EDITOR + Matrix4x4 cameraToWorldMatrix = webCamTextureToMatHelper.GetCameraToWorldMatrix(); +#else + Matrix4x4 cameraToWorldMatrix = mainCamera.cameraToWorldMatrix; +#endif + + Matrix4x4 worldToCameraMatrix = cameraToWorldMatrix.inverse; + + quad_renderer.sharedMaterial.SetMatrix("_WorldToCameraMatrix", worldToCameraMatrix); + + /* + // Position the canvas object slightly in front + // of the real world web camera. + Vector3 position = cameraToWorldMatrix.GetColumn(3) - cameraToWorldMatrix.GetColumn(2); + position *= 1.5f; + + // Rotate the canvas object so that it faces the user. + Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1)); + + gameObject.transform.position = position; + gameObject.transform.rotation = rotation; + */ + + // + // Adjusting the position and scale of the display screen + // to counteract the phenomenon of texture margins (transparent areas in MR space) being displayed as black when recording video using NRVideoCapture. + // + // Position the canvas object slightly in front + // of the real world web camera. + float overlayDistance = 1.5f; + Vector3 ccCameraSpacePos = UnProjectVector(webCamTextureToMatHelper.GetProjectionMatrix(), new Vector3(0.0f, 0.0f, overlayDistance)); + Vector3 tlCameraSpacePos = UnProjectVector(webCamTextureToMatHelper.GetProjectionMatrix(), new Vector3(-overlayDistance, overlayDistance, overlayDistance)); + + //position + Vector3 position = cameraToWorldMatrix.MultiplyPoint3x4(ccCameraSpacePos); + gameObject.transform.position = position; + + //scale + Vector3 scale = new Vector3(Mathf.Abs(tlCameraSpacePos.x - ccCameraSpacePos.x) * 2, Mathf.Abs(tlCameraSpacePos.y - ccCameraSpacePos.y) * 2, 1); + gameObject.transform.localScale = scale; + + // Rotate the canvas object so that it faces the user. + Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1)); + gameObject.transform.rotation = rotation; + // + } + } + + // + private Vector3 UnProjectVector(Matrix4x4 proj, Vector3 to) + { + Vector3 from = new Vector3(0, 0, 0); + var axsX = proj.GetRow(0); + var axsY = proj.GetRow(1); + var axsZ = proj.GetRow(2); + from.z = to.z / axsZ.z; + from.y = (to.y - (from.z * axsY.z)) / axsY.y; + from.x = (to.x - (from.z * axsX.z)) / axsX.x; + return from; + } + // + + /// + /// Raises the destroy event. + /// + protected virtual void OnDestroy() + { + webCamTextureToMatHelper.Dispose(); + imageOptimizationHelper.Dispose(); + + if (faceDetector != null) + faceDetector.Dispose(); + + Utils.setDebugMode(false); + } + + /// + /// Raises the back button click event. + /// + public virtual void OnBackButtonClick() + { + SceneManager.LoadScene("NrealLightWithOpenCVForUnityExample"); + } + + /// + /// Raises the play button click event. + /// + public virtual void OnPlayButtonClick() + { + webCamTextureToMatHelper.Play(); + } + + /// + /// Raises the pause button click event. + /// + public virtual void OnPauseButtonClick() + { + webCamTextureToMatHelper.Pause(); + } + + /// + /// Raises the stop button click event. + /// + public virtual void OnStopButtonClick() + { + webCamTextureToMatHelper.Stop(); + } + + /// + /// Raises the change camera button click event. + /// + public virtual void OnChangeCameraButtonClick() + { + webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.requestedIsFrontFacing; + } + + /// + /// Raises the enable frame skip toggle value changed event. + /// + public void OnEnableFrameSkipToggleValueChanged() + { + enableFrameSkip = enableFrameSkipToggle.isOn; + } + + /// + /// Raises the display camera image toggle value changed event. + /// + public void OnDisplayCameraImageToggleValueChanged() + { + displayCameraImage = displayCameraImageToggle.isOn; + } + + protected virtual Detection[] Detect(Mat image) + { + Imgproc.resize(image, inputMat, inputMat.size()); + + float scaleRatioX = (float)image.width() / inputMat.width(); + float scaleRatioY = (float)image.height() / inputMat.height(); + + Detection[] detections; + + using (Mat faces = new Mat()) + { + // The detection output faces is a two - dimension array of type CV_32F, whose rows are the detected face instances, columns are the location of a face and 5 facial landmarks. + // The format of each row is as follows: + // x1, y1, w, h, x_re, y_re, x_le, y_le, x_nt, y_nt, x_rcm, y_rcm, x_lcm, y_lcm + // , where x1, y1, w, h are the top - left coordinates, width and height of the face bounding box, { x, y}_{ re, le, nt, rcm, lcm} + // stands for the coordinates of right eye, left eye, nose tip, the right corner and left corner of the mouth respectively. + faceDetector.detect(inputMat, faces); + + detections = new Detection[faces.rows()]; + + for (int i = 0; i < faces.rows(); i++) + { + float[] buf = new float[Detection.Size]; + faces.get(i, 0, buf); + + for (int x = 0; x < 14; x++) + { + if (x % 2 == 0) + { + buf[x] *= scaleRatioX; + } + else + { + buf[x] *= scaleRatioY; + } + } + + GCHandle gch = GCHandle.Alloc(buf, GCHandleType.Pinned); + detections[i] = (Detection)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(Detection)); + gch.Free(); + } + } + + return detections; + } + + protected virtual void DrawDetection(Detection d, Mat frame) + { + Imgproc.rectangle(frame, new Point(d.xy.x, d.xy.y), new Point(d.xy.x + d.wh.x, d.xy.y + d.wh.y), bBoxColor, 2); + Imgproc.circle(frame, new Point(d.rightEye.x, d.rightEye.y), 2, keyPointsColors[0], 2); + Imgproc.circle(frame, new Point(d.leftEye.x, d.leftEye.y), 2, keyPointsColors[1], 2); + Imgproc.circle(frame, new Point(d.nose.x, d.nose.y), 2, keyPointsColors[2], 2); + Imgproc.circle(frame, new Point(d.rightMouth.x, d.rightMouth.y), 2, keyPointsColors[3], 2); + Imgproc.circle(frame, new Point(d.leftMouth.x, d.leftMouth.y), 2, keyPointsColors[4], 2); + + string label = d.score.ToString(); + int[] baseLine = new int[1]; + Size labelSize = Imgproc.getTextSize(label, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine); + + float top = Mathf.Max(d.xy.y, (float)labelSize.height); + float left = d.xy.x; + Imgproc.rectangle(frame, new Point(left, top - labelSize.height), + new Point(left + labelSize.width, top + baseLine[0]), Scalar.all(255), Core.FILLED); + Imgproc.putText(frame, label, new Point(left, top), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0, 255)); + } + + [StructLayout(LayoutKind.Sequential)] + public readonly struct Detection + { + // Bounding box + public readonly Vector2 xy; + public readonly Vector2 wh; + + // Key points + public readonly Vector2 rightEye; + public readonly Vector2 leftEye; + public readonly Vector2 nose; + public readonly Vector2 rightMouth; + public readonly Vector2 leftMouth; + + // Confidence score [0, 1] + public readonly float score; + + // sizeof(Detection) + public const int Size = 15 * sizeof(float); + }; + } +} +#endif + +#endif \ No newline at end of file diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealDnnObjectDetectionExample.cs.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.cs.meta similarity index 69% rename from Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealDnnObjectDetectionExample.cs.meta rename to Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.cs.meta index 3113cc6..f45067e 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealDnnObjectDetectionExample.cs.meta +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 701a3f5d55e57a04a8f7b1a29e1ca8fd -timeCreated: 1533711794 -licenseType: Pro +guid: 9aae69b6930abc946b7d07dbea7ef563 MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealLibFaceDetectionV2Example.unity b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.unity similarity index 99% rename from Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealLibFaceDetectionV2Example.unity rename to Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.unity index 4bf1b4a..4c80780 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealLibFaceDetectionV2Example.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.unity @@ -497,7 +497,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnDisplayCameraImageToggleValueChanged m_Mode: 1 @@ -773,7 +773,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnPlayButtonClick m_Mode: 1 @@ -836,7 +836,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 4275651716754104, guid: 665d8158924bd2648a94fb3f87691bbb, type: 3} propertyPath: m_RootOrder - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 4275651716754104, guid: 665d8158924bd2648a94fb3f87691bbb, type: 3} propertyPath: m_LocalPosition.x @@ -1221,7 +1221,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnChangeCameraButtonClick m_Mode: 1 @@ -1578,7 +1578,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 4808320353365586, guid: ad152f08ed7eb6e4abd93376a0203e38, type: 3} propertyPath: m_RootOrder - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 4808320353365586, guid: ad152f08ed7eb6e4abd93376a0203e38, type: 3} propertyPath: m_LocalPosition.x @@ -1688,7 +1688,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnEnableFrameSkipToggleValueChanged m_Mode: 1 @@ -1847,7 +1847,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnPauseButtonClick m_Mode: 1 @@ -1989,7 +1989,7 @@ GameObject: - component: {fileID: 1709852086} - component: {fileID: 1709852088} m_Layer: 0 - m_Name: NrealLibFaceDetectionV2Example + m_Name: NrealFaceDetectorYNExample m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -2098,7 +2098,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.DnnObjectDetectionWebCamTextureExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnWebCamTextureToMatHelperInitialized m_Mode: 1 @@ -2114,7 +2114,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.DnnObjectDetectionWebCamTextureExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnWebCamTextureToMatHelperDisposed m_Mode: 1 @@ -2130,7 +2130,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.DnnObjectDetectionWebCamTextureExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnWebCamTextureToMatHelperErrorOccurred m_Mode: 0 @@ -2152,26 +2152,10 @@ MonoBehaviour: m_GameObject: {fileID: 1709852081} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 701a3f5d55e57a04a8f7b1a29e1ca8fd, type: 3} + m_Script: {fileID: 11500000, guid: 9aae69b6930abc946b7d07dbea7ef563, type: 3} m_Name: m_EditorClassIdentifier: - model: yufacedetectnet-open-v2.caffemodel - config: yufacedetectnet-open-v2.prototxt - classes: - classesList: [] - confThreshold: 0.5 - nmsThreshold: 0.5 - scale: 1 - mean: - val: - - 0 - - 0 - - 0 - - 0 - swapRB: 0 - inpWidth: 320 - inpHeight: 240 - enableFrameSkip: 1 + enableFrameSkip: 0 enableFrameSkipToggle: {fileID: 1635194723} displayCameraImage: 0 displayCameraImageToggle: {fileID: 262404331} @@ -2294,7 +2278,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnBackButtonClick m_Mode: 1 @@ -2449,7 +2433,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealFaceDetectorYNExample, Assembly-CSharp m_MethodName: OnStopButtonClick m_Mode: 1 diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealLibFaceDetectionV2Example.unity.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.unity.meta similarity index 54% rename from Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealLibFaceDetectionV2Example.unity.meta rename to Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.unity.meta index 11ce672..98f9e62 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealLibFaceDetectionV2Example.unity.meta +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealFaceDetectorYNExample/NrealFaceDetectorYNExample.unity.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: 894b8d80caa984141949702467200ca2 -timeCreated: 1511714312 -licenseType: Pro +guid: 528f392f463840844a55f6dbe0d53e68 DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.cs index 5a3ab88..c9020c4 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.cs +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.cs @@ -21,8 +21,8 @@ namespace NrealLightWithOpenCVForUnityExample { /// /// Nreal Human Segmentation Example - /// An example of using OpenCV dnn module with Human Segmentation model. - /// Referring to https://github.com/opencv/opencv_zoo/tree/master/models/human_segmentation_pphumanseg. + /// An example of using OpenCV dnn module and Human Segmentation model on Nreal Light. + /// Referring to https://github.com/opencv/opencv_zoo/tree/master/models/human_segmentation_pphumanseg /// [RequireComponent(typeof(NRCamTextureToMatHelper))] public class NrealHumanSegmentationExample : MonoBehaviour @@ -56,7 +56,7 @@ public class NrealHumanSegmentationExample : MonoBehaviour /// /// MODEL_FILENAME /// - protected static readonly string MODEL_FILENAME = "OpenCVForUnity/dnn/human_segmentation_pphumanseg_2021oct.onnx"; + protected static readonly string MODEL_FILENAME = "OpenCVForUnity/dnn/human_segmentation_pphumanseg_2023mar.onnx"; /// /// The model filepath. diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.unity b/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.unity index 8ec679b..da86874 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealHumanSegmentationExample/NrealHumanSegmentationExample.unity @@ -288,6 +288,10 @@ PrefabInstance: propertyPath: m_Name value: FPSCanvas objectReference: {fileID: 0} + - target: {fileID: 114491031132128258, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} + propertyPath: m_PresetInfoIsWorld + value: 1 + objectReference: {fileID: 0} - target: {fileID: 224453369079705500, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} propertyPath: m_Pivot.x value: 0.5 diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.cs index b0d7c29..2e281f4 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.cs +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.cs @@ -94,14 +94,14 @@ public void OnNrealArUcoExampleButtonClick() { SceneManager.LoadScene("NrealArUcoExample"); } - public void OnNrealYoloObjectDetectionExampleButtonClick() + public void OnNrealObjectDetectionYOLOv4ExampleButtonClick() { - SceneManager.LoadScene("NrealYoloObjectDetectionExample"); + SceneManager.LoadScene("NrealObjectDetectionYOLOv4Example"); } - public void OnNrealLibFaceDetectionV2ExampleButtonClick() + public void OnNrealFaceDetectorYNExampleButtonClick() { - SceneManager.LoadScene("NrealLibFaceDetectionV2Example"); + SceneManager.LoadScene("NrealFaceDetectorYNExample"); } public void OnNrealHumanSegmentationExampleButtonClick() diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.unity b/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.unity index 5aca1ea..0c287c5 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealLightWithOpenCVForUnityExample.unity @@ -774,7 +774,7 @@ GameObject: - component: {fileID: 760717593} - component: {fileID: 760717592} m_Layer: 5 - m_Name: NrealYoloObjectDetectionExampleButton + m_Name: NrealObjectDetectionYOLOv4ExampleButton m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -867,7 +867,7 @@ MonoBehaviour: - m_Target: {fileID: 2004915444} m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealLightWithOpenCVForUnityExample, Assembly-CSharp - m_MethodName: OnNrealYoloObjectDetectionExampleButtonClick + m_MethodName: OnNrealObjectDetectionYOLOv4ExampleButtonClick m_Mode: 1 m_Arguments: m_ObjectArgument: {fileID: 0} @@ -1685,7 +1685,7 @@ MonoBehaviour: m_HorizontalOverflow: 0 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: Nreal Yolo ObjectDetection Example + m_Text: Nreal ObjectDetection YOLOv4 Example --- !u!222 &1333755879 CanvasRenderer: m_ObjectHideFlags: 0 @@ -1843,7 +1843,7 @@ MonoBehaviour: m_HorizontalOverflow: 0 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: Nreal LibFaceDetectionV2 Example + m_Text: Nreal FaceDetectorYN Example --- !u!222 &1387472477 CanvasRenderer: m_ObjectHideFlags: 0 @@ -2236,7 +2236,7 @@ GameObject: - component: {fileID: 1799018948} - component: {fileID: 1799018947} m_Layer: 5 - m_Name: NrealLibFaceDetectionV2ExampleButton + m_Name: NrealFaceDetectorYNExampleButton m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -2329,7 +2329,7 @@ MonoBehaviour: - m_Target: {fileID: 2004915444} m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealLightWithOpenCVForUnityExample, Assembly-CSharp - m_MethodName: OnNrealLibFaceDetectionV2ExampleButtonClick + m_MethodName: OnNrealFaceDetectorYNExampleButtonClick m_Mode: 1 m_Arguments: m_ObjectArgument: {fileID: 0} diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealYoloObjectDetectionExample.unity.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example.meta similarity index 54% rename from Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealYoloObjectDetectionExample.unity.meta rename to Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example.meta index 9b0a55e..d2c2ccd 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealYoloObjectDetectionExample.unity.meta +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: eaf609bd5bb31004a9b777d52bd497c3 -timeCreated: 1511714312 -licenseType: Pro +guid: cd849a6e224bbe948b75852fa1bb2a57 +folderAsset: yes DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.cs new file mode 100644 index 0000000..2678ef2 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.cs @@ -0,0 +1,726 @@ +#if !(PLATFORM_LUMIN && !UNITY_EDITOR) + +#if !UNITY_WSA_10_0 + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.SceneManagement; +using OpenCVForUnity.CoreModule; +using OpenCVForUnity.DnnModule; +using OpenCVForUnity.ImgprocModule; +using OpenCVForUnity.UnityUtils; +using OpenCVForUnity.UnityUtils.Helper; +using NrealLightWithOpenCVForUnity.UnityUtils.Helper; +using NRKernal; +using System.Text; +using OpenCVRect = OpenCVForUnity.CoreModule.Rect; + +namespace NrealLightWithOpenCVForUnityExample +{ + /// + /// Nreal ObjectDetection YOLOv4 Example + /// An example of detecting objects in Nreal Light RGB camera using OpenCV dnn module. + /// Referring to https://github.com/AlexeyAB/darknet. + /// https://gist.github.com/YashasSamaga/48bdb167303e10f4d07b754888ddbdcf + /// + /// [Tested Models] + /// yolov4-tiny https://github.com/AlexeyAB/darknet/releases/download/yolov4/yolov4-tiny.weights, https://raw.githubusercontent.com/AlexeyAB/darknet/0faed3e60e52f742bbef43b83f6be51dd30f373e/cfg/yolov4-tiny.cfg + /// yolov4 https://github.com/AlexeyAB/darknet/releases/download/yolov4/yolov4.weights, https://raw.githubusercontent.com/AlexeyAB/darknet/0faed3e60e52f742bbef43b83f6be51dd30f373e/cfg/yolov4.cfg + /// + [RequireComponent(typeof(NRCamTextureToMatHelper))] + public class NrealObjectDetectionYOLOv4Example : MonoBehaviour + { + [TooltipAttribute("Path to a binary file of model contains trained weights. It could be a file with extensions .caffemodel (Caffe), .pb (TensorFlow), .t7 or .net (Torch), .weights (Darknet).")] + public string model = "yolov4-tiny.weights"; + + [TooltipAttribute("Path to a text file of model contains network configuration. It could be a file with extensions .prototxt (Caffe), .pbtxt (TensorFlow), .cfg (Darknet).")] + public string config = "yolov4-tiny.cfg"; + + [TooltipAttribute("Optional path to a text file with names of classes to label detected objects.")] + public string classes = "coco.names"; + + [TooltipAttribute("Confidence threshold.")] + public float confThreshold = 0.25f; + + [TooltipAttribute("Non-maximum suppression threshold.")] + public float nmsThreshold = 0.45f; + + //[TooltipAttribute("Maximum detections per image.")] + //public int topK = 1000; + + [TooltipAttribute("Preprocess input image by resizing to a specific width.")] + public int inpWidth = 416; + + [TooltipAttribute("Preprocess input image by resizing to a specific height.")] + public int inpHeight = 416; + + + protected string classes_filepath; + protected string config_filepath; + protected string model_filepath; + + + /// + /// The texture. + /// + Texture2D texture; + + /// + /// The webcam texture to mat helper. + /// + NRCamTextureToMatHelper webCamTextureToMatHelper; + + /// + /// The image optimization helper. + /// + ImageOptimizationHelper imageOptimizationHelper; + + /// + /// The bgr mat. + /// + Mat bgrMat; + + /// + /// The YOLOv4 ObjectDetector. + /// + YOLOv4ObjectDetector objectDetector; + + + [HeaderAttribute("UI")] + + /// + /// Determines if frame skip. + /// + public bool enableFrameSkip; + + /// + /// The enable frame skip toggle. + /// + public Toggle enableFrameSkipToggle; + + /// + /// Determines if displays camera image. + /// + public bool displayCameraImage = false; + + /// + /// The display camera image toggle. + /// + public Toggle displayCameraImageToggle; + + /// + /// the main camera. + /// + Camera mainCamera; + + /// + /// The quad renderer. + /// + Renderer quad_renderer; + + + // Use this for initialization + protected virtual void Start() + { + enableFrameSkipToggle.isOn = enableFrameSkip; + displayCameraImageToggle.isOn = displayCameraImage; + + imageOptimizationHelper = gameObject.GetComponent(); + webCamTextureToMatHelper = gameObject.GetComponent(); + + + if (!string.IsNullOrEmpty(classes)) + { + classes_filepath = Utils.getFilePath("OpenCVForUnity/dnn/" + classes); + if (string.IsNullOrEmpty(classes_filepath)) Debug.Log("The file:" + classes + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); + } + if (!string.IsNullOrEmpty(config)) + { + config_filepath = Utils.getFilePath("OpenCVForUnity/dnn/" + config); + if (string.IsNullOrEmpty(config_filepath)) Debug.Log("The file:" + config + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); + } + if (!string.IsNullOrEmpty(model)) + { + model_filepath = Utils.getFilePath("OpenCVForUnity/dnn/" + model); + if (string.IsNullOrEmpty(model_filepath)) Debug.Log("The file:" + model + " did not exist in the folder “Assets/StreamingAssets/OpenCVForUnity/dnn”."); + } + + Run(); + } + + + // Use this for initialization + protected virtual void Run() + { + //if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console. + Utils.setDebugMode(true); + + if (string.IsNullOrEmpty(model_filepath) || string.IsNullOrEmpty(classes_filepath)) + { + Debug.LogError("model: " + model + " or " + "config: " + config + " or " + "classes: " + classes + " is not loaded."); + } + else + { + objectDetector = new YOLOv4ObjectDetector(model_filepath, config_filepath, classes_filepath, new Size(inpWidth, inpHeight), confThreshold, nmsThreshold/*, topK*/); + } + + webCamTextureToMatHelper.outputColorFormat = WebCamTextureToMatHelper.ColorFormat.RGB; + webCamTextureToMatHelper.Initialize(); + } + + /// + /// Raises the webcam texture to mat helper initialized event. + /// + public virtual void OnWebCamTextureToMatHelperInitialized() + { + Debug.Log("OnWebCamTextureToMatHelperInitialized"); + + Mat webCamTextureMat = webCamTextureToMatHelper.GetMat(); + + + texture = new Texture2D(webCamTextureMat.cols(), webCamTextureMat.rows(), TextureFormat.RGB24, false); + + gameObject.GetComponent().material.mainTexture = texture; + + quad_renderer = gameObject.GetComponent() as Renderer; + quad_renderer.sharedMaterial.SetTexture("_MainTex", texture); + quad_renderer.sharedMaterial.SetVector("_VignetteOffset", new Vector4(0, 0)); + quad_renderer.sharedMaterial.SetFloat("_VignetteScale", 0.0f); + +#if !UNITY_EDITOR + quad_renderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", webCamTextureToMatHelper.GetProjectionMatrix()); +#else + mainCamera = NRSessionManager.Instance.NRHMDPoseTracker.centerCamera; + quad_renderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", mainCamera.projectionMatrix); +#endif + + bgrMat = new Mat(webCamTextureMat.rows(), webCamTextureMat.cols(), CvType.CV_8UC3); + } + + /// + /// Raises the webcam texture to mat helper disposed event. + /// + public virtual void OnWebCamTextureToMatHelperDisposed() + { + Debug.Log("OnWebCamTextureToMatHelperDisposed"); + + if (bgrMat != null) + bgrMat.Dispose(); + + if (texture != null) + { + Texture2D.Destroy(texture); + texture = null; + } + } + + /// + /// Raises the webcam texture to mat helper error occurred event. + /// + /// Error code. + public virtual void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode) + { + Debug.Log("OnWebCamTextureToMatHelperErrorOccurred " + errorCode); + } + + // Update is called once per frame + protected virtual void Update() + { + if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame()) + { + + if (enableFrameSkip && imageOptimizationHelper.IsCurrentFrameSkipped()) + return; + + /* + Mat rgbMat = webCamTextureToMatHelper.GetMat(); + + if (net == null) + { + Imgproc.putText(rgbMat, "model file is not loaded.", new Point(5, rgbMat.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + Imgproc.putText(rgbMat, "Please read console message.", new Point(5, rgbMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + } + else + { + Mat blob = Dnn.blobFromImage(rgbMat, 1.0 / 255.0, new Size(192, 192), new Scalar(0.5, 0.5, 0.5), false, false, CvType.CV_32F); + // Divide blob by std. + Core.divide(blob, new Scalar(0.5, 0.5, 0.5), blob); + + net.setInput(blob); + + Mat prob = net.forward("save_infer_model/scale_0.tmp_1"); + + Mat result = new Mat(); + Core.reduceArgMax(prob, result, 1); + + result.convertTo(result, CvType.CV_8U); + + Mat mask192x192 = new Mat(192, 192, CvType.CV_8UC1, (IntPtr)result.dataAddr()); + Imgproc.resize(mask192x192, maskMat, rgbMat.size(), Imgproc.INTER_NEAREST); + + if (!displayCameraImage) + { + // fill all black. + Imgproc.rectangle(rgbMat, new Point(0, 0), new Point(rgbMat.width(), rgbMat.height()), new Scalar(0, 0, 0, 0), -1); + } + + rgbMat.setTo(new Scalar(255, 255, 255, 255), maskMat); + + mask192x192.Dispose(); + result.Dispose(); + + prob.Dispose(); + blob.Dispose(); + } + + Utils.matToTexture2D(rgbMat, texture); + */ + + Mat rgbMat = webCamTextureToMatHelper.GetMat(); + + if (objectDetector == null) + { + Imgproc.putText(rgbMat, "model file is not loaded.", new Point(5, rgbMat.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + Imgproc.putText(rgbMat, "Please read console message.", new Point(5, rgbMat.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false); + } + else + { + Imgproc.cvtColor(rgbMat, bgrMat, Imgproc.COLOR_RGB2BGR); + + //TickMeter tm = new TickMeter(); + //tm.start(); + + Mat results = objectDetector.infer(bgrMat); + + //tm.stop(); + //Debug.Log("YOLOv4ObjectDetector Inference time (preprocess + infer + postprocess), ms: " + tm.getTimeMilli()); + + if (!displayCameraImage) + { + // fill all black. + Imgproc.rectangle(rgbMat, new Point(0, 0), new Point(rgbMat.width(), rgbMat.height()), new Scalar(0, 0, 0, 0), -1); + } + + objectDetector.visualize(rgbMat, results, false, true); + } + + Utils.matToTexture2D(rgbMat, texture); + } + + if (webCamTextureToMatHelper.IsPlaying()) + { +#if UNITY_ANDROID && !UNITY_EDITOR + Matrix4x4 cameraToWorldMatrix = webCamTextureToMatHelper.GetCameraToWorldMatrix(); +#else + Matrix4x4 cameraToWorldMatrix = mainCamera.cameraToWorldMatrix; +#endif + + Matrix4x4 worldToCameraMatrix = cameraToWorldMatrix.inverse; + + quad_renderer.sharedMaterial.SetMatrix("_WorldToCameraMatrix", worldToCameraMatrix); + + /* + // Position the canvas object slightly in front + // of the real world web camera. + Vector3 position = cameraToWorldMatrix.GetColumn(3) - cameraToWorldMatrix.GetColumn(2); + position *= 1.5f; + + // Rotate the canvas object so that it faces the user. + Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1)); + + gameObject.transform.position = position; + gameObject.transform.rotation = rotation; + */ + + // + // Adjusting the position and scale of the display screen + // to counteract the phenomenon of texture margins (transparent areas in MR space) being displayed as black when recording video using NRVideoCapture. + // + // Position the canvas object slightly in front + // of the real world web camera. + float overlayDistance = 1.5f; + Vector3 ccCameraSpacePos = UnProjectVector(webCamTextureToMatHelper.GetProjectionMatrix(), new Vector3(0.0f, 0.0f, overlayDistance)); + Vector3 tlCameraSpacePos = UnProjectVector(webCamTextureToMatHelper.GetProjectionMatrix(), new Vector3(-overlayDistance, overlayDistance, overlayDistance)); + + //position + Vector3 position = cameraToWorldMatrix.MultiplyPoint3x4(ccCameraSpacePos); + gameObject.transform.position = position; + + //scale + Vector3 scale = new Vector3(Mathf.Abs(tlCameraSpacePos.x - ccCameraSpacePos.x) * 2, Mathf.Abs(tlCameraSpacePos.y - ccCameraSpacePos.y) * 2, 1); + gameObject.transform.localScale = scale; + + // Rotate the canvas object so that it faces the user. + Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1)); + gameObject.transform.rotation = rotation; + // + } + } + + // + private Vector3 UnProjectVector(Matrix4x4 proj, Vector3 to) + { + Vector3 from = new Vector3(0, 0, 0); + var axsX = proj.GetRow(0); + var axsY = proj.GetRow(1); + var axsZ = proj.GetRow(2); + from.z = to.z / axsZ.z; + from.y = (to.y - (from.z * axsY.z)) / axsY.y; + from.x = (to.x - (from.z * axsX.z)) / axsX.x; + return from; + } + // + + /// + /// Raises the destroy event. + /// + protected virtual void OnDestroy() + { + webCamTextureToMatHelper.Dispose(); + imageOptimizationHelper.Dispose(); + + if (objectDetector != null) + objectDetector.dispose(); + + Utils.setDebugMode(false); + } + + /// + /// Raises the back button click event. + /// + public virtual void OnBackButtonClick() + { + SceneManager.LoadScene("NrealLightWithOpenCVForUnityExample"); + } + + /// + /// Raises the play button click event. + /// + public virtual void OnPlayButtonClick() + { + webCamTextureToMatHelper.Play(); + } + + /// + /// Raises the pause button click event. + /// + public virtual void OnPauseButtonClick() + { + webCamTextureToMatHelper.Pause(); + } + + /// + /// Raises the stop button click event. + /// + public virtual void OnStopButtonClick() + { + webCamTextureToMatHelper.Stop(); + } + + /// + /// Raises the change camera button click event. + /// + public virtual void OnChangeCameraButtonClick() + { + webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.requestedIsFrontFacing; + } + + /// + /// Raises the enable frame skip toggle value changed event. + /// + public void OnEnableFrameSkipToggleValueChanged() + { + enableFrameSkip = enableFrameSkipToggle.isOn; + } + + /// + /// Raises the display camera image toggle value changed event. + /// + public void OnDisplayCameraImageToggleValueChanged() + { + displayCameraImage = displayCameraImageToggle.isOn; + } + } + + + public class YOLOv4ObjectDetector + { + Size input_size; + float conf_threshold; + float nms_threshold; + int topK; + int backend; + int target; + + int num_classes = 80; + + DetectionModel detection_model; + + List classNames; + + List palette; + + Mat maxSizeImg; + + MatOfInt classIds; + MatOfFloat confidences; + MatOfRect boxes; + + public YOLOv4ObjectDetector(string modelFilepath, string configFilepath, string classesFilepath, Size inputSize, float confThreshold = 0.25f, float nmsThreshold = 0.45f, int topK = 1000, int backend = Dnn.DNN_BACKEND_OPENCV, int target = Dnn.DNN_TARGET_CPU) + { + // initialize + if (!string.IsNullOrEmpty(modelFilepath)) + { + detection_model = new DetectionModel(modelFilepath, configFilepath); + detection_model.setInputParams(1.0 / 255.0, inputSize, new Scalar(0, 0, 0), true, false); + detection_model.setNmsAcrossClasses(false);// Perform classwise NMS. + detection_model.setPreferableBackend(this.backend); + detection_model.setPreferableTarget(this.target); + } + + if (!string.IsNullOrEmpty(classesFilepath)) + { + classNames = readClassNames(classesFilepath); + num_classes = classNames.Count; + } + + input_size = new Size(inputSize.width > 0 ? inputSize.width : 640, inputSize.height > 0 ? inputSize.height : 640); + conf_threshold = Mathf.Clamp01(confThreshold); + nms_threshold = Mathf.Clamp01(nmsThreshold); + this.topK = topK; + this.backend = backend; + this.target = target; + + classIds = new MatOfInt(); + confidences = new MatOfFloat(); + boxes = new MatOfRect(); + + palette = new List(); + palette.Add(new Scalar(255, 56, 56, 255)); + palette.Add(new Scalar(255, 157, 151, 255)); + palette.Add(new Scalar(255, 112, 31, 255)); + palette.Add(new Scalar(255, 178, 29, 255)); + palette.Add(new Scalar(207, 210, 49, 255)); + palette.Add(new Scalar(72, 249, 10, 255)); + palette.Add(new Scalar(146, 204, 23, 255)); + palette.Add(new Scalar(61, 219, 134, 255)); + palette.Add(new Scalar(26, 147, 52, 255)); + palette.Add(new Scalar(0, 212, 187, 255)); + palette.Add(new Scalar(44, 153, 168, 255)); + palette.Add(new Scalar(0, 194, 255, 255)); + palette.Add(new Scalar(52, 69, 147, 255)); + palette.Add(new Scalar(100, 115, 255, 255)); + palette.Add(new Scalar(0, 24, 236, 255)); + palette.Add(new Scalar(132, 56, 255, 255)); + palette.Add(new Scalar(82, 0, 133, 255)); + palette.Add(new Scalar(203, 56, 255, 255)); + palette.Add(new Scalar(255, 149, 200, 255)); + palette.Add(new Scalar(255, 55, 199, 255)); + } + + protected virtual Mat preprocess(Mat image) + { + // Add padding to make it square. + int max = Mathf.Max(image.cols(), image.rows()); + + if (maxSizeImg == null) + maxSizeImg = new Mat(max, max, image.type()); + if (maxSizeImg.width() != max || maxSizeImg.height() != max) + maxSizeImg.create(max, max, image.type()); + + Imgproc.rectangle(maxSizeImg, new OpenCVRect(0, 0, maxSizeImg.width(), maxSizeImg.height()), Scalar.all(114), -1); + + Mat _maxSizeImg_roi = new Mat(maxSizeImg, new OpenCVRect((max - image.cols()) / 2, (max - image.rows()) / 2, image.cols(), image.rows())); + image.copyTo(_maxSizeImg_roi); + + return maxSizeImg;// [max, max, 3] + } + + public virtual Mat infer(Mat image) + { + // cheack + if (image.channels() != 3) + { + Debug.Log("The input image must be in BGR format."); + return new Mat(); + } + + // Preprocess + Mat input_blob = preprocess(image); + + // Forward + detection_model.detect(input_blob, classIds, confidences, boxes, conf_threshold, nms_threshold); + + // Postprocess + int num = classIds.rows(); + Mat results = new Mat(num, 6, CvType.CV_32FC1); + + float maxSize = Mathf.Max((float)image.size().width, (float)image.size().height); + float x_shift = (maxSize - (float)image.size().width) / 2f; + float y_shift = (maxSize - (float)image.size().height) / 2f; + + for (int i = 0; i < num; ++i) + { + int[] classId_arr = new int[1]; + classIds.get(i, 0, classId_arr); + int id = classId_arr[0]; + + float[] confidence_arr = new float[1]; + confidences.get(i, 0, confidence_arr); + float confidence = confidence_arr[0]; + + int[] box_arr = new int[4]; + boxes.get(i, 0, box_arr); + int x = box_arr[0] - (int)x_shift; + int y = box_arr[1] - (int)y_shift; + int w = box_arr[2]; + int h = box_arr[3]; + + results.put(i, 0, new float[] { x, y, x + w, y + h, confidence, id }); + } + + return results; + } + + protected virtual Mat postprocess(Mat output_blob, Size original_shape) + { + return output_blob; + } + + public virtual void visualize(Mat image, Mat results, bool print_results = false, bool isRGB = false) + { + if (image.IsDisposed) + return; + + if (results.empty() || results.cols() < 6) + return; + + for (int i = results.rows() - 1; i >= 0; --i) + { + float[] box = new float[4]; + results.get(i, 0, box); + float[] conf = new float[1]; + results.get(i, 4, conf); + float[] cls = new float[1]; + results.get(i, 5, cls); + + float left = box[0]; + float top = box[1]; + float right = box[2]; + float bottom = box[3]; + int classId = (int)cls[0]; + + Scalar c = palette[classId % palette.Count]; + Scalar color = isRGB ? c : new Scalar(c.val[2], c.val[1], c.val[0], c.val[3]); + + Imgproc.rectangle(image, new Point(left, top), new Point(right, bottom), color, 2); + + string label = String.Format("{0:0.00}", conf[0]); + if (classNames != null && classNames.Count != 0) + { + if (classId < (int)classNames.Count) + { + label = classNames[classId] + " " + label; + } + } + + int[] baseLine = new int[1]; + Size labelSize = Imgproc.getTextSize(label, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine); + + top = Mathf.Max((float)top, (float)labelSize.height); + Imgproc.rectangle(image, new Point(left, top - labelSize.height), + new Point(left + labelSize.width, top + baseLine[0]), color, Core.FILLED); + Imgproc.putText(image, label, new Point(left, top), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.all(255), 1, Imgproc.LINE_AA); + } + + // Print results + if (print_results) + { + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < results.rows(); ++i) + { + float[] box = new float[4]; + results.get(i, 0, box); + float[] conf = new float[1]; + results.get(i, 4, conf); + float[] cls = new float[1]; + results.get(i, 5, cls); + + int classId = (int)cls[0]; + string label = String.Format("{0:0}", cls[0]); + if (classNames != null && classNames.Count != 0) + { + if (classId < (int)classNames.Count) + { + label = classNames[classId] + " " + label; + } + } + + sb.AppendLine(String.Format("-----------object {0}-----------", i + 1)); + sb.AppendLine(String.Format("conf: {0:0.0000}", conf[0])); + sb.AppendLine(String.Format("cls: {0:0}", label)); + sb.AppendLine(String.Format("box: {0:0} {1:0} {2:0} {3:0}", box[0], box[1], box[2], box[3])); + } + + Debug.Log(sb); + } + } + + public virtual void dispose() + { + if (detection_model != null) + detection_model.Dispose(); + + if (maxSizeImg != null) + maxSizeImg.Dispose(); + + maxSizeImg = null; + + if (classIds != null) + classIds.Dispose(); + if (confidences != null) + confidences.Dispose(); + if (boxes != null) + boxes.Dispose(); + + classIds = null; + confidences = null; + boxes = null; + } + + protected virtual List readClassNames(string filename) + { + List classNames = new List(); + + System.IO.StreamReader cReader = null; + try + { + cReader = new System.IO.StreamReader(filename, System.Text.Encoding.Default); + + while (cReader.Peek() >= 0) + { + string name = cReader.ReadLine(); + classNames.Add(name); + } + } + catch (System.Exception ex) + { + Debug.LogError(ex.Message); + return null; + } + finally + { + if (cReader != null) + cReader.Close(); + } + + return classNames; + } + } +} +#endif + +#endif \ No newline at end of file diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.cs.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.cs.meta new file mode 100644 index 0000000..93c5305 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e92f5bbb1585ca4fac252431867a2f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealYoloObjectDetectionExample.unity b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.unity similarity index 99% rename from Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealYoloObjectDetectionExample.unity rename to Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.unity index 48c0975..a231fe1 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealDnnObjectDetectionExample/NrealYoloObjectDetectionExample.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.unity @@ -288,6 +288,10 @@ PrefabInstance: propertyPath: m_Name value: FPSCanvas objectReference: {fileID: 0} + - target: {fileID: 114491031132128258, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} + propertyPath: m_PresetInfoIsWorld + value: 1 + objectReference: {fileID: 0} - target: {fileID: 224453369079705500, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} propertyPath: m_Pivot.x value: 0.5 @@ -493,7 +497,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnDisplayCameraImageToggleValueChanged m_Mode: 1 @@ -769,7 +773,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnPlayButtonClick m_Mode: 1 @@ -1217,7 +1221,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnChangeCameraButtonClick m_Mode: 1 @@ -1684,7 +1688,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnEnableFrameSkipToggleValueChanged m_Mode: 1 @@ -1843,7 +1847,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnPauseButtonClick m_Mode: 1 @@ -1985,7 +1989,7 @@ GameObject: - component: {fileID: 1709852086} - component: {fileID: 1709852088} m_Layer: 0 - m_Name: NrealYoloObjectDetectionExample + m_Name: NrealObjectDetectionYOLOv4Example m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -2094,7 +2098,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.DnnObjectDetectionWebCamTextureExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnWebCamTextureToMatHelperInitialized m_Mode: 1 @@ -2110,7 +2114,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.DnnObjectDetectionWebCamTextureExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnWebCamTextureToMatHelperDisposed m_Mode: 1 @@ -2126,7 +2130,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.DnnObjectDetectionWebCamTextureExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnWebCamTextureToMatHelperErrorOccurred m_Mode: 0 @@ -2148,23 +2152,14 @@ MonoBehaviour: m_GameObject: {fileID: 1709852081} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 701a3f5d55e57a04a8f7b1a29e1ca8fd, type: 3} + m_Script: {fileID: 11500000, guid: 1e92f5bbb1585ca4fac252431867a2f9, type: 3} m_Name: m_EditorClassIdentifier: model: yolov4-tiny.weights config: yolov4-tiny.cfg classes: coco.names - classesList: [] confThreshold: 0.25 - nmsThreshold: 0.25 - scale: 0.003921569 - mean: - val: - - 0 - - 0 - - 0 - - 0 - swapRB: 0 + nmsThreshold: 0.45 inpWidth: 416 inpHeight: 416 enableFrameSkip: 1 @@ -2290,7 +2285,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnBackButtonClick m_Mode: 1 @@ -2445,7 +2440,7 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1709852087} - m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealDnnObjectDetectionExample, + m_TargetAssemblyTypeName: NrealLightWithOpenCVForUnityExample.NrealObjectDetectionYOLOv4Example, Assembly-CSharp m_MethodName: OnStopButtonClick m_Mode: 1 diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.unity.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.unity.meta new file mode 100644 index 0000000..aa495df --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealObjectDetectionYOLOv4Example/NrealObjectDetectionYOLOv4Example.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b7627200c3c039044a6af91c86cd266c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials.meta new file mode 100644 index 0000000..b5dcbdc --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd37ceefb5eac1e4b8a830d309ab6425 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/BlueMaterial.mat b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/BlueMaterial.mat new file mode 100644 index 0000000..27c2602 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/BlueMaterial.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: BlueMaterial + m_Shader: {fileID: 4800000, guid: 9e8dc7d6627895842b0b4a0d26e4ad21, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + - _node_2675: 1.5 + - _node_3534: 1 + m_Colors: + - _Color: {r: 0, g: 0.11771345, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _node_5051: {r: 0, g: 0.14044952, b: 1, a: 0} + m_BuildTextureStacks: [] diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/BlueMaterial.mat.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/BlueMaterial.mat.meta new file mode 100644 index 0000000..f5717d9 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/BlueMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf04dd286bba0744db3afecf3b3781fd +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/GreenMaterial.mat b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/GreenMaterial.mat new file mode 100644 index 0000000..bd06786 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/GreenMaterial.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: GreenMaterial + m_Shader: {fileID: 4800000, guid: 9e8dc7d6627895842b0b4a0d26e4ad21, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + - _node_2675: 1.5 + - _node_3534: 1 + m_Colors: + - _Color: {r: 0.06021464, g: 1, b: 0, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _node_5051: {r: 0.010368347, g: 1, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/GreenMaterial.mat.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/GreenMaterial.mat.meta new file mode 100644 index 0000000..3a5482c --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/GreenMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8ad38677a34238c468ffe7ceada2902f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/PinkMaterial.mat b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/PinkMaterial.mat new file mode 100644 index 0000000..53ac9b7 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/PinkMaterial.mat @@ -0,0 +1,85 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: PinkMaterial + m_Shader: {fileID: 4800000, guid: 9e8dc7d6627895842b0b4a0d26e4ad21, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + - _node_2675: 1.5 + - _node_3534: 1 + m_Colors: + - _Color: {r: 1, g: 0, b: 0.93567896, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _node_5051: {r: 1, g: 0, b: 0.9272871, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/PinkMaterial.mat.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/PinkMaterial.mat.meta new file mode 100644 index 0000000..308ccdc --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/PinkMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9866a7a06a3f5e84792bd157f4b3f6a0 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/RedMaterial.mat b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/RedMaterial.mat new file mode 100644 index 0000000..37da12f --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/RedMaterial.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: RedMaterial + m_Shader: {fileID: 4800000, guid: 9e8dc7d6627895842b0b4a0d26e4ad21, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + - _node_2675: 1.5 + - _node_3534: 1 + m_Colors: + - _Color: {r: 1, g: 0, b: 0, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _node_5051: {r: 1, g: 0.10085273, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/RedMaterial.mat.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/RedMaterial.mat.meta new file mode 100644 index 0000000..1f0ae06 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/Materials/RedMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a82fec4d8056f6f4fa396a7f70313cea +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.cs index 7911329..26fa3f5 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.cs +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.cs @@ -79,6 +79,16 @@ public class NrealPhotoCaptureExample : MonoBehaviour MatOfRect faces; + public GameObject XREAL_Head; + public GameObject XREAL_RGBCamera; + public GameObject XREAL_LEye; + public GameObject XREAL_REye; + public GameObject XREAL_CenterEye; + public GameObject XREAL_LeftGrayscaleCamera; + public GameObject XREAL_RightGrayscaleCamera; + + public RaycastLaser raycastLaser; + protected void Start() { isBlendModeBlendToggle.isOn = isBlendModeBlend; @@ -178,9 +188,18 @@ void OnCapturedPhotoToMemory(NRPhotoCapture.PhotoCaptureResult result, PhotoCapt } else { - Camera mainCamera = NRSessionManager.Instance.NRHMDPoseTracker.centerCamera; - cameraToWorldMatrix = mainCamera.cameraToWorldMatrix; - + // Get cameraToWorldMatrix + // https://community.xreal.com/t/screen-to-world-point-from-centre-cam/1740/6 + Pose headPose = NRFrame.HeadPose; + Matrix4x4 HeadPoseMatrix = Matrix4x4.TRS(headPose.position, headPose.rotation, Vector3.one); + var eyeposeFromHead = NRFrame.EyePoseFromHead; + Matrix4x4 rgbCameraPoseFromHeadMatrix = Matrix4x4.TRS(eyeposeFromHead.RGBEyePose.position, eyeposeFromHead.RGBEyePose.rotation, Vector3.one); + Matrix4x4 localToWorldMatrix = HeadPoseMatrix * rgbCameraPoseFromHeadMatrix; + // Transform localToWorldMatrix to cameraToWorldMatrix. + cameraToWorldMatrix = localToWorldMatrix * Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0), new Vector3(1, 1, -1)); + Debug.Log("localToWorldMatrix:\n" + localToWorldMatrix.ToString()); + + // Get projectionMatrix bool _result; EyeProjectMatrixData pm = NRFrame.GetEyeProjectMatrix(out _result, 0.3f, 1000f); projectionMatrix = pm.RGBEyeMatrix; @@ -282,6 +301,12 @@ void OnCapturedPhotoToMemory(NRPhotoCapture.PhotoCaptureResult result, PhotoCapt // + // Place a marker objects at the coordinates of XREAL Glass Components. + PlaceMarkerObjects(); + // Draw the View Frustum of the RGB Camera. + DrawViewFrustum(cameraToWorldMatrix, projectionMatrix); + + Debug.Log("Took picture!"); if (saveTextureToGallery) @@ -305,6 +330,127 @@ private Vector3 UnProjectVector(Matrix4x4 proj, Vector3 to) } // + private void PlaceMarkerObjects() + { + // The XREAL glasses consists of the following key components + // 2 x Grayscale Cameras + // 2 x Display Cameras + // Head / IMU + // RGB Camera + // https://xreal.gitbook.io/nrsdk/v/v1.10.2/advanced/nrsdk-coordinate-systems#converting-extrinsics-from-unity-to-opencv + + // Head/IMU + Pose headPose = NRFrame.HeadPose; + Matrix4x4 headPoseM = Matrix4x4.TRS(headPose.position, headPose.rotation, Vector3.one); + ARUtils.SetTransformFromMatrix(XREAL_Head.transform, ref headPoseM); + + // RGB Camera + var eyeposeFromHead = NRFrame.EyePoseFromHead; + Pose rgbCameraPose = eyeposeFromHead.RGBEyePose; + Matrix4x4 rgbCameraPoseFromHeadM = Matrix4x4.TRS(rgbCameraPose.position, rgbCameraPose.rotation, Vector3.one); + Matrix4x4 rgbCameraPoseM = headPoseM * rgbCameraPoseFromHeadM; + ARUtils.SetTransformFromMatrix(XREAL_RGBCamera.transform, ref rgbCameraPoseM); + + // 2 x Grayscale Cameras + Pose leftGrayscaleCameraPose = NRFrame.GetDevicePoseFromHead(NativeDevice.LEFT_GRAYSCALE_CAMERA); + Matrix4x4 leftGrayscaleCameraPoseFromHeadM = Matrix4x4.TRS(leftGrayscaleCameraPose.position, leftGrayscaleCameraPose.rotation, Vector3.one); + Matrix4x4 leftGrayscaleCameraPoseM = headPoseM * leftGrayscaleCameraPoseFromHeadM; + ARUtils.SetTransformFromMatrix(XREAL_LeftGrayscaleCamera.transform, ref leftGrayscaleCameraPoseM); + Pose rightGrayscaleCameraPose = NRFrame.GetDevicePoseFromHead(NativeDevice.RIGHT_GRAYSCALE_CAMERA); + Matrix4x4 rightGrayscaleCameraPoseFromHeadM = Matrix4x4.TRS(rightGrayscaleCameraPose.position, rightGrayscaleCameraPose.rotation, Vector3.one); + Matrix4x4 rightGrayscaleCameraPoseM = headPoseM * rightGrayscaleCameraPoseFromHeadM; + ARUtils.SetTransformFromMatrix(XREAL_RightGrayscaleCamera.transform, ref rightGrayscaleCameraPoseM); + + // 2 x Display Cameras (LEye and REye) + Pose lEyePose = eyeposeFromHead.LEyePose; + Matrix4x4 lEyePoseFromHeadM = Matrix4x4.TRS(lEyePose.position, lEyePose.rotation, Vector3.one); + Matrix4x4 lEyePoseM = headPoseM * lEyePoseFromHeadM; + ARUtils.SetTransformFromMatrix(XREAL_LEye.transform, ref lEyePoseM); + Pose rEyePose = eyeposeFromHead.REyePose; + Matrix4x4 rEyePoseFromHeadM = Matrix4x4.TRS(rEyePose.position, rEyePose.rotation, Vector3.one); + Matrix4x4 rEyePoseM = headPoseM * rEyePoseFromHeadM; + ARUtils.SetTransformFromMatrix(XREAL_REye.transform, ref rEyePoseM); + + // Center Eye (the pose of between left eye and right eye) + Vector3 centerEye_pos = (eyeposeFromHead.LEyePose.position + eyeposeFromHead.REyePose.position) * 0.5f; + Quaternion centerEye_rot = Quaternion.Lerp(eyeposeFromHead.LEyePose.rotation, eyeposeFromHead.REyePose.rotation, 0.5f); + Pose centerEyePose = new Pose(centerEye_pos, centerEye_rot); + Matrix4x4 centerEyePoseFromHeadM = Matrix4x4.TRS(centerEyePose.position, centerEyePose.rotation, Vector3.one); + Matrix4x4 centerEyePoseM = headPoseM * centerEyePoseFromHeadM; + ARUtils.SetTransformFromMatrix(XREAL_CenterEye.transform, ref centerEyePoseM); + + Debug.Log("XREAL_Head_localToWorldMatrix: \n" + XREAL_Head.transform.localToWorldMatrix.ToString()); + Debug.Log("XREAL_RGBCamera_localToWorldMatrix: \n" + XREAL_RGBCamera.transform.localToWorldMatrix.ToString()); + Debug.Log("XREAL_LeftGrayscaleCamera_localToWorldMatrix: \n" + XREAL_LeftGrayscaleCamera.transform.localToWorldMatrix.ToString()); + Debug.Log("XREAL_RightGrayscaleCamera_localToWorldMatrix: \n" + XREAL_RightGrayscaleCamera.transform.localToWorldMatrix.ToString()); + Debug.Log("XREAL_LEye_localToWorldMatrix: \n" + XREAL_LEye.transform.localToWorldMatrix.ToString()); + Debug.Log("XREAL_REye_localToWorldMatrix: \n" + XREAL_REye.transform.localToWorldMatrix.ToString()); + Debug.Log("XREAL_CenterEye_localToWorldMatrix: \n" + XREAL_CenterEye.transform.localToWorldMatrix.ToString()); + + + // + Debug.Log("rgbCameraPoseFromHeadM: \n" + rgbCameraPoseFromHeadM.ToString()); // == NRFrame.GetDevicePoseFromHead(NativeDevice.RGB_CAMERA) + Debug.Log("leftGrayscaleCameraPoseFromHeadM: \n" + leftGrayscaleCameraPoseFromHeadM.ToString()); // Return identity matrix. + Debug.Log("rightGrayscaleCameraPoseFromHeadM: \n" + rightGrayscaleCameraPoseFromHeadM.ToString()); // Return identity matrix. + Debug.Log("lEyePoseFromHeadM: \n" + lEyePoseFromHeadM.ToString()); // == NRFrame.GetDevicePoseFromHead(NativeDevice.LEFT_DISPLAY) + Debug.Log("rEyePoseFromHeadM: \n" + rEyePoseFromHeadM.ToString()); // == NRFrame.GetDevicePoseFromHead(NativeDevice.RIGHT_DISPLAY) + Debug.Log("centerEyePoseFromHeadM: \n" + centerEyePoseFromHeadM.ToString()); // == NRFrame.CenterEyePose + + //Pose magenticePose = NRFrame.GetDevicePoseFromHead(NativeDevice.MAGENTICE); + //Matrix4x4 magenticePoseFromHeadM = Matrix4x4.TRS(magenticePose.position, magenticePose.rotation, Vector3.one); + //Debug.Log("magenticePoseFromHeadM: \n" + magenticePoseFromHeadM.ToString()); + + //Pose leftDisplayPose = NRFrame.GetDevicePoseFromHead(NativeDevice.LEFT_DISPLAY); + //Matrix4x4 leftDisplayPoseFromHeadM = Matrix4x4.TRS(leftDisplayPose.position, leftDisplayPose.rotation, Vector3.one); + //Debug.Log("leftDisplayPoseFromHeadM: \n" + leftDisplayPoseFromHeadM.ToString()); + + //Pose rightDisplayPose = NRFrame.GetDevicePoseFromHead(NativeDevice.RIGHT_DISPLAY); + //Matrix4x4 rightDisplayPoseFromHeadM = Matrix4x4.TRS(rightDisplayPose.position, rightDisplayPose.rotation, Vector3.one); + //Debug.Log("rightDisplayPoseFromHeadM: \n" + rightDisplayPoseFromHeadM.ToString()); + // + } + + private void DrawViewFrustum(Matrix4x4 cameraToWorldMatrix, Matrix4x4 projectionMatrix) + { + for (int i = raycastLaser.transform.childCount - 1; i >= 0; --i) + { + GameObject.DestroyImmediate(raycastLaser.transform.GetChild(i).gameObject); + } + + // Get the ray directions + Vector3 imageCenterDirection = PixelCoordToWorldCoord(cameraToWorldMatrix, projectionMatrix, new Vector2(0, 0)); + Vector3 imageTopLeftDirection = PixelCoordToWorldCoord(cameraToWorldMatrix, projectionMatrix, new Vector2(-1, -1)); + Vector3 imageTopRightDirection = PixelCoordToWorldCoord(cameraToWorldMatrix, projectionMatrix, new Vector2(1, -1)); + Vector3 imageBotLeftDirection = PixelCoordToWorldCoord(cameraToWorldMatrix, projectionMatrix, new Vector2(-1, 1)); + Vector3 imageBotRightDirection = PixelCoordToWorldCoord(cameraToWorldMatrix, projectionMatrix, new Vector2(1, 1)); + + // Paint the rays on the 3d world + raycastLaser.shootLaserFrom(cameraToWorldMatrix.GetColumn(3), imageCenterDirection, 3f); + raycastLaser.shootLaserFrom(cameraToWorldMatrix.GetColumn(3), imageTopLeftDirection, 3f); + raycastLaser.shootLaserFrom(cameraToWorldMatrix.GetColumn(3), imageTopRightDirection, 3f); + raycastLaser.shootLaserFrom(cameraToWorldMatrix.GetColumn(3), imageBotLeftDirection, 3f); + raycastLaser.shootLaserFrom(cameraToWorldMatrix.GetColumn(3), imageBotRightDirection, 3f); + } + + private static Vector3 PixelCoordToWorldCoord(Matrix4x4 cameraToWorldMatrix, Matrix4x4 projectionMatrix, Vector2 pixelCoordinates) + { + // pixelCoordinates is -1 to 1 coords + + float focalLengthX = projectionMatrix.GetColumn(0).x; + float focalLengthY = projectionMatrix.GetColumn(1).y; + float centerX = projectionMatrix.GetColumn(2).x; + float centerY = projectionMatrix.GetColumn(2).y; + + float normFactor = projectionMatrix.GetColumn(2).z; + centerX = centerX / normFactor; + centerY = centerY / normFactor; + + Vector3 dirRay = new Vector3((pixelCoordinates.x - centerX) / focalLengthX, (pixelCoordinates.y - centerY) / focalLengthY, 1.0f / normFactor); //Direction is in camera space + Vector3 direction = new Vector3(Vector3.Dot(cameraToWorldMatrix.GetRow(0), dirRay), Vector3.Dot(cameraToWorldMatrix.GetRow(1), dirRay), Vector3.Dot(cameraToWorldMatrix.GetRow(2), dirRay)); + + return direction; + } + /// Closes this object. void Close() { diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.unity b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.unity index 2cdb8d4..6fa3017 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/NrealPhotoCaptureExample.unity @@ -252,6 +252,14 @@ MonoBehaviour: isBlendModeBlendToggle: {fileID: 1599030165} saveTextureToGallery: 0 saveTextureToGalleryToggle: {fileID: 1837225065} + XREAL_Head: {fileID: 1798383046052817775} + XREAL_RGBCamera: {fileID: 6012705452618573093} + XREAL_LEye: {fileID: 114516038} + XREAL_REye: {fileID: 1692985371} + XREAL_CenterEye: {fileID: 5289682548225821218} + XREAL_LeftGrayscaleCamera: {fileID: 167833269} + XREAL_RightGrayscaleCamera: {fileID: 2057767375} + raycastLaser: {fileID: 1924227081} --- !u!4 &67997009 Transform: m_ObjectHideFlags: 0 @@ -260,12 +268,266 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 67997007} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0.05} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &113648879 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 113648880} + - component: {fileID: 113648883} + - component: {fileID: 113648882} + - component: {fileID: 113648881} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &113648880 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 113648879} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} + m_Children: [] + m_Father: {fileID: 1692985372} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &113648881 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 113648879} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &113648882 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 113648879} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &113648883 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 113648879} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &114516038 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 114516039} + m_Layer: 0 + m_Name: NRCameraPrefabBlue (3) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &114516039 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 114516038} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2066333908} + - {fileID: 2032232972} + m_Father: {fileID: 0} + m_RootOrder: 9 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &167833269 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 167833270} + m_Layer: 0 + m_Name: NRCameraPrefabBlue (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &167833270 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167833269} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1090644886} + - {fileID: 337999941} + m_Father: {fileID: 0} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &337999940 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 337999941} + - component: {fileID: 337999944} + - component: {fileID: 337999943} + - component: {fileID: 337999942} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &337999941 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 337999940} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} + m_Children: [] + m_Father: {fileID: 167833270} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &337999942 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 337999940} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &337999943 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 337999940} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &337999944 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 337999940} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} --- !u!1 &341837833 GameObject: m_ObjectHideFlags: 0 @@ -421,7 +683,7 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 341837833} m_CullTransparentMesh: 0 ---- !u!1 &585358593 +--- !u!1 &393670686 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -429,85 +691,180 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 585358594} - - component: {fileID: 585358596} - - component: {fileID: 585358595} - m_Layer: 5 - m_Name: Label + - component: {fileID: 393670687} + - component: {fileID: 393670690} + - component: {fileID: 393670689} + - component: {fileID: 393670688} + m_Layer: 0 + m_Name: Cube m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!224 &585358594 -RectTransform: +--- !u!4 &393670687 +Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 585358593} + m_GameObject: {fileID: 393670686} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} m_Children: [] - m_Father: {fileID: 1837225063} - m_RootOrder: 1 + m_Father: {fileID: 2057767376} + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 14, y: -0.5} - m_SizeDelta: {x: -38, y: -3} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &585358595 -MonoBehaviour: +--- !u!65 &393670688 +BoxCollider: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 585358593} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_GameObject: {fileID: 393670686} m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Save TextureToGallery Toggle ---- !u!222 &585358596 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 585358593} - m_CullTransparentMesh: 0 ---- !u!1 &853624083 -GameObject: + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &393670689 +MeshRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: + m_GameObject: {fileID: 393670686} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &393670690 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 393670686} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &585358593 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 585358594} + - component: {fileID: 585358596} + - component: {fileID: 585358595} + m_Layer: 5 + m_Name: Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &585358594 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 585358593} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1837225063} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 14, y: -0.5} + m_SizeDelta: {x: -38, y: -3} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &585358595 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 585358593} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Save TextureToGallery Toggle +--- !u!222 &585358596 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 585358593} + m_CullTransparentMesh: 0 +--- !u!1 &853624083 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: - component: {fileID: 853624084} - component: {fileID: 853624088} - component: {fileID: 853624087} @@ -711,6 +1068,14 @@ PrefabInstance: propertyPath: m_Name value: FPSCanvas objectReference: {fileID: 0} + - target: {fileID: 1874029496047342, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 114491031132128258, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} + propertyPath: m_PresetInfoIsWorld + value: 1 + objectReference: {fileID: 0} - target: {fileID: 224453369079705500, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} propertyPath: m_Pivot.x value: 0.5 @@ -809,6 +1174,101 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 67d84a29ffd5ca443ae62b9736795f1b, type: 3} +--- !u!1 &1090644885 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1090644886} + - component: {fileID: 1090644889} + - component: {fileID: 1090644888} + - component: {fileID: 1090644887} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1090644886 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1090644885} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} + m_Children: [] + m_Father: {fileID: 167833270} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1090644887 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1090644885} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1090644888 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1090644885} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1090644889 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1090644885} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} --- !u!1 &1121311764 GameObject: m_ObjectHideFlags: 0 @@ -1040,7 +1500,7 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1294417880} m_CullTransparentMesh: 0 ---- !u!1 &1323962946 +--- !u!1 &1309346976 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -1048,71 +1508,166 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 1323962947} - - component: {fileID: 1323962949} - - component: {fileID: 1323962948} - m_Layer: 5 - m_Name: Text + - component: {fileID: 1309346977} + - component: {fileID: 1309346980} + - component: {fileID: 1309346979} + - component: {fileID: 1309346978} + m_Layer: 0 + m_Name: Cube (1) m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!224 &1323962947 -RectTransform: +--- !u!4 &1309346977 +Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1323962946} + m_GameObject: {fileID: 1309346976} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} m_Children: [] - m_Father: {fileID: 341837834} - m_RootOrder: 0 + m_Father: {fileID: 2057767376} + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1323962948 -MonoBehaviour: +--- !u!65 &1309346978 +BoxCollider: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1323962946} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_GameObject: {fileID: 1309346976} m_Material: {fileID: 0} - m_Color: {r: 0.196, g: 0.196, b: 0.196, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Take Photo ---- !u!222 &1323962949 -CanvasRenderer: + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1309346979 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309346976} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1309346980 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309346976} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1323962946 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1323962947} + - component: {fileID: 1323962949} + - component: {fileID: 1323962948} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1323962947 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1323962946} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 341837834} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1323962948 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1323962946} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.196, g: 0.196, b: 0.196, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Take Photo +--- !u!222 &1323962949 +CanvasRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -1285,6 +1840,10 @@ PrefabInstance: propertyPath: m_Name value: NRCameraRig objectReference: {fileID: 0} + - target: {fileID: 1668515225578100, guid: 665d8158924bd2648a94fb3f87691bbb, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} - target: {fileID: 4275651716754104, guid: 665d8158924bd2648a94fb3f87691bbb, type: 3} propertyPath: m_RootOrder value: 0 @@ -1526,6 +2085,133 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1635887274} m_CullTransparentMesh: 0 +--- !u!1 &1692197330 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1692197331} + - component: {fileID: 1692197334} + - component: {fileID: 1692197333} + - component: {fileID: 1692197332} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1692197331 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1692197330} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} + m_Children: [] + m_Father: {fileID: 1692985372} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1692197332 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1692197330} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1692197333 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1692197330} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1692197334 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1692197330} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1692985371 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1692985372} + m_Layer: 0 + m_Name: NRCameraPrefabBlue (4) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1692985372 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1692985371} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1692197331} + - {fileID: 113648880} + m_Father: {fileID: 0} + m_RootOrder: 10 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1837225062 GameObject: m_ObjectHideFlags: 0 @@ -1778,7 +2464,7 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: ad152f08ed7eb6e4abd93376a0203e38, type: 3} ---- !u!1 &2078122076 +--- !u!1 &1924227080 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -1786,62 +2472,329 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 2078122081} - - component: {fileID: 2078122080} - - component: {fileID: 2078122079} - - component: {fileID: 2078122078} - - component: {fileID: 2078122077} - m_Layer: 5 - m_Name: Canvas + - component: {fileID: 1924227082} + - component: {fileID: 1924227081} + m_Layer: 0 + m_Name: RaycastLaser m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!114 &2078122077 +--- !u!114 &1924227081 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2078122076} + m_GameObject: {fileID: 1924227080} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: a3c7906c48f0cd94393196c6c9f7cab3, type: 3} + m_Script: {fileID: 11500000, guid: a913aa7b862f8c243a93a991f9ca8f23, type: 3} m_Name: m_EditorClassIdentifier: - Anchor: 3 - FollowSpeed: 2 - Offset: {x: 0.2, y: 0} ---- !u!114 &2078122078 -MonoBehaviour: + _lineWidthMultiplier: 0.01 + _laserMaterial: {fileID: 2100000, guid: 9866a7a06a3f5e84792bd157f4b3f6a0, type: 2} +--- !u!4 &1924227082 +Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2078122076} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 6750858741a2f3744a27ca80b2f55710, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 ---- !u!114 &2078122079 -MonoBehaviour: + m_GameObject: {fileID: 1924227080} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 13 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2032232971 +GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2078122076} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 1 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} + serializedVersion: 6 + m_Component: + - component: {fileID: 2032232972} + - component: {fileID: 2032232975} + - component: {fileID: 2032232974} + - component: {fileID: 2032232973} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2032232972 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2032232971} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} + m_Children: [] + m_Father: {fileID: 114516039} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &2032232973 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2032232971} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &2032232974 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2032232971} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &2032232975 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2032232971} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &2057767375 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2057767376} + m_Layer: 0 + m_Name: NRCameraPrefabBlue (2) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2057767376 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2057767375} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 393670687} + - {fileID: 1309346977} + m_Father: {fileID: 0} + m_RootOrder: 8 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2066333907 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2066333908} + - component: {fileID: 2066333911} + - component: {fileID: 2066333910} + - component: {fileID: 2066333909} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2066333908 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066333907} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} + m_Children: [] + m_Father: {fileID: 114516039} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &2066333909 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066333907} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &2066333910 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066333907} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &2066333911 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066333907} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &2078122076 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2078122081} + - component: {fileID: 2078122080} + - component: {fileID: 2078122079} + - component: {fileID: 2078122078} + - component: {fileID: 2078122077} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2078122077 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2078122076} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a3c7906c48f0cd94393196c6c9f7cab3, type: 3} + m_Name: + m_EditorClassIdentifier: + Anchor: 3 + FollowSpeed: 2 + Offset: {x: 0.2, y: 0} +--- !u!114 &2078122078 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2078122076} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6750858741a2f3744a27ca80b2f55710, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 +--- !u!114 &2078122079 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2078122076} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} m_ScreenMatchMode: 0 m_MatchWidthOrHeight: 0 m_PhysicalUnit: 3 @@ -1890,3 +2843,669 @@ RectTransform: m_AnchoredPosition: {x: -0.2, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!65 &312709744259662718 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505285391190724142} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &1505285391190724142 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1924648453796107754} + - component: {fileID: 2407255832677305886} + - component: {fileID: 2609013938104460028} + - component: {fileID: 312709744259662718} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &1798383045793203520 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1798383045793203523} + - component: {fileID: 1798383045793203532} + - component: {fileID: 1798383045793203533} + - component: {fileID: 1798383045793203522} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!65 &1798383045793203522 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1798383045793203520} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!4 &1798383045793203523 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1798383045793203520} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} + m_Children: [] + m_Father: {fileID: 1798383046052817774} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &1798383045793203532 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1798383045793203520} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1798383045793203533 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1798383045793203520} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8ad38677a34238c468ffe7ceada2902f, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!4 &1798383046052817774 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1798383046052817775} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1798383045793203523} + - {fileID: 1924648453796107754} + m_Father: {fileID: 0} + m_RootOrder: 12 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1798383046052817775 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1798383046052817774} + m_Layer: 0 + m_Name: NRCameraPrefabGreen + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1924648453796107754 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505285391190724142} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} + m_Children: [] + m_Father: {fileID: 1798383046052817774} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &2407255832677305886 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505285391190724142} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &2609013938104460028 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505285391190724142} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8ad38677a34238c468ffe7ceada2902f, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &5007510809078099811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5415613770737185959} + - component: {fileID: 8139644958240059219} + - component: {fileID: 8478182157675070385} + - component: {fileID: 6182156140087075379} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &5289682547948889088 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5289682547948889101} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &5289682547948889089 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5289682547948889101} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &5289682547948889101 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5289682547948889102} + - component: {fileID: 5289682547948889089} + - component: {fileID: 5289682547948889088} + - component: {fileID: 5289682547948889103} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5289682547948889102 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5289682547948889101} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} + m_Children: [] + m_Father: {fileID: 5289682548225821219} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &5289682547948889103 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5289682547948889101} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &5289682548225821218 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5289682548225821219} + m_Layer: 0 + m_Name: NRCameraPrefabBlue + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5289682548225821219 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5289682548225821218} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 5289682547948889102} + - {fileID: 5415613770737185959} + m_Father: {fileID: 0} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &5415613770737185959 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5007510809078099811} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} + m_Children: [] + m_Father: {fileID: 5289682548225821219} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &5751870512105311540 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6874622837063172196} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!4 &5850722960745683872 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6874622837063172196} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0.0075} + m_LocalScale: {x: 0.005, y: 0.005, z: 0.005} + m_Children: [] + m_Father: {fileID: 6012705452618573092} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &6012705452358667014 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6012705452358667018} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &6012705452358667015 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6012705452358667018} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a82fec4d8056f6f4fa396a7f70313cea, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!65 &6012705452358667016 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6012705452358667018} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!4 &6012705452358667017 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6012705452358667018} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.01, y: 0.01, z: 0.01} + m_Children: [] + m_Father: {fileID: 6012705452618573092} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &6012705452358667018 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6012705452358667017} + - component: {fileID: 6012705452358667014} + - component: {fileID: 6012705452358667015} + - component: {fileID: 6012705452358667016} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &6012705452618573092 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6012705452618573093} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 6012705452358667017} + - {fileID: 5850722960745683872} + m_Father: {fileID: 0} + m_RootOrder: 11 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &6012705452618573093 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6012705452618573092} + m_Layer: 0 + m_Name: NRCameraPrefabRed + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!65 &6182156140087075379 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5007510809078099811} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!1 &6874622837063172196 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5850722960745683872} + - component: {fileID: 7704535770270629972} + - component: {fileID: 8048315439147658422} + - component: {fileID: 5751870512105311540} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!33 &7704535770270629972 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6874622837063172196} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8048315439147658422 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6874622837063172196} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a82fec4d8056f6f4fa396a7f70313cea, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &8139644958240059219 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5007510809078099811} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8478182157675070385 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5007510809078099811} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: cf04dd286bba0744db3afecf3b3781fd, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/RaycastLaser.cs b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/RaycastLaser.cs new file mode 100644 index 0000000..77681f9 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/RaycastLaser.cs @@ -0,0 +1,23 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class RaycastLaser : MonoBehaviour +{ + public float _lineWidthMultiplier = 0.01f; + public Material _laserMaterial; + + public void shootLaserFrom(Vector3 from, Vector3 direction, float length, Material mat = null) + { + LineRenderer lr = new GameObject().AddComponent(); + lr.transform.parent = transform; + lr.widthMultiplier = _lineWidthMultiplier; + + lr.material = mat == null ? _laserMaterial : mat; + + Vector3 to = from + length * direction; + + lr.SetPosition(0, from); + lr.SetPosition(1, to); + } +} diff --git a/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/RaycastLaser.cs.meta b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/RaycastLaser.cs.meta new file mode 100644 index 0000000..e541b73 --- /dev/null +++ b/Assets/NrealLightWithOpenCVForUnityExample/NrealPhotoCaptureExample/RaycastLaser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a913aa7b862f8c243a93a991f9ca8f23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NrealLightWithOpenCVForUnityExample/Scripts/Utils/NRCamTextureToMatHelper.cs b/Assets/NrealLightWithOpenCVForUnityExample/Scripts/Utils/NRCamTextureToMatHelper.cs index 37ac490..dea5d7c 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/Scripts/Utils/NRCamTextureToMatHelper.cs +++ b/Assets/NrealLightWithOpenCVForUnityExample/Scripts/Utils/NRCamTextureToMatHelper.cs @@ -13,8 +13,8 @@ namespace NrealLightWithOpenCVForUnity.UnityUtils.Helper { /// /// NRCamTexture to mat helper. - /// v 1.0.0 - /// Depends on NRSDK v 1.9.5 (https://nreal.gitbook.io/nrsdk/nrsdk-fundamentals/core-features). + /// v 1.0.1 + /// Depends on NRSDK v 1.10.2 (https://nreal.gitbook.io/nrsdk/nrsdk-fundamentals/core-features). /// Depends on OpenCVForUnity version 2.4.1 (WebCamTextureToMatHelper v 1.1.2) or later. /// /// By setting outputColorFormat to RGB, processing that does not include extra color conversion is performed. @@ -89,6 +89,8 @@ public virtual int GetFrameCount() protected Matrix4x4 invertZM = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0), new Vector3(1, 1, -1)); + protected Matrix4x4 rgbCameraPoseFromHeadMatrix = Matrix4x4.identity; + protected Matrix4x4 centerEyePoseFromHeadMatrix = Matrix4x4.identity; protected Matrix4x4 projectionMatrix = Matrix4x4.identity; @@ -174,19 +176,18 @@ protected override IEnumerator _Initialize() initCoroutine = null; - // Get centerEyePose from Head Matrix - // - // Get physical RGBCamera position (offset position from Head). For some reason, when this value is used in the calculation, the position is shifted. - //Pose camPos = NRFrame.GetDevicePoseFromHead(NativeDevice.RGB_CAMERA);// Get Pose RGBCamera From Head - //centerEyePoseFromHeadMatrix = Matrix4x4.TRS(camPos.position, camPos.rotation, Vector3.one); - // - // or - // + // Get physical RGBCamera position (offset position from Head). + Pose camPos = NRFrame.GetDevicePoseFromHead(NativeDevice.RGB_CAMERA); + rgbCameraPoseFromHeadMatrix = Matrix4x4.TRS(camPos.position, camPos.rotation, Vector3.one); + // The position offset in the Z direction seemed too large, so code to change it to the same value as the center eye. + // (This will greatly improve the misalignment with reality during projection, but it is not perfect.) + //rgbCameraPoseFromHeadMatrix.m23 = -0.00678f; + + // Get CenterEyePose (between left eye and right eye) position (offset position from Head). var eyeposeFromHead = NRFrame.EyePoseFromHead; Vector3 localPosition = (eyeposeFromHead.LEyePose.position + eyeposeFromHead.REyePose.position) * 0.5f; Quaternion localRotation = Quaternion.Lerp(eyeposeFromHead.LEyePose.rotation, eyeposeFromHead.REyePose.rotation, 0.5f); centerEyePoseFromHeadMatrix = Matrix4x4.TRS(localPosition, localRotation, Vector3.one); - // // Get projection Matrix // @@ -198,6 +199,11 @@ protected override IEnumerator _Initialize() // bool result; EyeProjectMatrixData pm = NRFrame.GetEyeProjectMatrix(out result, 0.3f, 1000f); + while (!result) + { + yield return new WaitForEndOfFrame(); + pm = NRFrame.GetEyeProjectMatrix(out result, 0.3f, 1000f); + } projectionMatrix = pm.RGBEyeMatrix; // @@ -305,14 +311,18 @@ public override WebCamTexture GetWebCamTexture() public override Matrix4x4 GetCameraToWorldMatrix() { // - //Pose headPose = NRFrame.HeadPose; // Get Head pose - //Matrix4x4 HeadPoseM = Matrix4x4.TRS(headPose.position, headPose.rotation, Vector3.one); - //Matrix4x4 localToWorldMatrix = HeadPoseM * centerEyePoseFromHeadMatrix; + // RGB camera position is used. However, even if this correct value is used in the calculation, the projected AR object will appear slightly offset upward. + // https://community.xreal.com/t/screen-to-world-point-from-centre-cam/1740/6 + Pose headPose = NRFrame.HeadPose; + Matrix4x4 HeadPoseM = Matrix4x4.TRS(headPose.position, headPose.rotation, Vector3.one); + Matrix4x4 localToWorldMatrix = HeadPoseM * rgbCameraPoseFromHeadMatrix; // // or - // The values obtained by this method generally match reality, but I think they are slightly off to the left. - Pose centerEyePose = NRFrame.CenterEyePose; - Matrix4x4 localToWorldMatrix = Matrix4x4.TRS(centerEyePose.position, centerEyePose.rotation, Vector3.one); + // + // Center eye position is used. The projected positions obtained with this method are generally consistent with reality, but are slightly off to the left. + //Pose headPose = NRFrame.HeadPose; + //Matrix4x4 HeadPoseM = Matrix4x4.TRS(headPose.position, headPose.rotation, Vector3.one); + //Matrix4x4 localToWorldMatrix = HeadPoseM * centerEyePoseFromHeadMatrix; // // Transform localToWorldMatrix to cameraToWorldMatrix. diff --git a/Assets/NrealLightWithOpenCVForUnityExample/ShowLicense.unity b/Assets/NrealLightWithOpenCVForUnityExample/ShowLicense.unity index 2a830d4..a64b9e4 100644 --- a/Assets/NrealLightWithOpenCVForUnityExample/ShowLicense.unity +++ b/Assets/NrealLightWithOpenCVForUnityExample/ShowLicense.unity @@ -422,32 +422,156 @@ MonoBehaviour: m_HorizontalOverflow: 0 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: "IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r\n\r\nBy - downloading, copying, installing or using the software you agree to this license.\r\nIf - you do not agree to this license, do not download, install,\r\n copy or use the - software.\r\n\r\n\r\n License Agreement\r\n - For Open Source Computer Vision Library\r\n\r\nCopyright (C) 2000-2008, Intel - Corporation, all rights reserved.\r\nCopyright (C) 2008-2011, Willow Garage Inc., - all rights reserved.\r\nThird party copyrights are property of their respective - owners.\r\n\r\nRedistribution and use in source and binary forms, with or without - modification,\r\nare permitted provided that the following conditions are met:\r\n\r\n - * Redistributions of source code must retain the above copyright notice,\r\n - this list of conditions and the following disclaimer.\r\n\r\n * Redistributions - in binary form must reproduce the above copyright notice,\r\n this list of - conditions and the following disclaimer in the documentation\r\n and/or other - materials provided with the distribution.\r\n\r\n * The name of the copyright - holders may not be used to endorse or promote products\r\n derived from this - software without specific prior written permission.\r\n\r\nThis software is provided - by the copyright holders and contributors \"as is\" and\r\nany express or implied - warranties, including, but not limited to, the implied\r\nwarranties of merchantability - and fitness for a particular purpose are disclaimed.\r\nIn no event shall the - Intel Corporation or contributors be liable for any direct,\r\nindirect, incidental, - special, exemplary, or consequential damages\r\n(including, but not limited to, - procurement of substitute goods or services;\r\nloss of use, data, or profits; - or business interruption) however caused\r\nand on any theory of liability, whether - in contract, strict liability,\r\nor tort (including negligence or otherwise) - arising in any way out of\r\nthe use of this software, even if advised of the - possibility of such damage.\r\n" + m_Text: "The following components are governed by the licenses indicated below:\n\n- + OpenCV : Apache 2.0\n\nhttps://github.com/opencv/opencv/blob/4.x/COPYRIGHT\n\n + Apache License\n Version 2.0, January + 2004\n http://www.apache.org/licenses/\n\n + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n + \"License\" shall mean the terms and conditions for use, reproduction,\n + and distribution as defined by Sections 1 through 9 of this document.\n\n + \"Licensor\" shall mean the copyright owner or entity authorized by\n the + copyright owner that is granting the License.\n\n \"Legal Entity\" shall + mean the union of the acting entity and all\n other entities that control, + are controlled by, or are under common\n control with that entity. For the + purposes of this definition,\n \"control\" means (i) the power, direct or + indirect, to cause the\n direction or management of such entity, whether + by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or + more of the\n outstanding shares, or (iii) beneficial ownership of such + entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n + exercising permissions granted by this License.\n\n \"Source\" form shall + mean the preferred form for making modifications,\n including but not limited + to software source code, documentation\n source, and configuration files.\n\n + \"Object\" form shall mean any form resulting from mechanical\n transformation + or translation of a Source form, including but\n not limited to compiled + object code, generated documentation,\n and conversions to other media types.\n\n + \"Work\" shall mean the work of authorship, whether in Source or\n Object + form, made available under the License, as indicated by a\n copyright notice + that is included in or attached to the work\n (an example is provided in + the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether + in Source or Object\n form, that is based on (or derived from) the Work and + for which the\n editorial revisions, annotations, elaborations, or other + modifications\n represent, as a whole, an original work of authorship. For + the purposes\n of this License, Derivative Works shall not include works + that remain\n separable from, or merely link (or bind by name) to the interfaces + of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall + mean any work of authorship, including\n the original version of the Work + and any modifications or additions\n to that Work or Derivative Works thereof, + that is intentionally\n submitted to Licensor for inclusion in the Work + by the copyright owner\n or by an individual or Legal Entity authorized + to submit on behalf of\n the copyright owner. For the purposes of this definition, + \"submitted\"\n means any form of electronic, verbal, or written communication + sent\n to the Licensor or its representatives, including but not limited + to\n communication on electronic mailing lists, source code control systems,\n + and issue tracking systems that are managed by, or on behalf of, the\n Licensor + for the purpose of discussing and improving the Work, but\n excluding communication + that is conspicuously marked or otherwise\n designated in writing by the + copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean + Licensor and any individual or Legal Entity\n on behalf of whom a Contribution + has been received by Licensor and\n subsequently incorporated within the + Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions + of\n this License, each Contributor hereby grants to You a perpetual,\n + worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright + license to reproduce, prepare Derivative Works of,\n publicly display, publicly + perform, sublicense, and distribute the\n Work and such Derivative Works + in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms + and conditions of\n this License, each Contributor hereby grants to You + a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n + (except as stated in this section) patent license to make, have made,\n + use, offer to sell, sell, import, and otherwise transfer the Work,\n where + such license applies only to those patent claims licensable\n by such Contributor + that are necessarily infringed by their\n Contribution(s) alone or by combination + of their Contribution(s)\n with the Work to which such Contribution(s) was + submitted. If You\n institute patent litigation against any entity (including + a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n + or a Contribution incorporated within the Work constitutes direct\n or contributory + patent infringement, then any patent licenses\n granted to You under this + License for that Work shall terminate\n as of the date such litigation is + filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n + Work or Derivative Works thereof in any medium, with or without\n modifications, + and in Source or Object form, provided that You\n meet the following conditions:\n\n + (a) You must give any other recipients of the Work or\n Derivative Works + a copy of this License; and\n\n (b) You must cause any modified files to + carry prominent notices\n stating that You changed the files; and\n\n + (c) You must retain, in the Source form of any Derivative Works\n that + You distribute, all copyright, patent, trademark, and\n attribution + notices from the Source form of the Work,\n excluding those notices + that do not pertain to any part of\n the Derivative Works; and\n\n + (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, + then any Derivative Works that You distribute must\n include a readable + copy of the attribution notices contained\n within such NOTICE file, + excluding those notices that do not\n pertain to any part of the Derivative + Works, in at least one\n of the following places: within a NOTICE text + file distributed\n as part of the Derivative Works; within the Source + form or\n documentation, if provided along with the Derivative Works; + or,\n within a display generated by the Derivative Works, if and\n + wherever such third-party notices normally appear. The contents\n of + the NOTICE file are for informational purposes only and\n do not modify + the License. You may add Your own attribution\n notices within Derivative + Works that You distribute, alongside\n or as an addendum to the NOTICE + text from the Work, provided\n that such additional attribution notices + cannot be construed\n as modifying the License.\n\n You may add + Your own copyright statement to Your modifications and\n may provide additional + or different license terms and conditions\n for use, reproduction, or distribution + of Your modifications, or\n for any such Derivative Works as a whole, provided + Your use,\n reproduction, and distribution of the Work otherwise complies + with\n the conditions stated in this License.\n\n 5. Submission of Contributions. + Unless You explicitly state otherwise,\n any Contribution intentionally submitted + for inclusion in the Work\n by You to the Licensor shall be under the terms + and conditions of\n this License, without any additional terms or conditions.\n + Notwithstanding the above, nothing herein shall supersede or modify\n the + terms of any separate license agreement you may have executed\n with Licensor + regarding such Contributions.\n\n 6. Trademarks. This License does not grant + permission to use the trade\n names, trademarks, service marks, or product + names of the Licensor,\n except as required for reasonable and customary + use in describing the\n origin of the Work and reproducing the content of + the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable + law or\n agreed to in writing, Licensor provides the Work (and each\n + Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, + without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, + MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible + for determining the\n appropriateness of using or redistributing the Work + and assume any\n risks associated with Your exercise of permissions under + this License.\n\n 8. Limitation of Liability. In no event and under no legal + theory,\n whether in tort (including negligence), contract, or otherwise,\n + unless required by applicable law (such as deliberate and grossly\n negligent + acts) or agreed to in writing, shall any Contributor be\n liable to You + for damages, including any direct, indirect, special,\n incidental, or consequential + damages of any character arising as a\n result of this License or out of + the use or inability to use the\n Work (including but not limited to damages + for loss of goodwill,\n work stoppage, computer failure or malfunction, + or any and all\n other commercial damages or losses), even if such Contributor\n + has been advised of the possibility of such damages.\n\n 9. Accepting Warranty + or Additional Liability. While redistributing\n the Work or Derivative Works + thereof, You may choose to offer,\n and charge a fee for, acceptance of + support, warranty, indemnity,\n or other liability obligations and/or rights + consistent with this\n License. However, in accepting such obligations, + You may act only\n on Your own behalf and on Your sole responsibility, not + on behalf\n of any other Contributor, and only if You agree to indemnify,\n + defend, and hold each Contributor harmless for any liability\n incurred + by, or claims asserted against, such Contributor by reason\n of your accepting + any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n + APPENDIX: How to apply the Apache License to your work.\n\n To apply the + Apache License to your work, attach the following\n boilerplate notice, + with the fields enclosed by brackets \"[]\"\n replaced with your own identifying + information. (Don't include\n the brackets!) The text should be enclosed + in the appropriate\n comment syntax for the file format. We also recommend + that a\n file or class name and description of purpose be included on the\n + same \"printed page\" as the copyright notice for easier\n identification + within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n + Licensed under the Apache License, Version 2.0 (the \"License\");\n you may + not use this file except in compliance with the License.\n You may obtain a + copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n + Unless required by applicable law or agreed to in writing, software\n distributed + under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES + OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for + the specific language governing permissions and\n limitations under the License.\n\n\n----------------------------------------------------------------------------------------------------------------\r\n\r\n\n- + human_segmentation_pphumanseg_2023mar.onnx : Apache 2.0 License\r\nCopyright + (C) 2021, Shenzhen Institute of Artificial Intelligence and Robotics for Society, + all rights reserved.\r\nhttps://github.com/opencv/opencv_zoo/blob/master/models/human_segmentation_pphumanseg/LICENSE\r\n\r\n- + face_detection_yunet_2022mar.onnx : MIT License\r\nCopyright (C) 2021, Shenzhen + Institute of Artificial Intelligence and Robotics for Society, all rights reserved.\r\nhttps://github.com/opencv/opencv_zoo/blob/master/models/face_detection_yunet/LICENSE\r\n\r\n- + yolov4-tiny.cfg, yolov4-tiny.weights : YOLO LICENSE\r\nhttps://github.com/AlexeyAB/darknet/blob/master/LICENSE\r" --- !u!222 &593276360 CanvasRenderer: m_ObjectHideFlags: 0 @@ -877,7 +1001,7 @@ MonoBehaviour: m_HandleRect: {fileID: 2061365887} m_Direction: 2 m_Value: 1 - m_Size: 0.16990621 + m_Size: 0.028016226 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: diff --git a/BuildSettings.jpg b/BuildSettings.jpg index f284d2d..20b5101 100644 Binary files a/BuildSettings.jpg and b/BuildSettings.jpg differ diff --git a/ProjectAssets.jpg b/ProjectAssets.jpg index 40ca4a7..e5df987 100644 Binary files a/ProjectAssets.jpg and b/ProjectAssets.jpg differ diff --git a/README.md b/README.md index 58bab2e..7b6644d 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ ## Environment * Android (Galaxy S10+ SC-04L) -* Nreal Light -* Unity 2020.3.38f1+ (NRSDK supports the development environment of Unity 2018.4.X and above.) -* [NRSDK](https://developer.nreal.ai/download) Unity SDK 1.10.0 -* [OpenCV for Unity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088?aid=1011l4ehR) 2.5.1+ +* Nreal Light (XREAL Light) +* Unity 2020.3.48f1+ (NRSDK supports the development environment of Unity 2018.4.X and above.) +* [NRSDK](https://developer.nreal.ai/download) Unity SDK 1.10.2 +* [OpenCV for Unity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088?aid=1011l4ehR) 2.5.6+ ## Setup @@ -23,9 +23,10 @@ * Change the platform to Android in the "Build Settings" window. 1. Import the OpenCVForUnity. * Select MenuItem[Tools/OpenCV for Unity/Open Setup Tools]. + * Click the [Open Example Assets Downloader] button. + * Download files for examples ( HumanSegmentationExample, ObjectDetectionYolov4Example and FaceDetectionYNWebCamExample ) using the dnn, objdetect module. * Click the [Move StreamingAssets Folder] button. - * Download files for examples ( LibFaceDetectionV2Example, YoloObjectDetectionExample and HumanSegmentationExample ) using the dnn module.[setup_dnn_module.pdf](https://github.com/EnoxSoftware/OpenCVForUnity/blob/master/Assets/OpenCVForUnity/StreamingAssets/OpenCVForUnity/dnn/setup_dnn_module.pdf) - * Leave the following files and delete the rest. ("StreamingAssets/OpenCVForUnity/objdetect/haarcascade_frontalface_alt.xml", "lbpcascade_ frontalface.xml","StreamingAssets/OpenCVForUnity/dnn/coco.names","yolov4-tiny.cfg","yolov4-tiny.weights","yufacedetectnet-open-v2.caffemodel","yufacedetectnet-open-v2.prototxt", "human_segmentation_pphumanseg_2021oct.onnx") + * Leave the following files and delete the rest. ("StreamingAssets/OpenCVForUnity/objdetect/haarcascade_frontalface_alt.xml", "lbpcascade_ frontalface.xml", "face_detection_yunet_2023mar.onnx","StreamingAssets/OpenCVForUnity/dnn/coco.names","yolov4-tiny.cfg","yolov4-tiny.weights","human_segmentation_pphumanseg_2023mar.onnx") 1. Import the NRSDK. * Download the latest release NRSDK unitypackage. [NRSDKForUnity_Release_1.xx.x.unitypackage](https://developer.nreal.ai/download) * Setup the NRSDK. (See [Getting Started with NRSDK](https://nreal.gitbook.io/nrsdk/nrsdk-fundamentals/quickstart-for-android)) @@ -35,9 +36,9 @@ * (Print the AR marker "CanonicalMarker-d10-i1-sp500-bb1.pdf" on an A4 size paper) -|Project Assets|Build Settings| +|SetupTools_AssetsDownloader|Project Assets|Build Settings| |---|---| -|![ProjectAssets.jpg](ProjectAssets.jpg)|![BuildSettings.jpg](BuildSettings.jpg)| +|![SetupTools_AssetsDownloader.jpg](SetupTools_AssetsDownloader.jpg)|![ProjectAssets.jpg](ProjectAssets.jpg)|![BuildSettings.jpg](BuildSettings.jpg)| ## ScreenShot diff --git a/SetupTools_AssetsDownloader.jpg b/SetupTools_AssetsDownloader.jpg new file mode 100644 index 0000000..6d34515 Binary files /dev/null and b/SetupTools_AssetsDownloader.jpg differ