CoCalc Public Fileswww / talks / 2006-05-09-sage-digipen / tutorial / basic-4.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-4: Time management : a randomly moving caterpillar
20
21# In this lesson, we'll creates a caterpillar composed of a head (we've already done it
22# in the previous lesson ; now you understand why i have called it a 'head') and ten
23# spherish piece of body. Each piece of body follows the previous one, or the head for
24# first piece.
25
26# Run the tutorial if you don't understand well what is the caterpillar.
27
28
29# Import the Soya module.
30
31import sys, os, os.path, random, soya
32
33soya.init()
34soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))
35
36# Creates a scene.
37
38scene = soya.World()
39
41# It is identical to the Head class of lesson basic-3.py, except the class name.
42# So... no comment!
43
45  def __init__(self, parent):
47    self.speed = soya.Vector(self, 0.0, 0.0, -0.2)
48
49  def begin_round(self):
50    soya.Volume.begin_round(self)
51
52    self.rotate_lateral((random.random() - 0.5) * 50.0)
53
56
58
59
60# A CaterpillarPiece is a piece of the body of the caterpillar.
61# It follows another object -- the previous piece, or the head for the first one.
62
63class CaterpillarPiece(soya.Volume):
64
65  # The constructor takes two arguments: the parent and the previous piece of body that
66  # we must follow.
67  # Similarly to the head, we define a speed vector.
68
69  def __init__(self, parent, previous):
70    soya.Volume.__init__(self, parent, soya.Shape.get("caterpillar"))
71    self.previous = previous
72    self.speed = soya.Vector(self, 0.0, 0.0, -0.2)
73
74  def begin_round(self):
75    soya.Volume.begin_round(self)
76
77    # We rotates the caterpillar piece so as it looks toward the previous piece.
78
79    self.look_at(self.previous)
80
81    # The distance_to method returns the distance between two position.
82    # If we are too close to the previous piece of body, we set the speed's Z to 0.0,
83    # and thus the speed is a null vector : this piece no longer moves.
84
85    # Else, we reset the speed's Z to -0.2.
86
87    if self.distance_to(self.previous) < 1.5: self.speed.z =  0.0
88    else:                                     self.speed.z = -0.2
89
91
94
96
97
99
102
103# Creates 10 caterpillar piece of body.
104
106for i in range(10):
107  previous_caterpillar_piece = CaterpillarPiece(scene, previous_caterpillar_piece)
108  previous_caterpillar_piece.x = i + 1
109
110# Creates a light.
111
112light = soya.Light(scene)
113light.set_xyz(2.0, 5.0, 0.0)
114
115# Creates a camera.
116
117camera = soya.Camera(scene)
118camera.set_xyz(0.0, 15.0, 15.0)
120soya.set_root_widget(camera)
121
122soya.Idler(scene).idle()
123
124
125# For information, the caterpillar textures were done in the Gimp, and the model were
126# generated with this code (see modeling-*.py to understand it) :
127
128# import soya.sphere
129# caterpillar_material      = soya.Material(soya.Image.get("chenille.png"     ))
131# caterpillar_material     .filename = "caterpillar"
133# caterpillar_material     .save()
135
136# caterpillar      = soya.sphere.Sphere(slices = 12, stacks = 12, material = caterpillar_material)
137# caterpillar_head = soya.sphere.Sphere(slices = 12, stacks = 12, material = caterpillar_head_material)
139# caterpillar     .filename = "caterpillar"
141# caterpillar     .save()
143
144
145
146
147
148
149
150
151
152
153
154
155# XXX put this elsewhere
156
157# Lots of Soya methods have also an operator :
158#
159# Position +  Vector    => Point
161# Position >> Position   Position.vector_to (Position) => Vector
162# Position %= CoordSyst  Position.convert_to(CoordSyst)
163# Vector   *  float
164
165# Position +  Vector => Point
166
167# Position += Vector