control_KeyboardNavigation.ts
import * as math from "../math";
import {Control, type IControlParams} from "./Control";
import {input} from "../input/input";
import {Vec3} from "../math/Vec3";
import {Camera} from "../camera/Camera";
import {PlanetCamera} from "../camera/PlanetCamera";
import {RADIANS} from "../math";
interface IKeyboardNavigationParams extends IControlParams {
speed?: number;
camera?: Camera | PlanetCamera;
}
/**
* Planet camera keyboard navigation. Use W,S,A,D and left shift key for fly around a planet.
*/
export class KeyboardNavigation extends Control {
public speed: number;
public force: Vec3;
public vel: Vec3;
public mass: number;
protected _camera: Camera | PlanetCamera | null;
constructor(options: IKeyboardNavigationParams = {}) {
options = options || {};
super({name: "KeyboardNavigation", ...options});
this._camera = options.camera || null;
this.speed = options.speed || 10.0;
this.force = new Vec3();
this.vel = new Vec3();
this.mass = 1;
}
public bindCamera(camera: Camera) {
this._camera = camera;
}
public override onactivate() {
let r = this.renderer!;
// r.events.on("keypress", input.KEY_PGUP, this.onCameraMoveForward, this);
// r.events.on("keypress", input.KEY_PGDN, this.onCameraMoveBackward, this);
// r.events.on("keypress", input.KEY_PLUS, this.onCameraMoveForward, this);
// r.events.on("keypress", input.KEY_EQUALS, this.onCameraMoveForward, this);
r.events.on("keypress", input.KEY_S, this.onCameraMoveBackward, this);
r.events.on("keypress", input.KEY_W, this.onCameraMoveForward, this);
// r.events.on("keypress", input.KEY_A, this.onCameraStrifeLeft, this);
// r.events.on("keypress", input.KEY_D, this.onCameraStrifeRight, this);
r.events.on("keypress", input.KEY_UP, this.onCameraPitchUp, this);
r.events.on("keypress", input.KEY_DOWN, this.onCameraPitchDown, this);
r.events.on("keypress", input.KEY_LEFT, this.onCameraYawLeft, this);
r.events.on("keypress", input.KEY_RIGHT, this.onCameraYawRight, this);
r.events.on("draw", this.onDraw, this, -1000);
}
public override ondeactivate() {
let r = this.renderer!;
}
public override oninit() {
this.activate();
}
protected get dt(): number {
return 0.001 * this.renderer!.handler.deltaTime;
}
protected onCameraPitchUp = () => {
if (this._camera) {
this._camera.setPitch(this._camera.getPitch() + 0.1 * RADIANS);
}
}
protected onCameraPitchDown = () => {
if (this._camera) {
this._camera.setPitch(this._camera.getPitch() - 0.1 * RADIANS);
}
}
protected onCameraYawLeft = () => {
if (this._camera) {
this._camera.setYaw(this._camera.getYaw() - 0.1 * RADIANS);
}
}
protected onCameraYawRight = () => {
if (this._camera) {
this._camera.setYaw(this._camera.getYaw() + 0.1 * RADIANS);
}
}
protected onCameraMoveForward = () => {
if (this._camera) {
this.force.addA(this._camera.getForward()).normalize();
}
}
protected onCameraMoveBackward = () => {
if (this._camera) {
this.force.addA(this._camera.getBackward()).normalize();
}
}
protected onDraw() {
if (this.renderer && this._camera) {
let acc = this.force.scale(1.0 / this.mass);
this.vel.addA(acc);
this.vel.scale(0.96);
this.force.set(0, 0, 0);
let cam = this._camera;
cam.eye = cam.eye.add(this.vel.scaleTo(this.dt));
cam.update();
}
}
}