How to make input position stop depending on camera FOV?

  Kiến thức lập trình

I have a problem with creating brush size tool in Unity. I’m painting on 3D model, and using raycast for brush tool.

Problem: input position changes depending on camera’s fieldOfView. And because of that my brush size decreases when I increase zoom (which means decreasing FOV). How can I avoid that issue?

Code (method that called in FixedUpdate when brush is working):

public override void Execute()
{      
    Texture2D texture = RedactorStateManager.Instance.RedactState.ModelRenderer.material.mainTexture as Texture2D;

    Vector3 normalizedPos = new Vector3(InputPosition.x/Screen.width, InputPosition.y / Screen.height, 0);

    float OffsetRatio = Camera.main.fieldOfView < RedactorStateManager.Instance.ControllerState.maxZoom ? 
        (RedactorStateManager.Instance.ControllerState.maxZoom - Camera.main.fieldOfView) * BrushSizeController.Instance.FOWRatio : 0;

    foreach (var pixelOffset in BrushSizeController.Instance.CurrentBrushSizePixels)
    {
        float xOffset = pixelOffset.x > 0 ? (pixelOffset.x + OffsetRatio) : (pixelOffset.x - OffsetRatio);
        float yOffset = pixelOffset.y > 0 ? (pixelOffset.y + OffsetRatio) : (pixelOffset.y - OffsetRatio);

        if(pixelOffset == Vector2.zero)
        {
            xOffset = 0;
            yOffset = 0;
        }

        Vector3 modifiedPos = new Vector3(normalizedPos.x + (xOffset / Screen.width), 
                                            normalizedPos.y + (yOffset / Screen.height), 
                                            0);

        Vector3 worldPoint = Camera.main.ViewportToWorldPoint(new Vector3(modifiedPos.x, modifiedPos.y, 10));

        Ray ray = new Ray(Camera.main.transform.position, (worldPoint - Camera.main.transform.position).normalized);
        RaycastHit[] hits = Physics.RaycastAll(ray);

        Array.Sort(hits, (x, y) => x.distance.CompareTo(y.distance));

        for (int i = 0; i < hits.Length; i++)
        {
            if (i >= 2) break;

            PosX = (int)(hits[i].textureCoord.x * texture.width);
            PosY = (int)(hits[i].textureCoord.y * texture.height);

            if (RedactorStateManager.Instance.RedactState.ModelTexturePixels[new Vector2(PosX, PosY)].PixelColor.a == 0) continue;

            Vector2 pixel = new Vector2(PosX, PosY);
            if (RememberedPixels.ContainsKey(pixel)) continue;

            RememberedPixels.Add(pixel, texture.GetPixel(PosX, PosY));
            texture.SetPixel(PosX, PosY, PaintColor);
            texture.Apply();
            
            break;
        }
    }
}

I tried to change camera projection, but it broke the brush tool. I tried to change some formulas here and there but still no use. In the end I added FOWRatio to balance changes that FOV causes, and it helps, but only partially.

2

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT