Skip to content

Commit 49e7ffd

Browse files
committed
avm2: Move PerspectiveProjection computation to render crate
1 parent deab805 commit 49e7ffd

File tree

4 files changed

+71
-19
lines changed

4 files changed

+71
-19
lines changed

core/src/avm2/globals/flash/geom/PerspectiveProjection.as

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,6 @@ package flash.geom {
2828

2929
public native function set projectionCenter(value:Point);
3030

31-
public function toMatrix3D():Matrix3D {
32-
var fl: Number = this.focalLength;
33-
return new Matrix3D(new <Number>[
34-
fl, 0, 0, 0,
35-
0, fl, 0, 0,
36-
0, 0, 1, 1,
37-
0, 0, 0, 0
38-
]);
39-
}
31+
public native function toMatrix3D():Matrix3D;
4032
}
4133
}

core/src/avm2/globals/flash/geom/perspective_projection.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
use std::f64::consts::PI;
2-
31
use crate::avm2::error::argument_error;
4-
use crate::avm2::globals::flash::geom::transform::object_to_perspective_projection;
2+
use crate::avm2::globals::flash::geom::transform::{
3+
matrix3d_to_object, object_to_perspective_projection,
4+
};
55
use crate::avm2::globals::slots::flash_geom_perspective_projection as pp_slots;
66
use crate::avm2::globals::slots::flash_geom_point as point_slots;
77
use crate::avm2::{Activation, Error, Object, TObject, Value};
88
use crate::avm2_stub_setter;
99
use crate::display_object::TDisplayObject;
10-
11-
const DEG2RAD: f64 = PI / 180.0;
10+
use ruffle_render::perspective_projection::PerspectiveProjection;
1211

1312
fn get_width<'gc>(activation: &mut Activation<'_, 'gc>, this: Object<'gc>) -> f64 {
1413
let dobj = this
@@ -33,10 +32,9 @@ pub fn get_focal_length<'gc>(
3332
) -> Result<Value<'gc>, Error<'gc>> {
3433
let this = this.as_object().unwrap();
3534

36-
let fov = object_to_perspective_projection(this, activation)?.field_of_view;
37-
3835
let width = get_width(activation, this);
39-
let focal_length = (width / 2.0) as f32 * f64::tan((PI - fov * DEG2RAD) / 2.0) as f32;
36+
let focal_length =
37+
object_to_perspective_projection(this, activation)?.focal_length(width as f32);
4038

4139
Ok(focal_length.into())
4240
}
@@ -66,7 +64,7 @@ pub fn set_focal_length<'gc>(
6664
sync_from_display_object(activation, this)?;
6765

6866
let width = get_width(activation, this);
69-
let fov = f64::atan((width / 2.0) / focal_length) / DEG2RAD * 2.0;
67+
let fov = PerspectiveProjection::from_focal_length(focal_length, width).field_of_view;
7068
this.set_slot(pp_slots::FOV, fov.into(), activation)?;
7169

7270
sync_to_display_object(activation, this)?;
@@ -159,6 +157,19 @@ pub fn set_projection_center<'gc>(
159157
Ok(Value::Undefined)
160158
}
161159

160+
pub fn to_matrix_3d<'gc>(
161+
activation: &mut Activation<'_, 'gc>,
162+
this: Value<'gc>,
163+
_args: &[Value<'gc>],
164+
) -> Result<Value<'gc>, Error<'gc>> {
165+
let this = this.as_object().unwrap();
166+
167+
let width = get_width(activation, this);
168+
let matrix3d = object_to_perspective_projection(this, activation)?.to_matrix3d(width as f32);
169+
170+
matrix3d_to_object(matrix3d, activation)
171+
}
172+
162173
fn sync_from_display_object<'gc>(
163174
activation: &mut Activation<'_, 'gc>,
164175
this: Object<'gc>,

core/src/avm2/globals/flash/geom/transform.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ pub fn color_transform_to_object<'gc>(
211211
Ok(object)
212212
}
213213

214-
fn matrix3d_to_object<'gc>(
214+
pub fn matrix3d_to_object<'gc>(
215215
matrix: Matrix3D,
216216
activation: &mut Activation<'_, 'gc>,
217217
) -> Result<Value<'gc>, Error<'gc>> {

render/src/perspective_projection.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
use std::f64::consts::PI;
2+
3+
use crate::matrix3d::Matrix3D;
4+
15
#[derive(Copy, Clone, Debug, PartialEq)]
26
pub struct PerspectiveProjection {
37
/// Unit: degree. Must be greater than 0 and less than 180.
@@ -15,3 +19,48 @@ impl Default for PerspectiveProjection {
1519
}
1620
}
1721
}
22+
23+
impl PerspectiveProjection {
24+
const DEG2RAD: f64 = PI / 180.0;
25+
26+
pub fn from_focal_length(focal_length: f64, width: f64) -> Self {
27+
Self {
28+
field_of_view: f64::atan((width / 2.0) / focal_length) / Self::DEG2RAD * 2.0,
29+
..Default::default()
30+
}
31+
}
32+
33+
pub fn focal_length(&self, width: f32) -> f32 {
34+
let rad = self.field_of_view * Self::DEG2RAD;
35+
(width / 2.0) * f64::tan((PI - rad) / 2.0) as f32
36+
}
37+
38+
pub fn to_matrix3d(&self, width: f32) -> Matrix3D {
39+
let focal_length = self.focal_length(width) as f64;
40+
41+
Matrix3D {
42+
raw_data: [
43+
//
44+
focal_length,
45+
0.0,
46+
0.0,
47+
0.0,
48+
//
49+
0.0,
50+
focal_length,
51+
0.0,
52+
0.0,
53+
//
54+
0.0,
55+
0.0,
56+
1.0,
57+
1.0,
58+
//
59+
0.0,
60+
0.0,
61+
0.0,
62+
0.0,
63+
],
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)