Log in or register to post comments

How does Vuforia recognize two Targets, and draw one target's moving path in another target's coordinates system?

March 2, 2017 - 2:34am #1

Hello everyone,

    Here is my code:

    [self setFramebuffer];
    
    // Clear colour and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // Render video background and retrieve tracking state
    [sampleAppRenderer renderVideoBackground];
    
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);
    // We must detect if background reflection is active and adjust the culling direction.
    // If the reflection is active, this means the pose matrix has been reflected as well,
    // therefore standard counter clockwise face culling will result in "inside out" models.
    if (offTargetTrackingEnabled) {
        glDisable(GL_CULL_FACE);
    } else {
        glEnable(GL_CULL_FACE);
    }
    glCullFace(GL_BACK);
    
    Vuforia::Matrix44F mainModelViewMatrix;
    
    for (int i = 0; i < state.getNumTrackableResults(); ++i) {
        // Get the trackable
        const Vuforia::TrackableResult* result = state.getTrackableResult(i);
        const Vuforia::Trackable& trackable = result->getTrackable();
        const char* trackerName = trackable.getName();
        
        Vuforia::Matrix44F modelViewMatrix = Vuforia::Tool::convertPose2GLMatrix(result->getPose());
        
        
        Vuforia::Vec4F position;
        if (trackerName == "base") {
            
            mainModelViewMatrix = modelViewMatrix;
//            totalRenderCenters[0].data[0] = 0.0f;
//            totalRenderCenters[0].data[1] = 0.0f;
//            totalRenderCenters[0].data[2] = 0.0f;
            
//            position = {0.0f, 0.0f, 0.0f, 1.0f};
        } else {
            
            if (lastIndexOfRender == 1) {
                Vuforia::Matrix44F mainModelViewInverse = SampleMath::Matrix44FInverse(mainModelViewMatrix);
                Vuforia::Matrix44F qrcode2base = Vuforia::Tool::multiply(modelViewMatrix, mainModelViewInverse);
                float x = qrcode2base.data[12];
                float y = qrcode2base.data[13];
                float z = qrcode2base.data[14];
                totalRenderCenters[lastIndexOfRender - 1].data[0] = x;
                totalRenderCenters[lastIndexOfRender - 1].data[1] = y;
                totalRenderCenters[lastIndexOfRender - 1].data[2] = z;
                lastRenderPosition = {x,y,z,1.0f};
            } else if (lastIndexOfRender > 1) {
                Vuforia::Matrix44F mainModelViewInverse = SampleMath::Matrix44FInverse(mainModelViewMatrix);
                Vuforia::Matrix44F modelViewTranspose = SampleMath::Matrix44FTranspose(modelViewMatrix);
                Vuforia::Matrix44F offsetMatrix = Vuforia::Tool::multiply(mainModelViewInverse, modelViewTranspose);
                
                position = lastRenderPosition;
                position = SampleMath::Vec4FTransform(position, offsetMatrix);
                lastRenderPosition = position;
//                position = SampleMath::Vec4FDiv(position, 0.000001);
                totalRenderCenters[lastIndexOfRender - 1].data[0] = position.data[0];
                totalRenderCenters[lastIndexOfRender - 1].data[1] = position.data[1];
                totalRenderCenters[lastIndexOfRender - 1].data[2] = position.data[2];
            }
            lastIndexOfRender++;
        }
        
        
        
//        // OpenGL 2
//        mainModelViewMatrix = modelViewMatrix;
//            
//        Vuforia::Matrix44F mainModelViewInverse = SampleMath::Matrix44FInverse(mainModelViewMatrix);
//        Vuforia::Matrix44F modelViewTranspose = SampleMath::Matrix44FTranspose(modelViewMatrix);
//        Vuforia::Matrix44F offsetMatrix = Vuforia::Tool::multiply(mainModelViewInverse, modelViewTranspose);
//            
//        Vuforia::Vec4F position(0.0f, 0.0f, 0.0f, 1.0f);
//        if (lastIndexOfRender > 1) {
//            position = lastRenderPosition;
//        }
//        position = SampleMath::Vec4FTransform(position, offsetMatrix);
//        lastRenderPosition = position;
//        position = SampleMath::Vec4FDiv(position, 0.000005);
//        
//        totalRenderCenters[lastIndexOfRender].data[0] = position.data[0];
//        totalRenderCenters[lastIndexOfRender].data[1] = position.data[1];
//        totalRenderCenters[lastIndexOfRender].data[2] = position.data[2];
//        
////        glBufferSubData(GL_ARRAY_BUFFER, sizeof(position)*(lastIndexOfRender-1), sizeof(position), &position);
//        
//        lastIndexOfRender++;
    }
    
    Vuforia::Matrix44F modelViewProjection;
    SampleApplicationUtils::multiplyMatrix(&projectionMatrix.data[0], &mainModelViewMatrix.data[0], &modelViewProjection.data[0]);
    glUseProgram(shaderProgramID);
//    glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &totalRenderCenters[0].data[0]);
    glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &totalRenderCenters[0].data[0]);
    glEnableVertexAttribArray(vertexHandle);
    glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (GLfloat*) &modelViewProjection.data[0]);
    glLineWidth(20.0f);
//    glDrawArrays(GL_LINES, 0, lastIndexOfRender);
    glDrawArrays(GL_LINE_LOOP, 0, lastIndexOfRender);
    
    glEnable(GL_TEXTURE_2D);
    glDisableVertexAttribArray(vertexHandle);
    glDisableVertexAttribArray(normalHandle);
    glDisableVertexAttribArray(textureCoordHandle);
    
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    
    [self presentFramebuffer];

After call method "SampleMath::Matrix44FInverse(mainModelViewMatrix)", there is NaN in variable mainModelViewInverse. At last, there is nothing rendered in the screen. 

 

Anybody can Help me?

Thanks!

How does Vuforia recognize two Targets, and draw one target's moving path in another target's coordinates system?

March 2, 2017 - 3:46am #2

For a start you should initialize `mainModelViewMatrix` with identity because if you detect the other marker first you're going to compute the inverse of an uninitialized matrix.

Put a breakpoint at the `::Matrix44FInverse` call and check the content of the matrix passed as argument, does it look good?

Log in or register to post comments