diff --git a/sim_lab/halley_comet_research_calc.py b/sim_lab/halley_comet_research_calc.py index c699c8d41a5601b69c2df267f7ad3eadb47faa49..3505edf2eba63dd0cc978ab633fe57d80fc35fbe 100644 --- a/sim_lab/halley_comet_research_calc.py +++ b/sim_lab/halley_comet_research_calc.py @@ -136,8 +136,8 @@ def calc_simulator(params, factor=1): def before_evolve(dt, context: CalcContext): sim.start_time = conv_to_astropy_time(params.start_time) - # td = TimeData(sim.total_times * dt, BodyTimer.MIN_UNIT_SECONDS) - time_data = TimeData(sim.total_times * dt, BodyTimer.MIN_UNIT_SECONDS) + # td = TimeData(sim.total_times * dt, BodyTimer.MIN_UNIT_SECONDS, dt) + time_data = TimeData(sim.total_times * dt, BodyTimer.MIN_UNIT_SECONDS, dt) sim.total_times += 1 t = sim.start_time + time_data.total_days @@ -157,7 +157,7 @@ def calc_simulator(params, factor=1): d_sun = calculate_distance(sim.halley_comet.position, sim.sun.position) d_earth = calculate_distance(sim.halley_comet.position, sim.earth.position) time_data = context.get_param("time_data") - # td = TimeData(sim.total_times * dt * UrsinaSimulator.INTERVAL_FATOR, BodyTimer.MIN_UNIT_SECONDS) + # td = TimeData(sim.total_times * dt * UrsinaSimulator.INTERVAL_FATOR, BodyTimer.MIN_UNIT_SECONDS, dt) # sim.set_bodies_position(td) diff --git a/sim_scenes/featured/earth_3d.py b/sim_scenes/featured/earth_3d.py index 68aa9651e86810b3de847f6f9b362d98017313fd..396793cab020afdb27ae90126cfe5247c9295fd7 100644 --- a/sim_scenes/featured/earth_3d.py +++ b/sim_scenes/featured/earth_3d.py @@ -43,7 +43,7 @@ if __name__ == '__main__': def on_ready(): # 运行前触发 - create_sphere_sky(scale=2000) + sky = create_sphere_sky(scale=10000, rotation_y=150) def on_timer_changed(time_data): @@ -52,6 +52,13 @@ if __name__ == '__main__': # 地球转了一圈(360)就停止,370是留些余量 if abs(earth.planet.rotation_y) > 365: exit(0) + # from ursina import camera, Vec3, time + # camera.parent.position += Vec3(0.0000001 * time_data.dt, 0, -0.0000003 * time_data.dt) + # Camera3d.look_to(earth.planet) + # camera.parent.look_at(earth.planet) + # # camera.rotation_x = 0 + # # camera.rotation_y = 0 + # camera.rotation_z = 0 UniverseSimScenes.set_window_size((1920, 1079), False) @@ -63,8 +70,8 @@ if __name__ == '__main__': # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(bodies, - # SECONDS_PER_HOUR / 2, - SECONDS_PER_HOUR, + SECONDS_PER_HOUR / 5, + # SECONDS_PER_HOUR, position=(1.45 * earth.radius, 0, -30000), cosmic_bg="", # 无背景(黑色) show_grid=False, # 不显示网格 diff --git a/sim_scenes/featured/wormhole_sim.py b/sim_scenes/featured/wormhole_sim.py new file mode 100644 index 0000000000000000000000000000000000000000..cf511be25e5e4d520632ce299ad466505def7ca8 --- /dev/null +++ b/sim_scenes/featured/wormhole_sim.py @@ -0,0 +1,500 @@ +# -*- coding:utf-8 -*- +# title :虫洞效果模拟 +# description :虫洞效果模拟 +# author :Python超人 +# date :2023-11-19 +# link :https://gitcode.net/pythoncr/ +# python_version :3.9 +# ============================================================================== +import random + +from bodies import Sun, Earth, FixedStar +from sim_scenes.universe_sim_scenes import UniverseSimScenes +from simulators.ursina.entities.entity_utils import create_ambient_light +from bodies.universe_body import create_universe_body +from common.consts import SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU +from objs import Obj, SpaceShip, StarWarsSpeeder, ScifiGunship, SciFiBomber, CoreValagaClas +from sim_scenes.func import mayavi_run, mpl_run, ursina_run, camera_look_at, two_bodies_colliding, camera_move_control, \ + get_run_speed_factor, create_text_panel +from ursina import camera, application, lerp, Vec3 + +from bodies import Body +from simulators.ursina.ursina_event import UrsinaEvent +from dataclasses import dataclass, field +import inspect + + +@dataclass(order=True) +class WormholeInfo: + # entity: object + name: str = field(default='') + position: list[float] = field(default_factory=[0, 0, 0]) + camera_target_init_speed: int = 100 + camera_init_speed: int = 100 + camera_target_speed: int = 1200 + camera_target_max_speed: int = 1500 + camera_forward_speed: int = - 0.1 + camera_max_speed: int = 1500 + camera_acc_speed: int = 1.02 + camera_forward_acc_speed: int = 0.01 + size_factor: float = 16 + rotation_x: float = None + rotation_y: float = None + rotation_z: float = None + around_max_count: int = 400 + around_max_speed: int = -100 + around_min_speed: int = 100 + around_direction: str = "right" + around_acc_speed: int = -1.5 + + +class WormholeSim(UniverseSimScenes): + SIZE_SCALE = 1 + D = AU / 10 * SIZE_SCALE + + def create_universes(self): + D = self.D + # camera_target_init_speed: int = 100 + # camera_init_speed: int = 100 + # camera_target_speed: int = 1200 + # camera_target_max_speed: int = 1500 + # camera_forward_speed: int = - 0.1 + # camera_max_speed: int = 1500 + # camera_acc_speed: int = 1.02 + # camera_forward_acc_speed: int = 0.01 + # size_factor: float = 16 + # rotation_x: float = None + # rotation_y: float = None + # rotation_z: float = None + # around_max_count: int = 400 + # around_max_speed: int = -100 + # around_min_speed: int = 100 + # around_direction: str = "right" + # around_acc_speed: int = -1.5 + + wormhole_infos = [ + {"name": "我们宇宙", "position": [D, 0, -D], "rotation_y": 100, "around_direction": "down", + "camera_forward_speed": 0, "around_max_count": 400}, + {"name": "粉色宇宙", "position": [D, 0, D], "rotation_z": 0, "around_acc_speed": -2, + "around_min_speed": 150, "camera_forward_speed": -0.2, "around_max_count": 700}, + {"name": "蓝天宇宙", "position": [- D, -D, D], "around_direction": "left", "around_max_count": 600}, + {"name": "金色宇宙", "position": [- D, 0, -D], "around_max_count": 600}, + {"name": "深红宇宙", "position": [-D, D, D], "around_max_count": 800}, + # {"position": [D, -D, D]}, + # {"position": [- D, -D, -D]}, + # {"position": [- D, 0, D]}, + # {"position": [D, D, -D]}, + # {"position": [- D, D, -D]}, + # {"position": [- D, D, D]}, + # {"position": [D, -D, -D]} + ] + + def build_wormhole_info_param(wormhole_info): + # ps = WormholeInfoParams() + if self.wormholeinfo_default_vals is None: + self.wormholeinfo_default_vals = {} + init_wormholeinfo_default_vals = True + else: + init_wormholeinfo_default_vals = False + + ps = {} + attributes = inspect.getmembers(WormholeInfo) + for attr in attributes: + if not attr[0].startswith('_'): + pn = attr[0] + if init_wormholeinfo_default_vals: + self.wormholeinfo_default_vals[pn] = attr[1] + if pn not in wormhole_info.keys(): + continue + ps[pn] = wormhole_info[pn] # attr[1].default + + return ps + + for idx, wormhole_info in enumerate(wormhole_infos): + pos = wormhole_info.get("position", [0, 0, 0]) + name = wormhole_info.get("name", f"宇宙{idx}") + ps1 = build_wormhole_info_param(wormhole_info) + ps1["position"] = pos + ps1["name"] = name + universe = self.create_universe(name, idx, pos) + self.universes.append(universe) + self.wormhole_infos[universe] = WormholeInfo(**ps1) + + def __init__(self): + D = self.D + self.camera_target = CoreValagaClas(name="摄像机镜头", mass=1e30, color=(111, 140, 255), + # init_position=[0, 0, 0], + init_position=[D, 0, -D], + init_velocity=[0, 0, 0], + size_scale=self.SIZE_SCALE * 1e3).set_ignore_gravity(True) + self.wormholeinfo_default_vals = None + self.camera_target.go_target = None + self.camera_target.go_target_stage = None + self.last_universe = None + self.current_universe = None + self.target_universe = None + self.universes = [] + self.fixed_stars = [] + self.wormhole_infos = {} + + self.create_universes() + self.create_fixed_stars() + self.bodies = [self.camera_target] + self.universes + self.fixed_stars + + def create_universe(self, name, idx, position): + if name is None: + name = f"宇宙{idx}" + universe_body = create_universe_body(name, texture=f'cosmic_pan_{idx + 1}.jpg', # self.textures[idx], + size_scale=self.SIZE_SCALE, + init_position=position, + init_velocity=[0, 0, 0], + ) + universe_body.set_light_disable(True) + return universe_body + + def fixed_stars_D(self): + r = random.random() + D = self.D * (2 + r) + return D + + def create_fixed_stars(self): + D = self.fixed_stars_D + positions = [[D(), D(), D()], [D(), D(), -D()], [D(), -D(), D()], + [D(), -D(), -D()], [-D(), D(), D()], [-D(), D(), -D()], + [-D(), -D(), D()], [-D(), -D(), -D()]] + + # positions = [[D, D, D], [D, D, -D], [D, -D, D], [D, 0, D], [D, 0, - D], [D, 0, D], + # [D, -D, -D], [-D, D, D], [-D, D, -D], [0, -D, -D], [0, D, D], [0, D, -D], + # [-D, -D, D], [-D, -D, -D], [-D, -D, 0], [-D, -D, 0]] + + for position in positions: + fixed_star = FixedStar(color=(200, 200, 200), size_scale=0.5, init_position=position) + fixed_star.glows = (0, 1.1, 1.08) + self.fixed_stars.append(fixed_star) + + def init_setting(self): + camera.clip_plane_near = 0.6 + # camera.clip_plane_near = 0.01 + camera.clip_plane_far = 10000000 + # create_sphere_sky(scale=200000) + application.time_scale = 0.001 + # camera.scale = 1000 + # camera.parent = camera_target.planet + # camera.rotation_x = 90 + camera.fov = 120 + + for universe in self.universes: + universe.planet.collider = "sphere" + universe.planet.enabled = False + camera.forward_speed = 0 + + def get_wormhole_data(self, data_name, default_val=None, universe=None): + def ret_value(): + if default_val is None: + if data_name in self.wormholeinfo_default_vals.keys(): + return self.wormholeinfo_default_vals[data_name] + + return default_val + + if universe is None: + universe = self.current_universe + wormhole_info = self.wormhole_infos[universe] + if wormhole_info is None: + return ret_value() + + if not hasattr(wormhole_info, data_name): + return ret_value() + + val = getattr(wormhole_info, data_name) + if val is None: + return ret_value() + + return val + + def universe_reset(self): + + self.current_idx += 1 + self.target_idx += 1 + if self.current_idx > len(self.universes) - 1: + self.current_idx = 0 + if self.target_idx > len(self.universes) - 1: + self.target_idx = 0 + + for u in self.universes: + self.scale_down(u) + u.planet.enabled = False + + self.last_universe = self.current_universe + self.current_universe = self.universes[self.current_idx] + self.target_universe = self.universes[self.target_idx] + + rotation_x: float = self.get_wormhole_data("rotation_x") + rotation_y: float = self.get_wormhole_data("rotation_y") + rotation_z: float = self.get_wormhole_data("rotation_z") + + if rotation_x is not None: + self.current_universe.planet.rotation_x = rotation_x + if rotation_y is not None: + self.current_universe.planet.rotation_y = rotation_y + if rotation_z is not None: + self.current_universe.planet.rotation_z = rotation_z + + self.camera_target.speed = self.get_wormhole_data("camera_target_init_speed") + camera.speed = self.get_wormhole_data("camera_init_speed") + + if self.last_universe is None: + self.camera_target.go_target = self.target_universe + self.camera_target.go_target_stage = "target_universe" + self.camera_target.go_target_hit = False + else: + self.camera_target.go_target = self.last_universe + self.last_universe.planet.enabled = True + + size_factor = self.get_wormhole_data("size_factor", universe=self.last_universe) + + self.scale_down(self.last_universe, scale_size=self.SIZE_SCALE * size_factor) + self.camera_target.go_target_stage = "last_universe" + self.camera_target.go_target_hit = False + self.scale_down(u) + self.camera_target.speed = self.get_wormhole_data("camera_target_speed") + camera.forward_speed = self.get_wormhole_data("camera_forward_speed") + + self.scale_up(self.current_universe) + # self.scale_down(self.target_universe) + + self.current_universe.planet.enabled = True + # self.current_universe.planet.set_light_off() + self.target_universe.planet.enabled = True + # self.target_universe.planet.set_light_off() + + def body_update_reset(self): + # for b in self.bodies: + # b.planet.update = lambda: None + self.camera_target.planet.update = lambda: None + + def on_ready(self): + """ + 事件绑定后,模拟器运行前会触发 + @return: + """ + self.init_setting() + # create_ambient_light(parent=camera) + + self.current_idx = -1 + self.target_idx = 0 + self.current_universe = None + self.body_update_reset() + self.universe_reset() + + # camera_look_at(self.camera_target) + self.camera_target.planet.collider = "sphere" + self.camera_target.planet.enabled = False + camera.collider = "sphere" + camera.current_universe = self.current_universe + camera_look_at(self.camera_target, rotation_z=0) + + # self.text_panel = create_text_panel(font="fonts/DroidSansFallback.ttf", font_scale=1.3) + + def update_text_panel(self): + """ + 更新文字信息面板 + @param d_sun: + @return: + """ + if not hasattr(self, "text_panel"): + return + + panel_text = "虫洞穿越宇宙:\n\n当前宇宙:%s " % self.current_universe.name + panel_text += "\n\n下站宇宙:%s" % self.target_universe.name + if self.last_universe is not None: + panel_text += "\n\n上站宇宙:%s " % self.last_universe.name + + self.text_panel.text = panel_text + + def scale_up(self, obj): + if obj is None: + return + obj.planet.init_scale = self.SIZE_SCALE * 100 + + def scale_down(self, obj, scale_size=None): + if obj is None: + return + if scale_size is None: + scale_size = self.SIZE_SCALE + obj.planet.init_scale = scale_size + + def around_universe(self, around_target): + around_max_count = self.get_wormhole_data("around_max_count") + around_max_speed = self.get_wormhole_data("around_max_speed") + around_min_speed = self.get_wormhole_data("around_min_speed") + around_direction = self.get_wormhole_data("around_direction") + around_acc_speed = self.get_wormhole_data("around_acc_speed") + # around_target = camera + + self.camera_target.planet.look_at(around_target) + + # print(self.camera_target.planet.rotation_x,self.camera_target.planet.rotation_y,self.camera_target.planet.rotation_z) + planet_direction = getattr(self.camera_target.planet, around_direction) + + if not hasattr(self.camera_target, "around_speed"): + self.camera_target.around_speed = 0 + if not hasattr(self.camera_target, "around_count"): + self.camera_target.around_count = 0 + + if self.camera_target.around_count > around_max_count: + if hasattr(self.camera_target, "around_speed") and \ + abs(self.camera_target.around_speed) > abs(around_min_speed): + self.camera_target.around_speed -= around_acc_speed + else: + # delattr(self.camera_target, "around_speed") + delattr(self.camera_target, "around_count") + self.camera_target.go_target_stage = "last_universe" + self.camera_target.speed = self.get_wormhole_data("camera_init_speed") + else: + self.camera_target.around_speed += around_acc_speed + + if hasattr(self.camera_target, "around_speed"): + if abs(self.camera_target.around_speed) > abs(around_max_speed): + self.camera_target.around_speed = around_max_speed + + self.camera_target.planet.position += planet_direction * self.camera_target.around_speed + + print("around_speed", self.camera_target.around_speed) + + if hasattr(self.camera_target, "around_count"): + self.camera_target.around_count += 1 + + # camera.forward_speed = -0.05 + if abs(camera.forward_speed) > 0.01: + camera_forward_acc_speed = self.get_wormhole_data("camera_forward_acc_speed") + camera.forward_speed += camera_forward_acc_speed + # else: + # camera.forward_speed = 0 + + def go_last_universe(self, go_target): + if self.camera_target.planet.intersects(go_target).hit: + if not self.camera_target.go_target_hit: + self.camera_target.go_target_hit = True + self.camera_target.go_target_stage = "around_universe" + self.camera_target.go_target = self.target_universe + self.camera_target.speed = self.get_wormhole_data("camera_init_speed") + camera.speed = 1 # 在看上一个宇宙时候,停留一会 + # # camera.forward_speed = -0.05 + # if camera.forward_speed < 0: + # camera_forward_acc_speed = self.get_wormhole_data("camera_forward_acc_speed") + # camera.forward_speed += camera_forward_acc_speed + # else: + # camera.forward_speed = 0 + if hasattr(self.camera_target, "around_speed"): + if abs(self.camera_target.around_speed) > abs(10): + around_acc_speed = self.get_wormhole_data("around_acc_speed") + around_direction = self.get_wormhole_data("around_direction") + planet_direction = getattr(self.camera_target.planet, around_direction) + + self.camera_target.around_speed -= around_acc_speed + self.camera_target.planet.position += planet_direction * self.camera_target.around_speed + else: + delattr(self.camera_target, "around_speed") + + def on_timer_changed(self, time_data): + self.target_universe.planet.rotation_y -= 0.5 + if self.last_universe is not None: + self.last_universe.planet.rotation_y += 0.3 + camera_look_at(self.camera_target, rotation_z=0) + # camera.rotation_x -= 2 + + # self.camera_target.planet.look_at(self.target_universe.planet) + # self.camera_move(time_data) + from ursina import time, distance + + camera_max_speed = self.get_wormhole_data("camera_max_speed") + camera_acc_speed = self.get_wormhole_data("camera_acc_speed") + camera_target_max_speed = self.get_wormhole_data("camera_target_max_speed", ) + + if self.camera_target.go_target is not None: + go_target = self.camera_target.go_target.planet + if self.camera_target.go_target_stage == "around_universe": + # 摄像机镜头环绕目标宇运动(摄像机镜头暂时不去目标) + self.around_universe(go_target) + else: + # 摄像机镜头看向目标宇宙,并逐渐靠近目标 + self.camera_target.planet.look_at(go_target) + self.camera_target.planet.position = \ + lerp(self.camera_target.planet.position, go_target.position, + self.camera_target.speed * time.dt) + + # 摄像机镜头加速度计算(摄像机镜头圆滑效果),并对摄像机镜头移动速度进行限制 + self.camera_target.speed *= camera_acc_speed + if self.camera_target.speed > camera_target_max_speed: + self.camera_target.speed = camera_target_max_speed + + if self.camera_target.go_target_stage == "last_universe": + # 进入新的宇宙后,摄像机回看上一个宇宙的镜头 + self.go_last_universe(go_target) + + elif self.camera_target.go_target_stage == "target_universe": + # 摄像机镜头去往新的宇宙进行中 + if self.camera_target.planet.intersects(go_target).hit and not self.camera_target.go_target_hit: + # 摄像机镜头达到新的目标宇宙后,摄像机就不后退了 + self.camera_target.go_target_hit = True + camera.forward_speed = 0 + # camera.speed = 3000 # TODO:这个不能反复执行 + + # self.camera_target.planet.position += self.camera_target.planet.forward*100 + # print(self.camera_target.planet.position) + # 摄像机加速度计算(摄像机圆滑效果) + camera.speed *= camera_acc_speed + if camera.speed > camera_max_speed: + camera.speed = camera_max_speed + + if camera.speed != 0: + dd = distance(camera.position, self.target_universe.planet.position) + camera.position = lerp(camera.position, self.target_universe.planet.position, camera.speed * time.dt / dd) + if camera.forward_speed != 0: + camera.position += camera.forward * camera.forward_speed + + # if self.camera_target.planet.intersects(self.target_universe.planet).hit: + if camera.intersects(self.target_universe.planet).hit: + self.universe_reset() + + self.update_text_panel() + + def build_events(self): + # 订阅事件后,上面2个函数功能才会起作用 + # 运行中,每时每刻都会触发 on_timer_changed + UrsinaEvent.on_timer_changed_subscription(wormhole_sim.on_timer_changed) + # 运行前会触发 on_ready + UrsinaEvent.on_ready_subscription(wormhole_sim.on_ready) + + def run(self): + + self.set_window_size((1920, 1079), False) + + self.build_events() + # 使用 ursina 查看的运行效果 + # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 + # position = 左-右+、上+下-、前+后- + ursina_run(self.bodies, SECONDS_PER_DAY / 24, + # position=(0, AU / 1200, -1.003 * AU), + # position=[-AU/100, 0, 0], + # position=[0, 0, -AU / 10], + # position=[0, 0, ], + position=[0, self.D, -self.D * 2], + cosmic_bg='', + gravity_works=False, + # bg_music='sounds/no_glory.mp3', + timer_enabled=True, + video_recoder=True, + show_exit_button=False, + show_grid=False, + show_camera_info=False, + show_control_info=False, + show_trail=False) + + +if __name__ == '__main__': + """ + + """ + wormhole_sim = WormholeSim() + wormhole_sim.run() diff --git a/sim_scenes/func.py b/sim_scenes/func.py index 3d99ff5b822489582f2428aca54ab2634d8e05f0..bb0cf4a639045fa92ce5b9db0831f2de87893228 100644 --- a/sim_scenes/func.py +++ b/sim_scenes/func.py @@ -367,7 +367,7 @@ def create_light_ship(size_scale, init_position, speed=LIGHT_SPEED): init_velocity=[0, 0, speed]).set_light_disable(True) -def create_3d_card(left=-.885, top=0.495, width=0.02, height=0.02): +def create_3d_card(left=-.885, top=0.495, width=0.01, height=0.01): # 创建一个 Panel 组件 from ursina import Text, Panel, color, camera, Vec3 from simulators.ursina.ursina_config import UrsinaConfig @@ -707,13 +707,19 @@ def speed_smooth_adjust_test(): plt.show() -def create_sphere_sky(texture="bg_pan.jpg", scale=8000): +def create_sphere_sky(texture="bg_pan.jpg", scale=8000, rotation_x=None, rotation_y=None, rotation_z=None): from common.image_utils import find_texture from simulators.ursina.entities.sphere_sky import SphereSky sky_texture = find_texture(texture, None) if sky_texture is not None: sky = SphereSky(texture=sky_texture) sky.scale = scale + if rotation_x is not None: + sky.rotation_x = rotation_x + if rotation_y is not None: + sky.rotation_y = rotation_y + if rotation_z is not None: + sky.rotation_z = rotation_z return sky else: print(f'`textures`目录下没有找到图片`{texture}`,请访问如下链接下载,下载后,将图片放在`textures`目录下') diff --git a/simulators/ursina/entities/body_timer.py b/simulators/ursina/entities/body_timer.py index f0200d94ee84b8dae62d89826dc22398fe48d1f1..a26b76c87431eec695088f06b0deaa8113be60b6 100644 --- a/simulators/ursina/entities/body_timer.py +++ b/simulators/ursina/entities/body_timer.py @@ -17,7 +17,7 @@ from simulators.ursina.ursina_event import UrsinaEvent class TimeData: - def __init__(self, seconds, min_unit): + def __init__(self, seconds, min_unit, dt): from ursina import time if not hasattr(TimeData, "app_start_time"): setattr(TimeData, "app_start_time", time.time()) @@ -32,6 +32,7 @@ class TimeData: days, hours = divmod(hours, 24) years = days // 365 days = days % 365 + self.dt = dt self.years = int(years) self.days = int(days) @@ -196,7 +197,7 @@ class BodyTimer(Singleton): # time_text = f'{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}' # print(self.text) - UrsinaEvent.on_timer_changed(TimeData(seconds, self.min_unit)) + UrsinaEvent.on_timer_changed(TimeData(seconds, self.min_unit, dt)) def ignore_gravity(self, body): return True diff --git a/simulators/ursina/entities/camera3d.py b/simulators/ursina/entities/camera3d.py index 1a5899954a8980dfea4e41e9f8b079b65be5e713..51ef2666ebe787a3f8399e2bc30e9490cf4f8a25 100644 --- a/simulators/ursina/entities/camera3d.py +++ b/simulators/ursina/entities/camera3d.py @@ -37,15 +37,21 @@ class Camera3d(Entity): def switch_position(self): if self.camera_pos == "right": # 摄像机右眼 - self.x -= 2 * self.eye_distance + # self.x -= 2 * self.eye_distance + self.position += self.left * 2 * self.eye_distance self.camera_pos = "left" elif self.camera_pos == "left": # 摄像机左眼 - self.x += 2 * self.eye_distance + # self.x += 2 * self.eye_distance + self.position += self.right * 2 * self.eye_distance self.camera_pos = "right" def update(self): pass + @staticmethod + def look_to(target, axis='forward'): + Camera3d.o.camera3d.look_at(target, axis) + @staticmethod def init(eye_distance=None, init_pos=None): Camera3d.is_ready = True