Bonjour bonjour :)
J'ai un petit probleme et j'espere que vous pourrez m'aider ^^
Je cherche a faire un deplacement d'un mesh (fluide et pas teleportation) automatique.
Je m'explique :
Un mesh qui se deplace tout seul (sans que l'on appuie sur une touche) mais par etape..
En gros je suis en position 0, mon mesh se deplace de jusqu'a une coordonne precise (par exemple 10) et ainsi de suite...
C'est pas evidement a expliquer :S j'espere que vous avez compris ^^.
Peut etre qu'avec mon bout de code vous comprendrez mieux :
IAnimatedMesh* mesh = smgr->getMesh("mon_model");
player = smgr->addAnimatedMeshSceneNode(mesh);
player->setPosition(irr::core::vector3df(0, 0, 0));
while(device->run())
{
i = 0;
while (i != 10)
{
nodePosition.Z += 1;
player->setPosition(nodePosition);
i++;
}
}
Et en gros il se teleporte a la position 10.. au lieu de se deplacer jusqu'a cette position :S...
Quelqu'un pourrait t'il m'aider ?
Hors ligne
Bah, la boucle while(device->run()) va à la vitesse de tes fps, non ? c'est normal que t'ai pas le temps de voir si t'as plus de 10fps =o Si tu veux controler la vitesse de ce déplacement, un simple int incrementé ne suffira sans doute pas
Hors ligne
Ah.. d'accord.
Du coup il faut que je m'inspire du tuto 4 ? http://irrlicht.sourceforge.net/docu/example004.html
Quand il fait :
u32 then = device->getTimer()->getTime();
// This is the movemen speed in units per second.
const f32 MOVEMENT_SPEED = 5.f;
while(device->run())
{
// Work out a frame delta time.
const u32 now = device->getTimer()->getTime();
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
then = now;
if(receiver.IsKeyDown(irr::KEY_KEY_W))
nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime;
//Affichage et tout le tralala
}
(Je vais quand meme tester )
Mais c'est pour savoir si je suis dans la bonne direction
Hors ligne
j'pense que t'es dans la meilleure direction, oui les tutos officiels sont souvent bien pratiques...
après, si tu tiens absolument à utiliser le int, tu peux multiplier i=10 par le nombre de tes fps, et il durera en théorie effectivement 10s ... quoique, je sais même pas, si on prend en compte que les fps varient ...
Bref, essaie de continuer en t'inspirant du tuto, si ca marche pas réflechis à d'autres possibilité ^^
Hors ligne
Salut, t'as sans doute déjà trouvé une solution à ton problème mais bon,
Le problème dans ton code, c'est surtout que ton while gérant ton déplacement est dans ta boucle de jeu...donc à chaque rendu, tu effectue le déplacement complet et non pas les 10 étapes sur 10 rendus (qui donnerait une animation de ton déplacement).
Bon après même en corrigeant ça, ça n'est pas une bonne idée de faire le déplacement en fonction de la vitesse d'exécution de ton ordi, dans le cas présent: metytons que tu tournes à 1fps, ton déplacement prendrait 10 secondes, mais si tu tournes à 10fps, le déplacement prendra 1 seconde, alors imagine avec un fps élevé...
C'est pour ça que d'ans l'exemple il utilise le temps passé comme coefficient.
pourquoi tu ne fais pas une interpolation linéaire de la position par rapport au temps: ton déplacement sera fluide (si t'as un fps correct (>25 sinon ça lag et on n'y peut rien), et indépendant du fps (sur un autre ordinateur plus lent ou plus rapide, ton déplacement prendra le même temps et se fera à la même vitesse)
C'est pas bien compliqué à mettre en pratique, il te faut :
-La position de départ (pointDepart)
-La position d'arrivée souhaitée (pointArrivee)
-Le temps au moment du départ (tempsDepart)
-Le temps de déplacement souhaité (tempsParcours)(il peut être fixe et donc ton déplacement sera plus ou moins rapide en fonction de la distance à parcourir, ou bien tu le calcule en fonction de la vitesse qui sera fixe et de la distance à parcourir )
donc au moment où tu lance le déplacement, tu récupères le temps courant dans tempsDepart, la position actuelle dans pointDepart, la position voulue dans pointArrivee et tu décides d'un temps de parcours.
Ensuite à chaque tour de boucle de jeu, tu mets à jour la position en faisant le ratio du temps passé par rapport au temps de parcours total et tu applique ce même ratio sur la position suivant la ligne entre le point de départ et le point d'arrivée ( déplacement = tempsPasséDepuisLeLancement * DistanceAParcourir / TempsTotalParcours) :
...
// Au lancement de ton déplacement
pointDepart = position;
pointArrivee = target; // à toi de décider où aller
tempsDepart = device->getTimer()->getTime();
bouge = true;
...
// puis tant que le déplacement est actif, à chaque tour de boucle de jeu (typiquement dans l'appel que fait Irrlicht sur tes nodes avant chaque rendu : onAnimate() )
if( bouge )
{
irr::u32 now = device->getTimer()->getTime();
// mise à jour de la position (c'est ine version simplifiée pour le principe, il faudrait faire attention aux coordonnées négatives dans la soustraction...)
position.X = pointDepart.X + ( (now-tempsDepart) * (pointArrive..X - pointDepart.X) ) / tempsParcours );
position.X = pointDepart.Y + ( (now-tempsDepart) * (pointArrive..Y - pointDepart.Y) ) / tempsParcours );
position.X = pointDepart.Z + ( (now-tempsDepart) * (pointArrive..Z - pointDepart.Z) ) / tempsParcours );
if( ( now - tempsDepart ) >= tempsParcours )
{
bouge = false; // tu es arrivé
poistion = pointArrivee; // on recale au cas où on serait pas tombé pile poil sur la bonne position d'arrivée
}
}
Après, à toi d'encapsuler ça dans des fonctions et dans des classes...
Dernière modification par adiems (24-06-2010 11:25:54)
Hors ligne