attached camera don't move

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
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

attached camera don't move

Post by acropole »

Hi,

I create a camera attached to it's parent, a scenenode.
When I move the scene node the camera don't follow :

Code: Select all

device->getSceneManager()->addCameraSceneNode(Game->player);
and

Code: Select all

core::vector3df v = Game->player->getPosition();
if(keys[KEY_KEY_Z]){v.X += 1.0f;}
if(keys[KEY_KEY_S]){v.X -= 1.0f;}
if(keys[KEY_KEY_Q]){v.Y += 1.0f;}
if(keys[KEY_KEY_D]){v.Y -= 1.0f;}
if(keys[KEY_SPACE]){v.Z += 1.0f;}
if(keys[KEY_CONTROL]){v.Z -= 1.0f;}

Game->player->setPosition(v);
thanks
d3jake
Posts: 198
Joined: Sat Mar 22, 2008 7:49 pm
Location: United States of America

Post by d3jake »

You could try:

Code: Select all

camera->setPosition(sceneNode->getAbsolutePosition();
or something similar to that... I seem to remember that working for me but I'm not 100% sure right at this moment.
The Open Descent Foundation is always looking for programmers! http://www.odf-online.org
"I'll find out if what I deleted was vital here shortly..." -d3jake
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

Thanks, but I wont spend my time to trasnlate, rotate and scale every single node at every frame. Especially if there is an offset.

Irrlicht's doc says that the camera move with it's parent, not that I must mouve it miself.
wyrmmage
Posts: 204
Joined: Sun Mar 16, 2008 3:12 am
Contact:

Post by wyrmmage »

can you post the code that attaches the camera to its parent node? Is the camera being attached to a skinned mesh? (things are a bit different if it is)
-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

wyrmmage wrote:can you post the code that attaches the camera to its parent node?
do you mean :

Code: Select all

device->getSceneManager()->addCameraSceneNode(Game->player);
wyrmmage wrote: Is the camera being attached to a skinned mesh? (things are a bit different if it is)
-wyrmmage
thsi is my class (basic at this time):

Code: Select all

#ifndef _AMHPLAYER_
#define _AMHPLAYER_

#include <irrlicht.h>

using namespace irr;
using namespace scene;
using namespace core;

class amhPlayer :
	public ISceneNode
{
public:
	//! Constructor
	amhPlayer(ISceneNode* parent, ISceneManager* mgr, s32 id=-1,
			const core::vector3df& position = core::vector3df(0,0,0),
			const core::vector3df& rotation = core::vector3df(0,0,0),
			const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));

	void render(void);
	const aabbox3d<f32>& getBoundingBox() const;

private:
	core::aabbox3d<f32> Box;

public:
	~amhPlayer(void);
};
#endif

Code: Select all

#include "amhPlayer.h"

void amhPlayer::render(void){
}

const aabbox3d<f32>& amhPlayer::getBoundingBox() const{
	return Box;
}


amhPlayer::amhPlayer(ISceneNode* parent, ISceneManager* mgr, s32 id,
		const core::vector3df& position,
		const core::vector3df& rotation,
		const core::vector3df& scale): ISceneNode(parent, mgr, 501, position, rotation, scale)
{
	if (Parent)
		Parent->addChild(this);
	updateAbsolutePosition();
}

amhPlayer::~amhPlayer(void)
{
}
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

The code that you have provided looks fine. Either the problem is in code that you haven't shown us, or you are expecting the camera's view target to move, which won't happen.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

It's ok now, but as you say, rogerborg, the target don't move.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

OK, that's expected. Camera targets are absolute, not relative, so if you want a camera to keep looking in the same direction while it's moving, you'll have to keep updating its target.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

rogerborg wrote:OK, that's expected. Camera targets are absolute, not relative, so if you want a camera to keep looking in the same direction while it's moving, you'll have to keep updating its target.
what do you mean by "updating" ?
Should I call some irrlicht function or should I build it myself and add all the vector/matrices operations ?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Calculate a new look-at position and call setTarget() each time round your main render loop. You can have a look at CSceneNodeAnimatorCameraFPS::animateNode() for an example, although your calculation may not need to be anywhere near that complex.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

Weird things happens.

The camera moves but not the target and the camera rotate in weird directions.

Here is my class :

Code: Select all

#include "amhEventReceiver.h"
#include <fstream>
#include <string>

f32 MoveSpeed = 1.0f;
f32 RotateSpeed = PI/180;
f32 JumpSpeed = MoveSpeed;
vector3df cameraOffset(0.0f, 0.0f, 0.0f);

// on event
bool amhEventReceiver::OnEvent(const SEvent& event){
	
	if(event.EventType == EET_KEY_INPUT_EVENT){
			keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
	}
	if(event.EventType == EET_MOUSE_INPUT_EVENT){
		if(Game->game_state == IN_GAME)
		if(event.MouseInput.Event == EMIE_MOUSE_MOVED ){
			OnMouseMoved(); 
		}
	}
	if(event.EventType == EET_GUI_EVENT){
			return checkGuiEvent(event);
	}
	if(event.EventType == EET_LOG_TEXT_EVENT){
	}
	if(event.EventType == EET_USER_EVENT){
	}

	return false;
}

// rotate the node
void amhEventReceiver::rotate(ISceneNode *node, vector3df rot) 
{ 
    matrix4 m;
    m.setRotationDegrees(node->getRotation());
    matrix4 n;
    n.setRotationDegrees(rot);
    m *= n;
    node->setRotation( m.getRotationDegrees() );
    node->updateAbsolutePosition();
} 

// yaw
void amhEventReceiver::turn(ISceneNode *node, f32 rot){
    rotate(node, vector3df(0.0f, rot, 0.0f) );
} 

// pitch
void amhEventReceiver::pitch(ISceneNode *node, f32 rot){
    rotate(node, vector3df(rot, 0.0f, 0.0f) );
} 

// roll
void amhEventReceiver::roll(ISceneNode *node, f32 rot){ 
    rotate(node, vector3df(0.0f, 0.0f, rot) ); 
}

// when mouse move
void amhEventReceiver::OnMouseMoved(void){
	if(firstMouseMove){
		CursorControl->setPosition(0.5f, 0.5f);
		CenterCursor = CursorControl->getRelativePosition();

		lastMouseMouved = device->getTimer()->getTime();

		firstMouseMove = false;
	}

	u32 timeMs = device->getTimer()->getTime();
	f32 timeDiff = (f32) ( timeMs - lastMouseMouved );
	lastMouseMouved = timeMs;

	if (CursorControl){
		core::position2d<f32> cursorpos = CursorControl->getRelativePosition();

		vector3df RelativeRotation = Game->player->getRotation();

		if (!core::equals(cursorpos.X, CenterCursor.X) ||
			!core::equals(cursorpos.Y, CenterCursor.Y))
		{
			RelativeRotation.Y += (cursorpos.Y - 0.5f) * RotateSpeed;
			RelativeRotation.X += (cursorpos.X - 0.5f) * RotateSpeed;
			
			if(cursorpos.X != 0.5f)
				turn(Game->player, RelativeRotation.X);
			if(cursorpos.Y != 0.5f)
				pitch(Game->player, RelativeRotation.Y);

			CursorControl->setPosition(0.5f, 0.5f);
			CenterCursor = CursorControl->getRelativePosition();
		}
		updateCamera();
	}
}

// update the caerma
void amhEventReceiver::updateCamera(void){
	video::IVideoDriver* driver = smgr->getVideoDriver();
	matrix4 m; 
	m.setRotationDegrees(Game->player->getRotation()); 

	vector3df frv = vector3df (0.0f, 0.0f, 1.0f); 
	m.transformVect(frv); 

	vector3df upv = vector3df (0.0f, 1.0f, 0.0f); 
	m.transformVect(upv); 

	m.transformVect(cameraOffset); 

	smgr->getActiveCamera()->setPosition(Game->player->getPosition()); 
	smgr->getActiveCamera()->setUpVector(upv); 

	smgr->getActiveCamera()->setTarget(frv + Game->player->getPosition()); 
}

// gui events
bool amhEventReceiver::checkGuiEvent(const SEvent& event){
	IGUIEnvironment* env = device->getGUIEnvironment();
	s32 id = event.GUIEvent.Caller->getID();

	switch(event.GUIEvent.EventType){
		case EGET_SCROLL_BAR_CHANGED:
			if (id == 104)	{
				s32 barpos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
				for (s32 i=0; i<EGDC_COUNT ; ++i){
					SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
					col.setAlpha(barpos);
					env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
				}	
			}
			break;
		case EGET_BUTTON_CLICKED:
			if(id == 101){
				if(smgr->loadScene("media/maps/test01.irr")){
					Game->game_state = IN_GAME;
				}
			}
			if(id == 103){
				Game->game_state = GAME_EXIT;
			}
		break;
	}
	return false;
}

// keyboards, mous and GUI events
void amhEventReceiver::checkEvents(){
	if(keys[KEY_ESCAPE]){ Game->game_state = GAME_EXIT;	}

	// camera movements
	if(smgr->getActiveCamera()){
		core::vector3df pos = Game->player->getPosition();

		f32 timeDiff = (f32) ( device->getTimer()->getTime() - lastMouseMouved )/100000.0f;

		if (keys[KEY_KEY_Z])	
			pos.Z += timeDiff * MoveSpeed;
		if (keys[KEY_KEY_S])	pos.Z -= timeDiff * MoveSpeed;

		if (keys[KEY_KEY_Q])	pos.X -= timeDiff * MoveSpeed;
		if (keys[KEY_KEY_D])	pos.X += timeDiff * MoveSpeed;
		if (keys[KEY_SPACE])	pos.Y += timeDiff * JumpSpeed;
		if(keys[KEY_CONTROL])   pos.Y -=  timeDiff * JumpSpeed;

		Game->player->setPosition(pos);
		updateCamera();	
	}
}

amhEventReceiver::amhEventReceiver(IrrlichtDevice* d, amhGame* g, ICursorControl* icc)
						:firstMouseMove(true)
{
	device = d;
	smgr = device->getSceneManager();
	Game = g;
	CursorControl = icc;

	for(int x=0; x<irr::KEY_KEY_CODES_COUNT; x++) keys[x] = false; 
	loadConfig();
}

amhEventReceiver::~amhEventReceiver(void)
{
}

acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

well, I restart from the begining.

First I try to move the camera. Everything is OK except when I release the space barr. It's used to move the camera up but when I release it the camera is replaced at origin.

I add the camera with addCameraSceneNode

then I check the keys and I move it with this :

Code: Select all

void amhEventReceiver::move(vector3df dir){
	smgr->getActiveCamera()->setPosition(smgr->getActiveCamera()->getPosition() + dir);
	smgr->getActiveCamera()->setTarget(smgr->getActiveCamera()->getTarget() + dir);
}
nothing special there.
It seems that irrlicht itself don't want to let the camera where I placed it with the space barr.
The movement down is ok but not in the up dir.
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

it's weird.

If I use KEY_LSHIFT instead of KEY_SPACE nothing happens, but if I use KEY_V it's ok.

does KEY_LSHIFT and KEY_SPACE correctly handled by irrlicht ?

EDIT ---------------

I found why !

this is because :

Code: Select all

		case EGET_BUTTON_CLICKED:
			if(id == 101){
				if(smgr->loadScene("media/maps/test01.irr")){
					Game->game_state = IN_GAME;
					smgr->addCameraSceneNode();
				}
			}
the map is reloaded because the space barr is like a click on the button, even if the GUI is hidden.
Post Reply