Exemple #1
0
class RingShape(Shape):
    def __init__(self, inner_radius, outer_radius):
        Shape.__init__(self)
        self.inner_radius = inner_radius
        self.outer_radius = outer_radius
        self.nbOfPoints = 360
        #TODO: This is a big hack to make it work with ProceduralVirtualTextureSource
        self.lod = 0
        self.coord = 0  #TexCoord.Flat
        self.x0 = 0
        self.y0 = 0
        self.lod_scale_x = 1
        self.lod_scale_y = 1
        self.face = -1

    def is_spherical(self):
        return False

    def create_instance(self):
        self.instance = NodePath("ring")
        node = GeomNode('ring-up')
        node.addGeom(
            geometry.RingFaceGeometry(1.0, self.inner_radius,
                                      self.outer_radius, self.nbOfPoints))
        up = self.instance.attach_new_node(node)
        up.setDepthOffset(-1)
        node = GeomNode('ring-down')
        node.addGeom(
            geometry.RingFaceGeometry(-1.0, self.inner_radius,
                                      self.outer_radius, self.nbOfPoints))
        down = self.instance.attach_new_node(node)
        down.setDepthOffset(-1)
        self.apply_owner()
        self.instance.set_depth_write(False)
        return self.instance
def test_sphere_into_heightfield():
    root = NodePath("root")
    world = BulletWorld()
    # Create PNMImage to construct Heightfield with
    img = PNMImage(10, 10, 1)
    img.fill_val(255)
    # Make our nodes
    heightfield = make_node("Heightfield", BulletHeightfieldShape, img, 1, ZUp)
    sphere = make_node("Sphere", BulletSphereShape, 1)
    # Attach to world
    np1 = root.attach_new_node(sphere)
    np1.set_pos(0, 0, 1)
    world.attach(sphere)

    np2 = root.attach_new_node(heightfield)
    np2.set_pos(0, 0, 0)
    world.attach(heightfield)

    assert world.get_num_rigid_bodies() == 2
    test = world.contact_test_pair(sphere, heightfield)
    assert test.get_num_contacts() > 0
    assert test.get_contact(0).get_node0() == sphere
    assert test.get_contact(0).get_node1() == heightfield

    # Increment sphere's Z coordinate, no longer colliding
    np1.set_pos(0, 0, 2)
    test = world.contact_test_pair(sphere, heightfield)
    assert test.get_num_contacts() == 0
Exemple #3
0
class RingShape(Shape):
    def __init__(self, inner_radius, outer_radius):
        Shape.__init__(self)
        self.inner_radius = inner_radius
        self.outer_radius = outer_radius
        self.nbOfPoints = 360

    def is_spherical(self):
        return False

    def create_instance(self):
        self.instance = NodePath("ring")
        node = GeomNode('ring-up')
        node.addGeom(
            geometry.RingFaceGeometry(1.0, self.inner_radius,
                                      self.outer_radius, self.nbOfPoints))
        up = self.instance.attach_new_node(node)
        up.setDepthOffset(-1)
        node = GeomNode('ring-down')
        node.addGeom(
            geometry.RingFaceGeometry(-1.0, self.inner_radius,
                                      self.outer_radius, self.nbOfPoints))
        down = self.instance.attach_new_node(node)
        down.setDepthOffset(-1)
        self.apply_owner()
        self.instance.set_depth_write(False)
        return self.instance
    def __init__(self, structure: NDArray[(Any, Any, Any), np.uint8], mask: np.uint8, parent: NodePath, name: str = 'old_dynamic_voxel_mesh', default_colour: Colour = WHITE) -> None:
        self.name = name
        self.__structure = structure
        self.__mask = mask
        self.__default_colour = default_colour

        self.__body = parent.attach_new_node(self.name)
        self.__wireframe = parent.attach_new_node(self.name + "_wf")

        self.__cube_mesh = CubeMesh()
        self.__wireframe_instance = self.__wireframe.attach_new_node(self.__cube_mesh.wireframe_node)
        self.__wireframe_instance.detach_node()
        self.__wireframe_instance_name = name + '_wf_inst'
        self.__cube_instance = self.__body.attach_new_node(self.__cube_mesh.body_node)
        self.__cube_instance.detach_node()
        self.__cube_instance_name = name + '_cube_inst'

        self.__cube_default_coloured = np.full(self.structure.shape, True, dtype=bool)
        self.__wireframes = np.empty(self.structure.shape, dtype=NodePath)
        self.__cubes = np.empty(self.structure.shape, dtype=NodePath)

        for idx in np.ndindex(self.structure.shape):
            if bool(self.structure[idx] & self.mask):
                self.__cubes[idx] = path = self.__body.attach_new_node(self.__cube_instance_name)
                self.__cube_instance.instance_to(path)
                path.set_color(*self.__default_colour)
                path.set_pos(*idx)

                self.__wireframes[idx] = path = self.__wireframe.attach_new_node(self.__wireframe_instance_name)
                self.__wireframe_instance.instance_to(path)
                path.set_pos(*idx)
Exemple #5
0
 def animated_tile(self, tsx, tile):
     node = NodePath("animated tile")
     sequence = SequenceNode("animated tile")
     duration = int(tile[0][0].get("duration"))
     if duration >= 9000:
         sequence.set_frame_rate(0)
     else:
         sequence.set_frame_rate(1000 / duration)
     for frame in tile[0]:
         tileid = int(frame.get("tileid"))
         tile_node = self.build_tile(tsx, tileid)
         sequence.add_child(tile_node.node())
     sequence.loop(True)
     node.attach_new_node(sequence)
     return node
Exemple #6
0
class Satallite():
    def __init__(self, name, distance):
        self.pivot = NodePath(name + " pivot")
        self.root = self.pivot.attach_new_node(name)
        self.name = name
        self.distance = distance
        self.parent = None
        self.satallites = []
        self.hpr_velocity = Vec3()  # Determines trajectory sorta
        # random initial rotation
        self.pivot.set_hpr(uniform(0, 360), uniform(0, 360), uniform(0, 360))
        self.hpr_velocity[0] = uniform(1, 2)
        self.hpr_velocity[1] = uniform(1, 2)

    def update_orbit(self, recursive=True):
        hpr = self.hpr_velocity * CURRENT_TIME
        self.pivot.set_hpr(hpr)
        if recursive:
            for satallite in self.satallites:
                satallite.update_orbit(recursive)

    def connect(self, recursive=True):
        for satallite in self.satallites:
            satallite.pivot.reparent_to(self.root)
            satallite.root.set_y(satallite.distance)
            satallite.parent = self
            self.update_orbit(recursive=False)
            if recursive: satallite.connect(True)
Exemple #7
0
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__(self, render: NodePath):
     self._alight = AmbientLight('pb_alight')
     self._dlight = DirectionalLight('pb_dlight')
     self._anode = render.attach_new_node(self._alight)
     self._dnode = render.attach_new_node(self._dlight)
     self._render = render
     self._is_active = False
     self.set_active(True)
Exemple #9
0
def test_reduce_persist():
    from panda3d.core import NodePath

    parent = NodePath("parent")
    child = parent.attach_new_node("child")

    parent2, child2 = loads(dumps([parent, child]))
    assert tuple(parent2.children) == (child2, )
Exemple #10
0
def create(parent: NodePath, way: Way) -> NodePath:
    """Create node for given way and attach it to the parent."""
    geom = _generate_mesh(way)
    node = GeomNode(str(way.id))
    node.add_geom(geom)
    node.adjust_draw_mask(0x00000000, 0x00010000, 0xfffeffff)
    node_path = parent.attach_new_node(node)
    node_path.set_texture(textures.get('road'), 1)
    return node_path
Exemple #11
0
def create(parent: NodePath, node: Node) -> NodePath:
    """Create node for given node and attach it to the parent."""
    geom = _generate_mesh(node)
    node_ = GeomNode(str(node.id))
    node_.add_geom(geom)
    node_.adjust_draw_mask(0x00000000, 0x00010000, 0xfffeffff)
    node_path = parent.attach_new_node(node_)
    node_path.set_texture(textures.get('intersection'))
    return node_path
Exemple #12
0
def create(parent: NodePath, radius: float, count: int) -> NodePath:
    """Create and add the ground plane to the scene."""
    geom = _generate_mesh(radius, count)
    node = GeomNode('world')
    node.add_geom(geom)

    node_path = parent.attach_new_node(node)
    node_path.set_texture(textures.get('ground'))
    node_path.set_effect(DecalEffect.make())
    return node_path
Exemple #13
0
def make_sprite_node(
    sprite: Texture,
    size: tuple = None,
    name: str = None,
    is_two_sided: bool = True,
    is_transparent: bool = True,
    parent: NodePath = None,
    position: Vec3 = None,
    scale: float = 0.0,
) -> NodePath:
    """Make flat single-sprite node out of provided data"""
    # Using WM_clamp instead of WM_mirror, to avoid issue with black 1-pixel
    # bars appearing on top of spritesheet randomly.
    # Idk if this needs to have possibility to override it #TODO
    sprite.set_wrap_u(Texture.WM_clamp)
    sprite.set_wrap_v(Texture.WM_clamp)

    # Creating CardMaker frame
    card = CardMaker(name or sprite.get_name() or "sprite")
    # This will fail if texture has been generated with no set_orig_file_size()
    size = size or (sprite.get_orig_file_x_size(),
                    sprite.get_orig_file_y_size())

    # Been told that its not in pixels, thus accepting either 1, 2 or 4 values
    # Kinda jank, I know
    if len(size) > 3:
        card.set_frame(-size[0], size[1], -size[2], size[3])
    elif len(size) > 1:
        card.set_frame(-size[0], size[0], -size[1], size[1])
    else:
        card.set_frame(-size[0], size[0], -size[0], size[0])

    parent = parent or NodePath()
    node = parent.attach_new_node(card.generate())
    node.set_texture(sprite)

    # Making it possible to utilize texture's alpha channel settings
    # This is a float from 0 to 1, but I dont think there is a point to only
    # show half of actual object's transparency.
    # Do it manually afterwards if thats what you need
    if is_transparent:
        node.set_transparency(1)
    # Enabling ability to render texture on both front and back of card
    if is_two_sided:
        node.set_two_sided(True)
    # Setting object's position. This is done relatively to parent, thus if you
    # didnt pass any, it may be a bit janky
    if position:
        node.set_pos(*position)

    if scale and scale > 0:
        node.set_scale(scale)

    return node
Exemple #14
0
 def flatten_animated_tiles(self, group_node):
     # FIXME: hard to read: get_child() everywhere
     # Makes a new node for each frame using all its tiles
     # flatten the s*** out of the node and add to a new SequenceNode.
     tiles = group_node.get_children()
     flattened_sequence = SequenceNode(tiles[0].name)
     for a, animation in enumerate(tiles[0].node().get_children()):
         for f, frame in enumerate(animation.get_child(0).get_children()):
             combined_frame = NodePath("frame " + str(f))
             for tile in tiles:
                 new_np = NodePath("frame")
                 new_np.set_pos(tile.get_pos())
                 animation = tile.node().get_child(a).get_child(0)
                 new_np.attach_new_node(animation.get_child(f))
                 new_np.reparent_to(combined_frame)
             combined_frame.flattenStrong()
             flattened_sequence.add_child(combined_frame.node())
     framerate = animation.get_frame_rate()
     flattened_sequence.set_frame_rate(framerate)
     flattened_sequence.loop(True)
     return NodePath(flattened_sequence)
Exemple #15
0
def create_lane_connections_card(node: Node, parent: NodePath) -> NodePath:
    """Create textured mesh showing lane connectins and attach it."""
    image = _create_lane_connections_image(node)
    texture = create_texture(image)

    card = parent.attach_new_node(CARD_MAKER.generate())
    card.set_pos((*node.position, 0.25))
    card.look_at(card, (0.0, 0.0, -1.0))
    card.set_texture(texture)
    card.set_transparency(TransparencyAttrib.M_alpha)
    card.set_shader_off()
    return card
Exemple #16
0
 def load_objectgroup(self, objectgroup):
     layer_node = NodePath(objectgroup.get("name"))
     for object in objectgroup:
         name = object.get("name")
         if not name: name = "object"
         node = NodePath(name)
         if len(object) > 0:
             # Has a type, so it's either a polygon, text, point or ellipse
             # Points and ellipses are just an empty for now.
             kind = object[0].tag
             if kind == "polygon":
                 node.attach_new_node(self.build_polygon(object))
             elif kind == "text":
                 node.attach_new_node(self.build_text(object))
                 node.set_p(-90)
             self.attributes_to_tags(node, object[0])
         else:  # Doesn't have a type, so it's either an image or a rectangle
             node = NodePath(name)
             w = float(object.get("width")) / self.xscale
             h = float(object.get("height")) / self.yscale
             if object.get("gid"):  # Has a gid, so it's an image
                 self.get_tile(int(object.get("gid"))).copy_to(node)
                 node.set_scale(w, h, 1)
             else:  # It's none of the above, so it's a rectangle
                 node.attach_new_node(self.build_rectangle(w, h))
         x = y = 0
         if object.get("x"):
             x = float(object.get("x")) / self.xscale
         if object.get("y"):
             y = float(object.get("y")) / self.yscale
         node.set_pos(x, -y, 0)
         self.attributes_to_tags(node, object)
         node.reparent_to(layer_node)
     self.append_layer(layer_node, objectgroup.find("properties"))
Exemple #17
0
def make_station(name, size=5):
    if size == 0: size = 0.1
    maker = base.shapes
    root = NodePath(str(name))
    root.set_scale(0.02)
    model = root.attach_new_node("station model")

    torus_color = random_color()
    sphere_color = random_color()
    cap_color = random_color()
    # Make poker
    w = uniform(0.01*size, 0.05*size)
    shape = choice(("Cylinder", "Cone"))
    maker.new(
        shape,random_color(), parent=model,
        pos=(0,0,0), hpr=(0,0,0), scale=(w,w,size)
    )
    # Add kebab
    rings = int(size+1)#int(randint(1,4))
    distance = size/rings  
    for i in range(rings):
        z = (distance*(i+1))+ distance
        w = uniform(min(0.2,0.05*size),0.5*size)
        shape = choice(("Torus", "Torus", "Sphere"))
        h = uniform(0.5,2)
        # Spheres should be flattened and not so wide.
        color = torus_color
        if shape == "Sphere": 
            h/=randint(2,5)
            w/=2
            color = sphere_color
        maker.new(
            shape, color, parent=model,
            pos=(0,0,z), hpr=(0,0,0), scale=(w,w,h)
        )
    # Add top and bottom cap
    def cap(z,p):
        shape = choice(("Cone", "Sphere"))
        w = uniform(0.1*size,0.3*size)
        l = uniform(0.1,1)
        maker.new(
            shape, cap_color, parent=model,
            pos=(0,0,z), hpr=(0,p,0), scale=(w,w,l)
        )
    if not randint(0,2):
        cap(size*2,0)
    if not randint(0,2):
        cap(0,180)
 
    model.set_pos(0,0,-size/2)    
    root.flatten_strong()        
    return root
Exemple #18
0
    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()
Exemple #19
0
 def createPlane(self, frame=None, color=VBase4(1, 1, 1, 1)):
     """ Creates a Plane/Card with the Panda3d Cardmaker() class
     Keyword Arguments:
         frame {list} -- The coordinates [x1,y1,x2,y2] of the planes/cards edges (default: {[-1, -1, 1, 1]})
         color {VBase4} -- The color of the planes/cards (default: {VBase4(1, 1, 1, 1)})
     """
     frame = frame or [-1, -1, 1, 1]
     card = CardMaker("plane")
     card.set_color(color)
     card.set_frame(frame[0], frame[1], frame[2], frame[3])
     n = NodePath()
     self.plane = n.attach_new_node(card.generate())
     self.plane.reparentTo(self.render)
     self.plane.setHpr(0, 270, 0)
Exemple #20
0
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False):
    card_maker = CardMaker(name)
    card_maker.set_frame(-1, 1, -1, 1)
    node_path = NodePath(name)
    node = card_maker.generate()
    final_node_path = node_path.attach_new_node(node)
    final_node_path.set_billboard_point_eye()
    from panda3d.core import Filename
    shaders = Shader.load(Shader.SL_GLSL,
                          Filename('Shader/Star/vertex.glsl'),
                          Filename('Shader/Star/fragment.glsl'),
                          Filename(''),
                          Filename(''),
                          Filename(''))
    if not shaders:
        print("WARNING. STAR SHADER FAILED TO LOAD", type(shaders))
    else:
        final_node_path.set_shader_input('cameraSpherePos', 1, 1, 1)
        final_node_path.set_shader_input('sphereRadius', 1.0)
        final_node_path.set_shader_input('myCamera', base.camera)
        final_node_path.set_shader(shaders)
        final_node_path.set_shader_input('blackbody', color)
    material = Material()
    material.set_emission(VBase4(color, 1.0))
    final_node_path.set_material(material)
    xn = PerlinNoise3(0.5, 0.5, 0.5)
    #yn = PerlinNoise3(0.5, 0.5, 0.5)
    texture = Texture('star')
    texture.setup_3d_texture()
    for z in range(texture_size):
        p = PNMImage(texture_size, texture_size)
        for y in range(texture_size):
            for x in range(texture_size):
                p.set_gray(x, y, abs(xn.noise(x, y, z)))
        texture.load(p, z, 0)
    diffuse = texture
    diffuse.setMinfilter(Texture.FTLinearMipmapLinear)
    diffuse.setAnisotropicDegree(4)
    final_node_path.set_texture(diffuse)
    normal = sandbox.base.loader.loadTexture('data/empty_textures/empty_normal.png')
    normalts = TextureStage('normalts')
    final_node_path.set_texture(normalts, normal)
    specular = sandbox.base.loader.loadTexture('data/empty_textures/empty_specular.png')
    spects = TextureStage('spects')
    final_node_path.set_texture(spects, specular)
    roughness = sandbox.base.loader.loadTexture('data/empty_textures/empty_roughness.png')
    roughts= TextureStage('roughts')
    final_node_path.set_texture(roughts, roughness)
    return final_node_path
Exemple #21
0
def make_ship(name):
    maker = base.shapes
    root = NodePath(str(name))
    root.set_scale(0.007)
    model = root.attach_new_node("station model")
    maker.new(
        "Cone", random_color(), parent=model,
        pos=(0,0,0), hpr=(0,0,0), scale=(0.2,0.2,1)
    )
    maker.new(
        "Cone", random_color(), parent=model,
        pos=(0,0,0.3), hpr=(0,0,0), scale=(0.2,1,0.5)
    )
    root.flatten_strong()
    return root
Exemple #22
0
def make_character(name):
    maker = base.shapes
    root = NodePath(str(name))
    root.set_scale(0.0005)
    model = root.attach_new_node("station model")

    maker.new(
        "Cone", random_color(), parent=model,
        pos=(0,0,0), hpr=(0,180,0), scale=(0.2,1,1)
    )
    maker.new(
        "Sphere", random_color(), parent=model,
        pos=(0,0,1), hpr=(0,0,0), scale=(1,1,1)
    )
    root.flatten_strong()
    return root
def test_nodepath_replace_texture():
    from panda3d.core import NodePath, Texture

    tex1 = Texture()
    tex2 = Texture()

    path1 = NodePath("node1")
    path1.set_texture(tex1)
    path1.replace_texture(tex1, tex2)
    assert path1.get_texture() == tex2

    path1 = NodePath("node1")
    path2 = path1.attach_new_node("node2")
    path2.set_texture(tex1)
    path1.replace_texture(tex1, tex2)
    assert not path1.has_texture()
    assert path2.get_texture() == tex2
Exemple #24
0
    def __init__(self, camera_collection: cameras.Cameras,
                 map_scene: core.NodePath):
        self._camera_collection = camera_collection

        self._grid_parent: core.NodePath = map_scene.attach_new_node("grid_3d")
        self._grid_parent.set_transparency(True)

        self._small_grid = shapes.make_grid(
            self._camera_collection,
            "movement_grid",
            2,
            100,
            core.Vec4(0.5, 0.55, 0.8, 0.85),
        )
        self._small_grid.reparent_to(self._grid_parent)

        self._big_grid = shapes.make_grid(
            self._camera_collection,
            "big_movement_grid",
            4,
            100,
            core.Vec4(1, 0, 0, 0.95),
        )
        self._big_grid.reparent_to(self._grid_parent)
        self._big_grid.set_scale(self._LARGE_GRID_SIZE)

        self._vertical_grid = shapes.make_z_grid(
            self._camera_collection,
            "big_movement_grid",
            2,
            100,
            core.Vec4(0, 0, 1, 0.95),
        )
        self._vertical_grid.reparent_to(self._grid_parent)

        self._grid_parent.set_depth_offset(constants.DEPTH_OFFSET, 1)
        self._grid_parent.hide()

        self.set_color_scale = self._grid_parent.set_color_scale
        self.show = self._grid_parent.show
        self.hide = self._grid_parent.hide
        self.is_hidden = self._grid_parent.is_hidden
Exemple #25
0
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 make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False):
    card_maker = CardMaker(name)
    card_maker.set_frame(-1, 1, -1, 1)
    node_path = NodePath(name)
    node = card_maker.generate()
    final_node_path = node_path.attach_new_node(node)
    final_node_path.set_billboard_point_eye()
    shaders = Shader.load(Shader.SLGLSL,
                          'Shader/Star/vertex.glsl',
                          'Shader/Star/fragment.glsl')
    final_node_path.set_shader_input(b'cameraSpherePos', 1, 1, 1)
    final_node_path.set_shader_input(b'sphereRadius', 1.0)
    final_node_path.set_shader_input(b'myCamera', base.camera)
    final_node_path.set_shader(shaders)
    final_node_path.set_shader_input(b'blackbody', color)
    material = Material()
    material.set_emission(VBase4(color, 1.0))
    final_node_path.set_material(material)
    xn = PerlinNoise3(0.5, 0.5, 0.5)
    #yn = PerlinNoise3(0.5, 0.5, 0.5)
    texture = Texture('star')
    texture.setup_3d_texture()
    for z in range(texture_size):
        p = PNMImage(texture_size, texture_size)
        for y in range(texture_size):
            for x in range(texture_size):
                p.set_gray(x, y, abs(xn.noise(x, y, z)))
        texture.load(p, z, 0)
    diffuse = texture
    diffuse.setMinfilter(Texture.FTLinearMipmapLinear)
    diffuse.setAnisotropicDegree(4)
    final_node_path.set_texture(diffuse)
    normal = base.loader.loadTexture('Data/Textures/EmptyNormalTexture.png')
    normalts = TextureStage('normalts')
    final_node_path.set_texture(normalts, normal)
    specular = base.loader.loadTexture('Data/Textures/EmptySpecularTexture.png')
    spects = TextureStage('spects')
    final_node_path.set_texture(spects, specular)
    roughness = base.loader.loadTexture('Data/Textures/EmptyRoughnessTexture.png')
    roughts= TextureStage('roughts')
    final_node_path.set_texture(roughts, roughness)
    return final_node_path
Exemple #27
0
def create(parent: NodePath, path: Path) -> NodePath:
    """Create node for given path and attach it to the parent."""
    points = path.oriented_points()

    if len(points) >= 2:
        geom = _generate_mesh(points)
        node = GeomNode('path')
        node.add_geom(geom)
        node.adjust_draw_mask(0x00000000, 0x00010000, 0xfffeffff)
        node_path = parent.attach_new_node(node)
        node_path.set_light_off()
        # Setting depth write to false solves the problem of this big flat
        # polygon obscuring other semi-transparent things (like the lane
        # connections card) depending on the camera angle. See:
        # https://docs.panda3d.org/1.10/python/programming/texturing/transparency-and-blending
        node_path.set_depth_write(False)
        node_path.set_transparency(TransparencyAttrib.M_alpha)
    else:
        node_path = None

    return node_path
Exemple #28
0
def make_collision(solid_from, solid_into):
    node_from = CollisionNode("from")
    node_from.add_solid(solid_from)
    node_into = CollisionNode("into")
    node_into.add_solid(solid_into)

    root = NodePath("root")
    trav = CollisionTraverser()
    queue = CollisionHandlerQueue()

    np_from = root.attach_new_node(node_from)
    np_into = root.attach_new_node(node_into)

    trav.add_collider(np_from, queue)
    trav.traverse(root)

    entry = None
    for e in queue.get_entries():
        if e.get_into() == solid_into:
            entry = e

    return (entry, np_from, np_into)
Exemple #29
0
class RayMarchingShape(Shape):
    templates = {}

    def __init__(self, radius=1.0, scale=None):
        Shape.__init__(self)
        self.radius = radius
        if scale is None:
            self.radius = radius
            self.scale = LVecBase3(self.radius, self.radius, self.radius)
        else:
            self.scale = LVecBase3(*scale) * radius
            self.radius = max(scale) * radius
        self.blend = TransparencyBlend.TB_PremultipliedAlpha
        self.scale_factor = 1.0

    def shape_id(self):
        return ''

    def get_apparent_radius(self):
        return self.radius

    def create_instance(self):
        self.instance = NodePath("card")
        card_maker = CardMaker("card")
        card_maker.set_frame(-1, 1, -1, 1)
        node = card_maker.generate()
        self.card_instance = self.instance.attach_new_node(node)
        self.card_instance.setBillboardPointWorld()
        TransparencyBlend.apply(self.blend, self.instance)
        self.instance.node().setBounds(OmniBoundingVolume())
        self.instance.node().setFinal(True)
        return self.instance

    def get_scale(self):
        return Shape.get_scale(self) * self.scale_factor

    def update_instance(self, camera_pos, orientation):
        alpha = asin(self.radius / self.owner.distance_to_obs)
        self.scale_factor = 1.0 / cos(alpha)
Exemple #30
0
def make_collision(solid_from, solid_into):
    node_from = CollisionNode("from")
    node_from.add_solid(solid_from)
    node_into = CollisionNode("into")
    node_into.add_solid(solid_into)

    root = NodePath("root")
    trav = CollisionTraverser()
    queue = CollisionHandlerQueue()

    np_from = root.attach_new_node(node_from)
    np_into = root.attach_new_node(node_into)

    trav.add_collider(np_from, queue)
    trav.traverse(root)

    entry = None
    for e in queue.get_entries():
        if e.get_into() == solid_into:
            entry = e

    return (entry, np_from, np_into)
Exemple #31
0
class PointBall(object):
    def __init__(self, position, value):
        #Invisiible point so that both spheres have the same parent
        self.name = "pointball"
        self.center = NodePath(PandaNode("Pointball center"))
        self.ttl = 15  #Time to live in seconds
        self.ttl_max = 15
        self.max_size = 9000
        self.attraction_distance = 900000
        self.center.setPos(position)
        self.center.setTag("value", str(value))
        # Create 1st sphere
        self.one = loader.loadModel("./Models/sphere.egg")
        self.one.setColor(colors.get("blue-transparent"))
        self.one.setScale(self.max_size, self.max_size, self.max_size)
        self.one.setLightOff()
        self.one.reparentTo(self.center)
        #Create 2nd sphere
        self.two = loader.loadModel("./Models/sphere.egg")
        self.two.setColor(colors.get("lightblue-transparent"))
        self.two.setScale(self.max_size, self.max_size, self.max_size)
        self.two.setLightOff()
        self.two.reparentTo(self.center)

        #Create the light so the missle glows
        plight = PointLight('plight')
        plight.setColor(colors.get("blue"))
        plight.setAttenuation(LVector3(0, 0.000008, 0))
        plight.setMaxDistance(100)
        self.plnp = self.center.attachNewNode(plight)  #point light node point
        render.setLight(self.plnp)

        # Create Collision hitsphere
        cNode = CollisionNode(self.name)
        cNode.addSolid(CollisionSphere(0, 0, 0, self.max_size * 20))
        self.c_np = self.center.attach_new_node(cNode)
        #Render to scene
        self.center.reparentTo(render)
Exemple #32
0
    def __init__(self,
                 services: Services,
                 data: NDArray[(Any, Any, Any), bool],
                 parent: NodePath,
                 name: str = "map"):
        self._services = services
        self.__name = name
        self.__colour_callbacks = {}

        self.data = data

        self.logical_w = int(self.data.shape[0])
        self.logical_h = int(self.data.shape[1])
        self.logical_d = int(self.data.shape[2])

        self._services.ev_manager.register_listener(self)

        self.__root = parent.attach_new_node(self.name)
        self.root.set_transparency(TransparencyAttrib.M_alpha)

        self._add_colour(MapData.BG,
                         callback=lambda dc: self._services.graphics.window.
                         set_background_color(*dc()))
class PostProcessRegion(RPObject):

    """ Simple wrapper class to create fullscreen triangles and quads """

    @classmethod
    def make(cls, internal_buffer, *args):
        return cls(internal_buffer, *args)

    def __init__(self, internal_buffer, *args):
        RPObject.__init__(self)
        self._buffer = internal_buffer
        self._region = self._buffer.make_display_region(*args)
        self._node = NodePath("RTRoot")

        self._make_fullscreen_tri()
        self._make_fullscreen_cam()
        self._init_function_pointers()

    def _init_function_pointers(self):
        self.set_sort = self._region.set_sort
        self.set_instance_count = self._tri.set_instance_count
        self.disable_clears = self._region.disable_clears
        self.set_active = self._region.set_active
        self.set_clear_depth_active = self._region.set_clear_depth_active
        self.set_clear_depth = self._region.set_clear_depth
        self.set_shader = self._tri.set_shader
        self.set_camera = self._region.set_camera
        self.set_clear_color_active = self._region.set_clear_color_active
        self.set_clear_color = self._region.set_clear_color
        self.set_attrib = self._tri.set_attrib

    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

    def set_shader_input(self, *args, **kwargs):
        if kwargs.get("override", False):
            self._node.set_shader_input(*args, priority=100000)
        else:
            self._tri.set_shader_input(*args)

    def _make_fullscreen_cam(self):
        """ Creates an orthographic camera for the buffer """
        buffer_cam = Camera("BufferCamera")
        lens = OrthographicLens()
        lens.set_film_size(2, 2)
        lens.set_film_offset(0, 0)
        lens.set_near_far(-100, 100)
        buffer_cam.set_lens(lens)
        buffer_cam.set_cull_bounds(OmniBoundingVolume())
        self._camera = self._node.attach_new_node(buffer_cam)
        self._region.set_camera(self._camera)
Exemple #34
0
def v():
    return (random.random() - .5) * 2 * r


roots = []
idx2ori_nps = {}
for k in range(50):
    root = NodePath("flatten_root:%s" % k)
    root.reparent_to(G.render)
    nps = []
    for i in range(50):
        model = G.loader.loadModel('../assets/blender/twig.egg')
        # one trap here.
        # getChildren() at first, flatten() won't touch any geoms under model node path.
        new_np = root.attach_new_node('child_%s_%s' % (k, i))
        model.get_children().reparentTo(new_np)
        new_np.set_pos(v(), v(), v())

        #nps.append(new_np)
    roots.append(root)
    idx2ori_nps[k] = nps

var = {'ts': 0}


def flatten(idx=0):
    if idx >= len(roots):
        return
    import time
    var['ts'] = time.time()
Exemple #35
0
class World (object):
    """
    The World models basically everything about a map, including gravity, ambient light, the sky, and all map objects.
    """

    def __init__(self, camera, debug=False, audio3d=None, client=None, server=None):
        self.objects = {}
        self.incarnators = []
        self.collidables = set()
        self.updatables = set()
        self.updatables_to_add = set()
        self.garbage = set()
        self.render = NodePath('world')
        self.camera = camera
        self.audio3d = audio3d
        self.ambient = self._make_ambient()
        self.celestials = CompositeObject()
        self.sky = self.attach(Sky())
        # Set up the physics world. TODO: let maps set gravity.
        self.gravity = DEFAULT_GRAVITY
        self.physics = BulletWorld()
        self.physics.set_gravity(self.gravity)
        self.debug = debug
        self.client = client
        self.server = server
        if debug:
            debug_node = BulletDebugNode('Debug')
            debug_node.show_wireframe(True)
            debug_node.show_constraints(True)
            debug_node.show_bounding_boxes(False)
            debug_node.show_normals(False)
            np = self.render.attach_new_node(debug_node)
            np.show()
            self.physics.set_debug_node(debug_node)

    def _make_ambient(self):
        alight = AmbientLight('ambient')
        alight.set_color(VBase4(*DEFAULT_AMBIENT_COLOR))
        node = self.render.attach_new_node(alight)
        self.render.set_light(node)
        return node

    def attach(self, obj):
        assert hasattr(obj, 'world') and hasattr(obj, 'name')
        assert obj.name not in self.objects
        obj.world = self
        if obj.name.startswith('Incarnator'):
            self.incarnators.append(obj)
        if hasattr(obj, 'create_node') and hasattr(obj, 'create_solid'):
            # Let each object define it's own NodePath, then reparent them.
            obj.node = obj.create_node()
            obj.solid = obj.create_solid()
            if obj.solid:
                if isinstance(obj.solid, BulletRigidBodyNode):
                    self.physics.attach_rigid_body(obj.solid)
                elif isinstance(obj.solid, BulletGhostNode):
                    self.physics.attach_ghost(obj.solid)
            if obj.node:
                if obj.solid:
                    # If this is a solid visible object, create a new physics node and reparent the visual node to that.
                    phys_node = self.render.attach_new_node(obj.solid)
                    obj.node.reparent_to(phys_node)
                    obj.node = phys_node
                else:
                    # Otherwise just reparent the visual node to the root.
                    obj.node.reparent_to(self.render)
            elif obj.solid:
                obj.node = self.render.attach_new_node(obj.solid)
            if obj.solid and obj.collide_bits is not None:
                obj.solid.set_into_collide_mask(obj.collide_bits)
        self.objects[obj.name] = obj
        # Let the object know it has been attached.
        obj.attached()
        return obj

    def get_incarn(self):
        return random.choice(self.incarnators)

    def create_hector(self, name=None):
        # TODO: get random incarn, start there
        h = self.attach(Hector(name))
        h.move((0, 15, 0))
        return h

    def set_ambient(self, color):
        """
        Sets the ambient light to the given color.
        """
        self.ambient.node().set_color(VBase4(*color))

    def add_celestial(self, azimuth, elevation, color, intensity, radius, visible):
        """
        Adds a celestial light source to the scene. If it is a visible celestial, also add a sphere model.
        """
        if not self.camera:
            return
        location = Vec3(to_cartesian(azimuth, elevation, 1000.0 * 255.0 / 256.0))
        if intensity:
            dlight = DirectionalLight('celestial')
            dlight.set_color((color[0] * intensity, color[1] * intensity,
                color[2] * intensity, 1.0))
            node = self.render.attach_new_node(dlight)
            node.look_at(*(location * -1))
            self.render.set_light(node)
        if visible:
            if radius <= 2.0:
                samples = 6
            elif radius >= 36.0:
                samples = 40
            else:
                samples = int(round(((1.5 * radius) * (2 / 3.0)) + 3.75))
            celestial = Dome(radius * 1.5, samples, 2, color, 0, location,
                ((-(math.degrees(azimuth))), 90 + math.degrees(elevation), 0))
            self.celestials.attach(celestial)

    def create_celestial_node(self):
        bounds = self.camera.node().get_lens().make_bounds()
        self.celestials = self.celestials.create_node()
        self.celestials.set_transparency(TransparencyAttrib.MAlpha)
        self.celestials.set_light_off()
        self.celestials.set_effect(CompassEffect.make(self.camera, CompassEffect.PPos))
        self.celestials.node().set_bounds(bounds)
        self.celestials.node().set_final(True)
        self.celestials.reparent_to(self.render)

    def register_collider(self, obj):
        assert isinstance(obj, PhysicalObject)
        self.collidables.add(obj)

    def register_updater(self, obj):
        assert isinstance(obj, WorldObject)
        self.updatables.add(obj)

    def register_updater_later(self, obj):
        assert isinstance(obj, WorldObject)
        self.updatables_to_add.add(obj)

    def do_explosion(self, node, radius, force):
        center = node.get_pos(self.render);
        expl_body = BulletGhostNode("expl")
        expl_shape = BulletSphereShape(radius)
        expl_body.add_shape(expl_shape)
        expl_bodyNP = self.render.attach_new_node(expl_body)
        expl_bodyNP.set_pos(center)
        self.physics.attach_ghost(expl_body)
        result = self.physics.contact_test(expl_body)
        for contact in result.getContacts():
            n0_name = contact.getNode0().get_name()
            n1_name = contact.getNode1().get_name()
            obj = None
            try:
                obj = self.objects[n1_name]
            except:
                break
            if n0_name == "expl" and n1_name not in EXPLOSIONS_DONT_PUSH and not n1_name.startswith('Walker'):
                # repeat contact test with just this pair of objects
                # otherwise all manifold point values will be the same
                # for all objects in original result
                real_c = self.physics.contact_test_pair(expl_body, obj.solid)
                mpoint = real_c.getContacts()[0].getManifoldPoint()
                distance = mpoint.getDistance()
                if distance < 0:
                    if hasattr(obj, 'decompose'):
                        obj.decompose()
                    else:
                        expl_vec = Vec3(mpoint.getPositionWorldOnA() - mpoint.getPositionWorldOnB())
                        expl_vec.normalize()
                        magnitude = force * 1.0/math.sqrt(abs(radius - abs(distance)))
                        obj.solid.set_active(True)
                        obj.solid.apply_impulse(expl_vec*magnitude, mpoint.getLocalPointB())
                    if hasattr(obj, 'damage'):
                        obj.damage(magnitude/5)
        self.physics.remove_ghost(expl_body)
        expl_bodyNP.detach_node()
        del(expl_body, expl_bodyNP)

    def do_plasma_push(self, plasma, node, energy):
        obj = None
        try:
            obj = self.objects[node]
        except:
            raise
    
        if node not in EXPLOSIONS_DONT_PUSH and not node.startswith('Walker'):
            if hasattr(obj, 'decompose'):
                obj.decompose()
            else:
                solid = obj.solid
                dummy_node = NodePath('tmp')
                dummy_node.set_hpr(plasma.hpr)
                dummy_node.set_pos(plasma.pos)
                f_vec = render.get_relative_vector(dummy_node, Vec3(0,0,1))
                local_point = (obj.node.get_pos() - dummy_node.get_pos()) *-1
                f_vec.normalize()
                solid.set_active(True)
                try:
                    solid.apply_impulse(f_vec*(energy*35), Point3(local_point))
                except:
                    pass
                del(dummy_node)
        if hasattr(obj, 'damage'):
            obj.damage(energy*5)


    def update(self, task):
        """
        Called every frame to update the physics, etc.
        """
        dt = globalClock.getDt()
        for obj in self.updatables_to_add:
            self.updatables.add(obj)
        self.updatables_to_add = set()
        for obj in self.updatables:
            obj.update(dt)
        self.updatables -= self.garbage
        self.collidables -= self.garbage
        while True:
            if len(self.garbage) < 1:
                break;
            trash = self.garbage.pop()
            if(isinstance(trash.solid, BulletGhostNode)):
                self.physics.remove_ghost(trash.solid)
            if(isinstance(trash.solid, BulletRigidBodyNode)):
                self.physics.remove_rigid_body(trash.solid)
            if hasattr(trash, 'dead'):
                trash.dead()
            trash.node.remove_node()
            del(trash)
        self.physics.do_physics(dt)
        for obj in self.collidables:
            result = self.physics.contact_test(obj.node.node())
            for contact in result.get_contacts():
                obj1 = self.objects.get(contact.get_node0().get_name())
                obj2 = self.objects.get(contact.get_node1().get_name())
                if obj1 and obj2:
                    # Check the collision bits to see if the two objects should collide.
                    should_collide = obj1.collide_bits & obj2.collide_bits
                    if not should_collide.is_zero():
                        pt = contact.get_manifold_point()
                        if obj1 in self.collidables:
                            obj1.collision(obj2, pt, True)
                        if obj2 in self.collidables:
                            obj2.collision(obj1, pt, False)
        return task.cont
Exemple #36
0
class ColorWorld(object):
    def __init__(self, config=None):
        # keep track of velocity, this allows me to counteract joystick with keyboard
        self.velocity = LVector3(0)
        if config is None:
            self.config = {}
            execfile('config.py', self.config)
        else:
            self.config = config
        self.reward = None
        if pydaq:
            self.reward = pydaq.GiveReward()
        self.reward_count = 0
        # self.color_map always corresponds to (r, g, b)
        # does not change during game, each game uses a particular color space
        self.color_dict = square.make_color_map(self.config['colors'])
        # sets the range of colors for this map
        self.c_range = self.config['c_range']
        # color variables (make dictionary?)
        # color_list is set in beginning, and then after that this is only
        # called again for non-random (training)
        self.color_list = square.set_start_position_colors(self.config)
        self.color_match = [0, 0, 0]
        self.color_tolerance = []
        self.last_avt, self.avt_factor = square.translate_color_map(self.config, self.color_dict, self.color_list)
        print 'starting avt position', self.last_avt
        print 'map avatar factor', self.avt_factor
        self.random = True
        if self.config.get('match_direction'):
            self.random = False
        # adjustment to speed so corresponds to gobananas task
        # 7 seconds to cross original environment
        # speed needs to be adjusted to both speed in original
        # environment and c_range of colors
        # self.speed = 0.05 * (self.c_range[1] - self.c_range[0])
        # speed is own variable, so can be changed during training.
        self.speed = self.config['speed']
        # map avatar variables
        self.render2d = None
        self.match_square = None
        self.map_avt_node = []

        # need a multiplier to the joystick output to tolerable speed
        self.vel_base = 3
        self.max_vel = [500, 500, 0]

        self.card = None

        self.base = ShowBase()
        self.base.disableMouse()
        # assume we are showing windows unless proven otherwise
        if self.config.get('win', True):
            # only need inputs if we have a window
            self.inputs = Inputs(self.base)
            props = WindowProperties()
            props.setCursorHidden(True)
            props.setForeground(True)
            print self.config.get('resolution')
            if self.config.get('resolution'):
                props.set_size(int(self.config['resolution'][0]), int(self.config['resolution'][1]))
                props.set_origin(0, 0)
            else:
                props.set_size(600, 600)
                props.set_origin(400, 50)
            self.base.win.requestProperties(props)
            # print self.base.win.get_size()
            # setup color map on second window
            sq_node = square.setup_square(self.config)
            self.setup_display2(sq_node)
        # print 'background color', self.base.getBackgroundColor()
        # create the avatar
        self.avatar = NodePath(ActorNode("avatar"))
        self.avatar.reparentTo(self.base.render)
        self.avatar.setH(self.base.camera.getH())
        self.base.camera.reparentTo(self.avatar)
        self.base.camera.setPos(0, 0, 0)

        # initialize task variables
        self.frame_task = None
        self.started_game = None
        self.showed_match = None
        self.gave_reward = None

        # initialize and start the game
        self.set_next_trial()

        # print 'end init'

    def start_loop(self):
        # need to get new match
        print 'start loop'
        self.started_game = self.base.taskMgr.doMethodLater(5, self.start_play, 'start_play')
        self.showed_match = self.base.taskMgr.add(self.show_match_sample, 'match_image')

    # Task methods
    def show_match_sample(self, task):
        print 'show match sample'
        print self.color_match[:]
        # match_image.fill(*self.color_match[:])
        card = CardMaker('card')
        color_match = self.color_match[:]
        # add alpha channel
        color_match.append(1)
        print color_match
        card.set_color(*color_match[:])
        card.set_frame(-12, -8, 0, 4)
        # log this
        self.card = self.base.render.attach_new_node(card.generate())
        return task.done

    def start_play(self, task):
        print 'start play'
        # log this
        self.base.taskMgr.remove('match_image')
        self.card.removeNode()
        # print self.base.render.ls()
        self.frame_task = self.base.taskMgr.add(self.game_loop, "game_loop")
        self.frame_task.last = 0  # initiate task time of the last frame
        # log this
        self.base.setBackgroundColor(self.color_list[:])
        return task.done

    def game_loop(self, task):
        dt = task.time - task.last
        task.last = task.time
        self.velocity = self.inputs.poll_inputs(self.velocity)
        move = self.move_avatar(dt)
        stop = self.change_background(move)
        self.move_map_avatar(move, stop)
        match = self.check_color_match()
        if match:
            self.give_reward()
            return task.done
        return task.cont

    def reward_loop(self, task):
        self.reward_count += 1
        if self.reward_count <= self.config['num_beeps']:
            if self.reward:
                # log this
                print 'give a bloody reward already'
                self.reward.pumpOut()
            print 'give reward'
            return task.again
        else:
            self.end_loop()
            return task.done

    def move_avatar(self, dt):
        # print 'velocity', self.velocity
        # this makes for smooth (correct speed) diagonal movement
        # print 'velocity', self.velocity
        magnitude = max(abs(self.velocity[0]), abs(self.velocity[1]))
        move = None
        if self.velocity.normalize():
            # go left in increasing amount
            # print 'dt', dt
            # print 'normalized'
            # print 'velocity', self.velocity
            # print 'magnitude', magnitude
            self.velocity *= magnitude
            # print 'velocity', self.velocity
            # this makes for smooth movement
            move = self.velocity * self.vel_base * dt
            # print move
            self.avatar.setFluidPos(self.avatar, move)
        return move

    def change_background(self, move):
        stop = [True, True, True]
        if move:
            # print move
            move *= self.speed
            for i in range(3):
                value = self.color_dict[i]
                if value is not None:
                    stop[i] = False
                    # keys correspond to x,y,z
                    # values correspond to r,g,b
                    if i == 2:
                        # z axis is treated differently
                        # need to work on this. z should
                        # be at min when both x and y are at max
                        # taking the average is not quite right...
                        z_move = (move[0] + move[1])/2
                        # print z_move
                        self.color_list[value] -= z_move
                    else:
                        self.color_list[value] += move[i]
                    if self.color_list[value] < self.c_range[0]:
                        self.color_list[value] = self.c_range[0]
                        stop[i] = True
                    elif self.color_list[value] > self.c_range[1]:
                        self.color_list[value] = self.c_range[1]
                        stop[i] = True
            # log this
            self.base.setBackgroundColor(self.color_list[:])
            # print self.base.getBackgroundColor()
        return stop

    def move_map_avatar(self, move, stop):
        # print move
        # avatar is mapped assuming c_range of 0.5. What do I need to
        # change to use a different c_range? c_range of one is twice
        # the
        if move:
            avt = LineSegs()
            avt.setThickness(1)
            avt.setColor(1, 1, 1)
            # print 'last', self.last_avt
            avt.move_to(self.last_avt[0], -5, self.last_avt[1])
            # print 'move', move
            new_move = [i + (j * self.avt_factor) for i, j in zip(self.last_avt, move)]
            # new_move = [i + j for i, j in zip(self.last_avt, move)]
            # would it be better to have a local stop condition?
            if stop[0]:
                new_move[0] = self.last_avt[0]
                # print 'stop x', self.last_avt[0]
            if stop[1]:
                new_move[1] = self.last_avt[1]
                # print 'stop y', self.last_avt[1]
            # print 'new', new_move
            self.last_avt = [new_move[0], new_move[1]]
            avt.draw_to(new_move[0], -5, new_move[1])
            self.map_avt_node.append(self.render2d.attach_new_node(avt.create()))
            # print self.map_avt_node[-1]
            # can't let too many nodes pile up
            if len(self.map_avt_node) > 299:
                # removing the node does not remove the object from the list
                for i, j in enumerate(self.map_avt_node):
                    j.removeNode()
                    if i > 49:
                        break
                del self.map_avt_node[0:50]

    def check_color_match(self):
        # print 'match this', self.color_tolerance
        # print self.color_list
        check_color = [j[0] < self.color_list[i] < j[1] for i, j in enumerate(self.color_tolerance)]
        # print check_color
        if all(check_color):
            return True
        else:
            return False

    def give_reward(self):
        # clear the background
        self.base.setBackgroundColor(0.41, 0.41, 0.41)
        print 'give first reward'
        self.reward_count = 1
        if self.reward:
            # log this
            self.reward.pumpOut()
        self.gave_reward = self.base.taskMgr.doMethodLater(self.config['pump_delay'], self.reward_loop, 'reward_loop')

    def end_loop(self):
        print 'end loop'
        # clear avatar map
        self.clear_avatar_map()
        # if there is a match set, return to center of color gradient,
        # set new match, if applicable
        self.set_next_trial()

    def clear_avatar_map(self):
        for i, j in enumerate(self.map_avt_node):
            j.removeNode()
        self.map_avt_node = []

    def plot_match_square(self, corners):
        print 'plot match square'
        print corners
        match = LineSegs()
        match.setThickness(1.5)
        match.setColor(0, 0, 0)
        match.move_to(corners[0][0], -5, corners[1][0])
        match.draw_to(corners[0][1], -5, corners[1][0])
        match.draw_to(corners[0][1], -5, corners[1][1])
        match.draw_to(corners[0][0], -5, corners[1][1])
        match.draw_to(corners[0][0], -5, corners[1][0])
        # print self.render2d
        self.match_square = self.render2d.attach_new_node(match.create())

    def create_avatar_map_match_square(self, config=None):
        print 'make new square for map'
        if config is not None:
            config_dict = config
        else:
            config_dict = self.config
        # create square on avatar map for new color match
        map_color_match, factor = square.translate_color_map(config_dict, self.color_dict, self.color_match)
        tolerance = config_dict['tolerance'] * factor
        map_color_tolerance = [(i - tolerance, i + tolerance) for i in map_color_match]
        print map_color_tolerance
        if self.render2d:
            if self.match_square:
                self.match_square.removeNode()
            self.plot_match_square(map_color_tolerance)

    def set_next_trial(self):
        print 'set next trial'
        # move avatar back to beginning position, only matters for
        # showing card for next color match
        self.avatar.set_pos(-10, -10, 2)
        # set color_list with starting color
        # if random, won't use this again, but for manual, will
        # return to center
        # need to update self.config to new direction, if there is one
        if self.config.get('match_direction'):
            self.check_key_map()
            # return to center, otherwise random will start where you left off
            self.color_list = square.set_start_position_colors(self.config)
            # starting position for map avatar, just translate new color_list
            self.last_avt, self.avt_factor = square.translate_color_map(self.config, self.color_dict, self.color_list)
        print 'start color',  self.color_list
        print self.color_dict
        # again need to update self.config for match if using keys
        self.color_match = square.set_match_colors(self.config, self.color_dict)
        # sets the tolerance for how close to a color for reward
        self.color_tolerance = [(i - self.config['tolerance'], i + self.config['tolerance']) for i in self.color_match]
        print 'color match', self.color_match
        print 'color tolerance', self.color_tolerance
        self.create_avatar_map_match_square(self.config)
        # start the game
        self.start_loop()

    def check_key_map(self):
        if self.config['colors'][0]:
            if self.inputs.key_map['r']:
                self.config['match_direction'] = ['right']
            elif self.inputs.key_map['r'] is not None:
                self.config['match_direction'] = ['left']
        elif self.config['colors'][1]:
            if self.inputs.key_map['f']:
                self.config['match_direction'] = ['front']
            elif self.inputs.key_map['f'] is not None:
                self.config['match_direction'] = ['back']

    def setup_display2(self, display_node):
        print 'setup display2'
        props = WindowProperties()
        props.set_cursor_hidden(True)
        props.set_foreground(False)
        if self.config.get('resolution'):
            props.setSize(700, 700)
            props.setOrigin(-int(self.config['resolution'][0] - 5), 5)
        else:
            props.setSize(300, 300)
            props.setOrigin(10, 10)
        window2 = self.base.openWindow(props=props, aspectRatio=1)
        lens = OrthographicLens()
        lens.set_film_size(2, 2)
        lens.setNearFar(-100, 100)
        self.render2d = NodePath('render2d')
        self.render2d.attach_new_node(display_node)
        camera2d = self.base.makeCamera(window2)
        camera2d.setPos(0, -10, 0)
        camera2d.node().setLens(lens)
        camera2d.reparentTo(self.render2d)
Exemple #37
0
class PlayWorld(object):
    def __init__(self, config=None):
        if config is None:
            self.config = {}
            execfile('play_config.py', self.config)
        else:
            self.config = config
        self.reward = None
        print self.config['pydaq']
        if pydaq and self.config.setdefault('pydaq', True) is not None:
            self.reward = pydaq.GiveReward()
        self.reward_count = 0
        # adjustment to speed so corresponds to gobananas task
        # 7 seconds to cross original environment
        # speed needs to be adjusted to both speed in original
        # environment and c_range of colors
        # self.speed = 0.05 * (self.c_range[1] - self.c_range[0])
        # speed is own variable, so can be changed during training.
        self.speed = self.config['speed']

        # need a multiplier to the joystick output to tolerable speed
        self.vel_base = 4
        self.max_vel = [500, 500, 0]

        self.base = ShowBase()
        self.base.disableMouse()
        # self.base.setFrameRateMeter(True)
        # assume we are showing windows unless proven otherwise
        if self.config.get('win', True):
            # only need inputs if we have a window
            self.inputs = Inputs(self.base)
            props = WindowProperties()
            props.setCursorHidden(True)
            props.setForeground(True)
            print self.config.get('resolution')
            if self.config.get('resolution'):
                # main window
                props.set_size(int(self.config['resolution'][0]), int(self.config['resolution'][1]))
                # props.set_origin(1920, 0)
                props.set_origin(500, 0)
            else:
                props.set_size(600, 600)
                props.set_origin(400, 50)
            self.base.win.requestProperties(props)
        # print 'background color', self.base.getBackgroundColor()
        # field = self.base.loader.loadModel("../goBananas/models/play_space/field.bam")
        field = self.base.loader.loadModel("../goBananas/models/play_space/round_courtyard.bam")
        field.setPos(0, 0, 0)
        field.reparent_to(self.base.render)
        field_node_path = field.find('**/+CollisionNode')
        field_node_path.node().setIntoCollideMask(0)
        sky = self.base.loader.loadModel("../goBananas/models/sky/sky_kahana2.bam")
        sky.setPos(0, 0, 0)
        sky.setScale(1.6)
        sky.reparentTo(self.base.render)
        windmill = self.base.loader.loadModel("../goBananas/models/windmill/windmill.bam")
        windmill.setPos(-10, 30, -1)
        windmill.setScale(0.03)
        windmill.reparentTo(self.base.render)
        # mountain = self.base.loader.loadModel("../goBananas/models/mountain/mountain.bam")
        # mountain.setScale(0.0005)
        # mountain.setPos(10, 30, -0.5)

        # create the avatar
        self.avatar = NodePath(ActorNode("avatar"))
        self.avatar.reparentTo(self.base.render)
        self.avatar.setPos(0, 0, 1)
        self.avatar.setScale(0.5)
        pl = self.base.cam.node().getLens()
        pl.setFov(60)
        self.base.cam.node().setLens(pl)
        self.base.camera.reparentTo(self.avatar)

        # initialize task variables
        self.frame_task = None
        self.started_game = None
        self.showed_match = None
        self.gave_reward = None

        # initialize and start the game
        self.set_next_trial()

        # print 'end init'

    def start_loop(self):
        # need to get new match
        self.start_play()

    def start_play(self):
        print 'start play'
        # log this
        # print self.base.render.ls()
        self.frame_task = self.base.taskMgr.add(self.game_loop, "game_loop")
        self.frame_task.last = 0  # initiate task time of the last frame

    def game_loop(self, task):
        dt = task.time - task.last
        task.last = task.time
        velocity = self.inputs.poll_inputs(LVector3(0))
        self.move_avatar(dt, velocity)
        return task.cont

    def reward_loop(self, task):
        self.reward_count += 1
        if self.reward_count <= self.config['num_beeps']:
            if self.reward:
                # log this
                print 'give a bloody reward already'
                self.reward.pumpOut()
            print 'give reward'
            return task.again
        else:
            self.end_loop()
            return task.done

    def move_avatar(self, dt, velocity):
        # print 'velocity', self.velocity
        self.avatar.setH(self.avatar.getH() - velocity[0] * 1.1)
        move = LVector3(0, velocity[1], 0)
        self.avatar.setPos(self.avatar, move * dt * self.vel_base)

    def give_reward(self):
        # clear the background
        self.base.setBackgroundColor(0.41, 0.41, 0.41)
        print 'give first reward'
        self.reward_count = 1
        if self.reward:
            # log this
            self.reward.pumpOut()
        self.gave_reward = self.base.taskMgr.doMethodLater(self.config['pump_delay'], self.reward_loop, 'reward_loop')

    def end_loop(self):
        print 'end loop'
        # clear avatar map
        # if there is a match set, return to center of color gradient,
        # set new match, if applicable
        self.set_next_trial()

    def set_next_trial(self):
        print 'set next trial'
        # move avatar back to beginning position, only matters for
        # showing card for next color match
        # self.avatar.set_pos(-10, -10, 2)
        # start the game
        self.start_loop()

    def check_key_map(self):
        if self.config['colors'][0]:
            if self.inputs.key_map['r']:
                self.config['match_direction'] = ['right']
            elif self.inputs.key_map['r'] is not None:
                self.config['match_direction'] = ['left']
        elif self.config['colors'][1]:
            if self.inputs.key_map['f']:
                self.config['match_direction'] = ['front']
            elif self.inputs.key_map['f'] is not None:
                self.config['match_direction'] = ['back']

    def setup_display2(self, display_node):
        print 'setup display2'
        props = WindowProperties()
        props.set_cursor_hidden(True)
        props.set_foreground(False)
        if self.config.get('resolution'):
            props.setSize(700, 700)
            props.setOrigin(-int(self.config['resolution'][0] - 5), 5)
        else:
            props.setSize(300, 300)
            props.setOrigin(10, 10)
        window2 = self.base.openWindow(props=props, aspectRatio=1)
        lens = OrthographicLens()
        lens.set_film_size(2, 2)
        lens.setNearFar(-100, 100)
        self.render2d = NodePath('render2d')
        self.render2d.attach_new_node(display_node)
        camera2d = self.base.makeCamera(window2)
        camera2d.setPos(0, -10, 0)
        camera2d.node().setLens(lens)
        camera2d.reparentTo(self.render2d)
Exemple #38
0
class World:

    def __init__(self, loader=None, camera=None, debug=False):
        self.loader = loader
        self.camera = camera
        self.physics = BulletWorld()
        self.gravity = Vec3(0, 0, -30.0)
        self.physics.set_gravity(self.gravity)
        self.objects = {}
        self.frame = 0
        self.last_object_id = 0
        self.incarnators = []
        self.debug = debug
        self.setup()
        self.commands = []

    def setup(self):
        self.node = NodePath('world')
        self.node.set_transparency(TransparencyAttrib.MAlpha)
        if self.debug:
            d = BulletDebugNode('Debug')
            d.show_wireframe(True)
            d.show_normals(True)
            self.node.attach_new_node(d).show()
            self.physics.set_debug_node(d)
        if self.camera:
            self.camera.node().get_lens().set_fov(80.0, 50.0)
            self.camera.node().get_lens().set_near(0.1)
        # Default ambient light
        alight = AmbientLight('ambient')
        alight.set_color(DEFAULT_AMBIENT_COLOR)
        self.ambient = self.node.attach_new_node(alight)
        self.node.set_light(self.ambient)
        # Default directional lights
        self.add_celestial(math.radians(20), math.radians(45), (1, 1, 1, 1), 0.4, 30.0)
        self.add_celestial(math.radians(200), math.radians(20), (1, 1, 1, 1), 0.3, 30.0)

    def tick(self, dt):
        self.frame += 1
        self.physics.doPhysics(dt, 4, 1.0 / 60.0)
        state = {}
        for obj in list(self.objects.values()):
            if obj.update(self, dt):
                state[obj.world_id] = obj.get_state()
        for cmd, args in self.commands:
            yield cmd, args
        if state:
            yield 'state', {'frame': self.frame, 'state': state}
        self.commands = []

    def attach(self, obj):
        obj.setup(self)
        if obj.world_id is None:
            self.last_object_id += 1
            obj.world_id = self.last_object_id
        self.objects[obj.world_id] = obj
        obj.attached(self)
        if self.frame > 0 and False:
            self.commands.append(('attached', {
                'objects': [obj.serialize()],
                'state': {
                    obj.world_id: obj.get_state(),
                }
            }))
        return obj

    def remove(self, world_id):
        if isinstance(world_id, GameObject):
            world_id = world_id.world_id
        if world_id not in self.objects:
            return
        self.objects[world_id].removed(self)
        del self.objects[world_id]
        if self.frame > 0:
            self.commands.append(('removed', {'world_ids': [world_id]}))

    def find(self, pos, radius):
        for obj in self.objects.values():
            if isinstance(obj, PhysicalObject):
                d = (obj.node.get_pos() - pos).length()
                if d <= radius:
                    yield obj, d

    def add_incarnator(self, pos, heading):
        self.incarnators.append((pos, heading))

    def load_model(self, name):
        """
        Stubbed out here in case we want to allow adding/loading custom models from map XML.
        """
        return self.loader.load_model(name) if self.loader else None

    def serialize(self):
        return {world_id: obj.serialize() for world_id, obj in self.objects.items()}

    def deserialize(self, data):
        self.node.remove_node()
        self.setup()
        for world_id, obj_data in data.items():
            self.attach(GameObject.deserialize(obj_data))

    def get_state(self):
        states = {}
        for world_id, obj in self.objects.items():
            states[world_id] = obj.get_state()
        return states

    def set_state(self, states, fluid=True):
        for world_id, state in states.items():
            self.objects[world_id].set_state(state, fluid=fluid)

    def add_celestial(self, azimuth, elevation, color, intensity, radius):
        location = Vec3(to_cartesian(azimuth, elevation, 1000.0 * 255.0 / 256.0))
        if intensity:
            dlight = DirectionalLight('celestial')
            dlight.set_color((color[0] * intensity, color[1] * intensity, color[2] * intensity, 1.0))
            node = self.node.attach_new_node(dlight)
            node.look_at(*(location * -1))
            self.node.set_light(node)
Exemple #39
0
class World (object):
    """
    The World models basically everything about a map, including gravity, ambient light, the sky, and all map objects.
    """

    def __init__(self, camera, debug=False, audio3d=None, client=None, server=None):
        self.objects = {}

        self.incarnators = []

        self.collidables = set()

        self.updatables = set()
        self.updatables_to_add = set()
        self.garbage = set()
        self.scene = NodePath('world')


        # Set up the physics world. TODO: let maps set gravity.
        self.gravity = DEFAULT_GRAVITY
        self.physics = BulletWorld()
        self.physics.set_gravity(self.gravity)

        self.debug = debug

        if debug:
            debug_node = BulletDebugNode('Debug')
            debug_node.show_wireframe(True)
            debug_node.show_constraints(True)
            debug_node.show_bounding_boxes(False)
            debug_node.show_normals(False)
            np = self.scene.attach_new_node(debug_node)
            np.show()
            self.physics.set_debug_node(debug_node)


    def get_incarn(self):
        return random.choice(self.incarnators)


    def attach(self, obj):
        assert hasattr(obj, 'world') and hasattr(obj, 'name')
        assert obj.name not in self.objects
        obj.world = self
        if obj.name.startswith('Incarnator'):
            self.incarnators.append(obj)
        if hasattr(obj, 'create_node') and hasattr(obj, 'create_solid'):
            # Let each object define it's own NodePath, then reparent them.
            obj.node = obj.create_node()
            obj.solid = obj.create_solid()
            if obj.solid:
                if isinstance(obj.solid, BulletRigidBodyNode):
                    self.physics.attach_rigid_body(obj.solid)
                elif isinstance(obj.solid, BulletGhostNode):
                    self.physics.attach_ghost(obj.solid)
            if obj.node:
                if obj.solid:
                    # If this is a solid visible object, create a new physics node and reparent the visual node to that.
                    phys_node = self.scene.attach_new_node(obj.solid)
                    obj.node.reparent_to(phys_node)
                    obj.node = phys_node
                else:
                    # Otherwise just reparent the visual node to the root.
                    obj.node.reparent_to(self.scene)
            elif obj.solid:
                obj.node = self.scene.attach_new_node(obj.solid)
            if obj.solid and obj.collide_bits is not None:
                obj.solid.set_into_collide_mask(obj.collide_bits)
        self.objects[obj.name] = obj
        # Let the object know it has been attached.
        obj.attached()
        return obj



    def create_hector(self, name=None):
        # TODO: get random incarn, start there
        h = self.attach(Hector(name))
        h.move((0, 15, 0))
        return h

    def register_updater(self, obj):
        assert isinstance(obj, WorldObject)
        self.updatables.add(obj)

    def register_updater_later(self, obj):
        assert isinstance(obj, WorldObject)
        self.updatables_to_add.add(obj)



    def update(self, task):
        """
        Called every frame to update the physics, etc.
        """
        dt = globalClock.getDt()
        for obj in self.updatables_to_add:
            self.updatables.add(obj)
        self.updatables_to_add = set()
        for obj in self.updatables:
            obj.update(dt)
        self.updatables -= self.garbage
        self.collidables -= self.garbage
        while True:
            if len(self.garbage) < 1:
                break;
            trash = self.garbage.pop()
            if(isinstance(trash.solid, BulletGhostNode)):
                self.physics.remove_ghost(trash.solid)
            if(isinstance(trash.solid, BulletRigidBodyNode)):
                self.physics.remove_rigid_body(trash.solid)
            if hasattr(trash, 'dead'):
                trash.dead()
            trash.node.remove_node()
            del(trash)
        self.physics.do_physics(dt)
        for obj in self.collidables:
            result = self.physics.contact_test(obj.node.node())
            for contact in result.get_contacts():
                obj1 = self.objects.get(contact.get_node0().get_name())
                obj2 = self.objects.get(contact.get_node1().get_name())
                if obj1 and obj2:
                    # Check the collision bits to see if the two objects should collide.
                    should_collide = obj1.collide_bits & obj2.collide_bits
                    if not should_collide.is_zero():
                        pt = contact.get_manifold_point()
                        if obj1 in self.collidables:
                            obj1.collision(obj2, pt, True)
                        if obj2 in self.collidables:
                            obj2.collision(obj1, pt, False)
        return task.cont