Can I create a not-FPS 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.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

if you move the camera you'll have to update the target, too !!!
otherwise the camera is still looking at the previous target, what looks like the camera rotates (in fact it does)...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Peppe
Posts: 16
Joined: Wed Aug 08, 2007 5:12 pm

Post by Peppe »

If I click the arrow key I move the camera with setPosition and rotate the target...

I want rotate the target whit mouse movement.
Peppe
Posts: 16
Joined: Wed Aug 08, 2007 5:12 pm

Post by Peppe »

can you help me?
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

no, not as long as we don't know what you're doing now in your code... ;)
what do you do in your event receiver, how does your main loop look like and so on...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Ecliptic Fate
Posts: 19
Joined: Tue Apr 26, 2005 6:10 am

Post by Ecliptic Fate »

delete this... or get a real forum so I can do it!
Last edited by Ecliptic Fate on Mon Sep 27, 2010 12:54 am, edited 1 time in total.
Peppe
Posts: 16
Joined: Wed Aug 08, 2007 5:12 pm

Post by Peppe »

Ok...I solved...But if I solve a problem, another problem appear:

Image

When I rotate the camera target from -90° to 90° it work correctly, but if

I rotate the camera target over 90° , the target rotate forr 180° on the Y

axis and return to -90°.

This is My complete code:

Code: Select all


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

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")
 IrrlichtDevice* device = 0;
 	 

 
 int Spostamento_CameraX = 225;
 int Spostamento_CameraZ = 3000;

  
 bool sganctarg = false;
 core::vector3df last_rotation;
 core::vector3df rotazione_iniziale;
 core::position2d<s32> point;
 core::dimension2d<s32> screen_size; 
 float rotAngle   ;
core::vector3df  direction=core::vector3df(0,0,1); 
     
	class MyEventReceiver : public IEventReceiver
{
 
	 
 

  bool OnEvent(SEvent event)
	{
		 
		if (event.EventType == irr::EET_KEY_INPUT_EVENT&& event.KeyInput.PressedDown)
		{
			 if(event.KeyInput.Key== KEY_ESCAPE)
              {
              
 device->closeDevice(); 
 return true;
    }
       if(event.KeyInput.Key== KEY_UP )
              {  
                    Spostamento_CameraX=Spostamento_CameraX+5;           
                                return true;
    }
      
             if(event.KeyInput.Key== KEY_DOWN )
              {  
                    Spostamento_CameraX=Spostamento_CameraX-5;           
                                return true;
    }
      
       if(event.KeyInput.Key== KEY_RIGHT )
              {  
                    Spostamento_CameraZ=Spostamento_CameraZ-5;           
                                return true;
    }	
        if(event.KeyInput.Key== KEY_LEFT )
              {  
                    Spostamento_CameraZ=Spostamento_CameraZ+5;           
                                return true;
    }	  

                                         
                                            
  }
      if (event.EventType == EET_MOUSE_INPUT_EVENT)  { 
if(event.MouseInput.Event==EMIE_MOUSE_MOVED){
  
        
  }
  
  if ( event.MouseInput.Event==EMIE_RMOUSE_PRESSED_DOWN  ) 
      { 
   sganctarg = true;    





 }                                            
        if ( event.MouseInput.Event==EMIE_RMOUSE_LEFT_UP ) 
      { 
   sganctarg = false;    
  } 

  }
   }
	private:
	scene::ISceneNode* Terrain;	
	};

 
 


 
int main()
{
	 
 

 	
	  


	video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;

 
 driverType = video::EDT_DIRECT3D9;
	

	// creiamo la device

	 device = createDevice(driverType, core::dimension2d<s32>(1280, 800),16,false,false,false );

	if (device == 0)
		return 1; // non creiamo il driver selezionato
 
 
 
	/*
	First, we add standard stuff to the scene: A nice irrlicht engine
	logo, a small help text, a user controlled camera, and we disable
	the mouse cursor.
	*/   

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

	driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
 

	//set other font
	env->getSkin()->setFont(env->getFont("../media/fontlucida.png"));

//spostamento camera

 
	 

	// add camera
	
      scene::ICameraSceneNode* camera = 
 		smgr->addCameraSceneNode(     );

 
   
	camera->setFarValue(12000.0f);
 MyEventReceiver receiver;
device->setEventReceiver(&receiver);
	// disable mouse cursor
	device->getCursorControl()->setVisible(false);

	/*
	Here comes the terrain renderer scene node: We add it just like any 
	other scene node to the scene using ISceneManager::addTerrainSceneNode(). 
	The only parameter we use is a file name to the heightmap we use. A heightmap
	is simply a gray scale texture. The terrain renderer loads it and creates 
	the 3D terrain from it.
	To make the terrain look more big, we change the scale factor of it to (40, 4.4, 40).
	Because we don't have any dynamic lights in the scene, we switch off the lighting,
	and we set the file terrain-texture.jpg as texture for the terrain and 
	detailmap3.jpg as second texture, called detail map. At last, we set
	the scale values for the texture: The first texture will be repeated only one time over 
	the whole terrain, and the second one (detail map) 20 times. 
	*/
 //Il menu
 gui::IGUIContextMenu* menu = env->addMenu();
	menu->addItem(L"File", -1, true, true);
	menu->addItem(L"Tiles", -1, true, true);
	menu->addItem(L"Camera", -1, true, true);
	menu->addItem(L"Help", -1, true, true);
 
 	gui::IGUIContextMenu* submenu;
	submenu = menu->getSubMenu(0);
	submenu->addItem(L"Apri Tiles...", 100);
	submenu->addItem(L"Apri Gruppo Tiles...", 103);
    submenu->addSeparator();
    submenu->addItem(L"Salva Tiles...", 101);
	submenu->addItem(L"Salva Gruppo Tiles...", 104);
    submenu->addSeparator();
	submenu->addItem(L"Chiudi", 200);
	
	
	// add terrain scene node
	scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( 
		"../media/terrainheightmap.bmp",
		0,										// parent node
		-1,										// node id
		core::vector3df(0.f, 0.f, 0.f),			// position
		core::vector3df(0.f, 0.f, 0.f),			// rotation
		core::vector3df(40.f, 4.4f, 40.f),		// scale
		video::SColor ( 255, 255, 255, 255 ),	// vertexColor,
		5,										// maxLOD
		scene::ETPS_17,							// patchSize
		4										// smoothFactor
		);

	terrain->setMaterialFlag(video::EMF_LIGHTING, false);

	terrain->setMaterialTexture(0, driver->getTexture("../media/Textures/Erba1.jpg"));
	terrain->setMaterialTexture(1, driver->getTexture("../media/Terreno0/detailmap3.jpg"));
	
 
	terrain->setMaterialType(video::EMT_DETAIL_MAP);


	terrain->scaleTexture(20.0f, 20.0f);
	
	//terrain->setDebugDataVisible ( true );

//il mouse fuori dal loop 
  core::position2d<s32> Zp_MOUSE_Pos ;
  video::ITexture* cursore2 = driver->getTexture("../media/varie/puntatore.png");
  





 


	/*
	To be able to do collision with the terrain, we create a triangle selector.
	If you want to know what triangle selectors do, just take a look into the 
	collision tutorial. The terrain triangle selector works together with the
	terrain. To demonstrate this, we create a collision response animator 
	and attach it to the camera, so that the camera will not be able to fly 
	through the terrain.
	*/

	// create triangle selector for the terrain	
	scene::ITriangleSelector* selector
		= smgr->createTerrainTriangleSelector(terrain, 0);
	terrain->setTriangleSelector(selector);
	selector->drop();

	// create collision response animator and attach it to the camera
	scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
		selector, camera, core::vector3df(60,100,60),
		core::vector3df(0,0,0), 
		core::vector3df(0,50,0));
	camera->addAnimator(anim);
	anim->drop();

	/*
	To make the user be able to switch between normal and wireframe mode, we create
	an instance of the event reciever from above and let Irrlicht know about it. In 
	addition, we add the skybox which we already used in lots of Irrlicht examples.
	*/

	// create event receiver

   	// create skybox
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
     
	smgr->addSkyBoxSceneNode(
		driver->getTexture("../media/cieli/18/irrlicht2_up.jpg"),
		driver->getTexture("../media/cieli/18/irrlicht2_dn.jpg"),
		driver->getTexture("../media/cieli/18/irrlicht2_lf.jpg"),
		driver->getTexture("../media/cieli/18/irrlicht2_rt.jpg"),
		driver->getTexture("../media/cieli/18/irrlicht2_ft.jpg"),
		driver->getTexture("../media/cieli/18/irrlicht2_bk.jpg"));

	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

	/*
	That's it, draw everything. Now you know how to use terrain in Irrlicht.
	*/

	int lastFPS = -1;

	while(device->run())

    if (device->isWindowActive())
	{

        driver->beginScene(true, true, 0 );
 
		smgr->drawAll();
		env->drawAll();
 

     //Il mouse nel LOOP
  Zp_MOUSE_Pos = device->getCursorControl()->getPosition();
  driver->draw2DImage(
  cursore2,core::position2d<s32>(Zp_MOUSE_Pos.X,Zp_MOUSE_Pos.Y),
   
  core::rect<s32>(0,0,32,32), 0,video::SColor(255,255,255,255), true
  );
 
 
 //rotazione camera
 camera->setPosition(core::vector3df( Spostamento_CameraX*2,255*2,Spostamento_CameraZ*2));
  camera->updateAbsolutePosition();
  if (sganctarg==true){
  

    point=device->getCursorControl()->getPosition(); 
screen_size=device->getVideoDriver()->getScreenSize(); 
     if (point.X  >= 645){ 
     rotAngle  = rotAngle - 1; // rotate 1° anti clockwise, but should it not be clockwise? 
     if(rotAngle < 0) rotAngle  = rotAngle + 360; 
   } 
Code: 
 if (point.X <= 635){ 
      rotAngle  = rotAngle +1; 
   if(rotAngle >= 360) rotAngle  = rotAngle -360; 
   }  

rotazione_iniziale.X =Spostamento_CameraX + sin(rotAngle * 3.14156 / 180.0)*3000 ; 
   rotazione_iniziale.Z =Spostamento_CameraZ + cos(rotAngle * 3.14156 / 180.0)*3000 ;
 
 
 

 
   camera->setTarget(rotazione_iniziale) ; 
camera->updateAbsolutePosition(); 

 
}
   
 
   
			
        driver->endScene();
		       


		// display frames per second in window title
		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			core::stringw str = L"Terrain Renderer - Irrlicht Engine [";
			str += driver->getName();
			str += "] FPS:";
			str += fps;
			// Also print terrain height of current camera position
			// We can use camera position because terrain is located at coordinate origin
			str += " rot: ";
			 
            str += rotAngle;
       
			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}
		
	}
 
	device->drop();
	
	return 0;
}


I don't understand where is the problem :( :cry: :cry:
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

the problem seems to be with this 2 lines:

Code: Select all

rotazione_iniziale.X =Spostamento_CameraX + sin(rotAngle * 3.14156 / 180.0)*3000 ;
rotazione_iniziale.Z =Spostamento_CameraZ + cos(rotAngle * 3.14156 / 180.0)*3000 ;
there must be 3 lines and you always have to get the actual camera position, then you don't need to multiply with 3000 (or any other value) !!!
exchange the 2 lines with this 3 lines:

Code: Select all

rotazione_iniziale.Y =camera->getPosition().Y;
rotazione_iniziale.X =camera->getPosition().X + sin(rotAngle * 3.14156 / 180.0) ;
rotazione_iniziale.Z =camera->getPosition().Z + cos(rotAngle * 3.14156 / 180.0) ;
or maybe better this way:

Code: Select all

rotazione_iniziale = camera->getPosition();
rotazione_iniziale.X += sin(rotAngle * 3.14156 / 180.0) ;
rotazione_iniziale.Z += cos(rotAngle * 3.14156 / 180.0) ;
that should work... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

and use core::DEGTORAD and core::RADTODEG to convert instead of the manually added consts.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

right, that's probably faster ;)

now let's make a one-liner out of it :lol: :

Code: Select all

rotazione_iniziale = camera->getPosition() + vector3df(sin(rotAngle * core::DEGTORAD), 0, cos(rotAngle * core::DEGTORAD)); 
or direct with setTarget so you don't need rotazione_iniziale anymore 8) :

Code: Select all

camera->setTarget(camera->getPosition() + vector3df(sin(rotAngle * core::DEGTORAD), 0, cos(rotAngle * core::DEGTORAD))) ;
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Peppe
Posts: 16
Joined: Wed Aug 08, 2007 5:12 pm

Post by Peppe »

Wow, it work!!!!!!!!! :D :D Thank you very much!!!!!!!! :D
Post Reply