Smooth mixed 1st + 3rd Person Camera Scene Node (for RPG)

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
xterminhate
Posts: 206
Joined: Thu Sep 01, 2005 9:26 pm
Location: France

Post by xterminhate »

I don't think that this camera can be extended a lot to offer support of jumping, leaning, flying... using only Irrlicht library.

For enhanced and realistic player and camera moves, a physics engine is necessary. What do you think about a new project of 1+3 camera based on Newton engine ? Or another physics engine... let me know which physics engine you would like.

Keep in mind, this new camera will require linking your project with the physics library and perform supplementary meshes traitements.
Return to Irrlicht after years... I'm lovin it.
It's hard to be a Man !
Si vis pacem para belum
lug

Post by lug »

Hmm..after a quick look at the wiki page (http://www.irrforge.org/index.php/Physics_APIs), I think I would go with ODE for physics since it's open source and supports many platforms. That way you can peek inside the code if something goes wrong. We know that never happends! :shock:

That sound cool, xterminhate. I haven't used either newton or ode so I can't say one way or another. I favor ODE because of open source and many platform support. :wink:

Go! go! xterminhate!
kickBack
Posts: 13
Joined: Sat Jan 14, 2006 2:20 pm

Post by kickBack »

But i think you should use newton.. it is not so complicated and its better.
xterminhate
Posts: 206
Joined: Thu Sep 01, 2005 9:26 pm
Location: France

Post by xterminhate »

I will start with Newton Game Dynamics engine and I will have a look on ODE. During the development of the new camera, I maintain the current camera code.
Return to Irrlicht after years... I'm lovin it.
It's hard to be a Man !
Si vis pacem para belum
lug

Post by lug »

Heh...newton is cool with me. I just tried out their tractor demo. It's pretty cool.

So, when is this thread going to be moved to a more appropriate forum like the project announcement forum? :?

It only take a half a day before this thread gets bumped down. I vote to put this up as a cam tutorial on irrlicht wiki! :P
cubicool
Posts: 10
Joined: Sun Jan 29, 2006 7:15 pm

Post by cubicool »

Just wanted to update you real quick, Xterm, that I've changed the code up a bit for my own use so that this class no longer has to live inside of irr::scene and can be compiled __entirely__ outside of Irrlicht. My own engine is built on top of Irrlicht, and makes no modifications to Irrlicht's core, instead opting to implement the pure virtual interfaces of Irrlicht in my own namespaces. I can give the code to anyone who wants it, if it's needed.
Guest

Post by Guest »

Can you send me your code or give me a link ? I would like to have a look !

I'm currently working on Newton integration... :)
xterminhate
Posts: 206
Joined: Thu Sep 01, 2005 9:26 pm
Location: France

Post by xterminhate »

Damned cookies. It was me ! :twisted:
Return to Irrlicht after years... I'm lovin it.
It's hard to be a Man !
Si vis pacem para belum
Guest

Post by Guest »

The same for Irrlicht.Net ? ^^







Nezumi: Little french for little project
CodeDog
Posts: 106
Joined: Sat Oct 07, 2006 8:00 pm
Location: CA. USA
Contact:

Events in camera

Post by CodeDog »

I am having a strange issue with your camera. Then mouse and keyboard actions for mouse look and keyboard turn and move only work when the project is run from inside the IDE (VS 2005). When I run the compiled exe (outside of the IDE) the camera does not respond to the mouse look or keyboard based movement.
I have an event listener (I have the 'Q' key exit the program) that I attach when I create the device and it works correctly.
I thought perhaps my event listener might interfere with the camera but when I take out my event listener the camera still has the same strange behavior when running the compiled exe.


////////////////////////////code////////////////////////////////////////////////

Code: Select all

// Irrlicht3rdPersonCam2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <irrlicht.h>
#include <iostream>
#include "CCameraRPGSceneNode.hpp"

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

#pragma comment(lib, "Irrlicht.lib")

scene::ISceneNode* q3node = 0;
IrrlichtDevice* device = 0;
scene::IAnimatedMeshSceneNode* fairy;

class MyEventReceiver : public IEventReceiver
{

public:
	
	virtual bool OnEvent(SEvent event)
	{ 
		
		if (q3node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT &&
				!event.KeyInput.PressedDown)
		{
				switch(event.KeyInput.Key)
				{
				case KEY_KEY_Q:
					{
						device->closeDevice();
					}
					break;
				case KEY_KEY_W:
					{
						fairy->setMD2Animation(scene::EMAT_WAVE);						
					}
					break;
				case KEY_KEY_N:
					{
						
						fairy->setMD2Animation(scene::EMAT_STAND);	
						
					}
					return true;
				
				}
		}

	return false;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	MyEventReceiver receiver;
	// let user select driver type
	//video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
	//printf("Please select the driver you want for this example:\n"\
		//" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		//" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
		//" (f) NullDevice\n (otherKey) exit\n\n");
	//char i;
	//std::cin >> i;
	//switch(i)
	//{
		//case 'a': driverType = video::EDT_DIRECT3D9;break;
		//case 'b': driverType = video::EDT_DIRECT3D8;break;
		//case 'c': driverType = video::EDT_OPENGL;   break;
		//case 'd': driverType = video::EDT_SOFTWARE; break;
		//case 'e': driverType = video::EDT_SOFTWARE2;break;
		//case 'f': driverType = video::EDT_NULL;     break;
		//default: return 1;
	//}

	// create device and exit if creation failed
	//IrrlichtDevice *device = createDevice(driverType, core::dimension2d<s32>(1024, 768), 16, false, true, true);
	//device = createDevice(driverType, core::dimension2d<s32>(1024, 768), 16, false, true, true);
	//driverType = video::EDT_DIRECT3D9;
	device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(1024, 768), 16, false, true, true, &receiver);
	if (device == 0)
		return 1; // could not create selected driver.

	// set window caption
	device->setWindowCaption(L"Irrlicht Engine - smooth mixed 1st + 3rd person camera example by Xterm-In'Hate");

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

	// load it Quake 3 map archive.
	device->getFileSystem()->addZipFileArchive("C:\\irrlicht-1.1\\media\\map-20kdm2.pk3");
	scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
	
	q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));
    q3node->setPosition(core::vector3df(-1370,-130,-1400));
	
	// add billboard
	scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();
	bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
	bill->setMaterialTexture(0, driver->getTexture(
         "C:\\irrlicht-1.1\\media\\particle.bmp"));
	bill->setMaterialFlag(video::EMF_LIGHTING, false);
	bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));

	video::SMaterial material;
	
	material.Texture1 = driver->getTexture(
         "C:\\irrlicht-1.1\\media\\GremlinBody.bmp");
	material.Lighting = true;

	// create a triangle selector
	scene::ITriangleSelector* selector = smgr->createOctTreeTriangleSelector( q3levelmesh->getMesh(0), q3node, 128);
	q3node->setTriangleSelector(selector);
    selector->drop();

	// load and display animated fairy mesh
	
	fairy = smgr->addAnimatedMeshSceneNode( smgr->getMesh("C:\\irrlicht-1.1\\media\\gremlin.md2"));
	fairy->setMaterialTexture(0, driver->getTexture("C:\\irrlicht-1.1\\media\\GremlinBody.bmp")); // set diffuse texture
    fairy->setPosition(core::vector3df(0,0,-100));
	
	fairy->setScale(core::vector3df(1,1.65,1));
	fairy->setLoopMode(true);
	fairy->setMD2Animation(scene::EMAT_STAND);    
    

	// set ambient light
	driver->setAmbientLight(video::SColor(0,200,200,200));

    // create collision response animator
    scene::ISceneNodeAnimator * anim = smgr->createCollisionResponseAnimator( selector, fairy, core::vector3df(50,50,50),	core::vector3df(0,-1,0), core::vector3df(0,0,0));
	fairy->addAnimator(anim);
	anim->drop();

    // create camera RPG ////////////////////////////////////////////////
    irr::scene::CCameraRPGSceneNode * cam = new irr::scene::CCameraRPGSceneNode( fairy, smgr, 999,  device, selector, "cam.xml" );
    smgr->setActiveCamera( cam ); // As I did not modify SceneManager...
    cam->drop();
    // create camera RPG ////////////////////////////////////////////////
	//-----------------------------------------------------------------------------------------------//   
//getSceneNodeFromScreenCoordinatesBB

   scene::ISceneNode* selectedSceneNode = 0;
   scene::ISceneNode* lastSelectedSceneNode = 0;   
   

//-----------------------------------------------------------------------------------------------//    
    // run render loop
	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, irr::video::SColor( 255, 255, 255, 255 ) );
        smgr->drawAll();
		
		core::line3d<f32> line = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(
           device->getCursorControl()->getPosition(), cam);

		core::vector3df intersection;
		core::triangle3df tri;

		if (smgr->getSceneCollisionManager()->getCollisionPoint(
			line, selector, intersection, tri))
		{
			bill->setPosition(intersection);
				
			driver->setTransform(video::ETS_WORLD, core::matrix4());
			driver->setMaterial(material);
			driver->draw3DTriangle(tri, video::SColor(0,255,0,0));
		}

		selectedSceneNode = smgr->getSceneCollisionManager()->
          getSceneNodeFromCameraBB(cam);

		if (lastSelectedSceneNode)
			lastSelectedSceneNode->setMaterialFlag(
                video::EMF_LIGHTING, true);

		if (selectedSceneNode == q3node ||
           selectedSceneNode == bill)
			selectedSceneNode = 0;

		if (selectedSceneNode)
			selectedSceneNode->setMaterialFlag(
               video::EMF_LIGHTING, false);

		lastSelectedSceneNode = selectedSceneNode;
/*
        ////////////////////////////////////////////////////////////////////////
        // Colored debug axis (DEBUG)
        ////////////////////////////////////////////////////////////////////////

        // center of screen
        driver->draw2DLine(  core::position2d< s32 >( driver->getScreenSize().Width/2,0 ),  core::position2d< s32 >( driver->getScreenSize().Width/2,driver->getScreenSize().Height ), video::SColor( 255,255,255,255 ) );
        driver->draw2DLine(  core::position2d< s32 >( 0,driver->getScreenSize().Height/2 ),  core::position2d< s32 >( driver->getScreenSize().Width,driver->getScreenSize().Height/2 ), video::SColor( 255,255,255,255 ) );
        // absolute X red
        {
            core::vector3df delta_position = irr::core::vector3df( 100.0f, 0.0f, 0.0f );
            core::matrix4 transformation;
            transformation.setRotationDegrees( irr::core::vector3df( 0.0f, 0.0f, 0.0f ) );
            transformation.transformVect( delta_position );

            driver->setTransform(video::ETS_WORLD, core::matrix4());
			video::SMaterial material;
            material.Lighting = false;
            material.Texture1 = 0;
            driver->setMaterial(material);
            driver->draw3DLine( fairy->getPosition(), fairy->getPosition()+delta_position, video::SColor(255,255,0,0) );
        }
        // absolute Y green
        {
            core::vector3df delta_position = irr::core::vector3df( 100.0f, 0.0f, 0.0f );
            core::matrix4 transformation;
            transformation.setRotationDegrees( irr::core::vector3df( 0.0f, 90.0f, 0.0f ) );
            transformation.transformVect( delta_position );

            driver->setTransform(video::ETS_WORLD, core::matrix4());
			video::SMaterial material;
            material.Lighting = false;
            material.Texture1 = 0;
            driver->setMaterial(material);
            driver->draw3DLine( fairy->getPosition(), fairy->getPosition()+delta_position, video::SColor(255,0,255,0) );
        }
        // player X red
        {
            core::vector3df delta_position = irr::core::vector3df( 30.0f, 0.0f, 0.0f );
            core::matrix4 transformation;
            transformation.setRotationDegrees( irr::core::vector3df( 0.0f, fairy->getRotation().Y, 0.0f ) );
            transformation.transformVect( delta_position );

            driver->setTransform(video::ETS_WORLD, core::matrix4());
			video::SMaterial material;
            material.Lighting = false;
            material.Texture1 = 0;
            driver->setMaterial(material);
            driver->draw3DLine( fairy->getPosition(), fairy->getPosition()+delta_position, video::SColor(255,160,0,0) );
        }
        // player Y green
        {
            core::vector3df delta_position = irr::core::vector3df( 30.0f, 0.0f, 0.0f );
            core::matrix4 transformation;
            transformation.setRotationDegrees( irr::core::vector3df( 0.0f, 90.0f + fairy->getRotation().Y, 0.0f ) );
            transformation.transformVect( delta_position );

            driver->setTransform(video::ETS_WORLD, core::matrix4());
			video::SMaterial material;
            material.Lighting = false;
            material.Texture1 = 0;
            driver->setMaterial(material);
            driver->draw3DLine( fairy->getPosition(), fairy->getPosition()+delta_position, video::SColor(255,0,160,0) );
        }
        // camera target
        {
            driver->setTransform(video::ETS_WORLD, core::matrix4());
			video::SMaterial material;
            material.Lighting = false;
            material.Texture1 = 0;
            driver->setMaterial(material);
            driver->draw3DLine( cam->getTarget(), cam->getTarget()+core::vector3df(0,-1000,0), video::SColor(255,0xF9,0x42,0x9E) );
        }
        // plauer position
        {
            driver->setTransform(video::ETS_WORLD, core::matrix4());
			video::SMaterial material;
            material.Lighting = false;
            material.Texture1 = 0;
            driver->setMaterial(material);
            driver->draw3DLine( fairy->getPosition(), fairy->getPosition()+core::vector3df(0,-1000,0), video::SColor(255,0,0x42,0x9E) );
        }

        ////////////////////////////////////////////////////////////////////////
        // End of colored debug axis (DEBUG)
        ////////////////////////////////////////////////////////////////////////
*/
        //
        driver->endScene();
	}
	device->drop(); // drop device
	return 0;
}

xterminhate
Posts: 206
Joined: Thu Sep 01, 2005 9:26 pm
Location: France

Post by xterminhate »

Check that first : cam.xml must be in the same directory of your program.
Return to Irrlicht after years... I'm lovin it.
It's hard to be a Man !
Si vis pacem para belum
xterminhate
Posts: 206
Joined: Thu Sep 01, 2005 9:26 pm
Location: France

Post by xterminhate »

I did not update the camera for a long time. Maybe Irrlicht has changed...
Return to Irrlicht after years... I'm lovin it.
It's hard to be a Man !
Si vis pacem para belum
alex_3214
Posts: 1
Joined: Sun Oct 15, 2006 2:15 pm

Post by alex_3214 »

hello I have an error of compilation :

Code: Select all

main.cpp
.\main.cpp(72) : error C2259: 'irr::scene::CCameraRPGSceneNode' : cannot instantiate abstract class
        due to following members:
        'bool irr::scene::ICameraSceneNode::OnEvent(const irr::SEvent &)' : is abstract
        ..\..\include\ICameraSceneNode.h(60) : see declaration of 'irr::scene::ICameraSceneNode::OnEvent'
CameraSceneNode.cpp
Generating Code...
Build log was saved at "file://c:\irrlichtsvn\examples\01.HelloWorld\Release\BuildLog.htm"
HelloWorld_vc8 - 1 error(s), 0 warning(s)
========== Régénération globale : 0 a réussi, 1 a échoué, 0 a été ignoré ==========
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

The new OnEvent function arguement is a const&, so change your OnEvent functions to OnEvent( const SEvent& event );
Image
xterminhate
Posts: 206
Joined: Thu Sep 01, 2005 9:26 pm
Location: France

Post by xterminhate »

Thanks for your help Spintz ! :-)
Return to Irrlicht after years... I'm lovin it.
It's hard to be a Man !
Si vis pacem para belum
Post Reply