123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- import { __decorate } from "../tslib.es6.js";
- import { serialize, serializeAsMeshReference } from "../Misc/decorators.js";
- import { Tools } from "../Misc/tools.js";
- import { TargetCamera } from "./targetCamera.js";
- import { TmpVectors, Vector3 } from "../Maths/math.vector.js";
- import { Node } from "../node.js";
- import { FollowCameraInputsManager } from "./followCameraInputsManager.js";
- Node.AddNodeConstructor("FollowCamera", (name, scene) => {
- return () => new FollowCamera(name, Vector3.Zero(), scene);
- });
- Node.AddNodeConstructor("ArcFollowCamera", (name, scene) => {
- return () => new ArcFollowCamera(name, 0, 0, 1.0, null, scene);
- });
- /**
- * A follow camera takes a mesh as a target and follows it as it moves. Both a free camera version followCamera and
- * an arc rotate version arcFollowCamera are available.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera
- */
- export class FollowCamera extends TargetCamera {
- /**
- * Instantiates the follow camera.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera
- * @param name Define the name of the camera in the scene
- * @param position Define the position of the camera
- * @param scene Define the scene the camera belong to
- * @param lockedTarget Define the target of the camera
- */
- constructor(name, position, scene, lockedTarget = null) {
- super(name, position, scene);
- /**
- * Distance the follow camera should follow an object at
- */
- this.radius = 12;
- /**
- * Minimum allowed distance of the camera to the axis of rotation
- * (The camera can not get closer).
- * This can help limiting how the Camera is able to move in the scene.
- */
- this.lowerRadiusLimit = null;
- /**
- * Maximum allowed distance of the camera to the axis of rotation
- * (The camera can not get further).
- * This can help limiting how the Camera is able to move in the scene.
- */
- this.upperRadiusLimit = null;
- /**
- * Define a rotation offset between the camera and the object it follows
- */
- this.rotationOffset = 0;
- /**
- * Minimum allowed angle to camera position relative to target object.
- * This can help limiting how the Camera is able to move in the scene.
- */
- this.lowerRotationOffsetLimit = null;
- /**
- * Maximum allowed angle to camera position relative to target object.
- * This can help limiting how the Camera is able to move in the scene.
- */
- this.upperRotationOffsetLimit = null;
- /**
- * Define a height offset between the camera and the object it follows.
- * It can help following an object from the top (like a car chasing a plane)
- */
- this.heightOffset = 4;
- /**
- * Minimum allowed height of camera position relative to target object.
- * This can help limiting how the Camera is able to move in the scene.
- */
- this.lowerHeightOffsetLimit = null;
- /**
- * Maximum allowed height of camera position relative to target object.
- * This can help limiting how the Camera is able to move in the scene.
- */
- this.upperHeightOffsetLimit = null;
- /**
- * Define how fast the camera can accelerate to follow it s target.
- */
- this.cameraAcceleration = 0.05;
- /**
- * Define the speed limit of the camera following an object.
- */
- this.maxCameraSpeed = 20;
- this.lockedTarget = lockedTarget;
- this.inputs = new FollowCameraInputsManager(this);
- this.inputs.addKeyboard().addMouseWheel().addPointers();
- // Uncomment the following line when the relevant handlers have been implemented.
- // this.inputs.addKeyboard().addMouseWheel().addPointers().addVRDeviceOrientation();
- }
- _follow(cameraTarget) {
- if (!cameraTarget) {
- return;
- }
- const rotMatrix = TmpVectors.Matrix[0];
- cameraTarget.absoluteRotationQuaternion.toRotationMatrix(rotMatrix);
- const yRotation = Math.atan2(rotMatrix.m[8], rotMatrix.m[10]);
- const radians = Tools.ToRadians(this.rotationOffset) + yRotation;
- const targetPosition = cameraTarget.getAbsolutePosition();
- const targetX = targetPosition.x + Math.sin(radians) * this.radius;
- const targetZ = targetPosition.z + Math.cos(radians) * this.radius;
- const dx = targetX - this.position.x;
- const dy = targetPosition.y + this.heightOffset - this.position.y;
- const dz = targetZ - this.position.z;
- let vx = dx * this.cameraAcceleration * 2; //this is set to .05
- let vy = dy * this.cameraAcceleration;
- let vz = dz * this.cameraAcceleration * 2;
- if (vx > this.maxCameraSpeed || vx < -this.maxCameraSpeed) {
- vx = vx < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;
- }
- if (vy > this.maxCameraSpeed || vy < -this.maxCameraSpeed) {
- vy = vy < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;
- }
- if (vz > this.maxCameraSpeed || vz < -this.maxCameraSpeed) {
- vz = vz < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;
- }
- this.position = new Vector3(this.position.x + vx, this.position.y + vy, this.position.z + vz);
- this.setTarget(targetPosition);
- }
- /**
- * Attached controls to the current camera.
- * @param ignored defines an ignored parameter kept for backward compatibility.
- * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
- */
- attachControl(ignored, noPreventDefault) {
- // eslint-disable-next-line prefer-rest-params
- noPreventDefault = Tools.BackCompatCameraNoPreventDefault(arguments);
- this.inputs.attachElement(noPreventDefault);
- this._reset = () => { };
- }
- /**
- * Detach the current controls from the specified dom element.
- */
- detachControl() {
- this.inputs.detachElement();
- if (this._reset) {
- this._reset();
- }
- }
- /** @internal */
- _checkInputs() {
- this.inputs.checkInputs();
- this._checkLimits();
- super._checkInputs();
- if (this.lockedTarget) {
- this._follow(this.lockedTarget);
- }
- }
- _checkLimits() {
- if (this.lowerRadiusLimit !== null && this.radius < this.lowerRadiusLimit) {
- this.radius = this.lowerRadiusLimit;
- }
- if (this.upperRadiusLimit !== null && this.radius > this.upperRadiusLimit) {
- this.radius = this.upperRadiusLimit;
- }
- if (this.lowerHeightOffsetLimit !== null && this.heightOffset < this.lowerHeightOffsetLimit) {
- this.heightOffset = this.lowerHeightOffsetLimit;
- }
- if (this.upperHeightOffsetLimit !== null && this.heightOffset > this.upperHeightOffsetLimit) {
- this.heightOffset = this.upperHeightOffsetLimit;
- }
- if (this.lowerRotationOffsetLimit !== null && this.rotationOffset < this.lowerRotationOffsetLimit) {
- this.rotationOffset = this.lowerRotationOffsetLimit;
- }
- if (this.upperRotationOffsetLimit !== null && this.rotationOffset > this.upperRotationOffsetLimit) {
- this.rotationOffset = this.upperRotationOffsetLimit;
- }
- }
- /**
- * Gets the camera class name.
- * @returns the class name
- */
- getClassName() {
- return "FollowCamera";
- }
- }
- __decorate([
- serialize()
- ], FollowCamera.prototype, "radius", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "lowerRadiusLimit", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "upperRadiusLimit", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "rotationOffset", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "lowerRotationOffsetLimit", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "upperRotationOffsetLimit", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "heightOffset", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "lowerHeightOffsetLimit", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "upperHeightOffsetLimit", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "cameraAcceleration", void 0);
- __decorate([
- serialize()
- ], FollowCamera.prototype, "maxCameraSpeed", void 0);
- __decorate([
- serializeAsMeshReference("lockedTargetId")
- ], FollowCamera.prototype, "lockedTarget", void 0);
- /**
- * Arc Rotate version of the follow camera.
- * It still follows a Defined mesh but in an Arc Rotate Camera fashion.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera
- */
- export class ArcFollowCamera extends TargetCamera {
- /**
- * Instantiates a new ArcFollowCamera
- * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_introduction#followcamera
- * @param name Define the name of the camera
- * @param alpha Define the rotation angle of the camera around the longitudinal axis
- * @param beta Define the rotation angle of the camera around the elevation axis
- * @param radius Define the radius of the camera from its target point
- * @param target Define the target of the camera
- * @param scene Define the scene the camera belongs to
- */
- constructor(name,
- /** The longitudinal angle of the camera */
- alpha,
- /** The latitudinal angle of the camera */
- beta,
- /** The radius of the camera from its target */
- radius,
- /** Define the camera target (the mesh it should follow) */
- target, scene) {
- super(name, Vector3.Zero(), scene);
- this.alpha = alpha;
- this.beta = beta;
- this.radius = radius;
- this._cartesianCoordinates = Vector3.Zero();
- this.setMeshTarget(target);
- }
- /**
- * Sets the mesh to follow with this camera.
- * @param target the target to follow
- */
- setMeshTarget(target) {
- this._meshTarget = target;
- this._follow();
- }
- _follow() {
- if (!this._meshTarget) {
- return;
- }
- this._cartesianCoordinates.x = this.radius * Math.cos(this.alpha) * Math.cos(this.beta);
- this._cartesianCoordinates.y = this.radius * Math.sin(this.beta);
- this._cartesianCoordinates.z = this.radius * Math.sin(this.alpha) * Math.cos(this.beta);
- const targetPosition = this._meshTarget.getAbsolutePosition();
- this.position = targetPosition.add(this._cartesianCoordinates);
- this.setTarget(targetPosition);
- }
- /** @internal */
- _checkInputs() {
- super._checkInputs();
- this._follow();
- }
- /**
- * Returns the class name of the object.
- * It is mostly used internally for serialization purposes.
- * @returns the class name
- */
- getClassName() {
- return "ArcFollowCamera";
- }
- }
- //# sourceMappingURL=followCamera.js.map
|