diff --git a/bodies/__init__.py b/bodies/__init__.py index 19d9f392103133bc1004820beb6428bf056d4910..fab8379ef99bef8a4cacf00608ad2cae3dfb359b 100644 --- a/bodies/__init__.py +++ b/bodies/__init__.py @@ -33,3 +33,6 @@ from bodies.fixed_stars.uy_scuti import UYScuti from bodies.fixed_stars.eta_carinae import EtaCarinae from bodies.fixed_stars.y_canum_venaticorum import YCanumVenaticorum from bodies.fixed_stars.carinae_v382 import CarinaeV382 + +# +from bodies.color_body import ColorBody diff --git a/bodies/body.py b/bodies/body.py index 08379d9f0f3d5e7fbfce832bdf8527fde4de1da0..aa0a60c208319b68d9c59bed3f51a4598deed4a8 100644 --- a/bodies/body.py +++ b/bodies/body.py @@ -86,6 +86,11 @@ class Body(metaclass=ABCMeta): self.show_name = show_name self.resolution = None + self.light_disable = False + + def set_light_disable(self, value): + self.light_disable = value + return self def set_resolution(self, value): self.resolution = value diff --git a/bodies/color_body.py b/bodies/color_body.py new file mode 100644 index 0000000000000000000000000000000000000000..131ec705382051f82041c81edf88f739979238ce --- /dev/null +++ b/bodies/color_body.py @@ -0,0 +1,81 @@ +# -*- coding:utf-8 -*- +# title :颜色天体 +# description :颜色天体 +# author :Python超人 +# date :2023-02-11 +# link :https://gitcode.net/pythoncr/ +# python_version :3.8 +# ============================================================================== +from bodies.body import Body +from common.consts import MO +from common.image_utils import gen_color_body_texture, find_texture_root_path +import os +import random + + +class ColorBody(Body): + """ + 颜色天体基类 + """ + + def __init__(self, name="颜色天体", mass=1 * MO, + init_position=[0, 0, 0], + init_velocity=[0, 0, 0], + color=(0xFF, 0xFF, 0xFF), + texture=None, size_scale=1.0, distance_scale=1.0, + rotation_speed=None, ignore_mass=False, density=5e3, trail_color=None, + texture_bright=None, texture_contrast=None, show_name=False): + + self.color = color + texture = self.gen_texture(texture, texture_bright, texture_contrast) + if rotation_speed is None: + rotation_speed = random.randint(10, 100) / 50 + params = { + "name": name, + "mass": mass, + "init_position": init_position, + "init_velocity": init_velocity, + "density": density, + "color": color, + "texture": texture, + "size_scale": size_scale, + "distance_scale": distance_scale, + "rotation_speed": rotation_speed, + "ignore_mass": ignore_mass, + "trail_color": trail_color, + "show_name": show_name + } + super().__init__(**params) + + def gen_texture(self, texture, texture_bright, texture_contrast): + if texture is None: + return None + texture_path = find_texture_root_path() + if texture_path is None: + err_msg = "未找到纹理图片目录" + raise Exception(err_msg) + + temp_dir = os.path.join(texture_path, "temp") + if not os.path.exists(temp_dir): + os.mkdir(temp_dir) + + texture_name = os.path.basename(texture). \ + replace(".", "_").replace("/", "_"). \ + replace("\\", "_").replace("__", "_") + + save_file = os.path.join(temp_dir, "%s_%s.png" % (texture_name, "_".join([str(i) for i in list(self.color)]))) + + if os.path.exists(save_file): + return save_file + + body_img = os.path.join(texture_path, texture) + gen_color_body_texture(self.color, + bright=texture_bright, + contrast=texture_contrast, + save_file=save_file, + color_body_img=body_img) + return save_file + + +if __name__ == '__main__': + print(ColorBody()) diff --git a/bodies/fixed_stars/fixed_star.py b/bodies/fixed_stars/fixed_star.py index 70ec1ddd1ca64f291912a41418627308b4942f52..c60ed07a95baec66404746881ff5a3f249db71f9 100644 --- a/bodies/fixed_stars/fixed_star.py +++ b/bodies/fixed_stars/fixed_star.py @@ -1,6 +1,6 @@ # -*- coding:utf-8 -*- -# title :天狼星 -# description :天狼星 +# title :恒星 +# description :恒星 # author :Python超人 # date :2023-02-11 # link :https://gitcode.net/pythoncr/ @@ -49,6 +49,7 @@ class FixedStar(Body): "show_name": show_name } super().__init__(**params) + # 恒星属性 self.light_on = True self.glows = (12, 1.009, 0.08) @@ -59,9 +60,15 @@ class FixedStar(Body): if texture_path is None: err_msg = "未找到纹理图片目录" raise Exception(err_msg) - save_file = os.path.join(texture_path, "fixed_star_%s.png" % str(self.__class__.__name__).lower()) + + temp_dir = os.path.join(texture_path, "temp") + if not os.path.exists(temp_dir): + os.mkdir(temp_dir) + + save_file = os.path.join(temp_dir, "fixed_star_%s.png" % str(self.__class__.__name__).lower()) if os.path.exists(save_file): return save_file + fixed_star_img = os.path.join(texture_path, texture) gen_fixed_star_texture(self.color, bright=texture_bright, diff --git a/common/image_utils.py b/common/image_utils.py index 1e40748b3c835562e6fe4abca6452ffd7c850f8c..bf870c89d284574b10fe6f2570d6e933e456e3a1 100644 --- a/common/image_utils.py +++ b/common/image_utils.py @@ -194,6 +194,21 @@ def find_texture(texture): return "" +def gen_color_body_texture(color, save_file, color_body_img="color_body.jpg", bright=None, contrast=None): + bright = 1 if bright is None else bright + contrast = 1 if contrast is None else contrast + color_body_img = find_texture(color_body_img) + if color_body_img is None: + err_msg = "未找到纹理图片:" % color_body_img + raise Exception(err_msg) + trans_img = trans_png(color_body_img) + bg_img = create_image(trans_img.width, trans_img.height, color) + mixed = mix(bg_img, trans_img) + mixed = image_enhance(mixed, bright=bright, contrast=contrast) + mixed.save(save_file, 'PNG') + return mixed + + def gen_fixed_star_texture(color, save_file, fixed_star_img="fixed_star.png", bright=None, contrast=None): bright = 1.1 if bright is None else bright contrast = 3.2 if contrast is None else contrast @@ -250,7 +265,7 @@ if __name__ == '__main__': # mono = gray_to_mono(gray_img, (0, 0, 255)).show() # image_enhance(mono,bright=1,contrast=2).show() - gen_fixed_star_texture((198, 29, 3), "xxx.png",bright=2.2,contrast=3).show() + gen_fixed_star_texture((198, 29, 3), "xxx.png", bright=2.2, contrast=3).show() # fixed_star_img = find_texture("sun.png") # colorize_color(fixed_star_img,(0,0xff,0xff)).show() diff --git a/sim_scenes/interest/text_bodies.py b/sim_scenes/interest/text_bodies.py index 7769a02429a18877709451d9e6268976c77550a1..a4b350bfd0fce390a61d8e72ce6b47e1eb799e2d 100644 --- a/sim_scenes/interest/text_bodies.py +++ b/sim_scenes/interest/text_bodies.py @@ -6,7 +6,7 @@ # link :https://gitcode.net/pythoncr/ # python_version :3.8 # ============================================================================== -from bodies import Sun, Earth, Moon, FixedStar, Body +from bodies import Sun, Earth, Moon, FixedStar, ColorBody from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY, SECONDS_PER_WEEK from sim_scenes.func import mayavi_run, ursina_run from bodies.body import AU @@ -18,30 +18,22 @@ def show_text_bodies(): """ 显示文本的星球群 """ - D = 600 - mass = 0.5e25 + D = 6000 # camera_pos = 左-右+、上+下-、前+后- - camera_pos = (-100 * D, 0, -5000 * D) + camera_pos = (-130 * D, 0, -6000 * D) - def get_position(pos, scale): - # [ 远+近- , 左+右- , 上+下-] - return pos[0] + (scale - 1.0) * 200 * (random.randint(90, 110)) * D, pos[1], pos[2] - # return pos[0], pos[1], pos[2] - - bodies: list = gen_bodies_from_image(pixel_image="./images/python.png", - params={"D": D, "Body": Body, "mass": mass, - "get_position": get_position, - "camera_pos": camera_pos}) - face = FixedStar(name="bg", texture="fixed_star.png", mass=mass * 9000, color=(0xff, 0xf8, 0xd4), - init_position=[2000 * D, 260 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-] - ignore_mass=True) - face.light_on = False - bodies.append(face) + bodies: list = gen_bodies_from_image(pixel_image="./images/python.png", texture="color_body.jpg", + params={"camera_pos": camera_pos}) + bg = FixedStar(name="bg", texture="fixed_star.png", mass=5e31, color=(0xff, 0xf8, 0xd4), + init_position=[3000 * D, 260 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-] + ignore_mass=True) + bg.light_on = True + bodies.append(bg) # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- - ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos) + ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos, view_closely=True) if __name__ == '__main__': diff --git a/sim_scenes/interest/the_eye_of_god.py b/sim_scenes/interest/the_eye_of_god.py index ed0cd8640fd7af82c0865bc773a850fdc6e1d80a..a6feaa666cf98083e8d012aaa418cd1ee0463c39 100644 --- a/sim_scenes/interest/the_eye_of_god.py +++ b/sim_scenes/interest/the_eye_of_god.py @@ -17,29 +17,22 @@ def show_eye_of_god(): """ 上帝之眼 """ - D = 600 - mass = 0.9e25 + D = 6000 # camera_pos = 左-右+、上+下-、前+后- - camera_pos = (-100 * D, 0, -5000 * D) - - def get_position(pos, scale): - # [ 远+近- , 左+右- , 上+下-] - return pos[0] + (scale - 1.0) * 300 * (random.randint(90, 110)) * D, pos[1], pos[2] - # return pos[0], pos[1], pos[2] + camera_pos = (-100 * D, 0, -6000 * D) bodies: list = gen_bodies_from_image(pixel_image="./images/eye.png", - params={"D": D, "Body": Body, "mass": mass, - "get_position": get_position, "camera_pos": camera_pos}) - face = FixedStar(name="face", texture="fixed_star.png", mass=mass * 3000, color=(0xff, 0xf8, 0xd4), - init_position=[2000 * D, 200 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-] - ignore_mass=True) - face.light_on = False - bodies.append(face) + params={"camera_pos": camera_pos}) + bg = FixedStar(name="bg", texture="fixed_star.png", mass=5e31, color=(0xff, 0xf8, 0xd4), + init_position=[3000 * D, 200 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-] + ignore_mass=True) + # bg.light_on = False + bodies.append(bg) # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- - ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos) + ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos, view_closely=True) if __name__ == '__main__': diff --git a/sim_scenes/interest/utils/body_utils.py b/sim_scenes/interest/utils/body_utils.py index 1a7533a16c8364d15a27e666f147618028ec7e7d..a84174958fee62b54d722accc2775fce1972a93c 100644 --- a/sim_scenes/interest/utils/body_utils.py +++ b/sim_scenes/interest/utils/body_utils.py @@ -6,24 +6,38 @@ # link :https://gitcode.net/pythoncr/ # python_version :3.8 # ============================================================================== +from bodies import ColorBody +import random +from PIL import Image -def gen_bodies_from_image(pixel_image, params, body_template=None): + +def gen_bodies_from_image(pixel_image, params, texture="color_body.png"): """ 根据像素图片以及参数,自动生成星球,注意图片像素不能太多,否则会导致电脑运行太慢 @param pixel_image: @param params: @return: """ - from PIL import Image + D = 6000 + mass = 0.9e25 + + def get_position(pos, scale): + # [ 远+近- , 左+右- , 上+下-] + return pos[0] + (scale - 1.0) * 300 * (random.randint(90, 110)) * D, pos[1], pos[2] + # return pos[0], pos[1], pos[2] + + params["ColorBody"] = ColorBody + params["get_position"] = get_position + params["mass"] = mass + params["D"] = D img = Image.open(pixel_image).convert('RGBA') width, height = img.size interval_factor = 20 # 星球间距因子 - if body_template is None: - body_template = 'Body(name="%s", mass=mass, color=(%d, %d, %d), size_scale=%.4f, ' \ - 'init_position=get_position([0, %g * D, %g * D], %.4f), ' \ - 'init_velocity=[0, 0, 0], ignore_mass=True)' + body_template = 'ColorBody(name="%s", mass=mass, color=(%d, %d, %d), size_scale=%.4f, ' \ + 'init_position=get_position([0, %g * D, %g * D], %.4f), ' \ + f'init_velocity=[0, 0, 0], ignore_mass=True, texture="{texture}").set_light_disable(True)' bodies_str = "[" # 以图片像素为坐标,对角线的距离 @@ -44,7 +58,7 @@ def gen_bodies_from_image(pixel_image, params, body_template=None): # 对于纯白色的颜色,就忽略,不生成星球(这样图片中,纯白色越多,对电脑的压力就越小) if pixel[0] >= 255 and pixel[1] >= 255 and pixel[1] >= 255: continue - body_str = body_template % (f"星球{w}:{h}", pixel[0], pixel[1], pixel[2], scale, + body_str = body_template % (f"星球{w}:{h}", pixel[0], pixel[1], pixel[2], scale * 10, (width - w) * interval_factor, (height - h) * interval_factor, scale) bodies_str += body_str + ",\n" diff --git a/simulators/ursina/ui/control_handler.py b/simulators/ursina/ui/control_handler.py index d508ae140256d1e6b085fc014a5994e835a074db..d54683f9edcf011f18815682ca4352209224c175 100644 --- a/simulators/ursina/ui/control_handler.py +++ b/simulators/ursina/ui/control_handler.py @@ -36,6 +36,26 @@ class ControlHandler(EventHandler): key_info = Text(text=key_info_str, font=UrsinaConfig.CN_FONT, position=(-1, 0.5), origin=(-1, 1), background=True) + self.camera_info = Text(text="", scale=0.8, position=(0, -0.45), origin=(0, 1), + background=True) + + def camera_update(self): + pos = camera.position # WS => [2] + w_pos = camera.world_rotation # 鼠标右键 + # rot = camera.rotation + wt = camera.world_transform # QE[0,1,2] AD [0 , 2] 鼠标右键 + # print(camera.world_transform) + # print(camera.origin, camera.world_transform) + # LVector3f(-1, 0, 0) Vec3(0, 0, 1) LVector3f(0, 0, -1) Vec3(1, 0, 0) Vec3(1, 1, 1) 1.7777777910232544 LVector3f(0, -1, 0) Vec3(0, 1, 0) Vec3(1, 1, 1) Vec3(0, 0, 0) + # print(camera.left,camera.forward,camera.back,camera.right,camera.scale,camera.aspect_ratio,camera.down,camera.up,camera.world_scale,camera.world_rotation) + # fw = camera.forward + # self.camera_info.text = "pos:[%.2f,%.2f,%.2f] w_pos:[%.2f,%.2f,%.2f] rot:[%.2f,%.2f,%.2f] wt:[%s,%s,%s]" % \ + self.camera_info.text = "pos:[%.2f,%.2f,%.2f] w_pos:[%.2f,%.2f,%.2f] wt:[%s,%s]" % \ + (pos[0], pos[1], pos[2], + w_pos[0], w_pos[1], w_pos[2], + # rot[0], rot[1], rot[2], + wt[0], wt[1]) # , wt[2] + def sec_per_time_switch_changed(self): """ 按钮组("默认", "天", "周", "月", "年", "十年", "百年") 点击 @@ -195,6 +215,9 @@ class ControlHandler(EventHandler): @return: """ import sys + + self.camera_update() + if key == "escape": sys.exit() # print(key) @@ -230,7 +253,7 @@ class ControlHandler(EventHandler): import math # min=0.01, max=20 # # ', up' < > '. up' n m - self.ui.slider_control_speed_factor.current_step = self.ui.slider_control_speed_factor.value/2 + self.ui.slider_control_speed_factor.current_step = self.ui.slider_control_speed_factor.value / 2 self.slider_decrease(self.ui.slider_control_speed_factor, self.ui.slider_control_speed_factor.current_step) print(self.ui.slider_control_speed_factor.current_step) diff --git a/simulators/views/ursina_view.py b/simulators/views/ursina_view.py index 71d41d9d281c77a243f3943da9682c12e2b8db2a..3e1560bc5e9f43f54e0c6ea072aaf1742fde0054 100644 --- a/simulators/views/ursina_view.py +++ b/simulators/views/ursina_view.py @@ -130,18 +130,21 @@ class Planet(Entity): double_sided=True ) - if hasattr(self.body_view.body, "torus_stars") or \ - hasattr(self.body_view.body, "light_disable"): + if hasattr(self.body_view.body, "torus_stars"): # 星环小天体群(主要模拟小行星群,非一个天体) - # 或者灯光禁用 self.set_light_off() self.double_sided = True else: # 一个天体 # 拖尾球体的初始化 self.trail_init() - if self.body_view.body.is_fixed_star: - self.create_fixed_star_lights() + + if self.body_view.body.is_fixed_star: + # 如果是恒星,开启恒星的发光的效果、并作为灯光源 + self.create_fixed_star_lights() + elif self.body_view.body.light_disable: + # 如果是非恒星,并且禁用灯光 + self.set_light_off() if self.body_view.body.show_name: self.create_name_text() diff --git a/textures/color_body.jpg b/textures/color_body.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0dcedd3748d6cd93759932295fd31e3c25b4d60d Binary files /dev/null and b/textures/color_body.jpg differ