Using Irrlicht for Oculus Rift Demo

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
losnspays
Posts: 2
Joined: Sun Sep 06, 2015 7:44 am

Using Irrlicht for Oculus Rift Demo

Post by losnspays »

I was recently introduced to Irrlicht. I'd like make some DK2 demos using the engine. I am not interested in using positional tracking via and Oculus SDK or anything. If things go well I'll build my own head tracking system.

So far I've been able to stitch bits and pieces together into a very basic demo using various sections from "Quake3Map", "HelloWorld", "SplitScreen", etc...to make a 1920x1080 window with some boxes, a moving light and two cameras, one positioned for each eye:
Image
It's been easy so far to just move this window over to my second display (the Rift) and maximize for a pretty good 3D effect.
I'm trying to use WASD and mouse movement to move/rotate both cameras together. Does anyone have tips about how to approach this? I messed around with the FPS camera in the SplitScreen example, but couldn't quite wrap my head how it works.
I'd be extremely satisfied if I can get basic camera controls set up in this demo.

I'll paste below my main.cpp file for review.

Code: Select all

 
#include <irrlicht.h>
#include "driverChoice.h"
 
// --- Engine Namespaces ---
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
 
// --- Resolution, Fullscreen Options ---
const int ResX=1920;
const int ResY=1080;
const bool fullScreen=false;
 
// Cameras
ICameraSceneNode *camera[2]={0,0};
 
class MyEventReceiver : public IEventReceiver
{
    public:
    virtual bool OnEvent(const SEvent& event) {
        if (camera[0]) {
            return camera[0]->OnEvent(event);
            return false;
        }
    }
};
 
int main() {
 
// --- EventReceiver Instance --- //
    MyEventReceiver receiver;
 
// --- Engine Initialization --- //
    IrrlichtDevice *device = createDevice(EDT_OPENGL,               // Type of the device.
                                          dimension2du(ResX,ResY),  // Size of the Window or screen.
                                          32,                       // Color bits per pixel
                                          fullScreen,               // Run in fullscreen mode or not.
                                          false,                    // Stencil buffer (for drawing shadows).
                                          false,                    // Vsync
                                          &receiver);               // Event receiver.
    if (!device) return 1;
    ISceneManager *smgr = device->getSceneManager();
    IVideoDriver *driver = device->getVideoDriver();
 
// --- Skydome --- //
    scene::ISceneNode* skydome=smgr->addSkyDomeSceneNode
        (driver->getTexture("../../media/skyboxes/space/ksc_pano.jpg"),16,16,1.0f,2.0f);
    
// --- Lights --- //
    scene::ISceneNode* node = 0;
    node = smgr->addLightSceneNode(0,
                                   core::vector3df(0,0,0),
                                   video::SColorf(1.0f, 1.0f, 1.0f, 1.0f),
                                   800.0f);
    scene::ISceneNodeAnimator* anim = 0;
    anim = smgr->createFlyCircleAnimator (core::vector3df(0,150,0),250.0f);
    node->addAnimator(anim);
    anim->drop();
 
// --- Load Models --- //
    // load box model
    IAnimatedMesh *boxobj = smgr->getMesh("../../../models/cube.obj");
    if (!boxobj) return 1;
    // box 1
    IAnimatedMesh *model0 = boxobj;
    IAnimatedMeshSceneNode *model0_node = smgr->addAnimatedMeshSceneNode(model0);
    model0_node->setPosition(vector3df(0, 0, 0));
    
    // box 2
    IAnimatedMesh *model1 = boxobj;
    IAnimatedMeshSceneNode *model1_node = smgr->addAnimatedMeshSceneNode(model1);
    model1_node->setPosition(vector3df(0, 5, 10));
    // box 3
    IAnimatedMesh *model2 = boxobj;
    IAnimatedMeshSceneNode *model2_node = smgr->addAnimatedMeshSceneNode(model2);
    model2_node->setPosition(vector3df(-10, 0, -5));
 
// --- HMD Cameras --- //
    // Left Eye
    camera[0] = smgr->addCameraSceneNode(0, vector3df(10,10,-0.1), vector3df(0,0,0));
    // Right Eye
    camera[1] = smgr->addCameraSceneNode(0, vector3df(10,10,0.1), vector3df(0,0,0));
 
// --- Main Loop --- //
    while(device->run()) {
        
        //Set the viewpoint to the whole screen and begin scene
        driver->setViewPort(rect<s32>(0,0,ResX,ResY));
        driver->beginScene(true,true,SColor(255,100,100,100));
        
        //Activate cam_l
        smgr->setActiveCamera(camera[0]);
        driver->setViewPort(rect<s32>(0, 0, ResX/2, ResY));
        smgr->drawAll();
        
        //Activate cam_r
        smgr->setActiveCamera(camera[1]);
        driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY));
        smgr->drawAll();
        
        //Draw scene
        smgr->drawAll();
        driver->endScene();
 
    }
    
    // Delete device
    device->drop();
    return 0;
}
 
Note: in the code I also have a skydome ("ksc_pano.jpg"). The skydome is mostly working fine, right now it's more or less a placeholder. My real concern is to get model importing and camera movement set up.
If I can provide anymore details please let me know.
Thanks for your help!

OS = Debian 8
losnspays
Posts: 2
Joined: Sun Sep 06, 2015 7:44 am

Re: Using Irrlicht for Oculus Rift Demo

Post by losnspays »

I took some time today to try and understand the node concepts within this engine. After some messing around I'm not 100% sure what I did, but I got both cameras to work the way I wanted, except instead of WASD it's using the default arrow keys and mouse.

So far these are the steps...

1.) Make two cameras:

Code: Select all

ICameraSceneNode *cam_l;
ICameraSceneNode *cam_r;
2.) Still don't understand event receivers, but this class gets set up:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
    public:
    virtual bool OnEvent(const SEvent& event) {
        if (cam_l) {
            return cam_l->OnEvent(event);
            return false;
        }
    }
};
3.) Inside main() the IrrlichtDevice gets that event receiver:

Code: Select all

// --- EventReceiver Instance --- //
    MyEventReceiver receiver;
 
// --- Engine Initialization --- //
    IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2du(ResX,ResY), 32,
                                           fullScreen, false, false,&receiver);
4.) I originally had both cameras use addCameraSceneNode(...), but if I change one, for example cam_r, to FPS it magically enables movement/rotation of BOTH cameras with mouse/keyboard:

Code: Select all

// --- HMD Cameras --- //
    // Left Eye
    cam_l = smgr->addCameraSceneNode(0, vector3df(10,5,-0.1), vector3df(0,5,0));
    // Right Eye
    cam_r = smgr->addCameraSceneNodeFPS();
At this point I'm just throwing spaghetti at the wall. I have three smgr->drawAll(); in the full code. I don't quite get what is going on here, but it's been fun play around!

Code: Select all

 
#include <iostream>     // cout
#include <unistd.h>     // sleep
//~ #include <stdlib.h>
//~ #include <stdio.h>
//~ #include <time.h>
 
#include <irrlicht.h>
//~ #include "driverChoice.h"
 
// --- Standard Namespaces --- //
using namespace std;
// --- Engine Namespaces --- //
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
 
// --- Resolution, Fullscreen Options --- //
const int ResX=1920;
const int ResY=1080;
const bool fullScreen=false;
 
// --- Cameras -- //
ICameraSceneNode *cam_l;
ICameraSceneNode *cam_r;
 
class MyEventReceiver : public IEventReceiver
{
    public:
    virtual bool OnEvent(const SEvent& event) {
        if (cam_l) {
            return cam_l->OnEvent(event);
            return false;
        }
    }
};
 
int main() {
 
// --- EventReceiver Instance --- //
    MyEventReceiver receiver;
 
// --- Engine Initialization --- //
    IrrlichtDevice *device = createDevice(EDT_OPENGL,               // Type of the device.
                                          dimension2du(ResX,ResY),  // Size of the Window or screen.
                                          32,                       // Color bits per pixel
                                          fullScreen,               // Run in fullscreen mode or not.
                                          false,                    // Stencil buffer (for drawing shadows).
                                          false,                    // Vsync
                                          &receiver);               // Event receiver.
    if (!device) return 1;
    ISceneManager *smgr = device->getSceneManager();
    IVideoDriver *driver = device->getVideoDriver();
 
// --- Skydome --- //
    //~ scene::ISceneNode* skydome=smgr->addSkyDomeSceneNode
        //~ (driver->getTexture("../../media/skyboxes/space/ksc_pano.jpg"),16,16,1.0f,2.0f);
    
// --- Lights --- //
    // fancy light node
    scene::ISceneNode* fancy_light = 0;
    fancy_light = smgr->addLightSceneNode(0,
                                          core::vector3df(0,0,0),
                                          video::SColorf(1.0f, 1.0f, 1.0f, 1.0f),
                                          800.0f);
    // fly circle animator
    scene::ISceneNodeAnimator* circle_anim = 0;
    circle_anim = smgr->createFlyCircleAnimator (core::vector3df(0,150,0),250.0f);
    // add animator to light
    fancy_light->addAnimator(circle_anim);
    circle_anim->drop();
 
// --- Load Models --- //
    // load box model
    IAnimatedMesh *boxobj = smgr->getMesh("../../../models/cube.obj");
    if (!boxobj) return 1;
    // box 1
    IAnimatedMesh *model0 = boxobj;
    IAnimatedMeshSceneNode *model0_node = smgr->addAnimatedMeshSceneNode(model0);
    model0_node->setPosition(vector3df(0, 0, 0));
    // box 2
    IAnimatedMesh *model1 = boxobj;
    IAnimatedMeshSceneNode *model1_node = smgr->addAnimatedMeshSceneNode(model1);
    model1_node->setPosition(vector3df(0, 5, 10));
    // box 3
    IAnimatedMesh *model2 = boxobj;
    IAnimatedMeshSceneNode *model2_node = smgr->addAnimatedMeshSceneNode(model2);
    model2_node->setPosition(vector3df(-10, 0, -5));
 
// --- HMD Cameras --- //
    // Left Eye
    cam_l = smgr->addCameraSceneNode(0, vector3df(10,5,-0.1), vector3df(0,5,0));
    // Right Eye
    //~ cam_r = smgr->addCameraSceneNode(0, vector3df(10,5,0.1), vector3df(0,5,0));
    //User-controlled
    cam_r = smgr->addCameraSceneNodeFPS();
 
 
// --- Main Loop --- //
    while(device->run()) {
        //~ for(int i=0; i<100; i++) {
            
            //Set the viewpoint to the whole screen and begin scene
            driver->setViewPort(rect<s32>(0,0,ResX,ResY));
            driver->beginScene(true,true,SColor(255,100,100,100));
            
            //Activate cam_l
            //~ smgr->setActiveCamera(cam_l);
            driver->setViewPort(rect<s32>(0, 0, ResX/2, ResY));
            smgr->drawAll();
            
            //Activate cam_r
            //~ smgr->setActiveCamera(cam_r);
            driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY));
            smgr->drawAll();
            
            //Draw scene
            smgr->drawAll();
            driver->endScene();
            
 
            //~ cam_l->setRotation(vector3df(0,i,0));
            //~ cout << "i = " << i << "\n";
                
        //~ }
    }
    
    // Delete device
    device->drop();
    return 0;
}
Post Reply