【问题标题】:How can I make AR video to always face user's camera with marker vuforia native android如何使用标记 vuforia 本机 android 制作 AR 视频以始终面对用户的相机
【发布时间】:2018-10-29 17:37:11
【问题描述】:

我正在使用原生 android vuforia 开发标记 AR 我想要做的是根据相机移动我的视频对象(它应该始终面向相机)我尝试跟随但它不工作但有时它工作但它不是持久性

public void renderFrame(State state, float[] projectionMatrix) {

        mSampleAppRenderer.renderVideoBackground();
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);

        isTracking = false;

        for (int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++) {
            TrackableResult trackableResult = state.getTrackableResult(tIdx);
            ImageTarget imageTarget = (ImageTarget) trackableResult
                    .getTrackable();
            imageTarget.startExtendedTracking();

            isTracking = true;

            float[] modelViewMatrixVideo = Tool.convertPose2GLMatrix(
                    trackableResult.getPose()).getData();
            float[] modelViewProjectionVideo = new float[16];



            Matrix44F invTranspMV = SampleMath.Matrix44FTranspose(SampleMath.Matrix44FInverse(Tool.convertPose2GLMatrix(trackableResult.getPose())));


            Matrix.translateM(modelViewMatrixVideo, 0, 0f, 0f, 1f);
            Matrix.rotateM(modelViewMatrixVideo, 0, (float) Math.toDegrees(Math.asin(-invTranspMV.getData()[6])), 0.0f, 0.f, 1.0f);


            Matrix.multiplyMM(modelViewProjectionVideo, 0,
                    projectionMatrix, 0, modelViewMatrixVideo, 0);


            GLES20.glEnable(GLES20.GL_BLEND);
            GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
            GLES20.glUseProgram(videoPlaybackShaderID);


            GLES20.glVertexAttribPointer(videoPlaybackVertexHandle, 3,
                    GLES20.GL_FLOAT, false, 0, quadVertices);

            GLES20.glVertexAttribPointer(videoPlaybackTexCoordHandle,
                    2, GLES20.GL_FLOAT, false, 0,
                    fillBuffer(videoQuadTextureCoordsTransformedStones));

            GLES20.glEnableVertexAttribArray(videoPlaybackVertexHandle);
            GLES20.glEnableVertexAttribArray(videoPlaybackTexCoordHandle);

            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);


            GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                    videoPlaybackTextureID);
            GLES20.glUniformMatrix4fv(videoPlaybackMVPMatrixHandle, 1,
                    false, modelViewProjectionVideo, 0);

            GLES20.glDrawElements(GLES20.GL_TRIANGLES, NUM_QUAD_INDEX,
                    GLES20.GL_UNSIGNED_SHORT, quadIndices);

            GLES20.glDisableVertexAttribArray(videoPlaybackVertexHandle);
            GLES20.glDisableVertexAttribArray(videoPlaybackTexCoordHandle);

            GLES20.glUseProgram(0);
            GLES20.glDisable(GLES20.GL_BLEND);

            SampleUtils.checkGLError("VideoPlayback renderFrame");
        }

        GLES20.glDisable(GLES20.GL_DEPTH_TEST);

        Renderer.getInstance().end();


    }

到目前为止,我已经尝试过上述方法,并且它有时可以正常工作但不能正常工作 请帮助我,我正在尝试从一周开始这样做。

【问题讨论】:

    标签: android opengl-es native augmented-reality vuforia


    【解决方案1】:

    我想做的是根据相机移动我的视频对象(它应该始终面向相机)

    如果你想让一个物体面对相机(Billboard),那么你必须使用一个模型矩阵,它是逆视图矩阵,但没有平移部分。 使用Matrix44FInverse,得到Matrix44F的逆矩阵:

    public void renderFrame(State state, float[] projectionMatrix) {
    
        .....
    
        // get the view matrix and set translation part to (0, 0, 0)
        float[] tempViewMat = Tool.convertPose2GLMatrix(trackableResult.getPose()).getData();
        tempViewMat[12] = 0;
        tempViewMat[13] = 0;
        tempViewMat[14] = 0;
    
        // create the billboard matrix 
        Matrix44F billboardMatrix = new Matrix44F();
        billboardMatrix.setData(tempViewMat);
        billboardMatrix = SampleMath.Matrix44FInverse(billboardMatrix);
    
        // calculate the model view projection matrix
    
        float[] viewMatrixVideo = Tool.convertPose2GLMatrix(trackableResult.getPose()).getData();
    
        float[] modelViewVideo = new float[16];
        Matrix.multiplyMM(modelViewVideo, 0, viewMatrixVideo, 0, billboardMatrix.getData(), 0);
    
        float[] modelViewProjectionVideo = new float[16];
        Matrix.multiplyMM(modelViewProjectionVideo, 0, projectionMatrix, 0, modelViewVideo, 0);
    
        .....
    }
    

    我使用了你的代码,但我的 AR 向各个方向旋转,但我想要一些不同的东西相机,这样我就可以从任何角度看到我的 AR 视频都是垂直的

    您要做的是固定向上的方向,但将法向量定向到视线。

    视线是Right-Handed Coordinate System中视图空间的逆Z轴。

    Matrix44F inverse_view = SampleMath.Matrix44FInverse(
        Tool.convertPose2GLMatrix(trackableResult.getPose()));
    
    // line of sight  
    Vec3F los = new Vec3F(-inverse_view[8], -inverse_view[9], -inverse_view[10] );
    

    模型的 Y 轴 (0, 1, 0) 或 Z 轴 (0, 1, 0) 必须是 Z-方向矩阵的轴。 X 轴是视线和方向矩阵的 Z 轴的叉积 (Vec3FCross)。

    例如

    Vec3F z_axis = new Vec3F(0, 0, 1);
    Vec3F x_axis = Vec3FNormalize(Vec3FCross(los, z_axis));
    Vec3F y_axis = Vec3FCross(z_axis, x_axis);
    

    float[] orientationMatrix = new float[]{
        x_axis.getData()[0], x_axis.getData()[1], x_axis.getData()[2], 0,
        y_axis.getData()[0], y_axis.getData()[1], y_axis.getData()[2], 0,
        z_axis.getData()[0], z_axis.getData()[1], z_axis.getData()[2], 0,
        0,                   0,                   0,                   1
    };
    
    // calculate the model view projection matrix
    
    float[] viewMatrixVideo = Tool.convertPose2GLMatrix(trackableResult.getPose()).getData();
    
    float[] modelViewVideo = new float[16];
    Matrix.multiplyMM(modelViewVideo, 0, viewMatrixVideo, 0, orientationMatrix, 0);
    
    float[] modelViewProjectionVideo = new float[16];
    Matrix.multiplyMM(modelViewProjectionVideo, 0, projectionMatrix, 0, modelViewVideo, 0);
    

    【讨论】:

    • 感谢您的回答。我使用了您的代码,但我的 AR 向各个方向旋转,但我想要一些不同的东西我会看到我的 AR 视频从任何角度看都是垂直​​的。 @Rabbid76
    • 嘿,使用您的新解决方案,我的视频正在以正确的方向旋转,但相机移动错误意味着当我围绕 z 轴旋转手机时,但当我围绕 y 轴移动相机时我想要相同的旋转,所以视频将永远面对相机,就像一个男人总是看着相机一样
    • @MirzaAhmedBaig 还有另一个变种Vec3F z_axis = new Vec3F(0, 0, 1); Vec3F x_axis = Vec3FNormalize(Vec3FCross(los, z_axis)); Vec3F y_axis = Vec3FCross(z_axis, x_axis);。顺便说一句,链接不起作用:“缺少所需的权限”
    • @MirzaAhmedBaig 因为我无法调试您的应用程序,所以我唯一可以调查的是您链接中的视频。在我放弃之前的最后一次尝试:Vec3F z_axis = new Vec3F(0, 1, 0);Vec3F x_axis = Vec3FNormalize(Vec3FCross(los, z_axis));Vec3F y_axis = Vec3FCross(z_axis, x_axis);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多