From dbb7ae8fd6147509be9e102184c7f7ca2156efd7 Mon Sep 17 00:00:00 2001 From: march3 Date: Fri, 10 Mar 2023 14:46:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=AA=E9=98=B3=E7=B3=BB=E4=B8=89=E4=BD=93?= =?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 --- simulators/ursina_simulator.py | 89 +------------- simulators/views/ursina_view.py | 200 ++------------------------------ 2 files changed, 14 insertions(+), 275 deletions(-) diff --git a/simulators/ursina_simulator.py b/simulators/ursina_simulator.py index 6f386f2..5801eb7 100644 --- a/simulators/ursina_simulator.py +++ b/simulators/ursina_simulator.py @@ -12,94 +12,12 @@ from ursina.prefabs.first_person_controller import FirstPersonController from simulators.views.ursina_view import UrsinaView, UrsinaPlayer -# # ------------------------------------------------------------------------------- -# app = Ursina() -# # window.fullscreen = True -# window.color = color.black -# -# planets = [] -# -# -# class Planet(Entity): -# def __init__(self, _type, pos, texture, scale=2): -# self.angle = rd.uniform(0.0005, 0.01) -# self.fastMode = 0 -# self.rotation = (rd.randint(0, 360) for i in range(3)) -# self.rotspeed = rd.uniform(0.25, 1.5) -# self.rotMode = rd.choice(["x", "y", "z"]) -# self._type = _type -# # texture = eval(f"{_type}_texture") -# texture = load_texture(texture) -# super().__init__(model="sphere", -# scale=scale, -# texture=texture, -# color=color.white, -# position=pos) -# -# def turn(self, angle): -# # if self._type != "sun": -# # if self.fastMode: -# # angle *= 200 -# # self.x = self.x * cos(radians(angle)) - self.y * sin(radians(angle)) -# # self.y = self.x * sin(radians(angle)) + self.y * cos(radians(angle)) -# exec(f"self.rotation_{self.rotMode}+=self.rotspeed") -# # -# def input(self, key): -# if key == "enter": -# self.fastMode = 1 - self.fastMode -# -# -# -# -# -# def update(): -# global planets, player -# for planet in planets: -# planet.turn(planet.angle) -# player._update() -# -# # os.chdir("../") -# -# -# # sun_texture = load_texture(texture_root + "sun.png") -# # mercury_texture = load_texture(texture_root + "mercury.png") -# # venus_texture = load_texture(texture_root + "venus.png") -# # earth_texture = load_texture(texture_root + "earth.png") -# # mars_texture = load_texture(texture_root + "mars.png") -# # jupiter_texture = load_texture(texture_root + "jupiter.png") -# # saturn_texture = load_texture(texture_root + "saturn.png") -# # uranus_texture = load_texture(texture_root + "uranus.png") -# # neptune_texture = load_texture(texture_root + "neptune.png") -# -# texture_root = "../textures/" -# ps = ["sun", "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", "neptune"] -# cp = [200, 15, 35, 42, 20, 160, 145, 90, 80] # 大小缩放 -# x, y, z = 0, 0, 0 -# for i, p in enumerate(ps): -# # _type, pos, texture, scale=2 -# newPlanet = Planet(p, (x, y, z),texture_root+f"{p}.png", cp[i]) -# planets.append(newPlanet) -# x += cp[i] * 10 -# -# player = Player(planets) -# -# if __name__ == '__main__': -# # os.chdir("../") -# # sun_texture = os.path.join(texture_root, "sun.png") -# # print(os.path.exists(sun_texture)) -# app.run() -# -# # --------------------------------------------------------------------------- - - from simulators.simulator import Simulator from common.system import System import time import datetime from ursina import EditorCamera, PointLight, SpotLight, AmbientLight -player = None - class UrsinaSimulator(Simulator): def __init__(self, bodies_sys: System): @@ -134,6 +52,11 @@ class UrsinaSimulator(Simulator): super().evolve(self.evolve_dt) def cosmic_background(self, texture='../textures/cosmic1.jpg'): + """ + 加入宇宙背景 + :param texture: + :return: + """ # Add skybox from ursina import Sky Sky(texture=texture) @@ -207,7 +130,7 @@ if __name__ == '__main__': Earth(init_position=[1.12 * AU, 0, 0], init_velocity=[0, 29.79, 0], size_scale=4e3, distance_scale=1.3), # 地球放大 4000 倍,距离放大 1.3 倍 Moon(init_position=[363104 + 1.12 * AU, 0, 0], - init_velocity=[-9, 29.79 + 1.023, 0], size_scale=4e3, distance_scale=1.3), + init_velocity=[-9, 29.79 + 1.023, 0], size_scale=4e3, distance_scale=1.3), Mars(size_scale=4e3, distance_scale=1.3), # 火星放大 4000 倍,距离放大 1.3 倍 Jupiter(size_scale=0.68e3, distance_scale=0.65), # 木星放大 680 倍,距离缩小到真实距离的 0.65 Saturn(size_scale=0.68e3, distance_scale=0.52), # 土星放大 680 倍,距离缩小到真实距离的 0.52 diff --git a/simulators/views/ursina_view.py b/simulators/views/ursina_view.py index d274e75..92f06e1 100644 --- a/simulators/views/ursina_view.py +++ b/simulators/views/ursina_view.py @@ -21,72 +21,17 @@ import random from simulators.views.body_view import BodyView import numpy as np import math -from math import sin, cos, radians -import os -import matplotlib.pyplot as plt SCALE_FACTOR = 1e-6 -class Ring(Entity): - def __init__(self, thickness=0.2, inner_radius=0.5, outer_radius=3, texture=None, position=None, **kwargs): - super().__init__(**kwargs) - - inner_circle = Entity(parent=self, model='circle', texture=texture, scale=inner_radius, - position=position) - outer_circle = Entity(parent=self, model='circle', texture=texture, scale=outer_radius, - position=position) - - self.children.append(inner_circle) - self.children.append(outer_circle) - inner_circle.parent = self - outer_circle.parent = self - inner_circle.set_light_off() - outer_circle.set_light_off() - - # inner_circle.y += thickness / 2 - # outer_circle.y -= thickness / 2 - # self.scale_y = thickness - - -# 创建 TorusMesh -class TorusMesh(Mesh): - def __init__(self, radius=1, thickness=.25, radial_segments=16, tubular_segments=32): - super().__init__() - self.radius = radius - self.thickness = thickness - self.radial_segments = radial_segments - self.tubular_segments = tubular_segments - self.vertices = [] - self.triangles = [] - - for j in range(radial_segments): - for i in range(tubular_segments): - a = i / tubular_segments * math.pi * 2 - b = j / radial_segments * math.pi * 2 - x = (radius + thickness * math.cos(b)) * math.cos(a) - y = (radius + thickness * math.cos(b)) * math.sin(a) - z = thickness * math.sin(b) - u = i / tubular_segments - v = j / radial_segments - self.vertices.append((x, y, z)) - self.uvs.append((u, v)) - - for j in range(radial_segments): - for i in range(tubular_segments): - a = i - b = j - c = (i + 1) % tubular_segments - d = (j + 1) % radial_segments - self.triangles.append((a + b * tubular_segments, b + d * tubular_segments, c + b * tubular_segments)) - self.triangles.append((c + b * tubular_segments, b + d * tubular_segments, c + d * tubular_segments)) +class UrsinaPlayer(FirstPersonController): + """ + """ -class UrsinaPlayer(FirstPersonController): def __init__(self, position, targets=None): - # global planets super().__init__() - # pos = planets[0].position camera.fov = 100 camera.rotation_y = 90 self.planets = None @@ -116,51 +61,6 @@ class UrsinaPlayer(FirstPersonController): self.on_enable() self.rotation_speed = 80 - # def space_callback(self): - # best_camera_position = self.best_camera_position() - # if best_camera_position is None: - # return - # best_pos = np.array(best_camera_position[0]) * SCALE_FACTOR - # camera.position, camera.rotation = best_pos, best_camera_position[1] - # - # def best_camera_position(self): - # if self.planets is None: - # return None - # - # min_x, max_x, min_y, max_y, min_z, max_z = None, None, None, None, None, None - # for planet in self.planets: - # if min_x is None or planet.x < min_x: - # min_x = planet.x - # if max_x is None or planet.x > max_x: - # max_x = planet.x - # if min_y is None or planet.y < min_y: - # min_y = planet.y - # if max_y is None or planet.y > max_y: - # max_y = planet.y - # if min_z is None or planet.z < min_z: - # min_z = planet.z - # if max_z is None or planet.z > max_z: - # max_z = planet.z - # x = (min_x + max_x) / 2 - # y = (min_y + max_y) / 2 - # z = (min_z + max_z) / 2 - # distance = max(max_x - min_x, max_y - min_y, max_z - min_z) * 1.5 - # return (x, y + distance, z - distance), (0, -90, 0) - - # def camera_adj(self, targets): - # # 创建一些物体 - # # targets = [] - # # for i in range(10): - # # targets.append(Entity(model='cube', color=color.random_color(), position=(i * 2 - 10, i % 2 * 2 - 1, 0))) - # - # # 计算所有物体的平均位置 - # avg_pos = sum(np.array([target.position for target in targets]))/ len(targets) - # - # # 创建一个OrthographicCamera,使其位于所有目标的中心位置,并面向下方 - # # camera = OrthographicCamera() - # camera.position = avg_pos + (0, 0, 20) - # camera.rotation_x = -90 - def input(self, key): if key == "escape": if mouse.locked: @@ -168,55 +68,11 @@ class UrsinaPlayer(FirstPersonController): else: sys.exit() return super().input(key) - # elif key == "space": - # self.space_callback() - # Input.bind('space', space_callback) - - # def _update(self): - # # # {'left mouse': 0, 'left': 0, 'left shift': 0, 'space': 1, 'w': 0, 's': 0, 'd': 0, 'a': 0, 'shift': 0}) - # # if held_keys["left mouse"]: - # # self.on_enable() - # # if held_keys["left shift"]: - # # self.y -= self.vspeed - # # if held_keys["space"]: - # # self.y += self.vspeed - # # WASD keys - # - # if held_keys['f']: - # camera.fov += 1 - # if held_keys['r']: - # camera.fov -= 1 - # # camera.position - # # self.rotation_y += held_keys['d'] * self.rotation_speed * time.dt - # # self.rotation_y -= held_keys['a'] * self.rotation_speed * time.dt - # # self.rotation_x += held_keys['w'] * self.rotation_speed * time.dt - # # self.rotation_x -= held_keys['s'] * self.rotation_speed * time.dt - # - # forward = self.forward * (held_keys['w'] - held_keys['s']) - # right = self.right * (held_keys['d'] - held_keys['a']) - # - # self.position += (forward + right) * self.speed * time.dt - # # if held_keys['w']: - # # camera.position += camera.forward * time.dt - # # if held_keys['s']: - # # camera.position -= camera.forward * time.dt - # # if held_keys['a']: - # # camera.position -= camera.right * time.dt - # # if held_keys['d']: - # # camera.position += camera.right * time.dt - # # - # # # Mouse control - # # camera.rotation_y += held_keys['right mouse'] * mouse.velocity[0] * 20 - # # camera.rotation_x -= held_keys['right mouse'] * mouse.velocity[1] * 20 - # # camera.rotation_x = clamp(camera.rotation_x, -90, 90) class Planet(Entity): def __init__(self, body_view: BodyView): self.body_view = body_view - # self.angle = 0 # random.uniform(0.0005, 0.01) - # self.fastMode = 0 - # self.rotation = (random.randint(0, 360) for i in range(3)) # 旋转速度和大小成反比(未使用真实数据) self.rotspeed = 30000 / self.body_view.raduis # random.uniform(1.0, 2.0) self.rotMode = 'x' # random.choice(["x", "y", "z"]) @@ -225,18 +81,12 @@ class Planet(Entity): pos = body_view.position * body_view.body.distance_scale * SCALE_FACTOR scale = body_view.body.diameter * body_view.body.size_scale * SCALE_FACTOR - # texture = eval(f"{_type}_texture") - # e = os.path.exists(texture) - # texture = self.__set_texture(body_view.texture) if hasattr(body_view, "texture"): texture = load_texture(body_view.texture) else: texture = None - # 将贴图旋转90度C:\ProgramData\Anaconda3\envs\tf_gpu\Lib\site-packages\ursina\models_compressed\diamond.ursinamesh super().__init__( - # model=TorusMesh(radius=1e20, thickness=1.25e20, radial_segments=16, tubular_segments=32), - # model="sky_dome", model="sphere", scale=scale, texture=texture, @@ -244,30 +94,7 @@ class Planet(Entity): position=pos, rotation=(0, 0, 0)) - # def __set_texture(self, image_file): - # """ - # 设置纹理图片到天体 - # :param image_file: - # :return: - # """ - # outfile = image_file.replace('.png', '_rotate.png').replace('.jpg', '_rotate.jpg') - # from PIL import Image - # # 打开原始图片 - # image = Image.open(image_file) - # # 顺时针旋转90度 - # rotated_image = image.rotate(90, expand=True) - # - # # 保存旋转后的图片 - # rotated_image.save(outfile) - # - # return outfile - def turn(self): - # if self.name != "sun": - # if self.fastMode: - # angle *= 200 - # self.x = self.x * cos(radians(angle)) - self.y * sin(radians(angle)) - # self.y = self.x * sin(radians(angle)) + self.y * cos(radians(angle)) pos = self.body_view.position * SCALE_FACTOR self.x = -pos[1] @@ -289,35 +116,26 @@ class UrsinaView(BodyView): def __init__(self, body: Body): BodyView.__init__(self, body) self.velocity = body.velocity - # 将列表元素往后移动一位,最后一位变为第一位 - # a1 = a[1:] + [a[0]] - # self.velocity = np.concatenate((body.velocity[1:], [body.velocity[0]])) - - # 将列表元素往前移动一位,第一位变为最后一位 - # a2 = [a[-1]] + a[:-1] - # self.velocity = np.concatenate((np.array([body.velocity[-1]]), body.velocity[0:2])) self.planet = Planet(self) if body.has_rings: self.create_rings() - # self.planet.clear_light() if self.body.is_fixed_star: # 如果是恒星(如:太阳),自身会发光,则需要关闭灯光 self.planet.set_light_off() def create_rings(self): - from ursina import Cylinder + """ + 创建星环(使用土星贴图) + :return: + """ scale = 3 * self.body.diameter * self.body.size_scale * SCALE_FACTOR pos = self.planet.position - # self.ring = Entity(model='sphere', texture='textures/saturnRings.jpg', scale=scale, position=pos,double_sided=True) self.ring = Entity(model="circle", texture='../textures/saturnRings.jpg', scale=scale, position=pos, rotation=(70, 0, 0), double_sided=True) - # self.ring2 = Entity(model="circle", texture='../textures/saturnRings.jpg', scale=scale, position=pos, - # rotation=(180 + 70, 0, 0)) - + # 假设星环自身会发光 self.ring.set_light_off() - # self.ring2.set_light_off() def update(self): self.planet.turn() @@ -325,8 +143,6 @@ class UrsinaView(BodyView): self.light.position = Vec3(self.planet.x, self.planet.y, self.planet.z) if hasattr(self, "ring"): self.ring.position = Vec3(self.planet.x, self.planet.y, self.planet.z) - # if hasattr(self, "ring2"): - # self.ring2.position = Vec3(self.planet.x, self.planet.y, self.planet.z) def appear(self): pass -- GitLab