Как я могу сделать видео AR, чтобы всегда стоять лицом к камере пользователя с маркером Vuforia родной Android - PullRequest
0 голосов
/ 19 мая 2018

Я работаю над маркером AR с родной Android vuforia. Я пытаюсь сделать так, чтобы мой видеообъект перемещался в соответствии с камерой (она всегда должна быть направлена ​​на камеру). Я пытался следовать, но он не работает, но иногда он работает, но не сохраняется.

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();


    }

До сих пор я пробовал выше, и это иногда работает, но не правильно Пожалуйста, помогите мне, я пытаюсь сделать это через неделю. enter image description here

1 Ответ

0 голосов
/ 19 мая 2018

Я пытаюсь сделать, это переместить мой видеообъект в соответствии с камерой (он всегда должен быть направлен в сторону камеры)

Если вы хотите, чтобы объект был направлен в камеру (Billboarding), тогдаВы должны использовать матрицу модели, которая является матрицей обратного просмотра, но без части перевода.Используйте 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 таким жеэто вертикально от любого вида

То, что вы хотите сделать, это зафиксировать направление вверх, но ориентировать вектор нормали к линии визирования.

Линия визированияобратная ось 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] );

Eiterh Ось Y (0, 1, 0) или ось Z (0, 1, 0) модели должна быть осью Z матрицы ориентации.Ось X - это перекрестное произведение (Vec3FCross) линии визирования и оси Z матрицы ориентации.

например,

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);
...