Camera.update() es6 treeShaking?

Hello everyone,

my question is short but I can’t figure it out on my own:

What dependency do I have to import to be able to use camera.update()?

Thank you very much :slight_smile:

That depends on the camera you are using, but if you are importing the camera you actually want to use it will be imported automatically.

Do you have any issues with tree shaking and the camera class?

I am using arcRotateCamera:

import { ArcRotateCamera } from “@babylonjs/core/Cameras/arcRotateCamera”

I try to render the scene on demand. To do that I have to call camera.update() in the render loop to check if there are new inputs. But this doesn’t work if I just import the camera. If I import the whole package it works fine:

import { ArcRotateCamera } from “@babylonjs/core”

First one would be cleaner, of course :slight_smile:

What exactly doesn’t work? does it fail silently? does it show any error in the console? can you reproduce this somehow and provide a code example?

Since I only want to render the scene if the user made some inputs I call camera.update() in renderLoop: https://www.babylonjs-playground.com/#UD9LU6#41

If I import the camera via the full path “@babylonjs/core/Cameras/arcRotateCamera” I can’t interact with the scene. So I assume that camera.update() is the problem here. I noticed that it works fine if I import gamepadManager in addition to the camera:

import { GamepadManager } from “@babylonjs/core/Gamepads/gamepadManager”

I don’t know why that works.

The console doesn’t show any errors.

Is that the only import in your app?

Sounds like this should just work, @samevision, do you have a repro we could look at ?

1 Like

No I import a lot of modules but all by their specific path. Everything works fine except for camera.update().

How would you recommend to create a repro with treeshaking? I will try so set it up on git and will post it here later.

Nothing special is happening in camera.update. And if there was something missing you should have seen a warning in the console. Needs to be debugged…

I am not sure how you build your project, but that would be the best way :slight_smile: build your project with sourcemaps, or provide the repository if possible. that would help a lot.

1 Like

Sharing the repo on Github will be by far the fastest way to troubleshoot for us

I experience this as well in my personal project.

if i do

    // import { ArcRotateCamera } from '@babylonjs/core/Cameras/index.js';

it works

but if i do

    import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera.js';

onViewMatrixChangedObservable doesn’t seem to fire.

i have to import this to make it work

    import * as NecessaryImport from '@babylonjs/core/Gamepads/Controllers/poseEnabledController.js';

cc @RaananW

for reproduction, I am doing it in svelte.
hopefully it will still matter

Please see Canvas.svelte (2nd tab of the repl)

adding/removing import {} from '@babylonjs/core/Gamepads/Controllers/poseEnabledController.js'; seems weird for me as it somehow affects the other components/js files.

Hey,

I am not sure where the @nil-/3d code come from, but looking at the npm package, it seem to me like there is something wrong in the way the camera is being handled there.

This piece of code (in the Camera.svelte file):

function onViewUpdate() {
    context.render();
}
function updateCamera() {
    camera.update();
}
camera.onViewMatrixChangedObservable.add(onViewUpdate);
context.scene.onAfterRenderObservable.add(updateCamera);
context.scene.onPointerObservable.add(updateCamera);
camera.attachControl(context.canvas, true, false);
context.render();

Seems a bit off. Only render the context when the camera view has changed but update the camera after a render was triggered.

You can also see that the camera is actually moving when you drag the mouse around but doesn’t update because the context is not being rendered (try dragging the camera around and then changing something in the UI - you will see the camera changes).

The PoseEnabledController is WebVR-oriented controller type. the only reason it does what you expect it to do is probably the update function that forces a certain change that you expect. But it’s very hard to debug, beca7use the dev environment is not easily debuggable TBH.

But again, the way I see it, since you have this function in “Context”:

afterUpdate(() => this.renderCheck());

It only checks if it should render after the context has updated. since there is no true reason for the context to update, it will not render.

hello RaananW,

that is my personal project to sveltize babylonjs, and for me to learn babylon at the same time.
it is rendering only when there is a change in the scene and in the camera (viewMatrixChanged…).

onPointerObservable calls camera.update()
thus movement via mouse events will move the camera, and it should emit onViewMatrixChangedObservable.
onViewMatrixChangedObservable then calls scene.render to update the canvas

This is true on my personal project
I simply import the whole camera and it works.

import { ArcRotateCamera } from '@babylonjs/core/Cameras/index.js';

but if i only import arcRotateCamera only
onViewMatrixChangedObservable is not invoked even with mouse events

import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera.js';

the only way for me to “fix” the issue without importing the whole camera is to import:

import * as NecessaryImport from '@babylonjs/core/Gamepads/Controllers/poseEnabledController.js';

which looks weird because it means that it probably modifies some global “state”/object that babylon is using.

i think i can create a very small example in babylon’s sandbox for this. I’ll be right back with it…

Hello, I am back :smiley:
sorry for being persistent.

here is the minimal reproduction but using svelte repl as i need to “emulate” tree shaking

please go to impl.js and toggle the commented import code

// import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera.js';
import { ArcRotateCamera } from '@babylonjs/core/Cameras/index.js';

adding @sebavan and @RaananW (don’t hold your breath as they are both on vacation)

1 Like

I am currently seeing this in the repro image

About the code update won t trigger the onViewMatrixChangedObservable only getViewMatrix does if there was an actual change. You should call update then getViewMatrix to force triggering the event.

1 Like

@sebavan thanks!
i’m not sure why the repro fails on your end. :confused:

anyway. i did try to do it this way.

scene.onPointerObservable.add(() => {
    camera.getViewMatrix();
    camera.update();
});

it does work even with the other import commented out

// import {} from '@babylonjs/core/Gamepads/Controllers/poseEnabledController.js';

but still the question remains that poseEnabledController.js somehow affects the camera with/without its inclusion (import)

anyway, i’ll use this instead to force update the camera and trigger the observable.
I’ll leave it to the OP, and you guys decide what to do with this.

Thanks a lot!!!

1 Like

Just want to add some clarifications.
I just found out the part of the code that adds some “functionality” to the scene.

import {} from '@babylonjs/core/Culling/ray.js';

createPickingRayToRef is “changed(?)” by importing ray.js…
and when it is called, at the end before return, camera.getViewMatrix() is called.

anyway
that clears everything to me, why there is a behavior difference between importing ray.js vs not importing ray.js.
I am not sure why it is designed this way, if it is intentional, or it is a “bug” that should be fixed.
at least now, it is not “magical” anymore.

Thanks for helping reach this understanding. :pray: