MixedRealityToolkit / MixedRealityToolkit-Unity

This repository holds the third generation of the Mixed Reality Toolkit for Unity. The latest version of the MRTK can be found here.
BSD 3-Clause "New" or "Revised" License
387 stars 100 forks source link

The return eventData of "IMixedRealityPointerHandler" is innacurate.[BUG] #809

Closed CharserHH closed 2 months ago

CharserHH commented 3 months ago

Describe the bug

When I use "eventData.Pointer.Result.Details.Point" to get the hit point on a moving ball, it's going to be very innacurate.

image

I store the distance between the center of the ball and the hitpoint as "Radius", and I cast a normal ray that original in Unity, also store the data as "Another Radius". As the image show, the Radiuses are very wrong(it should be '0.5').

And it happends only on my mixed reality device, the data in Unity editor is correct.

To reproduce

I get the hitpoint like this:

void IMixedRealityPointerHandler.OnPointerDown(
        MixedRealityPointerEventData eventData)
    {
        long starttime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();  //function execute time
        chooseonce++;
        if (chooseonce == 1)
        {
            if (ischosen)
            {
                sequenceController.isstartclick = false;
                ballMove.startmove = false;
                // Create an empty object for localposition calculate
                GameObject localPoint = new GameObject();
               // I cast a ray here
                Vector3 anotherPos = GetHitPoint(eventData.Pointer.Position);
                localPoint.transform.position = eventData.Pointer.Result.Details.Point;
                localPoint.transform.forward = this.transform.parent.forward;
                localPoint.transform.parent = this.transform.parent;
                CurPosDebug(eventData.Pointer.Result.Details.Point, localPoint);
               // store the data
                sequenceController.SaveToFile(ballMove.currentAngle, ballMove.orientation, this.transform.localPosition.x.ToString(), this.transform.localPosition.y.ToString(), this.transform.localPosition.z.ToString(),
                    localPoint.transform.localPosition.x.ToString(), localPoint.transform.localPosition.y.ToString(), localPoint.transform.localPosition.z.ToString(), 
                    RadiusCalculate(localPoint.transform.localPosition, this.transform.localPosition),
                    RadiusCalculate(anotherPos, this.transform.position),
                    "1", this.transform.parent.position.x.ToString(), this.transform.parent.position.y.ToString(), this.transform.parent.position.z.ToString(),
                    this.transform.parent.forward.x.ToString(), this.transform.parent.forward.y.ToString(), this.transform.parent.forward.z.ToString(), 
                    true, starttime);
                Destroy(localPoint);
                ischosen = false;
                material.color = color_OnSelect;
                ballMove.startmove = false;
                StartCoroutine(Right());
            }
        }
    }

And I cast another ray by this function

Vector3 GetHitPoint(Vector3 origin){
        RaycastHit hit;
        Ray ray = new Ray(origin, (transform.position - origin).normalized);
        if(Physics.Raycast(ray, out hit)){
            return hit.point;
        }
        return Vector3.zero;
    }

This script is added to the ball.

My setup

Target platform

anonymous2585 commented 3 months ago

I might have a similar precision issue with the hand ray (using MRTK 3).

I work with complex industrial models. We have a scene with a bended sheet metal and a pipe hidden behind it. They have mesh colliders. Users can select models when pointing the ray on them. With a specific angle, the ray can go through the sheet metal and hit the pipe, even if it's not yet visible.

I don't have this issue with desktop mode, where we manually cast a Unity raycast under the mouse position (same 3D models).

Edit: I found that my issue is in the XRI XRRayInteractor, that has a limited number of raycast hits (10). My ray was hitting more than 10 objects and the sheet metal wasn't in the first 10 hits. I don't think it's related to your precision issue.

anonymous2585 commented 3 months ago

I think in MRTK 2 the default pointer "ray" is in fact a cone (or a sphere cast), to help user select small far objects without needing them to point them precisely.

In your hand ray prefab, be sure to set the ray settings to a simple raycast. If you use a ShellHandRayPointer, try set the "Sphere Cast Radius" to 0 (instead of default 0.1).

CharserHH commented 3 months ago

I think in MRTK 2 the default pointer "ray" is in fact a cone (or a sphere cast), to help user select small far objects without needing them to point them precisely.

In your hand ray prefab, be sure to set the ray settings to a simple raycast. If you use a , try set the "Sphere Cast Radius" to 0 (instead of default 0.1).ShellHandRayPointer

Thanks but the ray that innacurate is cast completely by the HoloLens device(To be honest I'm not 100% sure about this). I can only get the return eventData but can't alter it. So I decide to let the eventData only privide the time point and the hit, and I cast a normal ray with these information and get the final result instead of the hand ray.

AMollis commented 2 months ago

Hi @CharserHH , this is an issue with MRTK2. Please open MRTK2 issues at

https://github.com/microsoft/MixedRealityToolkit-Unity/issues