1 import sys
, os
, os
.path
, soya
2 import soya
.widget
as widget
3 from soya
import sdlconst
8 import pyworlds
.basics
.scene
10 global scene
,camera
,light
18 # TODO: Create a full-camera class to handle several kinds of performance for cameras
29 # TODO: Place functions to access KEY, and return float or bool values. x>0.5 => True
31 callback_advance
= None
32 # TODO: Add the user-callback
34 # TODO: Delete scene_body and use main Soya callbacks
38 # Import Psyco if available
42 print "Psyco found and started -- Python code accelerated."
44 print "I can't find PsyCo -- install it to get more speed"
49 def is_pyWorlds_installed():
50 print "pyWorlds seem to be installed and working."
54 def init(width
= 1020,height
= 760,title
="PyWorlds (Soya3D)",create_basic
=True):
55 global scene
,mainloop
,pyworlds_engine
56 pyworlds_engine
= "soya"
57 soya
.init(width
=width
, height
= height
,title
=title
)
58 soya
.path
.append(os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "data"))
59 scene
= basics
.scene
.scene
60 mainloop
=soya
.MainLoop(scene
)
61 scene
.mainloop
=mainloop
62 scene
.round_duration
=.04
63 mainloop
.round_duration
=.04
67 def init_basicscene():
68 global scene
, light
, camera
, scene_body
69 scene_body
= SceneBody(scene
,None)
71 light
= soya
.Light(scene
)
75 camera
= soya
.Camera(scene
)
76 #camera.set_xyz(0,2,5)
79 #camera = soya.TravelingCamera(scene)
82 def begin_loop(callbackround
=None, callbackadvance
=None, engine
="soya" ):
83 global scene
, callback_round
, callback_advance
, camera
,mainloop
84 import soya
.pudding
as pudding
85 callback_round
= callbackround
86 callback_advance
= callbackadvance
88 soya
.set_root_widget(camera
)
89 elif engine
=="pudding":
92 print "error engine %s unknown" % engine
93 #soya.set_root_widget(soya.widget.Group())
94 #soya.root_widget.add(camera)
95 #if enable_fps: soya.root_widget.add(soya.widget.FPSLabel())
96 return mainloop
.main_loop()
102 root
= soya
.gui
.RootLayer(None)
103 viewport
= soya
.gui
.CameraViewport(root
, camera
)
106 def init_pudding(width
= 1020,height
= 760,title
="PyWorlds (Soya3D)", options
= {}):
107 global root
,viewport
,camera
,scene
,mainloop
, pyworlds_engine
108 soya
.path
.append(os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "data"))
109 pyworlds_engine
= "pudding"
110 import soya
.pudding
as pudding
111 soya
.init(width
=width
, height
= height
, title
=title
)
113 scene
= basics
.scene
.scene
114 mainloop
=pudding
.main_loop
.MainLoop(scene
)
115 scene
.mainloop
=mainloop
116 scene
.round_duration
=.04
117 mainloop
.round_duration
=.04
120 if 'nobasics' not in options
: init_basicscene()
121 soya
.set_root_widget(pudding
.core
.RootWidget(width
= width
,height
= height
))
122 if 'nochild' not in options
: soya
.root_widget
.add_child(camera
)
126 def begin_guiloop(callbackround
=None, callbackadvance
=None ):
127 global root
, mainloop
128 global scene
, callback_round
, callback_advance
, camera
, scene_body
129 callback_round
= callbackround
130 callback_advance
= callbackadvance
133 soya
.set_root_widget(root
)
134 scene_body
= SceneBody(scene
,None)
137 def clearScene(fullClear
= False):
138 global scene
,camera
,light
,scene_body
140 validObj
=[scene_body
,camera
,light
]
141 if fullClear
: validObj
=[]
143 for body
in scene
.children
:
144 if body
not in validObj
: toRemove
.append(body
)
146 for body
in toRemove
:
148 scene
.children
.remove(body
)
152 class SceneBody(soya
.Body
):
153 def advance_time(self
, proportion
):
154 global callback_advance
155 soya
.Body
.advance_time(self
, proportion
)
156 if callback_advance
: callback_advance(proportion
)
158 def begin_round(self
):
160 global KEY
,callback_round
, MOUSE_X
, MOUSE_Y
, MOUSE_BUTTON
,MOUSE_BUTTONUP
, mainloop
161 soya
.Body
.begin_round(self
)
163 if pyworlds_engine
== "soya":
164 array_events
= soya
.process_event()
165 elif pyworlds_engine
== "pudding":
166 import soya
.pudding
as pudding
167 # Use mainloop.events instead of pudding.process_event() :
168 # array_events = pudding.process_event()
169 array_events
= mainloop
.events
171 for ev1
in MOUSE_BUTTONUP
:
172 if MOUSE_BUTTON
.has_key(ev1
):
173 del MOUSE_BUTTON
[ev1
]
176 for event
in array_events
:
178 if event
[0] == soya
.sdlconst
.KEYDOWN
:
179 if event
[1] == soya
.sdlconst
.K_ESCAPE
: soya
.MAIN_LOOP
.stop()
181 KEY
[event
[1]]=event
[:]
183 elif event
[0] == sdlconst
.KEYUP
:
184 if event
[1] in KEY
: del KEY
[event
[1]]
186 elif event
[0] == sdlconst
.QUIT
:
187 soya
.MAIN_LOOP
.stop()
189 elif event
[0] == soya
.sdlconst
.MOUSEBUTTONDOWN
:
190 MOUSE_BUTTON
[event
[1]]=event
[:]
193 a
,b
,c
,d
= MOUSE_BUTTON
[event
[1]]
194 if a
== 5 and (b
==4 or b
==5): MOUSE_WHEEL
= b
196 elif event
[0] == soya
.sdlconst
.MOUSEBUTTONUP
:
197 #print "Up: ",MOUSE_BUTTON[event[1]]
198 MOUSE_BUTTONUP
.append(event
[1])
199 #if MOUSE_BUTTON.has_key(event[1]):
200 # del MOUSE_BUTTON[event[1]]
204 elif event
[0] == soya
.sdlconst
.MOUSEMOTION
:
209 if callback_round
: callback_round()
212 class Body(soya
.Body
):
213 def __init__(self
,filename
):
215 if type(filename
) == type(''):
216 if filename
in meshes
:
217 mesh
= meshes
[filename
]
219 mesh
= soya
.Model
.get(filename
)
220 meshes
[filename
] = mesh
222 # if it's not a text it is a mesh.
226 soya
.Body
.__init
__(self
,scene
,mesh
)
227 self
.velocity
= soya
.Vector(self
,0,0,0)
228 self
.rotation
= [0,0,0]
230 def advance_time(self
, proportion
):
232 soya
.Body
.advance_time(self
, proportion
)
233 elapsed
= mainloop
.round_duration
* proportion
234 if elapsed
==0: elapsed
=0.001
236 self
.add_mul_vector(elapsed
, self
.velocity
)
237 self
.rotate_x(elapsed
* self
.rotation
[0])
238 self
.rotate_y(elapsed
* self
.rotation
[1])
239 self
.rotate_z(elapsed
* self
.rotation
[2])
244 #class Character(soya.Body):
245 #def __init__(self,filename):
247 #if type(filename) == type(''):
248 #if filename in animated_meshes:
249 #mesh = animated_meshes[filename]
251 #mesh = soya.AnimatedModel.get(filename)
252 #animated_meshes[filename] = mesh
254 ## if it's not a text it is a animated-mesh.
257 ## print "Available meshes :", sorcerer_model.meshes .keys()
258 ## print "Available animations:", mesh.animations.keys()
259 ## -> Available animations: ['marche', 'tourneD', 'chute', 'tourneG', 'attente', 'recule']
261 #soya.Body.__init__(self,scene,mesh)
263 #"stop" : ["garde","attente"],
264 #"walk" : ["marche"],
267 #self.statecycle = None
268 #self.character_setstate("stop")
269 #self.velocity = soya.Vector(self,0,0,0)
270 #self.rotation = [0,0,0]
271 #self.desiredangle = 0
272 #self.look_at_speed = 10
274 #def advance_time(self, proportion):
275 #soya.Body.advance_time(self, proportion)
276 #elapsed = mainloop.round_duration * proportion
277 #if elapsed==0: elapsed=0.001
278 #self.angle = self.get_absoluteangleXZ()
279 #if self.desiredangle >= 360: self.desiredangle-=360
280 #if self.desiredangle < 0: self.desiredangle+=360
282 #anglediff = self.desiredangle - self.angle
283 #if anglediff > 180: anglediff-=360
284 #if anglediff < -180: anglediff+=360
285 #factor = self.look_at_speed
286 #if factor > 1/elapsed : factor = 1/elapsed
287 #anglemov = anglediff * factor
289 #if abs(self.rotation[1])>abs(anglemov):
290 #self.rotation[1]=(self.rotation[1]-anglemov)/2.0
292 #self.rotation[1]=(self.rotation[1]*5-anglemov)/6.0
293 #if abs(anglediff)<1:
294 #self.rotation[1]=-anglediff
296 #self.add_mul_vector(elapsed , self.velocity)
297 #self.rotate_x(elapsed * self.rotation[0])
298 #self.rotate_y(elapsed * self.rotation[1])
299 #self.rotate_z(elapsed * self.rotation[2])
301 #def get_absoluteangleXZ(self,vector=None):
303 #vector = soya.Vector(self,0,0,-1)
305 #q=vector % scene # I mean an upper container.
307 #return xy_toangle(q.x,q.z)
309 #def character_setstate(self,newstate):
310 #if newstate==self.state: return False
311 #if not hasattr(self.mesh,"animations"): return False
312 #if len(self.states[newstate])<1: raise
315 #for statecycle in self.states[newstate]:
316 #if statecycle in self.mesh.animations:
317 #newstatecycle=statecycle
321 #if not newstatecycle:
322 #print "Not found any animation for %s: " % newstate, self.states[newstate]
323 #print "Available animations:", self.mesh.animations.keys()
327 #self.animate_clear_cycle(self.statecycle)
328 #self.statecycle = None
329 #self.animate_blend_cycle(newstatecycle)
330 #self.statecycle = newstatecycle
339 class FollowBody(Body
):
340 def __init__(self
,filename
,target
):
341 Body
.__init
__(self
,filename
)
346 self
.target_distance
= [0.5,1.0,2]
347 self
.set_springfactor(16)
348 self
.target_velocity
= 1
352 self
.advance_time(0.5)
354 def set_springfactor(self
,factor
):
355 self
.target_springfactor
= factor
/ 100.0
357 def begin_round(self
):
358 Body
.begin_round(self
)
360 distance
= self
.distance_to(self
.target
)
361 _min
= self
.target_distance
[0]
362 _med
= self
.target_distance
[1]
363 _max
= self
.target_distance
[2]
366 if distance
<= _min
: factor
= 0.0
367 elif distance
>= _max
: factor
= 0.0
369 Q
= (_med
- distance
)
371 Q
/= math
.sqrt(_med
- _min
)
372 factor
= (distance
- _min
) / (_med
- _min
)
374 Q
/= math
.sqrt(_max
- _med
)
375 factor
= (_max
- distance
) / (_max
- _med
)
379 factor2
= (_med
- distance
) / (_max
- _min
)
380 if factor2
< 1: factor2
= 1
381 if self
.velocity
.z
>1:
382 factor
/=self
.velocity
.z
384 vel
= self
.target_velocity
385 # self.velocity.z = (self.velocity.z * self.target_springfactor * factor + Q * vel ) / (self.target_springfactor * factor + 1 )
386 self
.velocity
.z
= (self
.velocity
.z
* self
.target_springfactor
* factor
+ (_med
- distance
) * vel
) / (self
.target_springfactor
* factor
+ 1 )
387 #self.velocity.z *= factor2
389 look_at_elastic(self
,self
.target
, sqrt_from
=360, factor
=(1-factor
)+.3)
391 self
.look_at(self
.target
)
393 def advance_time(self
, proportion
):
394 Body
.advance_time(self
, proportion
)
395 distance
= self
.distance_to(self
.target
)
396 _min
= self
.target_distance
[0]
397 _med
= self
.target_distance
[1]
398 _max
= self
.target_distance
[2]
399 f3
= (distance
- _med
) / (_max
- _med
)
400 f1
= self
.target_springfactor
* 100 + 1
405 self
.x
= (self
.x
* f1
+ self
.target
.x
* f3
) / (f1
+f3
)
406 self
.y
= (self
.y
* f1
+ self
.target
.y
* f3
) / (f1
+f3
)
407 self
.z
= (self
.z
* f1
+ self
.target
.z
* f3
) / (f1
+f3
)