【Sceneform-EQR】(手势优化)通过手势事件实现在AR/VR等三维场景中的控制模型旋转、平移与缩放


在上一篇文档中,我们实现了通过手势控制模型节点的旋转、缩放和平移。现在本文将介绍如何优化上一篇做的手势控制器,从而实现更好的跟手效果。

相关链接:【Sceneform-EQR】(手势控制器实现)通过手势事件实现在AR/VR等三维场景中的控制模型旋转、平移与缩放


手势优化

平移手势优化

当前存在的问题

直接采用安卓提供的onScroll方法,能够获取到distanceX\Y,而不同设备的屏幕密度不一致,会导致distanceX\Y的值都会有差异。

此外,在AR场景中,不同手机平板的相机的内参(相机焦距、感光元件尺寸等)都不同,会导致相机的视场角不同。

总之,这些都会导致无法实现"指哪打哪"的效果。

优化后的效果

"指哪打哪"的效果

解决思路

  • 思路是屏幕坐标转空间坐标

需要注意的是,屏幕坐标是二维的,空间坐标是三维的。

这里通过屏幕坐标计算出一条射线,然后通过这条射线取指定距离的空间点或是求射线与指定平面的交点。(两种方式都可以很好的实现平移效果,但是实际上有些区别(与相机的距离不一样))

  • 采用指定距离

Sceneform-EQR提供了屏幕坐标转射线的方法camera.screenPointToRay(x,y),然后我们传入指定距离即可。

java 复制代码
        //计算射线,再取得固定距离的空间点坐标.作为新的空间位置
        Vector3 newPosition = camera.screenPointToRay(screenPoint.x, screenPoint.y).getPoint(/*外部传入*/distance);
  • 采用线面相交

原理是,求射线与前方指定距离的平面的交点。用高中的立体几何知识,就不列举公式了,直接看下面代码。

代码如下:

java 复制代码
//向量AB
Vector3 vectorAB = Vector3.subtract(b, a);
//向量AC
Vector3 vectorAC = Vector3.subtract(c, a);
//直线方向向量i
Vector3 i = Vector3.subtract(v1, v0);
//平面法向量n
Vector3 n = Vector3.cross(vectorAB,vectorAC);

//点法式平面方程常数K(条件:代入A点坐标计算=>)
float constK = n.x * a.x + n.y * a.y + n.z * a.z;
//点向式直线方程常数M(条件:直线与平面相交=>)
float constM = (constK - n.x * v0.x - n.y * v0.y - n.z * v0.z)/(i.x * n.x + i.y * n.y + i.z * n.z);

//D点坐标
Vector3 d=new Vector3(v0.x + i.x * constM,v0.y + i.y * constM,v0.z + i.z * constM);

EQR-源码定位

java 复制代码
    private void onDoubleFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        isDoubleFingerScroll = true;
        //计算当前Node的世界坐标系下的空间位置。
        Vector3 screenPoint = camera.worldToScreenPoint(target.getWorldPosition());
        screenPoint.x -= distanceX;
        screenPoint.y -= distanceY;
        //计算射线,再取得固定距离的空间点坐标.作为新的空间位置
        Vector3 newPosition = camera.screenPointToRay(screenPoint.x, screenPoint.y).getPoint(/*外部传入*/distance);
        target.setWorldPosition(newPosition);
    }

旋转手势优化

当前存在的问题

在AR/VR等三维场景中,若场景相机的位姿(位置、姿态)发生变化,原旋转轴的计算已不再适用了

由上图,可发现,当前相机视角发生改变后,原来的旋转手势只能实现模型在它自身坐标系下旋转。

优化后的效果

优化后效果如下:

解决思路

步骤

  • 通过屏幕坐标转空间坐标的方法(与平移优化中用到的一样)计算两个MotionEvent事件的屏幕坐标AB对应的空间坐标A、B。
  • 获取当前相机的在世界坐标系下的位置C。
  • 通过余弦定义求∠ACB,这个作为旋转角度。
  • 通过向量CA与向量CB的叉乘求旋转轴。

叉乘计算:

java 复制代码
  /**
   * 叉乘
   * @return 垂直于两个矢量的矢量
   */
  public static Vector3 cross(Vector3 lhs, Vector3 rhs) {
    float lhsX = lhs.x;
    float lhsY = lhs.y;
    float lhsZ = lhs.z;
    float rhsX = rhs.x;
    float rhsY = rhs.y;
    float rhsZ = rhs.z;
    return new Vector3(
        lhsY * rhsZ - lhsZ * rhsY, lhsZ * rhsX - lhsX * rhsZ, lhsX * rhsY - lhsY * rhsX);
  }
  • 通过计算得到的旋转角度与旋转轴构造四元数,以此做旋转

EQR-源码定位

Commit记录

java 复制代码
        //单指实现旋转(计算旋转轴和旋转角度)
        //原理:
        //上一触摸点转为空间坐标点A,当前触摸点转为空间触摸点B。记当前场景相机的位置为点O
        //那么向量OA与向量OB的叉积则是旋转轴

        //转为空间坐标(屏幕坐标->射线->固定距离的点)
        Vector3 pointA = camera.screenPointToRay(currentEvent.getX() - distanceX,
                currentEvent.getY() - distanceY).getPoint(/*外部传入*/distance);

        Vector3 pointB = camera.screenPointToRay(currentEvent.getX(),currentEvent.getY()).getPoint(distance);
        Vector3 pointO = camera.getWorldPosition();
        Vector3 oa = Vector3.subtract(pointA, pointO);
        Vector3 ob = Vector3.subtract(pointB, pointO);
        float c = Vector3.subtract(pointA, pointB).length();
        float a = oa.length();
        float b = ob.length();
        float cosC = (a * a + b * b - c * c) / (2 * a * b);
        //旋转轴
        Vector3 cross = Vector3.cross(oa, ob).normalized();

查看示例demo请转至git。欢迎交流讨论!

Git仓库

相关推荐
ar01232 天前
AR远程专家指导:赋能工业、精密制造业
人工智能·ar
marteker2 天前
Meta关闭Horizon Worlds VR版
人工智能·vr
localbob3 天前
Pico 4XVR 1.10.13安装包下载与安装教程 ico 4XVR最新版下载、4XVR 1.10.13 APK安装包、Pico VR看电影软件、4XVR完整版安装教程、Pico 4播放器推荐、V
android·vr·vr播放器·vr眼镜播放器下载·pico 4xvr·4xvr下载·pico 4xvr最新版安装包
Pursue Limits3 天前
人形机器人之VR遥操作
机器人·vr
音源部落3 天前
Cubase15 R2R/VR一键安装完整版本下载安装Nuendo 14最新版本下载安装支持Win/Mac 双系统版本加104G原厂音源Mac系统不关SIP安装编曲软件Cubase 15.0.10下载
macos·vr·cubase·cubase15·nuendo·nuendo14
菜鸟不学编程3 天前
鸿蒙中的 AR/VR 开发与场景创建
ar·vr·harmonyos
ar01233 天前
维修新机遇:AR远程协助助力智能化远程维修指导
人工智能·ar
北京阿法龙科技有限公司3 天前
AR智能眼镜在职业教育培训的应用指南 | 阿法龙XR云平台
ar·xr
720云3 天前
AI结合VR全景创作新范式,720云全景图一拍多用落地方法
vr·vr全景·720云
星幻元宇VR3 天前
VR消防安全学习机|沉浸式体验守护生命安全的新方式
科技·学习·安全·vr·虚拟现实