// 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);
        }
    }
Esempio n. 2
0
    /// <summary>
    /// Updates existing overlay surfaces with the currently selected material and collider.
    /// </summary>
    public void UpdateOverlaySurfaces()
    {
        // get current material
        Material surfaceMat = GetSurfaceMaterial();

        foreach (string sKey in arData.dictOverlaySurfaces.Keys)
        {
            OverlaySurfaceUpdater surface = arData.dictOverlaySurfaces[sKey];

            MeshRenderer meshRenderer = surface.gameObject.GetComponent <MeshRenderer>();
            MeshCollider meshCollider = surface.gameObject.GetComponent <MeshCollider>();

            // surface renderer
            if (surfaceMat != null)
            {
                if (meshRenderer != null && !meshRenderer.enabled)
                {
                    meshRenderer.enabled = true;
                }

                surface.SetSurfaceMaterial(surfaceMat);
            }
            else
            {
                if (meshRenderer != null && meshRenderer.enabled)
                {
                    meshRenderer.enabled = false;
                }
            }

            // surface collider
            if (surfaceCollider)
            {
                if (meshCollider != null && !meshCollider.enabled)
                {
                    meshCollider.enabled = true;
                }

                surface.SetSurfaceCollider(surfaceCollider, colliderMaterial);
            }
            else
            {
                if (meshCollider != null && meshCollider.enabled)
                {
                    meshCollider.enabled = false;
                }
            }
        }
    }
    // loads AR scene and the detected surfaces
    public JsonArScene LoadArScene(string dataFilePath)
    {
        if (!File.Exists(dataFilePath))
        {
            return(null);
        }

        // load json
        string      sJsonText = File.ReadAllText(dataFilePath);
        JsonArScene data      = JsonUtility.FromJson <JsonArScene>(sJsonText);

        if (data != null)
        {
            if (useSavedHeading)
            {
                startHeading = data.startHeading;
            }

            Quaternion compStartRot = Quaternion.Euler(0f, -startHeading, 0f);

            if (data.surfaceSet != null)
            {
                // destroy currently loaded surfaces
                DestroyLoadedSurfaces();

                for (int i = 0; i < data.surfaceSet.surfaceCount; i++)
                {
                    GameObject overlaySurfaceObj = new GameObject();
                    overlaySurfaceObj.name = "surface-" + i;
                    overlaySurfaceObj.transform.SetParent(transform);

                    OverlaySurfaceUpdater overlaySurface = overlaySurfaceObj.AddComponent <OverlaySurfaceUpdater>();
                    overlaySurface.SetSurfaceMaterial(surfaceMaterial);
                    overlaySurface.SetSurfaceCollider(true, null);

                    Vector3 surfacePos = data.surfaceSet.surfaces[i].position;
                    surfacePos = compStartRot * surfacePos;

                    Quaternion surfaceRot = Quaternion.Euler(data.surfaceSet.surfaces[i].rotation);
                    surfaceRot = Quaternion.Euler(surfaceRot.eulerAngles + compStartRot.eulerAngles);                     //

                    List <Vector3> meshVertices = new List <Vector3>(data.surfaceSet.surfaces[i].vertices);
                    List <int>     meshIndices  = new List <int>(data.surfaceSet.surfaces[i].indices);

                    // update the surface mesh
                    overlaySurface.UpdateSurfaceMesh(surfacePos, surfaceRot, meshVertices, meshIndices);

                    alLoadedSurfaces.Add(overlaySurface);
                }
            }

            if (cameraTransform && data.sceneCam != null)
            {
                Vector3 camPos = data.sceneCam.camPos;
                camPos = compStartRot * camPos;

                Quaternion camRot = Quaternion.Euler(data.sceneCam.camRot);
                camRot = Quaternion.Euler(camRot.eulerAngles + compStartRot.eulerAngles);

                cameraTransform.position = camPos;
                cameraTransform.rotation = camRot;
            }

            if (displaySavedInfos)
            {
                if (locationInfoText)
                {
                    if (data.scenePos != null)
                    {
                        string sMessage = "Lat: " + data.scenePos.lat + ", Lon: " + data.scenePos.lon + ", Alt: " + data.scenePos.alt;
                        sMessage += "\nCompass Head: " + FormatHeading(data.compHeading) + ", Start: " + FormatHeading(data.startHeading);
                        locationInfoText.text = sMessage;
                    }
                    else
                    {
                        locationInfoText.text = "Location service not supported.";
                    }
                }

                if (gyroInfoText)
                {
                    if (data.sceneRot != null)
                    {
                        string sMessage = "Gyro Att: " + data.sceneRot.gyroAtt + ", Rot: " + data.sceneRot.gyroRot;
                        if (data.sceneCam != null)
                        {
                            sMessage += string.Format("\nCamera Pos: {0}, Rot: {1}", data.sceneCam.camPos, data.sceneCam.camRot);
                        }
                        gyroInfoText.text = sMessage;
                    }
                    else
                    {
                        gyroInfoText.text = "Gyroscope not supported.";
                    }
                }
            }

            Debug.Log("AR-Scene (head: " + (int)data.startHeading + ") loaded from: " + dataFilePath);
        }

        return(data);
    }
Esempio n. 4
0
    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);
                }
            }
        }
    }
Esempio n. 5
0
    // loads AR scene and the detected surfaces
    public JsonArScene LoadArScene(string dataFilePath)
    {
        if (!File.Exists(dataFilePath))
        {
            return(null);
        }

        // load json
        string      sJsonText = File.ReadAllText(dataFilePath);
        JsonArScene data      = JsonUtility.FromJson <JsonArScene>(sJsonText);

        if (data != null)
        {
            Quaternion compStartRot = Quaternion.Euler(0f, -startHeading, 0f);

            Vector3 camOffset = Vector3.zero;
            if (applyLocationDistance && locationEnabled &&
                Input.location.status == LocationServiceStatus.Running && data.scenePos != null)
            {
                Vector3 locSaved  = GeoUtils.LatLong2Meters(data.scenePos.lat, data.scenePos.lon, useLocationAltitude ? data.scenePos.alt : 0f);
                Vector3 locCamera = GeoUtils.LatLong2Meters(lastLoc.latitude, lastLoc.longitude, useLocationAltitude ? lastLoc.altitude : 0f);

                camOffset = locSaved - locCamera;
                camOffset = new Vector3(camOffset.y, camOffset.z, camOffset.x);                  // x=lon; y=alt; z=lat
            }

            if (data.surfaceSet != null)
            {
                // destroy currently loaded surfaces
                DestroyLoadedSurfaces();

                for (int i = 0; i < data.surfaceSet.surfaceCount; i++)
                {
                    GameObject overlaySurfaceObj = new GameObject();
                    overlaySurfaceObj.name = "surface-" + i;
                    overlaySurfaceObj.transform.SetParent(transform);

//					GameObject overlayCubeObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
//					overlayCubeObj.name = "surface-cube-" + i;
//					overlayCubeObj.transform.localScale = new Vector3(0.1f, 0.2f, 0.3f);
//					overlayCubeObj.transform.SetParent(overlaySurfaceObj.transform);

                    OverlaySurfaceUpdater overlaySurface = overlaySurfaceObj.AddComponent <OverlaySurfaceUpdater>();
                    overlaySurface.SetSurfaceMaterial(surfaceMaterial);
                    overlaySurface.SetSurfaceCollider(true, null);

                    Vector3 surfacePos = data.surfaceSet.surfaces[i].position;
                    surfacePos = compStartRot * surfacePos;

                    if (applyLocationDistance)
                    {
                        surfacePos += camOffset;
                    }

                    Quaternion surfaceRot = Quaternion.Euler(data.surfaceSet.surfaces[i].rotation);
                    surfaceRot = Quaternion.Euler(surfaceRot.eulerAngles + compStartRot.eulerAngles);                     //

                    List <Vector3> meshVertices = new List <Vector3>(data.surfaceSet.surfaces[i].vertices);
                    List <int>     meshIndices  = new List <int>(data.surfaceSet.surfaces[i].indices);

                    // update the surface mesh
                    overlaySurface.UpdateSurfaceMesh(surfacePos, surfaceRot, meshVertices, meshIndices);

//					// find the nearest currently tracked surface
//					MultiARInterop.TrackedSurface[] alTrackedSurf = arManager ? arManager.GetTrackedSurfaces(false) : null;
//
//					MultiARInterop.TrackedSurface nearestSurf;
//					float nearestDist = float.MaxValue;
//					bool foundNearestSurf = false;
//
//					if (alTrackedSurf != null && alTrackedSurf.Length > 0)
//					{
//						for (int s = 0; s < alTrackedSurf.Length; s++)
//						{
//							MultiARInterop.TrackedSurface trackedSurf = alTrackedSurf[s];
//
//
//						}
//					}

                    alLoadedSurfaces.Add(overlaySurface);
                }
            }

            Debug.Log("AR-Scene (head: " + (int)data.startHeading + ") loaded from: " + dataFilePath);
        }

        return(data);
    }