首页 / 模块目录 / 相机机位 / PositionFollowCameraRig

PositionFollowCameraRig

纯逻辑

以固定世界-basis 偏移和固定视角跟随目标位置并看向目标。

类别相机机位
依赖档位纯逻辑
相关模块
演示场camera-gallery · 相机机位 ↓
只取这个模块
modules/camera/PositionFollowCameraRig.js

连同其内部依赖一并复制,保留相对目录结构。

相机机位

three

自动行驶展示,无需操作。

源码

import { BaseCameraRig, CAMERA_ROTATION_MODES } from './BaseCameraRig.js';
import { toVec3 } from '../math/Vector3Utils.js';
import { DEFAULT_WORLD_BASIS } from '../math/WorldBasis.js';

export class PositionFollowCameraRig extends BaseCameraRig {
  constructor({
    azimuth = 0,
    distance = 18,
    height = 16,
    lookHeight = 0,
    positionLag = 0.00,
    lookLag = 0.00,
    basis = DEFAULT_WORLD_BASIS,
  }) {
    super({ basis, rotationMode: CAMERA_ROTATION_MODES.lookAt });
    Object.assign(this, {
      azimuth,
      distance,
      height,
      lookHeight,
      positionLag,
      lookLag,
    });
  }

  step({
    targetPosition,
    snapToTarget = false,
    deltaSeconds = 1 / 60,
    camera = null,
  }) {
    const focus = toVec3(targetPosition);

    const viewDirection = this.basis.fromBasisComponents(
      Math.sin(this.azimuth),
      0,
      Math.cos(this.azimuth)
    ).normalize();
    const cameraPosition = focus.clone()
      .addScaledVector(viewDirection, -this.distance);
    const cameraLookAt = focus.clone();
    const baseHeight = this.basis.upComponent(focus);

    this.basis.setHeight(cameraPosition, baseHeight + this.height);
    this.basis.setHeight(cameraLookAt, baseHeight + this.lookHeight);
    this.smoothVector(this.position, cameraPosition, this.positionLag, deltaSeconds, snapToTarget);
    this.smoothVector(this.lookAt, cameraLookAt, this.lookLag, deltaSeconds, snapToTarget);

    this.setLookAtPose({
      position: this.position,
      lookAt: this.lookAt,
      up: this.basis.upVector(),
    });

    const pose = this.getPose();
    this.applyToCamera(camera, pose);
    return pose;
  }
}