Therefore, in my opinion, red points and blue points should be at the same position in 2D because they are both the projection of the hand skeleton joints, the red one is got from screenshot while the blue one from calculation. But there remains a drift between the red and blue can I know why?
In this project, I used two cameras. Each of them attached by one viewport. And I created two renderwindow for each camera. The code for how I created the camera and viewport is shown below:
Code: Select all
void HandFrameListener::createScene()
{ // camera
_camera1 = _scenemanager->createCamera("Camera1");
_camera2 = _scenemanager->createCamera("Camera2");
_camera1->setPosition(Ogre::Vector3(-3.35f, 0.f, 20.f));
_camera2->setPosition(Ogre::Vector3(3.35f, 0.0f, 20));
_camera1->setFOVy(Radian(atan(240 / 236.f) * 2.f));
_camera2->setFOVy(Radian(atan(240 / 236.f) * 2.f));
_camera1->lookAt(Ogre::Vector3(-3.35f, 0.0f, -1.0f)); // 0, 0, -1 original
_camera1->setNearClipDistance(0.1);
//_camera1->setFarClipDistance(20);
_camera2->lookAt(Ogre::Vector3(3.35f, 0.0f, -1.0f));
_camera2->setNearClipDistance(0.1);
//_camera2->setFarClipDistance(20);
// viewport
Viewport *viewport = _window->addViewport(_camera1);
viewport->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f));
Viewport *viewportR = _windowR->addViewport(_camera2);
viewportR->setBackgroundColour(ColourValue(0.f, 0.f, 0.f));
// I also tried to use this piece of code below, no use;
/*Real r = Real(viewport->getActualWidth()) / Real(viewport->getActualHeight()); // I also tried _window->getwidth/_window->getheight, no use
_camera1->setAspectRatio(r);*/
/*Real r1 = Real(_window->getWidth() / _window->getHeight());
_camera1->setAspectRatio(r1);
Real r2 = Real(_windowR->getWidth() / _windowR->getHeight());
_camera2->setAspectRatio(r2);*/
}Code: Select all
void worldCoordToScreen(Vector3 objPos, Camera* cam, Vector2 screenRect, Vector2& screenPos)
{ Matrix4 viewMatrix = cam->getViewMatrix();
Matrix4 projMatrix = cam->getProjectionMatrix();
Vector4 in = Vector4(objPos.x, objPos.y, objPos.z, 1.0);
Vector4 out = viewMatrix * in;
#if 1 // method 1: use the existed function provided by Ogre
out = projMatrix * out;
out.x /= out.w;
out.y /= out.w;
out.z /= out.w;
if (out.w <= 0.0) return;
// Map x, y and z to range 0-1
out.x = out.x * 0.5 + 0.5;
out.y = out.y * 0.5 + 0.5;
out.z = out.z * 0.5 + 0.5;
// Map x,y to viewport
out.x = out.x * screenRect.x;
out.y = (1 - out.y) * screenRect.y;
screenPos.x = out.x;
screenPos.y = out.y;
#else // Method 2: write the projection myself
// I don't think this is 100% correct because no camera is at the origin.
out.x = 236.f * (out.x / out.z);
out.y = 236.f * (out.y / out.z);
screenPos.x = -out.x + (screenRect.x / 2.0f);
screenPos.y = out.y + (screenRect.y / 2.0f);
#endif
return;
}Thank you so much!