示例#1
0
    def _create_earth(self, entity: Entity, texture: str) -> \
            vpython.sphere:
        ground = vpython.sphere(
            pos=vpython.vector(0, 0, 0),
            axis=calc.angle_to_vpy(entity.heading),
            up=vpython.vector(0, 0, 1),
            # So the planet doesn't intersect the landing graphic
            radius=entity.r * 0.9,
            make_trail=True,
            retain=10000,
            texture=texture,
            bumpmap=vpython.bumpmaps.gravel,
            shininess=0.3  # Planet.SHININESS=0.3
        )
        clouds_texture = texture.replace(f'{entity.name}.jpg', 'Clouds.png')
        clouds_bumpmap = texture.replace('Clouds.png', 'Clouds-bumpmap.png')
        if entity.atmosphere_thickness is not None:
            clouds_radius = entity.r * entity.atmosphere_thickness * 0.9
        else:
            clouds_radius = entity.r * 1.28 * 0.9
        ground.clouds = vpython.sphere(
            pos=ground.pos,
            axis=ground.axis,
            up=ground.up,
            radius=clouds_radius,
            texture=clouds_texture,
            bumpmap=clouds_bumpmap,
            opacity=0.1,  # Cloud layer mostly transparent
            shininess=0.1)

        return ground
示例#2
0
    def _update_obj(self, entity: Entity,
                    state: PhysicsState, origin: Entity) -> None:
        # update planet objects
        self._obj.pos = entity.screen_pos(origin) / self._scale_factor
        self._obj.axis = calc.angle_to_vpy(entity.heading)

        # update label objects
        self._label.text = self._label_text(entity)
        self._label.pos = entity.screen_pos(origin) / self._scale_factor
示例#3
0
 def _create_obj(self, entity: Entity, origin: Entity,
                 texture: Optional[str]) -> vpython.sphere:
     return vpython.sphere(pos=entity.screen_pos(origin),
                           axis=calc.angle_to_vpy(entity.heading),
                           up=DEFAULT_UP,
                           forward=DEFAULT_FORWARD,
                           radius=entity.r,
                           make_trail=True,
                           retain=10000,
                           texture=texture,
                           bumpmap=vpython.bumpmaps.gravel,
                           shininess=Planet.SHININIESS)
示例#4
0
 def _create_obj(self, entity: Entity, origin: Entity,
                 texture: Optional[str]) -> vpython.sphere:
     return vpython.sphere(
         pos=entity.screen_pos(origin),
         axis=calc.angle_to_vpy(entity.heading),
         up=vpython.vector(0, 0, 1),
         # So the planet doesn't intersect the landing graphic
         radius=entity.r * 0.9,
         make_trail=True,
         retain=10000,
         texture=texture,
         bumpmap=vpython.bumpmaps.gravel,
         shininess=Planet.SHININIESS)
示例#5
0
    def _update_obj(self, entity: Entity, state: PhysicsState,
                    origin: Entity) -> None:
        # update planet objects
        self._obj.pos = entity.screen_pos(origin)
        self._obj.axis = calc.angle_to_vpy(entity.heading)

        # update label objects
        self._label.text = self._label_text(entity)
        self._label.pos = entity.screen_pos(origin)
        # update landing graphic objects
        self._update_landing_graphic(self._small_landing_graphic, entity,
                                     state.craft_entity())
        self._update_landing_graphic(self._large_landing_graphic, entity,
                                     state.craft_entity())
示例#6
0
    def _create_obj(self, entity: Entity, origin: Entity,
                    texture: Optional[str]) -> vpython.sphere:
        main_body = vpython.box()
        side_panels = vpython.box(height=2, width=0.5, length=0.6)
        obj = vpython.compound([main_body, side_panels],
                               make_trail=True,
                               texture=texture,
                               bumpmap=vpython.textures.gravel)
        obj.pos = entity.screen_pos(origin)
        obj.axis = calc.angle_to_vpy(entity.heading)
        obj.length = entity.r * 2
        obj.height = entity.r * 2
        obj.width = entity.r * 2

        # A compound object doesn't actually have a radius, but we need to
        # monkey-patch this for when we recentre the camera, to determine the
        # relevant_range of the space station
        obj.radius = entity.r
        return obj
示例#7
0
    def _create_obj(self, entity: Entity, origin: Entity,
                    texture_path: Optional[str]) -> vpython.sphere:
        ship = vpython.cone(pos=vpython.vector(5, 0, 0),
                            axis=vpython.vector(5, 0, 0),
                            radius=3)
        entrance = vpython.extrusion(
            path=[vpython.vec(0, 0, 0),
                  vpython.vec(4, 0, 0)],
            shape=[
                vpython.shapes.circle(radius=3),
                vpython.shapes.rectangle(pos=[0, 0], width=0.5, height=0.5)
            ],
            pos=vpython.vec(3, 0, 0))

        docking_arm = vpython.extrusion(
            path=[
                vpython.vec(0, 0, 0),
                vpython.vec(1.5, 0, 0),
                vpython.vec(1.5, 0.5, 0)
            ],
            shape=[vpython.shapes.circle(radius=0.03)])

        obj = vpython.compound([ship, entrance, docking_arm],
                               make_trail=True,
                               texture=vpython.textures.metal,
                               bumpmap=vpython.bumpmaps.gravel)
        obj.pos = entity.screen_pos(origin)
        obj.axis = calc.angle_to_vpy(entity.heading)
        obj.length = entity.r * 2
        obj.height = entity.r * 2
        obj.width = entity.r * 2

        # A compound object doesn't actually have a radius, but we need to
        # monkey-patch this for when we recentre the camera, to determine the
        # relevant_range of the space station
        obj.radius = entity.r

        return obj
示例#8
0
文件: habitat.py 项目: OCESS/orbitx
    def _create_hab(self, entity: Entity, texture: str) -> \
            vpython.compound:
        def vertex(x: float, y: float, z: float) -> vpython.vertex:
            return vpython.vertex(pos=vpython.vector(x, y, z))

        # See the docstring of ThreeDeeObj._create_obj for why the dimensions
        # that define the shape of the habitat will not actually directly
        # translate to world-space.

        body = vpython.cylinder(pos=vpython.vec(0, 0, 0),
                                axis=vpython.vec(-5, 0, 0),
                                radius=10)
        head = vpython.cone(pos=vpython.vec(0, 0, 0),
                            axis=vpython.vec(2, 0, 0),
                            radius=10)
        wing = vpython.triangle(v0=vertex(0, 0, 0),
                                v1=vertex(-5, 30, 0),
                                v2=vertex(-5, -30, 0))
        wing2 = vpython.triangle(v0=vertex(0, 0, 0),
                                 v1=vertex(-5, 0, 30),
                                 v2=vertex(-5, 0, -30))

        hab = vpython.compound([body, head, wing, wing2],
                               make_trail=True,
                               texture=texture)
        hab.axis = calc.angle_to_vpy(entity.heading)
        hab.radius = entity.r / 2
        hab.shininess = 0.1
        hab.length = entity.r * 2

        boosters: List[vpython.cylinder] = []
        body_radius = entity.r / 8
        for quadrant in range(0, 4):
            # Generate four SRB bodies.
            normal = vpython.rotate(vpython.vector(0, 1, 1).hat,
                                    angle=quadrant * vpython.radians(90),
                                    axis=vpython.vector(1, 0, 0))
            boosters.append(
                vpython.cylinder(radius=self.BOOSTER_RADIUS,
                                 pos=(self.BOOSTER_RADIUS + body_radius) *
                                 normal))
            boosters.append(
                vpython.cone(
                    radius=self.BOOSTER_RADIUS,
                    length=0.2,
                    pos=((self.BOOSTER_RADIUS + body_radius) * normal +
                         vpython.vec(1, 0, 0))))

        # Append an invisible point to shift the boosters down the fuselage.
        # For an explanation of why that matters, read the
        # ThreeDeeObj._create_obj docstring (and if that doesn't make sense,
        # get in touch with Patrick M please hello hi I'm always free!)
        boosters.append(vpython.sphere(opacity=0, pos=vpython.vec(1.2, 0, 0)))
        booster_texture = texture.replace(f'{entity.name}.jpg', 'SRB.jpg')
        hab.boosters = vpython.compound(boosters, texture=booster_texture)
        hab.boosters.length = entity.r * 2
        hab.boosters.axis = hab.axis

        parachute: List[vpython.standardAttributes] = []
        string_length = entity.r * 0.5
        parachute_texture = texture.replace(f'{entity.name}.jpg',
                                            'Parachute.jpg')
        # Build the parachute fabric.
        parachute.append(
            vpython.extrusion(
                path=vpython.paths.circle(radius=0.5, up=vpython.vec(-1, 0,
                                                                     0)),
                shape=vpython.shapes.arc(angle1=vpython.radians(5),
                                         angle2=vpython.radians(95),
                                         radius=1),
                pos=vpython.vec(string_length + self.PARACHUTE_RADIUS / 2, 0,
                                0)))
        parachute[0].height = self.PARACHUTE_RADIUS * 2
        parachute[0].width = self.PARACHUTE_RADIUS * 2
        parachute[0].length = self.PARACHUTE_RADIUS
        for quadrant in range(0, 4):
            # Generate parachute attachment lines.
            string = vpython.cylinder(axis=vpython.vec(string_length,
                                                       self.PARACHUTE_RADIUS,
                                                       0),
                                      radius=0.2)
            string.rotate(angle=(quadrant * vpython.radians(90) -
                                 vpython.radians(45)),
                          axis=vpython.vector(1, 0, 0))
            parachute.append(string)
        parachute.append(
            vpython.sphere(opacity=0,
                           pos=vpython.vec(
                               -(string_length + self.PARACHUTE_RADIUS), 0,
                               0)))
        hab.parachute = vpython.compound(parachute, texture=parachute_texture)
        hab.parachute.visible = False

        return hab
示例#9
0
文件: habitat.py 项目: OCESS/orbitx
    def _update_obj(self, entity: Entity, state: PhysicsState, origin: Entity):
        super()._update_obj(entity, state, origin)
        self._obj.boosters.pos = self._obj.pos
        self._obj.boosters.axis = self._obj.axis
        # Attach the parachute to the forward cone of the habitat.
        self._obj.parachute.pos = (
            self._obj.pos + calc.angle_to_vpy(entity.heading) * entity.r * 0.8)

        parachute_is_visible = ((state.craft == entity.name)
                                and state.parachute_deployed)
        if parachute_is_visible:
            drag = calc.drag(state)
            drag_mag = np.inner(drag, drag)
        for parachute in [self._obj.parachute, self._small_habitat.parachute]:
            if not parachute_is_visible or drag_mag < 0.00001:
                # If parachute_is_visible == False, don't show the parachute.
                # If the drag is basically zero, don't show the parachute.
                parachute.visible = False
                continue

            if drag_mag > 0.1:
                parachute.width = self.PARACHUTE_RADIUS * 2
                parachute.height = self.PARACHUTE_RADIUS * 2
            else:
                # Below a certain threshold the parachute deflates.
                parachute.width = self.PARACHUTE_RADIUS
                parachute.height = self.PARACHUTE_RADIUS

            parachute.axis = -vpython.vec(*drag, 0)
            parachute.visible = True

        if not self._broken and entity.broken:
            # We weren't broken before, but looking at new data we realize
            # we're now broken. Change the habitat texture.
            new_texture = self._obj.texture.replace('Habitat.jpg',
                                                    'Habitat-broken.jpg')
            assert new_texture != self._obj.texture, \
                f'{new_texture!r} == {self._obj.texture!r}'
            self._obj.texture = new_texture
            self._small_habitat.texture = new_texture
            self._broken = entity.broken
        elif self._broken and not entity.broken:
            # We were broken before, but we've repaired ourselves somehow.
            new_texture = self._obj.texture.replace('Habitat-broken.jpg',
                                                    'Habitat.jpg')
            assert new_texture != self._obj.texture, \
                f'{new_texture!r} == {self._obj.texture!r}'
            self._obj.texture = new_texture
            self._small_habitat.texture = new_texture
            self._broken = entity.broken

        # Set reference and target arrows of the minimap habitat.
        same = state.reference == entity.name
        default = vpython.vector(0, 0, -1)

        ref_arrow_axis = (entity.screen_pos(state.reference_entity()).norm() *
                          entity.r * -1.2)
        v = entity.v - state.reference_entity().v
        velocity_arrow_axis = \
            vpython.vector(*v, 0).norm() * entity.r

        self._ref_arrow.axis = default if same else ref_arrow_axis
        self._velocity_arrow.axis = default if same else velocity_arrow_axis
        self._small_habitat.axis = self._obj.axis
        self._small_habitat.boosters.axis = self._obj.axis

        # Invisible-ize the SRBs if we ran out.
        if state.srb_time == common.SRB_EMPTY and self._obj.boosters.visible:
            self._obj.boosters.visible = False
            self._small_habitat.boosters.visible = False
示例#10
0
 def _update_obj(self, entity: Entity,
                 state: PhysicsState, origin: Entity):
     super()._update_obj(entity, state, origin)
     self._obj.clouds.pos = self._obj.pos
     self._obj.clouds.axis = calc.angle_to_vpy(
         entity.heading * calc.windspeed_multiplier(entity, windspeed=100))