Android Google VR如何使用daydream controller执行选择

Android Google VR如何使用daydream controller执行选择,android,opengl-es-2.0,daydream,Android,Opengl Es 2.0,Daydream,下面是我的情况 我有一个矩形,左=0,右=1824,上=0,下=989,纵横比为1.84f,z轴为-3f 在这个矩形中,我有宽度和高度分别为344和182的小矩形。我将这些小矩形排列成3行3列,类似于网格画廊 我在不改变z轴的情况下对正交投影做了一些修改,使得新矩形在x轴的范围为-1,84到1.84,在y轴的范围为1到-1,所有小矩形都在这些范围内 然后,为了在VR上渲染这些矩形,我只需应用 view=perspective(z近0.1f,远100 f)*eye.getEyeVew 模型=范围

下面是我的情况

  • 我有一个矩形,左=0,右=1824,上=0,下=989,纵横比为1.84f,z轴为-3f
  • 在这个矩形中,我有宽度和高度分别为344和182的小矩形。我将这些小矩形排列成3行3列,类似于网格画廊
  • 我在不改变z轴的情况下对正交投影做了一些修改,使得新矩形在x轴的范围为
    -1,84到1.84,在y轴的范围为
    1到-1,所有小矩形都在这些范围内
  • 然后,为了在VR上渲染这些矩形,我只需应用

    view=perspective(z近0.1f,远100 f)*eye.getEyeVew
    模型=范围(-1.84f到1.84f:X,1到1f:Y)内的正交变换
    模型视图=视图*模型

  • 为了模拟控制器,我使用了一个带有
    的简单圆(centerX=0,centerY=0,radius=0.04f,zaxis=-3f)

  • 将以下变换应用于具有控制器旋转矩阵()的圆

    view=perspective(z近0.1f,远100 f)*eye.getEyeVew
    controllerMatrix=controller.toRotationMatrix
    modelView=视图*控制器矩阵

我的假设是:

  • 以来,我用统一的Z值绘制3D平面,我可以把它们看作是一个2D平面来选择。<李>
  • 我假设圆二维坐标(左、上、右、下)可以用于检查平面二维坐标(左、上、右、下),并查看圆是否落在平面中
  • 但是由于perspective&eye.getEyeView变换,圆和平面的z轴都会发生变化
因此,我的问题是,出于这个目的,我应该选择光线投射,还是有一个简单的解决方案来选择带有VR控制器的小矩形。 我正在使用GVR控制器
(谷歌VR 1.80.0版)
,并使用Android进行应用程序开发


谢谢

Google VR SDK附带了一些有用的示例项目,演示了如何实现这一点。如果检查,则
活动
类有一个方法
isLookingAtObject()

private boolean isLookingAtObject(){
//将对象空间转换为摄影机空间。使用onNewFrame中的头视图。
矩阵.multiplyMM(modelView,0,headView,0,modelCube,0);
矩阵.multiplyMV(tempPosition,0,modelView,0,POS\u Matrix\u MULTIPLY\u VEC,0);
浮动节距=(浮动)数学atan2(tempPosition[1],-tempPosition[2]);
浮动偏航=(浮动)数学atan2(tempPosition[0],-tempPosition[2]);
返回Math.abs(俯仰)
这将计算摄像机视线方向上的矢量与
modelCube
矩阵之间的角度。
modelCube
矩阵是一个4x4矩阵,用于定义三维场景中对象中心点的比例、旋转和平移。在您的例子中,这将是三维空间中矩形的中心点

还必须计算定义摄影机指向方向的向量与矩形相交的角度。下图对此进行了描述:

这里的原点是您的相机位置,点C是在3D空间中渲染的矩形的质心,矢量OC是相机直接聚焦在矩形中心时指向的方向矢量。Ꝋ 是从X轴到X-Z平面中的点C的角度。点P1-4是三维空间中矩形的顶点

螺距ɸ在下图中定义:

这里ɸ是从中心点C到新轴e的角度

PITCH\u LIMIT
是两个向量之间Y-e平面上的角度。从摄影机位置到对象边界框底部边缘的矢量以及从摄影机位置到对象边界框上部边缘的矢量。在这种情况下,它可以计算为OP3OP4之间的角度,或者OP2OP1之间的角度。这在以下2D横截面中进行了描述:

假设相机正直视矩形,此限制定义相机在中心不再直接指向矩形之前必须向上倾斜的程度

YAW_LIMIT
是X-Z平面上两个向量之间的角度,即从摄影机位置到对象边界框最左侧边缘的向量,以及从摄影机位置到对象边界框最右侧边缘的向量。在这种情况下,它可以计算为OP1OP4之间的角度,或者OP2OP3之间的角度。这在以下2D横截面中进行了描述:

同样,此限制定义了在相机中心不再直接指向矩形之前,相机可以向左或向右旋转的程度


请注意,
YAW_LIMIT
PITCH_LIMIT
值在离对象越远的情况下越小,在靠近对象的情况下越大。必须根据对象的当前摄影机位置和边顶点计算要检查的对象的这些限制。从对象空间到摄影机空间的坐标转换在
isLookingAtObject()
方法中处理。

首先,需要查看由提供的上述详细说明,其中包含与问题相关的所有概念。我感谢你提供了一个与这个问题相关的非常好的概念
private boolean isLookingAtObject() {
    // Convert object space to camera space. Use the headView from onNewFrame.
    Matrix.multiplyMM(modelView, 0, headView, 0, modelCube, 0);
    Matrix.multiplyMV(tempPosition, 0, modelView, 0, POS_MATRIX_MULTIPLY_VEC, 0);

    float pitch = (float) Math.atan2(tempPosition[1], -tempPosition[2]);
    float yaw = (float) Math.atan2(tempPosition[0], -tempPosition[2]);

    return Math.abs(pitch) < PITCH_LIMIT && Math.abs(yaw) < YAW_LIMIT;
}
Vertices:  X     Y     Z
      P1: 0.52   0.76  -2.40  //LeftTop
      P2: 0.52   0.21  -2.40  //LeftBottom
      P3: 1.54   0.21  -2.40  //RightBottom
      P4: 1.54   0.76  -2.40  //Right Top
Formula:  
    YAW: Math.atan2(x,-z)
  PITCH: Math.atan2(y,-z)
//Then yaw, pitch values for above vertices will be
         YAW   PITCH
     P1: 0.21  0.31  //LeftTop
     P2: 0.21  0.09  //LeftBottom
     P3: 0.57  0.09  //RightBottom
//We don't require P4 here
      YAW Left: 0.21 ( P2 or P1 YAW)
      YAW Right: 0.57 ( P3 YAW )
    PITCH Top: 0.31 ( P1 PITCH )
    PITCH Bottom: 0.09  ( P2 or P3 PITCH )
// let us find the pitch and yaw values of controllers as well
   angles = controller.orientation.toYawPitchRollRadians
   angles[0]: YAW
   angles[1]: PITCH
   angles[2]: ROLL
 //of controller
 // controller YAW moves positive to negative from left to right, but in 
 // normalized coordinates, negative to positive from left to right, so to 
 // match controller's YAW values
      YAW Left: 0.21 * -1 ( P2 or P1 YAW)
      YAW Right: 0.57 * -1 ( P3 YAW )
    PITCH Top: 0.31 ( P1 PITCH )
    PITCH Bottom: 0.09  ( P2 or P3 PITCH )
 // and to know whether the controller is at the rectangle or not we simply do
    public boolean isOnRectangle(float[] angles) {
    return angles[0] <= yawLeft && angles[0] >= yawRight
            && angles[1] <= pitchTop && angles[1] >= pitchBottom;
}