托管 CloudAnchor 后使用具有正确 position/rotation 的 AugmentedImages

Using AugmentedImages with correct position/rotation after hosting a CloudAnchor

我正在使用 arcore 为多个用户开发 AR 应用程序。因此,我正在使用云锚(就像在云锚示例中一样)并想要添加一些增强图像。在我托管云锚之前,虚拟对象将显示在增强图像之上,一切都很好。设置(和托管)云锚点后,增强图像的虚拟对象显示在完全不同的位置。当移动增强图像时,它们的位置和旋转会以意想不到的方式发生变化。它可能与 ARCoreWorldOriginHelper-class 有关,它将统一位置转换为与云锚点相关的位置,但我不知道如何解决这个问题。

我已经尝试过不同的设置。添加 AugmentedImageVisualizer(如 AugmentedImage 示例中)时,我使用 ARCoreWorldOriginHelper 来转换图像的锚点。

        //Image augmentation. Get updated images for this frame.
        Session.GetTrackables<AugmentedImage>(augmentedImages, TrackableQueryFilter.Updated);

        //Create visualizers for updated augmented images that are tracking and do not previously have a visualizer. Remove visualizers for stopped images.
        foreach(AugmentedImage image in augmentedImages)
        {
            ARImageVisualizer visualizer = null;

            //when visualizer was added before
            visualizers.TryGetValue(image.DatabaseIndex, out visualizer);

            Debug.Log("Tracking State is " + image.TrackingState);

            //if no visualizer was found, add one
            if(visualizer == null && image.TrackingState == TrackingState.Tracking)
            {
                //Anchor anchor = image.CreateAnchor(image.CenterPose);
                Anchor anchor = image.CreateAnchor(ARCoreWorldOriginHelper.WorldToAnchorPose(image.CenterPose));
                visualizer = (ARImageVisualizer)Instantiate(ARImageVisualizer, anchor.transform);
                visualizer.Image = image;
                visualizers.Add(image.DatabaseIndex, visualizer);
            }
            //if tracking has stopped and will never resume
            else if ((visualizer != null && image.TrackingState == TrackingState.Stopped))
            {
                visualizers.Remove(image.DatabaseIndex);
                Destroy(visualizer.transform.parent.gameObject);    //destroy visualizer
            }
        }

在 AugmentedImageVisualizer 中,我尝试了正常程序:仅更改 localPosition。我还尝试使用 ARCoreWorldOriginHelper(仅使用 FrameUpperRight)进行翻译,但这根本不起作用(有时我什至找不到虚拟对象)。

//if no image is tracked, disable visualized object
        if (Image == null || Image.TrackingState != TrackingState.Tracking || Image.TrackingMethod != AugmentedImageTrackingMethod.FullTracking)
        {
            FrameLowerLeft.SetActive(false);
            FrameLowerRight.SetActive(false);
            FrameUpperLeft.SetActive(false);
            FrameUpperRight.SetActive(false);
            return;
        }

        float halfWidth = Image.ExtentX / 2;
        float halfHeight = Image.ExtentZ / 2;
        FrameLowerLeft.transform.localPosition = (halfWidth * Vector3.left) + (halfHeight * Vector3.back);
        FrameLowerRight.transform.localPosition = (halfWidth * Vector3.right) + (halfHeight * Vector3.back);
        FrameUpperLeft.transform.localPosition = (halfWidth * Vector3.left) + (halfHeight * Vector3.forward);
        //FrameUpperRight.transform.localPosition = (halfWidth * Vector3.right) + (halfHeight * Vector3.forward);

                Pose framePose = ARCoreWorldOriginHelper.WorldToAnchorPose(new Pose((halfWidth * Vector3.right) + (halfHeight * Vector3.forward), FrameUpperRight.transform.localRotation));
                FrameUpperRight.transform.localPosition = framePose.position;

        FrameLowerLeft.SetActive(true);
        FrameLowerRight.SetActive(true);
        FrameUpperLeft.SetActive(true);
        FrameUpperRight.SetActive(true);

是否有人已经尝试过并知道要更改什么? 谢谢

最后我知道该怎么办了。问题是,你不能将锚点移动到不同的位置。锚点将始终在图像上。即使作为其他游戏对象的子对象,也不可能移动锚点。因此,当 smartphone/ARCoreRoot 不再是世界锚点而是云锚点时,要实现增强图像的偏移量,您不需要创建锚点。您只需实例化可视化工具并使其成为另一个获得偏移量的游戏对象的子对象。然后在每一帧中更新可视化工具的真实位置。使用偏移量,它将正确显示在图像上。在可视化工具本身中,您可以使用普通代码:

     //Image augmentation. Get updated images for this frame.
        Session.GetTrackables<AugmentedImage>(augmentedImages, TrackableQueryFilter.Updated);

        //Create visualizers for updated augmented images that are tracking and do not previously have a visualizer. Remove visualizers for stopped images.
        foreach(AugmentedImage image in augmentedImages)
        {
            ARImageVisualizer visualizer = null;

            //when visualizer was added before
            visualizers.TryGetValue(image.DatabaseIndex, out visualizer);

            //if no visualizer was found, add one
            if(visualizer == null && image.TrackingState == TrackingState.Tracking)
            {
                //AugmentedImages is the parent gameobject with the offset
                visualizer = (ARImageVisualizer)Instantiate(ARImageVisualizer, image.CenterPose.position, image.CenterPose.rotation, AugmentedImages.transform);
                visualizer.Image = image;
                visualizers.Add(image.DatabaseIndex, visualizer);
            }
            //if tracking has stopped and will never resume
            else if ((visualizer != null && image.TrackingState == TrackingState.Stopped))
            {
                visualizers.Remove(image.DatabaseIndex);
                Destroy(visualizer.transform.parent.gameObject);    //destroy visualizer
            }
            visualizer.transform.localPosition = image.CenterPose.position;
            visualizer.transform.localRotation = image.CenterPose.rotation;
        }
//if no image is tracked, disable visualized object
        if (Image == null || Image.TrackingState != TrackingState.Tracking || Image.TrackingMethod != AugmentedImageTrackingMethod.FullTracking)
        {
            FrameLowerLeft.SetActive(false);
            FrameLowerRight.SetActive(false);
            FrameUpperLeft.SetActive(false);
            FrameUpperRight.SetActive(false);
            return;
        }

        float halfWidth = Image.ExtentX / 2;
        float halfHeight = Image.ExtentZ / 2;
        FrameLowerLeft.transform.localPosition = (halfWidth * Vector3.left) + (halfHeight * Vector3.back);
        FrameLowerRight.transform.localPosition = (halfWidth * Vector3.right) + (halfHeight * Vector3.back);
        FrameUpperLeft.transform.localPosition = (halfWidth * Vector3.left) + (halfHeight * Vector3.forward);
        FrameUpperRight.transform.localPosition = (halfWidth * Vector3.right) + (halfHeight * Vector3.forward);


        FrameLowerLeft.SetActive(true);
        FrameLowerRight.SetActive(true);
        FrameUpperLeft.SetActive(true);
        FrameUpperRight.SetActive(true);