follow camera

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.
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

follow camera

Post by someguy99 »

I still dont understand how to attach a normal camera to a scenenode. I thought setParent was for that, but it doesnt work. How would you attach a camera to a node ( so when u move the node the camera would move with it)?
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Re: follow camera

Post by Virion »

someguy99 wrote:I still dont understand how to attach a normal camera to a scenenode. I thought setParent was for that, but it doesnt work. How would you attach a camera to a node ( so when u move the node the camera would move with it)?
that's exactly how setParent would work. all you have to do is create an empty node which is a child of either the scenenode or camera node and update your camera's target to it's location.
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

in my own proyect i am using this code :

Code: Select all

 
ICameraSceneNode *cam= irrlicht_device.smgr->addCameraSceneNode();
   cam->setPosition(vector3df(0,9,-14));
cam->setParent(ninja.node);

its simple but it works 8)
Psan
Posts: 16
Joined: Sun Oct 04, 2009 7:07 pm

Post by Psan »

Make sure you setPosition the camera well outside your node after setParent, else the node will make it blind.
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

Finally some free time.
Lil Margin wrote:in my own proyect i am using this code :

Code: Select all

 
ICameraSceneNode *cam= irrlicht_device.smgr->addCameraSceneNode();
   cam->setPosition(vector3df(0,9,-14));
cam->setParent(ninja.node);

its simple but it works 8)
It does? Maybe you add something else?

Code: Select all

Camera->setPosition(vector3df(0,9,-14));
Camera->setParent(node);
doesnt seem to work for me.
I just added that to example 4 but the camera doesnt move with the sphere.
I dont think theres a need to post the code , right? Its the same exakple 4 with normal camera instead of FPS...
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

Dudes...
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

post your code, its always good to see it for myself.
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


// event reciever
class MyEventReceiver : public IEventReceiver
{
public:
	// This is the one method that we have to implement
	virtual bool OnEvent(const SEvent& event)
	{
		// Remember whether each key is down or up
		if (event.EventType == irr::EET_KEY_INPUT_EVENT)
			KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

		return false;
	}

	// This is used to check whether a key is being held down
	virtual bool IsKeyDown(EKEY_CODE keyCode) const
	{
		return KeyIsDown[keyCode];
	}
	
	MyEventReceiver()
	{
		for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	}

private:
	// We use this array to store the current state of each key
	bool KeyIsDown[KEY_KEY_CODES_COUNT];
};


int main()
{	
    // create device
	MyEventReceiver receiver;

	IrrlichtDevice* device = createDevice(video::EDT_OPENGL,
			core::dimension2d<s32>(640, 480), 16, false, false, false, &receiver);

	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

	/*
	Create the node which will be moved with the WSAD keys. We create a
	sphere node, which is a built-in geometry primitive. We place the node
	at (0,0,30) and assign a texture to it to let it look a little bit more
	interesting. Because we have no dynamic lights in this scene we disable
	lighting for each model (otherwise the models would be black).
	*/
	scene::ISceneNode * node = smgr->addSphereSceneNode();
	if (node)
	{
		node->setPosition(core::vector3df(0,0,30));
		node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
		node->setMaterialFlag(video::EMF_LIGHTING, false);
	}

    // add a camera and attach it to the node
	ICameraSceneNode *camera= smgr->addCameraSceneNode();
	camera->setPosition(vector3df(0,9,-14));
    camera->setParent(node);
	
	// hide mouse
    device->getCursorControl()->setVisible(false);
    
	int lastFPS = -1;

	// In order to do framerate independent movement, we have to know
	// how long it was since the last frame
	u32 then = device->getTimer()->getTime();

	// This is the movemen speed in units per second.
	const f32 MOVEMENT_SPEED = 5.f;

	while(device->run())
	{
		// Work out a frame delta time.
		const u32 now = device->getTimer()->getTime();
		const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
		then = now;

		/* Check if keys W, S, A or D are being held down, and move the
		sphere node around respectively. */
		core::vector3df nodePosition = node->getPosition();

		if(receiver.IsKeyDown(irr::KEY_KEY_W))
			nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
		else if(receiver.IsKeyDown(irr::KEY_KEY_S))
			nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;

		if(receiver.IsKeyDown(irr::KEY_KEY_A))
			nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
		else if(receiver.IsKeyDown(irr::KEY_KEY_D))
			nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;

		node->setPosition(nodePosition);

		driver->beginScene(true, true, video::SColor(255,113,113,133));

		smgr->drawAll(); // draw the 3d scene
		device->getGUIEnvironment()->drawAll(); // draw the gui environment (the logo)

		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
			core::stringw tmp(L"Movement Example - Irrlicht Engine [");
			tmp += driver->getName();
			tmp += L"] fps: ";
			tmp += fps;

			device->setWindowCaption(tmp.c_str());
			lastFPS = fps;
		}
	}

	/*
	In the end, delete the Irrlicht device.
	*/
	device->drop();
	
	return 0;
}
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

as i see you only have one sphere...you don't have a world to see the difference the mouse is making...
try adding a world and see...at this moment its in blank space so you cant really notice the changes :)
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

That really isnt required.
If youll move the sphere the camera wouldnt move with it, it will stay in the same position. I dont need another object to notice that
I would need another object if say i had a follow camera and i wanted to check if the movement code works
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

So....
maybe something like this?

Code: Select all

camera->setTarget(node->getPosition());
before

Code: Select all

driver->beginScene(true, true, SColor(255,113,113,133));
? :wink:
NEW:

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


// event reciever
class MyEventReceiver : public IEventReceiver
{
public:
	// This is the one method that we have to implement
	virtual bool OnEvent(const SEvent& event)
	{
		// Remember whether each key is down or up
		if (event.EventType == irr::EET_KEY_INPUT_EVENT)
			KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

		return false;
	}

	// This is used to check whether a key is being held down
	virtual bool IsKeyDown(EKEY_CODE keyCode) const
	{
		return KeyIsDown[keyCode];
	}
	
	MyEventReceiver()
	{
		for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	}

private:
	// We use this array to store the current state of each key
	bool KeyIsDown[KEY_KEY_CODES_COUNT];
};


int main()
{	
    // create device
	MyEventReceiver receiver;

	IrrlichtDevice* device = createDevice(EDT_OPENGL,
			dimension2d<s32>(1024, 768), 16, false, false, false, &receiver);

	if (device == 0)
		return 1; // could not create selected driver.

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
    
    // add another object to prove it moves
    IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
	if (!mesh)
		return 1;
	IAnimatedMeshSceneNode* sydney = smgr->addAnimatedMeshSceneNode( mesh );
    if (sydney)
	{
		sydney->setMaterialFlag(EMF_LIGHTING, false);
		sydney->setMD2Animation(EMAT_STAND);
		sydney->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
	}
    
	/*
	Create the node which will be moved with the WSAD keys. We create a
	sphere node, which is a built-in geometry primitive. We place the node
	at (0,0,30) and assign a texture to it to let it look a little bit more
	interesting. Because we have no dynamic lights in this scene we disable
	lighting for each model (otherwise the models would be black).
	*/
	scene::ISceneNode * node = smgr->addSphereSceneNode();
	if (node)
	{
		node->setPosition(vector3df(0,0,0));
		node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
		node->setMaterialFlag(EMF_LIGHTING, false);
	}

    // add a camera and attach it to the node
	ICameraSceneNode *camera= smgr->addCameraSceneNode();
	camera->setPosition(vector3df(0,9,-14));
    
    // move with the node
    camera->setParent(node);
	
	// hide mouse
    device->getCursorControl()->setVisible(false);
    
	int lastFPS = -1;

	// In order to do framerate independent movement, we have to know
	// how long it was since the last frame
	u32 then = device->getTimer()->getTime();

	// This is the movemen speed in units per second.
	const f32 MOVEMENT_SPEED = 5.f;

	while(device->run())
	{
		// Work out a frame delta time.
		const u32 now = device->getTimer()->getTime();
		const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
		then = now;

		/* Check if keys W, S, A or D are being held down, and move the
		sphere node around respectively. */
		core::vector3df nodePosition = node->getPosition();

		if(receiver.IsKeyDown(KEY_KEY_W))
			nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
		else if(receiver.IsKeyDown(KEY_KEY_S))
			nodePosition.Y -= MOVEMENT_SPEED * frameDeltaTime;

		if(receiver.IsKeyDown(KEY_KEY_A))
			nodePosition.X -= MOVEMENT_SPEED * frameDeltaTime;
		else if(receiver.IsKeyDown(KEY_KEY_D))
			nodePosition.X += MOVEMENT_SPEED * frameDeltaTime;

		node->setPosition(nodePosition);
        
        // always look at the node
        camera->setTarget(node->getPosition());
        
		driver->beginScene(true, true, SColor(255,113,113,133));

		smgr->drawAll(); // draw the 3d scene
		device->getGUIEnvironment()->drawAll(); // draw the gui environment (the logo)

		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
			stringw tmp(L"Movement Example - Irrlicht Engine [");
			tmp += driver->getName();
			tmp += L"] fps: ";
			tmp += fps;

			device->setWindowCaption(tmp.c_str());
			lastFPS = fps;
		}
	}

	/*
	In the end, delete the Irrlicht device.
	*/
	device->drop();
	
	return 0;
}

Can someone tell me what is parenting for and why cant you just use

Code: Select all

camera->setTarget(node->getPosition());
?
Last edited by someguy99 on Tue Oct 20, 2009 11:08 am, edited 1 time in total.
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

parenting is used to make your camera a child of node, google search it for more.
as for your code...you say it doesnt work but i cant see the problem...i am not that advanced yet, sorry.
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

Lil Margin wrote:parenting is used to make your camera a child of node
Dude, i mean why is it used, what does it actually do. I know those terms.
as for your code...you say it doesnt work but i cant see the problem...
The latest one works...
EDIT: Whatever, now it works... weird, so

Code: Select all

camera->setParent(node);
makes the camera move with the node, and...

Code: Select all

camera->setTarget(node->getPosition());
makes the camera always look at the node
Last edited by someguy99 on Tue Oct 20, 2009 11:06 am, edited 2 times in total.
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

why doesnt Maya camera work? Arent you supposed to be allowed to set an object for it to look at? when i move the node it behaves weird
Bug?
Serg88
Posts: 30
Joined: Mon Oct 19, 2009 5:52 pm
Location: Moscow/Russia

Post by Serg88 »

i`ts doesnt bug,
perhaps you made a mistake, in my little experiment any camera follows for any object/
i dont seen you code, but this worked:

when init level:

Code: Select all

//i try this
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
//and this
scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.4f);

// ... some code

// from my_object_loader_func(...):
// object.node = smgr->addAnimatedMeshSceneNode(object.mesh);

// ... some code

player.node->addChild(camera);
in render loop:

Code: Select all

core::vector3df PlayerPos = this->player.node->getPosition();
	PlayerPos.Y += 20;
	this->player.node->setPosition(PlayerPos);
from Russia with love :))))
Post Reply