Searching the Ogre forums, several people have tried to use Ogre as the rendering engine for the ARToolkit - some successfully, some not. Here are a couple of relevent message threads:
- - http://www.ogre3d.org/phpBB2/viewtopic.php?p=163290
- http://www.ogre3d.org/phpBB2/viewtopic.php?t=17725
What I've done so far:
- - installed ARToolkit (original) and ran the included demo applications.
- used the ARToolkit's calibration programs to obtain a camera calibration file specific to my Logitech QuickCam Orbit (ARToolkitPlus is able to read these calibration files).
- installed and built ARToolkitPlus
- ARToolkitPlus comes with a simple test application and sample image. I confirmed that the test image is "trackable".
- printed out my own marker (from the ARToolkitPlus), glued it to a piece of cardboard, captured a frame from my webcam and hacked the demo app to check that I could "track" this single image.
- To bring the webcam images into Ogre. I used Timme's plug-in, http://www.ogre3d.org/phpBB2/viewtopic.php?t=16572. It offers notification of a new frame's arrival via a listener class. It's in this listener class constructor that I instantiate the ARToolkitPlus, and the "new frame" method that I search for the marker card.
- Combined, I now have a simple Ogre application with the webcam showing up as a background (see http://www.ogre3d.org/wiki/index.php/Displaying_2D_Backgrounds) and a small test mesh being moved around based on calculations coming from ARToolkitPlus.
My problem is the lack of correspondance between these two images
- Code: Select all
virtual void createCamera(void)
{
mCamera = mSceneMgr->createCamera("SceneCamera");
mCamera->setPosition(Vector3(0,0,0));
mCamera->lookAt(Vector3(0,0,-5)); // back along -ve z axis
mCamera->setNearClipDistance(0.01);
// vertical opening angle of webcam measured roughly as 85cm at a distance of 160cm distant
// let Ogre calculate horizontal FOV from viewport aspect ratio
mCamera->setFOVy(Radian(0.5163));
}
To check the positioning (ignore rotations for the moment), I created a small .mesh test cube with sides of 0.01m (1/10 the size of the external black border of my printed marker tile). To position this entity,
- Code: Select all
float* mv = (float*) (mTracker->getModelViewMatrix() );
Ogre::Vector3 position = Ogre::Vector3(-*(mv+12), *(mv+13), -*(mv+14));
std::cout << "Position: " << position << std::endl;
mNode->setPosition(position);
As we move the marker tile around now, the cube should track its centre. What I find though is that the y coordinate tracks fine but that there is a discrepency in the horizontal position. Video (DivX, 2.5Mb) of the result can be found http://www.edmstudio.com/ogre/06G19-artoolkitplus-translation.avi.
Part of the mismatch is coming from ARToolkitPlus. The following image shows the marker tile held at the position that gives (x,y) coordinates of (0,0).

The calculated modelview matrix is
- Code: Select all
Matched marker: 0 with confidence: 100
-0.8475 0.0245 -0.5302 0.0000
0.0070 0.9994 0.0349 0.0000
0.5307 0.0259 -0.8472 0.0000
0.0051 0.0057 1.6646 1.0000
Position: Vector3(-0.00508792, 0.00572599, -1.66464)
The red dot is where Ogre renders the test cube (0,0,-1.66). Note the horizontal difference between the middle of the marker tile and the image centre (white lines). I'm guessing that this is a camera calibration issue - though why (0,0) is offset from the image centre is strange.
With this tracking at least partly correct, let's consider rotations. Begin by replacing the tiny marker with a 0.1^3 cube sized to match the marker tile. For orientation, we follow haffax's advice (http://www.ogre3d.org/phpBB2/viewtopic.php?p=163290) and convert the ARToolkitPlus modelview matrix into an Ogre quaternion:
- Code: Select all
float* mv = (float*) (mTracker->getModelViewMatrix() );
Ogre::Vector3 x = Ogre::Vector3(*(mv+0), *(mv+1), *(mv+2));
Ogre::Vector3 y = Ogre::Vector3(*(mv+4), *(mv+5), *(mv+6));
Ogre::Vector3 z = Ogre::Vector3(*(mv+8), *(mv+9), *(mv+10));
Ogre::Quaternion orientation = Ogre::Quaternion(x.normalisedCopy(), y.normalisedCopy(), z.normalisedCopy());
mNode->setOrientation(orientation);
The results are shown in this video (DivX, 2.5Mb) http://www.edmstudio.com/ogre/06G19-artoolkitplus-orientation.avi with an image still shown below.
Rotations are obviously being calculated but two of the directions are reversed. This is where I'm currently up to ...





