AR FOUNDATION RAYCASTING: используя RayCast, чтобы определить, где разместить позицию Z - PullRequest
0 голосов
/ 03 апреля 2020

Я разрабатываю простое приложение для создания AR-фона, чтобы рисовать маленькие сферы на месте, когда вы касаетесь экрана. Проблема в том, что объекты нарисованы, но они не остаются на объекте реального мира, когда я перемещаю камеру. Это связано с тем, что моя позиция Z жестко закодирована в 8, и нарисованному объекту AR становится очень трудно оставаться на реальном объекте, особенно когда камера перемещается.

У вас есть решение для этого путем использования AR Foundation Raycasting?

Если да, можете ли вы поделиться его образцом, который я могу заменить здесь

Вот мой код Unity C#.

using System.Collections;
using UnityEngine;
using agora_gaming_rtc;

public class RemoteDrawer : MonoBehaviour
{
    // Start is called before the first frame update
    IRtcEngine rtcEngine;

    Camera arCam;     // the AR Camera
    Camera renderCam; // the Renderer Camera, space of 3D objects
    Camera viewCam; // the viewer of the projected quad, acting camera since AR Camera projects into a RenderTexture

    [SerializeField] Transform referenceObject = null;

    [SerializeField] GameObject DrawPrefab = null;

    public float DotScale = 0.15f;

    private GameObject anchorGO;
    private Color DrawColor = Color.black;

    void Start()
    {
        rtcEngine = IRtcEngine.QueryEngine();
        if (rtcEngine != null)
        {
            rtcEngine.OnStreamMessage += HandleStreamMessage;
        }

        CamStart();
    }


    /// <summary>
    ///    The delegate function to handle message sent from Audience side
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="streamId"></param>
    /// <param name="data"></param>
    /// <param name="length"></param>
    void HandleStreamMessage(uint userId, int streamId, string data, int length)
    {
        if (data.Contains("color"))
        {
            StartCoroutine(CoProcessDrawingData(data));
        }
        else if (data.Contains("clear"))
        {
            Destroy(anchorGO);
        }


        Debug.LogWarning("Main Camera pos = " + Camera.main.transform.position);
    }

    /// <summary>
    ///  Do the drawing async
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    IEnumerator CoProcessDrawingData(string data)
    {
        try
        {
            DrawmarkModel dm = JsonUtility.FromJson<DrawmarkModel>(data);
            DrawColor = dm.color;
            foreach (Vector2 pos in dm.points)
            {
                DrawDot(pos);
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError(e);
        }
        yield return null;
    }


    int dotCount = 0;
    /// <summary>
    ///   
    /// </summary>
    /// <param name="pos">Screen Position</param>
    void DrawDot(Vector2 pos)
    {
        if (anchorGO == null)
        {
            anchorGO = new GameObject();
            anchorGO.transform.SetParent(referenceObject.transform.parent);
            anchorGO.transform.position = Vector3.zero;
            anchorGO.transform.localScale = Vector3.one;
            anchorGO.name = "DrawAnchor";
        }


        // DeNormalize the position and adjust to passed camera
        Vector3 location = DeNormalizedPosition(pos, renderCam);


        GameObject go = GameObject.Instantiate(DrawPrefab, location, Quaternion.identity);
        go.transform.SetParent(anchorGO.transform);
        go.transform.localScale = DotScale * Vector3.one;
        go.layer = (int)CameraLayer.IGNORE_RAYCAST;
        go.name = "dot " + dotCount;
        dotCount++;
        Debug.LogFormat("{0} pos:{1} => : {2} ", go.name, pos, location);
        Renderer renderer = go.GetComponent<Renderer>();
        if (renderer != null)
        {
            Material mat = renderer.material;
            if (mat != null)
            {
                mat.color = DrawColor;
            }
        }
    }

    /// <summary>
    ///    Provide a ViewPort Position (0,0) = bottom left and (1,1) top right
    /// return world position for the current camera
    /// </summary>
    /// <param name="vector2"></param>
    /// <param name="camera"></param>
    /// <returns></returns>
    Vector3 DeNormalizedPosition(Vector2 vector2, Camera camera)
    {

        Vector3 pos = new Vector3(vector2.x, vector2.y);

        pos = camera.ViewportToScreenPoint(pos);

        // Consider using the referenceObject for position calculation
        // Vector3 deltaPos = camera.transform.position - referenceObject.position;

        pos = new Vector3(pos.x, pos.y, 8);

        return camera.ScreenToWorldPoint(pos);
    }

    // Use this for initialization
    void CamStart()
    {
        renderCam = GameObject.Find("RenderCamera").GetComponent<Camera>();
        arCam = GameObject.Find("AR Camera").GetComponent<Camera>();
        viewCam = GameObject.Find("ViewCamera").GetComponent<Camera>();
    }
}

Это линия, где я сложен. Как я могу использовать AR Foundation Raycasting для определения позиции Z? На данный момент я жестко закодировал.

pos = new Vector3(pos.x, pos.y, 8);

1 Ответ

0 голосов
/ 03 апреля 2020

Если вы используете ARFoundation и вы просто хотите разместить объект на поверхности, тогда используйте ARRaycastManager.

Тогда в вашем коде просто сделайте raycast

if (raycastManager.Raycast(position, hitResults))
    {
        //hitResults[0].pose.position is the position you are looking for
    }

I ' Я не уверен, почему вы сделали такой сложный код, но взгляните на RaycastManager.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...