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

Camera translations #46

Closed
djlastnight opened this issue Sep 9, 2021 · 10 comments
Closed

Camera translations #46

djlastnight opened this issue Sep 9, 2021 · 10 comments

Comments

@djlastnight
Copy link

Hey, thank you for this extremely cool api. After 5 days head banging, I found that I need to take into account the pixi's renderer resolution in order to make the camera coord conversion to work as it should.
Here are the wrapped methods (I am not sure 100% about the z values, because I do not need z at all in my app).

public static toWorld(
        container: Container,
        anchor: Point,
        model: Model
    ): ObservablePoint3D {
        let bounds = container.getBounds();
        let x = bounds.x + anchor.x * bounds.width;
        let y = bounds.y + anchor.y * bounds.height;
        return this.screenToWorld(x, y, model);
    }

    public static screenToWorld(
        x: number,
        y: number,
        model: Model
    ): ObservablePoint3D {
        let worldCoordinates = Camera.main.screenToWorld(
            x,
            y,
            Camera.main.z - model.z,
            undefined,
            {
                width:
                    App.instance.renderer.width /
                    App.instance.renderer.resolution,
                height:
                    App.instance.renderer.height /
                    App.instance.renderer.resolution,
            }
        );

        return worldCoordinates;
    }

    public static worldToScreen(
        x: number,
        y: number,
        z: number = Camera.main.z
    ): Point {
        let worldCoordinates = Camera.main.worldToScreen(x, y, z, undefined, {
            width:
                App.instance.renderer.width / App.instance.renderer.resolution,
            height:
                App.instance.renderer.height / App.instance.renderer.resolution,
        });

        return worldCoordinates;
    }

I hope this helps and it will save time to someone using your api.

Thanks,
Ivan

@jnsmalm
Copy link
Owner

jnsmalm commented Sep 10, 2021

Hey, thanks for this! Is the standard methods worldToScreen/screenToWorld not working when resolution is above 1?

@djlastnight
Copy link
Author

djlastnight commented Sep 10, 2021

Yes, the standard methods works only for resolution 1, that's why I am sending you the solution.

The easiest way to replicate the bug is to zoom in/out the page - this makes the pixi renderer change its resolution, so try it.
-edit-
I am not sure if this is related, but the PostProcessingSprite scale behaves strangely, when you resize the page/container. You might wish to check if this fixes this problem too (I abandoned the PPS class usage completely for this reason + I think it is eating too much resources, probably because of the frequent [pre]render event calls).

@jnsmalm
Copy link
Owner

jnsmalm commented Sep 10, 2021

I included your fixes in the dev branch, please check if this resolves the issues you had with it.

Could you please give some more details about PostProcessingSprite? The only thing happening in prerender is that the PPS is being resized (but only if you didn't provide a size yourself) - by default it want to be fullscreen. It could be an issue though that it's not resizing to correct resolution if above 1.

@djlastnight
Copy link
Author

djlastnight commented Sep 11, 2021

I still need to pass the viewSize arg to the worldToScreen and screenToWorld methods. If I omit it, it does not work.

This is really strange, because I can see that you are now using the renderer.screen property, which gives the correct width and height, i.e it takes into account the resolution. The following code works:

    public static worldToScreen(
        x: number,
        y: number,
        z: number = Camera.main.z
    ): Point {
        let worldCoordinates = Camera.main.worldToScreen(x, y, z, undefined, {
            width:
                App.instance.renderer.screen.width,
            height:
                App.instance.renderer.screen.height,
        });

        return worldCoordinates;
    }

The following does not work:

    public static worldToScreen(
        x: number,
        y: number,
        z: number = Camera.main.z
    ): Point {
        let worldCoordinates = Camera.main.worldToScreen(x, y, z);

        return worldCoordinates;
    }

As you can see we are using a singleton App class, which extends the PIXI.Application class. I am not sure if this could be a problem somehow.
I guess the PPS will behave the same way, so let's first fix this issue and I will test and give you more feedback about it.
image

-edit-
About the App instance. Both App.instance.renderer.screen and Camera.main.renderer.screen returns the same rectangle.
The following code works:

    public static screenToWorld(
        x: number,
        y: number,
        model: Model
    ): ObservablePoint3D {
        let worldCoordinates = Camera.main.screenToWorld(
            x,
            y,
            Camera.main.z - model.z,
            undefined,
            Camera.main.renderer.screen
        );

        return worldCoordinates;
    }

Really strange!

-- another edit ---
About the PPS. It seems I must omit the width and height at its constuctor in order to make it scale correctly, so I guess I was using your class incorrectly. Sorry about that. Unfortunately the PPS does not position itself correctly, when the resolution differs from 1. Please see the code and comments below.

            let resource = PIXI.Loader.shared.resources["test_model"];
            let asset = (<any>resource).gltf as glTFAsset;
            let model = Model.from(asset);
           // Important. Omit the pps width and height args, otherwise the scale will be weird.
            let pps = new PostProcessingSprite(Camera.main.renderer, {
                objectToRender: <any>model,
            });

            // Computing the screen center point for any resolution
            let pos = Model3D.screenToWorld(
                Camera.main.renderer.screen.width /
                   Camera.main.renderer.resolution /
                   2 ,
                Camera.main.renderer.screen.height /
                    Camera.main.renderer.resolution /
                    2,
                model
            );

            // The pps position will be set to the center of the screen
            // If the resolution equals 1, the resize works perfectly - the model stays always at the screen center.
            // If the resolution differs from 1, the resize does not work as it should (model does not stay at the screen center)
            model.position.set(pos.x, pos.y, pos.z);
            App.instance.stage.addChild(pps);

It seems I should prepare a test project for you to test this stuff easily. I got a feeling our game does something fishy with the renderer sizes on each window resize and your api does not like this much.

@jnsmalm
Copy link
Owner

jnsmalm commented Sep 11, 2021

Would be great help if you could reproduce these issues in a simple example.

@jnsmalm
Copy link
Owner

jnsmalm commented Sep 11, 2021

And about PPS, if you give it a width and height where the aspect ratio differs from the camera aspect ratio it will look wrong. The objects rendered to the PPS need to use a camera which have the same aspect ratio as the PPS. This is handled automatically if you don’t give it a width and height.

@djlastnight
Copy link
Author

djlastnight commented Sep 11, 2021

Yep, my bad about the PPS width and height, thank you for the clarification.
I made a test repo, everything is described at index.ts.
https://github.com/djlastnight/Pixi3DCameraTests

@jnsmalm
Copy link
Owner

jnsmalm commented Sep 12, 2021

I created a PR which should fix the issues: djlastnight/Pixi3DCameraTests#1

@djlastnight
Copy link
Author

djlastnight commented Sep 12, 2021

Thank you, it is merged, I will test it when I go back to home.
-edit-
Yes, it works now. The white rect is not centered on zoom change, but this is not important, because the model and pps works as they should.

@djlastnight
Copy link
Author

I guess we could close this now, thank you again ;)

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

2 participants