WoW like camera control & character movement (work in pr
WoW like camera control & character movement (work in pr
This here shall be an example of how to create a World of Warcraft like following camera.
The idea came from the thread Nightbird has posted on these forums.
http://irrlicht.sourceforge.net/phpBB2/ ... php?t=3245
Its about a NWN like Camera control but its not really finished yet.
Atm its in a very early stage but its planned to be a complete tutorial at the end.
Source can be downloadet @ :
http://www.loaditup.de/files//wow-like-camera.zip ( OLD VERSION )
( beware: work in progress -> not a finished tutorial yet )
Current version :
http://www.loaditup.de/135627.html
Work left to do:
- Smoth zoom in & out
- Maximum zoom Range ( done )
- 1st Person mode
- Minimum Zoom Range ( done )
- turning the character ( done )
- movement depending on the turned character ( done )
- Camera movement only when mousebuttens are pressed & the mouse is moved ( done )
- Camera movement up and down ( done )
- limit Camera movement up / down
- the Camera should stick behind the Players back
Any ideas , suggestions or links are very welcome.
For me its mainly a possibility to learn more about the irrlicht engine.
( This is in no way another - "i have a booombastic idea so lets make wow2 and earn $$$" thread - its just about learning how to do things with irrlicht and maybe creating another nice tutorial which might help people who are planning a rpg)
The idea came from the thread Nightbird has posted on these forums.
http://irrlicht.sourceforge.net/phpBB2/ ... php?t=3245
Its about a NWN like Camera control but its not really finished yet.
Atm its in a very early stage but its planned to be a complete tutorial at the end.
Source can be downloadet @ :
http://www.loaditup.de/files//wow-like-camera.zip ( OLD VERSION )
( beware: work in progress -> not a finished tutorial yet )
Current version :
http://www.loaditup.de/135627.html
Work left to do:
- Smoth zoom in & out
- Maximum zoom Range ( done )
- 1st Person mode
- Minimum Zoom Range ( done )
- turning the character ( done )
- movement depending on the turned character ( done )
- Camera movement only when mousebuttens are pressed & the mouse is moved ( done )
- Camera movement up and down ( done )
- limit Camera movement up / down
- the Camera should stick behind the Players back
Any ideas , suggestions or links are very welcome.
For me its mainly a possibility to learn more about the irrlicht engine.
( This is in no way another - "i have a booombastic idea so lets make wow2 and earn $$$" thread - its just about learning how to do things with irrlicht and maybe creating another nice tutorial which might help people who are planning a rpg)
Last edited by JonChaos on Thu Oct 11, 2007 9:08 pm, edited 3 times in total.
Here is the first update to the main.cpp file.
The following changes have been implemented:
If the left mousebutton is pressed the camera can be rotated around the model.
If the left mousebutton is released the camera moves back.
The rotation amount is determined by deltax , so if you move the mouse a litle bit the rotation is only a little bit.
If the right mousebutton is pressed the model is rotated.
If the middle mousebutton is pressed the zoomrange is resetted.
There is a min and maximum zoom range.
Still a lot of things to do...
The following changes have been implemented:
If the left mousebutton is pressed the camera can be rotated around the model.
If the left mousebutton is released the camera moves back.
The rotation amount is determined by deltax , so if you move the mouse a litle bit the rotation is only a little bit.
If the right mousebutton is pressed the model is rotated.
If the middle mousebutton is pressed the zoomrange is resetted.
There is a min and maximum zoom range.
Still a lot of things to do...
Code: Select all
/*
This tutorial will show how to implement a camera and character display which is a copy of the
one used in World of Warcraft.
Its purpose is to offer the Community an example for a camera and movement system for rpg or
as a base to develop theyr own movement/camera system.
It is based on the irrlicht Tutorial 12 and
NightBirds NWN Camera example http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=3245
Atm its all a bitt messy and very unclean but its still work in progress , althought comments
or suggestions are always welcome.
You can contact me in the Irrlicht Forums
Username: Jonchaos
or per Email
Antharon@Hotmail.com
*/
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
//****************************************************
//* *
//****************************************************
#define CAMERASPEED 0.1f // Camerarotationspeed
#define CHARROTATIONSPEED 3.0f
#define PI 3.14159265f
#define WIDTH 640 // screen width
#define HEIGHT 480 // screen height
#define STARTDISTANCE 35 // cam distance start
#define STARTANGLE 0.0f // cam angle
#define MAXZOOMRANGE 100
#define MINZOOMRANGE 30
//****************************************************
//* *
//****************************************************
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::ISceneNode* terrain ,
scene::IAnimatedMeshSceneNode* ptrCharacter,
IrrlichtDevice* ptrDevice,
scene::ICameraSceneNode* ptrCamera)
{
// store pointer to terrain so we can change its drawing mode
this->Terrain = terrain;
this->Character = ptrCharacter;
this->device = ptrDevice;
this->pCamera = ptrCamera;
this->CamRotationAngleY = STARTANGLE;
this->distance = STARTDISTANCE;
this->bIsRunning = false;
this->CameraRotating = false;
this->CharacterRotating = false;
}
void Update()
{
if (!pCamera || !Character) return;
if (m_lastTargetPos != Character->getPosition())
{
m_updated = true;
m_lastTargetPos = Character->getPosition();
}
if (m_updated)
{
m_updated = false;
irr::core::vector3df m_Camerapos = m_lastTargetPos;
m_Camerapos.X += distance*sin(CamRotationAngleY);
m_Camerapos.Z += distance*cos(CamRotationAngleY);
m_Camerapos.Y += distance;
pCamera->setPosition(m_Camerapos);
pCamera->setTarget(m_lastTargetPos);
}
}
bool OnEvent(SEvent event)
{
Update();
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
switch (event.MouseInput.Event)
{
case EMIE_MOUSE_WHEEL: // zooming
// tbd: find a way to smoth zooming
distance *= (((-event.MouseInput.Wheel)+1)/2+.5f);
if (distance >= MAXZOOMRANGE )
distance = MAXZOOMRANGE;
if (distance <= MINZOOMRANGE )
{
distance = MINZOOMRANGE;
// tbd: switch to 1st person
}
return true;
break;
case EMIE_LMOUSE_PRESSED_DOWN: // Manual Camera Rotation
this->CameraRotating = true;
return true;
break;
case EMIE_RMOUSE_PRESSED_DOWN: // character rotation
this->CharacterRotating = true;
return true;
break;
case EMIE_MOUSE_MOVED:
if (this->CameraRotating || this->CharacterRotating)
{
int DeltaX = event.MouseInput.X - OldMouseX;
int DeltaY = event.MouseInput.Y - OldMouseY;
OldMouseX = event.MouseInput.X;
OldMouseY = event.MouseInput.Y;
if (this->CameraRotating)
{
// Kamera rotieren
if (DeltaX > 0)
{
CamRotationAngleY += (DeltaX*CAMERASPEED);
while (CamRotationAngleY > 2*PI)
CamRotationAngleY -= 2*PI;
}
else
{
CamRotationAngleY += (DeltaX*CAMERASPEED);
while (CamRotationAngleY < 2*PI)
CamRotationAngleY += 2*PI;
}
// tbd: cam rotation up/down
if (DeltaY > 0)
{
}
else
{
}
}
if (this->CharacterRotating)
{ // tbd: rotation depending on value of DeltaX
if (DeltaX > 0)
{
irr::core::vector3df RotVect;
RotVect = Character->getRotation();
RotVect.Y = RotVect.Y + CHARROTATIONSPEED;
Character->setRotation(RotVect);
}
else
{
irr::core::vector3df RotVect;
RotVect = Character->getRotation();
RotVect.Y = RotVect.Y - CHARROTATIONSPEED;
Character->setRotation(RotVect);
}
}
}
return true;
break;
case EMIE_MMOUSE_PRESSED_DOWN:
this->distance = STARTDISTANCE;
return true;
break;
case EMIE_LMOUSE_LEFT_UP: // stop manual camera rotation
this->CameraRotating = false;
CamRotationAngleY = STARTANGLE;
return true;
break;
// Kamera wieder in urspr. position
case EMIE_RMOUSE_LEFT_UP: // stop character rotation
this->CharacterRotating = false;
return true;
break;
} ;
}
if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_WIREFRAME, !Terrain->getMaterial(0).Wireframe);
Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false);
return true;
case irr::KEY_KEY_P: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_POINTCLOUD, !Terrain->getMaterial(0).PointCloud);
Terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
return true;
case irr::KEY_KEY_D: // toggle detail map
Terrain->setMaterialType(
Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ?
video::EMT_DETAIL_MAP : video::EMT_SOLID);
return true;
case irr::KEY_ESCAPE:
this->device->closeDevice();
return true;
}
}
if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown )
{ // tbd: change walkkey input
switch (event.KeyInput.Key)
{
case irr::KEY_UP:
Charpos = Character->getPosition();
Charpos.X = Charpos.X - 10.0f ;
Character->setPosition(Charpos);
if (!this->bIsRunning)
{
Character->setMD2Animation(scene::EMAT_RUN);
this->bIsRunning = true;
}
return true;
case irr::KEY_DOWN:
Charpos = Character->getPosition();
Charpos.X = Charpos.X + 10.0f ;
Character->setPosition(Charpos);
if (!this->bIsRunning)
{
Character->setMD2Animation(scene::EMAT_RUN);
this->bIsRunning = true;
}
return true;
case irr::KEY_LEFT:
Charpos = Character->getPosition();
Charpos.Z = Charpos.Z - 10.0f ;
Character->setPosition(Charpos);
if (!this->bIsRunning)
{
Character->setMD2Animation(scene::EMAT_RUN);
this->bIsRunning = true;
}
return true;
case irr::KEY_RIGHT:
Charpos = Character->getPosition();
Charpos.Z = Charpos.Z + 10.0f ;
Character->setPosition(Charpos);
if (!this->bIsRunning)
{
Character->setMD2Animation(scene::EMAT_RUN);
this->bIsRunning = true;
}
return true;
}
}
// if one of the walk keys is lifted -> stop run animation
if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case irr::KEY_UP:
this->bIsRunning = false;
Character->setMD2Animation(scene::EMAT_STAND);
return true;
case irr::KEY_DOWN:
this->bIsRunning = false;
Character->setMD2Animation(scene::EMAT_STAND);
return true;
case irr::KEY_LEFT:
this->bIsRunning = false;
Character->setMD2Animation(scene::EMAT_STAND);
return true;
case irr::KEY_RIGHT:
this->bIsRunning = false;
Character->setMD2Animation(scene::EMAT_STAND);
return true;
}
}
return false;
}
private:
bool bIsRunning;
scene::ISceneNode* Terrain;
scene::IAnimatedMeshSceneNode* Character;
IrrlichtDevice* device;
scene::ICameraSceneNode* pCamera;
irr::core::vector3df m_lastTargetPos;
irr::core::vector3df Charpos;
bool m_updated;
float distance;
bool CameraRotating;
bool CharacterRotating;
float CamRotationAngleY;
int OldMouseX;
int OldMouseY;
};
//****************************************************
//* int main() *
//****************************************************
int main()
{
// 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) Burning's Software Renderer\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_BURNINGSVIDEO;break;
default: return 1;
}
// create device
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(WIDTH,HEIGHT));
if (device == 0)
return 1; // could not create selected driver.
/*
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);
// add irrlicht logo
env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
core::position2d<s32>(10,10));
//set other font
env->getSkin()->setFont(env->getFont("../../media/fontlucida.png"));
// add some help text
gui::IGUIStaticText* text = env->addStaticText(
L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map",
core::rect<s32>(10,440,250,475), true, true, 0, -1, true);
// add camera
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
camera->setPosition(core::vector3df(1900*2,255*2,3700*2));
camera->setTarget(core::vector3df(2397*2,343*2,2700*2));
camera->setFarValue(12000.0f);
//mouse cursor
device->getCursorControl()->setVisible(true);
device->getCursorControl()->setPosition(0,0);
// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../../media/terrain-heightmap.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/terrain-texture.jpg"));
terrain->setMaterialTexture(1, driver->getTexture("../../media/detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f);
//terrain->setDebugDataVisible ( true );
/*
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();
scene::IAnimatedMeshSceneNode* Character = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/sydney.md2"));
// create collision response animator and attach it to the Character
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, Character, core::vector3df(60,100,60),
core::vector3df(0,-100,0),
core::vector3df(0,50,0));
Character->addAnimator(anim);
anim->drop();
// create event receiver
MyEventReceiver receiver(terrain,Character,device,camera);
device->setEventReceiver(&receiver);
// create skybox
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
smgr->addSkyBoxSceneNode(
driver->getTexture("../../media/irrlicht2_up.jpg"),
driver->getTexture("../../media/irrlicht2_dn.jpg"),
driver->getTexture("../../media/irrlicht2_lf.jpg"),
driver->getTexture("../../media/irrlicht2_rt.jpg"),
driver->getTexture("../../media/irrlicht2_ft.jpg"),
driver->getTexture("../../media/irrlicht2_bk.jpg"));
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
/* Model Teil */
/*
To make to model look right we set the frames between which the animation
should loop, rotate the model around 180 degrees, and adjust the animation speed
and the texture.
To set the right animation (frames and speed), we would also be able to just
call "anms->setMD2Animation(scene::EMAT_RUN)" for the 'run' animation
instead of "setFrameLoop" and "setAnimationSpeed",
but this only works with MD2 animations, and so you know how to start other animations.
but it a good advice to use not hardcoded frame-numbers...
*/
Character->setMaterialFlag(video::EMF_LIGHTING, false);
Character->setFrameLoop(160, 183);
Character->setAnimationSpeed(40);
Character->setMD2Animation(scene::EMAT_STAND);
Character->setRotation(core::vector3df(0,180.0f,0));
Character->setMaterialTexture(0, driver->getTexture("../../media/sydney.bmp"));
Character->setPosition(core::vector3df(1900*2,255*2,3700*2)) ;
/*
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();
driver->endScene();
// display frames per second in window title
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"WoW like Camera&Character - 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 += " Height: ";
str += terrain->getHeight(camera->getAbsolutePosition().X, camera->getAbsolutePosition().Z);
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
I can see you have put in a lot of work, it would be nice to include the lib, irrlicht.dll and the include folder in your source download though Good Job keep up the good work.
Programming Blog: http://www.uberwolf.com
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Notes for anyone trying to use this:
MyEventReceiver() needs this added:
Find this code block:
and change it to this:
MyEventReceiver() needs this added:
Code: Select all
this->OldMouseX = 0;
this->OldMouseY = 0;
Code: Select all
if (this->CameraRotating)
{
// Kamera rotieren
if (DeltaX > 0)
Code: Select all
if (this->CameraRotating)
{
m_updated = true;
// Kamera rotieren
if (DeltaX > 0)
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
donerogerborg wrote: MyEventReceiver() needs this added:
Code: Select all
this->OldMouseX = 0; this->OldMouseY = 0;
m_updated wont be neccesary in the next version. Its left from the code Nightbird posted.rogerborg wrote: Find this code block:and change it to this:Code: Select all
if (this->CameraRotating) { // Kamera rotieren if (DeltaX > 0)
Code: Select all
if (this->CameraRotating) { m_updated = true; // Kamera rotieren if (DeltaX > 0)
Expect an minor update in a few hours.
@Rogerborg
Thx for the input. The more good ideas i recieve the faster this tutorial will be finished
Here is the new version with some minor changes:
- The character can now move in more than one direction
- Fixed flickering on movement
- Update() is now called in the main loop
- Run animation stopps properly if no movement key is pressed
- charactermodel isnt displayed anymore @ minimal zoomdistance ( 1st person )
- rogerborgs suggestions included
@ dejai
To use it you can extract the folder in my first post to /irrlicht/examples/ then everything should run fine ( at least with windows versions ).
I will provide a complete zip with everything needet if most of the todo's are done.
- The character can now move in more than one direction
- Fixed flickering on movement
- Update() is now called in the main loop
- Run animation stopps properly if no movement key is pressed
- charactermodel isnt displayed anymore @ minimal zoomdistance ( 1st person )
- rogerborgs suggestions included
@ dejai
To use it you can extract the folder in my first post to /irrlicht/examples/ then everything should run fine ( at least with windows versions ).
I will provide a complete zip with everything needet if most of the todo's are done.
Code: Select all
/*
This tutorial will show how to implement a camera and character display which is a copy of the
one used in World of Warcraft.
Its purpose is to offer the Community an example for a camera and movement system for rpg or
as a base to develop theyr own movement/camera system.
It is based on the irrlicht Tutorial 12 and
NightBirds NWN Camera example http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=3245
Atm its all a bitt messy and very unclean but its still work in progress , althought comments
or suggestions are always welcome.
You can contact me in the Irrlicht Forums
Username: Jonchaos
or per Email
Antharon@Hotmail.com
*/
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
//****************************************************
//* *
//****************************************************
#define CAMERASPEED 0.1f // Camerarotationspeed
#define CHARROTATIONSPEED 3.0f
#define PI 3.14159265f
#define WIDTH 640 // screen width
#define HEIGHT 480 // screen height
#define STARTDISTANCE 35 // cam distance start
#define STARTANGLE 0.0f // cam angle
#define MAXZOOMRANGE 100
#define MINZOOMRANGE 30
//****************************************************
//* *
//****************************************************
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::ISceneNode* terrain ,
scene::IAnimatedMeshSceneNode* ptrCharacter,
IrrlichtDevice* ptrDevice,
scene::ICameraSceneNode* ptrCamera)
{
// store pointer to terrain so we can change its drawing mode
this->Terrain = terrain;
this->Character = ptrCharacter;
this->device = ptrDevice;
this->pCamera = ptrCamera;
this->CamRotationAngleY = STARTANGLE;
this->distance = STARTDISTANCE;
this->bIsRunning = false; // is the character running ?
this->bRunDirectU = false;
this->bRunDirectD = false;
this->bRunDirectL = false;
this->bRunDirectR = false;
this->CameraRotating = false;
this->CharacterRotating = false;
this->OldMouseX = 0;
this->OldMouseY = 0;
this->IsAnimatingRun = false;
this->bFirstPerson = false;
}
void Update()
{
if (!pCamera || !Character) return;
if (m_lastTargetPos != Character->getPosition())
{
m_updated = true;
m_lastTargetPos = Character->getPosition();
}
if (m_updated)
{
m_updated = false;
irr::core::vector3df m_Camerapos = m_lastTargetPos;
m_Camerapos.X += distance*sin(CamRotationAngleY);
m_Camerapos.Z += distance*cos(CamRotationAngleY);
m_Camerapos.Y += distance;
pCamera->setPosition(m_Camerapos);
pCamera->setTarget(m_lastTargetPos);
}
if (this->bIsRunning)
this->StartRunAnimation();
else
this->StopRunAnimation();
}
void DoRunning()
{
// tbd : Character Movement depending on character rotation
if (this->bIsRunning)
{
if (this->bRunDirectU)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X - 1.0f ;
Character->setPosition(Charpos);
}
if (this->bRunDirectD)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X + 1.0f ;
Character->setPosition(Charpos);
}
if (this->bRunDirectL)
{
Charpos = Character->getPosition();
Charpos.Z = Charpos.Z - 1.0f ;
Character->setPosition(Charpos);
}
if (this->bRunDirectR)
{
Charpos = Character->getPosition();
Charpos.Z = Charpos.Z + 1.0f ;
Character->setPosition(Charpos);
}
this->Update();
}
}
bool OnEvent(SEvent event)
{
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
switch (event.MouseInput.Event)
{
case EMIE_MOUSE_WHEEL: // zooming
// tbd: find a way to smoth zooming
distance *= (((-event.MouseInput.Wheel)+1)/2+.5f);
if (this->bFirstPerson)
{
if (distance > MINZOOMRANGE )
{
this->bFirstPerson = false;
Character->setVisible(true);
}
if (distance < MINZOOMRANGE)
distance = MINZOOMRANGE;
}
else
{
if (distance >= MAXZOOMRANGE )
distance = MAXZOOMRANGE;
if (distance < MINZOOMRANGE )
{
distance = MINZOOMRANGE; // tbd: switch to 1st person
this->bFirstPerson = true;
Character->setVisible(false);
}
}
return true;
break;
case EMIE_LMOUSE_PRESSED_DOWN: // Manual Camera Rotation
this->CameraRotating = true;
return true;
break;
case EMIE_RMOUSE_PRESSED_DOWN: // character rotation
this->CharacterRotating = true;
return true;
break;
case EMIE_MOUSE_MOVED:
if (this->CameraRotating || this->CharacterRotating)
{
int DeltaX = event.MouseInput.X - OldMouseX;
int DeltaY = event.MouseInput.Y - OldMouseY;
OldMouseX = event.MouseInput.X;
OldMouseY = event.MouseInput.Y;
if (this->CameraRotating)
{
m_updated = true;
// Kamera rotieren
if (DeltaX > 0)
{
CamRotationAngleY += (DeltaX*CAMERASPEED);
while (CamRotationAngleY > 2*PI)
CamRotationAngleY -= 2*PI;
}
else
{
CamRotationAngleY += (DeltaX*CAMERASPEED);
while (CamRotationAngleY < 2*PI)
CamRotationAngleY += 2*PI;
}
// tbd: cam rotation up/down
if (DeltaY > 0)
{
}
else
{
}
}
if (this->CharacterRotating)
{ // tbd: rotation depending on value of DeltaX
if (DeltaX > 0)
{
irr::core::vector3df RotVect;
RotVect = Character->getRotation();
RotVect.Y = RotVect.Y + CHARROTATIONSPEED;
Character->setRotation(RotVect);
}
else
{
irr::core::vector3df RotVect;
RotVect = Character->getRotation();
RotVect.Y = RotVect.Y - CHARROTATIONSPEED;
Character->setRotation(RotVect);
}
}
}
return true;
break;
case EMIE_MMOUSE_PRESSED_DOWN:
this->distance = STARTDISTANCE;
return true;
break;
case EMIE_LMOUSE_LEFT_UP: // stop manual camera rotation
this->CameraRotating = false;
CamRotationAngleY = STARTANGLE;
return true;
break;
// Kamera wieder in urspr. position
case EMIE_RMOUSE_LEFT_UP: // stop character rotation
this->CharacterRotating = false;
return true;
break;
} ;
}
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
{
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_WIREFRAME, !Terrain->getMaterial(0).Wireframe);
Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false);
return true;
case irr::KEY_KEY_P: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_POINTCLOUD, !Terrain->getMaterial(0).PointCloud);
Terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
return true;
case irr::KEY_KEY_D: // toggle detail map
Terrain->setMaterialType(
Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ?
video::EMT_DETAIL_MAP : video::EMT_SOLID);
return true;
case irr::KEY_ESCAPE: // quit tutorial
this->device->closeDevice();
return true;
}
}
if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown )
{
switch (event.KeyInput.Key)
{
case irr::KEY_UP:
this->bRunDirectU = true;
this->bIsRunning = true;
return true;
case irr::KEY_DOWN:
this->bRunDirectD = true;
this->bIsRunning = true;
return true;
case irr::KEY_LEFT:
this->bRunDirectL = true;
this->bIsRunning = true;
return true;
case irr::KEY_RIGHT:
this->bRunDirectR = true;
this->bIsRunning = true;
return true;
}
}
// if one of the walk keys is lifted and no other walk key is pressed -> stop run animation
if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case irr::KEY_UP:
this->bRunDirectU = false;
if (!(this->bRunDirectR || this->bRunDirectL || this->bRunDirectD))
this->bIsRunning = false;
return true;
case irr::KEY_DOWN:
this->bRunDirectD = false;
if (!(this->bRunDirectR || this->bRunDirectL || this->bRunDirectU))
this->bIsRunning = false;
return true;
case irr::KEY_LEFT:
this->bRunDirectL = false;
if (!(this->bRunDirectR || this->bRunDirectU || this->bRunDirectD))
this->bIsRunning = false;
return true;
case irr::KEY_RIGHT:
this->bRunDirectR = false;
if (!(this->bRunDirectL || this->bRunDirectU || this->bRunDirectD))
this->bIsRunning = false;
return true;
}
}
return false;
}
private:
bool bIsRunning;
bool bRunDirectU;
bool bRunDirectD;
bool bRunDirectL;
bool bRunDirectR;
bool bFirstPerson;
scene::ISceneNode* Terrain;
scene::IAnimatedMeshSceneNode* Character;
IrrlichtDevice* device;
scene::ICameraSceneNode* pCamera;
irr::core::vector3df m_lastTargetPos;
irr::core::vector3df Charpos;
bool m_updated;
float distance;
bool CameraRotating;
bool CharacterRotating;
float CamRotationAngleY;
int OldMouseX;
int OldMouseY;
bool IsAnimatingRun;
void StartRunAnimation()
{
if (!this->IsAnimatingRun)
{
Character->setMD2Animation(scene::EMAT_RUN);
this->IsAnimatingRun = true;
}
};
void StopRunAnimation()
{
if (this->IsAnimatingRun)
{
Character->setMD2Animation(scene::EMAT_STAND);
this->IsAnimatingRun = false;
}
};
};
//****************************************************
//* int main() *
//****************************************************
int main()
{
// 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) Burning's Software Renderer\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_BURNINGSVIDEO;break;
default: return 1;
}
// create device
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(WIDTH,HEIGHT));
if (device == 0)
return 1; // could not create selected driver.
/*
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);
// add irrlicht logo
env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
core::position2d<s32>(10,10));
//set other font
env->getSkin()->setFont(env->getFont("../../media/fontlucida.png"));
// add some help text
gui::IGUIStaticText* text = env->addStaticText(
L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map",
core::rect<s32>(10,440,250,475), true, true, 0, -1, true);
// add camera
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
camera->setPosition(core::vector3df(1900*2,255*2,3700*2));
camera->setTarget(core::vector3df(2397*2,343*2,2700*2));
camera->setFarValue(12000.0f);
//mouse cursor
device->getCursorControl()->setVisible(true);
device->getCursorControl()->setPosition(1,1);
// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../../media/terrain-heightmap.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/terrain-texture.jpg"));
terrain->setMaterialTexture(1, driver->getTexture("../../media/detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f);
/*
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 character wont fall throught the terrain.
*/
// create triangle selector for the terrain
scene::ITriangleSelector* selector
= smgr->createTerrainTriangleSelector(terrain, 0);
terrain->setTriangleSelector(selector);
selector->drop();
scene::IAnimatedMeshSceneNode* Character = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/sydney.md2"));
// create collision response animator and attach it to the Character
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, Character, core::vector3df(60,100,60),
core::vector3df(0,-100,0),
core::vector3df(0,50,0));
Character->addAnimator(anim);
anim->drop();
// create event receiver
MyEventReceiver receiver(terrain,Character,device,camera);
device->setEventReceiver(&receiver);
// create skybox
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
smgr->addSkyBoxSceneNode(
driver->getTexture("../../media/irrlicht2_up.jpg"),
driver->getTexture("../../media/irrlicht2_dn.jpg"),
driver->getTexture("../../media/irrlicht2_lf.jpg"),
driver->getTexture("../../media/irrlicht2_rt.jpg"),
driver->getTexture("../../media/irrlicht2_ft.jpg"),
driver->getTexture("../../media/irrlicht2_bk.jpg"));
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
/* Model Teil */
Character->setMaterialFlag(video::EMF_LIGHTING, false);
Character->setFrameLoop(160, 183);
Character->setAnimationSpeed(40);
Character->setMD2Animation(scene::EMAT_STAND);
Character->setRotation(core::vector3df(0,180.0f,0));
Character->setMaterialTexture(0, driver->getTexture("../../media/sydney.bmp"));
Character->setPosition(core::vector3df(1900*2,255*2,3700*2)) ;
// That's it, draw everything.
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0 );
smgr->drawAll();
env->drawAll();
driver->endScene();
// display frames per second in window title
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"WoW like Camera&Character - 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 += " Height: ";
str += terrain->getHeight(camera->getAbsolutePosition().X, camera->getAbsolutePosition().Z);
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
receiver.Update();
receiver.DoRunning();
}
device->drop();
return 0;
}
Shouldnt crash.fukuda wrote:I just tested your last code update, it compiles well, but the .exe crashes with all the options.
What system & configuration do you use ?
I compiled it with msvstudio2005 on vista64 and it runs on the same machine and on a winxp ( 32 ) machine without problems.
Where have you put the project ?
Its assumed that its located in /Irrlicht/Examples/ProjectFolder
// edit
Another source for problems might be the irrlicht version your using.
I compiled and run it with 1.3.1.
Atm i'm still working on the next minor update.
When its ready ill upload a standalone folder with no need to place it in the irrlicht/examples folder.
Hope this solves some problems.
I use windows xp,
I compiled the .cpp with Dev-C++ in my own projects path,
I configured the project to link the libraries and I'm using 1.3.1 vesion
as you can see, I commented out some parts, but it still gives an error (the needed files are in the same folder as the project)
I compiled the .cpp with Dev-C++ in my own projects path,
I configured the project to link the libraries and I'm using 1.3.1 vesion
Code: Select all
/*
This tutorial will show how to implement a camera and character display which is a copy of the
one used in World of Warcraft.
Its purpose is to offer the Community an example for a camera and movement system for rpg or
as a base to develop theyr own movement/camera system.
It is based on the irrlicht Tutorial 12 and
NightBirds NWN Camera example http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=3245
Atm its all a bitt messy and very unclean but its still work in progress , althought comments
or suggestions are always welcome.
You can contact me in the Irrlicht Forums
Username: Jonchaos
or per Email
Antharon@Hotmail.com
*/
#include <IRR/irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
//****************************************************
//* *
//****************************************************
#define CAMERASPEED 0.1f // Camerarotationspeed
#define CHARROTATIONSPEED 3.0f
#define PI 3.14159265f
#define WIDTH 640 // screen width
#define HEIGHT 480 // screen height
#define STARTDISTANCE 35 // cam distance start
#define STARTANGLE 0.0f // cam angle
#define MAXZOOMRANGE 100
#define MINZOOMRANGE 30
//****************************************************
//* *
//****************************************************
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::ISceneNode* terrain ,
scene::IAnimatedMeshSceneNode* ptrCharacter,
IrrlichtDevice* ptrDevice,
scene::ICameraSceneNode* ptrCamera)
{
// store pointer to terrain so we can change its drawing mode
this->Terrain = terrain;
this->Character = ptrCharacter;
this->device = ptrDevice;
this->pCamera = ptrCamera;
this->CamRotationAngleY = STARTANGLE;
this->distance = STARTDISTANCE;
this->bIsRunning = false; // is the character running ?
this->bRunDirectU = false;
this->bRunDirectD = false;
this->bRunDirectL = false;
this->bRunDirectR = false;
this->CameraRotating = false;
this->CharacterRotating = false;
this->OldMouseX = 0;
this->OldMouseY = 0;
this->IsAnimatingRun = false;
this->bFirstPerson = false;
}
void Update()
{
if (!pCamera || !Character) return;
if (m_lastTargetPos != Character->getPosition())
{
m_updated = true;
m_lastTargetPos = Character->getPosition();
}
if (m_updated)
{
m_updated = false;
irr::core::vector3df m_Camerapos = m_lastTargetPos;
m_Camerapos.X += distance*sin(CamRotationAngleY);
m_Camerapos.Z += distance*cos(CamRotationAngleY);
m_Camerapos.Y += distance;
pCamera->setPosition(m_Camerapos);
pCamera->setTarget(m_lastTargetPos);
}
if (this->bIsRunning)
this->StartRunAnimation();
else
this->StopRunAnimation();
}
void DoRunning()
{
// tbd : Character Movement depending on character rotation
if (this->bIsRunning)
{
if (this->bRunDirectU)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X - 1.0f ;
Character->setPosition(Charpos);
}
if (this->bRunDirectD)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X + 1.0f ;
Character->setPosition(Charpos);
}
if (this->bRunDirectL)
{
Charpos = Character->getPosition();
Charpos.Z = Charpos.Z - 1.0f ;
Character->setPosition(Charpos);
}
if (this->bRunDirectR)
{
Charpos = Character->getPosition();
Charpos.Z = Charpos.Z + 1.0f ;
Character->setPosition(Charpos);
}
this->Update();
}
}
bool OnEvent(SEvent event)
{
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
switch (event.MouseInput.Event)
{
case EMIE_MOUSE_WHEEL: // zooming
// tbd: find a way to smoth zooming
distance *= (((-event.MouseInput.Wheel)+1)/2+.5f);
if (this->bFirstPerson)
{
if (distance > MINZOOMRANGE )
{
this->bFirstPerson = false;
Character->setVisible(true);
}
if (distance < MINZOOMRANGE)
distance = MINZOOMRANGE;
}
else
{
if (distance >= MAXZOOMRANGE )
distance = MAXZOOMRANGE;
if (distance < MINZOOMRANGE )
{
distance = MINZOOMRANGE; // tbd: switch to 1st person
this->bFirstPerson = true;
Character->setVisible(false);
}
}
return true;
break;
case EMIE_LMOUSE_PRESSED_DOWN: // Manual Camera Rotation
this->CameraRotating = true;
return true;
break;
case EMIE_RMOUSE_PRESSED_DOWN: // character rotation
this->CharacterRotating = true;
return true;
break;
case EMIE_MOUSE_MOVED:
if (this->CameraRotating || this->CharacterRotating)
{
int DeltaX = event.MouseInput.X - OldMouseX;
int DeltaY = event.MouseInput.Y - OldMouseY;
OldMouseX = event.MouseInput.X;
OldMouseY = event.MouseInput.Y;
if (this->CameraRotating)
{
m_updated = true;
// Kamera rotieren
if (DeltaX > 0)
{
CamRotationAngleY += (DeltaX*CAMERASPEED);
while (CamRotationAngleY > 2*PI)
CamRotationAngleY -= 2*PI;
}
else
{
CamRotationAngleY += (DeltaX*CAMERASPEED);
while (CamRotationAngleY < 2*PI)
CamRotationAngleY += 2*PI;
}
// tbd: cam rotation up/down
if (DeltaY > 0)
{
}
else
{
}
}
if (this->CharacterRotating)
{ // tbd: rotation depending on value of DeltaX
if (DeltaX > 0)
{
irr::core::vector3df RotVect;
RotVect = Character->getRotation();
RotVect.Y = RotVect.Y + CHARROTATIONSPEED;
Character->setRotation(RotVect);
}
else
{
irr::core::vector3df RotVect;
RotVect = Character->getRotation();
RotVect.Y = RotVect.Y - CHARROTATIONSPEED;
Character->setRotation(RotVect);
}
}
}
return true;
break;
case EMIE_MMOUSE_PRESSED_DOWN:
this->distance = STARTDISTANCE;
return true;
break;
case EMIE_LMOUSE_LEFT_UP: // stop manual camera rotation
this->CameraRotating = false;
CamRotationAngleY = STARTANGLE;
return true;
break;
// Kamera wieder in urspr. position
case EMIE_RMOUSE_LEFT_UP: // stop character rotation
this->CharacterRotating = false;
return true;
break;
} ;
}
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
{
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_WIREFRAME, !Terrain->getMaterial(0).Wireframe);
Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false);
return true;
case irr::KEY_KEY_P: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_POINTCLOUD, !Terrain->getMaterial(0).PointCloud);
Terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
return true;
case irr::KEY_KEY_D: // toggle detail map
Terrain->setMaterialType(
Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ?
video::EMT_DETAIL_MAP : video::EMT_SOLID);
return true;
case irr::KEY_ESCAPE: // quit tutorial
this->device->closeDevice();
return true;
}
}
if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown )
{
switch (event.KeyInput.Key)
{
case irr::KEY_UP:
this->bRunDirectU = true;
this->bIsRunning = true;
return true;
case irr::KEY_DOWN:
this->bRunDirectD = true;
this->bIsRunning = true;
return true;
case irr::KEY_LEFT:
this->bRunDirectL = true;
this->bIsRunning = true;
return true;
case irr::KEY_RIGHT:
this->bRunDirectR = true;
this->bIsRunning = true;
return true;
}
}
// if one of the walk keys is lifted and no other walk key is pressed -> stop run animation
if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case irr::KEY_UP:
this->bRunDirectU = false;
if (!(this->bRunDirectR || this->bRunDirectL || this->bRunDirectD))
this->bIsRunning = false;
return true;
case irr::KEY_DOWN:
this->bRunDirectD = false;
if (!(this->bRunDirectR || this->bRunDirectL || this->bRunDirectU))
this->bIsRunning = false;
return true;
case irr::KEY_LEFT:
this->bRunDirectL = false;
if (!(this->bRunDirectR || this->bRunDirectU || this->bRunDirectD))
this->bIsRunning = false;
return true;
case irr::KEY_RIGHT:
this->bRunDirectR = false;
if (!(this->bRunDirectL || this->bRunDirectU || this->bRunDirectD))
this->bIsRunning = false;
return true;
}
}
return false;
}
private:
bool bIsRunning;
bool bRunDirectU;
bool bRunDirectD;
bool bRunDirectL;
bool bRunDirectR;
bool bFirstPerson;
scene::ISceneNode* Terrain;
scene::IAnimatedMeshSceneNode* Character;
IrrlichtDevice* device;
scene::ICameraSceneNode* pCamera;
irr::core::vector3df m_lastTargetPos;
irr::core::vector3df Charpos;
bool m_updated;
float distance;
bool CameraRotating;
bool CharacterRotating;
float CamRotationAngleY;
int OldMouseX;
int OldMouseY;
bool IsAnimatingRun;
void StartRunAnimation()
{
if (!this->IsAnimatingRun)
{
Character->setMD2Animation(scene::EMAT_RUN);
this->IsAnimatingRun = true;
}
};
void StopRunAnimation()
{
if (this->IsAnimatingRun)
{
Character->setMD2Animation(scene::EMAT_STAND);
this->IsAnimatingRun = false;
}
};
};
//****************************************************
//* int main() *
//****************************************************
int main()
{
// 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) Burning's Software Renderer\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_BURNINGSVIDEO;break;
default: return 1;
}
// create device
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(WIDTH,HEIGHT));
if (device == 0)
return 1; // could not create selected driver.
/*
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);
/* // add irrlicht logo
env->addImage(driver->getTexture("irrlichtlogo2.png"),
core::position2d<s32>(10,10));
//set other font
env->getSkin()->setFont(env->getFont("fontlucida.png"));
// add some help text
gui::IGUIStaticText* text = env->addStaticText(
L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map",
core::rect<s32>(10,440,250,475), true, true, 0, -1, true);
*/
// add camera
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
camera->setPosition(core::vector3df(1900*2,255*2,3700*2));
camera->setTarget(core::vector3df(2397*2,343*2,2700*2));
camera->setFarValue(12000.0f);
//mouse cursor
device->getCursorControl()->setVisible(true);
device->getCursorControl()->setPosition(1,1);
/*
// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"terrain-heightmap.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("terrain-texture.jpg"));
terrain->setMaterialTexture(1, driver->getTexture("detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f);
*/
/*
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 character wont fall throught the terrain.
*/
/*// create triangle selector for the terrain
scene::ITriangleSelector* selector
= smgr->createTerrainTriangleSelector(terrain, 0);
terrain->setTriangleSelector(selector);
selector->drop();
scene::IAnimatedMeshSceneNode* Character = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/sydney.md2"));
// create collision response animator and attach it to the Character
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, Character, core::vector3df(60,100,60),
core::vector3df(0,-100,0),
core::vector3df(0,50,0));
Character->addAnimator(anim);
anim->drop();*/
// create event receiver
MyEventReceiver receiver(NULL,NULL,device,camera);
device->setEventReceiver(&receiver);
/*// create skybox
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
smgr->addSkyBoxSceneNode(
driver->getTexture("irrlicht2_up.jpg"),
driver->getTexture("irrlicht2_dn.jpg"),
driver->getTexture("irrlicht2_lf.jpg"),
driver->getTexture("irrlicht2_rt.jpg"),
driver->getTexture("irrlicht2_ft.jpg"),
driver->getTexture("irrlicht2_bk.jpg"));
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
/* Model Teil *//*
Character->setMaterialFlag(video::EMF_LIGHTING, false);
Character->setFrameLoop(160, 183);
Character->setAnimationSpeed(40);
Character->setMD2Animation(scene::EMAT_STAND);
Character->setRotation(core::vector3df(0,180.0f,0));
Character->setMaterialTexture(0, driver->getTexture("sydney.bmp"));
Character->setPosition(core::vector3df(1900*2,255*2,3700*2)) ;
*/
// That's it, draw everything.
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0 );
smgr->drawAll();
env->drawAll();
driver->endScene();
// display frames per second in window title
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"WoW like Camera&Character - 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 += " Height: ";
// str += terrain->getHeight(camera->getAbsolutePosition().X, camera->getAbsolutePosition().Z);
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
receiver.Update();
receiver.DoRunning();
}
device->drop();
return 0;
}
The files aren't needet at all because you commented out all the file loading.fukuda wrote: as you can see, I commented out some parts, but it still gives an error (the needed files are in the same folder as the project)
Maybe now there are problems in the main() when it calls
receiver.Update();
receiver.DoRunning();
both functions use a pointer to the Character scene node.
Don't know if they like a NULL pointer.
I uploadet the newest version.
In the .rar file is everything needet to run / compile ( dll , lib , include , source , vc8 project ).
The link can be found in post#1
// edit
If someone is experienced in doing 3d math and has a bit spare time i would appreciate help on the following 2 topics:
- character movement depending on the character rotation
- limiting the camera rotation up/down
In the .rar file is everything needet to run / compile ( dll , lib , include , source , vc8 project ).
The link can be found in post#1
// edit
If someone is experienced in doing 3d math and has a bit spare time i would appreciate help on the following 2 topics:
- character movement depending on the character rotation
- limiting the camera rotation up/down
Here is a minor update.
Walkdirection is now calculated based on the character rotation.
Code is a reimplementation from JReuschel1's Code from http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=19282
Walkdirection is now calculated based on the character rotation.
Code is a reimplementation from JReuschel1's Code from http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=19282
Code: Select all
void DoRunning()
{
if (this->bIsRunning)
{
float Rotation;
irr::core::vector3df CharRotation;
CharRotation = this->Character->getRotation();
Rotation = CharRotation.Y;
if (this->bRunDirectU)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X + ( RUNSPEED * cos(Rotation*PI/180));
Charpos.Z = Charpos.Z - ( RUNSPEED * sin(Rotation*PI/180));
Character->setPosition(Charpos);
}
if (this->bRunDirectD)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X - ( RUNSPEED * cos(Rotation*PI/180));
Charpos.Z = Charpos.Z + ( RUNSPEED * sin(Rotation*PI/180));
Character->setPosition(Charpos);
}
if (this->bRunDirectL)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X - ( RUNSPEED * cos(Rotation*PI/180+3.1416/2)) ;
Charpos.Z = Charpos.Z + ( RUNSPEED * sin(Rotation*PI/180+3.1416/2)) ;
Character->setPosition(Charpos);
}
if (this->bRunDirectR)
{
Charpos = Character->getPosition();
Charpos.X = Charpos.X + ( RUNSPEED * cos(Rotation*PI/180+3.1416/2));
Charpos.Z = Charpos.Z - ( RUNSPEED * sin(Rotation*PI/180+3.1416/2));
Character->setPosition(Charpos);
}
this->Update();
}
}
Re: WoW like camera control & character movement (work in pr
I know this thread is years old but I was wondering if anyone with a bit of experience could help with this code? Because this camera seems pretty sweet if I could get it to work. I've got it down to one error but not sure how to fix it:
IntelliSense: object of abstract class type "MyEventReceiver" is not allowed
Created from this code:
Thanks, TJ
IntelliSense: object of abstract class type "MyEventReceiver" is not allowed
Created from this code:
Code: Select all
MyEventReceiver receiver(NULL,NULL,device,camera);
Re: WoW like camera control & character movement (work in pr
Please if you report errors use compile-errors and not IntelliSense messages :-) And always copy-paste them exactly.
But in this case it's probably OnEvent which now needs a const-ref parameter for SEvent. Like: bool OnEvent(const SEvent& event)
But in this case it's probably OnEvent which now needs a const-ref parameter for SEvent. Like: bool OnEvent(const SEvent& event)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm