Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Can't get updated worldTransform immediately #10433

Open
tikotus opened this issue Apr 10, 2024 · 4 comments
Open

Bug: Can't get updated worldTransform immediately #10433

tikotus opened this issue Apr 10, 2024 · 4 comments
Assignees

Comments

@tikotus
Copy link

tikotus commented Apr 10, 2024

Current Behavior

After modifying a container's transform, by setting its scale, position, etc., I'm unable to calculate the new world transform immediately after the operation.

Expected Behavior

I'd expect to be able to retrieve the new world transform of the object after modifying its transform.

Steps to Reproduce

const container = app.stage.addChild(new PIXI.Container())
container.scale.set(0.5)
// TODO: Force a recalculation of the container's world transform. How?
console.log(container.worldTransform) // This currently prints a matrix that doesn't contain the scale

Environment

  • pixi.js version: 8.0.5

Possible Solution

No response

Additional Information

I understand there's performance implications, but in certain situations it is important to be able to do this. I found multiple notions about calling updateTransform, but that doesn't work, and doesn't seem to behave the same in PixiJS v8.

@GoodBoyDigital GoodBoyDigital self-assigned this Apr 29, 2024
@martin-pabst
Copy link

martin-pabst commented May 23, 2024

I have the same issue. Up to Pixijs version 6 method displayObject.parent.updateTransform followed by displayObject.transform.onChange somehow worked. Unfortunately this doesn't work in V8.
It would really be helpful if there's a proven method to get current world transform of a container immediately.

@GoodBoyDigital
Copy link
Member

hey both, sorry for the late response - curious what the use case is here?
Will have a think about the best way to implement..

@martin-pabst
Copy link

martin-pabst commented May 24, 2024

Thank you for your reply!

I teach computer science, mathematics and physics in a german high school. To help my students learning object oriented programming i developed a browser based java compiler, runtime engine and ide. I used pixi.js as graphic library. You can see it in action here
https://online-ide.de/ (use Button "Login als Testuser")
and here
https://learnj.de/

Unfortulately i haven't made an english translation yet. Click on "Login als Testuser", then choose "Mover Game" on the left side and start it (green triangle button on top of the screen) to see pixi.js in action.

In my runtime library there are classes for rectangles, circles, sprites, polygons, ..., and groups. Groups can contain other graphical objects (especially other groups) to form a tree-like structure. It is possible to add graphical objects to a group and to detach them from their group without changing their visual appearance, which means: without changing their worldtransform. To achieve this i had to really fight with pixi.js which unfortunately doesn't preserve the worldTransform when detaching children from transformed containers. It was especially hard as setting localTransform of a container doesn't immediately update worldTransform.

Another problem was collision detection. To get more acurracy than hitboxes i store a surrounding polygon ("hitPolygon") alongside each PIXI.container. To keep this in sync with container transformations whilst also retaining good performance i store only the 'initial' hitPolygons which correspond to worldTransform == identitiy. Whenever i need a hitPolygon i apply the container's worldTransform to it. This poses the problem that often worldTransforms are not up to date as pixi.js only updates them when it renders it's scene subsequently.

My workaround is to always update worldTransforms 'by hand' whenever i move/rotate/scale containers. This costs performance as it has to be done recursively (if a group is transformed) and it is redundant to pixi.js doing the same computations later when rendering the scene.

What i would need is a way to make pixi.js update an container's worldTransform matrix (and recursively the world matrices of it's subtree if it has children) whenever needed and to update it's internal dirty-flags so that this work is not done again when pixi.js renders the scene subsequently.

Another drawback of pixi.js is it's redundant system of pivot/scale/skew/rotation. I prefer to work with localTransform and it's methods to move/rotate/scale. If i need more complex operations (e.g. rotate around a given center outside the object or scale with a given center outside the object) matrix multiplications feel more comfortable than computing values for pivot/scale/skew/rotation. Unfortunately i always have to call container.setFromMatrix(this.container.localTransform) followed by container.updateLocalTransform() to make changes on localTransform take effect because pixi.js seems to need updated values of pivot/scale/skew rotation internally - which is surprising as it only needs worldTransform matrix when rendering later.

I'd appreciate it if pixi.js would make it easier to use a matrix-based approach.

@DanielLeone
Copy link

Hi - I believe I'm also running into this issue.
I'm trying to migrate pixi-essentials/transform to v8 and it's basically doing a lot of this:

displayObject.updateTransform();
decomposeTransform(displayObject.worldTransform).rotation;  // for example

which I'm thinking just isn't going to work because there's no way to force an update to world transform anymore?
(just a guess - I'm new here and just started using pixi today)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants