IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Boost C++ Discussion :

Crash avec boost::function


Sujet :

Boost C++

  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut Crash avec boost::function
    Bonsoir !

    Je dispose d'une classe de caméra qui peut mettre à jour la position de la camera de trois manières différentes, selon le type de caméra choisie. J'ai pensé au début à faire trois if :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (typeCamera1)
    {
    //
    }
    else if (typeCamera2)
    {
    //
    }
    else
    {
    //
    }
    Toutefois ces fonctions étant assez longues, cela m'aurait fait une fonction UpdatePosition() très très longue. J'ai donc pensé à faire un pointeur de fonction qui appelerait automatiquement la bonne fonction.

    Voici donc la signature de cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::function<void ()> updatePositionFunction;
    (variable membre privée)

    Dans le constructeur de la classe, j'attribue la fonction par défaut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    updatePositionFunction = boost::bind(&Camera::UpdatePositionFPS, this);
    Tout ce code compile correctement, le problème arrive avec la fonction UpdatePosition, qui doit appeler donc la bonne fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void UpdatePosition ()
    {
       updatePositionFunction; // Compile, mais n'appelle pas la fonction   UpdatePositionFPS
     
       updatePositionFunction(); // Compile, mais crash dès le début de l'application
    }
    D'autre part, est-il possible de traduire ce code sans utiliser boost (qu'avec la STL), tout en gardant une syntaxe pas trop dégueue ?

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Il faut que tu testes l'objet fonction avant de l'appeler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if( updatePositionFunction )
      updatePositionFunction();
    edit: cela dit non ça devrait être initialisé puisque tu le fais dans le constructeur...

    Sinon non je ne pense pas qu'il y ait une manière simple de parvenir à la même chose sans Boost.

    MAT.

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    2e tentative...

    Ca là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::function<void ()> updatePositionFunction;
    Personnellement je l'écris plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::function0<void> updatePositionFunction;
    Essaye peut-être pour voir ?

    MAT.

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    je pense qu'il y a des façons de faire beaucoup plus simple, et plus orientée objet.
    Par exemple, surcharger tout simplement ta fonction updatePosition. Ou encore faire en sorte qu'updatePosition soit une fonction membre de l'interface Camera, cette interface étant implémentée pour chaque type de caméra.

    Ou alors il y a un truc que je n'ai pas compris...
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  5. #5
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    boost::function<void ()> updatePositionFunction;
    et
    boost::function0<void> updatePositionFunction;

    sont identiques d'après la doc de boost, juste que la première écriture est l'écriture recommandée, et la seconde une qui est plus portable, visiblement.

    je pense qu'il y a des façons de faire beaucoup plus simple, et plus orientée objet.
    Par exemple, surcharger tout simplement ta fonction updatePosition. Ou encore faire en sorte qu'updatePosition soit une fonction membre de l'interface Camera, cette interface étant implémentée pour chaque type de caméra.

    Ou alors il y a un truc que je n'ai pas compris...
    Je ne pourrais pas surcharger ma fonction, vu qu'elles ont le même prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void UpdatePositionFPS ();
    void UpdatePositionFreeFly ();
    void UpdatePosition6DOF ();
    Quant à faire de l'héritage, j'aimerais éviter, j'aimerais garder cette classe assez compacte, et pas dériver trois classes juste pour une seule fonction :/. Là j'avais trouvé un moyen assez classe de régler ce problème, avec un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void SetMode (CAMERA_TYPE type)
    {
       if (type == FPS)
          updatePositionFunction = boost::bind(&Camera::UpdatePositionFPS,               this);
       else if (type == FREEFLY)
          updatePositionFunction = boost::bind(&Camera::UpdatePositionFreeFly, this);
       else
          updatePositionFunction = boost::bind(&Camera::UpdatePosition6DOF, this);
    }
    Et hop, après j'appelle la fonction UpdatePosition indéferemment, qui appelera directement la bonne fonction. Ca m'évite de faire trois ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void SetMode (CAMERA_TYPE type)
    {
       if (type == FPS)
          UpdatePositionFPS();
       else if (type == FREEFLY)
          UpdatePositionFreeFly();
       else
          UpdatePosition6DOF();
    }
    et d'avoir à faire à chaque fois des if qui, vraisemblablement, ne changeront qe très peu souvent au cours du programme.

    Mat007 >
    edit: cela dit non ça devrait être initialisé puisque tu le fais dans le constructeur...
    Oui oui, j'allais quand même pas me faire avoir si facilement

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Il n'existe pas de manière plus simple à ma connaissance.
    Ce sera toujours, dans le meilleur des cas, équivalent.

    En débuggant, tu obtiens quoi comme infos sur
    - le boost::function
    - l'endroit exact où s'arrête le programme (l'appel de la fonction ou le code qu'elle contient ?)
    ?

  7. #7
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    l'endroit exact où s'arrête le programme
    Le programme s'arrête ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void UpdatePosition ()
    {
       updatePositionFunction; // Compile, mais n'appelle pas la fonction   UpdatePositionFPS
     
       updatePositionFunction(); // Compile, mais crash dès le début de l'application
    }
    Dans le premier cas, pas de crash, mais la fonction UpdatePositionFPS n'est pas appelée. Dans le second cas, le programme crash, et visiblement la fonction n'est pas appelée.

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Il faut utiliser la deuxième syntaxe pour appeler ta fonction.

    Ton crash est du à quelque chose qui précède cet appel.
    Tu n'as pas un bon débugger sous la main ?

  9. #9
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Je n'ai jamais réussi à me servir d'un débuggeur. En effet il me semble bien que ce soit la deuxième qui soit correcte. De toute façon j'ai pas 50 lignes, en la commentant, ça plante pas, en la décommentant, ça plante.

  10. #10
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Il faudrait que tu apprennes à te servir des debuggers

    Sinon c'est certain c'est la deuxième syntaxe.

    Ensuite, mets un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::cout << "Entrée dans la fonction";
    en première ligne de ta fonction, pour voir si elle est effectivement appelée.
    C'est du debug manuel ça

  11. #11
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Il faudrait que tu apprennes à te servir des debuggers
    Oui, je sais... Faudrait vraiment que je m'y plonge.

    Sinon c'est certain c'est la deuxième syntaxe.
    Oui oui, c'est sûr.

    Ensuite, mets un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::cout << "Entrée dans la fonction";
    en première ligne de ta fonction, pour voir si elle est effectivement appelée.
    C'est du debug manuel ça
    Je te confirme, elle ne semble pas appeler. Si ça peut aider, je vais mettre tout le code, et je vous mets en rouge les choses qui concernent boost::function :

    Camera.hpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    #ifndef CAMERA_HPP
    #define CAMERA_HPP
    
    /// --------------------------------------------------------------------------------------
    ///
    /// Headers
    ///
    /// --------------------------------------------------------------------------------------
    #include <string> // The string class
    #include <map> // For STL map
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    #include <SFML/Graphics.hpp>
    
    #include "../Math/Matrix4.hpp" // It also includes Math/Vector3.hpp
    
    namespace Kanin
    {
    	enum CAMERA_TYPE {FPS = 0, FREE_FLY, SIX_DOF};
    
    	class Camera
    	{
    		/// Two typedefs. The first map holds a string which is the name of the action (for example
    		/// "Left", "Right"), while the second one is the SFML code (for exemple "sf::Key::Left").
    		/// The second map holds a SFML code and a boolean which indicates if the key is pressed
    		/// or not. This way, the user can specify his/her own configuration
    		typedef std::map<std::string, sf::Key::Code> KeyConfig;
    		typedef std::map<sf::Key::Code, bool> KeyStates;
    
    		public:
    			/// -----------------------------------------------------------------------------
    			///
    			/// Default constructor, do nothing
    			///
    			/// -----------------------------------------------------------------------------
    			Camera ();
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// Set the position of the camera
    			///
    			/// -----------------------------------------------------------------------------
    			void SetPosition (const Vector3d & position_);
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// This function gets input from mouse and keyboard, and creates a view matrix
    			/// that can be passed to OpenGL easily
    			///
    			/// -----------------------------------------------------------------------------
    			void UpdateFromInput (sf::RenderWindow & app_);	
    			
    			/// -----------------------------------------------------------------------------
    			///
    			/// Return the position of the camera
    			///
    			/// -----------------------------------------------------------------------------
    			inline const Vector3d & GetPosition () const;
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// Return the view matrix
    			///
    			/// -----------------------------------------------------------------------------
    			inline const Matrix4d & GetViewMatrix ();
    
    		private:
    			/// -----------------------------------------------------------------------------
    			///
    			/// This function must be called by UpdateFromInput. It updates the camera
    			/// orientation given the positions of the mouse
    			///
    			/// -----------------------------------------------------------------------------
    			void UpdateOrientation (const int mouseX_, const int mouseY_, const int halfWidth_,
    											const int halfHeight_);
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// This function must be called by UpdateFromInput. It calls the function that
    			/// will update the position given the user choice (FPS, FreeFly or 6DOF)
    			///
    			/// -----------------------------------------------------------------------------
    			void UpdatePosition ();
    			
    			/// -----------------------------------------------------------------------------
    			///
    			/// This function must be called by UpdateFromInput. It updates the position of
    			/// the camera given a FPS camera
    			///
    			/// -----------------------------------------------------------------------------
    			void UpdatePositionFPS ();
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// This function must be called by UpdateFromInput. It updates the position of
    			/// the camera given a Free-Fly camera
    			///
    			/// -----------------------------------------------------------------------------
    			void UpdatePositionFreeFly ();
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// This function must be called by UpdateFromInput. It updates the position of
    			/// the camera given a six degrees of freedom camera
    			///
    			/// -----------------------------------------------------------------------------
    			void UpdatePosition6DOF ();
    
    			/// -----------------------------------------------------------------------------
    			///
    			/// Construct the view matrix with the orientation and the position
    			///
    			/// -----------------------------------------------------------------------------
    			void ConstructViewMatrix ();
    
    		private:
    			Vector3d position; // The position of the camera
    			Vector3d right, up, forward; // Three rotation vectors
    			Vector3d rightMove, forwardMove; // Two moving vectors
    			Matrix4d viewMatrix; // The view matrix
    
    			double angleAboutRight, angleAboutUp; // How far we've rotated around each vector
    
    			double mouseSensibility; // Higher the value is, slower the rotations are
    			double movementsSpeed; // Higher the value is, quicker the camera moves
    
    			bool hasMoved; // If the camera hasn't moved since the last frame, don't do it again
    
    			KeyConfig keyConfig; // Key configuration (normally load from a file)
    			KeyStates keyStates; // The state of each key
    
    			boost::function<void ()> updatePositionFunction; // Call the appropriate update position function
    	};
    
    	// Return the position of the camera
    	inline const Vector3d & Camera::GetPosition () const
    	{
    		return position;
    	}
    
    	// Return the view matrix
    	inline const Matrix4d & Camera::GetViewMatrix ()
    	{
    		// We first construct the matrix if neither the position nor
    		// the orientation has moved
    		if (hasMoved)
    		{
    			ConstructViewMatrix ();
    			hasMoved = false;
    		}
    
    		return viewMatrix;
    	}
    
    };
    
    #endif // CAMERA_HPP
    Camera.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    // Kanin Engine - Camera class
    // Author : Gallego Michaël
    // Date : 2007-01-12
    // Description : Implementation file
    
    #include "Camera.hpp"
    using namespace Kanin;
    
    // Default constructor, do nothing
    Camera::Camera ()
       : position (0.0, 0.0, 0.0), // The position is at the origin
    	  right (1.0, 0.0, 0.0), // The positive X-axis to the right
    	  up (0.0, 1.0, 0.0), // The positive Y-axis up
    	  forward (0.0, 0.0, -1.0), // The camera is facing down the negative Z-axis
    	  rightMove (0.0, 0.0, 0.0), // The quantity that will be added when moving on one side
    	  forwardMove (0.0, 0.0, 0.0), // The quantity that will be added when moving forward or backward
    	  viewMatrix (), // The view matrix is set to the identity
    	  angleAboutRight (0.0), // Nor around the right vector
    	  angleAboutUp (0.0), // And nor around the up vector ^_^
    	  mouseSensibility (10.0), // Set mouse sensibility to 10.0
    	  movementsSpeed (1.0), // Set movementsSpeed to 1.0
    	  hasMoved (false) // The camera hasn't moved because it's just beeing created :D
    {
    	// Initialisation of the key configuration with default data
    	keyConfig.insert (std::make_pair ("Left", sf::Key::Left));
    	keyConfig.insert (std::make_pair ("Right", sf::Key::Right));
    	keyConfig.insert (std::make_pair ("Forward", sf::Key::Up));
    	keyConfig.insert (std::make_pair ("Backward", sf::Key::Down));
    
    	// Initialisation of the state of each keys
    	keyStates.insert (std::make_pair (keyConfig["Left"], false));
    	keyStates.insert (std::make_pair (keyConfig["Right"], false));
    	keyStates.insert (std::make_pair (keyConfig["Forward"], false));
    	keyStates.insert (std::make_pair (keyConfig["Backward"], false));
    
    	// The default camera type is a FPS camera
    	updatePositionFunction = boost::bind(&Camera::UpdatePositionFPS, this);
    }
    
    // Set the position of the camera
    void Camera::SetPosition (const Vector3d & position_)
    {
    	position = position_;
    	hasMoved = true;
    }
    
    // This function gets input from mouse and keyboard
    void Camera::UpdateFromInput (sf::RenderWindow & app_)
    {
    	// Get a reference to the input manager associated to our window, and store it for later use
       const sf::Input & Input = app_.GetInput();
    			
    	// ----------------------------------- ROTATION -----------------------------------	
    
    	// This function gets the position of the mouse
    	int mouseX = Input.GetMouseX();
    	int mouseY = Input.GetMouseY();
    	int halfWidth = app_.GetWidth() / 2;
    	int halfHeight = app_.GetHeight() / 2;
    	
    	// Call the function that updates the orientation
    	UpdateOrientation (mouseX, mouseY, halfWidth, halfHeight);
    	
    	// Set the mouse position to the center of the screen, so that the mouse cursor will
    	// never be outside the screen
    	app_.SetCursorPosition (halfWidth, halfHeight);
    
    	// ------------------------------------- MOVE -------------------------------------
    
    	// Update the state of each keys
    	KeyStates::iterator itEnd = keyStates.end();
    	for (KeyStates::iterator it = keyStates.begin() ; it != itEnd ; ++it)
    		it->second = Input.IsKeyDown (it->first);
    
    	// Call the function that updates the position of the camera
    	UpdatePosition ();		
    }
    
    // This function must be called by UpdateFromInput. It updates the camera
    // orientation given the positions of the mouse
    void Camera::UpdateOrientation (const int mouseX_, const int mouseY_,
    										  const int halfWidth_, const int halfHeight_)
    {
    	// If the mouse has moved on the x-axis, so we make a rotation around the
    	// up axis (y-axis)
    	if ((mouseX_ - halfWidth_) != 0)
    	{
    		angleAboutUp += (mouseX_ - halfWidth_) / mouseSensibility;
    	
    		// Clamp the angle so that it doesn't be superior to 360.0 degrees or
    		// inferior to 0.0 degrees
    		if (angleAboutUp < 0.0)
    			angleAboutUp += 360.0;
    		else if (angleAboutUp >= 360.0)
    			angleAboutUp -= 360.0;
    
    		hasMoved = true;
    	}
    
    	// If the mouse has moved on the y-axis, so we make a rotation around the
    	// right axis (x-axis)
    	if ((mouseY_ - halfHeight_) != 0)
    	{
    		angleAboutRight += (mouseY_ - halfHeight_) / mouseSensibility;
    		
    		// Clamp the angle so that the camera doesn't make an all turn around
    		// the x-axis :p
    		if (angleAboutRight < -90.0)
    			angleAboutRight = -90.0;
    		else if (angleAboutRight > 90.0)
    			angleAboutRight = 90.0;
    
    		hasMoved = true;
    	}
    	
    	// Some trig computations
    	double sp = std::sin(DegToRad(-angleAboutRight));
       double cp = std::cos(DegToRad(-angleAboutRight));
       double sy = std::sin(DegToRad(-angleAboutUp));
       double cy = std::cos(DegToRad(-angleAboutUp));
       
    	// Set the rotations around the right and forward vector...
       right.Set (cy, 0.0, -sy);
       forward.Set (sy * cp, -sp, cy * cp);
    
    	// And the moving vectors
    	forwardMove.Set (sy, sy, cy);
    	rightMove = right;
    
    	// The up vector is just the vector perpendicular to the forward vector
    	// and the right vector
       up = Cross (forward, right);	
    }
    
    // This function must be called by UpdateFromInput. It calls the function that
    // will update the position given the user choice (FPS, FreeFly or 6DOF)
    void Camera::UpdatePosition ()
    {
    	updatePositionFunction();
    }
    			
    // This function must be called by UpdateFromInput. It updates the position of
    // the camera given a FPS camera
    void Camera::UpdatePositionFPS ()
    {
    	if (keyStates[keyConfig["Left"]])
    	{
    		position -= rightMove * movementsSpeed;
    		hasMoved = true;
    	}
    
    	if (keyStates[keyConfig["Right"]])
    	{
    		position += rightMove * movementsSpeed;
    		hasMoved = true;
    	}
    
    	if (keyStates[keyConfig["Forward"]])
    	{
    		position -= forwardMove * movementsSpeed;
    		position.y = 0.0;
    		hasMoved = true;
    	}
    
    	if (keyStates[keyConfig["Backward"]])
    	{
    		position += forwardMove * movementsSpeed;
    		position.y = 0.0;
    		hasMoved = true;
    	}
    }
    
    // This function must be called by UpdateFromInput. It updates the position of
    // the camera given a Free-Fly camera
    void Camera::UpdatePositionFreeFly ()
    {
    	if (keyStates[keyConfig["Left"]])
    	{
    		position -= rightMove * movementsSpeed;
    		hasMoved = true;
    	}
    
    	if (keyStates[keyConfig["Right"]])
    	{
    		position += rightMove * movementsSpeed;
    		hasMoved = true;
    	}
    
    	if (keyStates[keyConfig["Forward"]])
    	{
    		position -= forwardMove * movementsSpeed;
    		hasMoved = true;
    	}
    
    	if (keyStates[keyConfig["Backward"]])
    	{
    		position += forwardMove * movementsSpeed;
    		hasMoved = true;
    	}
    }
    
    // This function must be called by UpdateFromInput. It updates the position of
    // the camera given a six degrees of freedom camera
    void Camera::UpdatePosition6DOF ()
    {
    	// A faire, parceque un peu long
    }
    
    // Construct the view matrix with the orientation and the position
    void Camera::ConstructViewMatrix ()
    {
    	// First set the orientation given the quaternion
    	viewMatrix.Set (right.x, right.y, right.z, -Dot (right, position),
    						 up.x, up.y, up.z, -Dot (up, position),
    						 forward.x, forward.y, forward.z, -Dot (forward, position),
    						 0.0, 0.0, 0.0, 1.0);
    }

  12. #12
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Personne n'a d'idée ?

  13. #13
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Fais un code minimal qui reproduit le problème qu'on puisse le tester pour voir ?

    MAT.

  14. #14
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Hum... C'est pas clair. J'ai écrit ce code minimal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    class Foo
    {
    	public:
    		// Constructeur
    		Foo ()
    		{
    			// Initialise le pointeur de fonction à la fonction A
    			func = boost::bind(&Foo::A, this);
    		}
     
    		// Fonction A
    		void A ()
    		{
    			std::cout << "A est appele ?";
    		}
     
    		// Fonction B
    		void B ()
    		{
    			std::cout << "B est appele";
    		}
     
    		// Fonction qui appelle la fonction adéquate
    		void CallFunction ()
    		{
    			// Devrait appeler A
    			func();
    		}
     
    	private:
    		boost::function<void ()> func; // Identique à boost::function0<void> func
     
    };
     
    int main()
    {
    	Foo object;
    	object.CallFunction();
     
    	return EXIT_SUCCESS;
    }
    et là, ça fonctionne . Très étonnant. Pourtant j'ai juste recopié le cas de l'autre .

    EDIT : j'avoue ne pas comprendre. Dans mon main, mon objet Camera est une variable globale. Là, je créé un autre objet Camera non globale, sans rien appeler d'autre que le constructeur, et là ça marche .

    EDIT 2 : bon, tout en gardant mon unique variable globale, et en incluant une fonction Bind en plus qui ne refait que ce que le constructeur fait (c'est à dire ça : updatePositionFunction = boost::bind(&Camera::UpdatePositionFPS, this);

    Et en appelant cette fonction Bind dès le début, plus de soucis, comme si cela plantait dans le constructeur .

    EDIT 3 : bon, encore autre chose. Sans aucune fonction bind, si je définit le constructeur DIRECTEMENT dans la classe, comme dans le petit exemple plus haut, ça marche. Si je définie le constructeur inline et que je définie le constructeur dans le fichier hpp mais en dehors de la classe, ça marche aussi. Par contre dès que je définie le constructeur dans le .cpp, ça plante .

    Est-ce un soucis de boost ?

  15. #15
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Je dois avouer que je ne comprends rien du tout à ce problème. J'ai refait un autre code minimal en séparant fichier d'en-tête et fichier d'implémentation, sans aucune fonction inline, avec une variable globale, et là ça fonctionne. Par contre, quand c'est mon programme, ça plante ...

    EDIT : bon, j'ai refait des tests, et ça vient peut-être de SFML... Je ne veux pas l'accuser direct, mais c'est bizarre. En effet, j'ai fait un petit test dès l'execution du programme, dans les premières lignes. J'ai testé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Camera myCamera; // Variable globale (juste globale pour la facilité ici)
     
    int main()
    {
       // Ici, le constructeur de Camera est déjà appelé
       myCamera.UpdatePosition; // Cette fonction appelle juste l'objet de boost
    }
    Dans ce cas là, la bonne fonction (UpdatePositionFPS) est bien appelée. Par contre, si je change en faisant ça :

    sf::RenderWindow App;
    Camera myCamera;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main()
    {
    	// On commence par créer une fenêtre et un contexte valide pour OpenGL
    	App.Create (sf::VideoMode (800, 600), "Hola a todos");
    	App.ShowMouseCursor (false);
    	App.SetFramerateLimit (60);
     
    	myCamera.UpdatePosition();
    }
    Là, ça ne fonctionne plus, et la fonction n'est pas appelée. Je vais essayer de me renseigner auprès de Laurent voir s'il n'y a pas quelque chose qui coince.

    EDIT 2 : ok, j'ai fait un code minimal, le conflit vient bien avec SFML. Je me renseigne auprès de Laurent.

  16. #16
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Bon, j'ai résolu le soucis... C'était évidemment de ma faute... En fait, j'utilise une version bêta de la SFML, et le dossier Include n'était pas à jour, et il fallait utiliser le dossier src, qui contenait les headers mis à jour, maintenant ça marche.

    Bref, tout ça à cause de ça :p.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 19
    Dernier message: 16/09/2008, 11h44
  2. [boost] Problème avec boost::function
    Par Bakura dans le forum Boost
    Réponses: 3
    Dernier message: 22/03/2007, 20h08
  3. probleme de compilation avec boost
    Par doof dans le forum Bibliothèques
    Réponses: 7
    Dernier message: 07/06/2005, 21h38
  4. Calculer un inverse de matrice avec boost?
    Par Clad3 dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 02/06/2005, 18h38
  5. probleme avec boost et devcpp
    Par Krost dans le forum Dev-C++
    Réponses: 12
    Dernier message: 02/01/2005, 19h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo