multi selection
multi selection
usually I select sceneNod using ray from camera toward the sceneNode,
I want to select more than sceneNode by drawing rectangle on the screen by dragging mouse and select all nodes behind this rectangle
any idea ?
I want to select more than sceneNode by drawing rectangle on the screen by dragging mouse and select all nodes behind this rectangle
any idea ?
Re: multi selection
To multiselect by draw rectangle.
You need to record 2 rays projection to screen coordinate (begin and end) using e.g.
core::position2di pos = device->getCursorControl()->getPosition();
device->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);
// Get node position in 2D projection coordinate.
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(scenNodePos);
Compare if screenpos are inside your rectangle--> Add node to selected list if it does.
To Draw rectangle:
device->getVideoDriver()->draw2DRectangleOutline(rec, video::SColor(255, 0, 255, 0));
Goodluck
thanh
You need to record 2 rays projection to screen coordinate (begin and end) using e.g.
core::position2di pos = device->getCursorControl()->getPosition();
device->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);
// Get node position in 2D projection coordinate.
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(scenNodePos);
Compare if screenpos are inside your rectangle--> Add node to selected list if it does.
To Draw rectangle:
device->getVideoDriver()->draw2DRectangleOutline(rec, video::SColor(255, 0, 255, 0));
Goodluck
thanh
Re: multi selection
what do you mean by "scenNodePos" ?
I think we well catch only sceneNodes which the mouse cursor move over, is that true ?
I think we well catch only sceneNodes which the mouse cursor move over, is that true ?
Re: multi selection
You loop through all you nodes and get the nodes 3D position.
Regards
thanh
Regards
thanh
Re: multi selection
You need to record 2 rays projection to screen coordinate (begin and end) using e.g.
core::position2di pos = device->getCursorControl()->getPosition();
device->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);
i have do that for every time or only for the left upper corner and right lower corner of rectangle
then loop for all nodes and do the following
// Get node position in 2D projection coordinate.
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(scenNodePos);
Compare if screenpos are inside your rectangle--> Add node to selected list if it does.
is that true?
core::position2di pos = device->getCursorControl()->getPosition();
device->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);
i have do that for every time or only for the left upper corner and right lower corner of rectangle
then loop for all nodes and do the following
// Get node position in 2D projection coordinate.
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(scenNodePos);
Compare if screenpos are inside your rectangle--> Add node to selected list if it does.
is that true?
Re: multi selection
Yes, that's how I do it.
There is another method, where you use the x and z coordinate in 3D.
But I don't think I need that. So I used the method I showed you.
Regards
thanh
There is another method, where you use the x and z coordinate in 3D.
But I don't think I need that. So I used the method I showed you.
Regards
thanh
Re: multi selection
core::position2di pos = device->getCursorControl()->getPosition();
device->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);
i have do that for every time or only for the left upper corner and right lower corner of rectangle
then loop for all nodes and do the following
true or false ?
device->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);
i have do that for every time or only for the left upper corner and right lower corner of rectangle
then loop for all nodes and do the following
true or false ?
Re: multi selection
1) only for the left upper corner and right lower corner of rectangle
On mouse click event get upper corner.
On mouse release event get lower corner.
Then loop through all sceneNode .
On each sceneNode use other function I gave previously to project 3D pos into 2D screen pos.
If node 2D screen pos lies inside 2d rectangle then add to select node list.
Regards
thanh
On mouse click event get upper corner.
On mouse release event get lower corner.
Then loop through all sceneNode .
On each sceneNode use other function I gave previously to project 3D pos into 2D screen pos.
If node 2D screen pos lies inside 2d rectangle then add to select node list.
Regards
thanh
Re: multi selection
i did as you advice me but the result was empty or not complete.
what should i do after
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(scenNodePos);
is there any transformation i have to do for screenpos ???
------------------------------------------------------------------------------
what should i do after
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(scenNodePos);
is there any transformation i have to do for screenpos ???
------------------------------------------------------------------------------
Re: multi selection
After that you just check if the point is inside the 2d rectangle.
Regards
Thanh
Regards
Thanh
Re: multi selection
Code: Select all
if(Receiver.leftMouseDown())
{
if(firstCorner == core::position2d<s32>(0,0))
firstCorner = device->getCursorControl()->getPosition();
secondCorner = device->getCursorControl()->getPosition();
}
if(Receiver.leftMouseUp())
{
length1=0;
core::list<scene::ISceneNode*> sn1 ;
scene::IMeshSceneNode* node = 0;
Rect = core::rect<s32>(firstCorner.X,firstCorner.Y,secondCorner.X,secondCorner.Y);
collMan->getRayFromScreenCoordinates(firstCorner, maincamera);
collMan->getRayFromScreenCoordinates(secondCorner, maincamera);
core::list<scene::ISceneNode*> childs =smgr->getRootSceneNode()->getChildren();
core::list<scene::ISceneNode*>::Iterator childs1 = childs.begin();
core::list<scene::ISceneNode*> childs2 =(*childs1)->getChildren();
//char** Selected_Node_Ids = new char*[100];
int index=0;
for(core::list<scene::ISceneNode*>::Iterator it1 = childs2.begin(); it1 != childs2.end(); ++it1)
{
scene::ISceneNode* n = *it1;
sn1=(*it1)->getChildren();
for(core::list<scene::ISceneNode*>::Iterator it2 = sn1.begin(); it2 != sn1.end(); ++it2)
{
node = static_cast<scene::IMeshSceneNode*>(*it2);
core::matrix4 t = node->getAbsoluteTransformation();
core::vector3df v = core::vector3df(t[13],t[14],t[15]);
core::vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(v);
if(screenpos.X>Rect.UpperLeftCorner.X && screenpos.X<Rect.LowerRightCorner.X && screenpos.Y>Rect.UpperLeftCorner.Y && screenpos.Y<Rect.LowerRightCorner.Y )
{
Selected_Node_Id = (char*)node->getParent()->getName();
funcMultiSelect();
}
}
}
length1=index;
firstCorner = core::position2d<s32>(0,0);
secondCorner = core::position2d<s32>(0,0);
Selected_Node_Id = "#";
funcMultiSelect();
}
}
Re: multi selection
bur the result is false
so i tried frustum
is that true????????????????????????????
so i tried frustum
Code: Select all
if(Receiver.leftMouseDown())
{
mouse_up = false;
if(firstCorner == core::position2d<s32>(0,0))
firstCorner = device->getCursorControl()->getPosition();
secondCorner = device->getCursorControl()->getPosition();
}
if(Receiver.leftMouseUp())
{
if(mouse_up==false)
{
mouse_up = true;
length1=0;
core::list<scene::ISceneNode*> sn1 ;
scene::IMeshSceneNode* node = 0;
Rect = core::rect<s32>(firstCorner.X,firstCorner.Y,secondCorner.X,secondCorner.Y);
collMan->getRayFromScreenCoordinates(firstCorner, maincamera);
collMan->getRayFromScreenCoordinates(secondCorner, maincamera);
core::line3d<f32> Rays[4];
core::position2d<s32> UpperRightCorner = core::position2d<s32>(Rect.LowerRightCorner.X,Rect.UpperLeftCorner.Y);
core::position2d<s32> LowerLeftCorner=core::position2d<s32>(Rect.UpperLeftCorner.X,Rect.LowerRightCorner.Y);
Rays[0]=collMan->getRayFromScreenCoordinates(Rect.UpperLeftCorner);
Rays[1]=collMan->getRayFromScreenCoordinates(UpperRightCorner);
Rays[2]=collMan->getRayFromScreenCoordinates(Rect.LowerRightCorner);
Rays[3]=collMan->getRayFromScreenCoordinates(LowerLeftCorner);
SViewFrustum SelectFrustum;
SelectFrustum.planes[SViewFrustum::VF_FAR_PLANE] = core::plane3d<f32>(Rays[0].end,Rays[2].end,Rays[1].end);
SelectFrustum.planes[SViewFrustum::VF_NEAR_PLANE] = core::plane3d<f32>(Rays[0].start,Rays[1].start,Rays[2].start);
SelectFrustum.planes[SViewFrustum::VF_LEFT_PLANE] = core::plane3d<f32>(Rays[0].start,Rays[3].start,Rays[0].end);
SelectFrustum.planes[SViewFrustum::VF_RIGHT_PLANE] = core::plane3d<f32>(Rays[1].start,Rays[1].end,Rays[2].end);
SelectFrustum.planes[SViewFrustum::VF_BOTTOM_PLANE] = core::plane3d<f32>(Rays[2].start,Rays[2].end,Rays[3].end);
SelectFrustum.planes[SViewFrustum::VF_TOP_PLANE] = core::plane3d<f32>(Rays[0].start,Rays[0].end,Rays[1].end);
core::aabbox3df box = SelectFrustum.getBoundingBox();
core::list<scene::ISceneNode*> childs =smgr->getRootSceneNode()->getChildren();
core::list<scene::ISceneNode*>::Iterator childs1 = childs.begin();
core::list<scene::ISceneNode*> childs2 =(*childs1)->getChildren();
//char** Selected_Node_Ids = new char*[100];
int index=0;
for(core::list<scene::ISceneNode*>::Iterator it1 = childs2.begin(); it1 != childs2.end(); ++it1)
{
scene::ISceneNode* n = *it1;
sn1=(*it1)->getChildren();
for(core::list<scene::ISceneNode*>::Iterator it2 = sn1.begin(); it2 != sn1.end(); ++it2)
{
node = static_cast<scene::IMeshSceneNode*>(*it2);
core::matrix4 t = node->getAbsoluteTransformation();
core::vector3df v = core::vector3df(t[13],t[14],t[15]);
core::vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(v);
/*if(screenpos.X>Rect.UpperLeftCorner.X && screenpos.X<Rect.LowerRightCorner.X && screenpos.Y>Rect.UpperLeftCorner.Y && screenpos.Y<Rect.LowerRightCorner.Y )
{
Selected_Node_Id = (char*)node->getParent()->getName();
funcMultiSelect();
}*/
if((v.X > box.MinEdge.X && v.X < box.MaxEdge.X &&
v.Y > box.MinEdge.Y && v.Y < box.MaxEdge.Y &&
v.Z > box.MinEdge.Z && v.Z < box.MaxEdge.Z))
{
Selected_Node_Id = (char*)node->getParent()->getName();
funcMultiSelect();
}
}
}
length1=index;
firstCorner = core::position2d<s32>(0,0);
secondCorner = core::position2d<s32>(0,0);
Selected_Node_Id = "#";
funcMultiSelect();
}
}
Re: multi selection
It should be about 15 lines of codes.
You don't need anything else beside the functions I mentioned in this post.
Regards
You don't need anything else beside the functions I mentioned in this post.
Regards
Re: multi selection
Assume you already get the rectangle shape.
Code: Select all
irr::core::rect<irr::f32> rect(lastPos.X, lastPos.Y, mousePos.X, mousePos.Y);
irr::core::list<irr::scene::ISceneNode *> children = root->getChildren();
core::list< scene::ISceneNode* >::Iterator IT = children.begin();
for (; IT != children.end(); ++IT)
{
ISceneNode *node = (*IT);
if (node== cameraNode || node == TerrainNode) continue; //Ignore camera and terrain node
vector3df vec = (*IT)->getPosition();
vector2d<irr::s32> screenpos = device->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vec);
vector2df v(screenpos.X, screenpos.Y);
if (rect.isPointInside(v))
{
AddToSelectionList(node);
}
}