示例#1
0
def points_random_3d(count,
                     range_x=(-10.0, 10.0),
                     range_y=(-10.0, 10.0),
                     range_z=(-10.0, 10.0),
                     seed=None):
    """
    Generates random positions

    :param count: Number of points
    :param range_x: min-max range for x axis
    :param range_y: min-max range for y axis
    :param range_z: min-max range for z axis
    :param seed: The random seed to be used
    """
    random.seed(seed)

    def gen():
        for i in range(count):
            yield random.uniform(*range_x)
            yield random.uniform(*range_y)
            yield random.uniform(*range_z)

    data = numpy.fromiter(gen(), count=count * 3, dtype=numpy.float32)
    pos = VBO(data)
    vao = VAO("geometry:points_random_3d", mode=GL.GL_POINTS)
    vao.add_array_buffer(GL.GL_FLOAT, pos)
    vao.map_buffer(pos, "in_position", 3)
    vao.build()
    return vao
示例#2
0
def sphere(radius=0.5, sectors=32, rings=16):
    """
    Generate a sphere

    :param radius: Radius or the sphere
    :param rings: number or horizontal rings
    :param sectors: number of vertical segments
    :return: VAO containing the sphere
    """
    R = 1.0 / (rings - 1)
    S = 1.0 / (sectors - 1)

    vertices = [0] * (rings * sectors * 3)
    normals = [0] * (rings * sectors * 3)
    uvs = [0] * (rings * sectors * 2)

    v, n, t = 0, 0, 0
    for r in range(rings):
        for s in range(sectors):
            y = math.sin(-math.pi / 2 + math.pi * r * R)
            x = math.cos(2 * math.pi * s * S) * math.sin(math.pi * r * R)
            z = math.sin(2 * math.pi * s * S) * math.sin(math.pi * r * R)

            uvs[t] = s * S
            uvs[t + 1] = r * R

            vertices[v] = x * radius
            vertices[v + 1] = y * radius
            vertices[v + 2] = z * radius

            normals[n] = x
            normals[n + 1] = y
            normals[n + 2] = z

            t += 2
            v += 3
            n += 3

    indices = [0] * rings * sectors * 6
    i = 0
    for r in range(rings - 1):
        for s in range(sectors - 1):
            indices[i] = r * sectors + s
            indices[i + 1] = (r + 1) * sectors + (s + 1)
            indices[i + 2] = r * sectors + (s + 1)

            indices[i + 3] = r * sectors + s
            indices[i + 4] = (r + 1) * sectors + s
            indices[i + 5] = (r + 1) * sectors + (s + 1)
            i += 6

    vbo_vertices = VBO(numpy.array(vertices, dtype=numpy.float32))
    vbo_normals = VBO(numpy.array(normals, dtype=numpy.float32))
    vbo_uvs = VBO(numpy.array(uvs, dtype=numpy.float32))
    vbo_element = VBO(numpy.array(indices, dtype=numpy.uint32),
                      target="GL_ELEMENT_ARRAY_BUFFER")

    vao = VAO("sphere")
    # VBOs
    vao.add_array_buffer(GL.GL_FLOAT, vbo_vertices)
    vao.add_array_buffer(GL.GL_FLOAT, vbo_normals)
    vao.add_array_buffer(GL.GL_FLOAT, vbo_uvs)
    # Mapping
    vao.map_buffer(vbo_vertices, "in_position", 3)
    vao.map_buffer(vbo_normals, "in_normal", 3)
    vao.map_buffer(vbo_uvs, "in_uv", 2)
    # Index
    vao.set_element_buffer(GL.GL_UNSIGNED_INT, vbo_element)
    vao.build()
    return vao
示例#3
0
def quad_2d(width, height, xpos=0.0, ypos=0.0):
    """
    Creates a 2D quad VAO using 2 triangles.

    :param width: Width of the quad
    :param height: Height of the quad
    :param xpos: Center position x
    :param ypos: Center position y
    """
    pos = VBO(
        numpy.array([
            xpos - width / 2.0,
            ypos + height / 2.0,
            0.0,
            xpos - width / 2.0,
            ypos - height / 2.0,
            0.0,
            xpos + width / 2.0,
            ypos - height / 2.0,
            0.0,
            xpos - width / 2.0,
            ypos + height / 2.0,
            0.0,
            xpos + width / 2.0,
            ypos - height / 2.0,
            0.0,
            xpos + width / 2.0,
            ypos + height / 2.0,
            0.0,
        ],
                    dtype=numpy.float32))
    normals = VBO(
        numpy.array([
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
        ],
                    dtype=numpy.float32))
    uvs = VBO(
        numpy.array([
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            1.0,
            1.0,
            0.0,
            1.0,
            1.0,
        ],
                    dtype=numpy.float32))
    vao = VAO("geometry:quad", mode=GL.GL_TRIANGLES)
    vao.add_array_buffer(GL.GL_FLOAT, pos)
    vao.add_array_buffer(GL.GL_FLOAT, normals)
    vao.add_array_buffer(GL.GL_FLOAT, uvs)
    vao.map_buffer(pos, "in_position", 3)
    vao.map_buffer(normals, "in_normal", 3)
    vao.map_buffer(uvs, "in_uv", 2)
    vao.build()
    return vao
示例#4
0
def plane_xz(size=(10, 10), resolution=(10, 10)):
    """
    Generates a plane on the xz axis of a specific size and resolution

    :param size: (x, y) tuple
    :param resolution: (x, y) tuple
    :return: VAO
    """
    sx, sz = size
    rx, rz = resolution
    dx, dz = sx / rx, sz / rz  # step
    ox, oz = -sx / 2, -sz / 2  # start offset

    def gen_pos():
        for z in range(rz):
            for x in range(rx):
                yield ox + x * dx
                yield 0
                yield oz + z * dz

    def gen_uv():
        for z in range(rz):
            for x in range(rx):
                yield x / (rx - 1)
                yield 1 - z / (rz - 1)

    def gen_normal():
        for z in range(rx * rz):
            yield 0.0
            yield 1.0
            yield 0.0

    def gen_index():
        for z in range(rz - 1):
            for x in range(rx - 1):
                # quad poly left
                yield z * rz + x
                yield z * rz + x + 1
                yield z * rz + x + rx
                # quad poly right
                yield z * rz + x + rx
                yield z * rz + x + 1
                yield z * rz + x + rx + 1

    pos_data = numpy.fromiter(gen_pos(), dtype=numpy.float32)
    position_vbo = VBO(pos_data)

    uv_data = numpy.fromiter(gen_uv(), dtype=numpy.float32)
    uv_vbo = VBO(uv_data)

    normal_data = numpy.fromiter(gen_normal(), dtype=numpy.float32)
    normal_vbo = VBO(normal_data)

    index_data = numpy.fromiter(gen_index(), dtype=numpy.uint32)
    index_vbo = VBO(index_data, target="GL_ELEMENT_ARRAY_BUFFER")

    vao = VAO("plane_xz", mode=GL.GL_TRIANGLES)

    vao.add_array_buffer(GL.GL_FLOAT, position_vbo)
    vao.add_array_buffer(GL.GL_FLOAT, uv_vbo)
    vao.add_array_buffer(GL.GL_FLOAT, normal_vbo)

    vao.map_buffer(position_vbo, "in_position", 3)
    vao.map_buffer(uv_vbo, "in_uv", 2)
    vao.map_buffer(normal_vbo, "in_normal", 3)
    vao.set_element_buffer(GL.GL_UNSIGNED_INT, index_vbo)

    vao.build()
    return vao
示例#5
0
def cube(width, height, depth, normals=True, uvs=True):
    """
    Generates a cube centered at 0, 0, 0

    :param width: Width of the cube
    :param height: height of the cube
    :param depth: depth of the bubs
    :param normals: (bool) Include normals
    :param uvs: (bool) include uv coordinates
    :return: VAO representing the cube
    """
    width, height, depth = width / 2, height / 2, depth / 2
    pos = VBO(
        numpy.array([
            width,
            -height,
            depth,
            width,
            height,
            depth,
            -width,
            -height,
            depth,
            width,
            height,
            depth,
            -width,
            height,
            depth,
            -width,
            -height,
            depth,
            width,
            -height,
            -depth,
            width,
            height,
            -depth,
            width,
            -height,
            depth,
            width,
            height,
            -depth,
            width,
            height,
            depth,
            width,
            -height,
            depth,
            width,
            -height,
            -depth,
            width,
            -height,
            depth,
            -width,
            -height,
            depth,
            width,
            -height,
            -depth,
            -width,
            -height,
            depth,
            -width,
            -height,
            -depth,
            -width,
            -height,
            depth,
            -width,
            height,
            depth,
            -width,
            height,
            -depth,
            -width,
            -height,
            depth,
            -width,
            height,
            -depth,
            -width,
            -height,
            -depth,
            width,
            height,
            -depth,
            width,
            -height,
            -depth,
            -width,
            -height,
            -depth,
            width,
            height,
            -depth,
            -width,
            -height,
            -depth,
            -width,
            height,
            -depth,
            width,
            height,
            -depth,
            -width,
            height,
            -depth,
            width,
            height,
            depth,
            -width,
            height,
            -depth,
            -width,
            height,
            depth,
            width,
            height,
            depth,
        ],
                    dtype=numpy.float32))
    if normals:
        normals = VBO(
            numpy.array([
                -0,
                0,
                1,
                -0,
                0,
                1,
                -0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                -1,
                -0,
                0,
                -1,
                -0,
                0,
                -1,
                -0,
                0,
                -1,
                -0,
                0,
                -1,
                -0,
                0,
                -1,
                -0,
                0,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                0,
                -1,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
                0,
                1,
                0,
            ],
                        dtype=numpy.float32))
    if uvs:
        uvs = VBO(
            numpy.array([
                1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0,
                1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
                0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0,
                1, 1, 0, 0, 1, 0, 0, 1, 0
            ],
                        dtype=numpy.float32))

    vao = VAO("geometry:cube")
    # Add buffers
    vao.add_array_buffer(GL.GL_FLOAT, pos)
    if normals:
        vao.add_array_buffer(GL.GL_FLOAT, normals)
    if uvs:
        vao.add_array_buffer(GL.GL_FLOAT, uvs)

    # Map buffers
    vao.map_buffer(pos, "in_position", 3)
    if normals:
        vao.map_buffer(normals, "in_normal", 3)
    if uvs:
        vao.map_buffer(uvs, "in_uv", 2)

    vao.build()
    return vao