Got Ray of length: 10187.501953
Start Point: 1775.391357, 221.420609, 1066.849121
End Point: 394.590485, 1102.506836, 11121.811523
Derr, it's hitting my Camera node. I have an FPS camera set up with collision to the ground. How can I avoid this? I'm using the collision example picking only nodes marked for selection.
Here's updated click code:
Code: Select all
// convert to Irrlicht friendly struct
irr::core::position2di mousePos(v2fPos.x, v2fPos.y);
// get our scene manager
scene::ISceneManager* pSceneMgr = GetIrrlichtManager()->GetScene();
scene::ISceneCollisionManager* pCollMgr = pSceneMgr->getSceneCollisionManager();
// get the ray from the screen point
irr::core::line3df collRay;
collRay = pCollMgr->getRayFromScreenCoordinates(mousePos, pSceneMgr->getActiveCamera()); // this appears to be getting unique values
LogMsg(" Got Ray of length: %f", collRay.getLength());
LogMsg(" Start Point: %f, %f, %f", collRay.start.X, collRay.start.Y, collRay.start.Z);
LogMsg(" End Point: %f, %f, %f", collRay.end.X, collRay.end.Y, collRay.end.Z);
// get the collision
core::vector3df collPoint;
core::triangle3df collTriangle;
scene::ISceneNode* pNode = 0;
pNode = pCollMgr->getSceneNodeAndCollisionPointFromRay(collRay, collPoint, collTriangle, IDFlag_IsPickable); // I'm always getting null here
if( !pNode )
{
pNode = pCollMgr->getSceneNodeFromScreenCoordinatesBB(mousePos,0,true); // but this is returning a node... wtf
}
// Unlight any currently highlighted scene node
if (m_pHilighted)
{
m_pHilighted->setMaterialFlag(video::EMF_LIGHTING, true);
m_pHilighted = 0;
}
if( pNode )
{
LogMsg(" Selected Node: %s", pNode->getName());
LogMsg(" Selected Point: %f, %f, %f", collPoint.X, collPoint.Y, collPoint.Z);
if((pNode->getID() & IDFlag_IsHighlightable) == IDFlag_IsHighlightable)
{
m_pHilighted = pNode;
// Highlighting in this case means turning lighting OFF for this node,
// which means that it will be drawn with full brightness.
m_pHilighted->setMaterialFlag(video::EMF_LIGHTING, false);
}
}
Here's the setup code:
Code: Select all
if (!GetIrrlichtManager()->GetDevice())
{
LogError("Error initializing Irrlicht");
return;
}
IrrlichtDevice * device = GetIrrlichtManager()->GetDevice();
video::IVideoDriver* driver = GetIrrlichtManager()->GetDriver();
scene::ISceneManager* smgr = GetIrrlichtManager()->GetScene();
device->getTimer()->setTime(0);
// load the .irr scene
std::string strBasePath = GetBaseAppPath();
device->getFileSystem()->changeWorkingDirectoryTo( (strBasePath).c_str());
smgr->loadScene((strBasePath+"game/scenes/jmvd1/jmvd1.irr").c_str());
scene::ICameraSceneNode * camera;
// Create a meta triangle selector to hold several triangle selectors.
scene::IMetaTriangleSelector * meta = smgr->createMetaTriangleSelector();
core::array<scene::ISceneNode *> nodes;
smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // Find all nodes
for (u32 i=0; i < nodes.size(); ++i)
{
scene::ISceneNode * node = nodes[i];
scene::ITriangleSelector * selector = 0;
node->getID();
switch(node->getType())
{
case scene::ESNT_CUBE:
case scene::ESNT_ANIMATED_MESH:
// Because the selector won't animate with the mesh,
// and is only being used for camera collision, we'll just use an approximate
// bounding box instead of ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0)
node->setID(IDFlag_IsPickable | IDFlag_IsHighlightable);
selector = smgr->createTriangleSelectorFromBoundingBox(node);
break;
case scene::ESNT_MESH:
case scene::ESNT_SPHERE: // Derived from IMeshSceneNode
node->setID(IDFlag_IsPickable | IDFlag_IsHighlightable);
selector = smgr->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
break;
case scene::ESNT_TERRAIN:
node->setID(IDFlag_IsPickable | IDFlag_IsHighlightable);
selector = smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node);
break;
case scene::ESNT_OCTREE:
node->setID(IDFlag_IsPickable | IDFlag_IsHighlightable);
selector = smgr->createOctreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node, 32);
break;
case scene::ESNT_CAMERA_FPS:
case scene::ESNT_CAMERA_MAYA:
case scene::ESNT_CAMERA:
// set up the camera
//smgr->addCameraSceneNode(0,core::vector3df(), core::vector3df(0, 0, 100), 0,true);
node->setID(ID_IsNotPickable);
smgr->setActiveCamera((scene::ICameraSceneNode*)node);
break;
default:
// Don't create a selector for this node type
break;
}
if(selector)
{
// Add it to the meta selector, which will take a reference to it
meta->addTriangleSelector(selector);
// And drop my reference to it, so that the meta selector owns it.
selector->drop();
}
}
// create the camera
if(camera = smgr->getActiveCamera())
{
//smgr->addCameraSceneNodeFPS(camera, 50.f, 0.1f);
// TODO: there's got to be a better way to do this
ICameraSceneNode* cameraFPS = smgr->addCameraSceneNodeFPS(0, 50.f, 0.1f, ID_IsNotPickable);//(0,100.0f,0.5,-1,0,0,true,0.1f,false,true);
cameraFPS->setPosition(camera->getPosition());
cameraFPS->setRotation(camera->getRotation());
cameraFPS->setTarget(camera->getTarget());
cameraFPS->setAspectRatio(camera->getAspectRatio());
cameraFPS->setFarValue(camera->getFarValue());
cameraFPS->setFOV(camera->getFOV());
camera = cameraFPS; // what a waste
}
else
{
camera = smgr->addCameraSceneNodeFPS(0, 50.f, 0.1f);
// Point the camera at the cube node, by finding the first node of type ESNT_CUBE
scene::ISceneNode * cube = smgr->getSceneNodeFromType(scene::ESNT_CUBE);
if(cube)
camera->setTarget(cube->getAbsolutePosition());
camera->setAspectRatio(GetScreenSizeXf()/GetScreenSizeYf());
camera->setFOV((120 * M_PI / 360.0f));
camera->setFarValue(1000.0f);
}
// add collision
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(meta, camera, core::vector3df(5,5,5), core::vector3df(0,0,0));
meta->drop(); // I'm done with the meta selector now
camera->addAnimator(anim);
anim->drop(); // I'm done with the animator now
// create mipmaps
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);