【Sceneform-EQR】使用安卓设备的传感器实现3Dof的VR效果

使用安卓设备的传感器实现3Dof的VR效果

渲染框架

Sceneform-EQR:
这是我对sceneform的扩展,目前已依赖最新版本(v1.54)的filament。

安卓传感器

利用 Android 传感器框架,可以访问多种类型的传感器。其中一些传感器 基于硬件,有些基于软件。基于硬件的传感器是构建的物理组件 手机或平板设备他们通过直接测量特定环境状况来推导出数据 例如加速度、地磁场强度或角度变化。基于软件 虽然它们模拟了基于硬件的传感器,但它们不是物理设备。基于软件的传感器 从一个或多个基于硬件的传感器获取数据,有时也称为虚拟传感器, 传感器或合成传感器例如,线性加速度传感器和重力传感器 基于软件的传感器。下图 总结了 Android 支持的传感器 平台。

很少有 Android 设备拥有所有类型的传感器。例如,大多数手机设备和 带有加速度计和磁力计的平板电脑,但配备 气压计或温度计此外,一个设备可以有多个特定类型的传感器。对于 例如,一个设备可以有两个重力传感器,每个重力传感器的范围各不相同。
Android 平台支持的传感器类型。

实现步骤

步骤简述:通过使用安卓的传感器获取到实时的三轴旋转角度,再同步给场景相机,即可实现3dof的VR效果。

通过旋转矢量传感器获取方位角

  • 注册传感器
    public void registerListener(){
        mSensorManager.registerListener(this,mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
                SensorManager.SENSOR_DELAY_GAME);
    }
  • 获取方位角
    @Override
    public void onSensorChanged(SensorEvent event) {
        //1.
        switch (event.sensor.getType()) {
            case Sensor.TYPE_ROTATION_VECTOR:
                processSensorOrientation(event.values);
                break;
        }
    }
  • 处理方位角

这里需要针对手机的旋转状态(横屏or竖屏)作处理。

    private void processSensorOrientation(float[] srcRotation) {
        float[] rotationMatrix = new float[9];
//        float[] rotation = {-srcRotation[1],srcRotation[2],srcRotation[0]};
        SensorManager.getRotationMatrixFromVector(rotationMatrix, srcRotation);
        final int worldAxisX;
        final int worldAxisY;

        switch (windowManager.getDefaultDisplay().getRotation()) {
            case Surface.ROTATION_90:
                worldAxisX = SensorManager.AXIS_Z;
                worldAxisY = SensorManager.AXIS_MINUS_X;
                break;
            case Surface.ROTATION_180:
                worldAxisX = SensorManager.AXIS_MINUS_X;
                worldAxisY = SensorManager.AXIS_MINUS_Z;
                break;
            case Surface.ROTATION_270:
                worldAxisX = SensorManager.AXIS_MINUS_Z;
                worldAxisY = SensorManager.AXIS_X;
                break;
            case Surface.ROTATION_0:
            default:
                worldAxisX = SensorManager.AXIS_X;
                worldAxisY = SensorManager.AXIS_Z;
                break;
        }
        float[] adjustedRotationMatrix = new float[9];
        SensorManager.remapCoordinateSystem(rotationMatrix, worldAxisX,
                worldAxisY, adjustedRotationMatrix);

        // yaw/pitch/roll
        float[] orientation = new float[3];
        SensorManager.getOrientation(adjustedRotationMatrix, orientation);
        }

这时,获取到的orientation中三个分量,分别表示方位角、俯仰角、横滚角。
下一步我们需要将其转为渲染框架中设置相机姿态所需的四元数。

将欧拉角转为旋转四元数

  • 将角度转为四元数

注意:这里需要注意设备坐标系和渲染框架坐标系的方向的区别。
下面传入的参数更改了坐标轴。

    /**
     * 计算旋转四元数
     * @return ENU坐标系的姿态//东北天坐标系
     */
    private Quaternion calculateRotation(float yaw,float pitch,float roll){
        return PoseUtils.toQuaternion(-pitch, -yaw, -roll);
    }

更新场景相机的姿态

获取场景相机,并更新其Rotation

getScene().getCamera().setWorldRotation(quaternion);

运行效果

VR效果

在这里插入图片描述

下图源于:通过手势事件实现在AR/VR等三维场景中的控制模型旋转、平移与缩放
由于采用同一个场景,因此不再额外录屏上传

补充:3Dof的AR效果可用同样的方式实现,只是需要额外接入相机实时预览画面。可以使用安卓提供的Camera2类实现。

源码示例

请转至github查看。链接:Sceneform-EQR

相关类

  • VrSceneView.java

Git仓库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EQ-雪梨蛋花汤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值