CenterGroupCamera!

This commit is contained in:
shenjack 2023-08-12 00:49:46 +08:00
parent 55e83b708f
commit 09e386e0fe
Signed by: shenjack
GPG Key ID: 7B1134A979775551
3 changed files with 58 additions and 33 deletions

View File

@ -6,10 +6,12 @@
from Difficult_Rocket.utils.camera import (Camera,
CenterCamera,
GroupCamera)
GroupCamera,
CenterGroupCamera)
__all__ = [
'Camera',
'CenterCamera',
'GroupCamera'
'GroupCamera',
'CenterGroupCamera'
]

View File

@ -73,6 +73,11 @@ class Camera:
def end(self) -> None:
self.window.view = self._stored_view
def reset(self):
self.zoom = 1
self.dx = 0
self.dy = 0
def __enter__(self):
self.begin()
return self
@ -104,7 +109,6 @@ class CenterCamera(Camera):
y = self.window.height / 2.0 / self.zoom + (self.dy / self.zoom)
view_matrix = view.translate((x * self.zoom, y * self.zoom, 0))
# print(f"camera translation {view_matrix}")
view_matrix = view_matrix.scale((self.zoom, self.zoom, 1))
self.window.view = view_matrix
@ -125,7 +129,9 @@ class GroupCamera(Group):
parent: Optional[Group] = None,
view_x: Optional[int] = 0,
view_y: Optional[int] = 0,
zoom: Optional[float] = 1.0, ):
zoom: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0):
super().__init__(order=order, parent=parent)
self._window = window
self._previous_view = None
@ -135,6 +141,8 @@ class GroupCamera(Group):
self._zoom = zoom
self._zoom_x = self._zoom
self._zoom_y = self._zoom
self.min_zoom = min_zoom
self.max_zoom = max_zoom
@property
def view_x(self) -> int:
@ -160,16 +168,15 @@ class GroupCamera(Group):
def zoom(self, value: float):
self._zoom = value
def reset(self):
self._view_x = 0
self._view_y = 0
self._zoom = 1
def set_state(self):
self._previous_view = self._window.view
# print(self._previous_view)
x = self._window.width / 2.0 / self._zoom_x + (self._view_x / self._zoom_x)
y = self._window.height / 2.0 / self._zoom_y + (self._view_y / self._zoom_y)
# view = Mat4.from_translation(Vec3(self._view_x * x, self._view_y * y, 0))
view = Mat4.from_translation(Vec3(self._view_x, self._view_y, 0))
# print(f"group translation {view}")
if self._zoom == 1.0:
self._window.view = view
else:
@ -178,3 +185,27 @@ class GroupCamera(Group):
def unset_state(self):
self._window.view = self._previous_view
class CenterGroupCamera(GroupCamera):
"""
A camera by group
can be used by just added to your widget
"""
def set_state(self):
self._previous_view = self._window.view
x = (self._window.width / 2) / self._zoom_x + (self._view_x / self._zoom_x)
y = (self._window.height / 2) / self._zoom_y + (self._view_y / self._zoom_y)
view = Mat4.from_translation(Vec3(x * self._zoom_x, y * self._zoom_y, 0))
# 不懂就问 为啥这里 * zoom 下面还 * zoom
if self._zoom == 1.0 and self._zoom_x == 1.0 and self._zoom_y == 1.0:
self._window.view = view
else:
view = view.scale(Vec3(self._zoom_x, self._zoom_y, 1))
self._window.view = view
def unset_state(self):
self._window.view = self._previous_view

View File

@ -10,12 +10,11 @@ import logging
import traceback
from pathlib import Path
from typing import List, TYPE_CHECKING, Union, Dict, Optional, Generator, Tuple
from typing import List, TYPE_CHECKING, Dict, Optional, Generator, Tuple
from pyglet.math import Vec4
from pyglet.text import Label
from pyglet.sprite import Sprite
# from pyglet.image import Texture
from pyglet.graphics import Batch, Group
from pyglet.shapes import Line, Rectangle
from pyglet.image import Framebuffer, Texture
@ -25,7 +24,7 @@ from . import DR_mod_runtime
# Difficult Rocket
from Difficult_Rocket import DR_status
from Difficult_Rocket.utils.translate import Tr
from Difficult_Rocket.api.camera import CenterCamera, GroupCamera
from Difficult_Rocket.api.camera import CenterCamera, CenterGroupCamera
from Difficult_Rocket.api.types import Fonts, Options
from Difficult_Rocket.command.line import CommandText
from Difficult_Rocket.client.screen import BaseScreen
@ -81,9 +80,8 @@ class SR1ShipRender(BaseScreen):
self.buffer.attach_texture(self.render_texture)
self.main_batch = Batch()
# self.group_camera = GroupCamera(window=main_window, order=10, parent=main_window.main_group)
# self.part_group = Group(0, parent=self.group_camera)
self.part_group = Group(10, parent=main_window.main_group)
self.group_camera = CenterGroupCamera(window=main_window, order=10, parent=main_window.main_group)
self.part_group = Group(0, parent=self.group_camera)
self.debug_label = Label(x=20, y=main_window.height - 100, font_size=DR_status.std_font_size,
text='SR1 render!', font_name=Fonts.微软等宽无线,
@ -284,9 +282,7 @@ class SR1ShipRender(BaseScreen):
self.render_d_line.y2 = self.camera.dy
self.buffer.bind()
window.clear()
with self.camera:
self.main_batch.draw()
# self.main_batch.draw() # use group camera, no need to with
self.main_batch.draw() # use group camera, no need to with
self.buffer.unbind()
self.render_texture.blit(x=self.dx, y=self.dy, z=0, width=self.width, height=self.height)
@ -320,24 +316,24 @@ class SR1ShipRender(BaseScreen):
mouse_dx = x - (window.width / 2)
mouse_dy = y - (window.height / 2)
# 鼠标缩放位置相对于屏幕中心的位置
mouse_dx_d = mouse_dx - self.camera.dx
mouse_dy_d = mouse_dy - self.camera.dy
mouse_dx_d = mouse_dx - self.group_camera.view_x
mouse_dy_d = mouse_dy - self.group_camera.view_y
# 鼠标相对偏移量的偏移量
if scroll_y == 0:
zoom_d = 1
else:
zoom_d = ((2 ** scroll_y) - 1) * 0.5 + 1
# 缩放的变换量
if not (self.camera.zoom == 10 and scroll_y > 0):
if self.camera.zoom * zoom_d >= 10:
zoom_d = 10 / self.camera.zoom
self.camera.zoom = 10
if not (self.group_camera.zoom == 10 and scroll_y > 0):
if self.group_camera.zoom * zoom_d >= 10:
zoom_d = 10 / self.group_camera.zoom
self.group_camera.zoom = 10
else:
self.camera.zoom *= zoom_d
self.group_camera.zoom *= zoom_d
mouse_dx_d *= (1 - zoom_d)
mouse_dy_d *= (1 - zoom_d)
self.camera.dx += mouse_dx_d
self.camera.dy += mouse_dy_d
self.group_camera.view_x += mouse_dx_d
self.group_camera.view_y += mouse_dy_d
elif self.status.moving:
# 如果是在移动整体渲染位置
size_x, size_y = self.size
@ -354,9 +350,7 @@ class SR1ShipRender(BaseScreen):
self.logger.info(f'command: {command}')
if command.find('render'):
if command.find('reset'):
self.camera.zoom = 1
self.camera.dx = 0
self.camera.dy = 0
self.group_camera.reset()
self.window_pointer.view = Vec4()
else:
self.status.draw_call = True
@ -444,8 +438,6 @@ class SR1ShipRender(BaseScreen):
def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"):
if self.status.focus:
self.camera.dx += dx
self.camera.dy += dy
self.group_camera.view_x += dx
self.group_camera.view_y += dy
self.status.update_call = True