controls_ThirdPersonCameraController.js

import * as THREE from 'three';
import { Vector3 } from 'three';
import { Controller } from './Controller';


const tempPoint1 = new THREE.Vector3();
const tempPoint2 = new THREE.Vector3();
/**
 * Camera controller that tracks an object and attempts to place the camera behind it
 * while restricting it to an above ground position.
 */
class ThirdPersonCameraController extends Controller {
    constructor(camera, domElement, map, trackedObject, heightAboveObject = 300, distanceBehindObject = 100) {
        super(camera, domElement, map);
        this.mouseRayCast = new THREE.Vector3();
        this.trackedObject = trackedObject;
        this.previousPosition = new Vector3().copy(trackedObject.position);
        this.heightAboveObject = heightAboveObject;
        this.distanceBehindObject = distanceBehindObject;
        this.clock = new THREE.Clock();
    }
    _handleEvent(eventName, e) {
        super._handleEvent(eventName, e);
    }

    _update() {
        const self = this;
        self.trackedObject.getWorldDirection(tempPoint1);
        tempPoint1.normalize().negate().multiplyScalar(self.distanceBehindObject);
        tempPoint2.copy(self.trackedObject.position).normalize().multiplyScalar(self.heightAboveObject);

        // tempPoint1 contains the desired camera position
        tempPoint1.add(tempPoint2).add(self.trackedObject.position);

        const llh = self.map.planet.llhToCartesian.inverse(tempPoint1)
        const terrainHeight = self.map.planet.getTerrainElevation({x:llh.x*0.0174532925, y:llh.y*0.0174532925});

        if(llh.z < terrainHeight+5){
            tempPoint2.divideScalar(self.heightAboveObject).multiplyScalar(terrainHeight+5-llh.z);
            tempPoint1.add(tempPoint2);
        }

        self.camera.position.lerp(tempPoint1, Math.pow(0.9,self.clock.getDelta()));
        self.camera.up.copy(self.camera.position).normalize();
        self.camera.lookAt(self.trackedObject.position);
        self.straighten()
        this.map.resetCameraNearFar();
    }

    straighten() {



        this.camera.getWorldDirection(tempPoint2).normalize();

        tempPoint1.crossVectors(this.camera.up.normalize(), tempPoint2);
        tempPoint2.add(this.camera.position);
        this.camera.lookAt(tempPoint2);
        this.camera.up.crossVectors(tempPoint2.sub(this.camera.position), tempPoint1);
    }

} export { ThirdPersonCameraController }