PlaneTracker scripting best practices?

I’m currently developing a filter which asks the user to place an object on a plane identified by the Plane Tracker. However I ran into a couple of issues which I’m not entirely sure how to deal with, maybe some fellow developer can share some best practices here:

  1. The plane tracker is by default configured to start automatically. I know this can be disabled in the properties - but how would you start the tracking manually later? There seems to be neither a method nor a patch input for that.

  2. I would like to achieve a kind of “live preview” of how and where the object would be placed in the real world. Currently I’m using a loop to “performHitTest” from the center point of the screen. If it returns a result and the current confidence is MEDIUM or above, I update the trackPoint to the hit position and display the preview object there.

Is this the right approach? I’m not 100% what “trackPoint” is used for and the documentation isn’t very helpful.

Any feedback or suggestions are appreciated!

Thank you,
Andy

  1. I suspect that calling the trackPoint function would start the planeTracker if auto-start is off, but I’m not entirely sure. If you don’t want the plane tracker active at the beginning, you could set it invisible in the properties and then unhide it when you want it active? You might also want to block touch inputs and such depending on what you want to do.

  2. This is the approach that I use:

const screenPoint = Reactive.point2d(CameraInfo.previewSize.width.mul(0.5), CameraInfo.previewSize.height.mul(0.5)); //get the center of the screen in pixels
planeTracker.trackPoint(screenPoint, "CHANGED"); //when screenPoint updates, this will automatically update the 3D space origin of the plane tracker. No need for loops 

Then when the user taps to place the object, it’s something like this:

        TouchGestures.onTap().subscribe(function(gesture){
            let confidence = planeTracker.confidence.pinLastValue();

            if(confidence == "MEDIUM" || confidence == "HIGH")
            {
                planeTracker.trackPoint(screenPoint, "ENDED");    
            }
        });

There’s more you could do so it’s more user-friendly, but this is the gist of it.

Also I know Josh is going to advise against using pinLastValue haha, but I’m not sure how to avoid it here since the tap is the driver of this and not the confidence.

Hey, thanks for all your suggestions! I’ve played around and here’s what I found:

Seems that doesn’t work. If auto-start is disabled then calling trackPoint does nothing - Probably what we should expect as no plane exists at this point.

I’m now still using auto-start, but setting the plane tracker to invisible until I actually need it, as you suggested. This seems to work well enough.

This works fine. I was able to shorten it a bit like this:

planeTracker.trackPoint(Camera.previewSize.mul(0.5), "CHANGED");

(note to self: I really gotta up my reactive game…)

You can actually avoid “pinLastValue()” like this:

TouchGestures.onTap(planeTracker).subscribeWithSnapshot({
  confidence: planeTracker.confidence,
}, (gesture, snapshot) => {
    
      if(result == null) {
        // no plane was hit
        return;
      }

      if(!(snapshot.confidence == "HIGH" || snapshot.confidence == "MEDIUM")) {
        // confidence too low
        return;
      }

      planeTracker.trackPoint(gesture.location);
  });
});

This approach seems to work quite well for me.

Cheers,
Andy

1 Like

I don’t think anyone can really blame you here when it comes to the trackPoint function. The way it works isn’t super obvious imo and the documentation doesn’t make it obvious that you can setup continuous updates like this.

Ah, I’d completely forgotten that subscribeWithSnapshot was a thing :sweat_smile: Yeah, that definitely looks cleaner

Thanks for sharing your improvements!