See site in english Voir le site en francais
Website skin:
home  download  forum  link  contact

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Author Topic: [tutorial] Posez vos question sur les DLL C++ (no 2)  (Read 74054 times)

0 Members and 1 Guest are viewing this topic.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
14 May 2008, 02:23:20
Par requète j'ouvre un nouveau fil "posez vos questions", il servira probablement bientôt, si vous ne programmez pas des dll actuellement évitez de polluer ce fil.

Ce post sera listé dans dans la série "tutorial DLL pour Orbiter"dispo ici:
http://orbiter.dansteph.com/forum/index.php?topic=6335.msg95352#msg95352

Vos questions et nos réponses (on peut etre plusieurs à répondre) serons
donc immortalisée et peut être utile à d'autres qui auront eu les mêmes
questions/probleme que vous.

Questions sur le C++,sur la SDK orbiter ou sur VC++ bienvenue.

Rappellez vous, y a pas de questions bêtes, mais essayez d'éviter le off-topic
et les blabla pour garder le post assez informatif.

A vos claviers !


NOTE: ce fil est le deuxième de la série "posez vos question sur les dll" vous pouvez trouver le premier qui a
été fermé car très long ici: http://orbiter.dansteph.com/forum/index.php?topic=6342.msg95437#msg95437
 




Message modifié ( 14-05-2008 03:04 )


Offline Papyref

  • Legend
  • ******
  • Posts: 5360
  • Country: France fr
  • Karma: 354
  • Je suis dans la Lune ne pas me déranger
Reply #1 - 14 May 2008, 08:15:55
Avec Visual C++ Express Edition, lorsqu'on crée un nouveau projet, le seul modèle disponible en application WIN32
est l'application console.

Comme la structure ne correspond pas avec la création d'une DLL, j'ai cherché dans l'aide si il est possible de charger
un modèle DLL mais je n'ai pas trouvé de solution ce qui m'a imposé de partir d'un projet existant, ShuttlePB en
l'occurence.

Quelle est la meilleure solution à retenir pour un développement en partant d'un exemple ?

:sage: Papyref


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #2 - 14 May 2008, 10:07:38
Quote
Avec Visual C++ Express Edition, lorsqu'on crée un nouveau projet, le seul modèle disponible en application
WIN32 est l'application console.
Oui, c'est l'express edition, tellement rapide que tout est en .exe >_<

Désolé mais ma version est en anglais...
File -> New -> Project from existing code -> renseigner les champs obligatoires et dans "Project type" choisir
"Dynamically linked library (DLL) project".

Plus sérieusement ces guignoleries m'agacent, c'est aussi simple d'utiliser un ancien projet et d'éditer à la main les
fichiers .sln et .vcproj!!!

Compile en Multi-threaded (/MT), çà t'évitera d'être dépendant des "VC++2005 runtime libraries".
[ properties->C/C++->Code Generation-> Runtime librarie -> Multi-Threaded (/MT) ]

En parlant du shuttlePB, une petite remarque qui peut être importante pour la suite de l'apprentissage:
Le modèle RCS du shuttlePB n'est pas compatible avec AttitudeMFD, LandMFD, LolaMFD et la plupart des MFD
possédant un contrôle des moteurs d'attitude (IMFD fonctionne bien malgrès tout car un beau jour dans l'été 2007,
j'ai contacté Jarmonik pour remonter ce bug).
Il vaut mieux préférer le modèle present dans le code du DeltaGlider ou n'importe quel autre modéle du moment que
les thg ne possèdent pas plus de 2 th (oui, enfin bref, si il y a plus de 2 tuyères impliquées c'est pas bon).

------------

no matter.

Offline Papyref

  • Legend
  • ******
  • Posts: 5360
  • Country: France fr
  • Karma: 354
  • Je suis dans la Lune ne pas me déranger
Reply #3 - 14 May 2008, 12:29:13
Merci !
Effictivement la gestion des RCS de ShuttkePB est plutôt merdique. Je vais m'orienter sur celle du DeltaGlider

:sage: Papyref


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #4 - 17 May 2008, 18:53:27
Y-a-t-il un moyen de récupérer la taille d'affichage utilisée par orbiter?



Message modifié ( 17-05-2008 18:53 )

------------

no matter.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #5 - 18 May 2008, 04:27:14
mhhhh...

Je récupère le handle de la window tout au début pour OrbiterSound avec ca tu peux appeller des fonctions
genre  "getsize" de window ? (GetWindowRect ou "Rec" ?)

Si tu rame je te donnerais le détail...

A++

Dan


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #6 - 18 May 2008, 05:07:16
ok, je cerne mieux ce qu'il faut faire mais j'ai réglé le problème avec les polices et le HUD que j'avais sans avoir besoin
de la taille de la fenêtre finalement.

Il me reste par contre un truc vraiment bizarre avec un MFD.
Je compile sur mon premier pc, affichage en 1280x1024. Je teste aussi de 1024x768 à 1600x1200 pour savoir si les
résolutions classiques passent bien.

Sur ce pc, lorsque je teste le mfd en 1024x768, j'obtiens ce à quoi je m'attend:


Sur mon vieux pc qui affiche en 1024x768 et orbiter en 1024x768 lorsque je teste le MFD, j'obtiens çà :


:rant:

Donc, il y aurait une différence entre un affichage d'orbiter en 1024x768 sous un windows en 1280x1024 et 1024x768
sous un windows qui fonctionne en 1024x768 ???? Serait-ce du à la taille différente entre les 2 écrans (19 et 17
pouces), à la féquence différente entre les deux ecrans (85Hz contre 75Hz),
au choix de la police (HFONT hFont = (HFONT)GetStockObject(SYSTEM_FONT);...pas de quoi fouetter un chat!) ,
à une incantation mystique provenant d'un des pontes de microsoft (acheter Vista, tu dois!)???



Message modifié ( 18-05-2008 05:11 )

------------

no matter.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #7 - 18 May 2008, 05:10:29
Ah, y à un gag avec les MFD et le HUD pour avoir toujours un affichage correct. Je crois que martin renvoie une
variable avec le rapport hauteur ligne bidule machin... me souviens plus désolé :sad:

Regarde peut etre dans l'exemple de MFD y a une variable "CT" ou dans le genre.

Dan


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #8 - 18 May 2008, 05:37:13
Oui, le hud, çà a été pénible mais vraiment pas insurmontable, j'avais choisi bêtement un police Arial avant de
m'apercevoir qu'elle devenait énorme ou trop fluette en 1024x768 suivant la taille choisie... avec system_font c'est ok.

Par contre, le coup du mfd me bluffe totalement (les deux screen sont en 1024x768 sur 2 écrans différents)  mais je
crois que je viens de trouver une possible erreur plutôt interessante dans mon code...


------------

no matter.

Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #9 - 18 May 2008, 18:18:18
Quote
mais je crois que je viens de trouver une possible erreur plutôt interessante dans mon code...
Ummmm....oui elle était pas mal celle-là d'erreur >_<
J'avais mis i au lieu de oapigetvesselCount()-i, mais evidemment dit comme çà çà ne raconte pas grand
chose...


------------

no matter.

Offline Papyref

  • Legend
  • ******
  • Posts: 5360
  • Country: France fr
  • Karma: 354
  • Je suis dans la Lune ne pas me déranger
Reply #10 - 18 May 2008, 18:40:22
Je merde pour définir une animation.
En utilisant les instructions de la doc API pour DefineAnimations, je me fait jeter avec UINT qui n'est pas je crois
accepté en C++. Il en est de même avec Static.

Quelle est la solution ?

C++ commence à me pomper car avec mes vieux yeux j'ai du mal à différencier [ et { par exemple, alors bonjour les
fautes de syntaxe !

:sage: Papyref


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #11 - 18 May 2008, 19:54:11
N'hesite pas à poster la partie de ton code qui pose problème. Là, la seule chose que je puisse te dire c'est
que UINT (unsigned int) ne pose pas de problème normalement en c++.
Quote
C++ commence à me pomper car avec mes vieux yeux j'ai du mal à différencier [ et { par exemple, alors bonjour les
fautes de syntaxe !
Çà ne remplace pas les yeux mais tu peux changer la police (et sa taille) utilisée par VC++:
menu tools-> Options...-> Environment-> Fonts and Colors



Message modifié ( 18-05-2008 19:54 )

------------

no matter.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #12 - 18 May 2008, 19:55:58
Quote
Papyref a écrit:
Je merde pour définir une animation.
En utilisant les instructions de la doc API pour DefineAnimations, je me fait jeter avec UINT qui n'est pas je crois
accepté en C++. Il en est de même avec Static.
Quelle est la solution ?
C++ commence à me pomper car avec mes vieux yeux j'ai du mal à différencier [ et { par exemple, alors bonjour les
fautes de syntaxe !
:sage: Papyref

Tu pourrais changer la taille de police, va voir dans les options. N'oublie pas si pas déjà fait que tu peux coloriser le
code: http://orbiter.dansteph.com/forum/index.php?topic=6359.msg95780#msg95780

Pour UINT il est defini dans windef.h, un appui sur F1 en selectionnant "UINT" te donne cette information.
Par contre moi j'ai pas de #include "windef.h" dans mes codes donc il doit être defini
aussi dans un autre header. Au début du header du DGIV j'ai que ca:

Code: [Select]
#define STRICT

#include "orbitersdk.h"
#include "resource.h"
#include "..\OrbiterSoundSDK\OrbiterSoundSDK35.h"
#include <stdio.h>

A mon avis orbitersdk.h "include" lui-même "window.h" qui inclu lui même "windef.h"


NOTE SUR LES TYPES:
des types en majuscule et non colorisé (UINT, BOOL,VECTOR3) ne sont pas vraiment des types de base standard
comme:

int
float


Ce sont des types "custom" formée d'autre types de base soit fait plus ou moins en standard dans window
(BOOL, UINT) soit totalement défini par l'utilisateur (VECTOR3, MESHANDLE)

Ainsi si tu clique droit sur "UINT" tu trouve dans "windef.h" la déclaration de type:

typedef unsigned int        UINT;

Donc "UINT" est un alias de "unsigned int" d'ailleur si tu utilise "unsigned int" pour ta variable ca marche aussi.

Ceci est extremement utile pour définir des type propre, ainsi le "MESHANDLE" de Martin n'est qu'un type:
void* un pointeur de type indéfini. (click droit sur une variable "voir definition" pour voir ou un type est
declaré)

Tout ca c'est très souple tu peux aussi faire en début de listing un:

typedef unsigned int        PAPPY;

Et declarer une variable de type "PAPPY" qui sera égale au "UINT" ;)


Pour les anims attention il y a deux methodes. une ancienne et une nouvelle. Je continue dans un nouveau post:
....



Message modifié ( 18-05-2008 19:56 )


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #13 - 18 May 2008, 20:12:49
Quote
A mon avis orbitersdk.h "include" lui-même "window.h" qui inclu lui même "windef.h"
Oui, c'est idem chez moi, je n'ai jamais eu à l'inclure moi-même. En suivant le fil, on a:
windows.h qui inclus windef.h est inclus dans orbiterAPI.h qui se trouve être inclus dans Orbitersdk.h, lui-même inclus
dans la solution...faut suivre ^^

------------

no matter.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #14 - 18 May 2008, 20:32:39
ANIMATION:

C'est pas la chose la plus simple à comprendre surtout du fait que c'est incroyablement souple mais le principe n'est
pas compliqué ni compliqué a mettre en oeuvre une fois qu'on à pigé. (c'est compliqué à expliquer du fait de la
souplesse)

Une animation ce défini dans clbksetclascap (ou fonction appellée par clbksetclasscap), Pour chaque animation on va
d'abord créer une animation vide avec la fonction:

CreateAnimation();

Ensuite on va définir à un endroit les caractéristiques comme no de mesh à animer, degre de liberté, axe de rotation
et puis passer ces données à une fonction:

AddAnimationComponent();

A la fin on obtient un "handle", c'est en passant de 0 a 1 à ce handle à chaque image (pour un mouvement) que
l'animation ce fera.

La lecture de la doc concernant ces deux fonctions est indispensable mais dans le principe on fait comme ca par
exemple pour une rotation:

1-Definir dans notre class vessel une variable de type MGROUP_ROTATE"

MGROUP_ROTATE *RadarTourne;

Dans clbkSetClassCap() (ou fonction appellée par clbksetclasscap) on donne d'abord quel partie du mesh va etre
concernée par cette animation, si par exemple c'est le bloc "3" du mesh:

static UINT GrpMeshRadar[1] = {3};

On peut définir plusieurs partie "bloc" du mesh par exemple si les groupes 3 et 14 forment le radar:

static UINT GrpMeshRadar[2] = {3,14};

Ensuite on défini les caracteristiques, axe, degre de rotation, no de mesh, position de départ dans le mesh etc etc
(voir doc MGROUP_ROTATE) par exemple:

RadarTourne= new MGROUP_ROTATE (0,GrpMeshRadar,1,_V(0,-1.9,-5.04),_V(1,0,0),(float)(2*PI));

En sortie on lui donne notre handle déclaré plus haut "RadarTourne"

Toutes nos données sont bonne , il nous reste plus qu'a créer l'animation dans Orbiter. Pour ce faire on utilise:
CreateAnimation et AddAnimationComponent.


En bref le code total donnerais par exemple pour une radar avec un seul groupe de mesh:

Declaration dans le header de la classe de notre vessel:

Code: [Select]
// animation radar
MGROUP_ROTATE *RadarTourne;     // données animation pour fonction "AddAnimationComponent "
UINT  uAnim_radar;                          // handle pour manipuler l'animation

Dans "clbkSetClassCap" ou fonction appellée par "clbkSetClassCap":

Code: [Select]
static UINT GrpMeshRadar[1] = {3};
RadarTourne= new MGROUP_ROTATE (0,GrpMeshRadar,1,_V(0,-1.9,-5.04),_V(1,0,0),(float)(2*PI));
uAnim_radar = CreateAnimation (1.0);
AddAnimationComponent (uAnim_radar, 0,1, RadarTourne);


Voila, ouf , terminé, nous pouvons maintenant utiliser en runtime notre animation avec la fonction:

SetAnimation();

Chaque appel positionnera le mesh , si par exemple nous aurions une mains qui s'ouvre lentement et que la position
fermée soit a 0.0 et ouverte à 1.0 nous appelerions une fois:

SetAnimation(0.0);

Et l'image suivante la main serais fermée (et le resterais jusqu'a un nouvel appel.

En pratique on va plutot l'utiliser dans  "clbkPostStep" et l'appeller à chaque image avec une légere variation de la
valeur à chaque image pour que l'animation ce fasse.

Le dernier probleme est qu'il faut utiliser une compensation du temps (sinon à 200FPS l'anim durera 1 secondes et
50FPS 4 secondes) et utiliser quelques variables logiques pour savoir quand démarrer et arreter l'animation.
Encore une fois le principe est simple mais compliqué a expliquer. Voir dans les exemples avec "DOOR_CLOSING" etc
etc.

(hésite pas si tu à plus de questions ;)


OUF ! PFFFF y a pas plus compliqué a expliqué que les anims, c'est tellement souple, on peut faire des hierarchie avec
des parties qui glissent, tournent, tout ca commandé par un seul handle et "SetAnimation"... dingue !

A++

Dan


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #15 - 18 May 2008, 20:49:14
NOTE SUR LES GROUPES DES MESH:

Chaque partie d'une mesh (dans 3dmax groupe séparé) est aussi séparé dans les mesh de martin et sont numéroté
dans l'ordre de lecture du mesh.

Ainsi si on a un mesh de deux cubes le cubes 1 sera le numéro 0 et le cube 2 le numéro 1. (On peut lire les
fichiers ".msh" avec notepad)

Il ne reste qu'a passer ce ou ces numéros pour les animer:

exemple: static UINT GrpMeshRadar[1] = {1};

Le drame c'est que dès qu'on va tripoter le mesh dans 3dmax ou autre (supprimer un groupe par exemple) il y a de
grande chances que tout les numéros (ordre des groupes) changent. Chiant mais pas grave avec trois animations,
dramatique avec comme le DGIV plus de 60 animations (on y arrive vite croyez moi)
Il faut retrouver tout les groupes (dans un mesh de 40'000 poly et 200 groupes c'est coton), leurs numéro et éditer
tout notre code. On le fait une fois mais pas deux.

C'est pour cela que j'ai modifié le script d'export de 3dmax qui me crée maintenant aussi un fichier "header" en C++
"MeshHeader.h" a inclure dans notre projet, Il contient le nom du groupe défini avec à coté le nouveau numéro réel
du groupe.

Les première lignes de ce header ont cette gueule pour le DGIV :

Code: [Select]
#define GRP_SPSiege 0
#define GRP_ANIMcpit_exter 5
#define GRP_ANIMcpit_inter 16
#define GRP_airlock 17
#define GRP_ANIMrightmain0 21
#define GRP_ANIMrightnose0 22
#define GRP_ANIMleftnosed0 23
#define GRP_ANIMnosestrut0 24
#define GRP_ANIMleft_wheel_door 25
#define GRP_ANIMleftmaind0 26
#define GRP_ANIMright_whe0 27

Du coup à notre animation on ne lui passe plus le numéro de groupe mais le nom défini:

exemple: static UINT GrpMeshRadar[1] = {GRP_SPSiege};

Et a chaque modif du mesh il suffira de copier le nouveau header et de recompiler pour que toutes les anims soient bonne automatiquement.

Pour de petit projet ce n'est pas indispensable mais pour des truc plus consequent il est impossible de bosser tout a
la main, sachez donc qu'il existe cette possibilité (mais seulement avec 3dsmax désolé)

A++

Dan



Message modifié ( 18-05-2008 20:51 )


Offline no matter

  • Legend
  • ******
  • Posts: 2826
  • Karma: 1
Reply #16 - 18 May 2008, 21:10:20
Quote
Toutes nos données sont bonne , il nous reste plus qu'a créer l'animation dans Orbiter. Pour ce faire on utilise:
CreateAnimation et AddAnimationComponent.
Il faut aussi effacer RadarTourne à la destruction, non?
MonAddon::~MonAddon ()
{
   delete RadarTourne;
}

------------

no matter.

Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #17 - 19 May 2008, 02:11:08
Quote
no matter a écrit:
Il faut aussi effacer RadarTourne à la destruction, non?
MonAddon::~MonAddon ()
{
   delete RadarTourne;
}

Oui c'est mieux, me semblais pas vital pour la bonne marche et je voulais pas alourdir... ;)
(50 octets de leak à chaque lancement faudrais quelques millions de lancements pour crasher le PC)

Papy débute je pensais le laisser prendre ces marques au début avec juste l'essentiel et "pousser" dans la
complexité et les informations au fur et à mesure de ces questions et de son avancement.

Mais perso je fuis les allocations dynamique comme la peste, dans 95% des cas elle ne servent à rien à part prendre
un gros risque de leak si on oublie une désallocation. A la place de martin je n'aurais pas fait comme cela dans la SDK.

Dan


Offline Papyref

  • Legend
  • ******
  • Posts: 5360
  • Country: France fr
  • Karma: 354
  • Je suis dans la Lune ne pas me déranger
Reply #18 - 19 May 2008, 08:56:29
Merci Dan !

Comme j'ai déjà réalisé des animations un peu sophistiquées comme le DGArm  en utilisant Spacecraft, je pense que
je vais arriver à m'en sortir avec tes conseils.
Pour l'instant je cherche seulement à réaliser ce que j'ai déjà fait sans chercher l'exploit pour comprendre les
principes sans chercher à traiter des interactions complexes.

Si je n'y arrive pas je me suicide :) J'ai d'ailleurs essayé il y a quelques jours en prenant un premier bain de mer pour
2008 avec une eau dans les 14°C !!! Ca raffermit les chairs....

:sage: Papyref


Offline DanSteph

  • Administrator
  • Legend
  • *****
  • Posts: 15407
  • Karma: 256
  • Hein, quoi !?
    • FsPassengers
Reply #19 - 19 May 2008, 09:42:55
Hésite pas à poser des questions précise, voir poster des bouts de code qui ne marchent pas.

On peut être plus utile et donner des informations plus pointues sur des points précis que de faire un tuto complet
sur tout le sujet. (il serait énorme sur les anims pour traiter tout les cas malgré que le principe soit simple)

14°C pour un type habitué à ce rafraichir en ouvrant un hublot de la station papy bar c'est de la gnognotte...
aucune crainte :)

(Par contre les caisses de bière stockées à l'exterieurs... c'est moyen la kronenbourg à -270°)

Dan


Offline Gat3rZ

  • Sr. Member
  • ****
  • Posts: 289
  • Karma: 0
Reply #20 - 19 May 2008, 13:58:13
Quote
DanSteph a écrit:
Par contre les caisses de bière stockées à l'exterieurs... c'est moyen la kronenbourg à -270°
Dan
sa se bois frais la bierre :badsmile: .



Message modifié ( 19-05-2008 13:58 )


Offline Gat3rZ

  • Sr. Member
  • ****
  • Posts: 289
  • Karma: 0
Reply #21 - 19 May 2008, 17:00:10
Au lieu de dire des bétises,
J'ai fais un système de refuel et je voudrais savoir la technique pour rendre ce type de système fps indépendant car
comme tous ce qui est dans la fonction clbkPostStep la vitesse dépend du fps...



Offline Papyref

  • Legend
  • ******
  • Posts: 5360
  • Country: France fr
  • Karma: 354
  • Je suis dans la Lune ne pas me déranger
Reply #22 - 19 May 2008, 17:03:35
J'ai créé ce groupe d'animation pour une porte. Les paramètres initiaux restent à vérifier

void MonAddon::DefineAnimations (void)
{
   static UINT GrpMeshLeftDoor[1] = {49};
   PorteOuvre = new MGROUP_ROTATE (0, GrpMeshLeftDoor,1, _V(6.7,7,0), _V(0,0,1), float(0.5*PI));
   uAnim_leftDoor = CreateAnimation (1.0);
   AddAnimationComponent (uAnim_leftDoor,0 ,1, PorteOuvre) ;
}

J'ai définit les variables en ClassVessel

   MGROUP_ROTATE *PorteOuvre;
   UINT uAnim_leftDoor;


Et comme je ne me fais pas jeter en compilant je pense que c'est bon jusque là.

C'est maintenant que je pédale. Est ce qu'il faut déclarer et utiiser cette animation dans clbkPostStep ? ou
autrement ?

J'avoue être un peu découragé après un certain nombre d'essais loupés et je pense que je vais mettre un terme à
cette expérience avant de me liquéfier le peu de méninges qui me restent !

:wall: Papyref


Offline brainstorm

  • Legend
  • ******
  • Posts: 2694
  • Karma: 0
Reply #23 - 19 May 2008, 17:45:24
Tout va bien papyref ;) pour la gestion de ta porte :

Dans ton fichier.h, tu déclares 2 variables supplémentaires:

Quote
double door_proc;
enum DoorStatus { DOOR_CLOSED, DOOR_CLOSING, DOOR_OPENING, DOOR_OPEN } door_status;

dans ton contructeur :
Quote

door_proc = 0;
door_status = DOOR_CLOSED; // si tu veux qu'elle soit fermée par défaut

dans la méthode clbkPostStep :
Quote
if (gear_status == GEAR_OPENING || gear_status == GEAR_CLOSING)
   {            
   double dg = simdt * DOOR_OPERATING_SPEED;     // double DOOR_OPERATING_SPEED = 0.5;
         
   if (door_status == DOOR_CLOSING)
      {
      if (door_proc > 0.0)
         door_proc = max (0.0, door_proc-dg);
      else                  
         door_status = DOOR_CLOSED;
      }
   else
      {
      if (door_proc < 1.0)
         door_proc = min (1.0, door_proc+dg);
      else                  
         door_status = DOOR_OPEN;
      }
   }      
   SetAnimation (uAnim_leftDoor, door_proc);
}
[/color]

Tu crées ensuite une méthode :
Quote
void taClasse::RevertDoor()
   {   
   if (door_status == DOOR_CLOSED|| door_status == DOOR_CLOSING)
      door_status = DOOR_OPENING;
   else if (door_status == DOOR_OPENING || door_status == DOOR_OPEN)
         door_status = DOOR_CLOSING;   
   }

 (déclare là dans ton .h)

et enfin, pour que ce soit effectif, dans ta méthode clbkConsumeBufferedKey :

   
Quote
if (!down)
      {
      return 0;    // Seulement pression d'une touche (pas de touche enfoncée)
      }
   
      if (KEYMOD_SHIFT (kstate))
         {
         switch (key)
            {
            case OAPI_KEY_D:    //Autrement si tu appuies sur SHIFT-D
            RevertDoor();
            return 1;
            }
         }
Pfiou  ! Fini ;)



Message modifié ( 19-05-2008 17:48 )


Offline Papyref

  • Legend
  • ******
  • Posts: 5360
  • Country: France fr
  • Karma: 354
  • Je suis dans la Lune ne pas me déranger
Reply #24 - 19 May 2008, 18:36:01
Merci,

C'est bien ce que j'avais essayé mais j'ai dû me planter dans la syntaxe.
Je reprendrai ça demain parceque ma femme me harcèle :)

:sage: Papyref