def get_move_direction(self) -> core.Vec3: if self._is_vertex: direction = self._wall.get_normalized_direction() return core.Vec3(direction.x, direction.y, 0) normal = self._wall.get_normal() return core.Vec3(normal.x, normal.y, 0)
def __init__( self, default_matcap: core.Texture, *, render_node: core.NodePath = None, light_dir: core.Vec3 = None, hueshift: core.Vec3 = None, ): self._default_matcap = default_matcap if render_node is None: render_node = base.render if light_dir is None: self._light_dir = core.PTA_float(core.Vec3(-1).normalized()) else: self._light_dir = core.PTA_float(light_dir.normalized()) if hueshift is None: hueshift = core.Vec3(0) self._hueshift = hueshift self._render_node = render_node # Do not force power-of-two textures core.Texture.set_textures_power_2(core.ATS_none) # Matcap Shader self._recompile_matcap()
def obelisk(r=(2.5, 1.8)): node_path = core.NodePath('obelisk') base = node_path.attach_new_node( sg.cone(origin=core.Vec3(0), direction=core.Vec3.up(), radius=r, polygon=4, length=15.0, smooth=False, capsule=False, origin_offset=0, color=core.Vec4(core.Vec3(0.2), 1), nac=False)) top = node_path.attach_new_node( sg.cone(origin=core.Vec3(0), direction=core.Vec3.up(), radius=(r[1], 0), polygon=4, length=1.5, smooth=False, capsule=False, origin_offset=0, color=core.Vec4(core.Vec3(0.2), 1), nac=False)) top.set_z(15) # mat = core.Material() # mat.set_emission(core.Vec4(.35, 1.0, 0.52, 0.1)) # mat.set_shininess(5.0) # node_path.set_material(mat) return node_path
def get_buffer(render_node, buff_size=None, clear_color=core.Vec4(0, 0, 0, 1)): buff_size = buff_size or core.ConfigVariableInt('portal-buffer-size', 1024).get_value() if _free_buffers: bobj = _free_buffers.pop() bobj.pipeline.render_node = render_node bobj.cam.reparent_to(render_node) return bobj basic = core.Filename.expand_from('$MAIN_DIR/assets/textures/basic_1.exr') basic = loader.load_texture(basic) buff = base.win.make_texture_buffer('Room Buffer', buff_size, buff_size) buff.set_clear_color(clear_color) buff.set_clear_color_active(True) buff.set_sort(-100) fog = core.Fog("Fog Name") fog.set_color(0, 0, 0) fog.set_exp_density(0.04) render_node.set_fog(fog) tex = buff.get_texture() cam = base.make_camera(buff) cam.reparent_to(render_node) pipeline = simplematcap.init(basic, render_node=render_node, light_dir=core.Vec3(-1, -1, 0.5).normalized(), hueshift=core.Vec3(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0), 20)) return BufferObject(buff, tex, cam, pipeline)
def center_point(self): pos, hpr = self._orient.get_pos(), self._orient.get_hpr() # z value for orientation is y value of draw. z = self._draw.get_pos(self._origin).y self._orient.set_pos_hpr(core.Vec3(0, 0, z), core.Vec3(0)) center_point = self._orient.get_pos(self._world) self._orient.set_pos_hpr(pos, hpr) return center_point
def _draw_triangle(self, position: core.Point3, colour: core.Vec4): debug_segments = core.LineSegs("debug") debug_segments.set_thickness(4) debug_segments.set_color(colour) debug_segments.draw_to(position + core.Vec3(0, 1024, 0)) debug_segments.draw_to(position + core.Vec3(1024, -1024, 0)) debug_segments.draw_to(position + core.Vec3(-1024, -1024, 0)) debug_segments.draw_to(position + core.Vec3(0, 1024, 0)) debug_segments.create(self._debug_geometry_node, dynamic=False)
def __init__(self, vid, point, color=core.Vec4(1), texcoord=core.Vec2(0)): self._vid = vid self._point = point self._color = color self._texcoord = texcoord self._trs = [] self._normal = None self._tangent = core.Vec3(0) self._bitangent = core.Vec3(0)
def camera_update(self, task): '''This function is a task run each frame, it controls the camera movement/rotation/zoom''' #dt is 'delta time' - how much time elapsed since the last time the task ran #we will use it to keep the motion independent from the framerate dt = globalClock.get_dt() #we'll be tracking the mouse #first we need to check if the cursor is in the window if self.mouseWatcherNode.has_mouse(): #let's see where the mouse cursor is now mouse_pos = self.mouseWatcherNode.get_mouse() #let's see how much it moved from last time, or if this is the first frame if self.last_mouse_pos is None: self.last_mouse_pos = p3d.Vec2(mouse_pos) return task.again mouse_delta = mouse_pos - self.last_mouse_pos #and let's remember where it is this frame so we can #check next frame where it was self.last_mouse_pos = p3d.Vec2(mouse_pos) #camera zoom if self.zoom != 0.0: #let's see how far the camera is from the pivot point distance = self.camera.get_distance(self.camera_node) #we don't want it to be too close nor to far away if (distance > self.zoom_limit[0] and self.zoom > 0.0) or \ (distance < self.zoom_limit[1] and self.zoom < 0.0): #move the camera away or closer to the pivot point #we do that by moving the camera relative to itself self.camera.set_y(self.camera, self.zoom * dt * self.camera_zoom_speed) if self.zoom >= 0.0: self.zoom -= dt * self.camera_zoom_damping else: self.zoom += dt * self.camera_zoom_damping else: self.zoom = 0.0 if self.key_down['rotate']: h = self.camera_node.get_h( ) - mouse_delta.x * self.camera_rotation_speed self.camera_node.set_h(h) p = self.camera_gimbal.get_p( ) - mouse_delta.y * self.camera_rotation_speed p = min(max(p, self.camera_p_limit.x), self.camera_p_limit.y) self.camera_gimbal.set_p(p) if self.key_down['relative_move']: pos = p3d.Vec3(mouse_delta.x, 0, mouse_delta.y) pos = self.camera_node.get_pos( self.camera) - pos * self.camera_move_speed self.camera_node.set_pos(self.camera, pos) elif self.key_down['move']: pos = p3d.Vec3(mouse_delta.x, mouse_delta.y, 0) self.camera_node.set_pos(self.camera_node, pos * self.camera_move_speed) return task.again
def fir_tree(avg_height=50, avg_segments=6, avg_radius=1.2, offset=0.4, tex=None): height = random.uniform(offset * avg_height, (1.0 - offset + 1) * avg_height) segments = int(ceil(avg_segments / avg_height * height)) trunk_radius = avg_radius / avg_height * height trunk_color = common.FIR_TRUNK_START trunk_color += common.FIR_TRUNK_DELTA * random.random() bbc = common.FIR_BRANCH_START + common.FIR_BRANCH_DELTA * random.random() branch_colors = [ bbc + common.FIR_BRANCH_DELTA * (random.random() - 0.5) * 0.1 for _ in range(segments) ] node_path = core.NodePath('fir_tree') trunk_node_path = node_path.attach_new_node( sg.cone(origin=core.Vec3(0), direction=core.Vec3.up(), radius=(trunk_radius, 0), polygon=12, length=height, origin_offset=0.05, color=trunk_color, nac=False, name='fir_tree/trunk')) trunk_node_path.set_hpr(random.uniform(0, 360), random.uniform(0, 5), 0) if tex is not None: trunk_node_path.set_texture(tex, 1) seg_height = height * 0.8 / segments seg_start = height * 0.2 for i, bc in enumerate(branch_colors): radius = ( random.uniform((segments - i) * trunk_radius * 0.8, (segments - i) * trunk_radius * 1.0), random.uniform((segments - i - 1) * trunk_radius * 0.6, (segments - i - 1) * trunk_radius * 0.8) if i < segments - 1 else 0, ) br_node_path = node_path.attach_new_node( sg.cone(origin=core.Vec3(0), direction=core.Vec3.up(), radius=radius, polygon=16, length=seg_height, color=bc, nac=False, name=f'fir_tree/branch{i}')) br_node_path.set_z(trunk_node_path, seg_start + seg_height * 0.5 + i * seg_height) br_node_path.set_hpr(random.uniform(0, 360), random.uniform(0, 5), 0) return node_path, trunk_radius
def leaf_tree(avg_height=25, avg_radius=0.8, offset=0.6, tex=None): height = random.uniform(offset * avg_height, (1.0 - offset + 1) * avg_height) trunk_radius = avg_radius / avg_height * height trunk_color = common.LEAF_TRUNK_START trunk_color += common.LEAF_TRUNK_DELTA * random.random() branch_color, branch_delta = random.choice(common.LEAF_BRANCH_COLORS) branch_color2 = branch_color * 0.999 branch_color += common.LEAF_TRUNK_DELTA * random.random() branch_color2 += common.LEAF_TRUNK_DELTA * random.random() node_path = core.NodePath('leaf_tree') trunk_node_path = node_path.attach_new_node( sg.cone(origin=core.Vec3(0), direction=core.Vec3.up(), radius=(trunk_radius, 0), polygon=12, length=height, origin_offset=0.05, color=trunk_color, nac=False, name='leaf_tree/trunk')) trunk_node_path.set_hpr(random.uniform(0, 360), random.uniform(0, 5), 0) if tex is not None: trunk_node_path.set_texture(tex, 1) for i in range(random.randint(1, 3)): bb = core.Vec3( random.uniform(trunk_radius * 4, height / 4), random.uniform(trunk_radius * 4, height / 4), random.uniform(height / 3, height * 0.4), ) br_node_path = node_path.attach_new_node( sg.blob( origin=core.Vec3(0), direction=core.Vec3.up(), bounds=bb, color=branch_color, color2=branch_color2, name='fir_tree/branch', # seed=np.random.randint(0, 2**31, dtype=np.int32), noise_radius=12, nac=False)) br_node_path.set_z(trunk_node_path, height - bb.z * random.random()) br_node_path.set_x(trunk_node_path, bb.x * (random.random() - 0.5)) br_node_path.set_y(trunk_node_path, bb.y * (random.random() - 0.5)) br_node_path.set_hpr(random.uniform(0, 360), random.uniform(0, 90), 0) return node_path, trunk_radius
def __init__(self, collision_handler): gamedata.GameData.__init__(self) self.heightfield = None self.__collision = collision_handler self.terrain = None self.terrain_root = None self.terrain_offset = core.Vec3(0) self.tree_root = self.render.attach_new_node('tree_root') self.devils_tower = None self.__solved_symbols = None self.noise = noise.Noise() self.__woods, self.__bounds, self.ob_coords = self.noise.woods() # print(self.ob_coords) self.setup_terrain() self.place_devils_tower() self.place_trees() self.__setup_solved_symbols() self.__first_obelisk = True self.__tutorial = True self.__tut_np = None self.__nonogram = None self.__puzzle = None self.__ng_last_active = 0 self.__inner_bounds = False self.__outer_bounds = False
def _debug_bunch(self, bunch: WallBunch, visible: bool, depth: int): if self._can_debug(depth): colour = self._debug_colour self._increment_debug_colour() if visible and bunch.other_side_sector is None: start_index = self._clip_range_to_clip_index(bunch.left) end_index = self._clip_range_to_clip_index(bunch.right) self._clip_buffer_colours[start_index:end_index + 1] = [ colour.x, colour.y, colour.z, ] if len(bunch.editor_walls) > 0: origin = bunch.editor_walls[0].origin theta = bunch.editor_walls[0].get_direction_theta() + 180 self._draw_triangle(origin, colour) position = origin + core.Vec3(0, 0, -512) self._make_debug_text(f"Visible: {visible}", position, colour, theta) for editor_wall in bunch.editor_walls: self._debug_wall(editor_wall, 100, colour)
def _transform_to_camera_delta(self, mouse_delta: core.Vec2): scale = self._camera_scale() / moving_clicker.MovingClicker.MOVE_SCALE return core.Vec3( (mouse_delta.x * scale.x) / 2, -(mouse_delta.y * scale.y) / 2, -mouse_delta.y, )
def load_tiles(self, tile_indices: typing.List[int] = None): if tile_indices is None: tile_indices = self._tile_manager.get_all_tiles() if tile_indices == self._tile_indices: return self._tile_indices = tile_indices for frame in self._tile_frames.values(): frame.hide() tile_count = len(tile_indices) row_count = math.ceil(tile_count / 10) self._top = 0.2 for y in range(row_count): self._top -= 0.2 for x in range(10): left = x * 0.2 picnum_index = y * 10 + x if picnum_index >= tile_count: break picnum = tile_indices[picnum_index] frame = self._get_tile_frame(picnum) frame.set_pos(core.Vec3(left, 0, self._top)) frame.show() self._top = min(-1, self._top) frame_size = list(self._frame["canvasSize"]) frame_size[2] = self._top self._frame["canvasSize"] = frame_size
def _callback(texture: core.Texture): if parent_frame.is_empty(): return frame_size = gui.size_inside_square_for_texture(texture, 0.2) if frame_size is None: return tile = DirectGui.DirectButton( parent=parent_frame, frameSize=(0.01, frame_size.x - 0.01, -0.01, -(frame_size.y - 0.01)), frameTexture=texture, relief=DirectGuiGlobals.FLAT, command=self._select_tile, extraArgs=[picnum], ) self._bind_scroll(tile) tile_number = DirectGui.DirectLabel( parent=tile, pos=core.Vec3(0, 0, -constants.TEXT_SIZE), scale=constants.TEXT_SIZE, text=str(picnum), frameColor=(0, 0, 0, 0), text_align=core.TextNode.A_left, text_fg=(1, 1, 1, 0.75), ) self._bind_scroll(tile_number)
def three_rings(): node_path = core.NodePath('three_rings') o1 = obelisk((1.5, 0.8)) o2 = obelisk((1.5, 0.8)) o1.reparent_to(node_path) o2.reparent_to(node_path) o1.set_pos(common.TR_O1_OFFSET) o2.set_pos(common.TR_O2_OFFSET) random.shuffle(common.TR_COLORS) rings = [] symbol_cards = [] for r, h, c in zip(common.TR_RADII, common.TR_HEIGHTS, common.TR_COLORS): rings.append( node_path.attach_new_node( sg.cone(origin=core.Vec3(0), direction=core.Vec3.up(), radius=r, polygon=common.TR_POLYGON, length=h, color=c, nac=False))) symbol_cards.append([]) for i in range(6): r_node = rings[-1].attach_new_node('rot') c = core.CardMaker(f'symbol {len(rings)}/{i}') c.set_frame(core.Vec4(-1, 1, -1, 1)) symbol_cards[-1].append(r_node.attach_new_node(c.generate())) r_node.set_h(i * 60) r_node.set_transparency(core.TransparencyAttrib.M_alpha) r_node.set_alpha_scale(common.TR_SYM_ALPHA) symbol_cards[-1][-1].set_y(r - 0.5) symbol_cards[-1][-1].set_z(h) symbol_cards[-1][-1].set_billboard_axis() return node_path, rings, symbol_cards
def _debug_sector(self, sector: EditorSector, depth: int): if self._can_debug(depth): for editor_wall in sector.walls: self._debug_wall(editor_wall, 4, core.Vec4(0, 1, 0, 0.5)) offset_2d = editor_wall.get_normalized_direction() * 2048 offset = core.Vec3(offset_2d.x, offset_2d.y, 0) + core.Vec3( 0, 0, -256) position = editor_wall.get_centre() - offset position_2 = editor_wall.get_centre() + offset theta = editor_wall.get_direction_theta() + 180 self._debug_wall_projection(editor_wall, theta, position, core.Vec4(1, 0, 0, 1)) self._debug_wall_projection(editor_wall.wall_point_2, theta, position_2, core.Vec4(0, 0, 1, 1))
def stone(xy): node_path = core.NodePath('stone') base = common.STONE_START color = base + common.STONE_DELTA * random.random() color2 = base + common.STONE_DELTA * random.random() bb = core.Vec3(xy, random.uniform(min(xy) * 0.9, min(xy) * 1.1)) br_node_path = node_path.attach_new_node( sg.blob( origin=core.Vec3(0), direction=core.Vec3.up(), bounds=bb, color=color, color2=color2, name='fir_tree/branch', # seed=random.randint(0, 2 ** 32 - 1), noise_radius=200, nac=False)) return br_node_path
def transform_to_camera_delta(self, mouse_delta: core.Vec2) -> core.Vec3: heading = self._builder.get_h() sin_theta = math.sin(math.radians(heading)) cos_theta = math.cos(math.radians(heading)) x_direction = sin_theta * mouse_delta.y + cos_theta * -mouse_delta.x y_direction = cos_theta * mouse_delta.y - sin_theta * -mouse_delta.x return core.Vec3(x_direction, y_direction, -mouse_delta.y)
def rotate_camera(self, delta: core.Vec2): hpr = self._builder.get_hpr() hpr = core.Vec3(hpr.x - delta.x * 90, hpr.y + delta.y * 90, 0) if hpr.y < -90: hpr.y = -90 if hpr.y > 90: hpr.y = 90 self._builder.set_hpr(hpr)
def start(self): #self.loader #self.camera.setPos(0, -28, 6) #self.win.setClearColorActive(True) #self.win.setClearColor(p3dc.VBase4(0, 0.5, 0, 1)) self.testModel = self.addModel(base().loader.loadModel('panda'), 'panda') self.testModel.reparentTo(base().render) # This rotates the actor 180 degrees on heading and 90 degrees on pitch. myInterval4 = self.testModel.hprInterval(1.0, p3dc.Vec3(360, 0, 0)) myInterval4.loop()
def __init__( self, parent: core.NodePath, tile_manager: manager.Manager, edit_mode: edit_mode.EditMode, task_manager: Task.TaskManager, ): self._dialog = DirectGui.DirectFrame(parent=parent, frameSize=(-1.1, 1.1, -0.9, 0.9)) self._dialog.hide() self._tile_manager = tile_manager self._tile_selected: typing.Optional[typing.Callable[[int], None]] = None DirectGui.DirectButton( parent=self._dialog, text="Ok", scale=0.05, pos=core.Vec3(0.81, -0.85), command=self._confirm, ) DirectGui.DirectButton( parent=self._dialog, text="Cancel", scale=0.05, pos=core.Vec3(0.95, -0.85), command=self._hide, ) self._tiles = tile_view.TileView( self._dialog, (-1.05, 1.05, -0.8, 0.88), self._tile_manager, self._select_tile, ) self._tiles.load_tiles() self._task_manager = task_manager self._edit_mode = edit_mode self._selected_picnum: typing.Optional[int] = None
def test_friction(world, scene): ball = scene.find('**/ball') for with_friction in (False, True): # Reset ball, give it a huge negative (CCW) spin about the X axis so # it'll roll in +Y direction if there's any friction ball.node().set_angular_velocity(core.Vec3(-1000, 0, 0)) ball.node().set_linear_velocity(core.Vec3(0)) ball.set_pos(-2, 0, 5) ball.node().friction = 1.0 * with_friction # Simulate until ball crosses Y axis assert simulate_until(world, lambda: ball.get_x() >= 0) if with_friction: # The ball had friction, so should've gone off in the +Y direction assert ball.get_y() > 1 else: # No friction means the Y axis should be unaffected assert abs(ball.get_y()) < 0.1
def test_restitution(world, scene): ball = scene.find('**/ball') scene.find('**/ramp').node().restitution = 1.0 for with_bounce in (False, True): # Reset ball ball.node().set_angular_velocity(core.Vec3(0)) ball.node().set_linear_velocity(core.Vec3(0)) ball.set_pos(-2, 0, 100) ball.node().restitution = 1.0 * with_bounce # Simulate until ball rolls/bounces across Y axis assert simulate_until(world, lambda: ball.get_x() >= 0) if with_bounce: # The ball bounced across, so it should be off the ground a bit assert ball.get_z() > 1.2 else: # The ball rolled, so it should be on the ground assert ball.get_z() < 1.2
def mirror_local(self, axis): tmp_vts = {} tmp_vts.update(self._vts) for v in tmp_vts.values(): pt = core.Vec3(v.point) pt[axis] *= -1 if pt == v.point: continue if v.point in self._pts: self._pts[pt] = self._pts.pop(v.point) v.point = pt self.flip_faces()
def __init__( self, camera_collection: cameras.Cameras, map_to_load: game_map.Map, audio_manager: audio.Manager, seq_manager: seq.Manager, tile_manager: manager.Manager, ): logger.info("Setting up sector editor") self._camera_collection = camera_collection self._scene: core.NodePath = self._camera_collection.scene.attach_new_node( "3d_view") self._tile_manager = tile_manager self._texture_stage = core.TextureStage.get_default() self._last_hit_position = core.Vec3() self._ticks = 0 self._snapper = grid_snapper.GridSnapper() self._clipping_debug: core.NodePath = None self._clipping_enabled = constants.PORTALS_ENABLED self._view_clipping_invalid = True self._undo_stack = undo_stack.UndoStack(self._camera_collection) self._sky_picnum = self._find_sky(map_to_load.sectors) self._sky: sky.Sky = None self._sky_offsets = map_to_load.sky_offsets self._setup_sky_box() path = find_resource("sky_indices.yaml") with open(path, "r") as file: self._sky_indices = yaml.load(file.read(), Loader=yaml.SafeLoader) geometry_factory = sector_geometry.SectorGeometryFactory( self._scene, self._tile_manager) self._sectors = SectorCollection( map_to_load, audio_manager, seq_manager, geometry_factory, self._suggest_sky, self._undo_stack, ) self._last_builder_sector: EditorSector = None self._builder_sector: EditorSector = None self._undo_stack.enable() if not constants.DYNAMIC_GEOMETRY_LOAD: for sector in self._sectors.sectors: sector.show() sector.reset_geometry_if_necessary() sector.hide()
def move(self, move_delta: core.Vec3, snapper: grid_snapper.GridSnapper): new_z = self._start_z + move_delta.z new_z = snapper.snap_to_grid(new_z) if self._part == map_objects.EditorSector.FLOOR_PART: self._sector.move_floor_to(new_z) else: self._sector.move_ceiling_to(new_z) snapped_delta_z = new_z - self._start_z sprite_delta = core.Vec3(0, 0, snapped_delta_z) for sprite_move in self._sprite_moves: sprite_move.sprite.move_to(sprite_move.start_position + sprite_delta)
def _get_mouse_pos(self): mouse = base.mouseWatcherNode.getMouse() pos = self._cef_node.get_relative_point( base.render2d, p3d.Vec3(mouse.get_x(), 0, mouse.get_y()), ) left, right, bottom, top = self._size posx = (pos.x - left) / (right - left) * self._cef_texture.get_x_size() posy = (pos.z - bottom) / (top - bottom) * self._cef_texture.get_y_size() posy = self._cef_texture.get_y_size() - posy return posx, posy
def add_new_sprite(self, position: core.Point3): new_blood_sprite = map_data.sprite.Sprite.new() new_blood_sprite.sprite.position_x = int(position.x) new_blood_sprite.sprite.position_y = int(position.y) new_blood_sprite.sprite.position_z = editor.to_build_height(position.z) new_sprite = self.add_sprite(new_blood_sprite) z_offset = core.Vec3(0, 0, -new_sprite.size.y / 2) new_position = new_sprite.position + z_offset new_sprite.move_to(new_position) self.invalidate_geometry() return new_sprite
def setup(self, origin, direction): """ Setup the rigs' origin and direction Args: origin: direction: """ self._origin.set_pos(0, 0, 0) self._origin.heads_up(core.Vec3(0, 1, 0), core.Vec3(0, 0, 1)) self._orient.set_pos_hpr(core.Vec3(0), core.Vec3(0)) self._orient_offset.set_pos_hpr(core.Vec3(0), core.Vec3(0)) self._draw.set_pos_hpr(core.Vec3(0), core.Vec3(0)) self._origin.look_at(direction) self._origin.set_pos(origin)