[SOLVED] IMeshSceneNode Problem

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
shial
Posts: 3
Joined: Thu Feb 07, 2013 3:17 pm

[SOLVED] IMeshSceneNode Problem

Post by shial »

Hey Guys

I got problem with my IMeshSceneNode.

take a look at My code and read my problem description below:
Block.h

Code: Select all

#ifndef __Block_H_INCLUDED__
#define __Block_H_INCLUDED__
#pragma once
#include <irrlicht.h>
 
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#if defined(_MSC_VER)    
#pragma comment(lib, "Irrlicht.lib")
#endif
 
class Block
{
public:
    Block(IrrlichtDevice *device);
    ~Block(void);
    void drawAll();
    void Node();
 
    void SetPosition(vector3df);
    vector3df GetPosition();
 
private:
    IVideoDriver* driver;
    ISceneManager* smgr;
    IGUIEnvironment* guienv;
    IMesh* mesh;
    IMeshSceneNode* node;
};
 
#endif
Block.cpp

Code: Select all

#include "stdafx.h"
#include "Block.h"
 
 
Block::Block(IrrlichtDevice *device)
{
     driver = device->getVideoDriver();    
     smgr = device->getSceneManager();   
     guienv = device->getGUIEnvironment();
     mesh = smgr->getMesh("Tetris\\jedenklocek.obj");  
     node =  smgr->addMeshSceneNode(mesh);
     Node();
 
}
 
 
Block::~Block(void)
{
    node->removeAll();
}
 
void Block::drawAll()
{
    smgr->drawAll();
}
void Block::Node()
{
    if (node) 
     {  
         this->SetPosition(vector3df(0.0f, 0.0f, 0.0f));
         //node->setScale(vector3df(0.1f, 0.1f, 0.1f));
         //guienv->addMessageBox(L"aaa", L"bbb");
         //node->setMaterialTexture( 0, driver->getTexture("Tetris\\klocek1a.bmp") );
         node->setMaterialFlag(EMF_LIGHTING, true);
     }
}
 
void Block::SetPosition(vector3df x)
{
    if (node) 
     {  
         node->setPosition(x);
     }
}
vector3df Block::GetPosition()
{
    if (node) 
     {  
         return node->getPosition();
     }
    else
    {
        guienv->addMessageBox(L"Error", L"There is no model");
        return vector3df(0.0f, 0.0f, 0.0f);
    }
}

and my class wich one have to define tetris block combination

Code: Select all

#pragma once
#include <irrlicht.h>
#include "Block.h"
#include <vector>
#include<iostream>
using namespace std;
using namespace irr;
 
class PieceOne
{
public:
    PieceOne(IrrlichtDevice *device);
    ~PieceOne(void);
    void Rotate();
    void Erase();
    void Draw();
 
    void move();
 
private:
//Funkcje wykorzystywane w klasie
    void Init();
 
private:
    vector<Block> figure;
};
 
 

Code: Select all

#include "stdafx.h"
#include "PieceOne.h"
 
 
PieceOne::PieceOne(IrrlichtDevice *device)
{
    for(int i=0; i<4; i++)
        figure.push_back(Block(device));
    this->Init();
 
    cout<<endl<<"figure.size() = "<<figure.size()<<endl;
}
 
PieceOne::~PieceOne(void)
{
}
 
void PieceOne::Init()
{
        figure[0].SetPosition(vector3df(0.0f, 0.0f, 0.0f));
        figure[1].SetPosition(vector3df(-10.0f, 0.0f, 0.0f));
        figure[2].SetPosition(vector3df(-10.0f, 0.0f, -10.0f));
        figure[3].SetPosition(vector3df(0.0f, 0.0f, -10.0f));
}
 
void PieceOne::Draw()
{
    //if(!figure.empty())
        //for(unsigned i=0; i<figure.size(); i++)
            figure[0].drawAll();
}
 
void PieceOne::Rotate()
{
    //nie jest nam potrzebna bo kostka sie nie odwraca :D
}
void PieceOne::Erase()//potrzebna to usuniecia elementow
{
    figure.pop_back();
    cout<<endl<<"figure.size() = "<<figure.size()<<endl;
}
The last one is part of my class of Appi

Code: Select all

#ifndef __App_H_INCLUDED__
#define __App_H_INCLUDED__
#pragma once
 
#include <irrlicht.h>
#include "PieceOne.h"
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#if defined(_MSC_VER)    
#pragma comment(lib, "Irrlicht.lib")
#endif
 
class MyEventReceiver : public IEventReceiver
{
public:
    // This is the one method that we have to implement
    virtual bool OnEvent(const SEvent& event)
    {
        // Remember whether each key is down or up
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
        return false;
    }
 
    // This is used to check whether a key is being held down
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
    
    MyEventReceiver()
    {
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }
 
private:
    // We use this array to store the current state of each key
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
 
struct rgb
    {
        f32 bg_r;    
        f32 bg_g;    
        f32 bg_b;
    };
 
class App
{
public:
    
    App();
    App(bool& outFullscreen, bool& outMusic,
            video::E_DRIVER_TYPE& outDriver);
    ~App(void);
    bool Init(void);
    bool run(void);
    void NodeSelector(void);
    void FpsCounter(void);
 
private:
    IrrlichtDevice *device;
    IVideoDriver* driver;
    ISceneManager* smgr;
    IGUIEnvironment* guienv;
    IMetaTriangleSelector* mainTriangleSelector;
 
    IGUIStaticText *text;
 
    dimension2d<u32> deskres;  //Rozmiar Okna
    int lastFPS;
    u32 then;
    
    const wchar_t *tmp_text;
    bool fullscreen;
    bool music;
    video::E_DRIVER_TYPE driverType;
    rgb rgb;
    enum
    { 
        ID_IsNotPickable = 0,
        IDFlag_IsPickable = 1 << 0,
        IDFlag_IsHighlightable = 1 << 1
    };
 
    //Obiekty zewnetrzne
    MyEventReceiver receiver;
    PieceOne* Kloc;
};
 
#endif

Code: Select all

#include "stdafx.h"
#include "App.h"
 
 
 
App::App(bool& outFullscreen, bool& outMusic,
            video::E_DRIVER_TYPE& outDriver)
{
    driverType=outDriver;
    fullscreen=outFullscreen;
    music=outMusic;
 
    rgb.bg_r = 255.0f;
    rgb.bg_g = 255.0f;
    rgb.bg_b = 255.0f;
 
    tmp_text = L"FPS: ";
    // create a NULL device to detect screen resolution
    IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL);
    deskres = nulldevice->getVideoModeList()->getDesktopResolution(); // pobierana rozdzielczosc ekranu i ustawienie jej jako roz. okna
    nulldevice -> drop();
    // now the dimensions can be used to create the real device
    this->deskres = dimension2d<u32>(480, 960); // rozdzielczośc okna manualnie ustawiana 
}
 
 
App::~App(void)
{
 
}
bool App::Init(void)
{
    device = createDevice(driverType, deskres, 32, fullscreen,
        false, false, &receiver);
    if (!device)
        return 1;
 
    device->setWindowCaption(L"Tetris");// Usawiamy nazwe Okna
 
    driver = device->getVideoDriver();
    smgr = device->getSceneManager();
    guienv = device->getGUIEnvironment();
    mainTriangleSelector = smgr->createMetaTriangleSelector();
 
 
    text = guienv->addStaticText(tmp_text,   //WYSWIETLA FPS
        rect<s32>(deskres.Width-50,10,deskres.Width-10,20), false);
 
 
    this->NodeSelector();// Wyszukuja wszystkoe node's i stworz sleketory dla potencjalnych node's
    smgr->addCameraSceneNode(0, vector3df(0,100,15), vector3df(0,5,0));
    smgr->setAmbientLight(video::SColorf(0.3,0.3,0.3,1));
    ILightSceneNode* light1 = smgr->addLightSceneNode( 0, core::vector3df(0,200,90), video::SColorf(0.3f,0.3f,0.3f), 1000.0f, 1 ); 
    //************
    //Obiekty Klas 
    //************
    Kloc = new PieceOne(device);
 
    //  MAIN LOOP
    mainTriangleSelector->drop();
    lastFPS = -1;
    then = device->getTimer()->getTime();
    
}
bool App::run(void)
{
    if(this->Init())//Inicjalizacja
        return 1;
    Kloc->Erase();
    while(device->run())
    {
        const u32 now = device->getTimer()->getTime();
        const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Czas w sekundach
        then = now;
 
        if(receiver.IsKeyDown(irr::KEY_KEY_W)) //Obsluga klawiatury
            Kloc->Erase();
 
        driver->beginScene(true, true, SColor(255,rgb.bg_r,rgb.bg_g,rgb.bg_b));
        Kloc->Draw();
        smgr->drawAll();
        guienv->drawAll();
        driver->endScene();
 
        this->FpsCounter(); //Obliczamy FPS i wyswietlamy
    }
 
    device->drop();
 
    return 0;
}
void App::FpsCounter(void)
{
    if (driver->getFPS() != lastFPS)
    {
        lastFPS = driver->getFPS();
        core::stringw tmp = L"FPS: ";
        tmp += lastFPS;
        text->setText(tmp.c_str()); //Wyswietla FPS
    }
}
void App::NodeSelector(void)
{
    core::array<scene::ISceneNode *> nodes;
    smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // znajdz wszystkie nodes
 
    for (u32 i=0; i < nodes.size(); ++i)
    {
        scene::ISceneNode * node = nodes[i];
        scene::ITriangleSelector * selector = 0;
 
        switch(node->getType())
        {
        case scene::ESNT_CUBE:
        case scene::ESNT_ANIMATED_MESH:
            // selektor nie animuje sie z siatkami modeli,
            // i uzywa sie tylko go do colizji kamery, uzyjemy przyblozonego
            // bounding box zamiast ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0)
            selector = smgr->createTriangleSelectorFromBoundingBox(node);
        break;
 
        case scene::ESNT_MESH:
        case scene::ESNT_SPHERE: // nody z IMeshSceneNode
            selector = smgr->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
            break;
 
        case scene::ESNT_TERRAIN:
            selector = smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node);
            break;
 
        case scene::ESNT_OCTREE:
            selector = smgr->createOctreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
            break;
 
        default:
            // Nie tworzymy selektorow jezeli nie ma node
            break;
        }
 
        if(selector)
        {
            // dodajemy je do  meta selectora, ktory bierze referencje do nich
            mainTriangleSelector->addTriangleSelector(selector);
            // i dropujemy selektor, by meta selektor mogl go kontrolowac.
            selector->drop();
        }
    }
}
ok now Descrition of my Prob
Take a look at my class Block. there i have definded a single block (cube). With this cube I want creat tetris block.
and second class is simple project to creat 1st element of tetris like this:
Image

The problem is when i try to implement function that will help me Erese one of cube from this model.
Cus when i delete them like up in code in function erese in class PieceOne it's maybe out of vector but in screen still there is.
and I notice i can use one function from class block to draw all ;/

I don't know if u understand what I mean so.
Imagine that: You are plaing tetris and u have completed a line... so now the line should disappere and I want do function to this.
I think the problem begin in class Block.
cus there I create node(only node is different from other objcect) cus smgr and other got this same address as other object. If u know what i mean.
and I need delete node in destructor ? if yes? how ?
Help me please
Last edited by shial on Fri Feb 08, 2013 6:01 pm, edited 1 time in total.
shial
Posts: 3
Joined: Thu Feb 07, 2013 3:17 pm

Re: IMeshSceneNode Problem

Post by shial »

I try do like this:

Code: Select all

Block::~Block(void)
{
    if (node) 
    { 
        node->remove();
    }
}
 
in destructor but I got error
Unhandled exception at 0xFEEEFEEE in Project3.exe: 0xC0000005: Access violation executing location 0xFEEEFEEE.
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: IMeshSceneNode Problem

Post by STTrife »

First, you dont need to call drawall in your block class or any of your own classes, just let the scenemanager draw the scene in your main loop. Using ->remove is good, if you use ->removeall then you only remove children. You dont need to manually delete the node. it is reference counted so it deletes itself ik you call remove. I notice you call erase the whole time when you hold w. Like each frame... Maybe that is the problem... Try not calling pop_back more ften then you have blocks...
Also try to load your mesh only one time, not for each block seperatly.. Also you dont free the mesh whe you delete your block.

Btw the FEEFEE error seems to mean you try to call a function on a already deleted object.
shial
Posts: 3
Joined: Thu Feb 07, 2013 3:17 pm

Re: IMeshSceneNode Problem

Post by shial »

Code: Select all

 
bool App::run(void)
{
    if(this->Init())//Inicjalizacja
        return 1;
    Kloc->Erase();  //<----- HERE 
    while(device->run())
    {
        const u32 now = device->getTimer()->getTime();
        const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Czas w sekundach
        then = now;
 
        if(receiver.IsKeyDown(irr::KEY_KEY_W)) //Obsluga klawiatury
            Kloc->Erase();
 
        driver->beginScene(true, true, SColor(255,rgb.bg_r,rgb.bg_g,rgb.bg_b));
        smgr->drawAll();
        guienv->drawAll();
        driver->endScene();
 
        this->FpsCounter(); //Obliczamy FPS i wyswietlamy
    }
 
    device->drop();
 
    return 0;
}
 

Forget key. I do it befor Main Loop yet. and iven if I have already done... the block still there is.
And how I can
Also try to load your mesh only one time, not for each block seperatly.. Also you dont free the mesh whe you delete your block.
load mesh only one time ? Whats your idea ?? How u see it ? Can you explain me ?
And in destructor i need do

Code: Select all

mesh->remove();
?
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: IMeshSceneNode Problem

Post by STTrife »

For each block, the mesh is the same, so you only load it once in your main program, and give the pointer every time when you add a scenenode.
You don't need your own block class per se. In the onepiece class just use an empty scene node to hold the 4 block-mesh. And just call addMeshSceneNode 4 times on that empty scenenode to add them. Then you can remove your own block class.

if you would want to delete mesh, you would do mesh->drop() I think. you only call remove on scenenodes
Post Reply