Camera Terrain Collision in a wxWidgets Frame

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
gbutcher
Posts: 8
Joined: Sun Jan 06, 2008 4:27 pm

Camera Terrain Collision in a wxWidgets Frame

Post by gbutcher »

Okay, I have a test application that paints the Irrlicht viewport in a wxWidgets frame. I'm animating the camera with the wxWidgets event routines, like this:

Code: Select all

void wxirrlichtFrm::wxirrlichtFrmKeyDown(wxKeyEvent& event)
{
	// insert your code here
	if (!cam) return;
	float sp = 10.0f;
	int k = event.GetKeyCode();
	core::vector3df whereat = cam->getPosition();
	core::vector3df lookat = cam->getTarget();
	core::vector3df delta = (whereat - lookat).normalize();
	if (event.GetModifiers() == wxMOD_SHIFT) sp = 1.0f;
	if (k == WXK_UP) {
        whereat.X -= delta.X*sp; whereat.Z -= delta.Z*sp;
        lookat.X -= delta.X*sp; lookat.Z -= delta.Z*sp;
    }
    if (k == WXK_DOWN) {
        whereat.X += delta.X*sp; whereat.Z += delta.Z*sp;
        lookat.X += delta.X*sp; lookat.Z += delta.Z*sp;
    }
    if (k == WXK_LEFT) {
        delta.rotateXZBy(90.0f,core::vector3df(0,0,0));
        whereat.X -= delta.X*sp; whereat.Z -= delta.Z*sp;
        lookat.X -= delta.X*sp; lookat.Z -= delta.Z*sp;
    }
    if (k == WXK_RIGHT) {
        delta.rotateXZBy(90.0f,core::vector3df(0,0,0));
        whereat.X += delta.X*sp; whereat.Z += delta.Z*sp;
        lookat.X += delta.X*sp; lookat.Z += delta.Z*sp;
    }

    if (k == WXK_PAGEUP) {
        whereat.Y += 10.0f;
        lookat.Y += 10.0f;
    }
    if (k == WXK_PAGEDOWN) {
        whereat.Y -= 10.0f;
        lookat.Y -= 10.0f;
    }
    cam->setPosition(whereat);
    cam->setTarget(lookat);
    cam->updateAbsolutePosition();
}
I've attached a collision response animator to the camera right after loading it from the .irr file:

Code: Select all

    ITerrainSceneNode* terrain = (ITerrainSceneNode*) smgr->getSceneNodeFromType(ESNT_TERRAIN);
    if (terrain) {
        ITriangleSelector* world = smgr->createTriangleSelector(terrain->getMesh(),terrain);
        terrain->setTriangleSelector(world);
        world->drop();
        if (world) {
            ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(world, cam, core::vector3df(30.0f,60.0f,30.0f), core::vector3df(0.0f,0.0f,0.0f), core::vector3df(0.0f,0.0f,0.0f));
            if (anim) {
                cam->addAnimator(anim);
                anim->drop();
            }
            else Log("Camera collision response animator creation failed.");
        }
        else Log("Terrain triangle selector creation failed.");
    }
    else Log("No terrain with which to create collision.");
I know the collision animator is working because I've set the gravity Y to a negative number and the camera falls, but I'm driving right through the terrain. I've inspected the FPS camera and I can't determine what I need to do in the wxWidgets event handler that's being done over there. I've also implemented the equivalent animator in a non-wxWidgets version of the program, per the tutorial, and it works fine. Any insight offered would be appreciated...
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I've never seen someone try to use a regular triangle selector with the terrain mesh. I don't think that mesh will have valid indices until after it has been rendered at least once. You might try to see if the returned mesh actually has any mesh buffers, vertices and indices in it. I doubt that it will.

You should probably use smgr->createTerrainTriangleSelector() instead.

Travis
gbutcher
Posts: 8
Joined: Sun Jan 06, 2008 4:27 pm

Post by gbutcher »

Doh!

Works fine now... thanks, vitek.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

vitek wrote:I've never seen someone try to use a regular triangle selector with the terrain mesh. I don't think that mesh will have valid indices until after it has been rendered at least once. You might try to see if the returned mesh actually has any mesh buffers, vertices and indices in it. I doubt that it will.
Yup, it's bogus. I'm not sure why it even has a getMesh() method. You could create an SMesh from getMeshBufferForLOD() and then use that, but it'd be hugely inefficient compared to a terrain triangle selector.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply