ursina_view.py 4.2 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
from ursina import Ursina, window, Entity, SmoothFollow, camera, color, mouse, Vec2, Vec3, load_texture, held_keys
M
march3 已提交
11 12 13 14 15
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 已提交
16 17 18 19 20 21 22
from bodies import Body
import random
from simulators.views.body_view import BodyView
import numpy as np
from math import sin, cos, radians
import os

M
march3 已提交
23
SCALE_FACTOR = 1e-7
M
march3 已提交
24 25 26


class UrsinaPlayer(FirstPersonController):
M
march3 已提交
27
    def __init__(self, position, targets=None):
M
march3 已提交
28 29 30 31
        # global planets
        super().__init__()
        # pos = planets[0].position
        camera.fov = 100
M
march3 已提交
32 33 34 35 36 37 38 39 40
        if targets is not None:
            # planets = []
            # targets = [view.planet.parent for view in targets]
            targets_parent = Entity()
            for view in targets:
                view.planet.parent = targets_parent
                # planets.append(view.planet)

            camera.add_script(SmoothFollow(targets_parent, offset=(0, 8, -20)))
M
march3 已提交
41 42
        pos = np.array(position) * SCALE_FACTOR
        self.position = Vec3(pos[0], pos[1], pos[2])
M
march3 已提交
43 44 45 46 47 48
        # 将摄像机位置设置为 x=0、y=1、z=0 的位置
        # camera.position = Vec3(pos[0], pos[1], pos[2])
        self.position = Vec3(pos[0], pos[1], pos[2])
        # 将摄像机的观察角度绕 x 轴旋转 45 度,绕 y 轴旋转 0 度,绕 z 轴旋转 0 度
        camera.rotation = Vec3(45, 90, 0)

M
march3 已提交
49
        self.gravity = 0
M
march3 已提交
50 51
        self.vspeed = 4000
        self.speed = 10000
M
march3 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
        self.mouse_sensitivity = Vec2(160, 160)
        self.on_enable()

    def input(self, key):
        if key == "escape":
            if mouse.locked:
                self.on_disable()
            else:
                sys.exit()

    def _update(self):
        # {'left mouse': 0, 'left': 0, 'left shift': 0, 'space': 1, 'w': 0, 's': 0, 'd': 0, 'a': 0, 'shift': 0})
        if held_keys["left mouse"]:
            self.on_enable()
        if held_keys["left shift"]:
            self.y -= self.vspeed
        if held_keys["space"]:
            self.y += self.vspeed

三月三net's avatar
三月三net 已提交
71 72

class Planet(Entity):
M
march3 已提交
73 74
    def __init__(self, body_view: BodyView):
        self.body_view = body_view
三月三net's avatar
三月三net 已提交
75 76 77 78
        self.angle = random.uniform(0.0005, 0.01)
        self.fastMode = 0
        self.rotation = (random.randint(0, 360) for i in range(3))
        self.rotspeed = random.uniform(0.25, 1.5)
M
march3 已提交
79 80 81 82 83 84
        self.rotMode = 'x'  # random.choice(["x", "y", "z"])
        self.name = body_view.name

        pos = body_view.position * SCALE_FACTOR
        scale = body_view.body.diameter * body_view.body.size_scale * SCALE_FACTOR

三月三net's avatar
三月三net 已提交
85 86
        # texture = eval(f"{_type}_texture")
        # e = os.path.exists(texture)
M
march3 已提交
87
        texture = load_texture(body_view.texture)
三月三net's avatar
三月三net 已提交
88 89 90 91 92 93 94
        super().__init__(model="sphere",
                         scale=scale,
                         texture=texture,
                         color=color.white,
                         position=pos)

    def turn(self, angle):
M
march3 已提交
95 96 97 98 99
        # if self.name != "sun":
        #     if self.fastMode:
        #         angle *= 200
        # self.x = self.x * cos(radians(angle)) - self.y * sin(radians(angle))
        # self.y = self.x * sin(radians(angle)) + self.y * cos(radians(angle))
M
march3 已提交
100 101 102 103
        pos = self.body_view.position * SCALE_FACTOR
        self.x = pos[0]
        self.y = pos[1]
        self.z = pos[2]
M
march3 已提交
104
        exec(f"self.rotation_{self.rotMode}+=self.rotspeed")
三月三net's avatar
三月三net 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118

    #
    def input(self, key):
        if key == "enter":
            self.fastMode = 1 - self.fastMode


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

    def __init__(self, body: Body):
        BodyView.__init__(self, body)
M
march3 已提交
119
        self.planet = Planet(self)
三月三net's avatar
三月三net 已提交
120 121

    def update(self):
M
march3 已提交
122
        self.planet.turn(self.planet.angle)
三月三net's avatar
三月三net 已提交
123 124 125 126 127

    def appear(self):
        pass

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