File: model_builder.pyx

package info (click to toggle)
soya 0.12-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 13,580 kB
  • ctags: 20,171
  • sloc: cpp: 45,252; python: 7,241; ansic: 5,226; perl: 273; makefile: 227; sh: 65
file content (249 lines) | stat: -rw-r--r-- 8,572 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# -*- indent-tabs-mode: t -*-

# Soya 3D
# Copyright (C) 2004 Jean-Baptiste LAMY -- jiba@tuxfamily.org
#
# 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

def _is_static_light(item):
	return isinstance(item, _Light) and item.static


cdef class ModelBuilder(_CObj):
	cdef _Model _to_model(self, _World world):
		pass


cdef class SimpleModelBuilder(ModelBuilder):
	"""SimpleModelBuilder

ModelBuilder for simple / normal / regular Model. The SimpleModelBuilder attributes allows to
customize the World -> Model computation.

Attributes are :

 - shadow (default 0) : enable shadows

 - max_face_angle (default 80.0) : if the angle (in degree) between 2 faces is less than
	 this value, vertices of the two faces can be merged if they are enough close. Set it
	 to 180.0 or more to disable this feature."""
	#cdef int   _shadow
	#cdef float _max_face_angle
	
	property shadow:
		def __get__(self):
			return self._shadow
		def __set__(self, int x):
			self._shadow = x
			
	property max_face_angle:
		def __get__(self):
			return self._max_face_angle
		def __set__(self, float x):
			self._max_face_angle = x
			
	def __init__(self, int shadow = 0, float max_face_angle = 80.0):
		"""SimpleModelBuilder(**attributes) -> SimpleModelBuilder

See SimpleModelBuilder.__doc__ for more info."""
		self._shadow         = shadow
		self._max_face_angle = max_face_angle
		
	cdef __getcstate__(self):
		return self._shadow, self._max_face_angle
	
	cdef void __setcstate__(self, cstate):
		self._shadow, self._max_face_angle = cstate
		
	cdef _Model _to_model(self, _World world):
		cdef _SimpleModel model
		cdef int          option
		cdef              ligths
		option = 0
		if self._shadow: option = option | MODEL_PLANE_EQUATION | MODEL_SIMPLE_NEIGHBORS | MODEL_SHADOW
		model = SimpleModel(world, self._max_face_angle, option, world.search_all(_is_static_light))
		model._build_sphere()
		model._build_display_list()
		return model

	
cdef class SolidModelBuilder(SimpleModelBuilder):
	"""SolidModelBuilder
"""
	cdef _Model _to_model(self, _World world):
		cdef _SolidModel model
		cdef int         option
		cdef             ligths
		option = 0
		if self._shadow: option = option | MODEL_PLANE_EQUATION | MODEL_SIMPLE_NEIGHBORS | MODEL_SHADOW
		model = SolidModel(world, self._max_face_angle, option, world.search_all(_is_static_light))
		model._build_sphere()
		model._build_display_list()
		return model
	
	
cdef class TreeModelBuilder(SimpleModelBuilder):
	"""TreeModelBuilder

ModelBuilder for tree-based Model. Yields a TreeModel instead of a SimpleModel.
TreeModel are optimized for big model with lots of faces, espescially if all the faces
are not visible at the same time (e.g. a game level). Both rendering and raypicking
are optimized.
Internally, the model is broken down into several hierarchinal nodes, each node grouping
close faces.

Attributes are :

 - shadow (default 0) : NOT IMPLEMENTED YET for tree

 - collapsing_distance (default 0.9) : this parameter tunes how many nodes are created.
	 If a child node's radius > parent node's radius X collapsing_distance, the child
	 and parent nodes are merged.

 - quality (default 0) : set to 1 to compute a slower but slightly more performant tree.

 - max_child_radius (default 0.5) : the maximum children node's radius, expressed in ratio
	 of the parent node's radius. Meaningfull only when quality == 0"""
	#cdef float _collapsing_distance
	#cdef int   _quality
	#cdef float _max_child_radius
	
	property collapsing_distance:
		def __get__(self):
			return self._collapsing_distance
		def __set__(self, float x):
			self._collapsing_distance = x
			
	property quality:
		def __get__(self):
			return self._quality
		def __set__(self, int x):
			self._quality = x
	
	property max_child_radius:
		def __get__(self):
			return self._max_child_radius
		def __set__(self, float x):
			self._max_child_radius = x
			
	def __init__(self, int shadow = 0, float max_face_angle = 200.0, float collapsing_distance = 0.9, int quality = 0, float max_child_radius = 0.5):
		"""TreeModelBuilder(**attributes) -> TreeModelBuilder

See TreeModelBuilder.__doc__ for more info."""
		SimpleModelBuilder.__init__(self, shadow, max_face_angle)
		self._collapsing_distance = collapsing_distance
		self._quality             = quality
		self._max_child_radius    = max_child_radius
		
	cdef __getcstate__(self):
		return self._shadow, self._max_face_angle, self._collapsing_distance, self._quality, self._max_child_radius
	
	cdef void __setcstate__(self, cstate):
		self._shadow, self._max_face_angle, self._collapsing_distance, self._quality, self._max_child_radius = cstate
		
	cdef _Model _to_model(self, _World world):
		cdef _TreeModel model
		cdef int        option
		option = 0
		if self._shadow: option = option | MODEL_PLANE_EQUATION | MODEL_SIMPLE_NEIGHBORS | MODEL_SHADOW
		model = TreeModel(world, self._max_face_angle, option, world.search_all(_is_static_light))
		model._build_tree()
		model._optimize_tree(self._collapsing_distance, self._quality, self._max_child_radius)
		return model
	
		
cdef class CellShadingModelBuilder(SimpleModelBuilder):
	"""CellShadingModelBuilder

ModelBuilder for cell-shaded Model.

Attributes are :

 - shadow (default 0) : enable shadows

 - shader : the material used for cell-shading lighting

 - outline_color (default black) : the color of the outline

 - outline_width (default 4.0) : the maximum line width when the cell-shaded model
	 is very near the camera (set to 0.0 to disable outlines)

 - outline_attenuation (default : 0.3) : specify how much the distance affect the
	 outline_width
"""
	
	#cdef _Material _shader
	#cdef           _outline_color
	#cdef float     _outline_width, _outline_attenuation
	
	property shader:
		def __get__(self):
			return self._shader
		def __set__(self, _Material x):
			self._shader = x
			
	property outline_color:
		def __get__(self):
			return self._outline_color
		def __set__(self, x):
			self._outline_color = x
			
	property outline_width:
		def __get__(self):
			return self._outline_width
		def __set__(self, float x):
			self._outline_width = x
			
	property outline_attenuation:
		def __get__(self):
			return self._outline_attenuation
		def __set__(self, float x):
			self._outline_attenuation = x
			
	def __init__(self, int shadow = 0, float max_face_angle = 80.0, _Material shader = None, outline_color = BLACK, float outline_width = 4.0, float outline_attenuation = 0.3):
		"""CellShadingModelBuilder(**attributes) -> CellShadingModelBuilder

See CellShadingModelBuilder.__doc__ for more info."""
		SimpleModelBuilder.__init__(self, shadow, max_face_angle)
		self._shader              = shader or _SHADER_DEFAULT_MATERIAL
		self._outline_color       = outline_color
		self._outline_width       = outline_width
		self._outline_attenuation = outline_attenuation
		
	cdef __getcstate__(self):
		return self._shadow, self._max_face_angle, self._shader, self._outline_color, self._outline_width, self._outline_attenuation
	
	cdef void __setcstate__(self, cstate):
		self._shadow, self._max_face_angle, self._shader, self._outline_color, self._outline_width, self._outline_attenuation = cstate
		
	cdef _Model _to_model(self, _World world):
		cdef _CellShadingModel model
		cdef int               option
		option = 0
		if self._shadow: option = option | MODEL_PLANE_EQUATION | MODEL_SIMPLE_NEIGHBORS | MODEL_SHADOW
		model = CellShadingModel(world, self._max_face_angle, option | MODEL_PLANE_EQUATION | MODEL_NEIGHBORS | MODEL_CELLSHADING, world.search_all(_is_static_light))
		model._build_sphere()
		model._build_cellshading(self._shader, self._outline_color, self._outline_width, self._outline_attenuation)
		model._build_display_list()
		return model
		
	
cdef ModelBuilder _DEFAULT_MODEL_BUILDER
_DEFAULT_MODEL_BUILDER = SimpleModelBuilder()
def _set_default_model_builder(ModelBuilder model_builder):
	global _DEFAULT_MODEL_BUILDER
	_DEFAULT_MODEL_BUILDER = model_builder