コード例 #1
0
        bool CameraUnProject(Vector3 p, Matrix4x4 cameraToWorld, Matrix4x4 clipToWorld, Rect viewport, out Vector3 outP)
        {
            // pixels to -1..1
            Vector3 in_v;

            in_v.x = (p.x - viewport.x) * 2.0f / viewport.width - 1.0f;
            in_v.y = (p.y - viewport.y) * 2.0f / viewport.height - 1.0f;
            // It does not matter where the point we unproject lies in depth; so we choose 0.95, which
            // is further than near plane and closer than far plane, for precision reasons.
            // In a perspective camera setup (near=0.1, far=1000), a point at 0.95 projected depth is about
            // 5 units from the camera.
            in_v.z = 0.95f;

            Vector3 pointOnPlane;

            if (clipToWorld.PerspectiveMultiplyPoint3(in_v, out pointOnPlane))
            {
                // Now we have a point on the plane perpendicular to the viewing direction. We need to return the one that is on the line
                // towards this point, and at p.z distance along camera's viewing axis.
                Vector3 cameraPos = cameraToWorld.GetPosition();
                Vector3 dir       = pointOnPlane - cameraPos;

                // The camera/projection matrices follow OpenGL convention: positive Z is towards the viewer.
                // So negate it to get into Unity convention.
                Vector3 forward     = -cameraToWorld.GetAxisZ();
                float   distToPlane = Vector3.Dot(dir, forward);
                if (Mathf.Abs(distToPlane) >= 1.0e-6f)
                {
                    bool isPerspective = clipToWorld.IsPerspective();
                    if (isPerspective)
                    {
                        dir *= p.z / distToPlane;
                        outP = cameraPos + dir;
                    }
                    else
                    {
                        outP = pointOnPlane - forward * (distToPlane - p.z);
                    }
                    return(true);
                }
            }
            outP = new Vector3(0.0f, 0.0f, 0.0f);
            return(false);
        }