Articles
World Effects
Scaling Objects for the Real World

Scaling Objects for the Real World

A 3D model of a chair being placed into a white and cream room using AR.

When creating Spark AR effects, you may want your objects to be sized to real-world scale. This is key when creating effects for business use cases. For example, if your effect allows users to place items from a furniture catalog in their living space, the 3D furniture should be sized based on the real-world space.

There are 2 ways to enable real world scale in Spark AR Studio depending on the type of user experience you want to create:

  • Enable Real-World Scale in the Inspector. Your object appears realistically scaled but only after a real-scale signal is detected. This means the user sees the object abruptly change size at some point after opening the effect.
  • Enable Real-World Scale in the Inspector and add further logic via the Patch Editor or scripting. This method allows you to hide the object until a real-scale signal is detected. This means the user only sees the object once it’s realistically scaled.

Enable Real-World Scale in the Inspector

Before importing a 3D object, disable automatic scaling for 3D objects with these steps:

  1. Go to Project in the menu bar.
  2. Select Edit Properties, then General.
  3. Clear the box to the left of Automatically scale imported 3D models.
The Spark AR Studio preferences screen. Automatically scale imported 3D models is the third option.

Next:

  1. Import your 3D object. Make sure your object is measured in meters before importing it.
  2. Add a plane tracker and make your object a child of the plane tracker.

Finally:

1. With planeTracker0 selected, go to the Inspector and to the right of Real-World-Scale, select the box.

2. From the Enable Effect dropdown, select one of the following the distribution methods:

  • On all devices: your effect is distributed to all devices that support the plane tracker. This means that people viewing your effect on a device without real scale will see objects rendered at an arbitrary scale. On devices that support real scale, the object will render in real scale, but only after a real scale signal is detected.
  • Only supported devices: your effect is only distributed to devices that support real scale. This limits your effect’s reach but is the best option if your effect doesn't make sense without real scale. Your object renders in real scale once the signal is detected.

Selecting whether or not the effect should only work with supported devices in the properties of the plane tracker.

Add futher logic

Patch Editor

To improve the user experience on all types of devices, you can build a patch graph to hide your object unless one of the following conditions is met:

  • Real scale is both supported and active and the plane tracker is found.
  • Real scale is not supported and the plane tracker is found.

To build this graph, you need a plane tracker real scale patch. To find this patch:

  1. With planeTracker0 selected, go to the Inspector.
  2. Under Interactions , and to the right of Patch , select Create, then Real-World Scale.
The Plane Tracker Real Scale patch.

This patch has two outputs that each send a boolean true/false signal.

  1. Real Scale Supported: A boolean output signal that’s true if the device supports real scale and false if real scale is unsupported.
  2. Real Scale Active: A boolean output signal that’s true once real scale is active and false when the device hasn’t received enough information yet to start real scale.

Example patch graph

In the example below, we built a patch graph so that a chair object is both hidden from users on newer devices until a real-scale signal is detected, and visible to users on unsupported devices.

A patch graph showing logic that can help to improve the user experience of real-scale effects.

In the example graph, the Or patch uses the signal received from both the purple Plane Tracker Real Scale and the Not patch to check which of the following conditions are true:

  • Real scale isn’t supported (First Boolean in Or patch is true).
  • Real scale is active (Second Boolean in Or patch is true).

When either boolean signal is true, the Or patch outputs a true signal to the First Boolean input in the And patch. The And patch checks this First Boolean signal and also checks the Second Boolean signal received from the planeTracker0 patch, which determines if the plane tracker is found or not.

The And patch only outputs a true signal to show the chair as visible if both the First and Second Boolean signals in the And patch are true, i.e.

  • Real scale is either not supported or real scale is active (determined by the Or patch).
  • The plane tracker is found (determined by the planeTracker0 patch).

If you’re only distributing your effect to devices with real scale, simplify your graph by disconnecting the top Real Scale supported output of the Plane Tracker Real Scale Patch and deleting the Not and OR patches:

A modified version of the above patch graph, for effects that are only going to be used on devices that support real-scale AR.

In this example graph, the And patch sends a signal to show the chair as visible once it’s checked that both the First Boolean and Second Boolean input signals are true, i.e:

  • Real scale is active.
  • The plane tracker is found.

Scripting

You can set up similar logic using scripting instead of patches.

The PlaneTracking module provided by the Spark AR API exposes signals that can be used to enable real scale in world effects.

The realScaleSupported read-only property returns a boolean signal indicating whether the device the effect is running on supports real world scale. The value of the signal is constant throughout the duration of the session.

The realScaleActive read-only property returns a boolean signal indicating whether the PlaneTracker in the scene is ready to display objects in real scale. If the device the effect is running on doesn’t support real scale, this signal will always return false.

Example JavaScript

// Load in the required modules
const Scene = require('Scene');
const Time = require('Time');
const PlaneTracking = require('PlaneTracking');


(async function() { // Enable async/await in JS [part 1]

  // Locate the plane tracker and object in the Scene
  const [planeTracker, object] = await Promise.all([
    Scene.root.findFirst('planeTracker0'),
    Scene.root.findFirst('object0')
  ]);

  // Set scale values to use depending on whether real scale
  // is supported on the device or not
  const realWorldScale = 1.0;
  const defaultScale = 0.60;

  // Hide the object and reduce its opacity
  object.hidden = true;
  object.opacity = 0.3;

  applyCorrectScale();


  // Checks whether real scale is supported on the device
  // the effect is running on and applies the appropriate scaling factor
  function applyCorrectScale(){

    Time.setTimeoutWithSnapshot({ realScaleSupported:   
    PlaneTracking.realScaleSupported}, (s) => {

      // Check if real scale is supported
      if (s.realScaleSupported){

        // If it is, scale the object to the 'realWorldScale' value
        setScale(object, realWorldScale);

        // Then, check if real scale is ready to use
        checkRealScaleReady();

      } else {

        // If real scale isn't supported, scale the object to 
        // the 'defaultScale' value instead
        setScale(object, defaultScale);

    // You can add additional logic to handle scenarios where
    // real scale isn't supported here
      }

    }, 500); // Runs the 'setTimeoutWithSnapshot' callback function after a delay
  }


  // Check if real scale is ready to use
  function checkRealScaleReady(){

    // Monitor the value of the 'realScaleActive' signal              
PlaneTracking.realScaleActive.monitor({fireOnInitialValue:true}).subscribe( (active) =>{

      // If real scale is ready to use, display the object
      if (active.newValue) {
        object.hidden = false;

      } else {
        // You can add logic to determine what happens while real scale 
        // isn't ready to use here
      }
    });
  }


  // Sets the x, y and z scale values of the object to 'scale'
  function setScale(sceneObject, scale){
    sceneObject.transform.scaleX = scale;
    sceneObject.transform.scaleY = scale;
    sceneObject.transform.scaleZ = scale;
  }

})(); // Enable async/await in JS [part 2]
        

Mirroring to ar player

When you mirror your real-scale effect, objects under the plane tracker will appear in their real-world size, relative to their position from the camera.

Was this article helpful?