pymaxwell - rotation d'un objet

Pour vous simplifier la vie
Avatar de l’utilisateur
Roch
Messages : 7576
Localisation : Marseille - France
Contact :

pymaxwell - rotation d'un objet

Message 11 mars 2013, 21:44

Salut Rodman,
un client timide me demande de poster ici pour te demander de l'aide. Si tu peux jeter ton oeil expert. merci.

le but du script faire tourner un objet dans une scène. La caméra est fixe. Ici c'est une double caméra pour une vue stéréo

# Find the rotate object
rotator = scene.getObject("rotator");
if rotator.isNull():
print('rotator is not in the scene');
return 0;
base,pivot = rotator.getBaseAndPivot();

nFrames = 4;
angle = 0;
for i in range(nFrames):
rot = rotator.getRotation();
print(degrees(rot.y()));
rot.assign(rot.x(),rot.y()+radians(angle),rot.z());
print(degrees(rot.y()));
rotator.setRotation(rot);
# Write a new frame to disk
leftEye.setActive();
framename = mxspath+'3D_CamL_'+'{0:0>4d}'.format(i)+'.mxs';
okLeft = scene.writeMXS(framename);
if okLeft == 0:
print("Error saving frame");
return 0;
else:
print("Left Cam for frame "+str(i)+" written");
rightEye.setActive();
framename = mxspath+'3D_CamR_'+'{0:0>4d}'.format(i)+'.mxs';
okRight = scene.writeMXS(framename);
if okRight == 0:
print("Error saving frame");
return 0;
else:
print("Right Cam for frame "+str(i)+" written");
# Update angle to next frame
angle = angle + 360/nFrames;
if angle > 360:
angle = angle - 360;
# Clean memory (end)
scene.freeScene();

return 1;

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 12 mars 2013, 00:49

J'ai testé le script après l'avoir nettoyé.

Du coup, j'en profite pour redire que Python n'a pas besoin de ";". Le script utilise des fonctions mathématiques qui demandent d'importer la bibliothèque math (from math import *) ce qui n'est pas écrit.

Dans la doc : http://support.nextlimit.com/display/pl ... ce/Cobject
Il y a plusieurs fonctions en noir qui ne sont pas documentés. Le script utilise l'une d'elle: la fonction getRotation, mais je ne pense pas qu'elle soit relier à l'objet. En gros passer par elle selon moi ne sert à rien.

J'ai testé avec ceci :

Code : Tout sélectionner

rotator.setRotation(Cvector(0,angle,0))
print rotator.getRotation()
Du coup je pense qu'il faut faire du calcul vectoriel, en bref des maths.

Je pense que ton client a utilisé ce script comme base : http://support.nextlimit.com/download/a ... 0015385000
Mais il a buté sur le vrai problème qui réside à trouver un moyen de faire tourner l'objet.

Avatar de l’utilisateur
lebulb
SL17
Messages : 1063

Re: pymaxwell - rotation d'un objet

Message 12 mars 2013, 15:00

Ha ba
je pensais un jour demander à Rodman un script pour faire tourner la cam autour de son pivot.
C'est pas plus simple d'ailleurs? pas le même éclairage mais bon.

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 12 mars 2013, 15:41

Oui, il y a déjà 2 scripts d'écrit pour faire tourner une caméra autour d'un objet : turnaround.py et turnaround_object.py


Concernant le problème, je vais déjà expliciter clairement ce qu'on a déjà :

Ce code :

Code : Tout sélectionner

base,pivot = rotator.getBaseAndPivot()
print base, pivot
donne :

Code : Tout sélectionner

origin: x = 0.646136, y = 0.710825, z = 0.000000
xAxis:  x = 0.803629, y = 0.595130, z = 0.000000
yAxis:  x = -0.595130, y = 0.803629, z = 0.000000
zAxis:  x = 0.000000, y = 0.000000, z = 1.000000

origin: x = 0.000000, y = 0.000000, z = 0.000000
xAxis:  x = 1.000000, y = 0.000000, z = 0.000000
yAxis:  x = 0.000000, y = 1.000000, z = 0.000000
zAxis:  x = 0.000000, y = 0.000000, z = 1.000000
origin c'est un point dans l'espace qui est le centre de l'objet
xAxis, yAxis, zAxis c'est la position d'un point dans l'espace du repère du pivot.

Si on veut tourner autour de la droite formée par les points origin et zAxis alors il faut travailler avec les point xAxis et yAxis.

Le problème revient à trouver la position des points xAxis et yAxis en fonction de l'angle de rotation.

Avatar de l’utilisateur
luluboss
SL18
Messages : 1120
Contact :

Re: pymaxwell - rotation d'un objet

Message 12 mars 2013, 16:05

Je vais surement poser une question bête, mais... pourquoi ne pas mettre juste deux clés d'animations ? :oops:

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 12 mars 2013, 16:25

Il n'y a pas d'animation dans Maxwell Studio.

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 13 mars 2013, 13:51

Le script turnaround_object.py fait bien tourner un objet mais j'ai testé et chez moi ça ne tourne pas dans le plan XZ (l'axe Y c'est l'axe "hauteur")

Cette partie du code devrait faire le boulot de la rotation :

Code : Tout sélectionner

		# Rotate base around Y axis.
		angle_s = sin(radians(angle))
		angle_c = cos(radians(angle))

		newAxis = Cvector()
		x = base.xAxis.x()*angle_c + base.zAxis.x()*angle_s
		y = base.xAxis.y()*angle_c + base.zAxis.y()*angle_s
		z = base.xAxis.z()*angle_c + base.zAxis.z()*angle_s
		newAxis.assign(x,y,z)
		base.xAxis = newAxis

		x = base.zAxis.x()*angle_c - base.xAxis.x()*angle_s
		y = base.zAxis.y()*angle_c - base.xAxis.y()*angle_s
		z = base.zAxis.z()*angle_c - base.xAxis.z()*angle_s
		newAxis.assign(x,y,z)
		base.zAxis = newAxis
		
		base.xAxis.normalize()
		base.zAxis.normalize()

		object.setBaseAndPivot(base,pivot)
Si vous regardez rapidement cette page : http://fr.wikipedia.org/wiki/Rotation_vectorielle ou celle-ci http://fr.wikipedia.org/wiki/Matrice_de_rotation
Vous vous apercevez que le script au dessus utilise la rotation matricielle plane (le vecteur Y étant fixe, il n'y a pas besoin d'y toucher) :

Image


Il n'y a plus qu'à trouver ce qui cloche dans cette partie du script et le tour est joué.
Cela embrouille un peu le fait que l'axe "hauteur" soit Y dans Maxwell Studio.

Pour connaître à quoi sert la fonction normalize dans le script je vous conseille de lire cette page : http://www.siteduzero.com/informatique/ ... malisation

Avatar de l’utilisateur
Roch
Messages : 7576
Localisation : Marseille - France
Contact :

Re: pymaxwell - rotation d'un objet

Message 13 mars 2013, 15:41

merci Rodman champion comme d'hab.

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 13 mars 2013, 17:26

Le code semble être cohérent au vu des valeurs :

Code : Tout sélectionner

xAxis:  x = 1.000000, y = 0.000000, z = 0.000000
yAxis:  x = 0.000000, y = 1.000000, z = 0.000000
zAxis:  x = 0.000000, y = 0.000000, z = 1.000000

x = -0.716086, y = 0.000000, z = 0.698012
x = 0.809017, y = 0.000000, z = 0.587785
x = 0.000000, y = 1.000000, z = 0.000000
---------------------------
x = -0.998117, y = 0.000000, z = 0.061335
x = 0.254999, y = 0.000000, z = 0.966941
x = 0.000000, y = 1.000000, z = 0.000000
---------------------------
x = -0.804314, y = 0.000000, z = -0.594204
x = -0.421516, y = 0.000000, z = 0.906821
x = 0.000000, y = 1.000000, z = 0.000000
---------------------------
x = -0.236988, y = 0.000000, z = -0.971513
x = -0.904212, y = 0.000000, z = 0.427084
x = 0.000000, y = 1.000000, z = 0.000000
---------------------------
Sur l'axe Z et X on a bien la valeur 0 qui montre bien que les vecteurs sont dans le plan ZX.
Sur l'axe Y on a bien le vecteur qui ne bouge pas de son axe.

Le problème viendrait-il de Maxwell Studio quand il reconvertit les coordonnées en angles ?
Il y aussi un problème sur certaines scènes (contenant 1 seul objet) où l'objet ne tourne pas du tout... :(

Quelqu'un a une idée ?


De rien Roch. :mrgreen:

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 13 mars 2013, 17:54

Voici le code pour tester :

Code : Tout sélectionner

from pymaxwell import *
from math import *

def turnaround_object(scene,objectName,nFrames,outPath,outName):
	
	# Get the object to rotate
	object = scene.getObject(objectName)
	
	if object.isNull():
		print(objectName+' is not in the scene')
		return 0

	# Checks whether the output path exists
	if not os.path.exists(outPath):
		# Create it
		os.mkdir(outPath)
	
	# Read object base and pivot
	base,pivot = object.getBaseAndPivot()
	print base
	
	# Rotate 360 degrees over nFrames frames in plane XZ
	angle = 360.0 / nFrames
	for i in range(nFrames):
		
		# Rotate base around Y axis.
		angle_s = sin(radians(angle))
		angle_c = cos(radians(angle))

		newAxis = Cvector()
		
		x = base.xAxis.x()*angle_c + base.zAxis.x()*angle_s
		y = base.xAxis.y()*angle_c + base.zAxis.y()*angle_s
		z = base.xAxis.z()*angle_c + base.zAxis.z()*angle_s
		newAxis.assign(x,y,z)
		base.xAxis = newAxis

		
		x = base.zAxis.x()*angle_c - base.xAxis.x()*angle_s
		y = base.zAxis.y()*angle_c - base.xAxis.y()*angle_s
		z = base.zAxis.z()*angle_c - base.xAxis.z()*angle_s
		newAxis.assign(x,y,z)
		base.zAxis = newAxis

		
		base.xAxis.normalize()
		base.zAxis.normalize()
		
		print base.zAxis
		print base.xAxis
		print base.yAxis
		print "---------------------------"

		# Set new camera position, target and up vector
		object.setBaseAndPivot(base,pivot)
		
		# Write a new frame to disk
		framename = outPath+'/'+outName+'{0:0>4d}'.format(i)+'.mxs'
		ok = scene.writeMXS(framename)
		if ok == 0:
			print("Error saving frame " + framename)
			return 0
	
	scene.freeScene()	
	return 1

def turnaround_object_test():
	mxs = Cmaxwell(mwcallback)
	if mxs.readMXS('e:/knot.mxs'): ### nom de la scène
		if turnaround_object(mxs,'Knot',3,'e:/output','object_turn'): ### nom de l'objet, nombre de frame, dossier de sortie, nom des fichiers de sortie
			return 1
		else:
			print("Error")
	else:
		print("Error reading scene from disk")
	return 0

turnaround_object_test()

Avatar de l’utilisateur
Roch
Messages : 7576
Localisation : Marseille - France
Contact :

Re: pymaxwell - rotation d'un objet

Message 15 mars 2013, 10:14

je crois que j'avais déjà posé la question mais pourquoi on n'utilise pas le getrotation ?

tu vois un truc plutot comme ça :

Code : Tout sélectionner

  # Get rotation
   rotation = object.getRotation()
   print "rotation"
   print rotation.x()
   print rotation.y()

   # Rotate 360 degrees over nFrames frames in plane XZ
   angle = 360.0 / nFrames
   for i in range(nFrames):
      
      # Rotate base around Y axis.
      newRotation = Cvector()
      x = rotation.x()
      y = rotation.y()+angle*i
      z = rotation.z()
      newRotation.assign(x,y,z)

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 15 mars 2013, 11:16

J'avais testé ceci au début :

Code : Tout sélectionner

rotator.setRotation(Cvector(0,angle,0))
print rotator.getRotation()
La fonction setRotation modifie bien l'angle car getRotation ensuite montre bien la modification. Le problème c'est qu'en enregistrant un mxs ça n'a pas l'air d'être pris en compte.

Dans ton code si je ne m'abuse il manque une ligne pour appliquer à l'objet la nouvelle valeur de rotation sur l'axe Y, non ?

Si tu veux demander à un développeur de chez Maxwell ce que veux dire dans la doc à coté de getRotation "Used by Maxwell Studio (not needed for rendering).", je suis tout ouïe !

Avatar de l’utilisateur
Roch
Messages : 7576
Localisation : Marseille - France
Contact :

Re: pymaxwell - rotation d'un objet

Message 15 mars 2013, 11:33

Dans ton code si je ne m'abuse il manque une ligne pour appliquer à l'objet la nouvelle valeur de rotation sur l'axe Y, non ?
oui je pensais que c'était object.setRotation(newRotation) mais ça n'a pas l'air de marcher.
Si tu veux demander à un développeur de chez Maxwell ce que veux dire dans la doc à coté de getRotation "Used by Maxwell Studio (not needed for rendering).", je suis tout ouïe !
j'ai été aussi assez surpris.

Avatar de l’utilisateur
Rodman
SL17
Messages : 1055

Re: pymaxwell - rotation d'un objet

Message 15 mars 2013, 11:50

Dans la doc ici : http://support.nextlimit.com/display/pl ... nitialized

Il y a des informations supplémentaires mais je n'arrive pas à comprendre à quoi sert isPosRotScaleInitialized qui retourne une valeur booléenne. En quoi cette fonction est-elle utile ? :?

Avatar de l’utilisateur
Roch
Messages : 7576
Localisation : Marseille - France
Contact :

Re: pymaxwell - rotation d'un objet

Message 20 mars 2013, 16:33

en fait ça marche mais uniquement au rendu pas dans Studio...

Répondre