1 import sys
, os
, os
.path
, soya
2 import soya
.widget
as widget
3 from soya
import sdlconst
10 global scene
,camera
,light
16 # TODO: Create a full-camera class to handle several kinds of performance for cameras
25 # TODO: Place functions to access KEY, and return float or bool values. x>0.5 => True
27 callback_advance
= None
28 # TODO: Add the user-callback
30 # TODO: Delete scene_body and use main Soya callbacks
34 # Import Psyco if available
38 print "Psyco found and started -- Python code accelerated."
40 print "I can't find PsyCo -- install it to get more speed"
45 def is_pyWorlds_installed():
46 print "pyWorlds seem to be installed and working."
50 def init(create_basic
=True):
53 soya
.path
.append(os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "data"))
54 scene
= basics
.scene
.scene
55 mainloop
=soya
.MainLoop(scene
)
56 scene
.mainloop
=mainloop
57 scene
.round_duration
=.04
58 mainloop
.round_duration
=.04
62 def init_basicscene():
63 global scene
, light
, camera
64 light
= soya
.Light(scene
)
68 camera
= soya
.Camera(scene
)
69 #camera.set_xyz(0,2,5)
72 #camera = soya.TravelingCamera(scene)
75 def begin_loop(callbackround
=None, callbackadvance
=None, engine
="soya" ):
76 global scene
, callback_round
, callback_advance
, camera
,mainloop
77 import soya
.pudding
as pudding
78 callback_round
= callbackround
79 callback_advance
= callbackadvance
81 soya
.set_root_widget(camera
)
82 elif engine
=="pudding":
85 print "error engine %s unknown" % engine
86 #soya.set_root_widget(soya.widget.Group())
87 #soya.root_widget.add(camera)
88 #if enable_fps: soya.root_widget.add(soya.widget.FPSLabel())
89 scene_body
= SceneBody(scene
,None)
96 root
= soya
.gui
.RootLayer(None)
97 viewport
= soya
.gui
.CameraViewport(root
, camera
)
101 global root
,viewport
,camera
,scene
,mainloop
102 soya
.path
.append(os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "data"))
104 import soya
.pudding
as pudding
107 scene
= basics
.scene
.scene
108 mainloop
=pudding
.main_loop
.MainLoop(scene
)
109 scene
.mainloop
=mainloop
110 scene
.round_duration
=.04
111 mainloop
.round_duration
=.04
115 soya
.set_root_widget(pudding
.core
.RootWidget())
116 soya
.root_widget
.add_child(camera
)
120 def begin_guiloop(callbackround
=None, callbackadvance
=None ):
121 global root
, mainloop
122 global scene
, callback_round
, callback_advance
, camera
123 callback_round
= callbackround
124 callback_advance
= callbackadvance
127 soya
.set_root_widget(root
)
128 scene_body
= SceneBody(scene
,None)
133 class SceneBody(soya
.Body
):
134 def advance_time(self
, proportion
):
135 global callback_advance
136 soya
.Body
.advance_time(self
, proportion
)
137 if callback_advance
: callback_advance(proportion
)
139 def begin_round(self
):
140 global KEY
,callback_round
, MOUSE_X
, MOUSE_Y
, MOUSE_BUTTON
141 soya
.Body
.begin_round(self
)
142 for event
in soya
.process_event():
144 if event
[0] == soya
.sdlconst
.KEYDOWN
:
145 if event
[1] == soya
.sdlconst
.K_ESCAPE
: soya
.MAIN_LOOP
.stop()
147 KEY
[event
[1]]=event
[:]
149 elif event
[0] == sdlconst
.KEYUP
:
150 if event
[1] in KEY
: del KEY
[event
[1]]
152 elif event
[0] == sdlconst
.QUIT
:
153 soya
.MAIN_LOOP
.stop()
155 elif event
[0] == soya
.sdlconst
.MOUSEBUTTONDOWN
:
156 MOUSE_BUTTON
[event
[1]]=event
[:]
160 elif event
[0] == soya
.sdlconst
.MOUSEBUTTONUP
:
161 del MOUSE_BUTTON
[event
[1]]
165 elif event
[0] == soya
.sdlconst
.MOUSEMOTION
:
171 if callback_round
: callback_round()
174 class Body(soya
.Body
):
175 def __init__(self
,filename
):
177 if type(filename
) == type(''):
178 if filename
in meshes
:
179 mesh
= meshes
[filename
]
181 mesh
= soya
.Model
.get(filename
)
182 meshes
[filename
] = mesh
184 # if it's not a text it is a mesh.
188 soya
.Body
.__init
__(self
,scene
,mesh
)
189 self
.velocity
= soya
.Vector(self
,0,0,0)
190 self
.rotation
= [0,0,0]
192 def advance_time(self
, proportion
):
194 soya
.Body
.advance_time(self
, proportion
)
195 elapsed
= mainloop
.round_duration
* proportion
196 if elapsed
==0: elapsed
=0.001
198 self
.add_mul_vector(elapsed
, self
.velocity
)
199 self
.rotate_x(elapsed
* self
.rotation
[0])
200 self
.rotate_y(elapsed
* self
.rotation
[1])
201 self
.rotate_z(elapsed
* self
.rotation
[2])
206 #class Character(soya.Body):
207 #def __init__(self,filename):
209 #if type(filename) == type(''):
210 #if filename in animated_meshes:
211 #mesh = animated_meshes[filename]
213 #mesh = soya.AnimatedModel.get(filename)
214 #animated_meshes[filename] = mesh
216 ## if it's not a text it is a animated-mesh.
219 ## print "Available meshes :", sorcerer_model.meshes .keys()
220 ## print "Available animations:", mesh.animations.keys()
221 ## -> Available animations: ['marche', 'tourneD', 'chute', 'tourneG', 'attente', 'recule']
223 #soya.Body.__init__(self,scene,mesh)
225 #"stop" : ["garde","attente"],
226 #"walk" : ["marche"],
229 #self.statecycle = None
230 #self.character_setstate("stop")
231 #self.velocity = soya.Vector(self,0,0,0)
232 #self.rotation = [0,0,0]
233 #self.desiredangle = 0
234 #self.look_at_speed = 10
236 #def advance_time(self, proportion):
237 #soya.Body.advance_time(self, proportion)
238 #elapsed = mainloop.round_duration * proportion
239 #if elapsed==0: elapsed=0.001
240 #self.angle = self.get_absoluteangleXZ()
241 #if self.desiredangle >= 360: self.desiredangle-=360
242 #if self.desiredangle < 0: self.desiredangle+=360
244 #anglediff = self.desiredangle - self.angle
245 #if anglediff > 180: anglediff-=360
246 #if anglediff < -180: anglediff+=360
247 #factor = self.look_at_speed
248 #if factor > 1/elapsed : factor = 1/elapsed
249 #anglemov = anglediff * factor
251 #if abs(self.rotation[1])>abs(anglemov):
252 #self.rotation[1]=(self.rotation[1]-anglemov)/2.0
254 #self.rotation[1]=(self.rotation[1]*5-anglemov)/6.0
255 #if abs(anglediff)<1:
256 #self.rotation[1]=-anglediff
258 #self.add_mul_vector(elapsed , self.velocity)
259 #self.rotate_x(elapsed * self.rotation[0])
260 #self.rotate_y(elapsed * self.rotation[1])
261 #self.rotate_z(elapsed * self.rotation[2])
263 #def get_absoluteangleXZ(self,vector=None):
265 #vector = soya.Vector(self,0,0,-1)
267 #q=vector % scene # I mean an upper container.
269 #return xy_toangle(q.x,q.z)
271 #def character_setstate(self,newstate):
272 #if newstate==self.state: return False
273 #if not hasattr(self.mesh,"animations"): return False
274 #if len(self.states[newstate])<1: raise
277 #for statecycle in self.states[newstate]:
278 #if statecycle in self.mesh.animations:
279 #newstatecycle=statecycle
283 #if not newstatecycle:
284 #print "Not found any animation for %s: " % newstate, self.states[newstate]
285 #print "Available animations:", self.mesh.animations.keys()
289 #self.animate_clear_cycle(self.statecycle)
290 #self.statecycle = None
291 #self.animate_blend_cycle(newstatecycle)
292 #self.statecycle = newstatecycle
301 class FollowBody(Body
):
302 def __init__(self
,filename
,target
):
303 Body
.__init
__(self
,filename
)
308 self
.target_distance
= [0.5,1.0,2]
309 self
.set_springfactor(16)
310 self
.target_velocity
= 1
314 self
.advance_time(0.5)
316 def set_springfactor(self
,factor
):
317 self
.target_springfactor
= factor
/ 100.0
319 def begin_round(self
):
320 Body
.begin_round(self
)
322 distance
= self
.distance_to(self
.target
)
323 _min
= self
.target_distance
[0]
324 _med
= self
.target_distance
[1]
325 _max
= self
.target_distance
[2]
328 if distance
<= _min
: factor
= 0.0
329 elif distance
>= _max
: factor
= 0.0
331 Q
= (_med
- distance
)
333 Q
/= math
.sqrt(_med
- _min
)
334 factor
= (distance
- _min
) / (_med
- _min
)
336 Q
/= math
.sqrt(_max
- _med
)
337 factor
= (_max
- distance
) / (_max
- _med
)
341 factor2
= (_med
- distance
) / (_max
- _min
)
342 if factor2
< 1: factor2
= 1
343 if self
.velocity
.z
>1:
344 factor
/=self
.velocity
.z
346 vel
= self
.target_velocity
347 # self.velocity.z = (self.velocity.z * self.target_springfactor * factor + Q * vel ) / (self.target_springfactor * factor + 1 )
348 self
.velocity
.z
= (self
.velocity
.z
* self
.target_springfactor
* factor
+ (_med
- distance
) * vel
) / (self
.target_springfactor
* factor
+ 1 )
349 #self.velocity.z *= factor2
351 look_at_elastic(self
,self
.target
, sqrt_from
=360, factor
=(1-factor
)+.3)
353 self
.look_at(self
.target
)
355 def advance_time(self
, proportion
):
356 Body
.advance_time(self
, proportion
)
357 distance
= self
.distance_to(self
.target
)
358 _min
= self
.target_distance
[0]
359 _med
= self
.target_distance
[1]
360 _max
= self
.target_distance
[2]
361 f3
= (distance
- _med
) / (_max
- _med
)
362 f1
= self
.target_springfactor
* 100 + 1
367 self
.x
= (self
.x
* f1
+ self
.target
.x
* f3
) / (f1
+f3
)
368 self
.y
= (self
.y
* f1
+ self
.target
.y
* f3
) / (f1
+f3
)
369 self
.z
= (self
.z
* f1
+ self
.target
.z
* f3
) / (f1
+f3
)