[Camera & Nodes] Trouble with Diablo-like-Cam

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Notion
Posts: 9
Joined: Mon Mar 20, 2017 11:00 pm

[Camera & Nodes] Trouble with Diablo-like-Cam

Post by Notion »

Hey everyone!
I recently started with Irrlicht and enjoy it alot so far. But right now Im pretty much stuck, trying to set up a Camera that basically works like in most Hack n Slay Games (Diablo II for example): While the Camera follows the Position of the PlayerCharacter, it does NOT rotate with the PlayerCharacter, but keeps its rotation and offset relative to the playercharacter.

I hope you know what I try to describe, if you dont, please let me know!

So I came up with the following Code, which should do: Create an Empty Node with fixed rotation. Make the CameraNode the Child of the Non-Rotating EmptyNode. Load a MeshNode and make it a child of the EmptyNode, so the Parent of Camera and Mesh are the same. This should result in both moving in exact the same way once the EmptyNode is moved, right? But it doesnt really work: Moving the Empty Node on the x-axis actually makes either the camera or the model rotate in some weird angle around the other, before making the model completely disappear from the cams view.

(Shortening the code, since the full programm uses a rather large but pretty foolproof structure)

Code: Select all

 
//Declarations
IrrlichtDevice *device;
IVideoDriver* driver;
ISceneManager* smgr;
IGUIEnvironment* guienv;
 
//Cam and Node
    ISceneNode* playerPositionNode; //THIS is basically gonna be the parent to Model and Cam.
    ICameraSceneNode *cam;
 
 
 int main() {
 
 
 
    //Setup Device
                                        
    device = createDevice(video::EDT_OPENGL, dimension2d<u32>(1920, 1080), 32, true, false, true, &receiver);
 
    //Setup Window
    device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
 
    driver = device->getVideoDriver();
    smgr = device->getSceneManager();
    guienv = device->getGUIEnvironment();
 
    //Setup PlayerPositionNode
    playerPositionNode = smgr->addEmptySceneNode();
 
    //Add Camera
    playerPositionNode->addChild(smgr->addCameraSceneNode(0, vector3df(0, 50, -40), vector3df(0, -30, 0)));
 
 
//Loading Model
    IAnimatedMesh* mesh = smgr->getMesh(path + ".md2");
    playerPositionNode->addChild(node = smgr->addAnimatedMeshSceneNode(mesh)); //THIS line is probably important?
 
    //Setting Textures and Animations
    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, false);
        node->setMD2Animation(scene::EMAT_STAND);
        node->setMaterialTexture(0, driver->getTexture(path + ".bmp"));
        irr::core::vector3df tempvec(0, 0, 0); 
        node->setPosition(tempvec);
    }
 
while(true)
{
input();
update();
}
 
}
 
irr::f32 x;
void update() {
 
    playerPositionNode->setPosition(irr::core::vector3df(0+x, 0, 0));
 
}
 
void input(){
x++;
}
 
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [Camera & Nodes] Trouble with Diablo-like-Cam

Post by CuteAlien »

Not an example that compiles and can be used for testing. I get what you try to do in theory and it might work (don't want to write my own example now for testing as I need to sleep soon).

But maybe just use a simpler solution. Use your player-node and camera-node, forget about that empty node. Then control your player however you want and update the camera manually. Do something like that in your update:

Code: Select all

 
irr::core::vector3df targetPos(  player->getAbsolutePosition() );
camera->setTarget(targetPos );
camera->updateAbsolutePosition(); // just to be save as setting target and position can influence each other
camera->setPosition( targetPos + irr::core::vector3df( 0, 50, -40) );
 
As long as you use a fixed distance it won't care what rotations your target does.
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
Notion
Posts: 9
Joined: Mon Mar 20, 2017 11:00 pm

Re: [Camera & Nodes] Trouble with Diablo-like-Cam

Post by Notion »

Thanks alot for your fast response! I fixed the code to make it compileable, you probably just need to adjust the path/name of the model file. (Code below). I tried the solution you suggested as well, and it basically does what I want, but when I start moving the character, it changes the offset to the cam a tiny bit until the movement stops. It looks kinda work-around-like and I try to avoid that. Thanks none the less!

Code: Select all

 
 
#include "MainClass.h"
#include <irrlicht.h>
#include <vector>
 
 
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
 
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
using namespace std;
 
//Declarations
IrrlichtDevice *device;
IVideoDriver* driver;
ISceneManager* smgr;
IGUIEnvironment* guienv;
 
//Cam and Node
ISceneNode* playerPositionNode; //THIS is basically gonna be the parent to Model and Cam.
ICameraSceneNode *cam;
 
 
void update();
void input();
void draw();
 
int main() {
 
 
 
    //Setup Device
 
    device = createDevice(video::EDT_OPENGL, dimension2d<u32>(1920, 1080), 32, true, false, true, 0);
 
    //Setup Window
    device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
 
    driver = device->getVideoDriver();
    smgr = device->getSceneManager();
    guienv = device->getGUIEnvironment();
 
    //Setup PlayerPositionNode
    playerPositionNode = smgr->addEmptySceneNode();
 
    //Add Camera
    playerPositionNode->addChild(smgr->addCameraSceneNode(0, vector3df(0, 50, -40), vector3df(0, -30, 0)));
 
    IAnimatedMeshSceneNode* node;
 
    //Loading Model
    IAnimatedMesh* mesh = smgr->getMesh( "Res/sydney.md2");
    playerPositionNode->addChild(node = smgr->addAnimatedMeshSceneNode(mesh)); //THIS line is probably important?
 
                                                                               //Setting Textures and Animations
    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, false);
        node->setMD2Animation(scene::EMAT_STAND);
        node->setMaterialTexture(0, driver->getTexture("Res/sydney.bmp"));
        irr::core::vector3df tempvec(0, 0, 0);
        node->setPosition(tempvec);
    }
 
    while (true)
    {
        input();
        update();
        draw();
    }
 
}
 
 
irr::f32 x;
void update() {
 
    playerPositionNode->setPosition(irr::core::vector3df(0 + x, 0, 0));
 
}
 
void input() {
    x++;
}
 
void draw() {
 
    driver->beginScene(true, true, SColor(255, 0, 0, 0));
 
    smgr->drawAll();
    guienv->drawAll();
 
    driver->endScene();
 
 
}
Last edited by Notion on Tue Mar 21, 2017 1:23 am, edited 1 time in total.
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [Camera & Nodes] Trouble with Diablo-like-Cam

Post by CuteAlien »

Please copy your example code over one of the examples and just press compile. That way you quickly can test if it compiles (I have to stop for today, so won't test anymore - but pretty certain code above at least does miss includes and namespaces).
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
Notion
Posts: 9
Joined: Mon Mar 20, 2017 11:00 pm

Re: [Camera & Nodes] Trouble with Diablo-like-Cam

Post by Notion »

Fixed the namespaces and includes, should work now. :)
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [Camera & Nodes] Trouble with Diablo-like-Cam

Post by CuteAlien »

Your problem is that this only updates camera position, but not the camera target. So it still looks at the old place.

So do something like this (the line with cam->setTarget, other changes don't matter):

Code: Select all

 
#include <irrlicht.h> 
 
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
 
int main() 
{
    //Setup Device
    IrrlichtDevice *device = createDevice(video::EDT_OPENGL, dimension2d<u32>(800, 600));
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager*smgr = device->getSceneManager();
 
    //Setup PlayerPositionNode
    ISceneNode* playerPositionNode = smgr->addEmptySceneNode();
 
    //Add Camera
    irr::core::vector3df camDistance(0, -30, 0);
    ICameraSceneNode *cam = smgr->addCameraSceneNode(playerPositionNode, vector3df(0, 50, -40), camDistance);
 
    //Loading Model
    IAnimatedMesh* mesh = smgr->getMesh( "../../media/sydney.md2");
    IAnimatedMeshSceneNode* node= smgr->addAnimatedMeshSceneNode(mesh, playerPositionNode);
 
    if (node)
    {
        node->setMaterialFlag(EMF_LIGHTING, false);
        node->setMD2Animation(scene::EMAT_STAND);
        node->setMaterialTexture(0, driver->getTexture("../../media/sydney.bmp"));
    }
 
    irr::f32 x=0;
    while (device->run())
    {
        x ++;
        playerPositionNode->setPosition(irr::core::vector3df(0 + x, 0, 0));
        cam->setTarget( playerPositionNode->getPosition() + camDistance );
 
        driver->beginScene(true, true, SColor(255, 0, 0, 0));
 
        smgr->drawAll();
 
        driver->endScene();
    }
}
 
(.. and examples that go fullscreen, go black within a second and can't be ended easily because you removed the device->run()...very evil!!!)
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
Post Reply