@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
105 lines (78 loc) • 2.92 kB
JavaScript
import Vector3 from "../../../../../core/geom/Vector3.js";
import { clamp } from "../../../../../core/math/clamp.js";
import ObservedValue from "../../../../../core/model/ObservedValue.js";
import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
import { System } from '../../../../ecs/System.js';
import { Transform } from '../../../../ecs/transform/Transform.js';
import TopDownCameraController from './TopDownCameraController.js';
const v3_scratch = new Vector3();
class TopDownCameraControllerSystem extends System {
constructor() {
super();
this.enabled = new ObservedValue(true);
this.dependencies = [TopDownCameraController];
this.components_used = [
ResourceAccessSpecification.from(Transform,ResourceAccessKind.Write)
];
}
/**
*
* @param {TopDownCameraController} ctrl
* @param {number} entity
* @private
*/
__visit_camera_entity(ctrl, entity){
const transform = this.entityManager.dataset.getComponent(entity,Transform);
if(transform === undefined){
return;
}
computeTopDownTransform(ctrl,transform);
}
update(timeDelta) {
const em = this.entityManager;
/**
*
* @type {EntityComponentDataset}
*/
const dataset = em.dataset;
if (this.enabled.get() && dataset !== null) {
dataset.traverseComponents(TopDownCameraController, this.__visit_camera_entity, this);
}
}
}
/**
*
* @param {TopDownCameraController} control
* @param {Transform} result
*/
export function computeTopDownTransform(control, result) {
const rotation = result.rotation;
//clamp the distance
const distance = clamp(control.distance, control.distanceMin, control.distanceMax);
const target = control.target;
const yaw = control.yaw;
const pitch = control.pitch;
const roll = control.roll;
// compute rotation
rotation.__setFromEuler(pitch, yaw, roll, 'ZYX');
// compute camera position
v3_scratch.copy(Vector3.forward);
v3_scratch.applyQuaternion(rotation);
v3_scratch.multiplyScalar(-distance);
v3_scratch.add(target);
result.position.copy(v3_scratch);
}
/**
*
* @param {Transform} transform
* @param {TopDownCameraController} controller
* @param {number} distance
*/
export function setCameraControllerFromTransform(transform, controller, distance = 20) {
const v_f = Vector3.forward.clone();
v_f.multiplyScalar(distance);
v_f.applyQuaternion(transform.rotation);
controller.setFromEyeAndTarget(transform.position,v_f);
}
export default TopDownCameraControllerSystem;