Sharedwww / talks / 2006-05-09-sage-digipen / tutorial / land-1.pyOpen in CoCalc
Author: William A. Stein
1
# Soya 3D tutorial
2
# Copyright (C) 2004 Jean-Baptiste 'Jiba' LAMY
3
# Copyright (C) 2001-2002 Bertrand 'blam!' LAMY
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20
# land-1: Landscape : bitmap-based landscape
21
22
# This lesson shows how to make a landscape (also known as heightmap or terrain), using
23
# a bitmap to describe the terrain. The bitmap acts like a popographic map ; the brighter
24
# a pixel is, the higher it is. You can make such bitmaps in software like the Gimp.
25
26
27
# Imports and inits Soya (see lesson basic-1.py).
28
29
import sys, os, os.path, soya, soya.sdlconst
30
31
soya.init()
32
soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))
33
soya.set_quality(2)
34
35
# Creates the scene.
36
37
scene = soya.World()
38
39
# Creates a new landscape in the scene.
40
41
land = soya.Land(scene)
42
43
# Gets the image "map1.png" from the tutorial data dir, and create the landscape
44
# from this image. The image dimension must be power of 2 plus 1 : (2 ** n) + 1.
45
46
land.from_image(soya.Image.get("map1.png"))
47
48
# By default, the landscape height ranges from 0.0 (black pixels) to 1.0 (white pixels).
49
# Here, we multiply the height by 8.0 so it ranges from 0.0 to 8.0.
50
51
land.multiply_height(8.0)
52
53
# Now that we have the landscape, we are going to texture it
54
# (see lesson modeling-material-2 about texturing). First, we creates two textured
55
# materials.
56
57
#material1 = soya.Material(soya.Image.get("block2.png"))
58
#material2 = soya.Material(soya.Image.get("metal1.png"))
59
material1 = soya.Material.get("block2")
60
material2 = soya.Material.get("metal1")
61
62
#material1 = soya.Material()
63
#material1.diffuse = (0.0, 0.0, 0.0, 1.0)
64
#material1 = soya.Material.get("block2")
65
#material2 = soya.Material()
66
67
# asigns MATERIAL1 to any point whose height is in the range 0.0-6.0, and material2 to
68
# any point whose height is in the range 6.0-8.0 (remember, height ranges from 0.0 to 8.0).
69
70
land.set_material_layer(material1, 0.0, 6.0)
71
land.set_material_layer(material2, 6.0, 8.0)
72
73
# Assigns material1 to any point whose height is in the range 0.0-8.0 and if the angle
74
# between the surface normal and the verticalvector is in the range 0.0-20.0.
75
76
land.set_material_layer_angle(material1, 0.0, 8.0, 0.0, 20.0)
77
78
# Now we set some Land attributes:
79
# - texture_factor specifies how much the textures are zoomed (higher values mean
80
# smaller texture)
81
82
# - scale_factor specifies how the landscape is scaled in the 2 horizontal dimensions.
83
84
# - the 2 last attributes influence the behaviour of the level of detail (LOD) algorithm
85
# (LOD means that parts of the landscape are rendered with more detail / more triangle
86
# if they are close to the camera). They are a trading between speed and quality.
87
#
88
# The higher split_factor is, the better precision you have (it means more triangles
89
# to draw the Land even far from Camera).
90
#
91
# patch_size represents the size of patches. A patch is a square part of the Land that
92
# computes its visibility and precision.
93
94
# the values below are the default ones.
95
96
land.texture_factor = 1.0
97
land.scale_factor = 1.0
98
land.patch_size = 8
99
land.split_factor = 2.0
100
land.texture_factor = 0.25
101
102
# Moves the landscape.
103
104
land.y = -2.5
105
106
# Adds a light.
107
108
light = soya.Light(scene)
109
light.set_xyz(0.0, 15.0, 0.0)
110
111
# Adds a keyboard-controlled camera and a rendering loop
112
113
class MovableCamera(soya.Camera):
114
def __init__(self, parent):
115
soya.Camera.__init__(self, parent)
116
117
self.speed = soya.Vector(self)
118
self.rotation_lateral_speed = 0.0
119
self.rotation_vertical_speed = 0.0
120
121
def begin_round(self):
122
soya.Camera.begin_round(self)
123
124
for event in soya.process_event():
125
if event[0] == soya.sdlconst.KEYDOWN:
126
if event[1] == soya.sdlconst.K_UP: self.speed.z = -1.0
127
elif event[1] == soya.sdlconst.K_DOWN: self.speed.z = 1.0
128
elif event[1] == soya.sdlconst.K_LEFT: self.rotation_lateral_speed = 10.0
129
elif event[1] == soya.sdlconst.K_RIGHT: self.rotation_lateral_speed = -10.0
130
elif event[1] == soya.sdlconst.K_q: soya.IDLER.stop()
131
elif event[1] == soya.sdlconst.K_ESCAPE: soya.IDLER.stop()
132
if event[0] == soya.sdlconst.KEYUP:
133
if event[1] == soya.sdlconst.K_UP: self.speed.z = 0.0
134
elif event[1] == soya.sdlconst.K_DOWN: self.speed.z = 0.0
135
elif event[1] == soya.sdlconst.K_LEFT: self.rotation_lateral_speed = 0.0
136
elif event[1] == soya.sdlconst.K_RIGHT: self.rotation_lateral_speed = 0.0
137
138
def advance_time(self, proportion):
139
self.add_mul_vector(proportion, self.speed)
140
self.turn_lateral (self.rotation_lateral_speed * proportion)
141
self.turn_vertical(self.rotation_vertical_speed * proportion)
142
143
144
camera = MovableCamera(scene)
145
camera.set_xyz(16.0, 6.0, 0.0)
146
camera.look_at(soya.Point(scene, 16.0, 6.0, 10.0))
147
soya.set_root_widget(camera)
148
149
150
#camera.set_xyz(16.0, 8.0, 0.0)
151
#camera.look_at(soya.Point(scene, 16.0, 6.0, 10.0))
152
153
154
scene.x = 100.0
155
156
157
scene.atmosphere = soya.Atmosphere()
158
scene.atmosphere.ambient = (1.0, 1.0, 1.0, 1.0)
159
160
#soya.Idler(scene).idle()
161
i = soya.Idler(scene)
162
#i.min_frame_duration = 0.0
163
i.idle()
164
print i.fps
165