Switch Tracking Mode


#1

Is it possible to switch tracking mode in the same experience?
I’m trying to set up a project that mostly relies on image tracking, but want to allow the users to switch to world tracking by pressing a button.

I’m assuming I should use 2 different cameras and activate either one when needed, but I haven’t got it to work so far.

What would be the right way to approach this, if possible at all?


#2

You could try nesting the zappar-instant tracking component inside the image tracking component such that when the image tracking is visible the content is visible as well as placement is false instead of listening to click listener. References: https://docs.zap.works/universal-ar/web-libraries/a-frame/image-tracking/ & https://docs.zap.works/universal-ar/web-libraries/a-frame/instant-world-tracking/

<a-assets>
    <a-asset-item id="target-file" src="myTarget.zpt"/>
</a-assets>

<a-entity zappar-image="#target-file" id="my-image-tracker">
  <a-entity zappar-instant="placement-mode: true;" id="my-instant-tracker">
     <!-- PLACE CONTENT TO APPEAR ON THE IMAGE HERE -->
  </a-entity>
</a-entity>

let myImageTracker = document.getElementById("my-image-tracker");
let myInstantTracker = document.getElementById("my-instant-tracker");

myImageTracker.addEventListener("zappar-visible", () => {
  console.log("Image has become visible");
  myInstantTracker.setAttribute("zappar-instant", "placement-mode: false;");
});

myImageTracker.addEventListener("zappar-notvisible", () => {
  console.log("Image is no longer visible");
});

Something like this I am not sure if it works or not, there may be some conflicts or errors but it is worth trying.


#3

Thanks! I’ll give it a try, even though the problem I’m having makes me think there’s a conflict with the coordinate system of the camera when switching from one tracking to the other.

In fact the 3D object that I want to use with the instant tracker appears just above the camera FOV when I switch to the instant tracking mode.

Will test your suggestion and share the update here!


#4

Hey @AhUhmm,

A simple solution is making a component which reparents your content based on the attribute you provide it. Here’s an example:

<html>
   <head>
      <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
      <script>
         AFRAME.registerComponent("reparent", {
           schema: {
             entity: { type: "string", default: "group1" }
           },

           init: function () {
             const group = document.getElementById(this.data.entity);
             group.object3D.add(this.el.object3D);
           },
           update: function () {
             const group = document.getElementById(this.data.entity);
             group.object3D.add(this.el.object3D);
           }
         });
      </script>
   </head>
   <body>
      <a-scene>
         <a-sphere
            reparent="entity: group1"
            radius="0.5"
            position="0.0 0 -5"
            id="myContent"
            color="#ff0000"
            ></a-sphere>
         <a-entity position="0.7 0 0" id="group0"> </a-entity>
         <a-entity position="-0.7 0 0" id="group1"> </a-entity>
      </a-scene>
      <script>
         let activeGroup = 0;
         setInterval(() => {
           const group = `group${++activeGroup % 2}`
           document.getElementById("myContent").setAttribute("reparent", `entity: ${group}`);
         }, 500);
      </script>
   </body>
</html>

The content should jump between the two groups every 500ms. The same can be applied to the tracker entities :slight_smile:

You shouldn’t need to use two cameras, one should work fine. Just remember to disable the tracker that’s inactive. Here’s an example:

<a-entity zappar-image="target: #target-file; enabled: false" id="anchor">
</a-entity>

Hope this helps!