Skip to content

Commit a06c5b0

Browse files
committed
avm2: Implement DisplayObject z getter/setter
They replace flash.display.DisplayObject z getter/setter stubs. The z value (z translation) is now taken into account in wgpu rendering.
1 parent ae3d5f4 commit a06c5b0

File tree

3 files changed

+58
-13
lines changed

3 files changed

+58
-13
lines changed

core/src/avm2/globals/flash/display/display_object.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,20 +413,30 @@ pub fn set_y<'gc>(
413413
}
414414

415415
pub fn get_z<'gc>(
416-
activation: &mut Activation<'_, 'gc>,
417-
_this: Value<'gc>,
416+
_activation: &mut Activation<'_, 'gc>,
417+
this: Value<'gc>,
418418
_args: &[Value<'gc>],
419419
) -> Result<Value<'gc>, Error<'gc>> {
420-
avm2_stub_getter!(activation, "flash.display.DisplayObject", "z");
421-
Ok(0.into())
420+
let this = this.as_object().unwrap();
421+
422+
if let Some(dobj) = this.as_display_object() {
423+
return Ok(dobj.z().into());
424+
}
425+
Ok(Value::Undefined)
422426
}
423427

424428
pub fn set_z<'gc>(
425429
activation: &mut Activation<'_, 'gc>,
426-
_this: Value<'gc>,
427-
_args: &[Value<'gc>],
430+
this: Value<'gc>,
431+
args: &[Value<'gc>],
428432
) -> Result<Value<'gc>, Error<'gc>> {
429-
avm2_stub_setter!(activation, "flash.display.DisplayObject", "z");
433+
let this = this.as_object().unwrap();
434+
435+
if let Some(dobj) = this.as_display_object() {
436+
let z = args.get_f64(activation, 0)?;
437+
dobj.set_z(activation.gc(), z);
438+
dobj.base_mut(activation.gc()).set_has_matrix3d_stub(true);
439+
}
430440
Ok(Value::Undefined)
431441
}
432442

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ pub fn get_matrix_3d<'gc>(
339339
let display_object = get_display_object(this);
340340
if display_object.base().has_matrix3d_stub() {
341341
let matrix = *get_display_object(this).base().matrix();
342-
let matrix3d = Matrix3D::from(matrix);
342+
let mut matrix3d = Matrix3D::from(matrix);
343+
matrix3d.set_tz(display_object.z());
343344
matrix3d_to_object(matrix3d, activation)
344345
} else {
345346
Ok(Value::Null)
@@ -359,19 +360,19 @@ pub fn set_matrix_3d<'gc>(
359360

360361
let display_object = get_display_object(this);
361362

362-
let (matrix, has_matrix3d) = {
363+
let (matrix, has_matrix3d, tz) = {
363364
match args.try_get_object(activation, 0) {
364365
Some(obj) => {
365366
let matrix3d = object_to_matrix3d(obj, activation)?;
366367
let matrix = Matrix::from(matrix3d);
367368
let tz = matrix3d.tz();
368-
display_object.base_mut(activation.gc()).set_tz(tz);
369-
(matrix, true)
369+
(matrix, true, tz)
370370
}
371-
None => (Matrix::IDENTITY, false),
371+
None => (Matrix::IDENTITY, false, 0.0),
372372
}
373373
};
374374

375+
display_object.base_mut(activation.gc()).set_matrix_tz(tz);
375376
display_object.set_matrix(activation.gc(), matrix);
376377
if let Some(parent) = display_object.parent() {
377378
// Self-transform changes are automatically handled,

core/src/display_object.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,11 @@ impl<'gc> DisplayObjectBase<'gc> {
336336
&mut self.transform.matrix
337337
}
338338

339-
pub fn set_tz(&mut self, tz: f64) {
339+
pub fn matrix_tz(&mut self) -> f64 {
340+
self.transform.tz
341+
}
342+
343+
pub fn set_matrix_tz(&mut self, tz: f64) {
340344
self.transform.tz = tz;
341345
}
342346

@@ -379,6 +383,17 @@ impl<'gc> DisplayObjectBase<'gc> {
379383
changed
380384
}
381385

386+
fn z(&self) -> f64 {
387+
self.transform.tz
388+
}
389+
390+
fn set_z(&mut self, tz: f64) -> bool {
391+
let changed = self.matrix_tz() != tz;
392+
self.set_transformed_by_script(true);
393+
self.set_matrix_tz(tz);
394+
changed
395+
}
396+
382397
/// Caches the scale and rotation factors for this display object, if necessary.
383398
/// Calculating these requires heavy trig ops, so we only do it when `_xscale`, `_yscale` or
384399
/// `_rotation` is accessed.
@@ -1380,6 +1395,25 @@ pub trait TDisplayObject<'gc>:
13801395
}
13811396
}
13821397

1398+
/// The `z` position in local space.
1399+
/// Returned by the `z` ActionScript properties.
1400+
fn z(&self) -> f64 {
1401+
self.base().z()
1402+
}
1403+
1404+
/// Sets the `z` position of this display object in local space.
1405+
/// Set by the `z` ActionScript properties.
1406+
/// This invalidates any ancestors cacheAsBitmap automatically.
1407+
fn set_z(&self, gc_context: &Mutation<'gc>, z: f64) {
1408+
if self.base_mut(gc_context).set_z(z) {
1409+
if let Some(parent) = self.parent() {
1410+
// Self-transform changes are automatically handled,
1411+
// we only want to inform ancestors to avoid unnecessary invalidations for tx/ty
1412+
parent.invalidate_cached_bitmap(gc_context);
1413+
}
1414+
}
1415+
}
1416+
13831417
/// The rotation in degrees this display object in local space.
13841418
/// Returned by the `_rotation`/`rotation` ActionScript properties.
13851419
fn rotation(&self, gc_context: &Mutation<'gc>) -> Degrees {

0 commit comments

Comments
 (0)