--- /dev/null
+from textwrap import dedent
+from panda3d.core import GeomVertexData, GeomVertexFormat, Geom, \
+ GeomVertexWriter, GeomTriangles, GeomNode, Shader, Point3
+
+
+class SidePanel:
+
+ def __init__(self, world, plane_node, top_l, bottom_r, y):
+ self._world = world
+ self._plane_node = plane_node
+ self._set(top_l, bottom_r, y)
+
+ def update(self, items):
+ p_from, p_to = Point3(), Point3() # in camera coordinates
+ base.camLens.extrude((-1, 1), p_from, p_to)
+ p_from = render.get_relative_point(base.cam, p_from) # global coords
+ p_to = render.get_relative_point(base.cam, p_to) # global coords
+ for hit in self._world.ray_test_all(p_from, p_to).get_hits():
+ if hit.get_node() == self._plane_node:
+ pos = hit.get_hit_pos()
+ top_l = pos[0] - .8, pos[2] + .8
+ bottom_r = pos[0], pos[2]
+ y = 1
+ for item in items:
+ if not item._instantiated:
+ bounds = item._np.get_tight_bounds()
+ if bounds[1][0] > bottom_r[0]:
+ bottom_r = bounds[1][0], bottom_r[1]
+ if bounds[0][2] < bottom_r[1]:
+ bottom_r = bottom_r[0], bounds[0][2]
+ if bounds[1][1] > y:
+ y = bounds[1][1]
+ bottom_r = bottom_r[0] + .3, bottom_r[1] - .3
+ self._set(top_l, bottom_r, y)
+
+ def _set(self, top_l, bottom_r, y):
+ if hasattr(self, '_np'):
+ self._np.remove_node()
+ vdata = GeomVertexData('quad', GeomVertexFormat.get_v3(), Geom.UHStatic)
+ vdata.setNumRows(2)
+ vertex = GeomVertexWriter(vdata, 'vertex')
+ vertex.add_data3(bottom_r[0], y, bottom_r[1])
+ vertex.add_data3(bottom_r[0], y, top_l[1])
+ vertex.add_data3(top_l[0], y, top_l[1])
+ vertex.add_data3(top_l[0], y, bottom_r[1])
+ prim = GeomTriangles(Geom.UHStatic)
+ prim.add_vertices(0, 1, 2)
+ prim.add_vertices(0, 2, 3)
+ prim.close_primitive()
+ geom = Geom(vdata)
+ geom.add_primitive(prim)
+ node = GeomNode('gnode')
+ node.add_geom(geom)
+ self._np = render.attach_new_node(node)
+ self._np.setTransparency(True)
+ vert = '''\
+ #version 150
+ uniform mat4 p3d_ModelViewProjectionMatrix;
+ in vec4 p3d_Vertex;
+ void main() {
+ gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; }'''
+ frag = '''\
+ #version 150
+ out vec4 p3d_FragColor;
+ void main() {
+ p3d_FragColor = vec4(.04, .04, .04, .06); }'''
+ self._np.set_shader(Shader.make(Shader.SL_GLSL, dedent(vert), dedent(frag)))
+ # mat = Material()
+ # mat.set_base_color((1, 1, 1, 1))
+ # mat.set_emission((1, 1, 1, 1))
+ # mat.set_metallic(.5)
+ # mat.set_roughness(.5)
+ # np.set_material(mat)
+ # texture_sz = 64
+ # base_color_pnm = PNMImage(texture_sz, texture_sz)
+ # base_color_pnm.fill(.1, .1, .1)
+ # base_color_pnm.add_alpha()
+ # base_color_pnm.alpha_fill(.04)
+ # base_color_tex = Texture('base color')
+ # base_color_tex.load(base_color_pnm)
+ # ts = TextureStage('base color')
+ # ts.set_mode(TextureStage.M_modulate)
+ # np.set_texture(ts, base_color_tex)
+ # emission_pnm = PNMImage(texture_sz, texture_sz)
+ # emission_pnm.fill(0, 0, 0)
+ # emission_tex = Texture('emission')
+ # emission_tex.load(emission_pnm)
+ # ts = TextureStage('emission')
+ # ts.set_mode(TextureStage.M_emission)
+ # np.set_texture(ts, emission_tex)
+ # metal_rough_pnm = PNMImage(texture_sz, texture_sz)
+ # ambient_occlusion = 1
+ # roughness = .5
+ # metallicity = .5
+ # metal_rough_pnm.fill(ambient_occlusion, roughness, metallicity)
+ # metal_rough_tex = Texture('ao metal roughness')
+ # metal_rough_tex.load(metal_rough_pnm)
+ # ts = TextureStage('ao metal roughness')
+ # ts.set_mode(TextureStage.M_selector)
+ # np.set_texture(ts, metal_rough_tex)
+ # normal_pnm = PNMImage(texture_sz, texture_sz)
+ # normal_pnm.fill(.5, .5, .1)
+ # normal_tex = Texture('normals')
+ # normal_tex.load(normal_pnm)
+ # ts = TextureStage('normals')
+ # ts.set_mode(TextureStage.M_normal)
+ # np.set_texture(ts, normal_tex)