Chase camera flickering in a CANNON-ES.JS + THREE.JS scene

Hi all,

Here is a web app I’m trying to build. I’m having difficulty making the chase camera stop flickering when the buggy is turning pretty much. Here is the code I used to set up the chase camera:

let world, cannonDebugger // init World
let timeStep = 1 / 60 // animation
let cannonGroundMaterial // ground material
let viewerBody, viewerMesh // The spaceship
let speed = 0, maxSpeed = 100, minSpeed = 0, acceleration = 2., angle = 0
 
const clock = new THREE.Clock()
let oldElapsedTime = 0

let chaseCamera, chaseCameraPivot
let view = new THREE.Vector3()

function CreateScene(canvas) {
    // Setup functions

    initScene(canvas)
     
    initWorld()
    initChaseCamera()
    createGround()
    createViewer()
    //createCity()
    animate()
}

function initWorld() {
    // CANNON world
    world = new CANNON.World()
    world.gravity.set(0, 0, -100)

    // Cannon debugger

    cannonDebugger = new CannonDebugger(scene, world, {
        color: 0xffffff, // wireframe color
        scale: 1.0 // wireframe scale
    })

}

function createViewer() {
    // create material for viewer body
    const viewerMaterial = new CANNON.Material("viewerMaterial")

    const slipperyGroundContactMaterial = new CANNON.ContactMaterial(
        cannonGroundMaterial, viewerMaterial,
        {
            friction: 0.4,
            restitution: 0.4,
            contactEquationStiffness: 1e9,
            contactEquationRelaxation: 3,
            frictionEquationStiffness: 1e5,
            frictionEquationRelaxation: 3
        }
    )

    world.addContactMaterial(slipperyGroundContactMaterial)

    // body shape

    const viewerBodyShape = new CANNON.Box(new CANNON.Vec3(200, 120, 50))

    viewerBody = new CANNON.Body({
        mass: 100,
        material: viewerMaterial,
        shape: viewerBodyShape
    })

    viewerBody.position = new CANNON.Vec3(0, 0, 400)

    viewerBody.fixedRotation = true
    viewerBody.updateMassProperties()

    world.addBody(viewerBody)

    const loader = new GLTFLoader()

    loader.load("/model/scene.gltf", (gltf) => {
        viewerMesh = gltf.scene
        viewerMesh.scale.set(15.0, 15., 15.0)

        //viewerMesh.up.set(1, 0, 0)
        //viewerMesh.rotation.x = Math.PI/2

        viewerMesh.add(chaseCamera)
        scene.add(viewerMesh)
    })

}

function moveViewer() {

    // set max speed
    if (speed > maxSpeed) {
        speed = maxSpeed
    }

    if (speed < minSpeed) {
        speed = minSpeed
    }

    viewerBody.position.y -= speed * Math.sin(angle)
    viewerBody.position.x -= speed * Math.cos(angle)

    if (viewerMesh) {

        viewerMesh.position.copy(viewerBody.position)
        viewerMesh.quaternion.copy(viewerBody.quaternion)

        viewerMesh.rotateX(Math.PI / 2)
        viewerMesh.rotateY(-Math.PI / 2)

        camera.lookAt(viewerMesh.position)
    }
}

document.onkeydown = (event) => {
    //console.log(event)

    switch (event.key) {
        case 'w':
        case 'ArrowUp':
            speed += acceleration

            break

        case 's':
        case 'ArrowDown':
            speed -= acceleration

            break

        case 'a':
        case 'ArrowLeft':
            angle += 2*(Math.PI / (180))

            break

        case 'd':
        case 'ArrowRight':
            angle -= 2*(Math.PI / (180))

            break
    }
    viewerBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 0, 1), angle)
}


function initChaseCamera() {
    chaseCamera = new THREE.Object3D()
    chaseCamera.position.set(0, 0, 0)

    chaseCameraPivot = new THREE.Object3D()
    chaseCameraPivot.position.set(0, 100, -100)

    chaseCamera.add(chaseCameraPivot)

    scene.add(chaseCamera)
}

function updateChaseCamera() {

    chaseCameraPivot.getWorldPosition(view)

    if (view.z < 1) {
        view.z = 1
    }


    camera.position.lerpVectors(camera.position, view, 0.1)
}

function animate() {
    const elapsedTime = clock.getElapsedTime()
    const deltaTime = elapsedTime - oldElapsedTime
    oldElapsedTime = elapsedTime
    // Update the controls (controls used when not using chase camera)

    //controls.update()

    // update cannon debugger
    cannonDebugger.update()

    // update world
    world.step(timeStep, deltaTime, 3)
    //world.fixedStep()

    // Control the viewer

    moveViewer() // update body position and rotation

    updateChaseCamera()

    // Update the renderer

    renderer.render(scene, camera)

    window.requestAnimationFrame(animate)
}

Once I fix this issue, I would like to become able to drag and drop the scene using my mouse and trackpad in the exact same way Bruno Simon does this in his folio. If anyone has any suggestions I would be thankful! Thank you in advance!