Newer
Older
AegisforEcosystem / next / AR.js-3.4.0 / three.js / src / new-api / arjs-anchor.js
@KAOKA Daisuke KAOKA Daisuke on 31 May 2022 5 KB into AR.js
import * as THREE from "three";
import ArMarkerControls from "threexArmarkercontrols"; // Alias for dynamic importing
import ArMarkerHelper from "../threex/threex-armarkerhelper";
import ArSmoothedControls from "../threex/threex-arsmoothedcontrols";
import MarkersAreaControls from "../markers-area/arjs-markersareacontrols";
import MarkersAreaUtils from "../markers-area/arjs-markersareautils";

// TODO this is a controls... should i give the object3d here ?
// not according to 'no three.js dependancy'

/**
 * Create an anchor in the real world
 *
 * @param {ARjs.Session} arSession - the session on which we create the anchor
 * @param {Object} markerParameters - parameter of this anchor
 */
const Anchor = function (arSession, markerParameters) {
  var _this = this;
  var arContext = arSession.arContext;
  var scene = arSession.parameters.scene;
  var camera = arSession.parameters.camera;

  this.arSession = arSession;
  this.parameters = markerParameters;

  // log to debug
  console.log(
    "ARjs.Anchor -",
    "changeMatrixMode:",
    this.parameters.changeMatrixMode,
    "/ markersAreaEnabled:",
    markerParameters.markersAreaEnabled
  );

  var markerRoot = new THREE.Group();
  scene.add(markerRoot);

  // set controlledObject depending on changeMatrixMode
  if (markerParameters.changeMatrixMode === "modelViewMatrix") {
    var controlledObject = markerRoot;
  } else if (markerParameters.changeMatrixMode === "cameraTransformMatrix") {
    var controlledObject = camera;
  } else console.assert(false);

  if (markerParameters.markersAreaEnabled === false) {
    var markerControls = new ArMarkerControls(
      arContext,
      controlledObject,
      markerParameters
    );
    this.controls = markerControls;
  } else {
    // sanity check - MUST be a trackingBackend with markers
    console.assert(arContext.parameters.trackingBackend === "artoolkit");

    // honor markers-page-resolution for https://webxr.io/augmented-website
    if (
      location.hash.substring(1).startsWith("markers-page-resolution=") === true
    ) {
      // get resolutionW/resolutionH from url
      var markerPageResolution = location.hash.substring(1);
      var matches = markerPageResolution.match(
        /markers-page-resolution=(\d+)x(\d+)/
      );
      console.assert(matches.length === 3);
      var resolutionW = parseInt(matches[1]);
      var resolutionH = parseInt(matches[2]);
      var arContext = arSession.arContext;
      // generate and store the ARjsMultiMarkerFile
      MarkersAreaUtils.storeMarkersAreaFileFromResolution(
        arContext.parameters.trackingBackend,
        resolutionW,
        resolutionH
      );
    }

    // if there is no ARjsMultiMarkerFile, build a default one
    if (localStorage.getItem("ARjsMultiMarkerFile") === null) {
      MarkersAreaUtils.storeDefaultMultiMarkerFile(
        arContext.parameters.trackingBackend
      );
    }

    // get multiMarkerFile from localStorage
    console.assert(localStorage.getItem("ARjsMultiMarkerFile") !== null);
    var multiMarkerFile = localStorage.getItem("ARjsMultiMarkerFile");

    // set controlledObject depending on changeMatrixMode
    if (markerParameters.changeMatrixMode === "modelViewMatrix") {
      var parent3D = scene;
    } else if (markerParameters.changeMatrixMode === "cameraTransformMatrix") {
      var parent3D = camera;
    } else console.assert(false);

    // build a multiMarkerControls
    var multiMarkerControls = MarkersAreaControls.fromJSON(
      arContext,
      parent3D,
      controlledObject,
      multiMarkerFile
    );
    this.controls = multiMarkerControls;

    // honor markerParameters.changeMatrixMode
    multiMarkerControls.parameters.changeMatrixMode =
      markerParameters.changeMatrixMode;

    // TODO put subMarkerControls visibility into an external file. with 2 handling for three.js and babylon.js
    // create ArMarkerHelper - useful to debug - super three.js specific
    var markerHelpers = [];
    multiMarkerControls.subMarkersControls.forEach(function (
      subMarkerControls
    ) {
      // add an helper to visuable each sub-marker
      var markerHelper = new ArMarkerHelper(subMarkerControls);
      markerHelper.object3d.visible = false;
      // subMarkerControls.object3d.add( markerHelper.object3d )
      subMarkerControls.object3d.add(markerHelper.object3d);
      // add it to markerHelpers
      markerHelpers.push(markerHelper);
    });
    // define API specific to markersArea
    this.markersArea = {};
    this.markersArea.setSubMarkersVisibility = function (visible) {
      markerHelpers.forEach(function (markerHelper) {
        markerHelper.object3d.visible = visible;
      });
    };
  }

  this.object3d = new THREE.Group();

  //////////////////////////////////////////////////////////////////////////////
  //		THREEx.ArSmoothedControls
  //////////////////////////////////////////////////////////////////////////////

  var shouldBeSmoothed = true;

  if (shouldBeSmoothed === true) {
    // build a smoothedControls
    var smoothedRoot = new THREE.Group();
    scene.add(smoothedRoot);
    var smoothedControls = new ArSmoothedControls(smoothedRoot);
    smoothedRoot.add(this.object3d);
  } else {
    markerRoot.add(this.object3d);
  }

  //////////////////////////////////////////////////////////////////////////////
  //		Code Separator
  //////////////////////////////////////////////////////////////////////////////
  this.update = function () {
    // update _this.object3d.visible
    _this.object3d.visible = _this.object3d.parent.visible;

    // console.log('controlledObject.visible', _this.object3d.parent.visible)
    if (smoothedControls !== undefined) {
      // update smoothedControls parameters depending on how many markers are visible in multiMarkerControls
      if (multiMarkerControls !== undefined) {
        multiMarkerControls.updateSmoothedControls(smoothedControls);
      }

      // update smoothedControls
      smoothedControls.update(markerRoot);
    }
  };
};

export default Anchor;