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

news2024/10/9 12:59:57

在Sceneform-EQR中实现旋转平移缩放手势

实现在AR/VR等三维场景,通过手势控制模型节点的缩放、平移和旋转。

实现思路

实现模型旋转

Sceneform-EQR(filament\opengl)中采用右手坐标系。通过欧拉角进行旋转采用Z->Y->X的顺序,在这里,我们不采用欧拉角控制旋转,而是采用四元数进行操作。因为四元数可进行插值,也方便后续对旋转操作做手势惯性。

采用四元数表示旋转
  • 实现思路:采用四元数的定义,通过旋转轴和旋转角度去构建四元数

旋转四元数相关定义可参考下面这个链接
链接:四元数:优雅而高效的空间旋转表示方法

  • 补充:四元数与欧拉角在线转换工具
    在这里插入图片描述
实现思路

采样四元数表示旋转 -> 通过旋转轴与旋转角度构造四元数

现已将问题转化为,通过安卓中的MotionEvent事件,构造旋转轴和旋转角度。

  • 示意图:
    在这里插入图片描述
  • 说明:

记:当前MotionEvent事件的触摸位置为B,上一MotionEvent事件的触摸位置为A。

那么,旋转轴与AB连线垂直,考虑AB的前进方向和右手坐标系,得出旋转轴的方向向量在AB前进方向的左侧。

因此这里,可以直接将AB向量绕点B逆时针旋转90度,得到的新向量即可表示旋转轴。

平面中,一个点(x,y)绕任意点(dx,dy)逆时针旋转a度后的坐标
xx= (x - dx)*cos(a) - (y - dy)*sin(a) + dx ;
yy= (x - dx)*sin(a) + (y - dy)*cos(a) +dy ;

这里,代入a=PI/2,dx = 向量AB的x,dy = 向量AB的y。x = 点B坐标的X,y = 点B坐标的Y。

此外,由于手机设备采用NDC坐标系,而当前渲染器采用同OpenGL的右手坐标系。

NDC坐标系的X方向 = GL的右手系的X方向
NDC坐标系的Y方向 = GL的右手系的-Y方向

因此,得出旋转轴为

//e1为点A对应的MotionEvent事件,e2为点B对应的MotionEvent事件
 x = 0 - (e1.y - e2.y),
 y = -/*取负是由于NDC坐标系和GL坐标系的Y轴正方向相反*/(e1.x - e2.x),
 z = 0f

最后说明,安卓的GestureDetector类提供了onScroll方法,通过重写onScroll方法即可。且由于onScroll方法提供了distanceX和distanceY。
因此,最后我们可以简化成如下的样子。

        lastRotationAxis.x = -distanceY;
        lastRotationAxis.y = -distanceX;
        lastRotationAxis.z = 0f;
源码定位

参考源码第137行

Commit记录

  • 新增手势控制器
    private void onOneFingerScroll(float distanceX, float distanceY) {
        if (isScaling || isDoubleFingerScroll)return;
        //单指实现旋转
        double distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
        //原理:
        // 求AB两点(当前时刻的位置为B,上一时刻的位置为A)的垂线(这里是求旋转平面的法向量),
        // (将垂线的一个方向作为正方向,这里当作旋转平面的法向量)再将这个方向向量作为旋转轴。
        // 根据绕轴旋转定义四元数。
        // 这里将求垂线 => 简化成绕点旋转90度。因为求垂线后仍然需要考虑方向,而绕B点逆时针旋转90度即可得到B2。‘AB2’则是目标向量
        //注意:安卓设备坐标系与OpenGL右手坐标系的XY方向。
//            dev.romainguy.kotlin.math.Float3(
//                x = 0 - (e1.y - e2.y)/* + e2.x*/,
//                y = -/*取负是由于NDC坐标系和GL坐标系的Y轴正方向相反*/(e1.x - e2.x)/* + e2.y*/,
//                z = 0f
//            )
        //改成使用distanceX/Y,简化后如下:
        lastRotationAxis.x = -distanceY;
        lastRotationAxis.y = -distanceX;
        lastRotationAxis.z = 0f;
        //todo 这里后续修改,为改用射线检测实现精准控制
        Quaternion rotation = Quaternion.axisAngle(lastRotationAxis, (float) Math.toRadians(distance * 0.168f));
        Quaternion localRotation = target.getLocalRotation();
        target.setLocalRotation(Quaternion.multiply(rotation,localRotation));
    }

实现模型缩放

模型缩放较为简单,借助安卓提供的ScaleGestureDetector即可检测到scale值

源码定位
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        isScaling = true;
        if (target == null)return false;
        float scaleFactor = detector.getScaleFactor();
        target.setLocalScale(scaleTmp.scaled(scaleFactor));
        return false;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        if (target == null)return false;
        scaleTmp = target.getLocalScale();
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        isScaling = false;
    }

实现模型平移

最容易想到的是,通过手势的Move事件的distanceX\Y,直接去修改所渲染的模型节点的position。

这种实现思路有两个弊端,一个是由于不同设备的屏幕密度不同会导致每台设备的平移效果不一致,二是无法精准控制平移的位置。

下一篇将介绍采用射线检测的方式去做平移。



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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2199081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dart-sass和node-sass的区别,使用dart-sass后可能会出现的问题

前言: 2020 年 10 月 27 日,Sass 官方团队正式宣布 Libsass 将弃用,以及基于它的 Node Sass 和 SassC,并且建议用户使用 Dart Sass。如果在 vue 脚手架搭建的项目中需要使用 sass,建议初始化时勾选 sass 配置&#xff…

MySQL数据库备份与恢复:全面指南

MySQL数据库备份与恢复:全面指南 MySQL数据库是许多应用程序的核心组件,数据的安全和可用性至关重要。无论是由于硬件故障、软件错误,还是人为操作失误,数据丢失的风险都时刻存在。因此,做好数据库的备份与恢复工作是…

前端无感刷新token机制(一文说明白)

前言 用户登录之后,会返回一个用户的标识,之后带上这个标识请求别的接口,就能识别出该用户。 标识登录状态的方案有两种: session 和 jwt。这两种方案一个服务端存储,通过 cookie 携带标识,一个在客户端存…

研发中台拆分之路:深度剖析、心得总结与经验分享

背景在 21 年,中台拆分在 21 年,以下为中台拆分的过程心得,带有一定的主观,偏向于中小团队中台建设参考(这里的中小团队指 3-100 人的团队),对于大型团队不太适用,毕竟大型团队人中 …

leetcode C++特性 AIDL的一些细节

leetcode细节 C的一些特性 【C基础】std::move用法介绍-CSDN博客 c thread的join和joinable的区别_thread joinable-CSDN博客 C线程介绍_std::thread 头文件-CSDN博客 https://blog.csdn.net/weixin_46645965/article/details/136259902 【C】—— 观察者模式-CSDN博客 C 迭…

LabVIEW交直流接触器动态检测系统

LabVIEW软件与霍尔传感器技术结合的交直流接触器动态检测系统通过实时数据采集和处理技术,有效地测量并分析交直流接触器在吸合及吸持阶段的电流和电压变化,以及相应的功率消耗,从而优化电力和配电系统的性能和可靠性。 项目背景 交直流接触…

在供应商准入时,如何规避风险、提高效率?

在进行供应商准入时,进行风险审核是至关重要的步骤,它有助于确保供应链的稳定性和企业的长期成功。通过风险审核,企业可以确保供应商提供的产品或服务符合质量标准,同时评估供应商的财务稳健性,以降低供应链中断的风险…

电桥的作用是什么?

一、电桥的基本概念和原理 电桥是一种测量电阻、电容、电感等电学量的仪器,其原理基于电路中的克希荷夫定律以及欧姆定律。电桥由四个电阻分支组成,在精确测量电阻时,需要把待测电阻与一个已知电阻进行比较,通过调节电桥中的一个…

如何微调LLM大模型?看这一篇就够了!

在这篇文章中,我们将探讨一些用于策划高质量训练数据集的经验法则。 第一部分探讨了将LLM适应于领域数据的普遍方法第二部分讨论了咋确定微调是否适用于你的实际情况 1 介绍 微调LLMs是一门艺术与科学的结合,该领域的最佳实践仍在不断发展中。在本篇博…

【开源风云】从若依系列脚手架汲取编程之道(五)

📕开源风云系列 🍊本系列将从开源名将若依出发,探究优质开源项目脚手架汲取编程之道。 🍉从不分离版本开写到前后端分离版,再到微服务版本,乃至其中好玩的一系列增强Plus操作。 🍈希望你具备如下…

基于Java(Jsp+Sevlet)+MySql 实现的(Web)成绩管理系统

1 概述 1.1 开发背景 随着学生数量的日渐增多,学生教务系统的数据量也不断增加,这无疑大大增加了教务系统的负担。如果能把负责学生成绩管理的模块独立出来形成一个独立的系统,便可以有效降低教务系统的数据量,不仅可以方便管理…

封装el-upload组件,用于上传图片和视频的组件

使用环境 vue3element plus 需要根据后端返回结构修改的函数&#xff1a;onPreview onRemove onSuccess 组件使用 基本使用 源代码&#xff1a; <script setup> import AutoUploadFile from /components/auto-upload-file/index.vue function change(urls){console.log…

懂球短视频系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;上传视频管理&#xff0c;用户管理&#xff0c;懂球视频管理&#xff0c;分享视频管理&#xff0c;收藏视频管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;上传视频&a…

深入剖析递归算法:原理、特点、应用与优化策略

在上一篇文章&#x1f449;【剖析十大经典二叉树题目】中&#xff0c;运用到了大量的递归算法&#xff0c;故本文将解析递归算法。 目录 &#x1f4af;引言 &#x1f4af;递归算法的定义与原理 ⭐定义 ⭐原理 &#x1f4af;递归算法的特点 ⭐简洁性 ⭐可读性 ⭐通用性 …

【Java】单例模式详解与实践

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; 单例模式 Singleton是一种常用的软件模式&#xff0c;确保一个类只有一个实例&#xff0c;并提供一个全局访问方法来获取这个实例。这种模式广泛应用于需要控制实例化次数的场景&#xff0c;如数据库…

昇思MindSpore进阶教程--数据处理性能优化(中)

大家好&#xff0c;我是刘明&#xff0c;明志科技创始人&#xff0c;华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享&#xff0c;如果你也喜欢我的文章&#xff0c;就点个关注吧 shuffle性能优化 shuffle操作主要是对有…

VMware ESXi 8.0U3 集成 AQC 网卡定制版更新 OEM BIOS 2.7 支持 Windows Server 2025

VMware ESXi 8.0U3 集成 AQC 网卡定制版更新 OEM BIOS 2.7 支持 Windows Server 2025 VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U3 集成驱动版&#xff0c;在个人电脑上运行企业级工作负载 请访问原文链接&…

数字化转型引领新时代:从架构到产品的全链路创新解析

在当前瞬息万变的商业环境中&#xff0c;数字化转型已经成为各类组织的核心战略手段。本文从数字化专业知识体系 (DPBOK) 中提炼出最具价值的核心观点&#xff0c;详细分析了数字化转型对企业的影响、实现路径&#xff0c;以及如何通过技术创新、文化转变和管理优化&#xff0c…

YOLO11涨点优化:注意力魔改 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文全网首发独家改进&#xff1a;多尺度卷积注意力&#xff08;MSCA&#xff09;&#xff0c;有效地提取上下文信息&#xff0c;新颖度高&#xff0c;创新十足。 &#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进&#xff1a;分别加入…

协议转换器——连接未来生产的纽带

智能制造作为制造业前沿趋势&#xff0c;面临不同设备和系统间通信协议不兼容导致的信息交换困难。我们自主研发的MG协议转换器作为桥梁与纽带&#xff0c;实现了不同设备和系统间的顺畅数据交换&#xff0c;提高了生产效率&#xff0c;降低了生产成本。在工业自动化和能源管理…