Camera shaking when traversing mesh edges

Hello everyone.

I’m trying to make a small game where you can control a ball rolling over a terrain.

I’ve just implement the camera and ball controlls so that the camera is always bind the ball and looking into the direction the ball is rolling.

The problem is that that the camera does some weird shaking, and it seems like it’s always happening when the ballis rolling over an edge of the terrain mesh.

Here is a video that demonstrates the problem: Loom video recording

The green mesh is the terrain. It’s a combination of a three.js and cannon.js plane that are identical. The green ball wireframe mesh represents the cannon.js sphere.

Here is the relevant logic that updates the camera:

update(delta) {
        if (this.controlKeys.w) {
            if (this.body.velocity.almostZero()) {
                this.body.velocity.z = -1
            }
            this.body.velocity.scale(1.1, this.body.velocity)
        }
        if (this.controlKeys.s) {
            this.body.velocity.scale(0.9, this.body.velocity)
        }
        const TURN_RADIANS = 0.09
        if (this.controlKeys.d) {
            const updatedVelocity = rotateVectorByRadians(this.body.velocity, new CANNON.Vec3(0, -TURN_RADIANS, 0))
            this.body.velocity.copy(updatedVelocity)
        }
        if (this.controlKeys.a) {
            const updatedVelocity = rotateVectorByRadians(this.body.velocity, new CANNON.Vec3(0, TURN_RADIANS, 0))
            this.body.velocity.copy(updatedVelocity)
        }
        const currentBodyPosition = new THREE.Vector3(this.body.position.x, this.body.position.y, this.body.position.z)
        const currentBodyVeloctiy = new THREE.Vector3(...this.body.velocity.toArray())

            this.arrowHelper.position.copy(currentBodyPosition)
            this.arrowHelper.setDirection(currentBodyVeloctiy)

            this.cameraDummy.position.set(...this.body.position.toArray())
            var mx = new THREE.Matrix4().lookAt(currentBodyVeloctiy.negate(),new THREE.Vector3(0,0,0),new THREE.Vector3(0,1,0));
            var qt = new THREE.Quaternion().setFromRotationMatrix(mx);
            this.cameraDummy.quaternion.copy(qt)
            this.camera.position.set(0, 3, 8)
        }