CoCalc Public Fileswww / talks / 2006-05-09-sage-digipen / tutorial / basic-6.py
Author: William A. Stein
1# Soya 3D tutorial
2# Copyright (C) 2004 Jean-Baptiste LAMY
3#
4# This program is free software; you can redistribute it and/or modify
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
19# basic-6: Event management : a mouse-controlled caterpillar
20
21# This time, we'll use the mouse to control the caterpillar.
22
23
24# Import the Soya module.
25
26import sys, os, os.path, soya, soya.sdlconst
27
28soya.init()
29soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))
30
31# Creates a scene.
32
33scene = soya.World()
34
35# The CaterpillarHead class is very similar to the CaterpillarHead class of the previous
36# lesson.
37
39  def __init__(self, parent):
41    self.speed                  = soya.Vector(self, 0.0, 0.0, 0.0)
42    self.rotation_lateral_speed = 0.0
43    self.mouse_x                = 0
44    self.mouse_y                = 0
45
46  def begin_round(self):
47    soya.Volume.begin_round(self)
48
49    # Loops over all Soya / SDL events.
50
51    for event in soya.process_event():
52
53      # Checks for mouse motion events, and store the mouse cursor X, Y coordinates.
54
55      if event[0] == soya.sdlconst.MOUSEMOTION:
56        self.mouse_x = event[1]
57        self.mouse_y = event[2]
58
59    # Computes the mouse coordinates in 3D. Camera.coord2d_to_3d takes the X and Y mouse 2D
60    # coordinates, and an optional Z coordinates (as it canoot guess the third coordinate ;
61    # Z default to -1.0).
62
63    # Here, we use for Z the Z coordinates of the caterpillar in the camera coordinate
64    # system: we consider the mouse cursor to be at the same depth that the caterpillar.
65    # The % operator is used for coordinate system conversion:
66    #     position % coordinate_system
67    # returns position converted into coordinate_system (possibly position itself if it
68    # is already in the right coordinate system).
69
70    mouse_pos = camera.coord2d_to_3d(self.mouse_x, self.mouse_y, (self % camera).z)
71
72    # Then, converts the mouse position into the scene coordinate system, and set its Y
73    # coordinate to 0.0, because we don't want the caterpillar to start flying !
74    # (remember, Y is the upper direction).
75
76    mouse_pos.convert_to(scene)
77    mouse_pos.y = 0.0
78
79    # Computes the speed Z coordinate ; we don't want a constant speed: the farther the
80    # mouse cursor is, the faster the caterpillar moves.
81    # Thus the speed Z coordinate is the distance from the caterpillar to the mouse,
82    # and it must be negative (cause -Z is front).
83
84    self.speed.z = -self.distance_to(mouse_pos)
85
86    # Rotations toward the mouse.
87
88    self.look_at(mouse_pos)
89
93
94
95# We change CaterpillarPiece, so it can deal with the variable-speed head.
96
97class CaterpillarPiece(soya.Volume):
98  def __init__(self, parent, previous):
99    soya.Volume.__init__(self, parent, soya.Shape.get("caterpillar"))
100    self.previous = previous
101    self.speed = soya.Vector(self, 0.0, 0.0, -0.2)
102
103  def begin_round(self):
104    soya.Volume.begin_round(self)
105
106    # As the speed can be very high, we need to take into account the speed of the previous
107    # piece (the one we are moving toward).
108    # Computes the next position of the previous piece, by translating the piece by the
109    # piece's speed vector.
110
111    previous_next_pos = self.previous + self.previous.speed
112
113    # Looks toward the previous piece's next position.
114
115    self.look_at(previous_next_pos)
116
117    # Computes the speed's Z coordinate. We use the distance between this piece and the
118    # next position of the previous one, and we remove 1.5 because we want each piece
119    # to be sepaarated by 1.5 distance units.
120
121    self.speed.z = -(self.distance_to(previous_next_pos) - 1.5)
122
126
127
128# Creates a caterpillar head and 10 caterpillar piece of body.
129
132
134for i in range(10):
135  previous_caterpillar_piece = CaterpillarPiece(scene, previous_caterpillar_piece)
136  previous_caterpillar_piece.x = i + 1
137
138# Creates a light.
139
140light = soya.Light(scene)
141light.set_xyz(2.0, 5.0, 1.0)
142
143# Creates a camera.
144
145camera = soya.Camera(scene)
146camera.set_xyz(0.0, 15.0, 15.0)