Certain applications need to be able to move the augmentation 3D model in a plane parallel to the screen; for instance this is a tyical requirement for applications where the user can drag the object around by tapping on the screen.
This article provides a quick guide on how to achieve that using the ImageTargets sample as a reference.
The first thing you need to do is to add a global variable to keep track of the 3D model overall displacement in the native code in ImageTargets.cpp:
QCAR::Vec3F targetCumulatedDisplacement(0.0f, 0.0f, 0.0f);
then you need to write some code to compute the conversion of the displacement vector from screen-aligned coordinates to object coordinates (i.e. to represent the vector in the target local reference frame):
void computeTargetTranslationFromScreenVector(float screenDeltaX, float screenDeltaY, QCAR::Matrix44F & modelViewMatrix, QCAR::Vec3F & result) { QCAR::Vec3F screenAlignedDisplacement; screenAlignedDisplacement.data[0] = screenDeltaX; screenAlignedDisplacement.data[1] = screenDeltaY; screenAlignedDisplacement.data[2] = 0.0f; // Compute matrix to pass from Eye Coordinates to Object Coordinates QCAR::Matrix44F inverseModelViewMatrix = SampleMath::Matrix44FInverse(modelViewMatrix); // Convert the screen-aligned displacement vector to Object Coordinates // (i.e. in the target local reference frame) QCAR::Vec3F localTargetDisplacement = SampleMath::Vec3FTransformNormal(screenAlignedDisplacement, inverseModelViewMatrix); // COmpute a speed factor based on the distance of the target object from the camera float distanceObjectToCamera = fabs(modelViewMatrix.data[14]); float speed = 0.001f * distanceObjectToCamera;// TODO adjust value to your needs // set the result taking the speed factor into account result.data[0] = speed * localTargetDisplacement.data[0]; result.data[1] = speed * localTargetDisplacement.data[1]; result.data[2] = speed * localTargetDisplacement.data[2]; }
Finally, you need to apply the function above to an actual vector that represents your desired 2D scren-aligned motion and to apply the resulting 3D displacement to the translation part of your 3D model; this can be done by adjusting the code in the renderFrame() function in ImageTargets.cpp as follows:
QCAR::Matrix44F modelViewProjection; SampleUtils::translatePoseMatrix(0.f, 0.f, kObjectScale, &modelViewMatrix.data[0]); SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale, &modelViewMatrix.data[0]); float screenDeltaX = 2.0f;// moving to the right 2 pixels every frame float screenDeltaY = 0.0f;// QCAR::Vec3F targetLocalDisplacement; computeTargetTranslationFromScreenVector(screenDeltaX, screenDeltaY, modelViewMatrix, targetLocalDisplacement); targetCumulatedDisplacement.data[0] += targetLocalDisplacement.data[0]; targetCumulatedDisplacement.data[1] += targetLocalDisplacement.data[1]; targetCumulatedDisplacement.data[2] += targetLocalDisplacement.data[2]; SampleUtils::translatePoseMatrix(targetCumulatedDisplacement.data[0], targetCumulatedDisplacement.data[1], targetCumulatedDisplacement.data[2], &modelViewMatrix.data[0]); SampleUtils::multiplyMatrix(&projectionMatrix.data[0], &modelViewMatrix.data[0] , &modelViewProjection.data[0]);