11mod camera;
2+ mod context;
3+ mod render_context;
4+ mod structs;
25
36use camera:: Camera ;
7+ use context:: StageContext ;
48use eframe:: egui:: { self } ;
5- use egui:: Pos2 ;
6- use nanoid:: nanoid;
7- use rand:: Rng ;
9+ use structs:: EntityTrait ;
810
9- use crate :: structs :: { StageObject , TextNode } ;
11+ use crate :: stage :: render_context :: RenderContext ;
1012
1113/// egui 和画布之间的桥梁
1214/// 负责坐标系转换、事件处理等
1315pub struct Stage {
1416 camera : Camera ,
15- items : Vec < Box < dyn StageObject > > ,
17+ context : StageContext ,
1618}
1719
1820impl Stage {
1921 pub fn new ( ) -> Self {
20- let mut rng = rand:: rng ( ) ;
21- let mut items = Vec :: < Box < dyn StageObject > > :: new ( ) ;
22- for _ in 0 ..5 {
23- let pos = Pos2 :: new (
24- rng. random_range ( -500.0 ..500.0 ) ,
25- rng. random_range ( -500.0 ..500.0 ) ,
26- ) ;
27-
28- items. push ( Box :: new ( TextNode {
29- id : nanoid ! ( ) ,
30- position : pos,
31- content : "Hello, World!" . to_string ( ) ,
32- } ) )
33- }
34-
3522 Stage {
3623 camera : Camera :: new ( ) ,
37- items ,
24+ context : StageContext :: random ( ) ,
3825 }
3926 }
4027
@@ -52,30 +39,16 @@ impl Stage {
5239 let screen_center = rect. center ( ) ;
5340 let mut visible_count = 0 ;
5441
55- for item in & self . items {
56- let screen_pos = self . camera . world_to_screen (
57- item. as_any ( ) . downcast_ref :: < TextNode > ( ) . unwrap ( ) . position ,
58- screen_center,
59- ) ;
60-
61- // 简单的视锥剔除 (Frustum Culling)
62- // 扩大一点范围以免边缘物体突然消失
63- // if !ui.clip_rect().expand(100.0).contains(screen_pos_egui) {
64- // continue;
65- // }
66-
42+ for entity in self . context . entities ( ) . values ( ) {
6743 visible_count += 1 ;
68-
69- ui. push_id ( item. id ( ) , |ui| {
70- ui. with_visual_transform (
71- egui:: emath:: TSTransform {
72- translation : screen_pos. to_vec2 ( ) ,
73- scaling : self . camera . zoom ( ) ,
74- } ,
75- |ui| {
76- item. render ( ui) ;
77- } ,
78- ) ;
44+ let screen_pos = self
45+ . camera
46+ . world_to_screen ( entity. position ( ) , screen_center) ;
47+
48+ entity. render ( & mut RenderContext {
49+ painter : painter. clone ( ) ,
50+ position : screen_pos,
51+ scale : self . camera . zoom ( ) ,
7952 } ) ;
8053 }
8154
@@ -90,22 +63,20 @@ impl Stage {
9063
9164 let scroll_delta = ui. input ( |i| i. smooth_scroll_delta ) ;
9265 if scroll_delta. y != 0.0 {
93- let zoom_factor = ( 1.0 + scroll_delta. y * 0.01 ) . clamp ( 0.9 , 1.1 ) ;
94-
9566 if let Some ( mouse_pos) = ui. input ( |i| i. pointer . hover_pos ( ) ) {
67+ let zoom_factor = ( 1.0 + scroll_delta. y * 0.01 ) . clamp ( 0.9 , 1.1 ) ;
9668 let old_zoom = self . camera . zoom ( ) ;
97- let new_zoom = old_zoom * zoom_factor;
69+ self . camera . zoom_by ( zoom_factor) ;
70+
9871 let offset = mouse_pos - rect. center ( ) ;
99- let delta = offset * ( 1.0 / old_zoom - 1.0 / new_zoom ) ;
72+ let delta = offset * ( self . camera . zoom ( ) / old_zoom - 1.0 ) ;
10073 self . camera . pan_by ( delta) ;
10174 }
102-
103- self . camera . zoom_by ( zoom_factor) ;
10475 }
10576
10677 // 中键拖拽平移
10778 if response. dragged_by ( egui:: PointerButton :: Middle ) {
108- let drag_delta = ui. input ( |i| i. pointer . delta ( ) ) / self . camera . zoom ( ) ;
79+ let drag_delta = ui. input ( |i| i. pointer . delta ( ) ) ;
10980 self . camera . pan_by ( -drag_delta) ;
11081 }
11182 }
0 commit comments