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

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

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

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

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

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

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

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

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

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

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

三月三net's avatar
三月三net 已提交
115 116 117 118 119 120 121 122
        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 已提交
123
            # 是通过月球保持一面面对地球,调整得到
三月三net's avatar
三月三net 已提交
124
            self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR  # / 60 / 24
三月三net's avatar
三月三net 已提交
125 126
            # rotation_speed 度/小时  dt 秒 = (dt / 3600)小时

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

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


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

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

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

三月三net's avatar
三月三net 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160
    #     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 已提交
161
    def create_rings(self):
三月三net's avatar
三月三net 已提交
162
        """
三月三net's avatar
三月三net 已提交
163
        创建行星环(使用土星贴图)
三月三net's avatar
三月三net 已提交
164 165
        :return:
        """
三月三net's avatar
三月三net 已提交
166
        # 行星环偏移角度
三月三net's avatar
三月三net 已提交
167
        # self.ring_rotation_x = 80
三月三net's avatar
三月三net 已提交
168
        # 创建行星环
三月三net's avatar
三月三net 已提交
169 170 171
        # 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)

三月三net's avatar
三月三net 已提交
172
        # 行星环偏移角度
三月三net's avatar
三月三net 已提交
173
        self.ring_rotation_x = 0
三月三net's avatar
三月三net 已提交
174 175
        # 创建行星环
        torus = create_body_torus(0.3, 1, 64)
三月三net's avatar
三月三net 已提交
176
        self.ring = Entity(parent=self.planet, model=torus, texture='../textures/saturnRings.jpg', scale=1,
三月三net's avatar
三月三net 已提交
177 178 179
                           rotation=(self.ring_rotation_x, 0, 0), double_sided=True)

        # 设置行星环不受灯光影响,否则看不清行星环
三月三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()