@@ -103,3 +103,77 @@ pub fn get_zoom_factor(source_size: (u32, u32), target_size: (u32, u32)) -> (f32
103103 ( target_size. 0 / source_size. 0 , 0.0 , 0.0 )
104104 }
105105}
106+
107+ // Calculation is based on https://github.com/jabbany/CommentCoreLibrary/issues/5#issuecomment-40087282
108+ // and https://github.com/m13253/danmaku2ass/issues/7#issuecomment-41489422
109+ // ASS FOV = width*4/3.0
110+ // But Flash FOV = width/math.tan(100*math.pi/360.0)/2 will be used instead
111+ // Result: (trans_x, trans_y, rot_x, rot_y, rot_z, scale_x, scale_y)
112+ pub fn convert_flash_rotation (
113+ rot_y : f64 ,
114+ rot_z : f64 ,
115+ x : f64 ,
116+ y : f64 ,
117+ width : f64 ,
118+ height : f64 ,
119+ ) -> ( f64 , f64 , f64 , f64 , f64 , f64 , f64 ) {
120+ let wrap_angle = |deg : f64 | -> f64 { 180.0 - ( ( 180.0 - deg) . rem_euclid ( 360.0 ) ) } ;
121+ let mut rot_y = wrap_angle ( rot_y) ;
122+ let rot_z = wrap_angle ( rot_z) ;
123+ let pi_angle = std:: f64:: consts:: PI / 180.0 ;
124+ if rot_y == 90.0 || rot_y == -90.0 {
125+ rot_y -= 1.0 ;
126+ }
127+ let ( out_x, out_y, out_z, rot_y, rot_z) = if rot_y == 0. || rot_z == 0. {
128+ let out_x = 0. ;
129+ let out_y = -rot_y; // Positive value means clockwise in Flash
130+ let out_z = -rot_z;
131+ let rot_y_rad = rot_y * pi_angle;
132+ let rot_z_rad = rot_z * pi_angle;
133+ ( out_x, out_y, out_z, rot_y_rad, rot_z_rad)
134+ } else {
135+ let rot_y_rad = rot_y * pi_angle;
136+ let rot_z_rad = rot_z * pi_angle;
137+ let out_y = ( -rot_y_rad. sin ( ) * rot_z_rad. cos ( ) ) . atan2 ( rot_y_rad. cos ( ) ) / pi_angle;
138+ let out_z = ( -rot_y_rad. cos ( ) * rot_z_rad. sin ( ) ) . atan2 ( rot_z_rad. cos ( ) ) / pi_angle;
139+ let out_x = ( rot_y_rad. sin ( ) * rot_z_rad. sin ( ) ) . asin ( ) / pi_angle;
140+ ( out_x, out_y, out_z, rot_y_rad, rot_z_rad)
141+ } ;
142+ let trans_x = ( x * rot_z. cos ( ) + y * rot_z. sin ( ) ) / rot_y. cos ( )
143+ + ( 1.0 - rot_z. cos ( ) / rot_y. cos ( ) ) * width / 2.0
144+ - rot_z. sin ( ) / rot_y. cos ( ) * height / 2.0 ;
145+ let trans_y = y * rot_z. cos ( ) - x * rot_z. sin ( )
146+ + rot_z. sin ( ) * width / 2.0
147+ + ( 1.0 - rot_z. cos ( ) ) * height / 2.0 ;
148+ let trans_z = ( trans_x - width / 2.0 ) * rot_y. sin ( ) ;
149+ let fov = width * ( 2.0 * std:: f64:: consts:: PI / 9.0 ) . tan ( ) / 2.0 ;
150+ let scale_xy = if fov + trans_z != 0.0 {
151+ fov / ( fov + trans_z)
152+ } else {
153+ // eprintln!(
154+ // "Rotation makes object behind the camera: trZ == {:.0}",
155+ // trans_z
156+ // );
157+ 1.
158+ } ;
159+ let trans_x = ( trans_x - width / 2.0 ) * scale_xy + width / 2.0 ;
160+ let trans_y = ( trans_y - height / 2.0 ) * scale_xy + height / 2.0 ;
161+ let ( scale_xy, out_x, out_y) = if scale_xy < 0. {
162+ // eprintln!(
163+ // "Rotation makes object behind the camera: trZ == {:.0} < {:.0}",
164+ // trans_z, fov
165+ // );
166+ ( -scale_xy, out_x + 180. , out_y + 180. )
167+ } else {
168+ ( scale_xy, out_x, out_y)
169+ } ;
170+ (
171+ trans_x,
172+ trans_y,
173+ wrap_angle ( out_x) ,
174+ wrap_angle ( out_y) ,
175+ wrap_angle ( out_z) ,
176+ scale_xy * 100. ,
177+ scale_xy * 100. ,
178+ )
179+ }
0 commit comments