Hi,
i try to keep tracking the last known position of an imageTarget by creating an ArAnchor at the position of the imageTarget, but i can not get it to work right.
I found a workaround, which you can see in the following code, but this is a bad solution and i would like to avoid using this workaround.
i did simply extend the class AnchorCreator of the arfoundation samples to make a small test project. I added the class in the code below as well as an ArTrackedImageManager to the Anchors scene in the samples.
The problem is, that i want to create a new Pose at the imageTarget transforms position, but if i do so with
Pose newPose = new Pose(trackedImage.transform.position, trackedImage.transform.rotation);
``` it is returning a different Pose than if i do a raycast to the plane represented by the image. It seems, that the returned Pose of the Raycast is in a different coordinate system (maybe ARSpace). The raycast workaround is only working if the tracked image is known to be vertical or horizontally placed and if a plane is found and that is not always the case if an image is found. There should be a way to create a correct Pose for a trackedImageTarget without doing a raycast, that could also fail.
I would appreciate any help.
TestCode
[spoiler]
```csharp
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
[RequireComponent(typeof(ARAnchorManager))]
[RequireComponent(typeof(ARRaycastManager))]
[RequireComponent(typeof(ARTrackedImageManager))]
public class AnchorCreatorImageTracking : MonoBehaviour
{
public void RemoveAllAnchors()
{
foreach (var anchor in m_Anchors)
{
m_AnchorManager.RemoveAnchor(anchor);
}
m_Anchors.Clear();
}
void Awake()
{
m_RaycastManager = GetComponent<ARRaycastManager>();
m_AnchorManager = GetComponent<ARAnchorManager>();
m_TrackedImageManager = GetComponent<ARTrackedImageManager>();
m_TrackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
m_Anchors = new List<ARAnchor>();
}
void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (var trackedImage in eventArgs.added)
{
Pose newPose = new Pose(trackedImage.transform.position, trackedImage.transform.rotation);
if (m_RaycastManager.Raycast( Camera.main.WorldToScreenPoint(trackedImage.transform.position), s_Hits, TrackableType.Planes))
{
Debug.Log("onFound HitTest PLanes");
Debug.LogFormat("HitTest Pose position: {0} rotation: {1}",s_Hits[0].pose.position,s_Hits[0].pose.rotation);
Debug.LogFormat("TrackedImage position: {0} rotation: {1}",trackedImage.transform.position,trackedImage.transform.rotation);
Debug.LogFormat("TrackedImage localPosition: {0} localRotation: {1}",trackedImage.transform.localPosition,trackedImage.transform.localRotation);
var hitPose = s_Hits[0].pose;
var anchor = m_AnchorManager.AddAnchor(hitPose);
m_Anchors.Add(anchor);
}
var anchor2 = m_AnchorManager.AddAnchor(newPose);
m_Anchors.Add(anchor2);
}
}
void Update()
{
if (Input.touchCount == 0)
return;
var touch = Input.GetTouch(0);
if (touch.phase != TouchPhase.Began)
return;
if (m_RaycastManager.Raycast(touch.position, s_Hits, TrackableType.FeaturePoint))
{
// Raycast hits are sorted by distance, so the first one
// will be the closest hit.
var hitPose = s_Hits[0].pose;
var anchor = m_AnchorManager.AddAnchor(hitPose);
if (anchor == null)
{
Logger.Log("Error creating anchor");
}
else
{
m_Anchors.Add(anchor);
}
}
}
static List<ARRaycastHit> s_Hits = new List<ARRaycastHit>();
List<ARAnchor> m_Anchors;
ARRaycastManager m_RaycastManager;
ARAnchorManager m_AnchorManager;
ARTrackedImageManager m_TrackedImageManager;
}
[/spoiler]