From 74d717091e2c7d5c0e42e409d82b762e5284152f Mon Sep 17 00:00:00 2001 From: march3 Date: Mon, 13 Mar 2023 22:51:20 +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 --- scenes/sun_earth_moon.py | 2 +- simulators/ursina_simulator.py | 12 +++-- simulators/views/ursina_view.py | 87 +++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/scenes/sun_earth_moon.py b/scenes/sun_earth_moon.py index 67e91e1..e89d9d4 100644 --- a/scenes/sun_earth_moon.py +++ b/scenes/sun_earth_moon.py @@ -32,4 +32,4 @@ if __name__ == '__main__': # mayavi_run(bodies, SECONDS_PER_HALF_DAY / 2, view_azimuth=-45) # 使用 ursina 查看的运行效果 - ursina_run(bodies, SECONDS_PER_WEEK, position=(0, 0, 0)) + ursina_run(bodies, SECONDS_PER_DAY, position=(0, 0, 0)) diff --git a/simulators/ursina_simulator.py b/simulators/ursina_simulator.py index 5f63849..274a1c8 100644 --- a/simulators/ursina_simulator.py +++ b/simulators/ursina_simulator.py @@ -102,8 +102,9 @@ class UrsinaSimulator(Simulator): # 创建一个新的 Entity 对象,作为光晕的容器 # glow_entity = Entity(parent=entity, model='sphere', scale=entity.scale * 1.2) # 创建 PointLight 对象,并设置它的属性 - light = PointLight(parent=lights[0], intensity=intensity, color=light_color, attenuation=attenuation) - lights.append(light) + for i in range(2): + light = PointLight(parent=lights[0], intensity=intensity, color=light_color, attenuation=attenuation) + lights.append(light) # 把 Entity 对象放到星星的后面,使得光晕看起来像是从星星发出来的 glow_entity.world_position = entity.world_position @@ -134,9 +135,10 @@ class UrsinaSimulator(Simulator): scale=math.pow(1.03, i), alpha=0.1) lights.append(glow_entity) - # 创建 PointLight 对象,作为恒星的灯光源 - light = PointLight(parent=entity, intensity=10, range=10, color=color.white) - lights.append(light) + for i in range(2): + # 创建 PointLight 对象,作为恒星的灯光源 + light = PointLight(parent=entity, intensity=10, range=10, color=color.white) + lights.append(light) # light = DirectionalLight(shadows=True, direction=Vec3(0, 0, 1), color=color.white) # light.look_at(Vec3(0, 0, -1)) diff --git a/simulators/views/ursina_view.py b/simulators/views/ursina_view.py index 341b1a5..28faf46 100644 --- a/simulators/views/ursina_view.py +++ b/simulators/views/ursina_view.py @@ -25,7 +25,7 @@ import math SCALE_FACTOR = 5e-7 # 旋转因子为1,则为正常的转速 ROTATION_SPEED_FACTOR = 1.0 -# ROTATION_SPEED_FACTOR = 0.1 +ROTATION_SPEED_FACTOR = 0.01 class UrsinaPlayer(FirstPersonController): @@ -74,6 +74,82 @@ class UrsinaPlayer(FirstPersonController): return super().input(key) +from math import pi, sin, cos + + +# def create_sphere(radius, subdivisions): +# # 生成球体的顶点、UV坐标、法线和三角面 +# # radius = 1 +# # subdivisions = 16 +# theta = np.linspace(0, 2 * np.pi, subdivisions + 1) +# phi = np.linspace(0, np.pi, subdivisions + 1) +# u = np.linspace(0, 1, subdivisions + 1) +# v = np.linspace(0, 1, subdivisions + 1) +# verts = [] +# uvs = [] +# normals = [] +# for i in range(len(theta)): +# for j in range(len(phi)): +# x = radius * np.sin(phi[j]) * np.cos(theta[i]) +# y = radius * np.sin(phi[j]) * np.sin(theta[i]) +# z = radius * np.cos(phi[j]) +# verts.append((x, y, z)) +# uvs.append((u[i], v[j])) +# normals.append((x / radius, y / radius, z / radius)) +# +# tris = [] +# for i in range(len(theta)): +# for j in range(len(phi)): +# a = i * (subdivisions + 1) + j +# b = (i + 1) * (subdivisions + 1) + j +# tris.append((a, b, a + 1)) +# tris.append((a + 1, b, b + 1)) +# +# # # 反转面法线 +# # for i in range(len(tris)): +# # a, b, c = tris[i] +# # tris[i] = (c, b, a) +# # normals[a], normals[b], normals[c] = -Vec3(*normals[a]), -Vec3(*normals[b]), -Vec3(*normals[c]) +# # normals[a], normals[b], normals[c] = -Vec3(*normals[a]), -Vec3(*normals[b]), -Vec3(*normals[c]) +# +# # 创建球体 Mesh 对象并设置材质 +# sphere_mesh = Mesh(vertices=verts, uvs=uvs, normals=normals, triangles=tris, mode='triangle') +# return sphere_mesh + +def create_sphere(radius, subdivisions): + verts = [] + tris = [] + normals = [] + uvs = [] + + for y in range(subdivisions + 1): + for x in range(subdivisions + 1): + x_segment = x / subdivisions + y_segment = y / subdivisions + x_pos = cos(x_segment * 2 * pi) * sin(y_segment * pi) + y_pos = cos(y_segment * pi) + z_pos = sin(x_segment * 2 * pi) * sin(y_segment * pi) + + verts.append(Vec3(x_pos, y_pos, z_pos) * radius) + uvs.append(Vec2(x_segment, y_segment)) + normals.append(Vec3(x_pos, y_pos, z_pos)) + + for y in range(subdivisions): + for x in range(subdivisions): + first = (y * (subdivisions + 1)) + x + second = first + subdivisions + 1 + tris.append((first, second + 1, second)) + tris.append((first, first + 1, second + 1)) + + # 反转面法线 + for i in range(len(tris)): + a, b, c = tris[i] + tris[i] = (c, b, a) + # normals[a], normals[b], normals[c] = -Vec3(*normals[a]), -Vec3(*normals[b]), -Vec3(*normals[c]) + + return Mesh(vertices=verts, triangles=tris, normals=normals, uvs=uvs, mode='triangle') + + class Planet(Entity): def __init__(self, body_view: BodyView): self.body_view = body_view @@ -84,13 +160,16 @@ 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 + subdivisions = 32 # int(scale*20) + if hasattr(body_view, "texture"): texture = load_texture(body_view.texture) else: texture = None super().__init__( - model="sphere", + # model="sphere", + model=create_sphere(0.5, subdivisions), scale=scale, texture=texture, color=color.white, @@ -113,7 +192,7 @@ class Planet(Entity): # self.rotspeed = 30000 / self.body_view.raduis # random.uniform(1.0, 2.0) else: # 是通过月球保持一面面对地球,调整得到 - self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR # / 60 / 24 + self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR # / 60 / 24 # rotation_speed 度/小时 dt 秒 = (dt / 3600)小时 self.rotation_y -= self.rotspeed @@ -142,7 +221,7 @@ class UrsinaView(BodyView): :return: """ # 行星环偏移角度 - self.ring_rotation_x = 70 + self.ring_rotation_x = 75 # 创建行星环 self.ring = Entity(parent=self.planet, model="circle", texture='../textures/saturnRings.jpg', scale=2, rotation=(self.ring_rotation_x, 0, 0), double_sided=True) -- GitLab