def make_circle(scene: core.NodePath, position: core.Point3, radius: float, point_count: int): vertex_data = _make_vertex_data(point_count) position_writer = core.GeomVertexWriter(vertex_data, "vertex") colour_writer = core.GeomVertexWriter(vertex_data, "color") for index in range(point_count): theta = (2 * math.pi * index) / point_count x = math.cos(theta) * radius y = math.sin(theta) * radius position_writer.add_data3(position.x + x, position.y + y, position.z) colour_writer.add_data4(1, 1, 1, 1) primitive = core.GeomTriangles(core.Geom.UH_static) for index in range(1, point_count + 1): point_2 = (index + 1) % point_count point_3 = (index + 2) % point_count primitive.add_vertices(0, point_2, point_3) primitive.close_primitive() geometry = core.Geom(vertex_data) geometry.add_primitive(primitive) geometry_node = core.GeomNode("circle") geometry_node.add_geom(geometry) result: core.NodePath = scene.attach_new_node(geometry_node) result.set_two_sided(True) result.set_transparency(True) return result
def _init_terrain(self): vertex_data = core.GeomVertexData('Terrain', core.GeomVertexFormat.getV3n3c4(), core.Geom.UH_static) pos = core.GeomVertexWriter(vertex_data, 'vertex') nrm = core.GeomVertexWriter(vertex_data, 'normal') col = core.GeomVertexWriter(vertex_data, 'color') for i in range(self.w): for j in range(self.h): pos.addData3f(*self.positions[i, j]) nrm.addData3f(*self.normals[i, j]) col.addData4f(self.colors[i, j], self.colors[i, j], self.colors[i, j], 1) triangles = core.GeomTriangles(core.Geom.UH_static) for i in range(self.w - 1): for j in range(self.h - 1): triangles.addVertices(i * self.h + j, i * self.h + (j + 1), (i + 1) * self.h + j) triangles.addVertices((i + 1) * self.h + (j + 1), (i + 1) * self.h + j, i * self.h + (j + 1)) geom = core.Geom(vertex_data) geom.addPrimitive(triangles) geom_node = core.GeomNode('Terrain') geom_node.addGeom(geom) self.terrain_np = self.model_np.attachNewNode(geom_node)
def render_heightmap(self, heights, cell_size, colours=None): form = core.GeomVertexFormat.get_v3n3c4() vdata = core.GeomVertexData('terrain', form, core.Geom.UHStatic) vdata.setNumRows(len(heights)) vertex = core.GeomVertexWriter(vdata, 'vertex') normal = core.GeomVertexWriter(vdata, 'normal') colour = core.GeomVertexWriter(vdata, 'color') for y in range(heights.shape[1]): for x in range(heights.shape[0]): vertex.addData3(x * cell_size, y * cell_size, heights[x][y]) if not colours is None: r, g, b = colours[x][y] colour.addData4(r, g, b, 1) else: colour.addData4(0.5, 0.5, 0.5, 1) normal.addData3(calculate_normal(heights, cell_size, x, y)) prim = core.GeomTriangles(core.Geom.UHStatic) for y in range(heights.shape[1] - 1): for x in range(heights.shape[0] - 1): base = x + y * heights.shape[0] idx = y * heights.shape[0] + x prim.add_vertices(base, base + heights.shape[0] + 1, base + heights.shape[0]) prim.add_vertices(base, base + 1, base + heights.shape[0] + 1) geom = core.Geom(vdata) geom.addPrimitive(prim) node = core.GeomNode('gnode') node.addGeom(geom) self.render.attachNewNode(node)
def test_geom_triangles_adjacency(): prim = core.GeomTriangles(core.GeomEnums.UH_static) prim.add_vertex(0) prim.add_vertex(1) prim.add_vertex(2) prim.close_primitive() prim.add_vertex(2) prim.add_vertex(1) prim.add_vertex(3) prim.close_primitive() adj = prim.make_adjacency() verts = adj.get_vertex_list() assert tuple(verts) == ( 0, 0, 1, 3, 2, 2, 2, 0, 1, 1, 3, 3, )
def __init__(self, name='noname', no_texcoord=False, tangents=True): self._name = name self._no_texcoord = no_texcoord self._tangents = tangents if no_texcoord and not tangents: self._vdata = core.GeomVertexData( self._name, core.GeomVertexFormat.get_v3n3c4(), core.Geom.UH_static) elif tangents: va_format = core.GeomVertexArrayFormat() va_format.add_column('vertex', 3, core.Geom.NT_float32, core.Geom.C_point) va_format.add_column('normal', 3, core.Geom.NT_float32, core.Geom.C_vector) va_format.add_column('tangent', 3, core.Geom.NT_float32, core.Geom.C_vector) va_format.add_column('binormal', 3, core.Geom.NT_float32, core.Geom.C_vector) va_format.add_column('color', 4, core.Geom.NT_float32, core.Geom.C_color) if not no_texcoord: va_format.add_column('texcoord', 2, core.Geom.NT_float32, core.Geom.C_texcoord) # noinspection PyCallByClass va_format = core.GeomVertexFormat.register_format(va_format) self._vdata = core.GeomVertexData(self._name, va_format, core.Geom.UH_static) else: self._vdata = core.GeomVertexData( self._name, core.GeomVertexFormat.get_v3n3c4t2(), core.Geom.UH_static) self._vwriter = core.GeomVertexWriter(self._vdata, 'vertex') self._nwriter = core.GeomVertexWriter(self._vdata, 'normal') if tangents: self._tawriter = core.GeomVertexWriter(self._vdata, 'tangent') self._biwriter = core.GeomVertexWriter(self._vdata, 'binormal') self._cwriter = core.GeomVertexWriter(self._vdata, 'color') if not no_texcoord: self._twriter = core.GeomVertexWriter(self._vdata, 'texcoord') else: self._twriter = None self._prim = core.GeomTriangles(core.Geom.UH_static) self._v_id = 0 self.set_num_rows = self._vdata.set_num_rows
def half_screen_quad(): vdata = p3d.GeomVertexData('half_screen_quad', p3d.GeomVertexFormat.get_v3n3c4t2(), p3d.Geom.UHStatic) vdata.set_num_rows(4) vertex = p3d.GeomVertexWriter(vdata, 'vertex') normal = p3d.GeomVertexWriter(vdata, 'normal') color = p3d.GeomVertexWriter(vdata, 'color') texcoord = p3d.GeomVertexWriter(vdata, 'texcoord') scale = 10 vertex.addData3f(-scale, 5, scale) normal.addData3f(0, 1, 0) color.addData4f(0.1, 0.2, 0.3, 1.0) texcoord.addData2f(0.0, 0.0) vertex.addData3f(0, 5, scale) normal.addData3f(0, 1, 0) color.addData4f(0.1, 0.2, 0.3, 1.0) texcoord.addData2f(0.0, 0.1) vertex.addData3f(0, 5, -scale) normal.addData3f(0, 1, 0) color.addData4f(0.1, 0.2, 0.3, 1.0) texcoord.addData2f(0.0, 0.2) vertex.addData3f(-scale, 5, -scale) normal.addData3f(0, 1, 0) color.addData4f(0.1, 0.2, 0.3, 1.0) texcoord.addData2f(0.0, 0.3) prim = p3d.GeomTriangles(p3d.Geom.UHStatic) prim.addVertices(2, 1, 0) prim.addVertices(0, 3, 2) geom = p3d.Geom(vdata) geom.addPrimitive(prim) node = p3d.GeomNode('gnode') node.addGeom(geom) nodepath = p3d.NodePath(node) return nodepath
def _make(vformat, vertices, faces): vdata = p3d.GeomVertexData('#vdata', vformat, p3d.Geom.UHStatic) vdata.unclean_set_num_rows(len(vertices)) vdata.modify_array_handle(0).set_subdata(0, len(vertices), vertices.astype(np.float32)) prim = p3d.GeomTriangles(p3d.Geom.UHStatic) prim.clear_vertices() for v1, v2, v3 in faces: prim.add_vertices(v1, v2, v3) prim.close_primitive() geom = p3d.Geom(vdata) geom.add_primitive(prim) node = p3d.GeomNode('#geom') node.add_geom(geom) return node
def _create_dot_geom(self, dot_rad, n_points): vertex_data = core.GeomVertexData('DotsRad' + str(dot_rad), core.GeomVertexFormat.getV3(), core.Geom.UH_static) pos = core.GeomVertexWriter(vertex_data, 'vertex') pos.addData3f(0, 0, 0) for i in range(n_points): pos.addData3f(dot_rad * cos(2 * pi * i / n_points), dot_rad * sin(2 * pi * i / n_points), 0) triangles = core.GeomTriangles(core.Geom.UH_static) for i in range(1, n_points): triangles.addVertices(0, i, i + 1) triangles.addVertices(0, n_points, 1) geom = core.Geom(vertex_data) geom.addPrimitive(triangles) return geom
def make_arc( scene: core.NodePath, position: core.Point3, radius: float, theta_degrees: float, point_count: int, ): theta_radians = math.radians(theta_degrees) vertex_data = _make_vertex_data(point_count + 1) position_writer = core.GeomVertexWriter(vertex_data, "vertex") colour_writer = core.GeomVertexWriter(vertex_data, "color") position_writer.add_data3(position.x, position.y, position.z) colour_writer.add_data4(1, 1, 1, 1) for index in range(point_count): theta = (theta_radians * index) / (point_count - 1) x = math.cos(theta) * radius y = math.sin(theta) * radius position_writer.add_data3(position.x + x, position.y + y, position.z) colour_writer.add_data4(1, 1, 1, 1) primitive = core.GeomTriangles(core.Geom.UH_static) total_point_count = point_count + 1 for index in range(point_count): point_2 = (index + 1) % total_point_count point_3 = (index + 2) % total_point_count primitive.add_vertices(0, point_2, point_3) primitive.close_primitive() geometry = core.Geom(vertex_data) geometry.add_primitive(primitive) geometry_node = core.GeomNode("arc") geometry_node.add_geom(geometry) result: core.NodePath = scene.attach_new_node(geometry_node) result.set_two_sided(True) result.set_transparency(True) return result
def __init__(self, name, master): self.name = name self.master = master self.primitive = core.GeomTriangles(core.Geom.UHStatic) self.primitive.setIndexType(core.Geom.NTUint32) self.indices = []
def _make_wall_part( self, all_geometry: sector_geometry.SectorGeometry, peg: float, floor_z_at_point_callback: typing.Callable[[core.Point2], float], ceiling_z_at_point_callback: typing.Callable[[core.Point2], float], part: sector_geometry.GeometryPart, stat: map_data.wall.Stat = None, ): if stat is None: stat = self._wall.wall.stat point_1_bottom = floor_z_at_point_callback(self.point_1) point_2_bottom = floor_z_at_point_callback(self.point_2) point_1_top = ceiling_z_at_point_callback(self.point_1) point_2_top = ceiling_z_at_point_callback(self.point_2) if point_1_top < point_1_bottom or point_2_top < point_2_bottom: vertex_data = core.GeomVertexData(part.part, constants.VERTEX_FORMAT, core.Geom.UH_static) vertex_data.set_num_rows(4) position_writer = core.GeomVertexWriter(vertex_data, "vertex") colour_write = core.GeomVertexWriter(vertex_data, "color") texcoord_writer = core.GeomVertexWriter(vertex_data, "texcoord") shade = self._shade_to_colour_channel(self.shade) colour_write.add_data4(shade, shade, shade, 1) colour_write.add_data4(shade, shade, shade, 1) colour_write.add_data4(shade, shade, shade, 1) colour_write.add_data4(shade, shade, shade, 1) texture_size = all_geometry.get_tile_dimensions(part.picnum) if texture_size.x < 1: texture_size.x = 1 if texture_size.y < 1: texture_size.y = 1 if stat.xflip: texture_size.x = -texture_size.x if stat.yflip: texture_size.y = -texture_size.y uv_1, uv_2, uv_3, uv_4 = self._get_texture_coordinates( texture_size, peg, point_1_bottom, point_1_top, point_2_bottom, point_2_top, ) position_writer.add_data3(self.point_1.x, self.point_1.y, point_1_bottom) texcoord_writer.add_data2(uv_1) position_writer.add_data3(self.point_1.x, self.point_1.y, point_1_top) texcoord_writer.add_data2(uv_2) position_writer.add_data3(self.point_2.x, self.point_2.y, point_2_top) texcoord_writer.add_data2(uv_3) position_writer.add_data3(self.point_2.x, self.point_2.y, point_2_bottom) texcoord_writer.add_data2(uv_4) primitive = core.GeomTriangles(core.Geom.UH_static) primitive.add_vertices(0, 2, 1) primitive.add_vertices(0, 3, 2) primitive.close_primitive() geometry = core.Geom(vertex_data) geometry.add_primitive(primitive) all_geometry.add_geometry(geometry, part) all_geometry.add_highlight_geometry(geometry, f"{self._name}_{part.part}") return True return False
def create_sphere(parent_node, units): vdata = pcore.GeomVertexData('name', pcore.GeomVertexFormat.getV3t2(), pcore.Geom.UHDynamic) vertex_writer = pcore.GeomVertexWriter(vdata, 'vertex') texcoord_writer = pcore.GeomVertexWriter(vdata, 'texcoord') prim_wall = pcore.GeomTriangles(pcore.Geom.UHStatic) vertex_count = 0 for i in range(units): phi1 = i / float(units) * 2 * 3.1452 phi2 = (i + 1) / float(units) * 2 * 3.1452 for j in range(int(np.floor(units / 2))): theta1 = j / float(units / 2) * 1 * 3.1452 theta2 = (j + 1) / float(units / 2) * 1 * 3.1452 x1 = math.cos(phi1) * math.sin(theta1) y1 = math.sin(phi1) * math.sin(theta1) z1 = math.cos(theta1) x2 = math.cos(phi2) * math.sin(theta1) y2 = math.sin(phi2) * math.sin(theta1) z2 = math.cos(theta1) x3 = math.cos(phi1) * math.sin(theta2) y3 = math.sin(phi1) * math.sin(theta2) z3 = math.cos(theta2) x4 = math.cos(phi2) * math.sin(theta2) y4 = math.sin(phi2) * math.sin(theta2) z4 = math.cos(theta2) vertex_writer.addData3f(x1, y1, z1) vertex_writer.addData3f(x2, y2, z2) vertex_writer.addData3f(x3, y3, z3) texcoord_writer.addData2f( math.sin(theta1) * math.cos(phi1), math.sin(theta1) * math.sin(phi1)) texcoord_writer.addData2f( math.sin(theta1) * math.cos(phi2), math.sin(theta1) * math.sin(phi2)) texcoord_writer.addData2f( math.sin(theta2) * math.cos(phi1), math.sin(theta2) * math.sin(phi1)) vertex_count = vertex_count + 3 prim_wall.addConsecutiveVertices(vertex_count - 3, 3) prim_wall.closePrimitive() vertex_writer.addData3f(x2, y2, z2) vertex_writer.addData3f(x3, y3, z3) vertex_writer.addData3f(x4, y4, z4) texcoord_writer.addData2f( math.sin(theta1) * math.cos(phi2), math.sin(theta1) * math.sin(phi2)) texcoord_writer.addData2f( math.sin(theta2) * math.cos(phi1), math.sin(theta2) * math.sin(phi1)) texcoord_writer.addData2f( math.sin(theta2) * math.cos(phi2), math.sin(theta2) * math.sin(phi2)) vertex_count = vertex_count + 3 prim_wall.addConsecutiveVertices(vertex_count - 3, 3) prim_wall.closePrimitive() geom_wall = pcore.Geom(vdata) geom_wall.addPrimitive(prim_wall) sphere = parent_node.attachNewNode("sphere") sphere_geomnode = pcore.GeomNode("sphere") sphere_geomnode.addGeom(geom_wall) sphere_model = sphere.attachNewNode(sphere_geomnode) return (sphere, sphere_model)
def _add_geometry( self, all_geometry: sector_geometry.SectorGeometry, height_callback: typing.Callable[[core.Vec2], float], x_panning: float, y_panning: float, stat: map_data.sector.Stat, shade: float, part: sector_geometry.GeometryPart, ): shade = self._shade_to_colour_channel(shade) for sub_sector in drawing_sector.Sector(self._walls).get_sub_sectors(): polygon = drawing_sector.Sector.get_wall_bunch_points(sub_sector.outer_wall) self._cleanup_polygon(polygon) holes = [] for wall in sub_sector.inner_walls: hole = drawing_sector.Sector.get_wall_bunch_points(wall) self._cleanup_polygon(hole) holes.append(hole) triangulator = core.Triangulator() for point in polygon: index = triangulator.add_vertex(point.x, point.y) triangulator.add_polygon_vertex(index) for hole in holes: triangulator.begin_hole() for point in hole: index = triangulator.add_vertex(point.x, point.y) triangulator.add_hole_vertex(index) triangulator.triangulate() vertex_data = core.GeomVertexData( "shape", constants.VERTEX_FORMAT, core.Geom.UH_static ) vertex_data.set_num_rows(triangulator.get_num_vertices()) position_writer = core.GeomVertexWriter(vertex_data, "vertex") colour_writer = core.GeomVertexWriter(vertex_data, "color") texcoord_writer = core.GeomVertexWriter(vertex_data, "texcoord") first_wall = self._walls[0] direction_segment = first_wall.line_segment first_wall_orthogonal = first_wall.get_orthogonal_vector() orthogonal_segment = segment.Segment( first_wall.point_1, first_wall.point_1 + first_wall_orthogonal ) texture_size = all_geometry.get_tile_dimensions(part.picnum) if texture_size.x < 1: texture_size.x = 1 if texture_size.y < 1: texture_size.y = 1 for point in triangulator.get_vertices(): point_2d = core.Point2(point.x, point.y) position_writer.add_data3( point_2d.x, point_2d.y, height_callback(point_2d) ) colour_writer.add_data4(shade, shade, shade, 1) if stat.align: new_y = direction_segment.get_point_distance( point_2d, ignore_on_line=True ) new_x = orthogonal_segment.get_point_distance( point_2d, ignore_on_line=True ) point_2d = core.Point2(new_x, new_y) if stat.swapxy: y_offset = point_2d.x + x_panning x_offset = point_2d.y + y_panning else: x_offset = point_2d.x + x_panning y_offset = point_2d.y + y_panning if stat.xflip: x_offset = -x_offset if stat.yflip: y_offset = -y_offset texture_coordinate_x = (x_offset / texture_size.x) / 16 texture_coordinate_y = (y_offset / texture_size.y) / 16 if stat.expand: texture_coordinate_x *= 2 texture_coordinate_y *= 2 texcoord_writer.add_data2(texture_coordinate_x, texture_coordinate_y) primitive = core.GeomTriangles(core.Geom.UH_static) if part.is_floor: for triangle_index in range(triangulator.get_num_triangles()): primitive.add_vertices( triangulator.get_triangle_v2(triangle_index), triangulator.get_triangle_v1(triangle_index), triangulator.get_triangle_v0(triangle_index), ) else: for triangle_index in range(triangulator.get_num_triangles()): primitive.add_vertices( triangulator.get_triangle_v0(triangle_index), triangulator.get_triangle_v1(triangle_index), triangulator.get_triangle_v2(triangle_index), ) primitive.close_primitive() geometry = core.Geom(vertex_data) geometry.add_primitive(primitive) if not stat.parallax and part.picnum != 504: all_geometry.add_geometry(geometry, part) else: part.node = None all_geometry.add_highlight_geometry(geometry, part.part)
def create_primitive(self): return core.GeomTriangles(core.Geom.UH_static)