提交 bf539743 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 96156167
...@@ -95,8 +95,11 @@ class SolarSystemRealitySim: ...@@ -95,8 +95,11 @@ class SolarSystemRealitySim:
if self.clock_position_center: if self.clock_position_center:
position, origin = (0, .25), (0, 0) position, origin = (0, .25), (0, 0)
else: else:
from ursina import window
aspect_ratio = window.aspect_ratio
position, origin = (0.5 * aspect_ratio - 0.3, -0.465), (-0.5, 0.5),
# position, origin = (0.60, -0.465), (-0.5, 0.5) # position, origin = (0.60, -0.465), (-0.5, 0.5)
position, origin = (-0.60, -0.465), (-0.5, 0.5) # position, origin = (-0.60, -0.465), (-0.5, 0.5)
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'), ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'),
position=position, position=position,
......
...@@ -411,16 +411,19 @@ def create_3d_card(left=-.885, top=0.495, width=0.02, height=0.02): ...@@ -411,16 +411,19 @@ def create_3d_card(left=-.885, top=0.495, width=0.02, height=0.02):
def create_text_panel(width=0.35, height=.5): def create_text_panel(width=0.35, height=.5):
# 创建一个 Panel 组件 # 创建一个 Panel 组件
from ursina import Text, Panel, color, camera, Vec3 from ursina import Text, Panel, color, camera, Vec3, window
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
panel = Panel( aspect_ratio = window.aspect_ratio
# 1920, 1080 1.777777777 position=(-.88, 0.3, 0), # 1.77
# 2376, 1080 2.2 position=(-.99, 0.3, 0), # 1.77
panel = Panel( # 2
parent=None, parent=None,
model='quad', model='quad',
# texture='white_cube', # texture='white_cube',
color=color.black, color=color.black,
origin=(-.48, .48, -.48), origin=(-.48, .48, -.48),
scale=(width, height), scale=(width, height),
position=(-.88, 0.3, 0), position=(-.49 * aspect_ratio, 0.3, 0),
alpha=0.5 alpha=0.5
) )
......
...@@ -95,8 +95,10 @@ class SolarSystemRealitySim: ...@@ -95,8 +95,10 @@ class SolarSystemRealitySim:
if self.clock_position_center: if self.clock_position_center:
position, origin = (0, .25), (0, 0) position, origin = (0, .25), (0, 0)
else: else:
# position, origin = (0.60, -0.465), (-0.5, 0.5) from ursina import window
position, origin = (-0.60, -0.465), (-0.5, 0.5) aspect_ratio = window.aspect_ratio
position, origin = (0.5 * aspect_ratio - 0.3, -0.465), (-0.5, 0.5),
# position, origin = (-0.60, -0.465), (-0.5, 0.5)
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'), ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'),
position=position, position=position,
......
...@@ -68,9 +68,20 @@ class HalleyCometSimBase: ...@@ -68,9 +68,20 @@ class HalleyCometSimBase:
self.pluto = None self.pluto = None
self.bodies = [] self.bodies = []
def set_window_size(self, size=(1536, 684)): def set_window_size(self, size=(1536, 684), fullscreen=False):
from ursina import window from ursina import window
if fullscreen:
# 设置窗口为全屏模式
window.fullscreen = True
# 设置窗口的宽度和高度
window.size = size window.size = size
# self.set_window_size((3500, 1024))
# r = 1
# self.set_window_size((1920*2, 1080*2))
# self.set_window_size((int(1920 * r), int(1080 * r)))
# self.set_window_size((2376, 1080))
# self.set_window_size((520, 540), fullscreen=False)
def build_solar_system(self, ignore_gravity=False, start_time=None): def build_solar_system(self, ignore_gravity=False, start_time=None):
# region 构建太阳系 # region 构建太阳系
...@@ -126,8 +137,9 @@ class HalleyCometSimBase: ...@@ -126,8 +137,9 @@ class HalleyCometSimBase:
# if self.clock_position_center: # if self.clock_position_center:
# position, origin = (0, .25), (0, 0), # position, origin = (0, .25), (0, 0),
# else: # else:
position, origin = (0.60, -0.465), (-0.5, 0.5), from ursina import window
aspect_ratio = window.aspect_ratio
position, origin = (0.5 * aspect_ratio - 0.3, -0.465), (-0.5, 0.5),
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'), ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'),
position=position, position=position,
origin=origin, origin=origin,
......
...@@ -72,8 +72,8 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -72,8 +72,8 @@ class HalleyCometSim(HalleyCometSimBase):
# UrsinaConfig.trail_length = 180 # UrsinaConfig.trail_length = 180
UrsinaConfig.trail_factor = 3 UrsinaConfig.trail_factor = 3
# self.set_window_size((3500, 1024)) r = 1
# self.set_window_size((1920, 1080)) self.set_window_size((int(1920 * r), int(1080 * r)), True)
# camera.clip_plane_near = 0.1 # camera.clip_plane_near = 0.1
camera.clip_plane_far = 1000000 camera.clip_plane_far = 1000000
...@@ -349,7 +349,7 @@ if __name__ == '__main__': ...@@ -349,7 +349,7 @@ if __name__ == '__main__':
show_trail=True, show_trail=True,
# bg_music='sounds/no_glory.mp3', # bg_music='sounds/no_glory.mp3',
show_camera_info=False, show_camera_info=False,
# save_as_video=True, save_as_video=True,
show_control_info=False, show_control_info=False,
timer_enabled=True, timer_enabled=True,
show_grid=False show_grid=False
......
...@@ -100,7 +100,10 @@ class SolarSystemRealitySim: ...@@ -100,7 +100,10 @@ class SolarSystemRealitySim:
if self.clock_position_center: if self.clock_position_center:
position, origin = (0, .25), (0, 0), position, origin = (0, .25), (0, 0),
else: else:
position, origin = (0.60, -0.465), (-0.5, 0.5), from ursina import window
aspect_ratio = window.aspect_ratio
position, origin = (0.5 * aspect_ratio - 0.3, -0.465), (-0.5, 0.5),
# position, origin = (0.60, -0.465), (-0.5, 0.5),
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'), ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'),
position=position, position=position,
......
...@@ -64,10 +64,10 @@ class VideoRecorder(Entity): ...@@ -64,10 +64,10 @@ class VideoRecorder(Entity):
for key, value in kwargs.items(): for key, value in kwargs.items():
setattr(self, key, value) setattr(self, key, value)
self.max_frames = int(self.duration * self.fps) # self.max_frames = int(self.duration * self.fps)
self.frames = [] # self.frames = []
self.save_name = "video_temp.mp4" self.save_name = "video_temp.mp4"
self.video = self.create_video(864, 1536) self.video = None
def create_video(self, height, width): def create_video(self, height, width):
fourcc = cv2.VideoWriter_fourcc(*'mp4v') fourcc = cv2.VideoWriter_fourcc(*'mp4v')
...@@ -75,11 +75,11 @@ class VideoRecorder(Entity): ...@@ -75,11 +75,11 @@ class VideoRecorder(Entity):
return video return video
def start_recording(self): def start_recording(self):
print('start recording,', self.duration, self.file_path) print('start recording,', self.file_path)
window.fps_counter.enabled = False window.fps_counter.enabled = False
window.exit_button.visible = False window.exit_button.visible = False
self.frames = [] # self.frames = []
self.max_frames = self.duration * self.fps # self.max_frames = self.duration * self.fps
if not self.file_path.exists(): if not self.file_path.exists():
self.file_path.mkdir() self.file_path.mkdir()
# base.movie(namePrefix=f'\\video_temp\\{self.video_name}', duration=2.0, fps=30, format='png', sd=4) # base.movie(namePrefix=f'\\video_temp\\{self.video_name}', duration=2.0, fps=30, format='png', sd=4)
...@@ -96,35 +96,35 @@ class VideoRecorder(Entity): ...@@ -96,35 +96,35 @@ class VideoRecorder(Entity):
def convert_to_mp4(self): def convert_to_mp4(self):
print("视频保存中") print("视频保存中")
for frame in self.frames: # for frame in self.frames:
self.video.write(frame) # self.video.write(frame)
self.video.release() self.video.release()
cv2.destroyAllWindows() cv2.destroyAllWindows()
# crop('video.mp4') # crop('video.mp4')
print("视频保存完成") print("视频保存完成")
print(self.save_name) print(self.save_name)
def screenshot_to_opencv_img(self, texture): # def screenshot_to_opencv_img(self, texture):
# 将Texture对象转换为numpy数组 # # 将Texture对象转换为numpy数组
array = texture.to_array() # array = texture.to_array()
# 将数组reshape为4D,以便opencv可以正确读取 # # 将数组reshape为4D,以便opencv可以正确读取
array = np.reshape(array, (texture.height, texture.width, -1)) # array = np.reshape(array, (texture.height, texture.width, -1))
# 转换为opencv读取的格式,注意需要先安装opencv库 # # 转换为opencv读取的格式,注意需要先安装opencv库
img = cv2.cvtColor(array, # img = cv2.cvtColor(array,
cv2.COLOR_RGB2BGR) # 这里的cv2.COLOR_RGB2BGR是将RGB格式转换为BGR格式,因为Ursina使用的是RGB格式,而opencv使用的是BGR格式 # cv2.COLOR_RGB2BGR) # 这里的cv2.COLOR_RGB2BGR是将RGB格式转换为BGR格式,因为Ursina使用的是RGB格式,而opencv使用的是BGR格式
return img # return img
def update(self): def update(self):
if not self.recording: if not self.recording:
return return
self.t += time.dt # self.t += time.dt
if self.t >= 1 / 30: # if self.t >= 1 / 30:
# base.screenshot( # # base.screenshot(
# namePrefix='\\video_temp\\' + self.video_name + '_' + str(self.i).zfill(4) + '.png', # # namePrefix='\\video_temp\\' + self.video_name + '_' + str(self.i).zfill(4) + '.png',
# defaultFilename=0, # # defaultFilename=0,
# ) # # )
self.t = 0 # self.t = 0
# image = deepcopy(camera.render_texture) # image = deepcopy(camera.render_texture)
# self.frames.append(self.renderToPNM()) # self.frames.append(self.renderToPNM())
from PIL import Image from PIL import Image
...@@ -136,7 +136,12 @@ class VideoRecorder(Entity): ...@@ -136,7 +136,12 @@ class VideoRecorder(Entity):
data = image.getRamImageAs("BGR").getData() data = image.getRamImageAs("BGR").getData()
np_data = np.frombuffer(data, dtype=np.uint8) np_data = np.frombuffer(data, dtype=np.uint8)
# #
img_data = np.reshape(np_data, (864, 1536, 3)) if self.video is None:
self.video_height = image.y_size # 864
self.video_width = image.x_size # 1536
self.video = self.create_video(self.video_height, self.video_width)
img_data = np.reshape(np_data, (self.video_height, self.video_width, 3))
# img = Image.fromarray(img_data) # img = Image.fromarray(img_data)
# img = self.screenshot_to_opencv_img(image) # img = self.screenshot_to_opencv_img(image)
# img = np.array(data) # img = np.array(data)
...@@ -158,12 +163,13 @@ class VideoRecorder(Entity): ...@@ -158,12 +163,13 @@ class VideoRecorder(Entity):
# # image = deepcopy(camera.render_texture) # # image = deepcopy(camera.render_texture)
# self.frames.append(data) # self.frames.append(data)
self.i += 1 # self.i += 1
# img_bgr = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR) # img_bgr = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR)
# if imageNum < self.fps * args.total_time: # if imageNum < self.fps * args.total_time:
# show_image(frame) # show_image(frame)
self.frames.append(normal_image) # self.frames.append(normal_image)
self.video.write(normal_image)
# store screenshot in memory # store screenshot in memory
# def renderToPNM(self): # def renderToPNM(self):
# base.graphicsEngine.renderFrame() # base.graphicsEngine.renderFrame()
...@@ -175,18 +181,18 @@ class VideoRecorder(Entity): ...@@ -175,18 +181,18 @@ class VideoRecorder(Entity):
# # win.setupRenderTexture() # # win.setupRenderTexture()
# return None # return None
def convert_to_gif(self): # def convert_to_gif(self):
import imageio # import imageio
images = [] # images = []
if not os.path.exists(self.file_path): # if not os.path.exists(self.file_path):
return # return
#
for filename in os.listdir(self.file_path): # for filename in os.listdir(self.file_path):
images.append(imageio.imread(self.file_path / filename)) # images.append(imageio.imread(self.file_path / filename))
#
imageio.mimsave(Path(f'{self.file_path.parent}/{self.video_name}.gif'), images) # imageio.mimsave(Path(f'{self.file_path.parent}/{self.video_name}.gif'), images)
shutil.rmtree(self.file_path) # delete temp folder # shutil.rmtree(self.file_path) # delete temp folder
print('saved gif to:', Path(f'{self.file_path.parent}/{self.video_name}.gif')) # print('saved gif to:', Path(f'{self.file_path.parent}/{self.video_name}.gif'))
class VideoRecorderUI(WindowPanel): class VideoRecorderUI(WindowPanel):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册