zoukankan      html  css  js  c++  java
  • ARCore中根据屏幕坐标计算射线的算法

    ARCore中提供了根据屏幕坐标、视口大小及view、 project矩阵计算从屏幕坐标发射一条射线的方法,此方法用于3D拾取。

     1 class Ray {
     2 
     3     public final Vector3f origin;//射线起点
     4     public final Vector3f direction;//射线方向
     5 
     6     public Ray(Vector3f origin, Vector3f direction) {
     7         this.origin = origin;
     8         this.direction = direction;
     9     }
    10 
    11     //根据屏幕坐标计算射线——3D拾取
    12     public static Ray screenPointToRay(Vector2f point, Vector2f viewportSize, float[] viewProjMtx) {
    13         point.y = viewportSize.y - point.y;//转化为左下角为原点
    14         float x = point.x * 2.0F / viewportSize.x - 1.0F;//转换到[-1,1]
    15         float y = point.y * 2.0F / viewportSize.y - 1.0F;//转换到[-1,1]
    16 
    17         float[] farScreenPoint = new float[]{x, y, 1.0F, 1.0F};//远*面上的坐标透视除法之后的值
    18         float[] nearScreenPoint = new float[]{x, y, -1.0F, 1.0F};//**面上的坐标透视除法之后的值
    19 
    20         float[] nearPlanePoint = new float[4];//用于记录世界坐标系下,**面上的点
    21         float[] farPlanePoint = new float[4];//用于记录世界坐标系下,远*面上的点
    22 
    23         float[] invertedProjectionMatrix = new float[16];
    24         Matrix.setIdentityM(invertedProjectionMatrix, 0);
    25         Matrix.invertM(invertedProjectionMatrix, 0, viewProjMtx, 0);//计算逆矩阵
    26 
    27         Matrix.multiplyMV(nearPlanePoint, 0, invertedProjectionMatrix, 0, nearScreenPoint, 0);//计算世界坐标系中,对应到**面的坐标
    28         Matrix.multiplyMV(farPlanePoint, 0, invertedProjectionMatrix, 0, farScreenPoint, 0);
    29 
    30         Vector3f direction = new Vector3f(farPlanePoint[0] / farPlanePoint[3], farPlanePoint[1] / farPlanePoint[3], farPlanePoint[2] / farPlanePoint[3]);
    31         Vector3f origin = new Vector3f(new Vector3f(nearPlanePoint[0] / nearPlanePoint[3], nearPlanePoint[1] / nearPlanePoint[3], nearPlanePoint[2] / nearPlanePoint[3]));
    32         direction.sub(origin);
    33         direction.normalize();
    34         return new Ray(origin, direction);
    35     }   
    36 }

    原理:

    一、世界坐标系的点P1转化到投影空间得到点P2的公式是:P2 = P1 * viewMatrix * projectMatrix = P1 * viewProjMatrix;

    在渲染管线中,投影空间的点还需要经过透视除法,转化到x , y , z值均为[-1,1]区间内,是一个单位立方体。公式是:point_clip = P2/P2.w;

    那么将点从单位立方体坐标系转化到世界坐标系的公式跟上述情况是逆过程,公式:

    P2 = point_clip * wValue;
    P1 = P2 * viewProjMatrix_invert;

    其中wValue代表给定的w值,在ARCore中此值为1,所以并未体现在代码中。

    二、上面代码片段,是将屏幕上的点的x,y坐标值均转化到[-1,1],给定*裁剪*面的点的z为-1,远裁剪*面上的点的z为1,其w值均为1,这种方法得到透视除法后单位立方体中的坐标。

    因为wValue为1,所以此时farScreenPoint和nearScreenPoint就代表投影空间中的坐标点。

    然后根据(一)中的结论即可得到对应到世界坐标系的坐标点,根据两个点可得到射线方法,最终即可得到射线的起点和方向。

  • 相关阅读:
    json数据转化格式
    远程安装软件控制台
    杂、记忆点
    布局(杂,细节处理)
    自己修改代码后push推送到zhile
    js中call和apply的区别 / 函数的call、apply以及bind的作用与区别
    一元运算符a++、++a、a--、--a
    javascript基础语法和算术运算符
    不同空格符号的区别
    2020.12.11面试两家
  • 原文地址:https://www.cnblogs.com/calence/p/7489019.html
Copyright © 2011-2022 走看看