Commit | Line | Data |
---|---|---|
a5dc83f4 FC |
1 | from textwrap import dedent |
2 | from panda3d.core import GeomVertexData, GeomVertexFormat, Geom, \ | |
852fb5ae | 3 | GeomVertexWriter, GeomTriangles, GeomNode, Shader, Point3, Plane, Vec3 |
53ddf3c3 | 4 | from ya2.lib.p3d.gfx import P3dGfxMgr |
a5dc83f4 FC |
5 | |
6 | ||
7 | class SidePanel: | |
8 | ||
5964572b | 9 | def __init__(self, world, plane_node, top_l, bottom_r, y, items): |
a5dc83f4 FC |
10 | self._world = world |
11 | self._plane_node = plane_node | |
13263131 | 12 | self._set((-1, 1), y) |
5964572b | 13 | self.update(items) |
a5dc83f4 FC |
14 | |
15 | def update(self, items): | |
13263131 | 16 | p_from, p_to = P3dGfxMgr.world_from_to((-1, 1)) |
a5dc83f4 FC |
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() | |
13263131 FC |
20 | y = 0 |
21 | corner = -20, 20 | |
a5dc83f4 FC |
22 | for item in items: |
23 | if not item._instantiated: | |
24 | bounds = item._np.get_tight_bounds() | |
a5dc83f4 FC |
25 | if bounds[1][1] > y: |
26 | y = bounds[1][1] | |
13263131 FC |
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) | |
852fb5ae FC |
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) | |
a5dc83f4 | 56 | |
13263131 | 57 | def _set(self, pos, y): |
a5dc83f4 FC |
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') | |
13263131 FC |
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) | |
a5dc83f4 FC |
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) | |
13263131 | 77 | self._np.set_pos(pos[0], y, pos[1]) |
a5dc83f4 | 78 | vert = '''\ |
c83fc94b | 79 | #version 130 |
a5dc83f4 FC |
80 | uniform mat4 p3d_ModelViewProjectionMatrix; |
81 | in vec4 p3d_Vertex; | |
82 | void main() { | |
83 | gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; }''' | |
84 | frag = '''\ | |
c83fc94b | 85 | #version 130 |
a5dc83f4 FC |
86 | out vec4 p3d_FragColor; |
87 | void main() { | |
13263131 | 88 | p3d_FragColor = vec4(.04, .04, .04, .08); }''' |
a5dc83f4 FC |
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) | |
5964572b FC |
130 | |
131 | def destroy(self): | |
132 | self._np.remove_node() |