I am very sure that you are doing something wrong. Are you absolutely sure that your player node is getting selected and not the camera or something else?
Here is a testcase that shows the
getSceneNodeFromScreenCoordinatesBB() in action and working to select a node that is behind other nodes.
At one position is the camera, and at another position is a sphere. Between the sphere and the camera are 5 flattened cubes. You can select nodes by pressing Shift and then left-clicking the nodes. If you try to select the cubes, you will not be able to. If you click over the sphere, it will get selected, even if there are cubes in the way.
Code: Select all
#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
using namespace scene;
#define NONE_MASK (0x0000)
#define BALL_MASK (0x0001)
#define CUBE_MASK (0x0002)
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(ISceneManager* smgr)
: SceneManager(smgr)
, Selected(0)
{
SceneManager->grab();
u32 k;
for (k = 0; k < sizeof(Keys) / sizeof(*Keys); ++k)
Keys[k] = false;
}
virtual ~MyEventReceiver()
{
SceneManager->drop();
}
virtual bool OnEvent(SEvent event)
{
if (event.EventType == EET_KEY_INPUT_EVENT)
{
Keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// if shift is down and mouse clicked, then do collision test
if (Keys[KEY_SHIFT] &&
event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
core::position2di pos(event.MouseInput.X, event.MouseInput.Y);
Selected =
SceneManager->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(pos, BALL_MASK);
return true;
}
return false;
}
private:
ISceneManager* SceneManager;
public:
ISceneNode* Selected;
bool Keys[KEY_KEY_CODES_COUNT];
};
int main()
{
// create device and exit if creation failed
IrrlichtDevice* device =
createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(800, 600));
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
// need a light to make things visible
ILightSceneNode* light =
smgr->addLightSceneNode(0, core::vector3df(0, 50, 0), video::SColorf(1.f, .5f, .5f, 1.f));
light->setID(NONE_MASK);
IBillboardSceneNode* bill =
smgr->addBillboardSceneNode(light);
bill->setID(NONE_MASK);
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
// make the camera
ICameraSceneNode* camera =
smgr->addCameraSceneNodeMaya(0, -1500.f, 200.f, 1500.f, NONE_MASK);
camera->setPosition(core::vector3df(0.f, 0.f, -10.f));
// make a few cubes
core::vector3df pos(0.f, 0.f, 5.f);
core::vector3df rot(0.f, 0.f, 0.f);
core::vector3df scl(10.f, 10.f, 1.f);
u32 c;
for (c = 0; c < 5; ++c)
{
smgr->addCubeSceneNode(1.f, 0, CUBE_MASK, pos, rot, scl);
pos.Z += 5.f;
}
// make a ball
smgr->addSphereSceneNode(5.f, 8, 0, BALL_MASK, core::vector3df(0, 0, 50));
MyEventReceiver receiver(smgr);
device->setEventReceiver(&receiver);
while (device->run())
{
if (device->isWindowActive())
{
if (driver->beginScene(true, true, video::SColor(255, 100, 100, 100)))
{
smgr->drawAll();
// draw the bounding box for the selected node
if (receiver.Selected)
{
video::SMaterial m;
m.Lighting = false;
m.ZBuffer = false;
driver->setMaterial(m);
driver->setTransform(video::ETS_WORLD,
receiver.Selected->getAbsoluteTransformation());
driver->draw3DBox(receiver.Selected->getBoundingBox());
}
driver->endScene();
}
}
}
device->drop();
return 0;
}
Travis