How to implement figures as independently operating objects?

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.
tchilrri
Posts: 8
Joined: Mon Jun 28, 2004 6:26 pm
Location: Germany

Post by tchilrri »

poop I forgot the tags. Sorry, once again.

Code: Select all

#include <irrlicht.h>

#include <qthread.h>
#include <qptrlist.h>
#include <qdatetime.h>
#include <qmutex.h>

#include <stdlib.h>

using namespace irr;

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

scene::ISceneManager* smgr;
video::IVideoDriver* driver;
IrrlichtDevice *device;
video::SMaterial material;
scene::ITriangleSelector* selector;
bool s_bDebug = false;
bool s_bRun = true;
QMutex smgrAccess;

int random()
{
    return QTime::currentTime().msec() + rand();
}

scene::ISceneNodeAnimatorCollisionResponse* AnimateObj(scene::ISceneNode* pNode, bool bFixedRadius = false)
{
    core::aabbox3df box = pNode->getBoundingBox();
    core::vector3df radius = bFixedRadius ? core::vector3df(30,50,30) : box.MaxEdge - box.getCenter();

	scene::ISceneNodeAnimatorCollisionResponse* anim = smgr->createCollisionResponseAnimator(
		selector, pNode,
        radius, // how big the object is (radius of an ellipsoid)
		core::vector3df(0,-100,0), // direction and speed of gravity (0,0,0 to disable gravity)
        100.0f, // acceleration value when falling down
		core::vector3df(0,0,0)); // translation from the center of the ellipsoid
	pNode->addAnimator(anim);
	anim->drop();
    return anim;
}

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
        if (event.EventType == irr::EET_KEY_INPUT_EVENT) { //&& !event.KeyInput.PressedDown)
			switch (event.KeyInput.Key) {
			case KEY_SPACE:
                s_bDebug = true;
				return true;
			}
		}
		return false;
	}
};

class Fairy
{
public:
    Fairy()
        : m_direction(90), m_bShouldRenderMove(false)
        ,m_id(0), m_jump(0),m_stepWidth(6)
    {
        static int id = 0;
        m_id = id++;
        m_pFairyNode = createFairy();

        static int x = -150;
        x += 5;
        m_oldPos = core::vector3df(x,50,5);
        m_pFairyNode->setPosition(core::vector3df(x,50,0));
        m_pFairyNode->setRotation(core::vector3df(0,m_direction,0));
        m_pCollRespAnim = AnimateObj(m_pFairyNode);
    }
    
    void move()
    {
        // really set to queued position
        m_pFairyNode->setPosition(m_newPos);
    }

    void signalFinishedMove()
    {
        // reset queue flag
        m_bShouldRenderMove = false;
    }

    bool shouldMove()
    {
        return m_bShouldRenderMove;
    }

    bool isDying()
    {
        if (m_pFairyNode->getPosition().Y < -1000) {
            // falling in the depth
            return true;
        }
        return false;
    }

    void live()
    {
        // if the queued new position is not already rendered, don't do further steps
        if (m_bShouldRenderMove) {
            return;
        }

        if (s_bDebug) {
            s_bDebug = false;
        }

        core::vector3df pos = m_pFairyNode->getPosition();
        core::vector3df move = computeNextStep();
        bool bCanWalk = !moodForDirectionChange();
        bool bDecidedNewDirection = false;
        do {
            if (!bCanWalk) {
                decideNewDirection();
                bDecidedNewDirection = true;
                move = computeNextStep();
            }
            bCanWalk = canWalk(pos, move);
        }
        while (!bCanWalk);

        if (bDecidedNewDirection) {
            turnToNewDirection();
        }

        // compute the new position where we'll be after the step
        // and queue it for rendering
        m_newPos = pos + computeNextStep();
        m_bShouldRenderMove = true;

        // store her old position for further checking if the queued step will be successful
        m_oldPos = pos;
    }

protected:
    scene::IAnimatedMeshSceneNode* createFairy()
    {
	    // add animated fairy.
	    material.Texture1 = driver->getTexture("../../media/faerie2.bmp");
	    material.Lighting = true;

	    scene::IAnimatedMeshSceneNode* node = 0;
	    scene::IAnimatedMesh* pFairy = smgr->getMesh("../../media/faerie.md2");

	    if (pFairy) {
		    node = smgr->addAnimatedMeshSceneNode(pFairy);
		    node->setPosition(core::vector3df(-70,0,-90));
		    node->setMD2Animation(scene::EMAT_STAND); // EMAT_RUN
		    node->getMaterial(0) = material;
	    }

        material.Texture1 = 0;
	    material.Lighting = false;

        return node;
    }

    bool moodForDirectionChange()
    {
        int r = random();
        if ((r % 40) == 0) {
            return true;
        }
        else {
            return false;
        }
    }

    bool canWalk(const core::vector3df& pos, const core::vector3df& move)
    {
        core::triangle3df triangle;
        core::vector3df resultPos;
        bool f = false;
        smgrAccess.lock();
        resultPos = smgr->getSceneCollisionManager()->getCollisionResultPosition(
                        m_pCollRespAnim->getWorld(), pos,
                        m_pCollRespAnim->getEllipsoidRadius(), move, triangle, f);
        smgrAccess.unlock();
        if (resultPos.X-(pos.X+move.X) < 0.1 &&
            resultPos.Y-(pos.Y+move.Y) < 0.1 &&
            resultPos.Z-(pos.Z+move.Z) < 0.1)
        {
            return true;
        }
        return false;
    }

    void decideNewDirection()
    {
        int oldDirection = m_direction;
        int diff;
        do {
            m_direction = random() % 360;
            diff = abs(oldDirection - m_direction);
        }
        while (diff < 60 || diff > 300);
    }

    void turnToNewDirection()
    {
        m_pFairyNode->setRotation(core::vector3df(0, m_direction, 0));
    }

    core::vector3df computeNextStep()
    {
        //   0° +X,  0
        //  90°  0, -Z
        // 180° -X,  0
        // 270°  0, +Z
        core::vector3df move = core::vector3df(m_stepWidth * cos(m_direction), m_jump, m_stepWidth * -sin(m_direction));
        return move;
    }

    scene::IAnimatedMeshSceneNode*              m_pFairyNode;
    scene::ISceneNodeAnimatorCollisionResponse* m_pCollRespAnim;
    core::vector3df                             m_oldPos;
    core::vector3df                             m_newPos;
    int                                         m_direction;
    bool                                        m_bShouldRenderMove;
    int                                         m_id;
    int                                         m_jump;
    int                                         m_stepWidth;
};

class AiControl : public QThread
{
public:
    AiControl() : QThread()
        ,m_bRunning(true)
    {
        // create a number of fairies, each one doing its action every 100 milliseconds
        for (int i = 0; i < 3; i++) {
            Fairy* pFairy = new Fairy;
            m_fairies.append(pFairy);
        }
    }

    virtual ~AiControl()
    {
        // destroys all fairies
        QPtrListIterator<Fairy> it(m_fairies);
        while (*it) {
            delete *it;
            ++it;
        }
    }

    void doExit()
    {
        m_bRunning = false;
    }

    bool isSomethingToDo()
    {
        QPtrListIterator<Fairy> it(m_fairies);
        while (*it) {
            Fairy* pFairy = *it;
            if (pFairy->shouldMove()) {
                return true;
            }
            ++it;
        }
        return false;
    }

    void doAI()
    {
        // check all fairies if they've queued a new step.
        // if so, do the walk
        QPtrListIterator<Fairy> it(m_fairies);
        while (*it) {
            Fairy* pFairy = *it;
            if (pFairy->shouldMove()) {
                pFairy->move();
            }
            ++it;
        }
    }

    void signalFinishedRendering()
    {
        QPtrListIterator<Fairy> it(m_fairies);
        while (*it) {
            Fairy* pFairy = *it;
            if (pFairy->shouldMove()) {
                pFairy->signalFinishedMove();
            }
            ++it;
        }
    }

protected:
    virtual void run()
    {
        while (m_bRunning) {
            // wait some milliseconds until the next action of the fairy
            msleep(50);
            // from time to time let the fairies do something intelligent
            QPtrListIterator<Fairy> it(m_fairies);
            while (*it) {
                Fairy* pFairy = *it;
                if (pFairy->isDying()) {
                    QPtrListIterator<Fairy> it2 = it;
                    ++it;
                    m_fairies.remove(it2);
                    delete pFairy;
                    if (!m_fairies.count()) {
                        s_bRun = false;
                    }
                }
                else {
                    pFairy->live();
                    ++it;
                }
            }
        }
    }

protected:
    QPtrList<Fairy>         m_fairies;
    bool                    m_bRunning;
};

int main()
{
    MyEventReceiver receiver;
    device = createDevice(video::EDT_DIRECTX9, core::dimension2d<s32>(640, 480), 16, false, false, &receiver);
	driver = device->getVideoDriver();
	smgr   = device->getSceneManager();
	device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

	scene::IAnimatedMesh* q3levelmesh   = smgr->getMesh("20kdm2.bsp");          if (!q3levelmesh) return 1;
    scene::IMesh*         pMesh         = q3levelmesh->getMesh(0);
	scene::ISceneNode*    q3node        = smgr->addOctTreeSceneNode(pMesh);     if (!q3node) return 1;
	q3node->setPosition(core::vector3df(-1370,-130,-1400));

    selector  = smgr->createOctTreeTriangleSelector(pMesh, q3node, 128);
	q3node->setTriangleSelector(selector);
	selector->drop();

	scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 300.0f);
	camera->setPosition(core::vector3df(0,50,0));
    camera->setRotation(core::vector3df(0,270,0));
    AnimateObj(camera, true);

    AiControl aiControl;
    aiControl.start();

	smgr->addLightSceneNode(0, core::vector3df(-60,100,400), video::SColorf(1.0f,1.0f,1.0f,1.0f), 600.0f); // Add a light
	device->getCursorControl()->setVisible(false); // disable mouse cursor

    // infinite rendering loop
	while (s_bRun && device->run()) {
        bool bDoAI = false;
        if (aiControl.isSomethingToDo()) {
            bDoAI = true;
            aiControl.doAI();
        }
		driver->beginScene(true, true, 0);
        smgrAccess.lock();
		smgr->drawAll();
        smgrAccess.unlock();
		driver->endScene();
        if (bDoAI) {
            aiControl.signalFinishedRendering();
        }
	}

	device->drop();
	return 0;
}

angel80
Posts: 22
Joined: Mon Feb 07, 2005 1:37 pm
Location: Paris (France)

please can u post your Makefile for linux ???

Post by angel80 »

I'd like to look how it it works but I can't compile it with qmake and changing links with irrlicht
there lots of error
What is your irrlicht version please?
.: Franck :.
.: Franck :.
Post Reply