ursina_view.py 5.4 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
M
march3 已提交
10 11 12 13
from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, time, camera, color, mouse, Vec2, Vec3, \
    load_texture, held_keys

# from ursina.camera import OrthographicCamera
M
march3 已提交
14 15 16 17 18
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 已提交
19 20 21 22
from bodies import Body
import random
from simulators.views.body_view import BodyView
import numpy as np
M
march3 已提交
23
import math
三月三net's avatar
三月三net 已提交
24

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


三月三net's avatar
三月三net 已提交
31 32
class UrsinaPlayer(FirstPersonController):
    """
M
march3 已提交
33

三月三net's avatar
三月三net 已提交
34
    """
M
march3 已提交
35

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

三月三net's avatar
三月三net 已提交
60 61 62 63
        # self.gravity = 0
        # self.vspeed = 400
        # self.speed = 1000
        # self.mouse_sensitivity = Vec2(160, 160)
M
march3 已提交
64
        self.on_enable()
三月三net's avatar
三月三net 已提交
65
        # self.rotation_speed = 80
M
march3 已提交
66

M
march3 已提交
67 68 69 70 71 72
    def input(self, key):
        if key == "escape":
            if mouse.locked:
                self.on_disable()
            else:
                sys.exit()
M
march3 已提交
73
        return super().input(key)
M
march3 已提交
74

三月三net's avatar
三月三net 已提交
75 76

class Planet(Entity):
M
march3 已提交
77 78
    def __init__(self, body_view: BodyView):
        self.body_view = body_view
三月三net's avatar
三月三net 已提交
79
        self.rotation_speed = self.body_view.body.rotation_speed
M
march3 已提交
80 81 82
        self.rotMode = 'x'  # random.choice(["x", "y", "z"])
        self.name = body_view.name

M
march3 已提交
83
        pos = body_view.position * body_view.body.distance_scale * SCALE_FACTOR
M
march3 已提交
84 85
        scale = body_view.body.diameter * body_view.body.size_scale * SCALE_FACTOR

三月三net's avatar
三月三net 已提交
86
        if hasattr(body_view, "texture"):
三月三net's avatar
三月三net 已提交
87 88 89
            texture = load_texture(body_view.texture)
        else:
            texture = None
M
march3 已提交
90

三月三net's avatar
三月三net 已提交
91 92 93 94 95 96 97
        super().__init__(
            model="sphere",
            scale=scale,
            texture=texture,
            color=color.white,
            position=pos,
            rotation=(0, 0, 0))
三月三net's avatar
三月三net 已提交
98

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

M
march3 已提交
102 103 104
        self.x = -pos[1]
        self.y = pos[2]
        self.z = pos[0]
M
march3 已提交
105

三月三net's avatar
三月三net 已提交
106 107 108 109 110 111 112 113
        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 已提交
114 115
            # 是通过月球保持一面面对地球,调整得到
            self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR # / 60 / 24
三月三net's avatar
三月三net 已提交
116 117
            # rotation_speed 度/小时  dt 秒 = (dt / 3600)小时

M
march3 已提交
118
        self.rotation_y -= self.rotspeed
M
march3 已提交
119

三月三net's avatar
三月三net 已提交
120 121 122
    # def input(self, key):
    #     if key == "enter":
    #         self.fastMode = 1 - self.fastMode
三月三net's avatar
三月三net 已提交
123 124 125 126 127 128 129 130 131


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

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

M
march3 已提交
134
        self.planet = Planet(self)
M
march3 已提交
135 136 137 138
        if body.has_rings:
            self.create_rings()

    def create_rings(self):
三月三net's avatar
三月三net 已提交
139
        """
三月三net's avatar
三月三net 已提交
140
        创建行星环(使用土星贴图)
三月三net's avatar
三月三net 已提交
141 142
        :return:
        """
三月三net's avatar
三月三net 已提交
143 144 145 146 147 148 149
        # 行星环偏移角度
        self.ring_rotation_x = 70
        # 创建行星环
        self.ring = Entity(parent=self.planet, model="circle", texture='../textures/saturnRings.jpg', scale=2,
                           rotation=(self.ring_rotation_x, 0, 0), double_sided=True)

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

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

三月三net's avatar
三月三net 已提交
155 156 157 158
        :return:
        """
        self.planet.turn()
        # 如果有行星环
三月三net's avatar
三月三net 已提交
159
        if hasattr(self, "ring"):
三月三net's avatar
三月三net 已提交
160 161 162 163
            # 如果有行星环,则不让行星环跟随行星转动
            self.ring.rotation = -Vec3(self.planet.rotation_x - self.ring_rotation_x,
                                       self.planet.rotation_y,
                                       self.planet.rotation_z)
三月三net's avatar
三月三net 已提交
164 165 166 167 168

    def appear(self):
        pass

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