1+ using System ;
2+ using static Box2D . NET . B2MathFunction ;
3+
4+ namespace Box2D . NET . Samples ;
5+
6+ public static class Cameras
7+ {
8+ public static Camera GetDefaultCamera ( )
9+ {
10+ var camera = new Camera ( ) ;
11+ camera . center = new B2Vec2 ( 0.0f , 20.0f ) ;
12+ camera . zoom = 1.0f ;
13+ camera . width = 1920.0f ;
14+ camera . height = 1080.0f ;
15+ return camera ;
16+ }
17+
18+ public static void ResetView ( ref Camera camera )
19+ {
20+ camera . center = new B2Vec2 ( 0.0f , 20.0f ) ;
21+ camera . zoom = 1.0f ;
22+ }
23+
24+ public static B2Vec2 ConvertScreenToWorld ( ref Camera camera , B2Vec2 ps )
25+ {
26+ float w = camera . width ;
27+ float h = camera . height ;
28+ float u = ps . X / w ;
29+ float v = ( h - ps . Y ) / h ;
30+
31+ float ratio = w / h ;
32+ B2Vec2 extents = new B2Vec2 ( camera . zoom * ratio , camera . zoom ) ;
33+
34+ B2Vec2 lower = b2Sub ( camera . center , extents ) ;
35+ B2Vec2 upper = b2Add ( camera . center , extents ) ;
36+
37+ B2Vec2 pw = new B2Vec2 ( ( 1.0f - u ) * lower . X + u * upper . X , ( 1.0f - v ) * lower . Y + v * upper . Y ) ;
38+ return pw ;
39+ }
40+
41+ public static B2Vec2 ConvertWorldToScreen ( ref Camera camera , B2Vec2 pw )
42+ {
43+ float w = camera . width ;
44+ float h = camera . height ;
45+ float ratio = w / h ;
46+
47+ B2Vec2 extents = new B2Vec2 ( camera . zoom * ratio , camera . zoom ) ;
48+
49+ B2Vec2 lower = b2Sub ( camera . center , extents ) ;
50+ B2Vec2 upper = b2Add ( camera . center , extents ) ;
51+
52+ float u = ( pw . X - lower . X ) / ( upper . X - lower . X ) ;
53+ float v = ( pw . Y - lower . Y ) / ( upper . Y - lower . Y ) ;
54+
55+ B2Vec2 ps = new B2Vec2 ( u * w , ( 1.0f - v ) * h ) ;
56+ return ps ;
57+ }
58+
59+ // Convert from world coordinates to normalized device coordinates.
60+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
61+ // This also includes the view transform
62+ public static void BuildProjectionMatrix ( ref Camera camera , Span < float > m , float zBias )
63+ {
64+ float ratio = ( float ) camera . width / ( float ) camera . height ;
65+ B2Vec2 extents = new B2Vec2 ( camera . zoom * ratio , camera . zoom ) ;
66+
67+ B2Vec2 lower = b2Sub ( camera . center , extents ) ;
68+ B2Vec2 upper = b2Add ( camera . center , extents ) ;
69+ float w = upper . X - lower . X ;
70+ float h = upper . Y - lower . Y ;
71+
72+ m [ 0 ] = 2.0f / w ;
73+ m [ 1 ] = 0.0f ;
74+ m [ 2 ] = 0.0f ;
75+ m [ 3 ] = 0.0f ;
76+
77+ m [ 4 ] = 0.0f ;
78+ m [ 5 ] = 2.0f / h ;
79+ m [ 6 ] = 0.0f ;
80+ m [ 7 ] = 0.0f ;
81+
82+ m [ 8 ] = 0.0f ;
83+ m [ 9 ] = 0.0f ;
84+ m [ 10 ] = - 1.0f ;
85+ m [ 11 ] = 0.0f ;
86+
87+ m [ 12 ] = - 2.0f * camera . center . X / w ;
88+ m [ 13 ] = - 2.0f * camera . center . Y / h ;
89+ m [ 14 ] = zBias ;
90+ m [ 15 ] = 1.0f ;
91+ }
92+
93+ public static B2AABB GetViewBounds ( ref Camera camera )
94+ {
95+ if ( camera . height == 0.0f || camera . width == 0.0f )
96+ {
97+ B2AABB bounds = new B2AABB ( b2Vec2_zero , b2Vec2_zero ) ;
98+ return bounds ;
99+ }
100+
101+ {
102+ B2AABB bounds ;
103+ bounds . lowerBound = ConvertScreenToWorld ( ref camera , new B2Vec2 ( 0.0f , ( float ) camera . height ) ) ;
104+ bounds . upperBound = ConvertScreenToWorld ( ref camera , new B2Vec2 ( ( float ) camera . width , 0.0f ) ) ;
105+ return bounds ;
106+ }
107+ }
108+ }
0 commit comments