0e2fcad9fcced6fc468e302cb306fffbaa28a65b
2 from logging
import debug
, info
4 from os
.path
import exists
, dirname
5 from panda3d
.core
import get_model_path
, AntialiasAttrib
, PandaNode
, \
6 LightRampAttrib
, Camera
, OrthographicLens
, NodePath
, OmniBoundingVolume
, \
7 AmbientLight
as P3DAmbientLight
, Spotlight
as P3DSpotlight
, Point2
, \
9 from direct
.filter.CommonFilters
import CommonFilters
10 from direct
.actor
.Actor
import Actor
11 from lib
.lib
.p3d
.p3d
import LibP3d
14 class RenderToTexture
:
16 def __init__(self
, size
=(256, 256)):
17 self
.__set
_buffer
(size
)
18 self
.__set
_display
_region
()
21 self
.display_region
.set_camera(self
.camera
)
23 def __set_buffer(self
, size
):
24 self
.buffer = base
.win
.make_texture_buffer('result buffer', size
[0],
26 self
.buffer.set_sort(-100)
28 def __set_display_region(self
):
29 self
.display_region
= self
.buffer.make_display_region()
30 self
.display_region
.set_sort(20)
32 def __set_camera(self
):
33 self
.camera
= NodePath(Camera('camera 2d'))
34 lens
= OrthographicLens()
35 lens
.set_film_size(1, 1)
36 lens
.set_near_far(-1000, 1000)
37 self
.camera
.node().set_lens(lens
)
40 self
.root
= NodePath('root')
41 self
.root
.set_depth_test(False)
42 self
.root
.set_depth_write(False)
43 self
.camera
.reparent_to(self
.root
)
46 def texture(self
): return self
.buffer.get_texture()
49 base
.graphicsEngine
.remove_window(self
.buffer)
50 if base
.win
: # if you close the window during a race
51 base
.win
.remove_display_region(self
.display_region
)
52 list(map(lambda node
: node
.remove_node(), [self
.camera
, self
.root
]))
57 def __init__(self
, model_path
, antialiasing
, shaders
, srgb
):
58 self
.root
= P3dNode(render
)
62 get_model_path().append_directory(model_path
)
64 root_dir
= LibP3d
.p3dpath(dirname(__file__
))
65 paths
= [root_dir
+ '/' + model_path
, root_dir
]
66 list(map(get_model_path().append_directory
, paths
))
67 render
.set_shader_auto()
68 # render.set_two_sided(True) # it breaks shadows
69 if antialiasing
: render
.set_antialias(AntialiasAttrib
.MAuto
)
70 if shaders
and base
.win
:
71 self
.filters
= CommonFilters(base
.win
, base
.cam
)
73 def load_model(self
, filename
, callback
=None, anim
=None):
74 ext
= '.bam' if exists(filename
+ '.bam') else ''
76 anim_dct
= {'anim': filename
+ '-Anim' + ext
}
77 node
= P3dNode(self
.set_srgb(Actor(filename
+ ext
, anim_dct
)))
79 callb
= lambda model
: callback(P3dNode(self
.set_srgb(model
)))
80 node
= loader
.loadModel(filename
+ ext
, callback
=callb
)
82 node
= P3dNode(self
.set_srgb(
83 loader
.loadModel(LibP3d
.p3dpath(filename
+ ext
))))
86 def set_srgb(self
, model
):
88 for texture
in model
.find_all_textures():
89 if texture
.get_format() in [Texture
.F_rgba
, Texture
.F_rgbm
]:
90 texture
.set_format(Texture
.F_srgb_alpha
)
91 elif texture
.get_format() in [Texture
.F_rgb
]:
92 texture
.set_format(Texture
.F_srgb
)
97 aa_not_none
= render
.get_antialias() != AntialiasAttrib
.MNone
98 if render
.has_antialias() and aa_not_none
:
99 render
.clear_antialias()
100 else: render
.set_antialias(AntialiasAttrib
.MAuto
, 1)
103 tmp_node
= NodePath(PandaNode('temp node'))
104 tmp_node
.set_attrib(LightRampAttrib
.make_single_threshold(.5, .4))
105 tmp_node
.set_shader_auto()
106 base
.cam
.node().set_initial_state(tmp_node
.get_state())
107 self
.filters
.set_cartoon_ink(separation
=1)
110 if not base
.win
: return
111 self
.filters
.setBloom(
112 blend
=(.3, .4, .3, 0), mintrigger
=.6, maxtrigger
=1.0, desat
=.6,
113 intensity
=1.0, size
='medium')
114 # default: (.3, .4, .3, 0), .6, 1, .6, 1, 'medium'
118 p3d
= base
.cam
.get_relative_point(node
.node
, Point3(0, 0, 0))
120 return p2d
if base
.camLens
.project(p3d
, p2d
) else None
123 def shader_support(self
):
124 return base
.win
.get_gsg().get_supports_basic_shaders()
126 def screenshot(self
, path
=None):
127 time
= datetime
.datetime
.now().strftime('%y%m%d%H%M%S')
128 #res = base.win.save_screenshot(Filename(path or ("yocto%s.png" % time)))
129 #debug('screenshot %s (%s)' % (path or ("yocto%s.png" % time), res))
130 res
= base
.screenshot(path
or ("yocto%s.png" % time
), False)
131 info('screenshot %s (%s; %s)' % (path
or ("yocto%s.png" % time
), res
, getcwd()))
134 def enable_shader(): render
.set_shader_auto()
137 def disable_shader(): render
.set_shader_off()
140 def print_stats(two_d
=True, three_d
=True, analyze
=True, ls
=True):
141 '''Print graphics stats. They use standard output (from p3d).'''
143 if two_d
and analyze
:
144 info
+=[('render2d.analyze', base
.render2d
.analyze
)]
145 if three_d
and analyze
:
146 info
+=[('render.analyze', base
.render
.analyze
)]
148 info
+=[('render2d.ls', base
.render2d
.ls
)]
150 info
+=[('render.ls', base
.render
.ls
)]
152 print('\n\n#####\n%s()' % elm
[0])
158 def __init__(self
, nodepath
):
159 self
.nodepath
= nodepath
160 self
.node
.set_python_tag('libnode', self
)
162 def set_collide_mask(self
, mask
): return self
.node
.set_collide_mask(mask
)
163 def set_x(self
, val
): return self
.node
.set_x(val
)
164 def set_y(self
, val
): return self
.node
.set_y(val
)
165 def set_z(self
, val
): return self
.node
.set_z(val
)
166 def set_hpr(self
, val
): return self
.node
.set_hpr(val
)
167 def set_h(self
, val
): return self
.node
.set_h(val
)
168 def set_p(self
, val
): return self
.node
.set_p(val
)
169 def set_r(self
, val
): return self
.node
.set_r(val
)
170 def set_scale(self
, val
): return self
.node
.set_scale(val
)
171 def set_transparency(self
, val
): return self
.node
.set_transparency(val
)
172 def set_alpha_scale(self
, val
): return self
.node
.set_alpha_scale(val
)
173 def set_texture(self
, texturestage
, texture
):
174 return self
.node
.set_texture(texturestage
, texture
)
175 def has_tag(self
, name
): return self
.node
.has_tag(name
)
176 def get_tag(self
, name
): return self
.node
.get_tag(name
)
177 def get_python_tag(self
, name
): return self
.node
.get_python_tag(name
)
178 def remove_node(self
): return self
.node
.remove_node()
179 def flatten_strong(self
): return self
.node
.flatten_strong()
180 def clear_model_nodes(self
): return self
.node
.clear_model_nodes()
181 def show(self
): return self
.node
.show()
182 def set_depth_offset(self
, val
): return self
.node
.set_depth_offset(val
)
183 def loop(self
, val
): return self
.node
.loop(val
)
184 def cleanup(self
): return self
.node
.cleanup()
185 def write_bam_file(self
, fname
): return self
.node
.write_bam_file(fname
)
187 def attach_node(self
, name
):
188 return P3dNode(self
.node
.attach_new_node(name
))
190 def add_shape(self
, shape
):
191 return self
.node
.node().add_shape(shape
._mesh
_shape
)
192 #TODO: don't access a protected member
195 def name(self
): return self
.node
.get_name()
198 def node(self
): return self
.nodepath
201 def p3dnode(self
): return self
.node
.node()
203 def set_pos(self
, pos
): return self
.node
.set_pos(pos
._vec
)
204 #TODO: don't access a protected member
206 def get_pos(self
, other
=None):
207 return self
.node
.get_pos(* [] if other
is None else [other
.node
])
210 def x(self
): return self
.node
.get_x()
213 def y(self
): return self
.node
.get_y()
216 def z(self
): return self
.node
.get_z()
219 def hpr(self
): return self
.node
.get_hpr()
222 def h(self
): return self
.node
.get_h()
225 def p(self
): return self
.node
.get_p()
228 def r(self
): return self
.node
.get_r()
231 def scale(self
): return self
.node
.get_scale()
234 def is_empty(self
): return self
.node
.is_empty()
236 def get_relative_vector(self
, node
, vec
):
237 return self
.node
.get_relative_vector(node
.node
, vec
)
239 def set_material(self
, mat
): return self
.node
.set_material(mat
, 1)
241 def set_python_tag(self
, name
, val
):
242 return self
.node
.set_python_tag(name
, val
)
244 def get_distance(self
, other_node
):
245 return self
.node
.get_distance(other_node
.node
)
247 def reparent_to(self
, parent
): return self
.node
.reparent_to(parent
.node
)
249 def wrt_reparent_to(self
, parent
):
250 return self
.node
.wrt_reparent_to(parent
.node
)
253 def __get_pandanode(nodepath
):
254 if nodepath
.has_python_tag('libnode'):
255 return nodepath
.get_python_tag('libnode')
256 return P3dNode(nodepath
)
258 def find_all_matches(self
, name
):
259 nodes
= self
.node
.find_all_matches(name
)
260 return [self
.__get
_pandanode
(node
) for node
in nodes
]
262 def find(self
, name
):
263 model
= self
.node
.find(name
)
264 if model
: return self
.__get
_pandanode
(model
)
267 self
.node
.prepare_scene(base
.win
.get_gsg()) # crash with texture.set_format
268 self
.node
.premunge_scene(base
.win
.get_gsg())
270 def hide(self
, mask
=None):
271 return self
.node
.hide(*[] if mask
is None else [mask
])
274 def tight_bounds(self
): return self
.node
.get_tight_bounds()
277 def parent(self
): return self
.node
.get_parent()
280 def children(self
): return self
.node
.get_children()
282 def destroy(self
): return self
.node
.remove_node()
287 def __init__(self
, filepath
, anim_dct
):
288 self
.node
= Actor(filepath
, anim_dct
)
290 def loop(self
, val
): return self
.node
.loop(val
)
292 def reparent_to(self
, node
): self
.node
.reparent_to(node
)
295 def name(self
): return self
.node
.get_name()
298 self
.node
.prepare_scene(base
.win
.get_gsg())
299 self
.node
.premunge_scene(base
.win
.get_gsg())
302 self
.node
.node().set_bounds(OmniBoundingVolume())
303 self
.node
.node().set_final(True)
305 def destroy(self
): self
.node
.cleanup()
308 class P3dAmbientLight
:
310 def __init__(self
, color
):
311 ambient_lgt
= P3DAmbientLight('ambient light')
312 ambient_lgt
.set_color(color
)
313 self
.ambient_np
= render
.attach_new_node(ambient_lgt
)
314 render
.set_light(self
.ambient_np
)
317 render
.clear_light(self
.ambient_np
)
318 self
.ambient_np
.remove_node()
323 def __init__(self
, mask
=None):
324 self
.spot_lgt
= render
.attach_new_node(P3DSpotlight('spot'))
325 snode
= self
.spot_lgt
.node()
326 snode
.set_scene(render
)
327 snode
.set_shadow_caster(True, 1024, 1024)
328 snode
.get_lens().set_fov(40)
329 snode
.get_lens().set_near_far(20, 200)
330 if mask
: snode
.set_camera_mask(mask
)
331 render
.set_light(self
.spot_lgt
)
333 def set_pos(self
, pos
): return self
.spot_lgt
.set_pos(*pos
)
335 def look_at(self
, pos
): return self
.spot_lgt
.look_at(*pos
)
337 def set_color(self
, color
): return self
.spot_lgt
.set_color(*color
)
340 render
.clear_light(self
.spot_lgt
)
341 self
.spot_lgt
.remove_node()