What's New in Vuforia 4

Object Recognition : Detect and track rigid 3D objects. Objects must have some texture or detail.

Vuforia Object Scanner : A new android app that allows you to scan your 3D object and create an Object Target

Usage Reports : A new analytics capability that allows you to measure Recos per target. Usage is available for targets in both device and cloud target databases.

iOS 64 bit Support : developers may build 64 bit vuforia apps for iOS

License Manager : All apps now need a license to run. The License Manager is a new tool, available on the Vuforia developer portal that allows you to create and manage app license keys. Each app must have its own unique license key. The same license key may be used by an app if it is deployed on more than one operating system platform, but the license key may not be shared across apps.

Developer Library : the newly redesigned developer library, replaces the Dev Guide, provides concise, easy-to-read articles that include practical advice from the developer forums. The library includes a wealth of knowledge, with feature details, code snippets, best practices, how-to-guides, technical FAQs and more.

Click here to see the new license options. developer.vuforia.com/pricing

Changes

There are a a few changes to the Vuforia API with 4.0 arising from the introduction of Object Recognition and a redesign of the Smart Terrain API to support more sophisticated reconstruction handling. This guide details these changes and provides instructions on how to use the new APIs and how to transition your existing code to use the features of Vuforia 4.0.

For instructions on how to upgrade your existing Vuforia projects to 4.0, See: How To Migrate Your Existing Apps

For instructions on how to enable your iOS Vuforia apps to support iOS 64bit, See: iOS 64 Bit Migration

Introducing the Object Tracker

We have refactored the ImageTracker into a unified ObjectTracker class that supports the detection and tracking of 3D objects along with Image, Cylinder and Multi Targets.

  • ObjectTarget ( 3D objects )
  • CylinderTarget (parametric 3D object)
  • MultiTarget (composite of planar objects)
  • ImageTarget (planar object)

The relationships of the Object Tracker are as follows:

  • ObjectTracker tracks ObjectTargets, along with ImageTargets CylinderTargets and MultiTargets
  • ObjectTracker produces an ObjectTargetResult, which can be similarly specialized for image based targets.
  • The ObjectTarget is defined in a Device Database in the same way that Image, Cylinder and MultiTargets are.
Developer s Note: The methods of ImageTracker now belong to the ObjectTracker. Developers can easily transition to the new API by just replacing any reference of ImageTracker to ObjectTracker in their code.

Class definitions:

ObjectTarget

The ObjectTarget class represents a unified target definition for the ObjectTracker. ImageTargets, MultiTargets and CylinderTargets are now specializations of ObjectTarget.

The ObjectTarget class provides parent properties such as the size of the target (3D Vector), therefore this property is valid for any specialized target type. It offers a simple way for developers to get the size any ObjectTracker s trackable (or its name), without considering their specific type, which is useful for parsing results generically.

The size property can be seen as the bounding box of any of the existing objects. For ImageTarget, the last component of the size vector will be 0 (a flat object). For CylinderTarget, the size will be computed based on existing procedural parameters (e.g. side-length, diameter, etc). For MultiTarget, size is currently not supported.
Developer s Note: You will have to change your getSize()/setSize() method in ImageTarget from Vec2F to Vec3F. No change is required for CylinderTarget.

ObjectTargetResult

ObjectTargetResults are published in the State object and can be accessed from the Renderer or from the QCAR::UpdateCallback. ObjectTargetResult corresponds to the pose of an Object Target or from a derived target result.

Specialized targets ( ImageTarget, MultiTarget, CylinderTarget ) inherit their result from the ObjectTargetResult and only publish their specialized result in the State object.
Developer s Note: If your apps iterate over the list of target results from the State object in their their application logic, you won t have to modify existing code parsing the list of results, but only add a new conditional statement for parsing ObjectTargetResult. If you need to differentiate between ObjectTracker s target result type (or associated Trackable), you will need to iterate on the derived type before the parent type, i.e. ObjectTargetResult should be verified after ImageTargetResult, CylinderTargetResult or MultiTargetResult. If you don t need to differentiate on the type of ObjectTracker s target result type (or associated Trackable), you only need to use ObjectTargetResult type to get the pose of all the trackable results from ObjectTracker.


example:

for (int r = 0; r < state.getNumTrackableResults(); ++ r)
    {
        const QCAR::TrackableResult* trackableResult = state.getTrackableResult(r);
        
        if (trackableResult->isOfType(ImageTargetResult::getClassType()))
        {
            renderCube(colourRed, trackableResult->getPose());
        }
        else if (trackableResult->isOfType(MarkerResult::getClassType()))
        {
            renderCube(colourRed, trackableResult->getPose());
        }
        else if (trackableResult->isOfType(MultiTargetResult::getClassType()))
        {
            renderCube(colourRed, trackableResult->getPose());
        }
        else if (trackableResult->isOfType(CylinderTargetResult::getClassType()))
        {
            renderCube(colourRed, trackableResult->getPose());
        } 
        else if (trackableResult->isOfType(ObjectTargetResult::getClassType()))
        {
            static const QCAR::Vec3F rightBodyTargetScale(40.f, 40.f, 40.f);
            renderCube(colourRed, trackableResult->getPose(), &rightBodyTargetScale);
        }
     
    }

DataSet

The same DataSet class that was used for ImageTracker now supports loading of ObjectTarget trackable.

This is an example of how to load and activate datasets using the ObjectTracker.
QCAR::TrackerManager& trackerManager = TrackerManager::getInstance();
    QCAR::ObjectTracker* objectTracker = static_cast<QCAR::ObjectTracker*>(trackerManager.initTracker(QCAR::ObjectTracker::getClassType()));

    QCAR::DataSet* dataSetOt1 = objectTracker->createDataSet();
    dataSetOt1->load("car.xml", QCAR::STORAGE_ABSOLUTE);
    objectTracker->activateDataSet(dataSetOt1);
       (init camera) 
    objectTracker->start();

A new design pattern for Smart Terrain

We've redesigned the SmartTerrainTracker s reconstruction API into a command pattern and moved that into a new class named SmartTerrainBuilder which manages Reconstruction objects.

The workflow for initializing Smart Terrain has changed:

Initialize the ObjectTracker and SmartTerrainTracker
Initialize the SmartTerrainBuilder module
Load the image target dataset and activate it
Create a ReconstructionFromTarget object passing in the image target that we want to start reconstruction from and register a callback.




We've also defined a specialization of the Reconstruction object, which is named ReconstructionFromTarget. We kept SmartTerrainTracker as the module responsible for tracking Surfaces and Props and the hierarchy of SmartTerrainTrackable with Surfaces and Props has remained the same.

Smart Terrain Tracker

class QCAR_API SmartTerrainTracker : public Tracker
{
public:

    /// Returns the tracker class' type
    static Type getClassType();
    
    /// Set the scaling factor for SmartTerrain trackables from millimeters 
    /// into scene units.
    /* 
     * The default scaling factor is 1.0.
     * Returns false if the tracker is not in the stopped state, true if the 
     * scale is non-zero and we are able to set the scale factor.
     */
    virtual bool setScaleToMillimeter(float scaleFactor) =0;

    /// Gets the scaling factor from millimeters to scene units.
    virtual float getScaleToMillimeter() const = 0;

    /// Gets a reference to the SmartTerrainBuilder.
    virtual SmartTerrainBuilder& getSmartTerrainBuilder() = 0;
};

SmartTerrainTracker is responsible for tracking reconstructed Surfaces and Props and is the owner of the SmartTerrainBuilder object.

Smart Terrain Builder

class QCAR_API SmartTerrainBuilder : private NonCopyable
{
public:

    /// Returns the Tracker class' type
    static Type getClassType();    

    /// Returns the Trackable instance's type
    virtual Type getType() const = 0;

    /// Checks whether the builder instance's type equals or has been
    /// derived from a give type
    virtual bool isOfType(Type type) const = 0;

    // Factory method for creating an instance of a reconstruction 
    /* 
     * Valid types are ReconstructionFromEnvironment and ReconstructionFromTarget.
     * Passing in any other type will cause NULL to be returned.
     */
    virtual Reconstruction* createReconstruction(Type type) = 0;

    /// Method for cleaning up a previously created reconstruction object
    virtual bool destroyReconstruction(Reconstruction* reco) = 0;

    /// Returns the number of reconstructions registered with the builder.
    virtual unsigned int getNumReconstructions() const = 0;

    /// Adds a reconstruction to the builder and starts it.
    virtual bool addReconstruction(Reconstruction* obj) = 0; 

    /// Removes a reconstruction from the builder and cleans up any generated 
    /// trackables as well.
    virtual bool removeReconstruction(unsigned int index) = 0;

    /// Gets the reconstruction at the given index.
    virtual Reconstruction* getReconstruction(unsigned int index) const = 0;

    /// Initializes the builder, returning true if able to.
    virtual bool init() = 0;

    /// Deinitializes the builder, return true if able to do so.
    virtual bool deinit() = 0;
};

When a reconstruction is added to the builder, the builder attempts to start the object. Removing a reconstruction object causes the reconstruction to be removed.

Reconstruction

class QCAR_API Reconstruction : private NonCopyable
{
public:

    /// Returns the reconstruction class' type
    static Type getClassType();

    /// Returns the instance's type
    virtual Type getType() const = 0;

    /// Set the maximum extent of the smart terrain in scene units
    /**
     *  The ground plane will not expand outside of this rectangle.
     *  Objects are only created inside the rectangle. Objects on the boundary
     *  of the rectangle will be cut off.
     */
    virtual bool setMaximumArea(const Rectangle& rect) = 0;

    /// Get the maximum extent of the smart terrain in scene units.
    /**
     *  Returns false if no maximum extent has been defined.
     */
    virtual bool getMaximumArea(Rectangle& rect) const = 0;

    /// Define how much the SmartTerrain ground plane mesh is diminished.
    Virtual void setNavMeshPadding(float padding) = 0;

    /// Smart terrain reconstruction is started or continued if it was 
    /// previously stopped.
    virtual bool start() = 0;

    /// Smart terrain reconstruction is stopped, existing trackables are 
    /// still tracked.
    virtual bool stop() = 0;

    /// Resets the reconstruction, clearing out existing trackables.    
    /**
     *  The ground plane and all objects are cleared.
     *  The scene has to be scanned completely again.
     */
    virtual bool reset() = 0;

    /// Returns true if the terrain and objects are being updated
    virtual bool isReconstructing() const = 0;

protected:
    /// Destructor.
    virtual ~Reconstruction() {}
};

The Reconstruction class is the core interface for encapsulating a reconstruction operation.

class QCAR_API ReconstructionFromTarget : public Reconstruction
{
public:

    /// Returns the reconstruction class' type
    static Type getClassType();

    /// Define the trackable which is used for starting smart terrain.
    /**
     *  The occluderVolume is an axis-aligned box, which defines the area 
     *  where the table is occluded by the target and its surrounding object.
     */
    virtual bool setInitializationTarget(const Trackable* trackable,
                                         const Box3D& occluderVolume) = 0;

    /// Define trackable which is used for starting smart terrain.
    /**
     *  The occluderVolume is an axis-aligned box, which defines the area 
     *  where the table is occluded by the target and its surrounding object.     
     *  offsetToOccluderPose is a pose matrix that allows to define a
     *  translational offset and rotation of the occluder volume with respect
     *  to the initialization target.
     */
    virtual bool setInitializationTarget(const Trackable* trackable,
                                         const Box3D& occluderVolume,
                                         const Matrix34F& offsetToOccluderPose) = 0;

    /// Returns the trackable used for initialization.
    /**
     *  Returns null if no initialization target has been defined.
     */
    virtual const Trackable* getInitializationTarget() const = 0;

protected:
    virtual ~ReconstructionFromTarget() {}
};

The ReconstructionFromTarget initializes the reconstruction process from an ImageTarget, MultiTarget, or CylinderTarget types - this method is not compatible with ObjectTargets for 3D objects.
The scale parameter has also been moved from the setInitializationTarget API into the SmartTerrainTracker so that the scale factor is uniform across reconstructions for when we support multiple reconstruction.

A new namespace in Unity

Vuforia 4.0 also introduces a new Vuforia namespace. You'll need to add the following statement at the top of any scripts that reference the Vuforia API.

using Vuforia;