Skip to content
Snippets Groups Projects
scene-preview-camera.js 2.13 KiB
Newer Older
Greg Fodor's avatar
Greg Fodor committed
/**
 * Nicely pans the camera for previewing a scene. There's some weirdness with this right now
 * since it ends up panning in a direction dependent upon the start camera orientation,
 * but it's good enough for now.
 */
function lerp(start, end, t) {
  return (1 - t) * start + t * end;
}

AFRAME.registerComponent("scene-preview-camera", {
Greg Fodor's avatar
Greg Fodor committed
  schema: {
    duration: { default: 90, type: "number" },
    positionOnly: { default: false, type: "boolean" }
Greg Fodor's avatar
Greg Fodor committed
  },

Greg Fodor's avatar
Greg Fodor committed
  init: function() {
    this.startPoint = this.el.object3D.position.clone();
    this.startRotation = new THREE.Quaternion();
    this.startRotation.setFromEuler(this.el.object3D.rotation);

    this.targetPoint = new THREE.Vector3(1, 0.5, -0.5);
    this.targetPoint.applyMatrix4(this.el.object3D.matrix);
    this.targetPoint.add(new THREE.Vector3(0, 0, -2));

    const targetRotDelta = new THREE.Euler(-0.15, 0.0, 0.15);
    this.targetRotation = new THREE.Quaternion();
    this.targetRotation.setFromEuler(targetRotDelta);
    this.targetRotation.premultiply(this.startRotation);

    this.startTime = new Date().getTime();
    this.backwards = false;
    this.ranOnePass = false;
Greg Fodor's avatar
Greg Fodor committed
  },

  tick: function() {
Greg Fodor's avatar
Greg Fodor committed
    let t = (new Date().getTime() - this.startTime) / (1000.0 * this.data.duration);
Greg Fodor's avatar
Greg Fodor committed
    t = Math.min(1.0, Math.max(0.0, t));
    if (!this.ranOnePass) {
Greg Fodor's avatar
Greg Fodor committed
      t = t * (2 - t);
    } else {
      t = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
    }
Greg Fodor's avatar
Greg Fodor committed

    const from = this.backwards ? this.targetPoint : this.startPoint;
    const to = this.backwards ? this.startPoint : this.targetPoint;
    const fromRot = this.backwards ? this.targetRotation : this.startRotation;
    const toRot = this.backwards ? this.startRotation : this.targetRotation;
    const newRot = new THREE.Quaternion();

    THREE.Quaternion.slerp(fromRot, toRot, newRot, t);

    this.el.object3D.position.set(lerp(from.x, to.x, t), lerp(from.y, to.y, t), lerp(from.z, to.z, t));

    if (!this.data.positionOnly) {
      this.el.object3D.rotation.setFromQuaternion(newRot);
    }
Greg Fodor's avatar
Greg Fodor committed

Greg Fodor's avatar
Greg Fodor committed
    if (t >= 0.9999) {
      this.ranOnePass = true;
Greg Fodor's avatar
Greg Fodor committed
      this.backwards = !this.backwards;
      this.startTime = new Date().getTime();
    }
  }
});