示例#1
0
    def __init__(self, whl_pos, whl_radius, car_h):
        GameObject.__init__(self)
        self.radius = whl_radius
        v_f = GeomVertexFormat.getV3()
        vdata = GeomVertexData('skid', v_f, Geom.UHDynamic)
        prim = GeomTriangles(Geom.UHStatic)
        self.vtx_cnt = 1
        self.last_pos = whl_pos
        geom = Geom(vdata)
        geom.add_primitive(prim)
        self.node = GeomNode('gnode')
        self.node.add_geom(geom)
        nodepath = self.eng.gfx.root.attach_node(self.node)
        nodepath.set_transparency(True)
        nodepath.set_depth_offset(1)
        nodepath.node.set_two_sided(True)  # for self-shadowing issues
        self.__set_material(nodepath)
        nodepath.p3dnode.set_bounds(OmniBoundingVolume())
        self.add_vertices(whl_radius, car_h)
        self.add_vertices(whl_radius, car_h)

        def alpha(time, n_p):
            if not n_p.is_empty:
                n_p.node.set_shader_input('alpha', time)
            # this if seems necessary since, if there are skidmarks and you
            # exit from the race (e.g. back to the menu), then alpha is being
            # called from the interval manager even if the interval manager
            # correctly says that there are 0 intervals.

        self.remove_seq = Sequence(
            Wait(8), LerpFunc(alpha, 8, .5, 0, 'easeInOut', [nodepath]),
            Func(nodepath.remove_node))
        self.remove_seq.start()
示例#2
0
def mesh(vertices, normals, colours, triangles):

    # TODO: Make this name meaningful in some way
    name = 'test'

    v3n3c4 = GeomVertexFormat.get_v3n3c4()
    data = GeomVertexData(name, v3n3c4, Geom.UHStatic)
    data.set_num_rows(len(vertices))

    vertex_writer = GeomVertexWriter(data, 'vertex')
    normal_writer = GeomVertexWriter(data, 'normal')
    colour_writer = GeomVertexWriter(data, 'color')

    for vertex in vertices:
        vertex_writer.add_data3(*vertex)

    for normal in normals:
        normal_writer.add_data3(*normal)

    for colour in colours:
        colour_writer.add_data4(*colour)

    prim = GeomTriangles(Geom.UHStatic)

    for triangle in triangles:
        prim.add_vertices(*triangle)

    geom = Geom(data)
    geom.add_primitive(prim)

    node = GeomNode(name)
    node.add_geom(geom)

    return node
示例#3
0
 def _make_fullscreen_tri(self):
     """ Creates the oversized triangle used for rendering """
     vformat = GeomVertexFormat.get_v3()
     vdata = GeomVertexData("vertices", vformat, Geom.UH_static)
     vdata.set_num_rows(3)
     vwriter = GeomVertexWriter(vdata, "vertex")
     vwriter.add_data3f(-1, 0, -1)
     vwriter.add_data3f(3, 0, -1)
     vwriter.add_data3f(-1, 0, 3)
     gtris = GeomTriangles(Geom.UH_static)
     gtris.add_next_vertices(3)
     geom = Geom(vdata)
     geom.add_primitive(gtris)
     geom_node = GeomNode("gn")
     geom_node.add_geom(geom)
     geom_node.set_final(True)
     geom_node.set_bounds(OmniBoundingVolume())
     tri = NodePath(geom_node)
     tri.set_depth_test(False)
     tri.set_depth_write(False)
     tri.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 10000)
     tri.set_color(Vec4(1))
     tri.set_bin("unsorted", 10)
     tri.reparent_to(self._node)
     self._tri = tri
示例#4
0
 def wrap_up(self):
     self.prim.close_primitive()
     geom = Geom(self.vdata)
     geom.add_primitive(self.prim)
     node = GeomNode('point')
     node.add_geom(geom)
     return NodePath(node)
示例#5
0
    def get_p3d_geom_node(self, name='UnnamedGeom'):
        # type: (Optional[str]) -> GeomNode
        """Returns a Panda3D GeomNode object"""
        vertex_data = GeomVertexData(name, GeomVertexFormat.get_v3c4(),
                                     Geom.UH_static)
        total_triangles = len(self.__triangles__)

        # Every triangle gets its unique set of vertices for flat shading
        num_rows = total_triangles * 3
        vertex_data.set_num_rows(num_rows)
        vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
        color_writer = GeomVertexWriter(vertex_data, 'color')
        for i in range(total_triangles):
            triangle = self.vertices[self.triangles[i]]
            vertex_writer.add_data3f(*triangle[0])
            vertex_writer.add_data3f(*triangle[1])
            vertex_writer.add_data3f(*triangle[2])
            triangle_color = self.colors[self.triangles[i]].sum(axis=0) / 3
            for _ in [0, 0, 0]:
                color_writer.add_data4f(*triangle_color)

        geom = Geom(vertex_data)
        for i in range(total_triangles):
            triangle = GeomTriangles(Geom.UH_static)
            first = i * 3
            triangle.add_vertex(first)
            triangle.add_vertex(first + 1)
            triangle.add_vertex(first + 2)
            geom.add_primitive(triangle)
        node = GeomNode(name)
        node.add_geom(geom)
        return node
 def _make_fullscreen_tri(self):
     """ Creates the oversized triangle used for rendering """
     vformat = GeomVertexFormat.get_v3()
     vdata = GeomVertexData("vertices", vformat, Geom.UH_static)
     vdata.set_num_rows(3)
     vwriter = GeomVertexWriter(vdata, "vertex")
     vwriter.add_data3f(-1, 0, -1)
     vwriter.add_data3f(3, 0, -1)
     vwriter.add_data3f(-1, 0, 3)
     gtris = GeomTriangles(Geom.UH_static)
     gtris.add_next_vertices(3)
     geom = Geom(vdata)
     geom.add_primitive(gtris)
     geom_node = GeomNode("gn")
     geom_node.add_geom(geom)
     geom_node.set_final(True)
     geom_node.set_bounds(OmniBoundingVolume())
     tri = NodePath(geom_node)
     tri.set_depth_test(False)
     tri.set_depth_write(False)
     tri.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 10000)
     tri.set_color(Vec4(1))
     tri.set_bin("unsorted", 10)
     tri.reparent_to(self._node)
     self._tri = tri
示例#7
0
class Grid:
    """A grid of lines for visual reference."""

    focus: NodePath
    node_path: NodePath
    spacing: float
    size: float

    def __init__(self, spacing: float, size: float, parent: NodePath,
                 focus: NodePath):
        self.spacing = spacing
        self.size = size
        self.focus = focus
        self._create_geom()

        node = GeomNode('grid')
        node.add_geom(self.geom)
        self.node_path = parent.attach_new_node(node)
        self.node_path.set_z(0.1)
        self.node_path.set_transparency(TransparencyAttrib.M_alpha)
        self.node_path.set_light_off()
        self.node_path.set_shader_off()

    def update(self):
        """Update callback."""
        x, y = self.focus.get_x(), self.focus.get_y()
        self.node_path.set_x(x - x % self.spacing)
        self.node_path.set_y(y - y % self.spacing)

    def _create_geom(self):
        color = ConfigVariableColor('grid-color', DEFAULT_GRID_COLOR)

        radius = floor(self.size / (2 * self.spacing))
        diameter = (2 * radius + 1)
        start = -radius * self.spacing

        vertex_format = GeomVertexFormat.get_v3c4()
        vertex_data = GeomVertexData('grid', vertex_format, Geom.UH_static)
        vertex_data.set_num_rows(diameter * 4)
        vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
        color_writer = GeomVertexWriter(vertex_data, 'color')

        for i, j in product(range(diameter), repeat=2):
            vertex_writer.add_data3f(start + i * self.spacing,
                                     start + j * self.spacing, 0.0)
            alpha = GRID_ALPHA - GRID_ALPHA * (
                Vector(i - radius, j - radius).norm() / radius)
            color_writer.add_data4f(color[0], color[1], color[2], alpha)

        primitive = GeomLinestrips(Geom.UH_static)
        for vertex in vertex_indexes(diameter):
            primitive.add_vertex(vertex)
        primitive.close_primitive()
        self.geom = Geom(vertex_data)
        self.geom.add_primitive(primitive)
示例#8
0
    def create_hidden_area_mesh(self, mask):
        """
        Using the provided mask configuration, create the mesh that will cover the area not visible from the HMD
        """

        gvf = GeomVertexFormat.get_v3()
        gvd = GeomVertexData('gvd', gvf, Geom.UH_static)
        geom = Geom(gvd)
        gvw = GeomVertexWriter(gvd, InternalName.get_vertex())
        for i in range(mask.unTriangleCount * 3):
            vertex = mask.pVertexData[i]
            # The clip space in Panda3D has [-1, 1] coordinates, the received coordinates are in [0, 1]
            gvw.add_data3(vertex[0] * 2 - 1, vertex[1] * 2 - 1, -1)
        prim = GeomTriangles(Geom.UH_static)
        for i in range(mask.unTriangleCount):
            prim.add_vertices(i * 3, i * 3 + 1, i * 3 + 2)
        geom.add_primitive(prim)
        node = GeomNode('hidden-area-mesh')
        node.add_geom(geom)
        return node
示例#9
0
def _generate_mesh(way: Way) -> Geom:
    """Generate mesh for a Way."""
    geometry = way.geometry
    rows = 2 * len(geometry.segments) + 2

    vertex_data = GeomVertexData(str(way.id), VERTEX_FORMAT, Geom.UH_static)
    vertex_data.set_num_rows(rows)
    vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
    normal_writer = GeomVertexWriter(vertex_data, 'normal')
    texcoord_writer = GeomVertexWriter(vertex_data, 'texcoord')

    start_z = way.start.level * LEVEL_HEIGHT
    end_z = way.end.level * LEVEL_HEIGHT
    lanes_float = float(way.total_lane_count)

    segment = geometry.segments[0]
    for vertex in (segment.start_left, segment.start_right):
        vertex_writer.add_data3f(vertex.x, vertex.y, start_z)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
    texture_v = 0.0
    texcoord_writer.add_data2f(0.0, texture_v)
    texcoord_writer.add_data2f(lanes_float, texture_v)

    lengths = [s.length() for s in geometry.segments]
    total_len = sum(lengths)

    for segment, acc_len in zip(geometry.segments, accumulate(lengths)):
        height = start_z + (end_z - start_z) * acc_len / total_len
        for vertex in (segment.end_left, segment.end_right):
            vertex_writer.add_data3f(vertex.x, vertex.y, height)
            normal_writer.add_data3f(0.0, 0.0, 1.0)
        texture_v = acc_len / LANE_WIDTH
        texcoord_writer.add_data2f(0.0, texture_v)
        texcoord_writer.add_data2f(lanes_float, texture_v)

    primitive = GeomTristrips(Geom.UH_static)
    primitive.add_consecutive_vertices(0, rows)
    primitive.close_primitive()
    geom = Geom(vertex_data)
    geom.add_primitive(primitive)
    return geom
示例#10
0
 def addLine(self, points):
     """
 Adds a line to class GeomNode from a pair of points
 """
     #Creates objects needed to draw a geometry on the HUD
     #The vertex data which will define the rendered geometry
     vertex_data = GeomVertexData("graph", GeomVertexFormat.getV3(),
                                  Geom.UHStatic)
     #The object that writes vertexes the vertex data
     writer = GeomVertexWriter(vertex_data, "vertex")
     for point in points:
         writer.add_data3f(point[0], 0, point[1])
     #Defines that this geometry represents a polyline
     primitive = GeomLinestrips(Geom.UHStatic)
     #Tells geometry how many verticies will be added(?)
     primitive.add_consecutive_vertices(0, 2)
     primitive.close_primitive()
     geometry = Geom(vertex_data)
     geometry.add_primitive(primitive)
     #Draws a graph on the HUD
     self.geom_node.add_geom(geometry)
示例#11
0
    def __init__(self, base):
        # Load texture
        tex = Loader(base).loadTexture((Path(path.realpath(__file__)).parent.parent.parent / "res/images/checkerboard.png").absolute())
        tex.setMagfilter(SamplerState.FT_nearest)
        tex.setMinfilter(SamplerState.FT_nearest)

        # Set up vertex data
        vdata = GeomVertexData("floor_data", GeomVertexFormat.get_v3t2(), Geom.UHStatic)
        vdata.setNumRows(6)
        vertex = GeomVertexWriter(vdata, "vertex")
        texcoord = GeomVertexWriter(vdata, "texcoord")

        vertex.addData3(-5, -5, 0)
        texcoord.addData3(0, 0, 0)
        vertex.addData3(-5, 5, 0)
        texcoord.addData3(0, 10, 0)
        vertex.addData3(5, 5, 0)
        texcoord.addData3(10, 10, 0)

        vertex.addData3(5, 5, 0)
        texcoord.addData3(10, 10, 0)
        vertex.addData3(5, -5, 0)
        texcoord.addData3(10, 0, 0)
        vertex.addData3(-5, -5, 0)
        texcoord.addData3(0, 0, 0)

        # Create primitive
        prim = GeomTriangles(Geom.UHStatic)
        prim.addVertices(0, 1, 2)
        prim.addVertices(3, 4, 5)
        geom = Geom(vdata)
        geom.add_primitive(prim)

        # Initialize geometry node
        GeomNode.__init__(self, "floor")
        attrib = TextureAttrib.make(tex)
        state = RenderState.make(attrib)
        self.addGeom(geom, state)
示例#12
0
def _generate_mesh(node: Node) -> Geom:
    """Generate mesh for a Node."""
    size = len(node.geometry.polygon)
    vertex_data = GeomVertexData(str(node.id), VERTEX_FORMAT, Geom.UH_static)
    vertex_data.set_num_rows(size)
    vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
    normal_writer = GeomVertexWriter(vertex_data, 'normal')
    texcoord_writer = GeomVertexWriter(vertex_data, 'texcoord')

    indexes = [range(i - 1, i + 2) for i in range(0, size, 2)]
    triangles = [[node.geometry.polygon[j] for j in t] for t in indexes]

    for point in node.geometry.polygon:
        vertex_writer.add_data3f(point.x, point.y, LEVEL_HEIGHT * node.level)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
        texcoord_writer.add_data2f(point.x / LANE_WIDTH, point.y / LANE_WIDTH)

    indexes = [
        i for i, t in zip(indexes, triangles)
        if not t[0].close_to(t[1]) and not t[1].close_to(t[2])
    ]

    geom = Geom(vertex_data)
    primitive = GeomTriangles(Geom.UH_static)
    for index in chain.from_iterable(indexes):
        primitive.add_vertex(index % size)
    primitive.close_primitive()
    geom.add_primitive(primitive)

    if size > 4:
        primitive = GeomTristrips(Geom.UH_static)
        for index in (i if i % 2 else -i - 1 for i in range(size // 2)):
            primitive.add_vertex(index % size)
        primitive.close_primitive()
        geom.add_primitive(primitive)

    return geom
示例#13
0
def create_geometry_from_mesh(mesh):
    # Define the individual array formats for vertex attributes.
    vertex_position_format = GeomVertexArrayFormat("vertex", 3,
                                                   Geom.NT_float32,
                                                   Geom.C_point)
    vertex_normal_format = GeomVertexArrayFormat("normal", 3, Geom.NT_float32,
                                                 Geom.C_normal)
    vertex_color_format = GeomVertexArrayFormat("color", 4, Geom.NT_uint8,
                                                Geom.C_color)

    # Define the vertex data format with positions and colors.
    vertex_format = GeomVertexFormat()
    vertex_format.addArray(vertex_position_format)
    vertex_format.addArray(vertex_normal_format)
    vertex_format.addArray(vertex_color_format)
    vertex_format = GeomVertexFormat.registerFormat(vertex_format)

    # Populate the vertex position and color arrays.
    vertex_data = GeomVertexData("mesh_vertices", vertex_format,
                                 Geom.UH_static)
    vertex_data.modifyArrayHandle(0).copyDataFrom(
        np.array(mesh.positions, dtype=np.float32))
    vertex_data.modifyArrayHandle(1).copyDataFrom(
        np.array(mesh.normals, dtype=np.float32))
    vertex_data.modifyArrayHandle(2).copyDataFrom(
        np.array(mesh.colors, dtype=np.uint8))

    # Populate the triangle indices.
    triangles = GeomTriangles(Geom.UH_static)
    triangles.setIndexType(Geom.NT_uint32)
    triangles.modifyVertices().modifyHandle().copyDataFrom(
        np.array(mesh.triangles, dtype=np.uint32))

    geometry = Geom(vertex_data)
    geometry.add_primitive(triangles)
    return geometry
示例#14
0
def _generate_mesh(radius: float, count: int) -> Geom:
    """Generate mesh for the ground plane."""
    vertex_data = GeomVertexData('ground', VERTEX_FORMAT, Geom.UH_static)
    vertex_data.set_num_rows(count**2)
    vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
    normal_writer = GeomVertexWriter(vertex_data, 'normal')
    texcoord_writer = GeomVertexWriter(vertex_data, 'texcoord')

    step = 2 * radius / count
    for i, j in product(range(count + 1), repeat=2):
        vertex_writer.add_data3f(i * step - radius, j * step - radius, 0.0)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
        texcoord_writer.add_data2f(i * 512, j * 512)

    geom = Geom(vertex_data)
    primitive = GeomTristrips(Geom.UH_static)
    for j in range(count):
        rows = range(count + 1) if j % 2 else reversed(range(count + 1))
        for i in rows:
            primitive.add_vertex((j + (j + 1) % 2) * (count + 1) + i)
            primitive.add_vertex((j + j % 2) * (count + 1) + i)
    primitive.close_primitive()
    geom.add_primitive(primitive)
    return geom
示例#15
0
文件: mesh.py 项目: tcdude/thirty
 def get_node(self):
     geom = Geom(self._vert_data)
     geom.add_primitive(self._prim)
     node = GeomNode(self._name)
     node.add_geom(geom)
     return node
示例#16
0
class SquareMesh():
    name: Final[str]
    mesh: Final[Geom]
    depth: Final[float]

    __vertex_data_format: GeomVertexFormat
    __vertex_data: GeomVertexData

    __triangles: GeomTriangles
    __triangle_data: GeomVertexArrayData

    __vertex: GeomVertexWriter
    __normal: GeomVertexWriter
    __texcoord: GeomVertexWriter

    def __init__(self, width: int = 1, height: int = 1, depth: Real = 0.1, name: str = 'SquareMesh') -> None:
        self.name = name
        self.depth = depth

        self.__vertex_data_format = GeomVertexFormat. getV3n3t2()
        self.__vertex_data = GeomVertexData(name, self.__vertex_data_format, Geom.UHStatic)
        self.__vertex_data.set_num_rows(4)

        self.mesh = Geom(self.__vertex_data)
        self.__triangles = GeomTriangles(Geom.UHStatic)
        self.__triangle_data = self.__triangles.modifyVertices()

        self.__vertex = GeomVertexWriter(self.__vertex_data, 'vertex')
        self.__normal = GeomVertexWriter(self.__vertex_data, 'normal')
        self.__texcoord = GeomVertexWriter(self.__vertex_data, 'texcoord')

        self.__face_count = 0

        def make(x1, y1, z1, x2, y2, z2, tex) -> None:
            if x1 == x2:
                self.__vertex.add_data3f(x1, y1, z1)
                self.__vertex.add_data3f(x2, y2, z1)
                self.__vertex.add_data3f(x2, y2, z2)
                self.__vertex.add_data3f(x1, y1, z2)

                self.__normal.add_data3(normalise(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
                self.__normal.add_data3(normalise(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))
                self.__normal.add_data3(normalise(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
                self.__normal.add_data3(normalise(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))
            else:
                self.__vertex.add_data3f(x1, y1, z1)
                self.__vertex.add_data3f(x2, y1, z1)
                self.__vertex.add_data3f(x2, y2, z2)
                self.__vertex.add_data3f(x1, y2, z2)

                self.__normal.add_data3(normalise(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
                self.__normal.add_data3(normalise(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1))
                self.__normal.add_data3(normalise(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
                self.__normal.add_data3(normalise(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1))

            for data in tex:
                self.__texcoord.addData2f(*data)

            vertex_id = self.__face_count * 4

            self.__triangles.addVertices(vertex_id, vertex_id + 1, vertex_id + 3)
            self.__triangles.addVertices(vertex_id + 1, vertex_id + 2, vertex_id + 3)

            self.__face_count += 1

        if self.depth == 0:
            make(0, 0, 0, width, height, 0, [(1.0, 1.0), (0.0, 1.0), (0.0, 0.0), (1.0, 0.0)])
        else:
            make(0, height, -self.depth, 0, 0, 0, ((0.0, 1.0), (0.0, 0.0), (0.0, 0.0), (0.0, 1.0))) # SIDE
            make(0, 0, -self.depth, width, 0, 0, ((0.0, 0.0), (1.0, 0.0), (1.0, 0.0), (0.0, 0.0)))  # SIDE
            make(width, height, -self.depth, 0, height, 0, ((1.0, 1.0), (0.0, 1.0), (0.0, 1.0), (1.0, 1.0))) # SIDE
            make(width, 0, -self.depth, width, height, 0, ((1.0, 0.0), (1.0, 1.0), (1.0, 1.0), (1.0, 0.0))) # SIDE
            make(width, height, 0, 0, 0, 0, ((1.0, 1.0), (0.0, 1.0), (0.0, 0.0), (1.0, 0.0))) # TOP
            make(0, height, -self.depth, width, 0, -self.depth, ((0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0))) # BOTTOM

        self.__triangles.close_primitive()
        self.mesh.add_primitive(self.__triangles)

    @property
    def geom_node(self) -> str:
        return 'geom_node'

    @geom_node.getter
    def geom_node(self) -> GeomNode:
        node = GeomNode(self.name)
        node.addGeom(self.mesh)
        return node
示例#17
0
def make_points(vertices, colors=None, texture_coords=None, geom=None):
    """Make or update existing points set geometry.

    Arguments:
        root_path {str} -- path to the group's root node
        name {str} -- node name within a group
        vertices {list} -- point coordinates (and other data in a point cloud format)

    Keyword Arguments:
        colors {list} -- colors (default: {None})
        texture_coords {list} -- texture coordinates (default: {None})
        geom {Geom} -- geometry to update (default: {None})

    Returns:
        Geom -- p3d geometry
    """
    if not isinstance(vertices, np.ndarray):
        vertices = np.asarray(vertices, dtype=np.float32)

    if colors is not None:
        if not isinstance(colors, np.ndarray):
            colors = np.asarray(colors)
        if colors.dtype != np.uint8:
            colors = np.uint8(colors * 255)
        vertices = np.column_stack((
            vertices.view(dtype=np.uint32).reshape(-1, 3),
            colors.view(dtype=np.uint32)))

    if texture_coords is not None:
        if not isinstance(texture_coords, np.ndarray):
            texture_coords = np.asarray(texture_coords)
        vertices = np.column_stack((
            vertices.view(dtype=np.uint32).reshape(-1, 3),
            texture_coords.view(dtype=np.uint32).reshape(-1, 2)))

    data = vertices.tostring()

    if geom is None:
        if vertices.strides[0] == 12:
            vformat = GeomVertexFormat.get_v3()
        elif vertices.strides[0] == 16:
            vformat = GeomVertexFormat.get_v3c4()
        elif vertices.strides[0] == 20:
            vformat = GeomVertexFormat.get_v3t2()
        else:
            raise ViewerError('Incompatible point clout format: {},{}'.format(
                vertices.dtype, vertices.shape))

        vdata = GeomVertexData('vdata', vformat, Geom.UHDynamic)
        vdata.unclean_set_num_rows(len(vertices))
        vdata.modify_array_handle(0).set_subdata(0, len(data), data)

        prim = GeomPoints(Geom.UHDynamic)
        prim.clear_vertices()
        prim.add_consecutive_vertices(0, len(vertices))
        prim.close_primitive()

        geom = Geom(vdata)
        geom.add_primitive(prim)
    else:
        vdata = geom.modify_vertex_data()
        vdata.unclean_set_num_rows(len(vertices))
        vdata.modify_array_handle(0).set_subdata(0, len(data), data)

        prim = geom.modify_primitive(0)
        prim.clear_vertices()
        prim.add_consecutive_vertices(0, len(vertices))
        prim.close_primitive()

    return geom
示例#18
0
def _generate_mesh(points: List[Point]) -> Geom:
    """Generate mesh for a Path."""
    def calc_color(param):
        return interpolate_rgb(START_COLOR, END_COLOR, param)

    if len(points) < 2:
        return Geom()

    vertex_data = GeomVertexData('path', VERTEX_FORMAT, Geom.UH_static)
    vertex_data.set_num_rows(2 * len(points) + 1)
    vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
    normal_writer = GeomVertexWriter(vertex_data, 'normal')
    color_writer = GeomVertexWriter(vertex_data, 'color')

    length = sum(p1.distance(p2) for p1, p2 in window_iter(points))
    vector = points[1] - points[0]
    distance = vector.norm()
    position = distance / length
    vector = vector.normalized()

    width_vector = LANE_WIDTH * 0.5 * vector.rotated_left()
    for vertex in (points[0] + width_vector, points[0] - width_vector):
        vertex_writer.add_data3f(vertex.x, vertex.y, HEIGHT)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
        color_writer.add_data4f(*START_COLOR)

    last_vector = vector
    for point, next_ in zip(islice(points, 1, None), islice(points, 2, None)):
        vector = next_ - point
        distance = vector.norm()
        vector = vector.normalized()
        try:
            bisector = (last_vector + vector).normalized()
            width_vector = (sec(bisector, vector) * 0.5 * LANE_WIDTH
                            * bisector.rotated_left())
        except ZeroDivisionError:
            width_vector = vector.rotated_right() * 0.5 * LANE_WIDTH
        color = calc_color(position)
        for vertex in (point + width_vector, point - width_vector):
            vertex_writer.add_data3f(vertex.x, vertex.y, HEIGHT)
            normal_writer.add_data3f(0.0, 0.0, 1.0)
            color_writer.add_data4f(*color)
        position = position + distance / length
        last_vector = vector

    point = points[-1]
    width_vector = 0.5 * LANE_WIDTH * last_vector.rotated_left()

    distance = LANE_WIDTH if distance > LANE_WIDTH else distance / 2
    vector = -last_vector * distance

    for vertex in (point + width_vector + vector,
                   point - width_vector + vector,
                   point):
        vertex_writer.add_data3f(vertex.x, vertex.y, HEIGHT)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
        color_writer.add_data4f(*END_COLOR)

    primitive = GeomTristrips(Geom.UH_static)
    primitive.add_consecutive_vertices(0, 2 * len(points) + 1)
    primitive.close_primitive()
    geom = Geom(vertex_data)
    geom.add_primitive(primitive)
    return geom
示例#19
0
    def gen_geom(self, mesh_json):
        # Create vertex format
        geom_array = GeomVertexArrayFormat()
        geom_array.add_column("vertex", 3, Geom.NTFloat32, Geom.CPoint)
        has_normals = False
        has_texcoords = False
        has_weights = False
        if "normals" in mesh_json:
            geom_array.add_column("normal", 3, Geom.NTFloat32, Geom.CNormal)
            has_normals = True
        if "texcoords" in mesh_json:
            geom_array.add_column("texcoord", 3, Geom.NTFloat32,
                                  Geom.CTexcoord)
            has_texcoords = True
        if "weights" in mesh_json:
            geom_array.add_column("joint", 4, Geom.NTUint8, Geom.CIndex)
            geom_array.add_column("weight", 4, Geom.NTFloat32, Geom.COther)
            has_weights = True
        geom_format = GeomVertexFormat()
        geom_format.add_array(geom_array)
        geom_format = GeomVertexFormat.register_format(geom_format)

        # Set up vertex data
        vdata = GeomVertexData(
            str(random.randint(0, 255)) + "_vdata", geom_format, Geom.UHStatic)
        vcount = len(mesh_json["vertices"]) // 3
        vdata.setNumRows(vcount)
        vertex = GeomVertexWriter(vdata, "vertex")

        for i in range(vcount):
            vertex.addData3(mesh_json["vertices"][3 * i],
                            mesh_json["vertices"][3 * i + 1],
                            mesh_json["vertices"][3 * i + 2])
        if has_normals:
            normal = GeomVertexWriter(vdata, "normal")
            for i in range(vcount):
                normal.addData3(mesh_json["normals"][3 * i],
                                mesh_json["normals"][3 * i + 1],
                                mesh_json["normals"][3 * i + 2])
        if has_texcoords:
            texcoord = GeomVertexWriter(vdata, "texcoord")
            for i in range(vcount):
                texcoord.addData2(mesh_json["texcoords"][2 * i],
                                  mesh_json["texcoords"][2 * i + 1])
        if has_weights:
            joint = GeomVertexWriter(vdata, "joint")
            weight = GeomVertexWriter(vdata, "weight")
            for i in range(vcount):
                joint_count = len(mesh_json["joints"][i])
                joint.addData4(
                    0 if joint_count < 1 else mesh_json["joints"][i][0],
                    0 if joint_count < 2 else mesh_json["joints"][i][1],
                    0 if joint_count < 3 else mesh_json["joints"][i][2],
                    0 if joint_count < 4 else mesh_json["joints"][i][3])
                weight.addData4(
                    0 if joint_count < 1 else mesh_json["weights"][i][0],
                    0 if joint_count < 2 else mesh_json["weights"][i][1],
                    0 if joint_count < 3 else mesh_json["weights"][i][2],
                    0 if joint_count < 4 else mesh_json["weights"][i][3])

        # Create primitive
        prim = GeomTriangles(Geom.UHStatic)
        for i in range(vcount // 3):
            prim.addVertices(3 * i, 3 * i + 1, 3 * i + 2)
        geom = Geom(vdata)
        geom.add_primitive(prim)

        # Load texture
        tex = None
        if "texture" in mesh_json:
            tex = Loader(EComponent.base).loadTexture(
                (Path("resources") / mesh_json["texture"]).absolute())
            tex.setMagfilter(SamplerState.FT_nearest)
            tex.setMinfilter(SamplerState.FT_nearest)

        # Create new geometry node
        geom_node = GeomNode(str(random.randint(0, 255)) + "_node")
        if tex is None:
            geom_node.addGeom(geom)
        else:
            attrib = TextureAttrib.make(tex)
            state = RenderState.make(attrib)
            geom_node.addGeom(geom, state)
        if EComponent.panda_root_node is not None:
            self.geom_path = EComponent.panda_root_node.attach_new_node(
                geom_node)
            self.geom_path.set_shader_input("object_id", self.object_id)

        # Set shader
        if has_weights and self.geom_path is not None:
            self.geom_path.setTag("shader type", "skinned")
            bone_mats = PTA_LMatrix4f()
            for _ in range(100):
                bone_mats.push_back(helper.np_mat4_to_panda(np.identity(4)))
            self.geom_path.set_shader_input(f"boneMats", bone_mats)

            # Disable culling
            self.geom_path.node().setBounds(OmniBoundingVolume())
            self.geom_path.node().setFinal(True)
示例#20
0
文件: geom.py 项目: dcwatson/pavara
 def get_geom(self):
     geom = Geom(self.vdata)
     geom.add_primitive(self.tris)
     return geom
示例#21
0
    def __make_points(vertices, colours=None, geom: Geom = None) -> Geom:
        """
        This function is largely inspired by panda3d_viewer's implementation.

        Copyright (c) 2020, Igor Kalevatykh

        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:

        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.

        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
        EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
        MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
        IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
        DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
        OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
        OR OTHER DEALINGS IN THE SOFTWARE.
        """

        if not isinstance(vertices, np.ndarray):
            vertices = np.asarray(vertices, dtype=np.float32)

        if colours is not None:
            if not isinstance(colours, np.ndarray):
                colours = np.asarray(colours)
            if colours.dtype != np.uint8:
                colours = np.uint8(colours * 255)
            vertices = np.column_stack((vertices.view(dtype=np.uint32).reshape(-1, 3),
                                        colours.view(dtype=np.uint32)))

        data = vertices.tostring()

        if geom is None:
            if vertices.strides[0] == 12:
                vformat = GeomVertexFormat.get_v3()
            elif vertices.strides[0] == 16:
                vformat = GeomVertexFormat.get_v3c4()
            else:
                raise ValueError('Incompatible point clout format: {},{}'.format(vertices.dtype, vertices.shape))

            vdata = GeomVertexData('vdata', vformat, Geom.UHDynamic)
            vdata.unclean_set_num_rows(len(vertices))
            vdata.modify_array_handle(0).set_subdata(0, len(data), data)

            prim = GeomPoints(Geom.UHDynamic)
            prim.clear_vertices()
            prim.add_consecutive_vertices(0, len(vertices))
            prim.close_primitive()

            geom = Geom(vdata)
            geom.add_primitive(prim)
        else:
            vdata = geom.modify_vertex_data()
            vdata.unclean_set_num_rows(len(vertices))
            vdata.modify_array_handle(0).set_subdata(0, len(data), data)

            prim = geom.modify_primitive(0)
            prim.clear_vertices()
            prim.add_consecutive_vertices(0, len(vertices))
            prim.close_primitive()

        return geom
示例#22
0
class CubeMesh():
    name: str
    geom: Geom

    __face_count: int

    __vertex_data_format: GeomVertexFormat
    __vertex_data: GeomVertexData

    __triangles: GeomTriangles
    __triangle_data: GeomVertexArrayData

    __vertex: GeomVertexWriter
    __normal: GeomVertexWriter

    __wireframe_node: GeomNode

    def __init__(self,
                 name: str = 'cube_mesh',
                 wireframe_thickness: float = 5) -> None:
        self.name = name

        self.__vertex_data_format = GeomVertexFormat.getV3n3()
        self.__vertex_data = GeomVertexData(name, self.__vertex_data_format,
                                            Geom.UHStatic)

        self.geom = Geom(self.__vertex_data)
        self.__triangles = GeomTriangles(Geom.UHStatic)
        self.__triangle_data = self.__triangles.modifyVertices()

        self.__vertex = GeomVertexWriter(self.__vertex_data, 'vertex')
        self.__normal = GeomVertexWriter(self.__vertex_data, 'normal')

        self.__face_count = 0

        def add_face(face: Face) -> None:
            self.__make_face(face)

        self.__make_face(Face.LEFT)
        self.__make_face(Face.RIGHT)
        self.__make_face(Face.BACK)
        self.__make_face(Face.FRONT)
        self.__make_face(Face.BOTTOM)
        self.__make_face(Face.TOP)

        self.__triangles.close_primitive()
        self.geom.add_primitive(self.__triangles)

        def is_connected(x, y, z, x1, y1, z1):
            return (abs(x - x1) == 1 and abs(y - y1) != 1 and abs(z - z1) != 1) or \
                   (abs(x - x1) != 1 and abs(y - y1) == 1 and abs(z - z1) != 1) or \
                   (abs(x - x1) != 1 and abs(y - y1) != 1 and abs(z - z1) == 1)

        ls = LineSegs()
        ls.set_thickness(wireframe_thickness)
        arr_x = [0, 0, 0, 0, 1, 1, 1, 1]
        arr_y = [0, 0, 1, 1, 1, 1, 0, 0]
        arr_z = [0, -1, -1, 0, 0, -1, -1, 0]
        for pos1 in range(len(arr_x) - 1):
            for pos2 in range(pos1, len(arr_x)):
                x = arr_x[pos1]
                y = arr_y[pos1]
                z = arr_z[pos1]
                x1 = arr_x[pos2]
                y1 = arr_y[pos2]
                z1 = arr_z[pos2]
                if (is_connected(x, y, z, x1, y1, z1)):
                    ls.move_to(x, y, z)
                    ls.draw_to(x1, y1, z1)
        self.__wireframe_node = ls.create()

    def __make_face(self, face: Face, pos: Point = Point(0, 0, 0)) -> None:
        def make(x1, y1, z1, x2, y2, z2) -> None:
            if x1 == x2:
                self.__vertex.add_data3f(x1, y1, z1)
                self.__vertex.add_data3f(x2, y2, z1)
                self.__vertex.add_data3f(x2, y2, z2)
                self.__vertex.add_data3f(x1, y1, z2)

                self.__normal.add_data3(
                    normalise(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
                self.__normal.add_data3(
                    normalise(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))
                self.__normal.add_data3(
                    normalise(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
                self.__normal.add_data3(
                    normalise(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))
            else:
                self.__vertex.add_data3f(x1, y1, z1)
                self.__vertex.add_data3f(x2, y1, z1)
                self.__vertex.add_data3f(x2, y2, z2)
                self.__vertex.add_data3f(x1, y2, z2)

                self.__normal.add_data3(
                    normalise(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
                self.__normal.add_data3(
                    normalise(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1))
                self.__normal.add_data3(
                    normalise(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
                self.__normal.add_data3(
                    normalise(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1))

            vertex_id = self.__face_count * 4

            self.__triangles.addVertices(vertex_id, vertex_id + 1,
                                         vertex_id + 3)
            self.__triangles.addVertices(vertex_id + 1, vertex_id + 2,
                                         vertex_id + 3)

            self.__face_count += 1

        x, y, z = pos
        if face == Face.FRONT:
            make(x + 1, y + 1, z - 1, x, y + 1, z)
        elif face == Face.BACK:
            make(x, y, z - 1, x + 1, y, z)
        elif face == Face.RIGHT:
            make(x + 1, y, z - 1, x + 1, y + 1, z)
        elif face == Face.LEFT:
            make(x, y + 1, z - 1, x, y, z)
        elif face == Face.TOP:
            make(x + 1, y + 1, z, x, y, z)
        elif face == Face.BOTTOM:
            make(x, y + 1, z - 1, x + 1, y, z - 1)
        else:
            raise Exception("unknown face")

    @property
    def artificial_lighting(self) -> str:
        return 'artificial_lighting'

    @artificial_lighting.getter
    def artificial_lighting(self) -> bool:
        return self.__artificial_lighting

    @property
    def body_node(self) -> GeomNode:
        node = GeomNode(self.name)
        node.addGeom(self.geom)
        return node

    @property
    def wireframe_node(self) -> GeomNode:
        return self.__wireframe_node
示例#23
0
 def get_geom(self):
     geom = Geom(self.vdata)
     geom.add_primitive(self.tris)
     return geom