Salut a vout !

Je viens vous voir car apres avoir été au bout de ce que je pensais etre la bonne voie pour faire ce que je veux, il faut se rendre a l'evidence que ca ne marche pas !

En gros j'ai un kinect, pour ceux qui ne savent pas c'est une camera 3D qui envoi a l'ordi les coordonées de translation XYZ des points representant mon corp (main, coude, epaule, torse, genou, tete,......), ca donne un truc un peu comme ca http://b.vimeocdn.com/ts/117/658/117658478_640.jpg

Or en 3D, pour animer le skelete d'un personnage les joints preferent etre tournés(rotation) que depalcés(translations), car sinon ca deforme pas mal le model, c'est pas fait pour quoi.

Du coup je me suis mis en tete de pondre un algo qui va me faire ca, et je penses que j'ai pas mal avancé, mieux que ca, dans la bonne voie ! Mais arrivé a la fin, j'ai des comportement erratiques. Du coup je me dis que j'ai merdé quelquepart.

Donc en gros pour l'exercice j'essaye de calculer l'angle de mon bras droit. j'ai donc les coordoné XYZ de mon epaule, et pareils pour la main.

Dans un premier temps, avec de la trigo, je transforme donc ces positions en rotations pour chaque axe avec ce code

(a : main, b : epaule);

BC = (a.x-b.x);
AB = (a.y-b.y);
AC = sqrt((AB*AB)+(BC*BC));
BD = AC - AB;
YY = atan(AB/BC)+atan(BD/BC)
X = (YY*180/PI)*2

j'ai donc X Y Z a 360°, en reapliquant ces infos a la roation d'un cube, il ne tourne pas comme mon bras. quand j'atteins des 90 ou 180° il tourne sur lui meme, change de sens, ou que sais je.

Apres des petites recherches en ligne j'ai decouvert que la 3D a besoin d'un reper en plus sinon les angles se croisent et ca fait nimporte quoi, ca s'appel le Gimbal Lock. voir article tres itneressant sur cee site meme http://jeux.developpez.com/faq/math...formations#Q34b.

Il faut donc pour regler ce probleme si j'ai bien compris, convertir les angles d'euler en quaternion, et les reconvertir en angles d'euler, avec une petite condition a un moment sensée corrigé l'erreur.

Sur l'article il y a un exemple de code, que j'ai recuperé et teste, mais mon cube ne tourne toujours pas dans le bon sens. Apres verif su un calculateur en ligne euler/quaternion/euleur, en comparant ses resultats avec les miens, il s'avere que mes resultats ne correspondent pas dans un cas, celui du Gimbal Lock (cos(Y) > 0.005 (donc Y = 90°)).

J'ai donc readapté mon code pour qu'il colle avec celui du comparateur en ligne, mais malheuresement, LE CUBE NE TOURNE TOUJOURS PAS DANS LE BON SENS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Du coup je me dis que sois, c'est la premiere partie de mon code qui calcul les angles qui foire(mais ca n'a pas l'air), sois c'est le Gimbal lock fix(et ca n'a pas l'air non plus mais je comprends moins bien), sois une troisieme option que j'ignore.

Je me tourne donc vers vous. Voila les sources (un peu modifiés mais toujours correctes) selon l'article cité plus haut. J'ai aussi celle que j'ai modifié par rapport au calculateur en ligne, mais elles sont moins lisibles ...

la partie dans if (Math.abs(C) > 0.005) a l'air de marcher,

c'est plutot celle du "else" qui qui peche normalement.

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
var RADIANS = 180/3.14159;
 
var _X = 20;
var _Y = 90;
var _Z = 100;
 
var C,X,Y,Z,RX,RY;
var cos_X,cos_Y,cos_Z,sin_X,sin_Y,sin_Z;
 
sin_Y = Math.sin(_Y/RADIANS);
cos_X = Math.cos(_X/RADIANS);
cos_Z = Math.cos(_Z/RADIANS);
sin_X = Math.sin(_X/RADIANS);
sin_Z = Math.sin(_Z/RADIANS);
cos_Y = Math.cos(_Y/RADIANS);
 
Y = -Math.asin(-sin_Y);
C = Math.cos(Y);
Y *= RADIANS;
 
if (Math.abs(C) > 0.005) {
 
		RX = (cos_X*cos_Y)/ C
		RY = -(-sin_X*cos_Y)/ C
 
		X = Math.atan2(RY,RX);
		X *= RADIANS;
 
		RX = (cos_Y*cos_Z)/ C
		RY = -(-cos_Y*sin_Z)/ C
 
		Z = Math.atan2(RY,RX);
		Z *= RADIANS;
 
}else{
 
 
	X = 0;
 
	RX = ((sin_X*sin_Y)*sin_Z)+(cos_X*cos_Z);
	RY = -(sin_X*sin_Y)*cos_Z+cos_X*sin_Z;
 
	Z = Math.atan2(RX,RY);
	Z *= RADIANS;
 
}
 
trace("x: "+X);
trace("y: "+Y);
trace("z: "+Z);
Voila j'espere qu'une bonne ame pourra m'aider en ligne,

et si quelqu'un est sur Paris et veut venir me filer un coup de main se sera avec plaisirs