From e567cd88ed7095418fabc9abe920a3774ae13edf Mon Sep 17 00:00:00 2001 From: march3 Date: Mon, 20 Nov 2023 14:19:45 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sim_lab/wormhole_sim_02.py | 391 +++++++++++++++++++++ sim_scenes/wormhole_sim.py | 269 +++++++++++--- simulators/ursina/entities/entity_utils.py | 2 +- 3 files changed, 618 insertions(+), 44 deletions(-) create mode 100644 sim_lab/wormhole_sim_02.py diff --git a/sim_lab/wormhole_sim_02.py b/sim_lab/wormhole_sim_02.py new file mode 100644 index 0000000..083bd2a --- /dev/null +++ b/sim_lab/wormhole_sim_02.py @@ -0,0 +1,391 @@ +# -*- coding:utf-8 -*- +# title :虫洞效果模拟 +# description :虫洞效果模拟 +# author :Python超人 +# date :2023-11-19 +# link :https://gitcode.net/pythoncr/ +# python_version :3.9 +# ============================================================================== +from bodies import Sun, Earth +from common import color_utils +from common.image_utils import find_texture +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 +from ursina import time, distance, invoke +from ursina import Vec3 +from bodies import Body +from simulators.ursina.ursina_event import UrsinaEvent +from simulators.ursina.ursina_mesh import create_circle, create_line + + +class WormholeSim: + SIZE_SCALE = 1 + D = AU / 10 * SIZE_SCALE + + 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 * 1e2).set_ignore_gravity(True) + 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.create_universes() + self.bodies = [self.camera_target] + self.universes + + def create_universe(self, idx, position): + universe_body = create_universe_body(f"宇宙{idx}", texture=f'cosmic_pan_{idx + 1}.jpg', # self.textures[idx], + size_scale=self.SIZE_SCALE, + init_position=position, + init_velocity=[0, 0, 0], + ) + return universe_body + + def create_universes(self): + D = self.D + positions = [[D, 0, -D], [D, 0, D], [- D, 0, -D], [- D, 0, D], + [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, 0, -D], [D, 0, D], [- D, -D, D], [- D, 0, -D], [D, D, D], + [D, -D, D], + [- D, -D, -D], + [- D, 0, D], + [D, D, -D], + [- D, D, -D], [- D, D, D], [D, -D, -D] + + ] + + for idx, pos in enumerate(positions): + self.universes.append(self.create_universe(idx, pos)) + + def init_setting(self): + camera.clip_plane_near = 0.00005 + # camera.clip_plane_near = 0.01 + camera.clip_plane_far = 100000000 + # create_sphere_sky(scale=200000) + application.time_scale = 0.001 + # camera.scale = 1000 + # camera.parent = camera_target.planet + # camera.rotation_x = 90 + camera.fov = 100 + + for universe in self.universes: + universe.planet.collider = "sphere" + universe.planet.enabled = False + camera.forward_speed = 0 + + def show_wormhole_portal(self, position): + if not hasattr(camera, "wormhole_portal"): + wormhole_portal = self.create_wormhole_portal(position) + camera.wormhole_portal = wormhole_portal + camera.wormhole_portal.alpha = 0 + camera.wormhole_portal.enabled = True + camera.wormhole_portal.update_fun = "" + + if camera.wormhole_portal.update_fun == "show_update": + return + + def show_update(): + camera.wormhole_portal.look_at(camera) + if camera.wormhole_portal.alpha < 1: + camera.wormhole_portal.alpha += 0.05 + + camera.wormhole_portal.enabled = True + camera.wormhole_portal.position = position + camera.wormhole_portal.update = show_update + camera.wormhole_portal.update_fun = "show_update" + + def hide_wormhole_portal(self): + def hide_update(): + camera.wormhole_portal.alpha -= 0.001 + # camera.wormhole_portal.alpha -= 0.01 + # if camera.wormhole_portal.alpha <= 0: + # camera.wormhole_portal.enabled = False + + + if hasattr(camera, "wormhole_portal"): + camera.wormhole_portal.update_fun = "hide_update" + camera.wormhole_portal.enabled = False + if camera.wormhole_portal.update_fun == "hide_update": + return + pp = self.get_intersection_point(self.last_universe.planet.position, self.last_universe.planet.scale, + camera.position) + if pp is None: + return + camera.wormhole_portal.position = pp + camera.wormhole_portal.look_at(camera) + camera.wormhole_portal.update = hide_update + camera.wormhole_portal.update_fun = "hide_update" + + def create_wormhole_portal(self, position): + portal_circle = create_circle(parent=None, pos=position, scale=2) + # portal_circle.texture = find_texture("fixed_star_glow.png") + portal_circle.texture = find_texture("two_way_foil_circle.png") + + # glow_circle.color = color.white + portal_circle.set_light_off(True) + + def glow_circle_update(): + # glow_circle.enabled = fixed_star.enabled + portal_circle.look_at(camera) + + portal_circle.update = glow_circle_update + return portal_circle + + def get_intersection_point(self, center, r, pt): + """ + 计算线段和球体的交点坐标 + + Args: + x0, y0, z0: 球体的中心坐标 + r: 球体的半径 + x1, y1, z1: 线段的两个端点坐标 + + Returns: + 线段和球体的交点坐标,如果没有交点,则返回 None + """ + import math + x0, y0, z0, x1, y1, z1 = center[0], center[1], center[2], pt[0], pt[1], pt[2] + r = r[0] + # 计算线段的方向向量 + dx = x1 - x0 + dy = y1 - y0 + dz = z1 - z0 + + # 计算线段的长度 + l = math.sqrt(dx ** 2 + dy ** 2 + dz ** 2) + + # 计算球心到线段的距离 + d = math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2 + (z0 - z1) ** 2) + + # 如果球心到线段的距离小于球体的半径,则有交点 + if d < r: + return None + + # 计算线段和球体的交点坐标 + x = x0 + dx * (r ** 2 - d ** 2) / (l ** 2) + y = y0 + dy * (r ** 2 - d ** 2) / (l ** 2) + z = z0 + dz * (r ** 2 - d ** 2) / (l ** 2) + + return Vec3(x, y, z) + + def check_and_create_wormhole_portal(self): + + d = distance(camera, self.target_universe) + center = lerp(camera.position, self.target_universe.planet.position, 0.5) + if d < 21156327: + # direction = self.target_universe.planet.position - camera.position + # tca = direction.dot(self.target_universe.planet.position - camera.position) + # sum(direction ** 2) - tca ** 2 + # line = create_line(from_pos=camera.position, to_pos=self.target_universe.planet.position) + # #line.get_intersection(self.target_universe.planet) + + pp = self.get_intersection_point(self.target_universe.planet.position, self.target_universe.planet.scale, + camera.position) + self.target_universe.planet.alpha = 0.2 + # application.paused = True + print(d, center) + self.show_wormhole_portal(position=pp) + + def universe_reset(self): + self.camera_target.speed = 100 + camera.speed = 100 + 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] + + 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 + self.scale_down(self.last_universe, scale_size=self.SIZE_SCALE * 10) + self.camera_target.go_target_stage = "last_universe" + self.camera_target.go_target_hit = False + self.scale_down(u) + self.camera_target.speed = 2000 + camera.forward_speed = -0.1 + + 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() + + self.hide_wormhole_portal() + # invoke(self.hide_wormhole_portal, delay=0.1) + + 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() + + # self.target_universe.planet.rotation_y = 100 + # self.current_universe.planet.rotation_y = 200 + # self.current_universe.planet.rotation_x = 30 + + # 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: + """ + 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 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) + + self.check_and_create_wormhole_portal() + + if self.camera_target.go_target is not None: + go_target = self.camera_target.go_target.planet + self.camera_target.planet.look_at(go_target) + self.camera_target.speed *= 1.02 + if self.camera_target.speed > 2000: + self.camera_target.speed = 2000 + self.camera_target.planet.position = \ + lerp(self.camera_target.planet.position, go_target.position, + self.camera_target.speed * time.dt) + + if self.camera_target.go_target_stage == "last_universe": + 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 == "target_universe" + self.camera_target.go_target = self.target_universe + self.camera_target.speed = 100 + camera.speed = 1 # 在看上一个宇宙时候,停留一会 + # camera.forward_speed = -0.05 + if camera.forward_speed < 0: + camera.forward_speed += 0.01 + else: + camera.forward_speed = 0 + 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 *= 1.02 + if camera.speed > 5000: + camera.speed = 5000 + + dd = distance(camera.position, self.target_universe.planet.position) + if camera.speed != 0: + 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.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, 0], + # position=[0, self.D, -self.D * 2], + cosmic_bg='', + gravity_works=False, + timer_enabled=True, + show_grid=False, + show_trail=False) + + +if __name__ == '__main__': + """ + + """ + wormhole_sim = WormholeSim() + wormhole_sim.run() diff --git a/sim_scenes/wormhole_sim.py b/sim_scenes/wormhole_sim.py index a254287..c9b91ca 100644 --- a/sim_scenes/wormhole_sim.py +++ b/sim_scenes/wormhole_sim.py @@ -13,10 +13,39 @@ from common.consts import SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH, 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 +from ursina import camera, application, lerp, Vec3 from bodies import Body from simulators.ursina.ursina_event import UrsinaEvent +from dataclasses import dataclass, field + + +@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 = 2000 + camera_target_max_speed: int = 2000 + camera_forward_speed: int = - 0.1 + camera_max_speed: int = 5000 + camera_acc_speed: int = 1.02 + camera_forward_acc_speed: int = 0.01 + size_factor: float = 10 + rotation_x: float = None + rotation_y: float = None + rotation_z: float = None + + +# class WormholeInfoParams: +# def __init__(self): +# self.params = [] +# +# def add(self, param_name): +# +# return self class WormholeSim: @@ -29,18 +58,21 @@ class WormholeSim: # init_position=[0, 0, 0], init_position=[D, 0, -D], init_velocity=[0, 0, 0], - size_scale=self.SIZE_SCALE * 1e2).set_ignore_gravity(True) + size_scale=self.SIZE_SCALE * 1e3).set_ignore_gravity(True) 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.wormhole_infos = {} self.create_universes() self.bodies = [self.camera_target] + self.universes - def create_universe(self, idx, position): - universe_body = create_universe_body(f"宇宙{idx}", texture=f'cosmic_pan_{idx + 1}.jpg', # self.textures[idx], + 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], @@ -50,22 +82,86 @@ class WormholeSim: def create_universes(self): D = self.D - positions = [[D, 0, -D], [D, 0, D], [- D, 0, -D], [- D, 0, D], - [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, 0, -D], [D, 0, D], [- D, -D, D], [- D, 0, -D], [D, D, D], - [D, -D, D], - [- D, -D, -D], - [- D, 0, D], - [D, D, -D], - [- D, D, -D], [- D, D, D], [D, -D, -D] - - ] - - for idx, pos in enumerate(positions): - self.universes.append(self.create_universe(idx, pos)) + # camera_target_init_speed: int = 100 + # camera_init_speed: int = 100 + # camera_target_speed: int = 2000 + # camera_forward_speed: int = - 0.1 + # camera_max_speed: int = 2000 + # camera_acc_speed: int = 1.02 + # camera_forward_acc_speed: int = 0.01 + # size_factor: float = 10 + # rotation_x: float = None + # rotation_y: float = None + # rotation_z: float = None + wormhole_infos = [ + {"position": [D, 0, -D], "rotation_y": -150}, + {"position": [D, 0, D], "rotation_z": 30}, + {"position": [- D, -D, D]}, + {"position": [- D, 0, -D]}, + {"position": [D, D, D]}, + {"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() + ps = {} + import inspect + attributes = inspect.getmembers(WormholeInfo) + for attr in attributes: + if not attr[0].startswith('_'): + pn = attr[0] + if pn not in wormhole_info.keys(): + continue + ps[pn] = wormhole_info[pn] # attr[1].default + # return { + # attr[0]: attr[1].default + # for attr in attributes + # if not attr[0].startswith('_') + # } + 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}") + # camera_target_init_speed: int = wormhole_info.get("camera_target_init_speed", 100) + # camera_init_speed: int = wormhole_info.get("camera_init_speed", 100) + # camera_target_speed: int = wormhole_info.get("camera_target_speed", 2000) + # camera_target_max_speed: int = wormhole_info.get("camera_target_max_speed", 2000) + # camera_forward_speed: int = wormhole_info.get("camera_forward_speed", -0.1) + # camera_max_speed: int = wormhole_info.get("camera_max_speed", 5000) + # camera_acc_speed: int = wormhole_info.get("camera_acc_speed", 1.02) + # camera_forward_acc_speed: int = wormhole_info.get("camera_forward_acc_speed", 0.01) + # size_factor: float = wormhole_info.get("size_factor", 10) + # rotation_x: float = wormhole_info.get("rotation_x", None) + # rotation_y: float = wormhole_info.get("rotation_y", None) + # rotation_z: float = wormhole_info.get("rotation_z", None) + 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) + # self.wormhole_infos[universe] = WormholeInfo(name=name, position=pos, + # camera_target_init_speed=camera_target_init_speed, + # camera_init_speed=camera_init_speed, + # camera_target_speed=camera_target_speed, + # camera_target_max_speed=camera_target_max_speed, + # camera_forward_speed=camera_forward_speed, + # camera_max_speed=camera_max_speed, + # camera_acc_speed=camera_acc_speed, + # camera_forward_acc_speed=camera_forward_acc_speed, + # size_factor=size_factor, + # rotation_x=rotation_x, + # rotation_y=rotation_y, + # rotation_z=rotation_z + # + # ) def init_setting(self): camera.clip_plane_near = 0.00005 @@ -83,9 +179,24 @@ class WormholeSim: universe.planet.enabled = False camera.forward_speed = 0 + def get_wormhole_data(self, data_name, default_val=None, universe=None): + if universe is None: + universe = self.current_universe + wormhole_info = self.wormhole_infos[universe] + if wormhole_info is None: + return default_val + + if not hasattr(wormhole_info, data_name): + return default_val + + val = getattr(wormhole_info, data_name) + if val is None: + return default_val + + return val + def universe_reset(self): - self.camera_target.speed = 100 - camera.speed = 100 + self.current_idx += 1 self.target_idx += 1 if self.current_idx > len(self.universes) - 1: @@ -101,6 +212,20 @@ class WormholeSim: 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", 100) + camera.speed = self.get_wormhole_data("camera_init_speed", 100) + if self.last_universe is None: self.camera_target.go_target = self.target_universe self.camera_target.go_target_stage = "target_universe" @@ -108,12 +233,15 @@ class WormholeSim: else: self.camera_target.go_target = self.last_universe self.last_universe.planet.enabled = True - self.scale_down(self.last_universe, scale_size=self.SIZE_SCALE * 10) + + size_factor = self.get_wormhole_data("size_factor", 10, 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 = 2000 - camera.forward_speed = -0.1 + self.camera_target.speed = self.get_wormhole_data("camera_target_speed", 2000) + camera.forward_speed = self.get_wormhole_data("camera_forward_speed", -0.1) self.scale_up(self.current_universe) # self.scale_down(self.target_universe) @@ -148,7 +276,7 @@ class WormholeSim: # camera_look_at(self.camera_target) self.camera_target.planet.collider = "sphere" - self.camera_target.planet.enabled = False + # self.camera_target.planet.enabled = False camera.collider = "sphere" camera.current_universe = self.current_universe camera_look_at(self.camera_target, rotation_z=0) @@ -190,29 +318,84 @@ class WormholeSim: # 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", 5000) + camera_acc_speed = self.get_wormhole_data("camera_acc_speed", 1.02) + camera_target_max_speed = self.get_wormhole_data("camera_target_max_speed", 2000) + if self.camera_target.go_target is not None: go_target = self.camera_target.go_target.planet - self.camera_target.planet.look_at(go_target) - self.camera_target.speed *= 1.02 - if self.camera_target.speed > 2000: - self.camera_target.speed = 2000 - self.camera_target.planet.position = \ - lerp(self.camera_target.planet.position, go_target.position, - self.camera_target.speed * time.dt) + if self.camera_target.go_target_stage == "around_universe": + around_max_count: int = 300 + around_max_speed: int = -200 + around_direction: str = "right" + around_acc_speed: int = -2 + around_target = camera + around_target = go_target + + 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) > 100: + self.camera_target.around_speed -= around_acc_speed * 10 + 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", 100) + 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 camera.forward_speed < 0: + camera_forward_acc_speed = self.get_wormhole_data("camera_forward_acc_speed", 0.01) + camera.forward_speed += camera_forward_acc_speed + else: + camera.forward_speed = 0 + + 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": 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 == "target_universe" + self.camera_target.go_target_stage = "around_universe" self.camera_target.go_target = self.target_universe - self.camera_target.speed = 100 + self.camera_target.speed = self.get_wormhole_data("camera_init_speed", 100) camera.speed = 1 # 在看上一个宇宙时候,停留一会 - # camera.forward_speed = -0.05 - if camera.forward_speed < 0: - camera.forward_speed += 0.01 - else: - camera.forward_speed = 0 + # # camera.forward_speed = -0.05 + # if camera.forward_speed < 0: + # camera_forward_acc_speed = self.get_wormhole_data("camera_forward_acc_speed", 0.01) + # camera.forward_speed += camera_forward_acc_speed + # else: + # camera.forward_speed = 0 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 @@ -221,9 +404,9 @@ class WormholeSim: # self.camera_target.planet.position += self.camera_target.planet.forward*100 # print(self.camera_target.planet.position) - camera.speed *= 1.02 - if camera.speed > 5000: - camera.speed = 5000 + camera.speed *= camera_acc_speed + if camera.speed > camera_max_speed: + camera.speed = camera_max_speed dd = distance(camera.position, self.target_universe.planet.position) if camera.speed != 0: diff --git a/simulators/ursina/entities/entity_utils.py b/simulators/ursina/entities/entity_utils.py index 81e042f..e8d170e 100644 --- a/simulators/ursina/entities/entity_utils.py +++ b/simulators/ursina/entities/entity_utils.py @@ -372,7 +372,7 @@ def create_fixed_star_lights(fixed_star): glow_circle.set_light_off(True) def glow_circle_update(): - # from ursina import camera + glow_circle.enabled = fixed_star.enabled glow_circle.look_at(camera) glow_circle.update = glow_circle_update -- GitLab