ya2 · news · projects · code · about

removed uml diagrams
[pmachines.git] / ya2 / lib / p3d / gfx.py
CommitLineData
8ee66edd
FC
1import datetime
2from logging import debug, info
3from os import getcwd
4from os.path import exists, dirname
5from panda3d.core import get_model_path, AntialiasAttrib, PandaNode, \
6 LightRampAttrib, Camera, OrthographicLens, NodePath, OmniBoundingVolume, \
7 AmbientLight as P3DAmbientLight, Spotlight as P3DSpotlight, Point2, \
8 Point3, Texture
9from direct.filter.CommonFilters import CommonFilters
10from direct.actor.Actor import Actor
cb700bcc 11# from ya2.lib.p3d.p3d import LibP3d
8ee66edd
FC
12
13
64eae9c7
FC
14def set_srgb(model):
15 for texture in model.find_all_textures():
16 if texture.get_format() in [Texture.F_rgba, Texture.F_rgbm]:
17 texture.set_format(Texture.F_srgb_alpha)
18 elif texture.get_format() in [Texture.F_rgb]:
19 texture.set_format(Texture.F_srgb)
20
21
cb700bcc 22# class RenderToTexture:
8ee66edd 23
cb700bcc
FC
24# def __init__(self, size=(256, 256)):
25# self.__set_buffer(size)
26# self.__set_display_region()
27# self.__set_camera()
28# self.__set_root()
29# self.display_region.set_camera(self.camera)
8ee66edd 30
cb700bcc
FC
31# def __set_buffer(self, size):
32# self.buffer = base.win.make_texture_buffer('result buffer', size[0],
33# size[1])
34# self.buffer.set_sort(-100)
8ee66edd 35
cb700bcc
FC
36# def __set_display_region(self):
37# self.display_region = self.buffer.make_display_region()
38# self.display_region.set_sort(20)
8ee66edd 39
cb700bcc
FC
40# def __set_camera(self):
41# self.camera = NodePath(Camera('camera 2d'))
42# lens = OrthographicLens()
43# lens.set_film_size(1, 1)
44# lens.set_near_far(-1000, 1000)
45# self.camera.node().set_lens(lens)
8ee66edd 46
cb700bcc
FC
47# def __set_root(self):
48# self.root = NodePath('root')
49# self.root.set_depth_test(False)
50# self.root.set_depth_write(False)
51# self.camera.reparent_to(self.root)
8ee66edd 52
cb700bcc
FC
53# @property
54# def texture(self): return self.buffer.get_texture()
8ee66edd 55
cb700bcc
FC
56# def destroy(self):
57# base.graphicsEngine.remove_window(self.buffer)
58# if base.win: # if you close the window during a race
59# base.win.remove_display_region(self.display_region)
60# list(map(lambda node: node.remove_node(), [self.camera, self.root]))
8ee66edd
FC
61
62
63class P3dGfxMgr:
64
65 def __init__(self, model_path, antialiasing, shaders, srgb):
66 self.root = P3dNode(render)
67 self.__srgb = srgb
68 self.callbacks = {}
69 self.filters = None
70 get_model_path().append_directory(model_path)
71 if LibP3d.runtime():
72 root_dir = LibP3d.p3dpath(dirname(__file__))
73 paths = [root_dir + '/' + model_path, root_dir]
74 list(map(get_model_path().append_directory, paths))
75 render.set_shader_auto()
76 # render.set_two_sided(True) # it breaks shadows
77 if antialiasing: render.set_antialias(AntialiasAttrib.MAuto)
78 if shaders and base.win:
79 self.filters = CommonFilters(base.win, base.cam)
80
81 def load_model(self, filename, callback=None, anim=None):
82 ext = '.bam' if exists(filename + '.bam') else ''
83 if anim:
84 anim_dct = {'anim': filename + '-Anim' + ext}
85 node = P3dNode(self.set_srgb(Actor(filename + ext, anim_dct)))
86 elif callback:
87 callb = lambda model: callback(P3dNode(self.set_srgb(model)))
88 node = loader.loadModel(filename + ext, callback=callb)
89 else:
90 node = P3dNode(self.set_srgb(
91 loader.loadModel(LibP3d.p3dpath(filename + ext))))
92 return node
93
94 def set_srgb(self, model):
95 if self.__srgb:
96 for texture in model.find_all_textures():
97 if texture.get_format() in [Texture.F_rgba, Texture.F_rgbm]:
98 texture.set_format(Texture.F_srgb_alpha)
99 elif texture.get_format() in [Texture.F_rgb]:
100 texture.set_format(Texture.F_srgb)
101 return model
102
103 @staticmethod
104 def toggle_aa():
105 aa_not_none = render.get_antialias() != AntialiasAttrib.MNone
106 if render.has_antialias() and aa_not_none:
107 render.clear_antialias()
108 else: render.set_antialias(AntialiasAttrib.MAuto, 1)
109
110 def set_toon(self):
111 tmp_node = NodePath(PandaNode('temp node'))
112 tmp_node.set_attrib(LightRampAttrib.make_single_threshold(.5, .4))
113 tmp_node.set_shader_auto()
114 base.cam.node().set_initial_state(tmp_node.get_state())
115 self.filters.set_cartoon_ink(separation=1)
116
117 def set_bloom(self):
118 if not base.win: return
119 self.filters.setBloom(
120 blend=(.3, .4, .3, 0), mintrigger=.6, maxtrigger=1.0, desat=.6,
121 intensity=1.0, size='medium')
122 # default: (.3, .4, .3, 0), .6, 1, .6, 1, 'medium'
123
124 @staticmethod
125 def pos2d(node):
126 p3d = base.cam.get_relative_point(node.node, Point3(0, 0, 0))
127 p2d = Point2()
128 return p2d if base.camLens.project(p3d, p2d) else None
129
13263131
FC
130 @staticmethod
131 def screen_coord(pos):
132 new_node = NodePath('temp')
133 new_node.set_pos(pos)
134 coord3d = new_node.get_pos(base.cam)
135 new_node.remove_node()
136 coord2d = Point2()
137 base.camLens.project(coord3d, coord2d)
138 coord_r2d = Point3(coord2d[0], 0, coord2d[1])
139 coord_a2d = base.aspect2d.get_relative_point(render2d, coord_r2d)
140 return coord_a2d[0], coord_a2d[2]
141
142 @staticmethod
143 def world_from_to(pos):
144 p_from, p_to = Point3(), Point3() # in camera coordinates
145 base.camLens.extrude(pos, p_from, p_to)
146 p_from = render.get_relative_point(base.cam, p_from) # global coords
147 p_to = render.get_relative_point(base.cam, p_to) # global coords
148 return p_from, p_to
149
8ee66edd
FC
150 @property
151 def shader_support(self):
152 return base.win.get_gsg().get_supports_basic_shaders()
153
154 def screenshot(self, path=None):
155 time = datetime.datetime.now().strftime('%y%m%d%H%M%S')
156 #res = base.win.save_screenshot(Filename(path or ("yocto%s.png" % time)))
157 #debug('screenshot %s (%s)' % (path or ("yocto%s.png" % time), res))
8ce16d6c
FC
158 res = base.screenshot(path or ("pmachines%s.png" % time), False)
159 info('screenshot %s (%s; %s)' % (path or ("pmachines%s.png" % time), res, getcwd()))
8ee66edd
FC
160
161 @staticmethod
162 def enable_shader(): render.set_shader_auto()
163
164 @staticmethod
165 def disable_shader(): render.set_shader_off()
166
167 @staticmethod
168 def print_stats(two_d=True, three_d=True, analyze=True, ls=True):
169 '''Print graphics stats. They use standard output (from p3d).'''
170 info = []
171 if two_d and analyze:
172 info +=[('render2d.analyze', base.render2d.analyze)]
173 if three_d and analyze:
174 info +=[('render.analyze', base.render.analyze)]
175 if two_d and ls:
176 info +=[('render2d.ls', base.render2d.ls)]
177 if three_d and ls:
178 info +=[('render.ls', base.render.ls)]
179 for elm in info:
180 print('\n\n#####\n%s()' % elm[0])
181 elm[1]()
182
183
cb700bcc 184# class P3dNode:
8ee66edd 185
cb700bcc
FC
186# def __init__(self, nodepath):
187# self.nodepath = nodepath
188# self.node.set_python_tag('libnode', self)
8ee66edd 189
cb700bcc
FC
190# def set_collide_mask(self, mask): return self.node.set_collide_mask(mask)
191# def set_x(self, val): return self.node.set_x(val)
192# def set_y(self, val): return self.node.set_y(val)
193# def set_z(self, val): return self.node.set_z(val)
194# def set_hpr(self, val): return self.node.set_hpr(val)
195# def set_h(self, val): return self.node.set_h(val)
196# def set_p(self, val): return self.node.set_p(val)
197# def set_r(self, val): return self.node.set_r(val)
198# def set_scale(self, val): return self.node.set_scale(val)
199# def set_transparency(self, val): return self.node.set_transparency(val)
200# def set_alpha_scale(self, val): return self.node.set_alpha_scale(val)
201# def set_texture(self, texturestage, texture):
202# return self.node.set_texture(texturestage, texture)
203# def has_tag(self, name): return self.node.has_tag(name)
204# def get_tag(self, name): return self.node.get_tag(name)
205# def get_python_tag(self, name): return self.node.get_python_tag(name)
206# def remove_node(self): return self.node.remove_node()
207# def flatten_strong(self): return self.node.flatten_strong()
208# def clear_model_nodes(self): return self.node.clear_model_nodes()
209# def show(self): return self.node.show()
210# def set_depth_offset(self, val): return self.node.set_depth_offset(val)
211# def loop(self, val): return self.node.loop(val)
212# def cleanup(self): return self.node.cleanup()
213# def write_bam_file(self, fname): return self.node.write_bam_file(fname)
8ee66edd 214
cb700bcc
FC
215# def attach_node(self, name):
216# return P3dNode(self.node.attach_new_node(name))
8ee66edd 217
cb700bcc
FC
218# def add_shape(self, shape):
219# return self.node.node().add_shape(shape._mesh_shape)
220# #TODO: don't access a protected member
8ee66edd 221
cb700bcc
FC
222# @property
223# def name(self): return self.node.get_name()
8ee66edd 224
cb700bcc
FC
225# @property
226# def node(self): return self.nodepath
8ee66edd 227
cb700bcc
FC
228# @property
229# def p3dnode(self): return self.node.node()
8ee66edd 230
cb700bcc
FC
231# def set_pos(self, pos): return self.node.set_pos(pos._vec)
232# #TODO: don't access a protected member
8ee66edd 233
cb700bcc
FC
234# def get_pos(self, other=None):
235# return self.node.get_pos(* [] if other is None else [other.node])
8ee66edd 236
cb700bcc
FC
237# @property
238# def x(self): return self.node.get_x()
8ee66edd 239
cb700bcc
FC
240# @property
241# def y(self): return self.node.get_y()
8ee66edd 242
cb700bcc
FC
243# @property
244# def z(self): return self.node.get_z()
8ee66edd 245
cb700bcc
FC
246# @property
247# def hpr(self): return self.node.get_hpr()
8ee66edd 248
cb700bcc
FC
249# @property
250# def h(self): return self.node.get_h()
8ee66edd 251
cb700bcc
FC
252# @property
253# def p(self): return self.node.get_p()
8ee66edd 254
cb700bcc
FC
255# @property
256# def r(self): return self.node.get_r()
8ee66edd 257
cb700bcc
FC
258# @property
259# def scale(self): return self.node.get_scale()
8ee66edd 260
cb700bcc
FC
261# @property
262# def is_empty(self): return self.node.is_empty()
8ee66edd 263
cb700bcc
FC
264# def get_relative_vector(self, node, vec):
265# return self.node.get_relative_vector(node.node, vec)
8ee66edd 266
cb700bcc 267# def set_material(self, mat): return self.node.set_material(mat, 1)
8ee66edd 268
cb700bcc
FC
269# def set_python_tag(self, name, val):
270# return self.node.set_python_tag(name, val)
8ee66edd 271
cb700bcc
FC
272# def get_distance(self, other_node):
273# return self.node.get_distance(other_node.node)
8ee66edd 274
cb700bcc 275# def reparent_to(self, parent): return self.node.reparent_to(parent.node)
8ee66edd 276
cb700bcc
FC
277# def wrt_reparent_to(self, parent):
278# return self.node.wrt_reparent_to(parent.node)
8ee66edd 279
cb700bcc
FC
280# @staticmethod
281# def __get_pandanode(nodepath):
282# if nodepath.has_python_tag('libnode'):
283# return nodepath.get_python_tag('libnode')
284# return P3dNode(nodepath)
8ee66edd 285
cb700bcc
FC
286# def find_all_matches(self, name):
287# nodes = self.node.find_all_matches(name)
288# return [self.__get_pandanode(node) for node in nodes]
8ee66edd 289
cb700bcc
FC
290# def find(self, name):
291# model = self.node.find(name)
292# if model: return self.__get_pandanode(model)
8ee66edd 293
cb700bcc
FC
294# def optimize(self):
295# self.node.prepare_scene(base.win.get_gsg()) # crash with texture.set_format
296# self.node.premunge_scene(base.win.get_gsg())
8ee66edd 297
cb700bcc
FC
298# def hide(self, mask=None):
299# return self.node.hide(*[] if mask is None else [mask])
8ee66edd 300
cb700bcc
FC
301# @property
302# def tight_bounds(self): return self.node.get_tight_bounds()
8ee66edd 303
cb700bcc
FC
304# @property
305# def parent(self): return self.node.get_parent()
8ee66edd 306
cb700bcc
FC
307# @property
308# def children(self): return self.node.get_children()
8ee66edd 309
cb700bcc 310# def destroy(self): return self.node.remove_node()
8ee66edd 311
8ee66edd 312
cb700bcc
FC
313# class P3dAnimNode:
314
315# def __init__(self, filepath, anim_dct):
316# self.node = Actor(filepath, anim_dct)
317
318# def loop(self, val): return self.node.loop(val)
319
320# def reparent_to(self, node): self.node.reparent_to(node)
321
322# @property
323# def name(self): return self.node.get_name()
8ee66edd 324
cb700bcc
FC
325# def optimize(self):
326# self.node.prepare_scene(base.win.get_gsg())
327# self.node.premunge_scene(base.win.get_gsg())
8ee66edd 328
cb700bcc
FC
329# def set_omni(self):
330# self.node.node().set_bounds(OmniBoundingVolume())
331# self.node.node().set_final(True)
8ee66edd 332
cb700bcc 333# def destroy(self): self.node.cleanup()
8ee66edd
FC
334
335
cb700bcc 336# class P3dAmbientLight:
8ee66edd 337
cb700bcc
FC
338# def __init__(self, color):
339# ambient_lgt = P3DAmbientLight('ambient light')
340# ambient_lgt.set_color(color)
341# self.ambient_np = render.attach_new_node(ambient_lgt)
342# render.set_light(self.ambient_np)
8ee66edd 343
cb700bcc
FC
344# def destroy(self):
345# render.clear_light(self.ambient_np)
346# self.ambient_np.remove_node()
8ee66edd
FC
347
348
cb700bcc 349# class P3dSpotlight:
8ee66edd 350
cb700bcc
FC
351# def __init__(self, mask=None):
352# self.spot_lgt = render.attach_new_node(P3DSpotlight('spot'))
353# snode = self.spot_lgt.node()
354# snode.set_scene(render)
355# snode.set_shadow_caster(True, 1024, 1024)
356# snode.get_lens().set_fov(40)
357# snode.get_lens().set_near_far(20, 200)
358# if mask: snode.set_camera_mask(mask)
359# render.set_light(self.spot_lgt)
8ee66edd 360
cb700bcc 361# def set_pos(self, pos): return self.spot_lgt.set_pos(*pos)
8ee66edd 362
cb700bcc 363# def look_at(self, pos): return self.spot_lgt.look_at(*pos)
8ee66edd 364
cb700bcc 365# def set_color(self, color): return self.spot_lgt.set_color(*color)
8ee66edd 366
cb700bcc
FC
367# def destroy(self):
368# render.clear_light(self.spot_lgt)
369# self.spot_lgt.remove_node()