I wrote my own function to get a line from screen coordinates straight forward...
to create a ray for ray casting (node picking)...
it works so far...
but the screen coordinates are not calculated, it seems...
the node always stays at the center of the screen, as if I used the center coordinates...
even if I use coordinates that are way out of screen bounds !!!
below is an example code...
can someone spot the error I made?
thanks
Code: Select all
#include <irrlicht.h>
irr::core::line3df getRayFromScreen(irr::IrrlichtDevice* irrDevice, float screenX, float screenY, float distance){
irr::core::line3df ln(0,0,0,0,0,0);
float DegToRad = irr::core::PI / 180.0;
irr::scene::ICameraSceneNode* camera = irrDevice->getSceneManager()->getActiveCamera();
irr::core::vector3df vecView = camera->getTarget() - camera->getPosition();
vecView.normalize();
irr::core::vector3df up = camera->getUpVector() * -1.0;
irr::core::vector3df position = camera->getPosition();
irr::core::dimension2du sSize = irrDevice->getVideoDriver()->getScreenSize();
float CAMERA_FOV = camera->getFOV();
float CAMERA_NEAR = camera->getNearValue();
float Ratio = camera->getAspectRatio();
irr::core::vector3df screenHoritzontally = vecView.crossProduct(up);
screenHoritzontally.normalize();
irr::core::vector3df screenVertically = screenHoritzontally.crossProduct(vecView);
screenVertically.normalize();
float halfHeight = tan(CAMERA_FOV * DegToRad * 0.5) * CAMERA_NEAR;
float halfScaledAspectRatio = halfHeight * Ratio;
screenVertically *= halfHeight;
screenHoritzontally *= halfScaledAspectRatio;
irr::core::vector3df PosInWorld = position + vecView;
float shW = sSize.Width / 2;
float shH = sSize.Height / 2;
screenX -= shW;
screenY -= shH;
screenX /= shW;
screenY /= shH;
screenX /= -CAMERA_NEAR;
screenY /= CAMERA_NEAR;
PosInWorld.X += (screenHoritzontally.X * screenX + screenVertically.X * screenY);
PosInWorld.Y += (screenHoritzontally.Y * screenX + screenVertically.Y * screenY);
PosInWorld.Z += (screenHoritzontally.Z * screenX + screenVertically.Z * screenY);
irr::core::vector3df Direction = PosInWorld - position;
Direction.normalize();
return irr::core::line3df(PosInWorld, PosInWorld + (Direction * distance));
}
//! main
int main(){
//! create Irrlicht
irr::SIrrlichtCreationParameters irrParameter;
irrParameter.DriverType = irr::video::EDT_OPENGL;
irrParameter.WindowSize = irr::core::dimension2di(800, 600);
irr::IrrlichtDevice* device = createDeviceEx(irrParameter);
irr::video::IVideoDriver* driver = device->getVideoDriver();
irr::scene::ISceneManager* smgr = device->getSceneManager();
//! create the camera
irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
device->getCursorControl()->setVisible(false);
//! the test node
irr::scene::ISceneNode* node1 = smgr->addSphereSceneNode(1);
node1->setMaterialFlag(irr::video::EMF_LIGHTING, false);
//! main loop
while(device->run()){
driver->beginScene(true, true, irr::video::SColor(0,60,110,160));
smgr->drawAll();
driver->endScene();
//! get ray from screen and update node
// but the node stays at the center of the screen
// even if the screen-position is way out of bounds !?!?!
irr::core::line3df ray = getRayFromScreen(device, 2000, 1500, 20);
node1->setPosition(ray.end);
}
//! close program
device->drop();
return 0;
}