Open wangvnn opened 6 years ago
Hi, thanks for the report. I cannot reproduce your issue. Using PlaneWithinInfinity does not guarantee that all planes will be hit. Only planes that would intersect if they were infinitely big will be hit. In a 3D environment this is not always true. Let me know if this helps or if you still experience this issue with planes that should be clearly be hit.
I added image for clarification: https://ibb.co/mwsXAe
As you can see it works on the top image, it does not work well on the bottom image. I have 4 planes (1,2,3,4), I cast a ray from camera (6) and detect all the hits and display the reticle (5) on the lowest plane. In the top image, it returns 4 hit planes (1,2,3,4), and in the bottom image it returns 1 hit planes only (3).
NOTE: plane 3 is a book on my table, 2 is my table, 1,4 is the floor planes that have not been merged yet.
I use this code:
List
I trace the code until: HitTestApi.cs
public static bool RaycastAll(float x, float y, TrackableHitFlags filter, List<TrackableHit> hitResults)
{
hitResults.Clear();
var nativeSession = LifecycleManager.Instance.NativeSession;
if (nativeSession == null)
{
return false;
}
return nativeSession.HitTestApi.Raycast(nativeSession.FrameHandle, x, Screen.height - y, filter, hitResults, true);
}
And
public bool Raycast(IntPtr frameHandle, float x, float y, TrackableHitFlags filter,
List
IntPtr hitResultListHandle = IntPtr.Zero;
ExternApi.ArHitResultList_create(m_NativeSession.SessionHandle, ref hitResultListHandle);
ExternApi.ArFrame_hitTest(m_NativeSession.SessionHandle, frameHandle, x, y, hitResultListHandle);
int hitListSize = 0;
ExternApi.ArHitResultList_getSize(m_NativeSession.SessionHandle, hitResultListHandle, ref hitListSize);
for (int i = 0; i < hitListSize; i++)
{
TrackableHit trackableHit;
if (HitResultListGetItemAt(hitResultListHandle, i, out trackableHit))
{
if ((filter & trackableHit.Flags) != TrackableHitFlags.None)
{
outHitList.Add(trackableHit);
}
}
}
ExternApi.ArHitResultList_destroy(hitResultListHandle);
return outHitList.Count != 0;
}
And it looks like the result returned from hit test API is wrong. I also notice at this line: ExternApi.ArFrame_hitTest(m_NativeSession.SessionHandle, frameHandle, x, y, hitResultListHandle);
The code does not pass in any hit flag param, so I assume internally the API would do ray cast with all infinite planes. But it does not seem to work that way.
Hi, thanks for reporting this. Looking further into it, we are only hitting against planes of 2x the current size instead of infinite planes. I added it to our internal tracker to fix it for next releases.
Great. Btw, do you have information about the next release (date, fixes, improvements...) ?
Unfortunately I cannot share any timelines. But we do add the "fixed in upcoming release" tag to issues when a bug is fixed for the next release.
@pablisho Any update on when we can expect the fix for 'PlaneWithinInfinity' or do you suggest any workaround for this.
Thanks!
@pablisho Found this issue by searching with Google. So I'm not 100% sure if this is the right place: I'm also facing this problem within my current project using ARCore XR Plugin 1.0.0 preview 24 from the Unity Package Manager. Did your team already fix this in ARCore, or is Unity's package not up to date?
I am using Frame.RaycastAll to find all the planes that are intersected with the ray from the center all the screen. I use TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinInfinity; The problem is internally this: ExternApi.ArFrame_hitTest(m_NativeSession.SessionHandle, frameHandle, x, y, hitResultListHandle); sometimes does not return all the valid planes. For example: plan1 is closer and plane 2 is further. Sometimes the API only return plane1, instead of returning both (both are valid result) It looks like internally the API did not use the flag PlaneWithinInfinity, because If plane2 is big enough to cover the area underneath plane1, then the API returns the correct result (2 planes) otherwise it will return 1 plane only.