I'm posting here below a code snippet that works, as I just tested it.

It's written for Android, but you can basically use it on iOS too, or adjust your code by comparing it with mine.

To give a bit of explanation to it:

what you need to do is to add your "backMotion_InWorldCoordinates" translation at the end of all your "usual" transformations by using multiplyMatrix function like for any other translation; please check how this is done in the code I paste here below.

Also, note that the inverseModelViewMatrix must be initalized to identity matrix in the rendering initialization function (otherwise at the first frame the matrix will be undefined or all zeros).

So, here is the code snippet:

for(int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++)

{

// Get the trackable:

const QCAR::TrackableResult* result = state.getTrackableResult(tIdx);

const QCAR::Trackable& trackable = result->getTrackable();

QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose());

QCAR::Matrix44F modelViewProjection;

//apply usual transformations here

SampleUtils::translatePoseMatrix(0.0f, 0.0f, kObjectScale,

&modelViewMatrix.data[0]);

SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,

&modelViewMatrix.data[0]);

/////

//NEW: apply our custom backward translation here

QCAR::Vec3F backMoveCameraRef(0.0f, 0.0f, 1.0f);

QCAR::Vec3F backMoveWorldRef = SampleMath::Vec3FTransformNormal(backMoveCameraRef, inverseModelViewMatrix);

backMoveWorldRef = SampleMath::Vec3FNormalize(backMoveWorldRef);

float speed = 0.2f;

backTranslation.data[0] += speed*backMoveWorldRef.data[0];

backTranslation.data[1] += speed*backMoveWorldRef.data[1];

backTranslation.data[2] = 0.0f;

SampleUtils::translatePoseMatrix(backTranslation.data[0], backTranslation.data[1], backTranslation.data[2],

&modelViewMatrix.data[0]);

/////////////////////

//NEW: update inverseModelViewMatrix

inverseModelViewMatrix = SampleMath::Matrix44FInverse(modelViewMatrix);

//multiply modelview and projection matrix as usual

SampleUtils::multiplyMatrix(&projectionMatrix.data[0],

&modelViewMatrix.data[0] ,

&modelViewProjection.data[0]);

glUseProgram(shaderProgramID);

glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,

(const GLvoid*) &teapotVertices[0]);

// etc.

Let me know if you have more questions on this.

Hi, I think the problem is that you need to convert your "swipe" motion into a "translation vector" in the world reference frame (i.e. the target reference frame);

so, let's suppose that when you "swipe up" on your device screen, you want the object to move away from you (while also being constrained in its X-Y plane, if I understand right):

first, you need to define a 3d vector (direction) in your camera reference frame;

we know that the camera reference frame in OpenGL is defined with X pointing to the right of the screen, Y pointing upward, and Z axis pointin to you (i.e. exiting the screen);

so, we can say that a "move away" direction vector is defined as a QCAR::Vec3F (0, 0, -1) in such camera ref frame (note the Z = -1, i.e. direction is "entering the screen")

Now you need to convert this "move away" vector from camera coordinates to a representation in world coordinates (i.e. to represent our vector in the target reference frame);

To do this coordinate transformation you must use the inverse matrix of the ModelView matrix;

so, take the SampleMath.cpp from the Dominoes sample in the Vuforia sample disribution; you will see there are two functions:

- QCAR::Matrix44F SampleMath::Matrix44FInverse(QCAR::Matrix44F& m)

and

- QCAR::Vec3F SampleMath::Vec3FTransformNormal(QCAR::Vec3F& v, QCAR::Matrix44F& m)

You can use the first function to get the inverse ModelView matrix:

QCAR::Matrix44F inverseModelViewMatrix = SampleMath::Matrix44FInverse(modelViewMatrix);

And the second function to turn your "move away" vector from camera coordinates to world coordinates:

QCAR::Vec3F moveAwayInWorldCoords = SampleMath::Vec3FTransformNormal(moveAwayInCameraCoords, inverseModelViewMatrix);

Also, you may want to normalize this vector to make sure it is a unit length vector (as it just represents a direction):

QCAR::Vec3F normalizedMoveAwayInWorldCoords = SampleMath::Vec3FNormalize(moveAwayInWorldCoords);

Once you have this vector, you can project it on the target XY plane by simply suppressing the Z coordinate of the vector, i.e.:

normalizedMoveAwayInWorldCoords.data[2] = 0.0f; //data[2] is Z coordinate, we set it null so to have vector in XY

And then, you will have to normalize the vector once again.

QCAR::Vec3F moveAwayFinal = SampleMath::Vec3FNormalize(normalizedMoveAwayInWorldCoords);

Then you can multiply it by some "motion" factor depending on how fast you want to move your object in response to your "swipe"

You can generalize this approach to fit different cases of course (e.g. to "move close" as opposed to "move away", etc.)

I hope this helps.