ursina_view.py 6.6 KB
Newer Older
三月三net's avatar
三月三net 已提交
1 2 3 4 5 6 7 8 9
# -*- coding:utf-8 -*-
# title           :ursina天体视图
# description     :ursina天体视图(天体效果展示用,需要安装 ursina)
# author          :Python超人
# date            :2023-02-11
# link            :https://gitcode.net/pythoncr/
# python_version  :3.8
# ==============================================================================
# pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina
三月三net's avatar
三月三net 已提交
10 11
from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, time, \
    camera, color, mouse, Vec2, Vec3, Vec4,\
M
march3 已提交
12 13 14
    load_texture, held_keys

# from ursina.camera import OrthographicCamera
M
march3 已提交
15 16 17 18 19
from math import sin, cos, radians
from ursina.prefabs.first_person_controller import FirstPersonController
import sys
import random as rd
import os
三月三net's avatar
三月三net 已提交
20 21
from bodies import Body
import random
三月三net's avatar
三月三net 已提交
22

三月三net's avatar
三月三net 已提交
23
from simulators.views.body_view import BodyView
三月三net's avatar
三月三net 已提交
24
from simulators.views.ursina_mesh import create_sphere, create_body_torus
三月三net's avatar
三月三net 已提交
25
import numpy as np
M
march3 已提交
26
import math
三月三net's avatar
三月三net 已提交
27

三月三net's avatar
三月三net 已提交
28 29 30
SCALE_FACTOR = 5e-7
# 旋转因子为1,则为正常的转速
ROTATION_SPEED_FACTOR = 1.0
三月三net's avatar
三月三net 已提交
31
ROTATION_SPEED_FACTOR = 0.01
M
march3 已提交
32 33


三月三net's avatar
三月三net 已提交
34 35
class UrsinaPlayer(FirstPersonController):
    """
M
march3 已提交
36

三月三net's avatar
三月三net 已提交
37
    """
三月三net's avatar
三月三net 已提交
38 39
    body_rotation_speed_control = 1.0

M
march3 已提交
40

M
march3 已提交
41
    def __init__(self, position, targets=None):
M
march3 已提交
42 43
        super().__init__()
        camera.fov = 100
M
march3 已提交
44 45
        camera.rotation_y = 90
        self.planets = None
M
march3 已提交
46
        if targets is not None:
M
march3 已提交
47
            self.planets = []
M
march3 已提交
48
            # targets = [view.planet.parent for view in targets]
M
march3 已提交
49
            # targets_parent = Entity()
M
march3 已提交
50
            for view in targets:
M
march3 已提交
51 52 53 54 55 56
                # view.planet.parent = targets_parent
                self.planets.append(view.planet)
            # self.camera_adj(planets)
            #     # planets.append(view.planet)
            #
            # camera.add_script(SmoothFollow(targets_parent, offset=(0, 8, -20)))
M
march3 已提交
57
        pos = np.array(position) * SCALE_FACTOR
三月三net's avatar
三月三net 已提交
58
        # self.position = Vec3(pos[0], pos[1], pos[2])
M
march3 已提交
59
        # 将摄像机位置设置为 x=0、y=1、z=0 的位置
三月三net's avatar
三月三net 已提交
60
        camera.position = Vec3(pos[0], pos[1], pos[2])
三月三net's avatar
三月三net 已提交
61
        # self.position = Vec3(pos[0], pos[1], pos[2])
M
march3 已提交
62
        # 将摄像机的观察角度绕 x 轴旋转 45 度,绕 y 轴旋转 0 度,绕 z 轴旋转 0 度
三月三net's avatar
三月三net 已提交
63 64
        # camera.rotation = Vec3(45, 90, 0)
        camera.rotation = Vec3(0, 0, 0)
M
march3 已提交
65

三月三net's avatar
三月三net 已提交
66 67 68 69
        # self.gravity = 0
        # self.vspeed = 400
        # self.speed = 1000
        # self.mouse_sensitivity = Vec2(160, 160)
M
march3 已提交
70
        self.on_enable()
三月三net's avatar
三月三net 已提交
71
        # self.rotation_speed = 80
M
march3 已提交
72

M
march3 已提交
73 74 75 76 77 78
    def input(self, key):
        if key == "escape":
            if mouse.locked:
                self.on_disable()
            else:
                sys.exit()
M
march3 已提交
79
        return super().input(key)
M
march3 已提交
80

三月三net's avatar
三月三net 已提交
81 82

class Planet(Entity):
M
march3 已提交
83 84
    def __init__(self, body_view: BodyView):
        self.body_view = body_view
三月三net's avatar
三月三net 已提交
85
        self.rotation_speed = self.body_view.body.rotation_speed
M
march3 已提交
86 87 88
        self.rotMode = 'x'  # random.choice(["x", "y", "z"])
        self.name = body_view.name

M
march3 已提交
89
        pos = body_view.position * body_view.body.distance_scale * SCALE_FACTOR
M
march3 已提交
90 91
        scale = body_view.body.diameter * body_view.body.size_scale * SCALE_FACTOR

三月三net's avatar
三月三net 已提交
92
        subdivisions = 32  # int(scale*20)
三月三net's avatar
三月三net 已提交
93

三月三net's avatar
三月三net 已提交
94
        if hasattr(body_view, "texture"):
三月三net's avatar
三月三net 已提交
95 96 97
            texture = load_texture(body_view.texture)
        else:
            texture = None
M
march3 已提交
98

三月三net's avatar
三月三net 已提交
99
        super().__init__(
三月三net's avatar
三月三net 已提交
100 101
            # model="sphere",
            model=create_sphere(0.5, subdivisions),
三月三net's avatar
三月三net 已提交
102 103 104 105
            scale=scale,
            texture=texture,
            color=color.white,
            position=pos,
三月三net's avatar
三月三net 已提交
106 107
            rotation=(0, 0, 0),
            double_sided=True)
三月三net's avatar
三月三net 已提交
108

M
march3 已提交
109
    def turn(self):
M
march3 已提交
110
        pos = self.body_view.position * SCALE_FACTOR
三月三net's avatar
三月三net 已提交
111

M
march3 已提交
112 113 114
        self.x = -pos[1]
        self.y = pos[2]
        self.z = pos[0]
M
march3 已提交
115

三月三net's avatar
三月三net 已提交
116 117 118 119 120 121 122 123
        dt = 0
        if hasattr(self.body_view.body, "dt"):
            dt = self.body_view.body.dt
        if self.rotation_speed is None or dt == 0:
            self.rotspeed = 0
            # 旋转速度和大小成反比(未使用真实数据)
            # self.rotspeed = 30000 / self.body_view.raduis  # random.uniform(1.0, 2.0)
        else:
三月三net's avatar
三月三net 已提交
124
            # 是通过月球保持一面面对地球,调整得到
三月三net's avatar
三月三net 已提交
125
            self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR  # / 60 / 24
三月三net's avatar
三月三net 已提交
126 127
            # rotation_speed 度/小时  dt 秒 = (dt / 3600)小时

M
march3 已提交
128
        self.rotation_y -= self.rotspeed
M
march3 已提交
129

三月三net's avatar
三月三net 已提交
130 131 132
    # def input(self, key):
    #     if key == "enter":
    #         self.fastMode = 1 - self.fastMode
三月三net's avatar
三月三net 已提交
133 134 135 136 137 138 139 140 141


class UrsinaView(BodyView):
    """
    ursina天体视图(天体效果展示用)
    """

    def __init__(self, body: Body):
        BodyView.__init__(self, body)
M
march3 已提交
142 143
        self.velocity = body.velocity

M
march3 已提交
144
        self.planet = Planet(self)
M
march3 已提交
145 146 147
        if body.has_rings:
            self.create_rings()

三月三net's avatar
三月三net 已提交
148 149 150 151 152 153 154 155 156 157 158 159 160 161
    #     self.create_glow()
    #
    # def create_glow(self):
    #     # self.body.color
    #     # for i in range(1):
    #     b_color = self.body.color
    #     color = Vec4(b_color[0], b_color[1], b_color[2], 0.2)
    #         # glow_entity = Entity(parent=self.planet, model='sphere', color=color,
    #         #                      scale=math.pow(1.2, i), alpha=0.2)
    #
    #     glow_entity = Entity(parent=self.planet, model='sphere', color=color,
    #                          scale=1.01, alpha=0.1)
    #     glow_entity.set_light_off()

M
march3 已提交
162
    def create_rings(self):
三月三net's avatar
三月三net 已提交
163
        """
三月三net's avatar
三月三net 已提交
164
        创建行星环(使用土星贴图)
三月三net's avatar
三月三net 已提交
165 166
        :return:
        """
三月三net's avatar
三月三net 已提交
167 168 169 170 171 172 173 174 175
        # # # 行星环偏移角度
        # self.ring_rotation_x = 80
        # # 创建行星环
        # self.ring = Entity(parent=self.planet, model='circle', texture='../textures/saturnRings.jpg', scale=3.5,
        #                    rotation=(self.ring_rotation_x, 0, 0), double_sided=True)

        self.ring_rotation_x = 0
        torus = create_body_torus(0.3, 1, 32)
        self.ring = Entity(parent=self.planet, model=torus, texture='../textures/saturnRings.jpg', scale=1,
三月三net's avatar
三月三net 已提交
176 177
                           rotation=(self.ring_rotation_x, 0, 0), double_sided=True)

三月三net's avatar
三月三net 已提交
178

三月三net's avatar
三月三net 已提交
179
        # 设置行星环不受灯光影响,否则看不清行星环
三月三net's avatar
三月三net 已提交
180
        self.ring.set_light_off()
三月三net's avatar
三月三net 已提交
181 182

    def update(self):
三月三net's avatar
三月三net 已提交
183
        """
三月三net's avatar
三月三net 已提交
184

三月三net's avatar
三月三net 已提交
185 186 187 188
        :return:
        """
        self.planet.turn()
        # 如果有行星环
三月三net's avatar
三月三net 已提交
189
        if hasattr(self, "ring"):
三月三net's avatar
三月三net 已提交
190 191 192 193
            # 如果有行星环,则不让行星环跟随行星转动
            self.ring.rotation = -Vec3(self.planet.rotation_x - self.ring_rotation_x,
                                       self.planet.rotation_y,
                                       self.planet.rotation_z)
三月三net's avatar
三月三net 已提交
194 195 196 197 198

    def appear(self):
        pass

    def disappear(self):
M
march3 已提交
199
        self.planet.disable()