ya2 · news · projects · code · about

ee59d7d1130df0381fc859590ad9151e59afae47
[pmachines.git] / game / sidepanel.py
1 from textwrap import dedent
2 from panda3d.core import GeomVertexData, GeomVertexFormat, Geom, \
3 GeomVertexWriter, GeomTriangles, GeomNode, Shader, Point3, Plane, Vec3
4 from ya2.lib.p3d.gfx import P3dGfxMgr
5
6
7 class SidePanel:
8
9 def __init__(self, world, plane_node, top_l, bottom_r, y, items):
10 self._world = world
11 self._plane_node = plane_node
12 self._set((-1, 1), y)
13 self.update(items)
14
15 def update(self, items):
16 p_from, p_to = P3dGfxMgr.world_from_to((-1, 1))
17 for hit in self._world.ray_test_all(p_from, p_to).get_hits():
18 if hit.get_node() == self._plane_node:
19 pos = hit.get_hit_pos()
20 y = 0
21 corner = -20, 20
22 for item in items:
23 if not item._instantiated:
24 bounds = item._np.get_tight_bounds()
25 if bounds[1][1] > y:
26 y = bounds[1][1]
27 icorner = item.get_corner()
28 icorner = P3dGfxMgr.screen_coord(icorner)
29 if icorner[0] > corner[0]:
30 corner = icorner[0], corner[1]
31 if icorner[1] < corner[1]:
32 corner = corner[0], icorner[1]
33 self._set((pos[0], pos[2]), y)
34 bounds = self._np.get_tight_bounds()
35 corner3d = bounds[1][0], bounds[1][1], bounds[0][2]
36 corner2d = P3dGfxMgr.screen_coord(corner3d)
37 plane = Plane(Vec3(0, 1, 0), y)
38 pos3d, near_pt, far_pt = Point3(), Point3(), Point3()
39 ar, margin = base.get_aspect_ratio(), .04
40 x = corner[0] / ar if ar >= 1 else corner[0]
41 z = corner[1] * ar if ar < 1 else corner[1]
42 x += margin / ar if ar >= 1 else margin
43 z -= margin * ar if ar < 1 else margin
44 base.camLens.extrude((x, z), near_pt, far_pt)
45 plane.intersects_line(
46 pos3d, render.get_relative_point(base.camera, near_pt),
47 render.get_relative_point(base.camera, far_pt))
48 corner_pos3d, near_pt, far_pt = Point3(), Point3(), Point3()
49 base.camLens.extrude((-1, 1), near_pt, far_pt)
50 plane.intersects_line(
51 corner_pos3d, render.get_relative_point(base.camera, near_pt),
52 render.get_relative_point(base.camera, far_pt))
53 self._np.set_pos((pos3d + corner_pos3d) / 2)
54 scale = Vec3(pos3d[0] - corner_pos3d[0], 1, corner_pos3d[2] - pos3d[2])
55 self._np.set_scale(scale)
56
57 def _set(self, pos, y):
58 if hasattr(self, '_np'):
59 self._np.remove_node()
60 vdata = GeomVertexData('quad', GeomVertexFormat.get_v3(), Geom.UHStatic)
61 vdata.setNumRows(2)
62 vertex = GeomVertexWriter(vdata, 'vertex')
63 vertex.add_data3(.5, 0, -.5)
64 vertex.add_data3(.5, 0, .5)
65 vertex.add_data3(-.5, 0, .5)
66 vertex.add_data3(-.5, 0, -.5)
67 prim = GeomTriangles(Geom.UHStatic)
68 prim.add_vertices(0, 1, 2)
69 prim.add_vertices(0, 2, 3)
70 prim.close_primitive()
71 geom = Geom(vdata)
72 geom.add_primitive(prim)
73 node = GeomNode('gnode')
74 node.add_geom(geom)
75 self._np = render.attach_new_node(node)
76 self._np.setTransparency(True)
77 self._np.set_pos(pos[0], y, pos[1])
78 vert = '''\
79 #version 130
80 uniform mat4 p3d_ModelViewProjectionMatrix;
81 in vec4 p3d_Vertex;
82 void main() {
83 gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; }'''
84 frag = '''\
85 #version 130
86 out vec4 p3d_FragColor;
87 void main() {
88 p3d_FragColor = vec4(.04, .04, .04, .08); }'''
89 self._np.set_shader(Shader.make(Shader.SL_GLSL, dedent(vert), dedent(frag)))
90 # mat = Material()
91 # mat.set_base_color((1, 1, 1, 1))
92 # mat.set_emission((1, 1, 1, 1))
93 # mat.set_metallic(.5)
94 # mat.set_roughness(.5)
95 # np.set_material(mat)
96 # texture_sz = 64
97 # base_color_pnm = PNMImage(texture_sz, texture_sz)
98 # base_color_pnm.fill(.1, .1, .1)
99 # base_color_pnm.add_alpha()
100 # base_color_pnm.alpha_fill(.04)
101 # base_color_tex = Texture('base color')
102 # base_color_tex.load(base_color_pnm)
103 # ts = TextureStage('base color')
104 # ts.set_mode(TextureStage.M_modulate)
105 # np.set_texture(ts, base_color_tex)
106 # emission_pnm = PNMImage(texture_sz, texture_sz)
107 # emission_pnm.fill(0, 0, 0)
108 # emission_tex = Texture('emission')
109 # emission_tex.load(emission_pnm)
110 # ts = TextureStage('emission')
111 # ts.set_mode(TextureStage.M_emission)
112 # np.set_texture(ts, emission_tex)
113 # metal_rough_pnm = PNMImage(texture_sz, texture_sz)
114 # ambient_occlusion = 1
115 # roughness = .5
116 # metallicity = .5
117 # metal_rough_pnm.fill(ambient_occlusion, roughness, metallicity)
118 # metal_rough_tex = Texture('ao metal roughness')
119 # metal_rough_tex.load(metal_rough_pnm)
120 # ts = TextureStage('ao metal roughness')
121 # ts.set_mode(TextureStage.M_selector)
122 # np.set_texture(ts, metal_rough_tex)
123 # normal_pnm = PNMImage(texture_sz, texture_sz)
124 # normal_pnm.fill(.5, .5, .1)
125 # normal_tex = Texture('normals')
126 # normal_tex.load(normal_pnm)
127 # ts = TextureStage('normals')
128 # ts.set_mode(TextureStage.M_normal)
129 # np.set_texture(ts, normal_tex)
130
131 def destroy(self):
132 self._np.remove_node()