2016-03-10 2 views
0

J'ai un joueur en forme de sphère qui peut se déplacer librement dans les directions x et z. Les joueurs vitesse actuelle est mémorisée dans un vecteur qui est ajouté à la position des joueurs sur chaque image:Rotation d'une matrice dans la direction d'un vecteur?

m_position += m_speed; 

J'ai aussi une matrice de rotation que je voudrais tourner dans le sens que le mouvement du joueur (Imaginez comment une balle tournerait si elle roulait sur le sol). Voici une courte vidéo pour aider à visualiser le problème: http://imgur.com/YrTG2al

Avis dans la vidéo quand je commence à se déplacer vers le haut et vers le bas (Z) par opposition à gauche et à droite (X) l'axe de rotation ne correspond plus le mouvement du joueur.

code utilisé pour produire les résultats:

glm::vec3 UP = glm::vec3(0, 1, 0); 
float rollSpeed = fabs(m_Speed.x + m_Speed.z); 
if (rollSpeed > 0.0f) { 
    m_RotationMatrix = glm::rotate(m_RotationMatrix, rollSpeed, glm::cross(UP, glm::normalize(m_Speed))); 
} 

Thankful aide

+0

rotation a besoin de deux choses: un axe de rotation et un sens de rotation. Quand vous dites "tourner la matrice dans la direction d'un vecteur", voulez-vous dire une rotation avec le vecteur comme axe de rotation? – user463035818

+0

@ tobi303 Peut-être que ma question n'était pas très claire. Fondamentalement, j'essaie de comprendre l'axe correct à utiliser lors de la rotation de la matrice, compte tenu de la vitesse actuelle des joueurs. – bapibopi

+0

peut-être un petit dessin peut aider à illustrer le problème – user463035818

Répondre

1

Votre calcul est erroné rollSpeed - par exemple, si les signes de m_Speed.x et m_Speed.z vitesse sont différents, ils seront Soustraire. Vous devez utiliser la norme de la vitesse dans le plan:

float rollSpeed = sqrt(m_Speed.x * m_Speed.x + m_Speed.y * m_Speed.y); 

Pour être plus général à ce sujet, vous pouvez réutiliser votre produit au lieu de croix. De cette façon, votre calcul est moins susceptible de se désynchroniser - quelque chose comme:

glm::vec3 rollAxis = glm::cross(UP, m_speed); 
float rollSpeed = glm::length(rollAxis); 
m_RotationMatrix = glm::rotate(m_RotationMatrix, rollSpeed, rollAxis); 
+0

Vous avez raison sur le fait que rollSpeed ​​est mal calculé, bien que je pense que le problème montré que j'ai démontré dans la vidéo réside dans le calcul du rollAxis (cross (UP, m_Speed)). Peut-être que «up» devrait varier en fonction de la rotation actuelle de la sphère. – bapibopi

+1

Vous n'avez pas dit comment vous utilisez la matrice, mais vous semblez l'utiliser dans le mauvais sens, en mettant à jour la matrice du mauvais côté ou quelque chose de comparable. Vérifiez vos hypothèses sur vos systèmes de coordonnées; par exemple, vous devrez peut-être utiliser l'inverse de 'm_RotationMatrix' pour faire pivoter votre sphère. – comingstorm

+0

inverser la matrice travaillée. Voici comment j'utilise la matrice de rotation: 'modèle glm :: mat4; modèle = glm :: translate (modèle, m_Position) * glm :: inverse (m_RotationMatrix); // définir l'uniformité du modèle dans le shader' – bapibopi

-1

Si je comprends bien, vous avez besoin d'une rotation de la matrice qui fonctionnerait dans toutes les directions de l'axe (x, y, z).

Je pense que vous devriez écrire une méthode rotate() par axe (x, y, z), vous devriez également indiquer la direction sur quel axe vos points de direction, vous devez écrire direction.x ou direction.y ou direction.z et de la matrice de rotation comprendras où le vecteur de direction est en train d'être pointé.

+0

Si je vous comprends bien (ce qui est un peu difficile, s'il vous plaît respecter la capitalisation et les mots complets), vous suggérez d'écrire une clause if pour chaque direction. C'est exactement ce que fait le code ci-dessus en utilisant le produit croisé, de manière plus générale, en travaillant avec des directions arbitraires dans le plan xz. – BDL

+0

Non non non qui a dit que si une clause est requise?!code ci-dessus ne fait que ce que l'auteur dit, quand il change le code de direction du vecteur ne fonctionne pas. Je pense qu'il devrait être plus spécifique par direction d'axe pour le vecteur de direction pointant. C'est mon opinion. –

+0

@BDL "J'ai essayé ce qui suit qui fonctionne jusqu'à ce que vous essayiez de vous déplacer dans une direction différente de celle dans laquelle vous vous êtes précédemment déplacé. (X à z ou vice versa)" Citation de l'auteur du message. –

0

rollSpeed devrait être la taille du vecteur de vitesse.

float rollSpeed = glm::length(m_Speed); 

La matrice de transformation attend un angle. L'angle de rotation dépendra de la taille de votre balle. Mais dire que c'est rayon r alors l'angle (en radians) dont vous avez besoin est

angle = rollSpeed/r;