Aller au contenu

Soya/Python base 2

Un livre de Wikilivres.
# -*- indent-tabs-mode: t -*-

# Tutorial Soya.
# Copyright (C) 2001-2004 Jean-Baptiste LAMY
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


# base 2 :  gestion du temps et rotation d'un modèle 3D.

# Cette leçon est la même que [[base-1]].py excepté la rotation du modèle.

# Vous allez apprendre la gestion du temps et la rotation.

# Les fonctions basiques servant à la rotation :
#
# rotate_x : tourne dans l'axe X
# rotate_y : tourne dans l'axe Y (= dans le plan horizontal)
# rotate_z : tourne dans l'axe Z


# Importation et initialisation de Soya (voir 1ère leçon).

import sys, os, os.path, soya

soya.init()
soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))

# Création de la scène.

scene = soya.World()

# Chargement du modèle de l'épée.

sword_model = soya.Model.get("sword")


# Création de la classe servant à la rotation des Body. Soya, puisque il est entièrement orienté objet, presque 
# toutes les classes Soya peuvent être complétés.
# Ici notre classe provenant de soya.Body, et alors on peut afficher un modèle.

class RotatingBody(soya.Body):
        
        # La classe principale appelle répétitivement la méthode advance_time pour tous les objets dans la scène.
        # Pour tourner un Body, nous avons juste à modifier cette méthode.
        # Dans Soya, l'unité de temps est le "Round", un Round équivaut à 30 millisecondes (par défaut).
        # Donc l'argument de advance_time est la proportion de temps dans un round ce qui produit :
        # par exemple, 0.3 fait que 30% d'un Round s'est passé entre 2appels soit 9 millisecondes.
        
        # advance_time doit être limité pour l'animation de code mais pas pour le code de décision. Nous verrons 
        # d'autres méthodes pour ça dans Base 3.
        
        def advance_time(self, proportion):

                # Appel de advance_time. Ceci est indispensable, comme tous les objets de Soya
                # que nous avons déjà dans la méthode advance_time.
                
                soya.Body.advance_time(self, proportion)
                
                # Tourner un objet sur l'axe Y. L'angle est proportionnel car
                # le plus gros du temps a été épuisé, nous voulons tourner dans l'ordre du lissage de l'animation.                
                # Presque toutes les rotations ou les mouvements se produisent dans advance_time qui a besoin
                # d'être proportionnel.[1]
                
                self.rotate_y(proportion * 5.0)


# On fait la rotation du Body dans la scène, utilisation du modèle de l'épée.

sword = RotatingBody(scene, sword_model)

# Création de la lampe.

light = soya.Light(scene)
light.set_xyz(0.5, 0.0, 2.0)

# Création de la caméra.

camera = soya.Camera(scene)
camera.z = 3.0
soya.set_root_widget(camera)

soya.MainLoop(scene).main_loop()

[1]

# Rotates the object around Y axis. The angle is proportional to proportion because
# the more time has been spent, the more we want to rotate, in order to achieve a
# smooth animation.
# Almost every rotations or moves that occurs in advance_time should be proportional
# to proportion.