Find a way to activate collisions during animations

Hi,

I’m looking to enable collisions during camera animations. I saw on this topic (here) that this is not the case for performance reasons.

But I’m using very simple elements (cube and low poly sphere) and I’d like to change the current behavior to enable collisions during animations.
I use collisions to block the camera in some areas (with sliding response effect) and animations for built-in interpolation.

What I have investigated for the moment is that the _getViewMatrix function of my ArcRotateCamera is well executed during animations but no collisions are found.

Could someone give me some hints to accomplish this? Or more important explanations on how collisions are disabled during animations?

Thanks in advance!

cc @Cedric and @PolygonalSun

So just like the referenced topic says, collisions are not checked for during an animation so there’s currently nothing to enable/disable for collisions, at least as far as I understand. You could use moveWithCollisions inside of the Render Loop to move things, depending on what kind of movements you need to make. I could potentially see using mesh.intersectsMesh and build key frames on the fly for a new animation but that’d be a pretty complex option. At least that’s what I can think of off the top of my head.

1 Like

Hi,
I finally got what I wanted to do, so here I share my solution.
The idea is to compute collisions after animation using the observable.

This part keeps the position (before the animation) and executes the collision function if necessary (after the animation) :

        this.scene.onBeforeAnimationsObservable.add(() => {
            this._previousPosition = this._camera.position.clone(); // Keep position before animation
        });

        this.scene.onAfterAnimationsObservable.add(() => {
            if (this._camera.wasActiveBeforeRender && this._camera.checkCollisions)
                this._checkCollisionsAfterward();
        });

This part checks if an animation has been made on the camera during this frame :

        this.scene.onBeforeAnimationsObservable.add(() => {
            this._wasActiveBeforeRender = this.scene.animatables.some((a) => a.target === this);
        });

This function calculates collisions afterward :

    private _checkCollisionsAfterward() {
        const cachedPosition = this._camera._position.clone(); // Use _position instead of position to avoid rebuilding angles
        this._camera._position = this._previousPosition.clone();
        this._camera.getViewMatrix(); // Perform collision check

        if (!this._camera.lastCollidedMesh) {
            this._camera._position = cachedPosition;
        }
    }

Hopefully it will help someone ,

3 Likes

Thanks a lot for adding the solution back !!!

1 Like

Nice. Did you notice anything in terms of performance?
Anyways, I’m gonna bookmark this. Can be very useful so thanks a lot for sharing (and for the thinking) :smiley: GJ,

1 Like

Thank you for your feedback,

I have not observed any impact on performance but I use very simple meshes for these collisions.

In some cases, with concave meshes, we can observe a camera shaking effect.
To limit this, I added the line below in _checkCollisionsAfterward :

if (this._camera.lastCollidedMesh) this._stopCameraShakingIfNeeded();

The _stopCameraShakingIfNeeded function checks if the camera shakes and stops its animations if it does. To determine if the camera is shaking, I check if consecutive collision directions are in the opposite direction.

I can’t spend more time on this right now. But if I find new ideas or solutions, I will add them in this topic.

2 Likes