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

Post by someguy99 »

Are you talking about Maya camera? I dont think so
Serg88
Posts: 30
Joined: Mon Oct 19, 2009 5:52 pm
Location: Moscow/Russia

Post by Serg88 »

its worked with maya too.

what version of irrlicht you use?
from Russia with love :))))
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

Here is the code

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;
}
Now edit the camera to Maya camera and youll notice the weird behavior.
Serg88
Posts: 30
Joined: Mon Oct 19, 2009 5:52 pm
Location: Moscow/Russia

Post by Serg88 »

yours camera strange rotate?
if yes then, im seen it once :))))
but with FPS camera

Code: Select all

node->setPosition(nodePosition); 
        
camera->setTarget(node->getPosition());

//add this code and camera will folow a objects
nodePosition.Y += 200; //displacement along the axis of the camera
nodePosition.Z += 200; //displacement along the axis of the camera
camera->setPosition(nodePosition);
with each camera, thas i made
i myself calculate geometry without make him parenting or childing node
from Russia with love :))))
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

So this is a bug?
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

I still think this is a bug.
To me it looks like it IS parented, because when you move the node, it moves. But in a weird way. Looks like it's orbit turns from sphere to elipsoid shape or something as you move the node.
Seraph
Posts: 68
Joined: Wed Oct 21, 2009 5:58 pm

Post by Seraph »

i think that i have the same problem. i create a fps game and i need to verify the position of the camera, but when i use:

font->draw(core::stringw(game->camera->getPosition().X).c_str(), core::rect<s32>(700,655,300,60),video::SColor(0,255,0,0));

(this part of code have also a warning... [Warning] passing `const irr::f32' for converting 1 of `irr::core::string<T>::string(int) [with T = wchar_t]' )

the value that is on the screen is the same that i set at the start of the application. why? is the warning the problem? the camera that i want is not a child, i must use this

camera->setTarget(???->getPosition());

how?
someguy99
Posts: 38
Joined: Sun Oct 11, 2009 11:20 am

Post by someguy99 »

Sorry, but what does that have to do with my problem??

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->addCameraSceneNodeMaya();
   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;
}

This is my problem.
Notice the weird way it moves and rotates?
Now change

Code: Select all

ICameraSceneNode *camera= smgr->addCameraSceneNodeMaya();
to

Code: Select all

ICameraSceneNode *camera= smgr->addCameraSceneNode();
Works fine.
I would understand if FPS camera behaved weird because whats the point in using FPS camera if it moves with the node and always looks at the node?
But Maya camera was ment for that ( to orbit around something (node))
Post Reply