Hi all,
i have a little question about 2D projection :
I'm working with event.MouseInput, but the X and Y parameter of event.MouseInput is in screen coordinate... how can i cast a ray from camera for finding the projection of event.MouseInput.X and event.MouseInput.Y in the world coordinate (vector3df) of a BSP level ?
Thanks for your help and sorry for my bad english...
Regards.
cyb
PS : i don't want to use Camera->getTarget() because it's a customized camera
2d screen -> 3d world coordinate
-
- Posts: 64
- Joined: Mon Sep 08, 2003 8:21 am
- Location: Paris, France
-
- Posts: 64
- Joined: Mon Sep 08, 2003 8:21 am
- Location: Paris, France
Hi,
Thanks for your response, but i can't use this function, why ?
Because i want to select more than one node with a dragging box (the dragging box is Draw2DRectangle), one the dragging box is choosed i want to check all node's coordinates to see if UpperLeft.X and LowerRight.X (UpperLeft.Y and LowerRight.Y too) is in my dragging box...
The only solution is to projectate the coordinates of my 2D dragging box in the 3D world... (or maybe inverse... project the 3D Coordinate of the nodes in my 2D screen coordinate.... someone have a better solution ?)
The main idea is :in the future, instead of having a 2DRectangle on the screen, i'll made a 3DBox for selecting node.
if i use getSceneNodeFromScreenCoordinatesBB and my dragging box is 150x150 pixels, i must call 22500 getSceneNodeFromScreenCoordinatesBB !
Thanks for your response, but i can't use this function, why ?
Because i want to select more than one node with a dragging box (the dragging box is Draw2DRectangle), one the dragging box is choosed i want to check all node's coordinates to see if UpperLeft.X and LowerRight.X (UpperLeft.Y and LowerRight.Y too) is in my dragging box...
The only solution is to projectate the coordinates of my 2D dragging box in the 3D world... (or maybe inverse... project the 3D Coordinate of the nodes in my 2D screen coordinate.... someone have a better solution ?)
The main idea is :in the future, instead of having a 2DRectangle on the screen, i'll made a 3DBox for selecting node.
if i use getSceneNodeFromScreenCoordinatesBB and my dragging box is 150x150 pixels, i must call 22500 getSceneNodeFromScreenCoordinatesBB !
-
- Posts: 64
- Joined: Mon Sep 08, 2003 8:21 am
- Location: Paris, France
Hurrah ! it's working
This is the code :
And this is how i use it (sorry it's a little long) in my OnEvent function :
And in the main routine :
It's just for 1 node, but after i can use this for recursively search the node is the dragging selection box ...
Thanks for your help
This is the code :
Code: Select all
vector3df cameraMoving::getSceneNodeFromScreenCoordinatesBB(core::position2d<s32> pos, s32 idBitMask)
{
const scene::SViewFrustrum* f =
smgr->getActiveCamera()->getViewFrustrum();
core::vector3df farLeftUp = f->getFarLeftUp();
core::vector3df lefttoright = f->getFarRightUp() - farLeftUp;
core::vector3df uptodown = f->getFarLeftDown() - farLeftUp;
core::dimension2d<s32> screenSize = driver->getScreenSize();
f32 dx = pos.X / (f32)screenSize.Width;
f32 dy = pos.Y / (f32)screenSize.Height;
core::vector3df end = farLeftUp + (lefttoright * dx) + (uptodown * dy);
core::line3d<f32> line;
line.start = camera->getPosition();
line.end = line.start +(end - line.start).normalize() * 1000.0f;
core::vector3df intersection;
core::triangle3df tri;
if (smgr->getSceneCollisionManager()->getCollisionPoint(line, selector_floor, intersection, tri))
return intersection;
return end;
};
Code: Select all
if (event.EventType==EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event==EMIE_LMOUSE_LEFT_UP)
{
drawSelected=false;
if (drawRect)
{
std::cerr<<"LEFT CLICKED UP"<<std::endl;
vector3df lowerRightCorner, upperLeftCorner;
lowerRightCorner = getSceneNodeFromScreenCoordinatesBB(position2d<s32>(event.MouseInput.X,event.MouseInput.Y),0);
upperLeftCorner = getSceneNodeFromScreenCoordinatesBB(position2d<s32>(selectionRect.UpperLeftCorner.X,selectionRect.UpperLeftCorner.Y),0);
std::cerr<<"UPPER LEFT X :"<<upperLeftCorner.X<<std::endl;
std::cerr<<"UPPER LEFT Z :"<<upperLeftCorner.Z<<std::endl;
std::cerr<<"LOWER RIGHT X :"<<lowerRightCorner.X<<std::endl;
std::cerr<<"LOWER RIGHT Z :"<<lowerRightCorner.Z<<std::endl;
std::cerr<<"NODE POSITION X :"<<node->getPosition().X<<std::endl;
std::cerr<<"NODE POSITION Z :"<<node->getPosition().Z<<std::endl;
if (node->getPosition().X<upperLeftCorner.X && node->getPosition().X>lowerRightCorner.X
&& node->getPosition().Z>lowerRightCorner.Z && node->getPosition().Z<upperLeftCorner.Z)
{
std::cerr<<"SELECTED"<<std::endl;
drawSelected=true;
}
}
else
{
if (smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(position2d<s32>(event.MouseInput.X,event.MouseInput.Y),0))
{
std::cerr<<"SELECTED"<<std::endl;
drawSelected=true;
}
}
oldMouseInputX=0;
oldMouseInputY=0;
stayLClicked=false;
drawRect=false;
Code: Select all
if (drawSelected)
driver->draw3DBox(node->getBoundingBox(),SColor(0,250,0,0));
Thanks for your help