ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

A-Frame开发过程中相关问题的记录

2021-04-22 17:29:40  阅读:336  来源: 互联网

标签:记录 camera Frame 菜单栏 开发 组件 rotation PI frame


帮助文档很丰富,github上示例也很多,但开发起来还是有很多问题 T T
本次开发使用的是A-Frame 1.2.0版本,使用的是Oculus Rift S头盔,FireFox版本为78.10.0(高版本的可能有问题),记录的是已经解决的一些问题的思路,


1、组件传参

a-frame的整体是通过“实体-组件-系统”的概念实现的,js代码都是给实体添加组件,在组件的钩子函数中进行各种操作。但是a-frame未提供相应的数据共享方法,因此,可以通过修改组件的参数来实现传值
例如entity1的A组件要给entity2的B组件传递一个值,那么需要先在B组件的schema中定义B组件接收的参数X,然后A组件通过entity2.setAttribute的方法定义entity2的B组件的参数X的值,然后B组件在使用的时候就可以获取到更新过的参数X。如果需要大量传参,还可以定义一个数据共享的组件,专门用于各组件之间传值。

2、显示中文

a-frame默认的字体无法显示中文,可以在这个网站上选择字体以及需要显示的文字,生成对应字体的json文件与png文件才可以使用。使用的过程中发现标签的许多属性例如align属性不起作用,换成的写法之后才可以起作用。

3、点击事件

a-frame中的点击事件和web中的点击事件有所区别,只设置模型被点击时候的事件是不行的,必须设定射线投射器(raycaster),射线和模型表明相交时,才表明模型被点击了。对于需要求交的模型,设置其class为x,而将左右手柄的射线发射器raycaster的属性值设置为object: .x,这样才可以触发射线与模型相交的事件。

4、相机相对位置

由于菜单栏、手柄、信息框、属性图片都是显示在用户面前,即场景的相机面前的,每次当相机位置改变的时候,都需要调整手柄的位置,当菜单栏、信息框和属性图片显示的时候,都需要计算相机的位置再显示,这样是十分麻烦的。因此,可以根据相机建立一个局部坐标系,每次当相机移动的时候,菜单栏、手机、信息框和属性图片都一同移动。建立局部坐标系的方式为
在这里插入图片描述
外部id为rig的entity就是一个局部坐标系,这样当相机移动的时候,其实是rig的position将变化,camera的rotation变化,这样menu、hand、infoBox、infoImage的position就变为了相对于rig的position了,这样更方便位置的控制。

5、文字排版

a-frame中显示文字背景、实现hover效果和web端的实现思路有所差别,a-frame无法直接显示文字背景,而是在文字的后面显示一个plane的geometry来当做文字背景,且font的大小没有size等参数控制,只能通过scale等比缩放font,而hover效果必须通过鼠标的mouseenter、mouseleave实现,所以需要设置每个plane的class为对应的射线投射器的名字。并且,a-frame中没有div文字溢出、滚轮等方法,所以必须提前给每一个文字、横线、平面设定好大小和尺寸,动态控制它们scale或visible实现。

6、选择

当菜单栏、模型等可以通过射线投射器选择的entity,当设置其为visible为false时候,仅仅是让其不显示,但是射线投射器还是可以选择,例如当菜单栏隐藏的时候,右手还算可以选择对应菜单栏的某一项回到某位置,此时只是菜单栏没有显示,但是还是位于对应的位置,还是可以计算射线与entity是否相交,因此此时通过设置visible属性是存在一定问题的,最好的是同时设置scale属性,例如初始状态设置scale为0.0001 0.0001 0.0001,此时scale过小,大多数情况下射线与entity是无法相交的,而当entity应该显示是实话,设置scale为1 1 1,这样entity就可以正常显示、正常被选择了。

7、计算位置

计算菜单栏、信息框显示的时候,需要计算它们相对于用户当时的position,以及rotation。a-frame的position坐标系和rotation坐标系如下所示,是右手坐标系。rotation采用的欧拉角,默认的旋转顺序为x、y、z,因此x和z的取值范围为[-PI,PI],y的取值范围为[-PI/2,PI/2](这篇帖子有证明
在这里插入图片描述
在这里插入图片描述

由于菜单栏、信息框相对于用户移动的位置已经通过上面第三点解决了,此时只需要计算菜单栏、信息框相对于camera的位置。例如,当菜单栏初始位置为0 0 -1的时候,就是在用户初始视角正前方1个单位的位置,而当camera的rotation变为0 -90 0,即为右手边的方向时,此时菜单栏的位置应该是0 1 0。
(1)菜单栏只需要绕y轴旋转camera旋转的角度即可,但是,在开发过程中发现,由于y的取值范围为[-PI/2,PI/2],共180°,因此无法辨别绕y轴旋转360°不同的方向,所以,必须修改rotation的默认顺序,可以把XYZ变为YZX,这样y轴的取值范围就为[-PI,PI],符合要求。由于没有找到a-frame或three.js提供的响应接口,就直接修改源码。
在这里插入图片描述

所以rotation设置为0 theta 0即可,theta的值为camera.rotation.y。

(2)确定了菜单栏的rotation之后,还需要确定其位置,y值即为显示的高度,设置为camera的position.y即可,而x和z主要是根据theta以及菜单栏与camera的距离确定。设菜单栏的初始坐标为0 0 -r,然后相机旋转了theta角度,根据r和theta即可求得菜单栏的x值和z值。俯视图如下所示,三角形最小锐角对应的方向为视线或显示方向:
在这里插入图片描述
还需要注意计算时候的符号,由于在a-frame中上述的theta是负值,所以计算过程为:
在这里插入图片描述

标签:记录,camera,Frame,菜单栏,开发,组件,rotation,PI,frame
来源: https://blog.csdn.net/t865377557/article/details/116021134

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有