// creates boundary plane for mr headsets private void CreateBoundaryPlane(Transform planeParent, Material planeMat, bool isCollider, PhysicMaterial colliderMat) { //if(boundaryPlane == null) { boundaryPlane = GameObject.CreatePrimitive(PrimitiveType.Plane); boundaryPlane.name = "Boundary"; boundaryPlane.layer = MultiARInterop.GetSurfaceLayer(); boundaryPlane.transform.SetParent(planeParent); } MeshRenderer meshRenderer = boundaryPlane.GetComponent <MeshRenderer>(); if (meshRenderer) { meshRenderer.enabled = planeMat != null; meshRenderer.material = planeMat; } MeshCollider meshCollider = boundaryPlane.GetComponent <MeshCollider>(); if (meshCollider) { meshCollider.enabled = isCollider; if (isCollider && colliderMat) { meshCollider.material = colliderMat; } } }
void Update() { // // don't consider taps over the UI // if(UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) // return; // check for click if (objectPrefab && arManager && arManager.IsInitialized() && arManager.IsInputAvailable(true)) { MultiARInterop.InputAction action = arManager.GetInputAction(); if (action == MultiARInterop.InputAction.Click) { // raycast world //Vector2 screenPos = Input.GetTouch(0).position; MultiARInterop.TrackableHit hit; if (arManager.RaycastToWorld(true, out hit)) { // instantiate the object and anchor it to the world position GameObject spawnObj = Instantiate(objectPrefab, hit.point, !verticalModel ? hit.rotation : Quaternion.identity); arManager.AnchorGameObjectToWorld(spawnObj, hit); // look at the camera if (modelLookingAtCamera) { Camera arCamera = arManager.GetMainCamera(); MultiARInterop.TurnObjectToCamera(spawnObj, arCamera, hit.point, hit.normal); } } } } }
// sets the world position of the current model private bool SetModelWorldPos(Vector3 vNewPos, Quaternion qNewRot) { if (modelTransform) { // activate model if needed if (!modelTransform.gameObject.activeSelf) { modelTransform.gameObject.SetActive(true); } // set position and look at the camera modelTransform.position = vNewPos; modelTransform.rotation = qNewRot; if (modelLookingAtCamera) { Camera arCamera = arManager.GetMainCamera(); MultiARInterop.TurnObjectToCamera(modelTransform.gameObject, arCamera, modelTransform.position, modelTransform.up); } return(true); } return(false); }
// Updates overlay surface mesh. Returns true on success, false if the surface needs to be deleted private bool UpdateOverlaySurface(OverlaySurfaceUpdater overlaySurface, DetectedPlane trackedSurface) { // check for validity if (overlaySurface == null || trackedSurface == null) { return(false); } else if (trackedSurface.SubsumedBy != null) { return(false); } else if (trackedSurface.TrackingState != TrackingState.Tracking) { overlaySurface.SetEnabled(false); return(true); } // enable the surface overlaySurface.SetEnabled(true); // estimate mesh vertices List <Vector3> meshVertices = new List <Vector3>(); // GetBoundaryPolygon returns points in clockwise order. trackedSurface.GetBoundaryPolygon(meshVertices); int verticeLength = meshVertices.Count; // surface position & rotation Vector3 surfacePos = trackedSurface.CenterPose.position; // Vector3.zero; // Quaternion surfaceRot = trackedSurface.CenterPose.rotation; // Quaternion.identity; // // estimate vertices relative to the center Quaternion invRot = Quaternion.Inverse(surfaceRot); for (int v = verticeLength - 1; v >= 0; v--) { meshVertices[v] -= surfacePos; meshVertices[v] = invRot * meshVertices[v]; if (Mathf.Abs(meshVertices[v].y) > 0.1f) { meshVertices.RemoveAt(v); } } // estimate mesh indices List <int> meshIndices = MultiARInterop.GetMeshIndices(meshVertices.Count); // update the surface mesh overlaySurface.UpdateSurfaceMesh(surfacePos, surfaceRot, meshVertices, meshIndices); return(true); }
// invoked by AnchorAdded-event private void PlaneAnchorAdded(ARPlaneAnchor arPlaneAnchor) { Debug.Log("Plane added: " + arPlaneAnchor.identifier); GameObject go = null; // if(arManager.displayTrackedSurfaces) // { // go = UnityARUtility.CreatePlaneInScene(arPlaneAnchor); // go.AddComponent<DontDestroyOnLoad>(); // these GOs persist across scene loads // } ARPlaneAnchorGameObject arpag = new ARPlaneAnchorGameObject(); arpag.planeAnchor = arPlaneAnchor; arpag.gameObject = go; planeAnchorDict.Add(arPlaneAnchor.identifier, arpag); trackedPlanesTimestamp = GetLastFrameTimestamp(); // create overlay surfaces as needed if (arManager.useOverlaySurface != MultiARManager.SurfaceRenderEnum.None) { // estimate the material Material surfaceMat = arManager.GetSurfaceMaterial(); int surfaceLayer = MultiARInterop.GetSurfaceLayer(); MultiARInterop.MultiARData arData = arManager.GetARData(); string surfId = arPlaneAnchor.identifier; if (!arData.dictOverlaySurfaces.ContainsKey(surfId)) { GameObject overlaySurfaceObj = new GameObject(); overlaySurfaceObj.name = "surface-" + surfId; overlaySurfaceObj.layer = surfaceLayer; overlaySurfaceObj.transform.SetParent(arData.surfaceRendererRoot ? arData.surfaceRendererRoot.transform : null); // GameObject overlayCubeObj = GameObject.CreatePrimitive(PrimitiveType.Cube); // overlayCubeObj.name = "surface-cube-" + surfId; // overlayCubeObj.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f); // overlayCubeObj.transform.SetParent(overlaySurfaceObj.transform); OverlaySurfaceUpdater overlaySurface = overlaySurfaceObj.AddComponent <OverlaySurfaceUpdater>(); overlaySurface.SetSurfaceMaterial(surfaceMat); overlaySurface.SetSurfaceCollider(arManager.surfaceCollider, arManager.colliderMaterial); arData.dictOverlaySurfaces.Add(surfId, overlaySurface); } // update the surface mesh UpdateOverlaySurface(arData.dictOverlaySurfaces[surfId], arPlaneAnchor); } }
/// <summary> /// Gets the currently tracked surfaces. /// </summary> /// <returns>The tracked surfaces.</returns> public MultiARInterop.TrackedSurface[] GetTrackedSurfaces(bool bGetPoints) { MultiARInterop.TrackedSurface[] trackedPlanes = new MultiARInterop.TrackedSurface[allTrackedPlanes.Count]; for (int i = 0; i < allTrackedPlanes.Count; i++) { DetectedPlane surface = allTrackedPlanes[i]; trackedPlanes[i] = new MultiARInterop.TrackedSurface(); trackedPlanes[i].position = surface.CenterPose.position; trackedPlanes[i].rotation = surface.CenterPose.rotation; trackedPlanes[i].bounds = new Vector3(surface.ExtentX, 0f, surface.ExtentZ); if (bGetPoints) { List <Vector3> alPoints = new List <Vector3>(); surface.GetBoundaryPolygon(alPoints); int vertexCount = alPoints.Count; Quaternion invRot = Quaternion.Inverse(surface.CenterPose.rotation); Vector3 centerPos = surface.CenterPose.position; for (int v = vertexCount - 1; v >= 0; v--) { alPoints[v] -= centerPos; alPoints[v] = invRot * alPoints[v]; if (Mathf.Abs(alPoints[v].y) > 0.1f) { alPoints.RemoveAt(v); } } // get mesh indices List <int> meshIndices = MultiARInterop.GetMeshIndices(vertexCount); trackedPlanes[i].points = alPoints.ToArray(); trackedPlanes[i].triangles = meshIndices.ToArray(); } } return(trackedPlanes); }
// sets the world position of the current model private bool SetModelWorldPos(Vector3 vNewPos, Quaternion qNewRot) { if (currentModel) { // set position and look at the camera currentModel.position = vNewPos; currentModel.rotation = qNewRot; if (modelLookingAtCamera) { Camera arCamera = arManager.GetMainCamera(); MultiARInterop.TurnObjectToCamera(currentModel.gameObject, arCamera, currentModel.position, currentModel.up); } return(true); } return(false); }
/// <summary> /// Raycasts from screen point or camera to the world. /// </summary> /// <returns><c>true</c>, if a plane was hit, <c>false</c> otherwise.</returns> /// <param name="screenPos">Screen position.</param> /// <param name="hit">Hit data.</param> public bool RaycastToWorld(bool fromInputPos, out MultiARInterop.TrackableHit hit) { hit = new MultiARInterop.TrackableHit(); if (!isInitialized || !mainCamera) { return(false); } // ray-cast Ray camRay = GetCameraRay(); hit.rayPos = camRay.origin; hit.rayDir = camRay.direction; int surfaceLayer = MultiARInterop.GetSurfaceLayer(); // LayerMask.NameToLayer("SpatialSurface"); //Debug.Log("SpatialSurfaceLayer: " + surfaceLayer); int layerMask = 1 << surfaceLayer; RaycastHit[] rayHits = Physics.RaycastAll(camRay, MultiARInterop.MAX_RAYCAST_DIST, layerMask); for (int i = 0; i < rayHits.Length; i++) { RaycastHit rayHit = rayHits[i]; // check for child of SpatialMappingCollider //if(rayHit.transform.GetComponentInParent<SpatialMappingCollider>() != null) if (rayHit.collider != null) { hit.point = rayHit.point; hit.normal = rayHit.normal; hit.distance = rayHit.distance; hit.rotation = Quaternion.FromToRotation(Vector3.up, rayHit.normal); hit.psObject = rayHit; //Debug.Log(string.Format("Hit {0} at position {1}.", rayHit.collider.gameObject, rayHit.point)); return(true); } } return(false); }
// checks if the input action ray-casts UI element or not private bool CheckForCanvasInputAction() { if (uiRaycasters != null && arInterface != null) { Vector2 inputPos = arInterface.GetInputScreenPos(false); foreach (UnityEngine.UI.GraphicRaycaster gr in uiRaycasters) { GameObject rayHit = MultiARInterop.RaycastUI(gr, inputPos); if (rayHit != null) { // check for UI text UnityEngine.UI.Text uiText = rayHit.gameObject.GetComponent <UnityEngine.UI.Text>(); return(uiText == null); } } } return(false); }
// saves the current screen shot public bool SaveScreenShot(string saveFilePath) { if (saveFilePath == string.Empty) { return(false); } MultiARManager marManager = MultiARManager.Instance; Texture2D texScreenshot = MultiARInterop.MakeScreenShot(marManager != null ? marManager.GetMainCamera() : null); if (texScreenshot) { byte[] btScreenShot = texScreenshot.EncodeToJPG(); GameObject.Destroy(texScreenshot); File.WriteAllBytes(saveFilePath, btScreenShot); return(true); } return(false); }
// initializes the AR-Core components private void InitArCore() { //Debug.Log("InitArCore started."); // disable the main camera, if any Camera currentCamera = MultiARInterop.GetMainCamera(); if (currentCamera) { currentCamera.gameObject.SetActive(false); } // create ARCore-Device in the scene arCoreDeviceObj = Instantiate(arCoreDevicePrefab, Vector3.zero, Quaternion.identity); arCoreDeviceObj.name = "ARCore Device"; DontDestroyOnLoad(arCoreDeviceObj); // get background material arCodeRenderer = FindObjectOfType <ARCoreBackgroundRenderer>(); if (arCodeRenderer) { backgroundMat = arCodeRenderer.BackgroundMaterial; } // update the session config, if needed ARCoreSession arSession = arCoreDeviceObj.GetComponent <ARCoreSession>(); if (arSession != null && arSession.SessionConfig != null && arImageDatabase != null) { arSession.SessionConfig.AugmentedImageDatabase = arImageDatabase; } // reference to the AR main camera mainCamera = arCoreDeviceObj.GetComponentInChildren <Camera>(); // // disable directional light, if any // Light currentLight = MultiARInterop.GetDirectionalLight(); // if(currentLight) // { // currentLight.gameObject.SetActive(false); // } // // // create AR environmental light // GameObject envLight = new GameObject("Evironmental Light"); // //envLight.transform.position = Vector3.zero; // //envLight.transform.rotation = Quaternion.identity; // envLight.AddComponent<EnvironmentalLight>(); // // // reference to the AR directional light // //directionalLight = envLight.GetComponent<Light>(); // modify the directional light Light currentLight = MultiARInterop.GetDirectionalLight(); if (!currentLight) { GameObject currentLightObj = new GameObject("Directional light"); currentLight = currentLightObj.AddComponent <Light>(); currentLight.type = LightType.Directional; } // reset light position & rotation currentLight.transform.position = Vector3.zero; currentLight.transform.rotation = Quaternion.Euler(40f, 40f, 0f); DontDestroyOnLoad(currentLight.gameObject); // set light parameters //currentLight.lightmapBakeType = LightmapBakeType.Mixed; currentLight.color = new Color32(255, 254, 244, 255); // add the ar-light component currentLight.gameObject.AddComponent <MultiARDirectionalLight>(); // get ar-data MultiARInterop.MultiARData arData = arManager ? arManager.GetARData() : null; if (arManager && arManager.usePointCloudData) { arData.pointCloudData = new Vector3[MultiARInterop.MAX_POINT_COUNT]; arData.pointCloudLength = 0; arData.pointCloudTimestamp = 0.0; } // create surface renderer if (arManager && arData != null) { arData.surfaceRendererRoot = new GameObject(); arData.surfaceRendererRoot.name = "SurfaceRenderer"; DontDestroyOnLoad(arData.surfaceRendererRoot); } // interface is initialized isInitialized = true; //Debug.Log("InitArCore finished."); }
void Update() { if (arInterface != null) { // get last frame timestamp and tracking state lastFrameTimestamp = arInterface.GetLastFrameTimestamp(); cameraTrackingState = arInterface.GetCameraTrackingState(); } // show the tracking state if (infoText) { int numSurfaces = GetTrackedSurfacesCount(); int numAnchors = GetAnchorsCount(); int numObjects = GetAnchoredObjectsCount(); infoText.text = "Tracker: " + arInterface.GetCameraTrackingState() + " " + arInterface.GetTrackingErrorMessage() + string.Format("\nLight: {0:F3}", arInterface.GetLightIntensity()) + ", Surfaces: " + numSurfaces + ", Anchors: " + numAnchors + ", Objects: " + numObjects; //+ "\nTimestamp: " + lastFrameTimestamp.ToString(); } // check the tracking state if (arInterface == null || cameraTrackingState != MultiARInterop.CameraTrackingState.NormalTracking) { const int LOST_TRACKING_SLEEP_TIMEOUT = 15; Screen.sleepTimeout = LOST_TRACKING_SLEEP_TIMEOUT; //return; } else { // normal trackin Screen.sleepTimeout = SleepTimeout.NeverSleep; } // display the point cloud if (pointCloudPrefab && arData.pointCloudTimestamp > lastPointCloudTimestamp) { lastPointCloudTimestamp = arData.pointCloudTimestamp; int pointCloudLen = arData.pointCloudLength < MultiARInterop.MAX_POINT_COUNT ? arData.pointCloudLength : MultiARInterop.MAX_POINT_COUNT; int[] indices = new int[pointCloudLen]; for (int i = 0; i < pointCloudLen; i++) { indices[i] = i; } pointCloudMesh.Clear(); pointCloudMesh.vertices = arData.pointCloudData; pointCloudMesh.SetIndices(indices, MeshTopology.Points, 0, false); } // show cursor if needed if (cursorObject && showCursor != ShowCursorEnum.Never) { MultiARInterop.TrackableHit hit; hit.point = Vector3.zero; // check how to raycast bool isFromInputPos = IsInputAvailable(false); if (showCursor == ShowCursorEnum.OnSurfacesOnly) { RaycastToWorld(isFromInputPos, out hit); } else { if (!RaycastToScene(isFromInputPos, out hit)) { RaycastToWorld(isFromInputPos, out hit); } } // if (infoText) // { // string hitObjName = string.Empty; // if (hit.psObject != null) // { // if (hit.psObject is RaycastHit) // hitObjName = ((RaycastHit)hit.psObject).transform.gameObject.name; // else // hitObjName = hit.psObject.ToString(); // } // // infoText.text += "\ninputPos: " + isFromInputPos + ", hit: " + hit.point + ", obj: " + hitObjName; // } if (showCursor == ShowCursorEnum.Always || hit.point != Vector3.zero) { MultiARInterop.ShowCursor(cursorObject, hit, 0.03f, 2f, 50f); } } }
void Update() { // check for click if (objectPrefab && arManager && arManager.IsInitialized() && arManager.IsInputAvailable(true)) { MultiARInterop.InputAction action = arManager.GetInputAction(); if (action == MultiARInterop.InputAction.Click && (Time.time - lastInstanceTime) >= 1.5f) { // dont allow too often instance creation lastInstanceTime = Time.time; // remove current object, if any if (objectInstance) { DestroyObjectInstance(); } // raycast world MultiARInterop.TrackableHit hit; if (arManager.RaycastToWorld(true, out hit)) { // instantiate the object and anchor it to the world position objectInstance = Instantiate(objectPrefab, hit.point, !verticalModel ? hit.rotation : Quaternion.identity); arManager.AnchorGameObjectToWorld(objectInstance, hit); // get object renderer & initial scale objectRenderer = GetObjectRenderer(objectInstance); objectScale = objectInstance.transform.localScale; // look at the camera if (modelLookingAtCamera) { Camera arCamera = arManager.GetMainCamera(); MultiARInterop.TurnObjectToCamera(objectInstance, arCamera, hit.point, hit.normal); } if (infoText) { infoText.text = string.Format("{0} placed at {1}", objectPrefab.name, hit.point); } } } else if (objectInstance && action == MultiARInterop.InputAction.Grip) { // get nav coordinates Vector3 navCoords = arManager.GetInputNavCoordinates(); lastInstanceTime = Time.time; // estimate the scale change and target scale Vector3 scaleChange = navCoords.x >= 0 ? (objectScale * navCoords.x) : ((objectScale / 2f) * navCoords.x); targetScale = objectScale + scaleChange; objectInstance.transform.localScale = Vector3.Lerp(objectInstance.transform.localScale, targetScale, smoothFactor * Time.deltaTime); if (infoText) { float fScaleChange = 1f + (navCoords.x >= 0 ? navCoords.x : (0.5f * navCoords.x)); infoText.text = string.Format("Scale change: {0:F2}", fScaleChange); } // outline object bounds if (objectRenderer && boundsPrefab) { Bounds objectBounds = objectRenderer.bounds; // instantiate bounds-cube, if needed if (boundsInstance == null) { boundsInstance = GameObject.Instantiate(boundsPrefab); boundsInstance.transform.SetParent(objectInstance.transform); } // set the bounds-cube tras=nsform boundsInstance.transform.position = objectBounds.center; boundsInstance.transform.rotation = objectInstance.transform.rotation; Vector3 objScale = objectInstance.transform.localScale; Vector3 boundsScale = new Vector3(objectBounds.size.x / objScale.x, objectBounds.size.y / objScale.y, objectBounds.size.z / objScale.z); boundsInstance.transform.localScale = boundsScale; } } else if (action == MultiARInterop.InputAction.Release) { // instantiate bounds-cube, if needed if (boundsInstance != null) { Destroy(boundsInstance); boundsInstance = null; } if (infoText) { infoText.text = "Tap to place the object, then drag right or left, to scale it up or down."; } } } }
// Update is called once per frame void Update() { // check for tap if (portalPrefab && arManager && arManager.IsInitialized() && arManager.IsInputAvailable(true)) { MultiARInterop.InputAction action = arManager.GetInputAction(); if (action == MultiARInterop.InputAction.Click) { // raycast to world MultiARInterop.TrackableHit hit; if (arManager.RaycastToWorld(true, out hit)) { // create the portal object, if needed if (!portalObj) { portalObj = Instantiate(portalPrefab); } // set its position and rotation portalObj.transform.position = hit.point; portalObj.transform.rotation = !verticalPortal ? hit.rotation : Quaternion.identity; // look at the camera if (portalLookingAtCamera) { Camera arCamera = arManager.GetMainCamera(); MultiARInterop.TurnObjectToCamera(portalObj, arCamera, hit.point, hit.normal); } // remove object anchor, if it was anchored before string anchorId = arManager.GetObjectAnchorId(portalObj); if (anchorId != string.Empty) { arManager.RemoveGameObjectAnchor(anchorId, true); } // anchor it to the new world position arManager.AnchorGameObjectToWorld(portalObj, hit); // apply the vertical offset if (verticalOffset != 0f) { Vector3 objPos = portalObj.transform.position; //objPos.y += verticalOffset; objPos += portalObj.transform.up * verticalOffset; portalObj.transform.position = objPos; } // play portal-open animation if (playAnimation != string.Empty) { // get reference to the portal animator if (!animator) { animator = portalObj.GetComponent <Animator>(); } if (animator) { animator.Play(playAnimation, 0, 0f); } } // create camera rigidbody (no gravity) & box-collider, if needed if (cameraBoxCollider != Vector3.zero) { Camera arCamera = arManager.GetMainCamera(); Rigidbody camRigidbody = arCamera.gameObject.GetComponent <Rigidbody>(); if (camRigidbody == null) { camRigidbody = arCamera.gameObject.AddComponent <Rigidbody>(); camRigidbody.useGravity = false; } BoxCollider camBoxCollider = arCamera.gameObject.GetComponent <BoxCollider>(); if (camBoxCollider == null) { camBoxCollider = arCamera.gameObject.AddComponent <BoxCollider>(); camBoxCollider.size = cameraBoxCollider; camBoxCollider.isTrigger = true; } } } } } }
// -- // -- // -- // -- // -- // -- // -- // -- // -- // -- // void Start() { if (!isInterfaceEnabled) { return; } // determine if display is opaque or transparent isDisplayOpaque = HolographicSettings.IsDisplayOpaque; Debug.Log("Display: " + (isDisplayOpaque ? "Opaque" : "Transparent")); // modify the main camera in the scene Camera currentCamera = MultiARInterop.GetMainCamera(); if (!currentCamera) { GameObject currentCameraObj = new GameObject("Main Camera"); currentCameraObj.tag = "MainCamera"; currentCamera = currentCameraObj.AddComponent <Camera>(); } // reset camera position & rotation //currentCamera.transform.position = Vector3.zero; currentCamera.transform.rotation = Quaternion.identity; // set camera parameters currentCamera.clearFlags = CameraClearFlags.SolidColor; currentCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); currentCamera.nearClipPlane = 0.5f; // HoloLens recommended currentCamera.farClipPlane = 100f; if (isDisplayOpaque) { currentCamera.clearFlags = CameraClearFlags.Skybox; } // set the fastest quality setting QualitySettings.SetQualityLevel((int)qualityLevel); Debug.Log("QualityLevel: " + QualitySettings.names[(int)qualityLevel]); // reference to the AR main camera mainCamera = currentCamera; // don't destroy the light between scenes DontDestroyOnLoad(currentCamera.gameObject); // // add camera parent // if(currentCamera.transform.parent == null) // { // GameObject cameraParent = new GameObject("CameraParent"); // currentCamera.transform.SetParent(cameraParent.transform); // } // modify the directional light Light currentLight = MultiARInterop.GetDirectionalLight(); if (!currentLight) { GameObject currentLightObj = new GameObject("Directional light"); currentLight = currentLightObj.AddComponent <Light>(); currentLight.type = LightType.Directional; } // reset light position & rotation currentLight.transform.position = Vector3.zero; currentLight.transform.rotation = Quaternion.Euler(40f, 40f, 0f); // set light parameters currentLight.color = new Color32(255, 254, 244, 255); // add the ar-light component //currentLight.gameObject.AddComponent<MultiARDirectionalLight>(); // reference to the AR directional light //directionalLight = currentLight; // don't destroy the light between scenes DontDestroyOnLoad(currentLight.gameObject); // there is no point cloud in WinMR MultiARInterop.MultiARData arData = arManager.GetARData(); // check for point cloud getter if (arManager.pointCloudPrefab != null) { arData.pointCloudData = new Vector3[0]; arData.pointCloudLength = 0; arData.pointCloudTimestamp = 0.0; } // set tracking state cameraTrackingState = WorldManager.state; WorldManager.OnPositionalLocatorStateChanged += WorldManager_OnPositionalLocatorStateChanged; // // set tracking space type // Debug.Log("Before: " + XRDevice.GetTrackingSpaceType()); // if(XRDevice.GetTrackingSpaceType() != TrackingSpaceType.Stationary) // { // if(!XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary)) // { // Debug.LogError("Cannot set stationary space type!"); // } // } // create gesture input if (!isDisplayOpaque) { gestureRecognizer = new GestureRecognizer(); gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.Hold | GestureSettings.NavigationX | GestureSettings.NavigationY | GestureSettings.NavigationZ); gestureRecognizer.Tapped += GestureRecognizer_Tapped; // gestureRecognizer.HoldStarted += GestureRecognizer_HoldStarted; // gestureRecognizer.HoldCompleted += GestureRecognizer_HoldCompleted; // gestureRecognizer.HoldCanceled += GestureRecognizer_HoldCanceled; gestureRecognizer.NavigationStarted += GestureRecognizer_NavigationStarted; gestureRecognizer.NavigationUpdated += GestureRecognizer_NavigationUpdated; gestureRecognizer.NavigationCompleted += GestureRecognizer_NavigationCompleted; gestureRecognizer.NavigationCanceled += GestureRecognizer_NavigationCanceled; gestureRecognizer.StartCapturingGestures(); Debug.Log("Gesture recognizer inited and started."); } //else { // init interaction manager // InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed; // InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated; // InteractionManager.InteractionSourceReleased += InteractionManager_InteractionSourceReleased; InteractionManager.InteractionSourceDetected += InteractionManager_InteractionSourceDetected; InteractionManager.InteractionSourceLost += InteractionManager_InteractionSourceLost; InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated; Debug.Log("Interaction manager inited."); } // create surface renderer if (arManager.useOverlaySurface != MultiARManager.SurfaceRenderEnum.None) { GameObject objRenderer = new GameObject(); objRenderer.name = "SurfaceRenderer"; objRenderer.layer = MultiARInterop.GetSurfaceLayer(); arData.surfaceRendererRoot = objRenderer; surfaceRootTransform = objRenderer.transform; DontDestroyOnLoad(objRenderer); if (!isDisplayOpaque) { // hololens surfaceRenderer = objRenderer.AddComponent <SpatialMappingRenderer>(); surfaceRenderer.surfaceParent = objRenderer; switch (arManager.useOverlaySurface) { case MultiARManager.SurfaceRenderEnum.None: surfaceRenderer.renderState = SpatialMappingRenderer.RenderState.None; break; case MultiARManager.SurfaceRenderEnum.Visualization: surfaceRenderer.renderState = SpatialMappingRenderer.RenderState.Visualization; break; case MultiARManager.SurfaceRenderEnum.Occlusion: case MultiARManager.SurfaceRenderEnum.OcclusionWithShadows: surfaceRenderer.renderState = SpatialMappingRenderer.RenderState.Occlusion; break; } if (arManager.useOverlaySurface != MultiARManager.SurfaceRenderEnum.None) { surfaceRenderer.visualMaterial = arManager.surfaceVisualizationMaterial; surfaceRenderer.occlusionMaterial = arManager.useOverlaySurface == MultiARManager.SurfaceRenderEnum.OcclusionWithShadows ? arManager.surfaceOcclusionWithShadowsMaterial : arManager.surfaceOcclusionMaterial; } } else { // use special surface material on opaque displays Material visualMaterial = arManager.GetSurfaceMaterial(); if (arManager.useOverlaySurface == MultiARManager.SurfaceRenderEnum.Visualization && vrSurfaceMaterial) { visualMaterial = vrSurfaceMaterial; } // mr headsets CreateBoundaryPlane(objRenderer.transform, visualMaterial, arManager.surfaceCollider, arManager.colliderMaterial); boundaryMgr = objRenderer.AddComponent <HoloToolkit.Unity.Boundary.BoundaryManager>(); boundaryMgr.FloorQuad = boundaryPlane; boundaryMgr.AwakeBoundaryManager(); } } // create surface collider if (arManager.surfaceCollider) { GameObject objCollider = new GameObject(); objCollider.name = "SurfaceCollider"; objCollider.layer = MultiARInterop.GetSurfaceLayer(); DontDestroyOnLoad(objCollider); if (!isDisplayOpaque) { // hololens surfaceCollider = objCollider.AddComponent <SpatialMappingCollider>(); surfaceCollider.surfaceParent = objCollider; surfaceCollider.lodType = SpatialMappingBase.LODType.Low; surfaceCollider.layer = MultiARInterop.GetSurfaceLayer(); if (arManager.colliderMaterial) { surfaceCollider.material = arManager.colliderMaterial; } } else { // mr headsets if (boundaryPlane == null) { // there was no boundary rendering CreateBoundaryPlane(objCollider.transform, null, true, arManager.colliderMaterial); boundaryMgr = objCollider.AddComponent <HoloToolkit.Unity.Boundary.BoundaryManager>(); boundaryMgr.FloorQuad = boundaryPlane; boundaryMgr.AwakeBoundaryManager(); } } } // // if camera is too near to the floor, lower the floor 1.5 meter below the camera // if(currentCamera && boundaryMgr) // { // if(currentCamera.transform.position.y < 0.1f) // { // boundaryMgr.CurrentFloorHeightOffset = currentCamera.transform.position.y - 1.5f; // Debug.Log(string.Format("FloorHeightOffset set below the camera at {0:F2}m.", boundaryMgr.CurrentFloorHeightOffset)); // } // } // starts co-routine to check rendered surfaces StartCoroutine(CheckSurfacesRoutine()); Debug.Log("TrackingSpaceType: " + XRDevice.GetTrackingSpaceType()); Debug.Log("Screen size: " + Screen.width + " x " + Screen.height); int surfaceLayer = MultiARInterop.GetSurfaceLayer(); // LayerMask.NameToLayer("SpatialSurface"); Debug.Log("SpatialSurfaceLayer: " + surfaceLayer); // interface is initialized isInitialized = true; }
void Update() { if (!isInitialized) { return; } // check for errors _QuitOnConnectionErrors(); // check for input (touch) CheckForInputAction(); // estimate the tracking state SessionStatus status = Session.Status; if (status.IsError() || status.IsNotInitialized()) { cameraTrackingState = TrackingState.Stopped; return; } else if (status == SessionStatus.Tracking) { cameraTrackingState = TrackingState.Tracking; } else { cameraTrackingState = TrackingState.Paused; } // get frame timestamp and light intensity lastFrameTimestamp = GetCurrentTimestamp(); if (Frame.LightEstimate.State == LightEstimateState.Valid) { // Normalize pixel intensity by middle gray in gamma space. const float middleGray = 0.466f; currentLightIntensity = Frame.LightEstimate.PixelIntensity / middleGray; } // get point cloud, if needed MultiARInterop.MultiARData arData = arManager.GetARData(); if (arManager.usePointCloudData) { if (Frame.PointCloud.PointCount > 0 && Frame.PointCloud.IsUpdatedThisFrame) { // Copy the point cloud points for (int i = 0; i < Frame.PointCloud.PointCount; i++) { PointCloudPoint point = Frame.PointCloud.GetPointAsStruct(i); arData.pointCloudData[i] = new Vector3(point.Position.x, point.Position.y, point.Position.z); } arData.pointCloudLength = Frame.PointCloud.PointCount; arData.pointCloudTimestamp = lastFrameTimestamp; } } // // display the tracked planes if needed // if(arManager.displayTrackedSurfaces && trackedPlanePrefab) // { // // get the new planes // Frame.GetNewPlanes(ref newTrackedPlanes); // // // Iterate over planes found in this frame and instantiate corresponding GameObjects to visualize them. // for (int i = 0; i < newTrackedPlanes.Count; i++) // { // // Instantiate a plane visualization prefab and set it to track the new plane. // GameObject planeObject = Instantiate(trackedPlanePrefab, Vector3.zero, Quaternion.identity); // planeObject.GetComponent<GoogleARCore.HelloAR.TrackedPlaneVisualizer>().SetTrackedPlane(newTrackedPlanes[i]); // // // Apply a random color and grid rotation. // planeObject.GetComponent<Renderer>().material.SetColor("_GridColor", planeColors[Random.Range(0, planeColors.Length - 1)]); // planeObject.GetComponent<Renderer>().material.SetFloat("_UvRotation", Random.Range(0.0f, 360.0f)); // } // } // get all tracked planes Session.GetTrackables <DetectedPlane>(allTrackedPlanes, TrackableQueryFilter.All); // create overlay surfaces as needed if (arManager.useOverlaySurface != MultiARManager.SurfaceRenderEnum.None) { alSurfacesToDelete.Clear(); alSurfacesToDelete.AddRange(arData.dictOverlaySurfaces.Keys); // estimate the material Material surfaceMat = arManager.GetSurfaceMaterial(); int surfaceLayer = MultiARInterop.GetSurfaceLayer(); for (int i = 0; i < allTrackedPlanes.Count; i++) { string surfId = allTrackedPlanes[i].m_TrackableNativeHandle.ToString(); if (!arData.dictOverlaySurfaces.ContainsKey(surfId)) { GameObject overlaySurfaceObj = new GameObject(); overlaySurfaceObj.name = "surface-" + surfId; overlaySurfaceObj.layer = surfaceLayer; overlaySurfaceObj.transform.SetParent(arData.surfaceRendererRoot ? arData.surfaceRendererRoot.transform : null); // GameObject overlayCubeObj = GameObject.CreatePrimitive(PrimitiveType.Cube); // overlayCubeObj.name = "surface-cube-" + surfId; // overlayCubeObj.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f); // overlayCubeObj.transform.SetParent(overlaySurfaceObj.transform); OverlaySurfaceUpdater overlaySurface = overlaySurfaceObj.AddComponent <OverlaySurfaceUpdater>(); overlaySurface.SetSurfaceMaterial(surfaceMat); overlaySurface.SetSurfaceCollider(arManager.surfaceCollider, arManager.colliderMaterial); arData.dictOverlaySurfaces.Add(surfId, overlaySurface); } // update the surface mesh bool bValidSurface = UpdateOverlaySurface(arData.dictOverlaySurfaces[surfId], allTrackedPlanes[i]); if (bValidSurface && alSurfacesToDelete.Contains(surfId)) { alSurfacesToDelete.Remove(surfId); } } // delete not tracked surfaces foreach (string surfId in alSurfacesToDelete) { OverlaySurfaceUpdater overlaySurface = arData.dictOverlaySurfaces[surfId]; arData.dictOverlaySurfaces.Remove(surfId); Destroy(overlaySurface.gameObject); } } // check status of the anchors List <string> alAnchorsToRemove = new List <string>(); foreach (string anchorId in arData.allAnchorsDict.Keys) { List <GameObject> anchoredObjs = arData.allAnchorsDict[anchorId]; foreach (GameObject anchoredObj in anchoredObjs) { Transform parentTrans = anchoredObj.transform.parent; if (parentTrans == null) { if (!alAnchorsToRemove.Contains(anchorId)) { alAnchorsToRemove.Add(anchorId); } anchoredObj.SetActive(false); } else { Anchor anchor = parentTrans.GetComponent <Anchor>(); if (anchor == null || anchor.TrackingState == TrackingState.Stopped) { if (!alAnchorsToRemove.Contains(anchorId)) { alAnchorsToRemove.Add(anchorId); } anchoredObj.transform.parent = null; anchoredObj.SetActive(false); } } } } // remove the stopped anchors from our list foreach (string anchorId in alAnchorsToRemove) { arData.allAnchorsDict.Remove(anchorId); } // clean up alAnchorsToRemove.Clear(); // look for image anchors, if enabled if (arData.imageAnchorsEnabled) { // Get updated augmented images for this frame. Session.GetTrackables <AugmentedImage>(alTrackedAugmentedImages, TrackableQueryFilter.Updated); foreach (var image in alTrackedAugmentedImages) { string sImageName = image.Name; bool wasImageTracked = dictImageAnchors.ContainsKey(sImageName); if (!wasImageTracked && image.TrackingState == TrackingState.Tracking) { // Create an anchor to ensure that ARCore keeps tracking this augmented image. Anchor anchor = image.CreateAnchor(image.CenterPose); anchor.gameObject.name = "ImageAnchor-" + sImageName; DontDestroyOnLoad(anchor.gameObject); alImageAnchorNames.Add(sImageName); dictImageAnchors.Add(sImageName, anchor.gameObject); } else if (wasImageTracked && image.TrackingState == TrackingState.Stopped) { // remove the anchor GameObject anchorObj = dictImageAnchors[sImageName]; alImageAnchorNames.Remove(sImageName); dictImageAnchors.Remove(sImageName); GameObject.Destroy(anchorObj); } } } }
// -- // -- // -- // -- // -- // -- // -- // -- // -- // -- // void Start() { if (!isInterfaceEnabled) { return; } if (!yuvMaterial) { Debug.LogError("ARKit-interface cannot start: YuvMaterial is not set."); return; } // modify the main camera in the scene Camera currentCamera = MultiARInterop.GetMainCamera(); if (!currentCamera) { GameObject currentCameraObj = new GameObject("Main Camera"); currentCameraObj.tag = "MainCamera"; currentCamera = currentCameraObj.AddComponent <Camera>(); } // reset camera position & rotation currentCamera.transform.position = Vector3.zero; currentCamera.transform.rotation = Quaternion.identity; // set camera parameters currentCamera.clearFlags = CameraClearFlags.Depth; currentCamera.nearClipPlane = 0.1f; currentCamera.farClipPlane = 30f; // reference to the AR main camera mainCamera = currentCamera; // add camera parent if (currentCamera.transform.parent == null) { GameObject cameraParent = new GameObject("CameraParent"); currentCamera.transform.SetParent(cameraParent.transform); DontDestroyOnLoad(cameraParent); } else { DontDestroyOnLoad(currentCamera.transform.root.gameObject); } // add the needed camera components arVideoRenderer = currentCamera.gameObject.AddComponent <UnityARVideo>(); arVideoRenderer.m_ClearMaterial = yuvMaterial; backgroundMat = yuvMaterial; currentCamera.gameObject.AddComponent <UnityARCameraNearFar>(); // modify the directional light Light currentLight = MultiARInterop.GetDirectionalLight(); if (!currentLight) { GameObject currentLightObj = new GameObject("Directional light"); currentLight = currentLightObj.AddComponent <Light>(); currentLight.type = LightType.Directional; } // reset light position & rotation currentLight.transform.position = Vector3.zero; currentLight.transform.rotation = Quaternion.Euler(40f, 40f, 0f); DontDestroyOnLoad(currentLight.gameObject); // set light parameters //currentLight.lightmapBakeType = LightmapBakeType.Mixed; currentLight.color = new Color32(255, 254, 244, 255); // add the ar-light component currentLight.gameObject.AddComponent <MultiARDirectionalLight>(); // reference to the AR directional light //directionalLight = currentLight; // create camera manager GameObject camManagerObj = new GameObject("ARCameraManager"); DontDestroyOnLoad(camManagerObj); UnityARCameraManager camManager = camManagerObj.AddComponent <UnityARCameraManager>(); camManager.m_camera = currentCamera; camManager.startAlignment = cameraAlignment; camManager.planeDetection = UnityARPlaneDetection.HorizontalAndVertical; //Debug.Log("arImageDatabase: " + (arImageDatabase != null ? arImageDatabase.resourceGroupName : "-")); if (arImageDatabase != null) { camManager.detectionImages = arImageDatabase; Debug.Log("camManager.detectionImages set to: " + arImageDatabase); } // allow relocalization after session interruption UnityARSessionNativeInterface.ARSessionShouldAttemptRelocalization = true; // get ar-data MultiARInterop.MultiARData arData = arManager ? arManager.GetARData() : null; // check for point cloud getter if (arManager && arManager.pointCloudPrefab != null) { arData.pointCloudData = new Vector3[0]; arData.pointCloudLength = 0; arData.pointCloudTimestamp = 0.0; } // create surface renderer if (arManager && arData != null) { arData.surfaceRendererRoot = new GameObject(); arData.surfaceRendererRoot.name = "SurfaceRenderer"; DontDestroyOnLoad(arData.surfaceRendererRoot); } // // check for tracked plane display // if(arManager.displayTrackedSurfaces && trackedPlanePrefab) // { // UnityARUtility.InitializePlanePrefab(trackedPlanePrefab); // } // add needed events UnityARSessionNativeInterface.ARFrameUpdatedEvent += ARFrameUpdated; UnityARSessionNativeInterface.ARSessionTrackingChangedEvent += ARSessionTrackingChanged; UnityARSessionNativeInterface.ARAnchorAddedEvent += PlaneAnchorAdded; UnityARSessionNativeInterface.ARAnchorUpdatedEvent += PlaneAnchorUpdated; UnityARSessionNativeInterface.ARAnchorRemovedEvent += PlaneAnchorRemoved; UnityARSessionNativeInterface.ARUserAnchorAddedEvent += UserAnchorAdded; UnityARSessionNativeInterface.ARUserAnchorRemovedEvent += UserAnchorRemoved; // create ARCoreSession component, if the cloud functionality is used GoogleARCore.ARCoreSession arCoreSession = gameObject.GetComponent <GoogleARCore.ARCoreSession>(); if (arCoreSession == null) { TextAsset cloudApiKey = Resources.Load("RuntimeSettings/CloudServicesApiKey") as TextAsset; if (cloudApiKey != null) { arCoreSession = gameObject.AddComponent <GoogleARCore.ARCoreSession>(); } } // interface is initialized isInitialized = true; }
// -- // -- // -- // -- // -- // -- // -- // -- // -- // -- // void Start() { if (!isInterfaceEnabled) { return; } if (!metaCameraRigPrefab) { Debug.LogError("Meta2-interface cannot start: MetaCameraRig-prefab is not set."); return; } // disable the main camera, if any Camera currentCamera = MultiARInterop.GetMainCamera(); if (currentCamera) { currentCamera.gameObject.SetActive(false); } // create ARCore-Device in the scene GameObject arCoreDeviceObj = Instantiate(metaCameraRigPrefab, Vector3.zero, Quaternion.identity); arCoreDeviceObj.name = "ARCore Device"; DontDestroyOnLoad(arCoreDeviceObj); // reference to the AR main camera mainCamera = arCoreDeviceObj.GetComponentInChildren <Camera>(); // // add camera parent // if(currentCamera.transform.parent == null) // { // GameObject cameraParent = new GameObject("CameraParent"); // currentCamera.transform.SetParent(cameraParent.transform); // } // modify the directional light Light currentLight = MultiARInterop.GetDirectionalLight(); if (!currentLight) { GameObject currentLightObj = new GameObject("Directional light"); currentLight = currentLightObj.AddComponent <Light>(); currentLight.type = LightType.Directional; } // reset light position & rotation currentLight.transform.position = Vector3.zero; currentLight.transform.rotation = Quaternion.Euler(40f, 40f, 0f); // set light parameters currentLight.color = new Color32(255, 254, 244, 255); // add the ar-light component //currentLight.gameObject.AddComponent<MultiARDirectionalLight>(); // reference to the AR directional light //directionalLight = currentLight; // don't destroy the light between scenes DontDestroyOnLoad(currentLight.gameObject); // there is no point cloud in WinMR MultiARInterop.MultiARData arData = arManager.GetARData(); // check for point cloud getter if (arManager.pointCloudPrefab != null) { arData.pointCloudData = new Vector3[0]; arData.pointCloudLength = 0; arData.pointCloudTimestamp = 0.0; } // set tracking state cameraTrackingState = WorldManager.state; WorldManager.OnPositionalLocatorStateChanged += WorldManager_OnPositionalLocatorStateChanged; // // set tracking space type // Debug.Log("Before: " + XRDevice.GetTrackingSpaceType()); // if(XRDevice.GetTrackingSpaceType() != TrackingSpaceType.Stationary) // { // if(!XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary)) // { // Debug.LogError("Cannot set stationary space type!"); // } // } // create gesture input if (!isDisplayOpaque) { gestureRecognizer = new GestureRecognizer(); gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.Hold | GestureSettings.NavigationX | GestureSettings.NavigationY | GestureSettings.NavigationZ); gestureRecognizer.Tapped += GestureRecognizer_Tapped; // gestureRecognizer.HoldStarted += GestureRecognizer_HoldStarted; // gestureRecognizer.HoldCompleted += GestureRecognizer_HoldCompleted; // gestureRecognizer.HoldCanceled += GestureRecognizer_HoldCanceled; gestureRecognizer.NavigationStarted += GestureRecognizer_NavigationStarted; gestureRecognizer.NavigationUpdated += GestureRecognizer_NavigationUpdated; gestureRecognizer.NavigationCompleted += GestureRecognizer_NavigationCompleted; gestureRecognizer.NavigationCanceled += GestureRecognizer_NavigationCanceled; gestureRecognizer.StartCapturingGestures(); Debug.Log("Gesture recognizer inited and started."); } else { InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed; InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated; InteractionManager.InteractionSourceReleased += InteractionManager_InteractionSourceReleased; Debug.Log("Interaction manager inited."); } // create surface renderer if (arManager.useOverlaySurface != MultiARManager.SurfaceRenderEnum.None) { GameObject objRenderer = new GameObject(); objRenderer.name = "SurfaceRenderer"; objRenderer.layer = MultiARInterop.GetSurfaceLayer(); arData.surfaceRendererRoot = objRenderer; surfaceRootTransform = objRenderer.transform; DontDestroyOnLoad(objRenderer); if (!isDisplayOpaque) { // hololens surfaceRenderer = objRenderer.AddComponent <SpatialMappingRenderer>(); surfaceRenderer.surfaceParent = objRenderer; surfaceRenderer.renderState = (SpatialMappingRenderer.RenderState)arManager.useOverlaySurface; if (arManager.useOverlaySurface != MultiARManager.SurfaceRenderEnum.None) { surfaceRenderer.visualMaterial = arManager.surfaceVisualizationMaterial; surfaceRenderer.occlusionMaterial = arManager.surfaceOcclusionMaterial; } } else { // mr headsets CreateBoundaryPlane(objRenderer.transform, arManager.GetSurfaceMaterial(), arManager.surfaceCollider, arManager.colliderMaterial); boundaryMgr = objRenderer.AddComponent <HoloToolkit.Unity.Boundary.BoundaryManager>(); boundaryMgr.FloorQuad = boundaryPlane; boundaryMgr.AwakeBoundaryManager(); } } // create surface collider if (arManager.surfaceCollider) { GameObject objCollider = new GameObject(); objCollider.name = "SurfaceCollider"; objCollider.layer = MultiARInterop.GetSurfaceLayer(); DontDestroyOnLoad(objCollider); if (!isDisplayOpaque) { // hololens surfaceCollider = objCollider.AddComponent <SpatialMappingCollider>(); surfaceCollider.surfaceParent = objCollider; surfaceCollider.lodType = SpatialMappingBase.LODType.Low; surfaceCollider.layer = MultiARInterop.GetSurfaceLayer(); if (arManager.colliderMaterial) { surfaceCollider.material = arManager.colliderMaterial; } } else { // mr headsets if (boundaryPlane == null) { // there was no boundary rendering CreateBoundaryPlane(objCollider.transform, null, true, arManager.colliderMaterial); boundaryMgr = objCollider.AddComponent <HoloToolkit.Unity.Boundary.BoundaryManager>(); boundaryMgr.FloorQuad = boundaryPlane; boundaryMgr.AwakeBoundaryManager(); } } } // // if camera is too near to the floor, lower the floor 1.5 meter below the camera // if(currentCamera && boundaryMgr) // { // if(currentCamera.transform.position.y < 0.1f) // { // boundaryMgr.CurrentFloorHeightOffset = currentCamera.transform.position.y - 1.5f; // Debug.Log(string.Format("FloorHeightOffset set below the camera at {0:F2}m.", boundaryMgr.CurrentFloorHeightOffset)); // } // } // starts co-routine to check rendered surfaces StartCoroutine(CheckSurfacesRoutine()); Debug.Log("TrackingSpaceType: " + XRDevice.GetTrackingSpaceType()); Debug.Log("Screen size: " + Screen.width + " x " + Screen.height); int surfaceLayer = MultiARInterop.GetSurfaceLayer(); // LayerMask.NameToLayer("SpatialSurface"); Debug.Log("SpatialSurfaceLayer: " + surfaceLayer); // interface is initialized isInitialized = true; }