Help with custom SceneNode

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
eXodus
Posts: 320
Joined: Tue Jan 04, 2005 10:07 am
Location: Canada
Contact:

Help with custom SceneNode

Post by eXodus »

Hi everyone!

I'm trying to develop a topview chopper game done with Irrlicht. Here's a clue :
Image

With time, the MyEventReceiver is getting bigger and bigger to a point that its unreadable. I'm trying to clean up code by creating a custom SceneNode that implements IEventReceiver::OnEvent(SEvent).

I've been through the tutorial on this subject and created pretty much the same class. Each time MyEventReceiver is notified of an event, it gives it to the CPlayerSceneNode::OnEvent(SEvent) which returns true if treated. I'm only checking for simple inputs to move the node according to which arrow key is pressed.

Here's my problem, I went through some debugging and I know that :
When pressing the arrow key, the CPlayerSceneNode::OnEvent(SEvent) gets notified. GOOD
If the pressed key is an arrow, the proper code gets executed. GOOD
According to the arrow key, the node's position gets updated. STILL GOOD
But even if the node's position is changing, there's no visual feedback. The mesh stays at its initial position. Not that good...

Here's a part of the code

Code: Select all

bool CPlayerSceneNode::OnEvent(SEvent event)
{
	bool consumed = false;

	if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
	{
		vector3df pos = this->getPosition();
		switch(event.KeyInput.Key)
		{
		case KEY_LEFT:
			{
				pos.X--;
				consumed = true;
			}
			break;
		case KEY_RIGHT:
			{
				pos.X++;
				consumed = true;
			}
			break;
		}
		this->setPosition(pos);
	}

	return consumed;
}
Could the problem be related to the render method that only calls

Code: Select all

IVideoDriver * driver = SceneManager->getVideoDriver();
	driver->setMaterial(m_material);
	driver->drawMeshBuffer(m_mesh->getMeshBuffer(0));
Morrog
Posts: 58
Joined: Mon Dec 13, 2004 5:13 am

Post by Morrog »

Your render should be similar to:

Code: Select all

//! renders the node.
void CMeshSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();

	if (!Mesh || !driver)
		return;

	driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
	Box = Mesh->getBoundingBox();

	// for debug purposes only:
	if (DebugDataVisible)
	{
		video::SMaterial m;
		m.Lighting = false;
		driver->setMaterial(m);
		driver->draw3DBox(Box, video::SColor(0,255,255,255));
	}

	for (s32 i=0; i<Mesh->getMeshBufferCount(); ++i)
	{
		scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
		
		driver->setMaterial(Materials[i]);
		driver->drawMeshBuffer(mb);
	}			
}
You can omit the debug stuff. I just copied that right from Irrlicht's source.
And make sure you don't override OnPostRender without calling ISceneNode::OnPostRender() since ISceneNode's implementation of OnPostRender takes care of updating the transformation matrix.
eXodus
Posts: 320
Joined: Tue Jan 04, 2005 10:07 am
Location: Canada
Contact:

Post by eXodus »

You just solved my problem :mrgreen:

Just one more question :
Is calling the custom node's OnEvent method from MyEventReceiver the only way to do it? Could the node receive event notifications automatically?
Post Reply