~jtaylor/ubuntu/oneiric/soya/fix-780305

« back to all changes in this revision

Viewing changes to tutorial/lesson-104.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Dequènes (Duck)
  • Date: 2005-01-30 09:55:06 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050130095506-f21p6v6cgaobhn5j
Tags: 0.9.2-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Soya 3D tutorial
2
 
# Copyright (C) 2001-2002 Bertrand 'blam!' LAMY
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
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
 
# ---------------------
20
 
# Lesson 104: Landscape
21
 
# ---------------------
22
 
 
23
 
# This lesson shows how to make a landscape (also known as heightmap)
24
 
 
25
 
import random, os, os.path, sys, time
26
 
 
27
 
import soya.model
28
 
import soya.soya3d
29
 
import soya.land
30
 
 
31
 
 
32
 
soya.init()
33
 
 
34
 
data_dir = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "data")
35
 
 
36
 
soya.model.Image   .PATH = os.path.join(data_dir, "images")
37
 
soya.model.Material.PATH = os.path.join(data_dir, "materials")
38
 
soya.soya3d.World  .PATH = os.path.join(data_dir, "worlds")
39
 
soya.model.Shape   .PATH = os.path.join(data_dir, "shapes")
40
 
 
41
 
# Create a world
42
 
world = soya.soya3d.World()
43
 
 
44
 
# Add a light
45
 
light = soya.soya3d.Light(world)
46
 
light.set_xyz(0.0, 15.0, 0.0)
47
 
 
48
 
 
49
 
# Land creation
50
 
# -------------
51
 
#   There are 2 ways to create a landscape:
52
 
#   1) give each height value
53
 
#   2) create a landscape from an image (white pixels are upper)
54
 
 
55
 
land_size = 33
56
 
land = soya.land.Land(land_size)
57
 
# Land_size is the size of the landscape. Landscapes are always squares
58
 
# and their size must always be like this : (2^n)+1
59
 
 
60
 
# The following lines set randomized value for each height
61
 
i = 0
62
 
while (i < land_size):
63
 
  j = 0
64
 
  while (j < land_size):
65
 
    land.set_height(i, j, random.random())
66
 
    j = j + 1
67
 
  i = i + 1
68
 
 
69
 
# Multiply all the heights by 4
70
 
land.multiply_height(4.0)
71
 
 
72
 
# Now we must set a Material to the Land. Land must always have a Material
73
 
# even if it is None (None is a white Material)
74
 
i = 0
75
 
while (i < land_size):
76
 
  j = 0
77
 
  while (j < land_size):
78
 
    land.set_material(i, j, None)
79
 
    j = j + 1
80
 
  i = i + 1
81
 
 
82
 
 
83
 
# Above lines are quite useless. Now we will see how to create a Land from
84
 
# an image and how to texture it quickly
85
 
 
86
 
 
87
 
# Create a new Land
88
 
land = soya.land.Land(0)
89
 
# The size of 0 will be overriden by the size of the image
90
 
land.from_image(soya.model.Image("map1.tga"))
91
 
# Heights range from 0.0 (black pixels) to 1.0 (white pixels)
92
 
land.multiply_height(8.0)
93
 
 
94
 
# Create 2 Materials
95
 
material1 = soya.model.Material()
96
 
material1.tex_filename  = "block2.tga"
97
 
 
98
 
material2 = soya.model.Material()
99
 
material2.tex_filename  = "metal1.tga"
100
 
 
101
 
#   land.set_material_layer(MATERIAL, FROM, TO)
102
 
# Set to all points that have a height between FROM and TO the material
103
 
# MATERIAL
104
 
land.set_material_layer(material1, 0.0, 6.0)
105
 
land.set_material_layer(material2, 6.0, 8.0)
106
 
 
107
 
# You can also use:
108
 
#   land.set_material_layer_angle(MATERIAL, HEIGHT_FROM, HEIGHT_TO, ANGLE_FROM, ANGLE_TO)
109
 
# This function works just has the previous one but add 2 more arguments:
110
 
# ANGLE_FROM and ANGLE_TO.
111
 
# This means that all points of the land will have the given material
112
 
# only if:
113
 
# - its height is between HEIGHT_FROM and HEIGHT_TO
114
 
# - its normal makes an angle with the horizontal plane that is between ANGLE_FROM
115
 
# and ANGLE_TO (expressed in degrees).
116
 
land.set_material_layer_angle(material1, 0.0, 8.0, 0.0, 20.0)
117
 
 
118
 
 
119
 
# Now we will see some Land attributes:
120
 
 
121
 
land.scale_factor = 1.5
122
 
# This is the distance between 2 consecutive heights that you have given
123
 
# to define the Land. This is quite like doing the following:
124
 
#   world.scale(1.5, 1.0, 1.5)
125
 
# Default value is 1.5
126
 
 
127
 
land.texture_factor = 1.0
128
 
# This factor is applied to texture coordinates when rendering the Land.
129
 
# Default value is 1.0
130
 
 
131
 
land.map_size = 8
132
 
land.split_factor = 4.0
133
 
# These 2 values influence the behaviour of the level of detail algorithm
134
 
# (it means that there are more triangles to draw the Land near the Camera
135
 
# and less far from the Camera).
136
 
# The higher split_factor is, the better precision you have (it means more
137
 
# triangles to draw the Land even at long distance from Camera).
138
 
# map_size represents the size of a map. A map is a square part of the Land
139
 
# that computes its visibility and precision.
140
 
# map_size and split_factor values can change FPS (rendering speed). Values
141
 
# above are default ones (I get the best FPS with these ones on my computer)
142
 
 
143
 
 
144
 
# Land is a shape (and so can't be added in a World but must be set as shape)
145
 
world.set_shape(land)
146
 
 
147
 
 
148
 
# Add a camera and a loop to render
149
 
 
150
 
camera = soya.soya3d.Camera(world)
151
 
camera.set_xyz (16.0, 8.0, 0.0)
152
 
camera.look_at (soya.soya3d.Point (world, 16.0, 6.0, 10.0))
153
 
soya.set_root_widget(camera)
154
 
 
155
 
 
156
 
while(1):
157
 
  soya.render()
158
 
 
159
 
  time.sleep(0.1)
160
 
  
161
 
# Use Up, Down, Left, Right arrows to move the camera
162
 
 
163
 
  for event in soya.process_event():
164
 
    if event[0] == soya.KEYDOWN:
165
 
      if event[1] == soya.K_UP:
166
 
        camera.translate(0.0, 0.0, 0.5)
167
 
      elif event[1] == soya.K_DOWN:
168
 
        camera.translate(0.0, 0.0, -0.5)
169
 
      elif event[1] == soya.K_LEFT:
170
 
        camera.translate(0.5, 0.0, 0.0)
171
 
      elif event[1] == soya.K_RIGHT:
172
 
        camera.translate(-0.5, 0.0, 0.0)
173
 
      elif event[1] == soya.K_q:
174
 
        sys.exit()
175
 
 
176
 
 
177
 
# Other Land functions not aborded in this tutorial (easy to understand):
178
 
# -----------------------------------------------------------------------
179
 
#   height = land.get_height(x, z)
180
 
#   material = land.get_material(x, z)
181
 
#   land.add_height(value)
182
 
#     [x and z are integers, value and height are floats]
183
 
 
184
 
 
185
 
# TO DO exercice:
186
 
# ---------------
187
 
# make a Land editor
188