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

 class Ray {

     public final Vector3f origin;//射线起点
public final Vector3f direction;//射线方向 public Ray(Vector3f origin, Vector3f direction) {
this.origin = origin;
this.direction = direction;
} //根据屏幕坐标计算射线——3D拾取
public static Ray screenPointToRay(Vector2f point, Vector2f viewportSize, float[] viewProjMtx) {
point.y = viewportSize.y - point.y;//转化为左下角为原点
float x = point.x * 2.0F / viewportSize.x - 1.0F;//转换到[-1,1]
float y = point.y * 2.0F / viewportSize.y - 1.0F;//转换到[-1,1] float[] farScreenPoint = new float[]{x, y, 1.0F, 1.0F};//远平面上的坐标透视除法之后的值
float[] nearScreenPoint = new float[]{x, y, -1.0F, 1.0F};//近平面上的坐标透视除法之后的值 float[] nearPlanePoint = new float[4];//用于记录世界坐标系下,近平面上的点
float[] farPlanePoint = new float[4];//用于记录世界坐标系下,远平面上的点 float[] invertedProjectionMatrix = new float[16];
Matrix.setIdentityM(invertedProjectionMatrix, 0);
Matrix.invertM(invertedProjectionMatrix, 0, viewProjMtx, 0);//计算逆矩阵 Matrix.multiplyMV(nearPlanePoint, 0, invertedProjectionMatrix, 0, nearScreenPoint, 0);//计算世界坐标系中,对应到近平面的坐标
Matrix.multiplyMV(farPlanePoint, 0, invertedProjectionMatrix, 0, farScreenPoint, 0); Vector3f direction = new Vector3f(farPlanePoint[0] / farPlanePoint[3], farPlanePoint[1] / farPlanePoint[3], farPlanePoint[2] / farPlanePoint[3]);
Vector3f origin = new Vector3f(new Vector3f(nearPlanePoint[0] / nearPlanePoint[3], nearPlanePoint[1] / nearPlanePoint[3], nearPlanePoint[2] / nearPlanePoint[3]));
direction.sub(origin);
direction.normalize();
return new Ray(origin, direction);
}
}

原理:

一、世界坐标系的点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就代表投影空间中的坐标点。

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

ARCore中根据屏幕坐标计算射线的算法的更多相关文章

  1. ARCore中Pose类变换点的算法实现

    ARCore中Pose类变换点的算法实现,主要分为两步,分别是平移和旋转. 1. 旋转向量:通过四元数计算旋转后的向量 参数列表:q表示四元数, v是长度为4的float数组,表示待旋转的向量,   ...

  2. EIGRP-11-弥散更新算法-EIGRP中的本地计算和弥散计算

    至此,我们已经了解了诸多概念: RD (报告距离). CD (计算距离). FD (可行距 离)和FC (可行性条件) ,在此基础上继续了解EIGRP对于拓扑变化的应对方法想必是轻松愉快的.能够导致拓 ...

  3. 三角函数计算,Cordic 算法入门

    [-] 三角函数计算Cordic 算法入门 从二分查找法说起 减少乘法运算 消除乘法运算 三角函数计算,Cordic 算法入门 三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来 ...

  4. (转)三角函数计算,Cordic 算法入门

    由于最近要使用atan2函数,但是时间上消耗比较多,因而网上搜了一下简化的算法. 原帖地址:http://blog.csdn.net/liyuanbhu/article/details/8458769 ...

  5. ARCore中四元数的插值算法实现

    ARCore中四元数差值算法: 其中t的取值范围为[0, 1],当 t = 0 时,结果为a:当t = 1 时,结果为b. public static Quaternion makeInterpola ...

  6. SVD在推荐系统中的应用详解以及算法推导

    SVD在推荐系统中的应用详解以及算法推导     出处http://blog.csdn.net/zhongkejingwang/article/details/43083603 前面文章SVD原理及推 ...

  7. DDos攻击,使用深度学习中 栈式自编码的算法

    转自:http://www.airghc.top/2016/11/10/Dection-DDos/ 最近研究了一篇论文,关于检测DDos攻击,使用了深度学习中 栈式自编码的算法,现在简要介绍一下内容论 ...

  8. 【微信小程序】 小程序中的递归运算/二分查找算法/Maximum call stack size exceeded

    摘要: 小程序中的递归运算/二分查找算法/Maximum call stack size exceeded 场景:最近做一个车贷计算器, 其中存在一个公式如下: /**** 总金额 * 月利率 * ( ...

  9. --关于null在oracle数据库中是否参与计算,进行验证,

    --关于null在oracle数据库中是否参与计算,进行验证,with td as (select null id,1 name from dual ),td1 as ( select null id ...

随机推荐

  1. 从零开始学Shell(二)

    $1,$2....${10},${11},[root@localhost cee]# cat p.sh #!/bin/bash#file_name:p.shecho $1 $2[root@localh ...

  2. .Net Core 控制台程序生产exe

    打开csproj ,添加一行 <RuntimeIdentifier>win10-x64</RuntimeIdentifier> 具体如下: <Project Sdk=&q ...

  3. 入门项目 A5-1 interface-bank 第三方接口1

    from db import db_handler # 提现接口 def withdraw_interface(name, money): # 定义提现接口,传入name与money参数 user_d ...

  4. mysql中外键的创建与删除

    外键的创建 方法1:创建表的时候设置(外键名随机生成) 1.前提条件,必须要有一个主表,这里设为persons 2.主表中必须设置主键字段primary key,这里设为id_p //创建数据库dat ...

  5. Ubuntu Server 16.04设置WiFi

    wifi :http://www.cnblogs.com/joeyupdo/p/3350463.html http://blog.csdn.net/meic51/article/details/173 ...

  6. jsp弹窗并跳转

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcepti ...

  7. MarkDown学习——基础用法

    目录 MarkDown开发版本MD2All基础用法 此处有代码<a id="top"></a>作为页内锚点 此处是用自动生成的目录 MarkDown是什么M ...

  8. Unity打开外部程序exe/Bat文件方案

    Unity调用外部程序/Bat文件 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  9. JUnit4测试报错:class not found XXX

     初学java框架,最近用eclipse跟着视频坐淘淘商城这个项目,其中使用了JUnit4做单元测试.当运行测试代码时,项目报错:class not found xxx. 借助了其他大神的博客,论坛等 ...

  10. vue 15分钟倒计时

    HTML: <span>{{minute}}:{{second}}</span> script: 一          二 // 倒计时 num(n) { return n & ...