#0 

27-05-2008 10:31:09

noals
Membre
Date d'inscription: 17-05-2008
Messages: 34

salut,

en fait j'ai fait une caméra 3rd person.
j'ai donc l'axe X de ma souris qui change la rotation du player
et j'ai l'axe Y de la souris qui bouge la caméra de haut en bas ou inversement.

mon problème, c'est que comme je base mes mouvement sur la position de la souris, si mon cursor se trouve au bord de mon écran, ma caméra peut pas aller plus loin.

j'ai demander sur le forum US déjà, il m'on dit de regarder le fichier source de la caméra FPS.
donc j'comprend dans ce fichier qu'il utilise la position relative de la souris avec une sorte d'algo pour définir la position de leur caméra mais sinon, j'y comprend kedal.

j'ai essayer dans tous les sens avec ce que j'savais mais j'en sais pas asser donc forcement ça limite.
'fin bref, si vous avez un bout de code ou une piste un peu plus précise qui pourrait m'aider à comprendre comment j'peux définir ma classe pour que les mouvement de ma caméra ne soit pas limité, ça serait sympa parce que là, j'comprend tous simplement pas.

j'avais uploader mon projet à titre d'exemple sur fileden mais filden bug la, j'mettrai le lien plus tard quand ils auront reglé leur probleme de serveur chez fileden.


pour mon code, en gros j'l'ai comme ça pour l'instant.

Code:

//--->  DEFINITION  <---///////////////////////////////////////////////////////////////////////////
position2d<f32> cursor;
f32 myX;
f32 myY;
f32 myZ;
f32 myX2;
f32 myY2;
f32 myZ2;

///////////////////////////////////////////////////////////////////////////////////////////////////
//--->  EVEN RECEIVER  <---////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

class MyEventReceiver: public IEventReceiver
{
    public: virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_MOUSE_INPUT_EVENT)
        {
            cursor.X = event.MouseInput.X;
            cursor.Y = event.MouseInput.Y;
        }

    }
};


//--->  DEFINITION  <---///////////////////////////////////////////////////////////////////////////
vector3df myRotation(f32 myX, f32 myY, f32 myZ)
{
    f32 x = 0;
    f32 y = cursor.X;
    f32 z = 0;
    vector3df result;
    result.X = x;
    result.Y = y;
    result.Z = z;
    return result;
}
vector3df myRotation2(f32 myX2, f32 myY2, f32 myZ2)
{
    f32 x = 0;
    f32 y = -250 + cursor.Y;
    f32 z = 100;
    vector3df result;
    result.X = x;
    result.Y = y;
    result.Z = z;
    return result;
}

Code:

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
//////////////////////////////        RENDERING        ////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

    IGUIEnvironment* guienv = device->getGUIEnvironment();
    IGUIStaticText* debug_panel = guienv->addStaticText(L"",rect<s32>(15, 15, 50, 30),true,true,0,-1,false);

    int lastFPS = -1;

    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, true, video::SColor(0,200,200,200));

//--------------------------------------------------------------------------------------------------------
        myCamera->setTarget(playerNode->getPosition()); //refresh caméra target
        myCamera->setPosition(myRotation2(myX2,myY2,myZ2)); //caméra angle
        playerNode->setRotation(myRotation(myX,myY,myZ));//player rotation


        smgr->drawAll();

merci
a+

Hors ligne


#1 

27-05-2008 13:19:12

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Voila un demande qui motiverai un mort smile ;
Je ne sais pas ce que tu veux en faire de cette camera mais ne serait-il pas mieu de faire tourner la cam ou le perso seulement lorsque le curseur est contre un bord de l'ecran ?
Ainsi la souris serait libre ( cliquer sur me mechant, sur le bouton de la gui .....) et il n'y aurait pas le probleme de de l'arret de la rotation.

Hors ligne


#2 

27-05-2008 19:04:04

noals
Membre
Date d'inscription: 17-05-2008
Messages: 34

j'ai mis mon projet sur megaupload en attendant fileden.
donc : lien
voila déjà ce que ça donne. (opengl, fullscreen, alt f4 pour quitter)

firnafin :

Voila une demande qui motiverai un mort smile ;
Je ne sais pas ce que tu veux en faire de cette camera


pour l'instant, j'veux juste en faire une caméra pour avoir un gameplay comme dans jedy academy.
pas de gui ni rien, j'veux trouver le moyen de retirer cette limite et ensuite, j'continuerai mes recherche par rapport à l'atribution des touches, mouvement et animations.

firnafin :

mais ne serait-il pas mieu de faire tourner la cam ou le perso seulement lorsque le curseur est contre un bord de l'ecran ?


il me faudrai les deux parce qu'avec ta méthode si le cursor et dans l'écran, y'a plus rien qui bouge.
d'un autre coté, ça me donne une piste à étudier mais le problème est un peu le meme pour moi.
j'sais pas comment dissocié ma position de cursor et les position dont j'me sert pour la caméra et le joueur, j'ai du mal avec les algo.
mon autre probleme c'est que j'sais pas non plus comment définir mes trucs pour pouvoir utiliser par exemple cursor->getRelativePosition() dans ma classe.
si j'ai bien compris il faut que j'utilise :

Code:

#ifndef __E_EXEMPLE_H__
#define __E_EXEMPLE_H__

et que j'fasse un fichier header pour mon programme mais j'comprend pas trop l'architecture du truc avec les namespace, constructor et destructor.
en plus la dedans faut ajouté des include non ?, lequels sont vraiment nécessaire, etc...

sinon, j'ai un exemple qui fonctionne dans mes projet mais le problème c'est qu'il fonctionne avec le clic de la souris donc j'avais pensé remplacer ce clic par "si la souris bouge" ou "si la souris bouge pas" mais j'ai beau essayer, j'arrive pas non plus.

'fin bref, y'a plein de truc que j'sais pas la donc j'ai beau chercher dans tous les coin mais j'me perd plus qu'autre chose et j'sais plus par ou commencer.

Hors ligne


#3 

27-05-2008 21:27:56

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Pour ce qui est du porbleme de la limitation le plus simple serai de faire comme ca :

Code:

irr::f32 RotateSpeed=1.0; // determine la vitesse de rotation ;
irr::core::position2d<s32> Centre; // centre de l'ecran ; 

Centre.X=400; // milieu de l'ecran selon X
Centre.Y=300; // milieu de l'ecran selon Y
irr::core::vector3df v;
v.x=0;
v.y=PlayerNode->getRotation().Y+RotateSpeed*(Centre.X-Cursor.X); // on ajoute a la rotation selon Y de la node un angle si le curseur a bougé selon X sinon Centre.X-Cursor.X =0
v.z=0;

PlayerNode->setRotation(v); // on affecte la nouvelle valeur de calculée.
myICursorControl->setPosition(Centre); // on replace le curseur au centre;

En gros le curseur reste au milieu , si il y a deplacement de celui ci on fait bouger la node puis on le remet au milieu.

Hors ligne


#4 

27-05-2008 22:03:44

noals
Membre
Date d'inscription: 17-05-2008
Messages: 34

merci, j'vais essayer de le mettre dans mon code.
j'metrai le code ici quand j'aurai réussi.
a+

Hors ligne


#5 

28-05-2008 03:05:51

noals
Membre
Date d'inscription: 17-05-2008
Messages: 34

j'ai réussi ! ^^
merci énormément de ton aide.
le seul truc que j'ai pas compris, c'est que si a la fin j'mettais mycursor->setPosition(ScreenCenter);, la souris ne revenais pas au milieu donc j'ai galéré pas mal pour le découvrir, et pour aranger ça bah j'me suis pas pris la tête, j'ai juste mis mycursor->setPosition(400,300); alors que ScreenCenter à les même valeurs.
un bug peut etre, j'sais pas..
'fin bref, là, ça marche nikel et j'l'ai mis sur le positionnement de la caméra aussi, merci encore.

maintenant faut que je limite la distance de la caméra quand elle est déplacé et j'ajouterai ensuite le zoom avec la molette de la souris, ça devrait etre moin compliqué. ^^

voice mon code complet :

Code:

#include <irrlicht.h>
#include <iostream>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

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



//--->  DEFINITION  <---///////////////////////////////////////////////////////////////////////////

position2d<f32> cursor; //position du curseur de la souris
position2d<f32> ScreenCenter; //centre de l'ecran bien que le curseur soit pas d'accord avec ça lol

f32 RotationSpeed= 1.0; //determine la vitesse de rotation du joueur.
vector3df v; //rotation du joueur
vector3df c; //position de la camera


///////////////////////////////////////////////////////////////////////////////////////////////////
//--->  EVEN RECEIVER  <---////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

class MyEventReceiver: public IEventReceiver
{
    public: virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_MOUSE_INPUT_EVENT)
        {
            cursor.X = event.MouseInput.X;
            cursor.Y = event.MouseInput.Y;
        }
        return 0;
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                       //////////////////////////////////////////////////////
//////////////////////////////         MAIN          //////////////////////////////////////////////////////
//////////////////////////////                       //////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

int main()
{
    MyEventReceiver receiver;                  //initialisation du receiver
    IrrlichtDevice* device = createDevice(
        EDT_OPENGL,                            //EDT_SOFTWARE, EDT_NULL, EDT_DIRECT3D8, EDT_DIRECT3D9
        dimension2d<s32>(800, 600),
        32,
        true,                                  //fullscreen ?
        false, false,                          //?
        &receiver);                            //node
    if (device == 0)return 1;                  //exit if creation failed

    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    ICursorControl* myCursor = device->getCursorControl();

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                       //////////////////////////////////////////////////////
//////////////////////////////       TERRAIN         //////////////////////////////////////////////////////
//////////////////////////////                       //////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

    ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
        "heightmap/F18.bmp",                                               //heightmap
        0,                                                                 //parent
        -1,                                                                //ID
        vector3df(0.f, 0.f, 0.f),                                          //position
        vector3df(0.f, 0.f, 0.f),                                          //rotaton ?
        vector3df(200, 22, 200),                                           //scaling de la heightmap / taille
        SColor(255, 255, 255, 250),                                        //couleur des vertex
        5,                                                                 //detail du node
        ETPS_33,                                                           //patchsize wth ??
        3,                                                                 //smoothfactor
        false);                                                            //add terrain node even with empty heightmap

    terrain->setMaterialFlag(EMF_LIGHTING, false);                            //lumière ?
    terrain->setMaterialTexture(0, driver->getTexture("terrain/herbe.jpg"));  //texture
    terrain->setMaterialType(EMT_DETAIL_MAP);
    terrain->scaleTexture(200, 16000);                                  //scaling de la texture

//SKYBOX
    driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);              //true ?
    smgr->addSkyBoxSceneNode(
        driver->getTexture("skybox/siege_up.jpg"),                   //up
        driver->getTexture("skybox/siege_dn.jpg"),                   //down
        driver->getTexture("skybox/siege_lf.jpg"),                   //left
        driver->getTexture("skybox/siege_rt.jpg"),                   //right
        driver->getTexture("skybox/siege_bk.jpg"),                   //back
        driver->getTexture("skybox/siege_ft.jpg"));                  //front
        driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true);        //?

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                             ////////////////////////////////////////////////
//////////////////////////////       TRIANGLE SELECTOR     ////////////////////////////////////////////////
//////////////////////////////                             ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

    ISceneNode* terrainNode = 0;
    if(terrain)
    terrainNode = smgr->addMeshSceneNode(terrain->getMesh());

    ITriangleSelector* selector = 0;
    if(terrainNode)
    {
        terrainNode->setPosition(vector3df(-1370,-130,-1400));
        selector = smgr->createTerrainTriangleSelector(terrain, 0);
        terrainNode->setTriangleSelector(selector);
        selector->drop();
    }

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
//////////////////////////////          PLAYER         ////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

    ISceneNode* playerNode = smgr->addEmptySceneNode();  //3rd person
    playerNode->setPosition(vector3df(19000, 3500, 37000));

    IAnimatedMesh* playerMesh= smgr->getMesh("models/faerie.md2");                                //model
    IAnimatedMeshSceneNode* visualNode= smgr->addAnimatedMeshSceneNode(playerMesh, playerNode);
    if (visualNode)
    {
        visualNode->setMaterialFlag(EMF_LIGHTING, false);
        visualNode->setFrameLoop(0, 310);
        visualNode->setMaterialTexture(0, driver->getTexture("models/faerie.bmp"));               //texture
        visualNode->setRotation(core::vector3df(0,90,0)); //player dos a la caméra
    }

//COLLISION
    const aabbox3df& box=        playerNode->getBoundingBox();
    const f32 height=            (box.MaxEdge.Y - box.MinEdge.Y)/ 2.f;
    const f32 verticalOffset=    -box.MinEdge.Y - box.MaxEdge.Y;
    const f32 waist=             max_(box.MaxEdge.X - box.MinEdge.X, box.MaxEdge.Z - box.MinEdge.Z)/ 2.f;

    ISceneNodeAnimator* anim= smgr->createCollisionResponseAnimator
    (
        selector,                                  //triangle selector
        playerNode,                                //scene node
        vector3df(30,25,30),                       //ellipsoidRadius  //position du perso 30;60;30
        vector3df(0,-3,0),                         //gravity
        vector3df(0,0,0),                          //ellipsoidTranslation
        0.0005f                                    //slidingValue
    );
    playerNode->addAnimator(anim);
    anim->drop();

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
//////////////////////////////          CAMERA         ////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

    ICameraSceneNode* myCamera =
    smgr->addCameraSceneNode(
        playerNode,                                      //parent
        vector3df(0,75,100),                             //angleX, angleH, distance
        playerNode->getPosition(), //vector3df(0,0,0),   //look at...
        -1);                                             //ID
    myCamera->setFarValue(4000);                         //drawing distance

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
//////////////////////////////          CURSOR         ////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
    myCursor->setVisible(false);

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
//////////////////////////////        RENDERING        ////////////////////////////////////////////////////
//////////////////////////////                         ////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////

    IGUIEnvironment* guienv = device->getGUIEnvironment();
    IGUIStaticText* debug_panel = guienv->addStaticText(L"",rect<s32>(15, 15, 50, 30),true,true,0,-1,false); //100 : L - h




    int lastFPS = -1;

    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, true, video::SColor(0,200,200,200));

//--------------------------------------------------------------------------------------------------------
    ScreenCenter.X= 400;
    ScreenCenter.Y= 300;
    v.X=0;
    v.Y=playerNode->getRotation().Y+RotationSpeed*(ScreenCenter.X-cursor.X)*-1;
    v.Z=0;
    c.X=0;
    c.Y=myCamera->getPosition().Y+RotationSpeed*(ScreenCenter.Y-cursor.Y)*-1;
    c.Z=100;

//--------------------------------------------------------------------------------------------------------

        myCamera->setTarget(playerNode->getPosition()); //refresh caméra target
        myCamera->setPosition(c);
        playerNode->setRotation(v);

        myCursor->setPosition(400,300); //remise a zéro du cursor.

        smgr->drawAll();
        //s32 myx = cursor.X;
        s32 framerate = driver->getFPS();
        debug_panel->setText(stringw(framerate).c_str()); //framerate
        debug_panel->setOverrideColor(SColor(255,255,255,255));
        debug_panel->setBackgroundColor(SColor(255,0,0,0));


        device->getGUIEnvironment()->drawAll();
        driver->endScene();
    }
    device->drop();
    return 0;

}

Hors ligne


#6 

28-05-2008 10:32:45

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Que SetPosition(ScreenCenter) ne fonctionne pas vient du fait que :
-Si ScreenCenter est du type position2d<f32> il faut que  0.0<=ScreenCenter.X<=1.0 ( de meme pour Y ) , c'est des coords relatives comme pour les textures , en haut a gauche (0.0,0.0) en bas a droite (1.0,1.0) , ScreenCenter=(0.5,0.5) pour avoir le centre
Soit ScreenCenter est du type position2d<s32> et la tu y met des coords en pixel : 400,300;
Toi tu mets un ScreenCenter en <f32> comme si c'etait du <s32> alors les valeur sont superieur a 1.0 donc ca ne fait rien.
Regarde ce que j'ai ecrit , Center est du type position2d<s32> c'est pas pour rien ; smile
Tout ca c'est clairement dit dans la doc.

Autre chose , essaye de regarde comment sont codé les tutos et les codes orientés objéts en general ,ca pourra t'aide a organiser le tien car c'est plutot chaotique la .Meme pour apprendre , il faut essayé de travailler au maximun avec des classes.

Dernière modification par firnafin (28-05-2008 10:44:27)

Hors ligne


#7 

28-05-2008 21:57:04

noals
Membre
Date d'inscription: 17-05-2008
Messages: 34

disons que j'écris mon code de manière à m'y retrouver donc du moment que j'm'y retrouve, pour le moment ça va mais c'est vrai que j'sais pas trop bien me servir des classes donc j'me sert de ce que j'vois et ce que j'comprend mais y'a plein de truc qu'il faudra que je réorganise ne serait-ce que pour que ça fonctionne bien.

j'regarde la doc souvent pour comprendre comment me servir de certaines fonction mais j'avais jamais regarder <s32> ou <f32>, je sais a quoi ca correspond comme ça, merci.

en finalité, j'veux arrivé à ça.
http://img527.imageshack.us/img527/1690/gameplayoc5.jpg
'fin y'a une erreur, en gros j'veux deux gameplay switchable avec la touche ALT et un troisième gameplay type doom-like qui vient en fonction du zoom ou autre.

normalement il me faudra donc 3 classes bien distinct que j'appelle ensuite dans mon loop ou une plus complexe peut etre mais bon, j'sais pas trop encore comment j'vais faire.
pour l'instant j'dois déjà juste comprendre comment bouger mon mesh. ^^
y'a un tuto pour ça mas j'ai un peu de mal avec les nodes dans mon prog et les anims.
j'sais qu'il y a pas mal de tuto pour le control d'façon.

'fin bref, j'ai de quoi faire... ^^;
merci
a+

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
99 invités en ligne
Aucun membre connecté
RSS Feed