Best approach for implementing Image Target + SLAM using Niantic Studio?

While I’ve worked in the Cloud Editor in the past, I’m new to Niantic Studio (and the new API) and I would really appreciate some help with writing a custom component that transfers an entity group from being pinned to an image target, to being SLAM-tracked.

Problem summary

Here’s the basic rundown of the project:
I have a mural of Martin Luther King on an office wall as an image target that, when scanned, displays a group of entities (a lectern and a set of three microphones). These entities are all parented to an empty object, called “mlk-content,” so that they can be positioned as a group. The entity-group is then parented to the image target (called, “mlkMural”):

Once the “mlk-content” entity group appears, I need for them to stay pinned in place within the room and remain visible/interactable, even when the mural image-target is no longer visible. In other words, I’m trying to enable users to look around the lectern and microphones, which means they will occasionally need to turn away from the mural.

Proposed design approach

My approach to this was to have the lectern/microphone entity group initially parented to the image target, so that they will be positioned relative to the mural, and then use a custom component called, “transferToWorldTracking.ts” that would do the following:

  1. listen for the image-target found event
  2. when found, it would store the entity group’s worldTransform into a variable
  3. re-parent the entity group from the image target, to a root level empty entity (called, “worldRoot”)
  4. re-apply the entity group’s worldTransform
  5. allow the entity group to remain SLAM-tracked from then on, so that it no longer needs the image target in view.

The transferring of the entity group from image-tracking to SLAM-tracking would only happen once, after the initial finding of the image target (and positioning of its child entities).

First, of all, is this a sound approach for handling this, or is there a better way?

Second, here is my custom component script, as far as I was able to figure it out:

Code snippet


import * as ecs from '@8thwall/ecs' 

ecs.registerComponent({
  name: 'transferToWorldTracking',
  schema: {
    imageAnchor: ecs.eid,
    imageAnchorName: ecs.string,
    contentToTransfer: ecs.eid,
    worldRoot: ecs.eid,
  },
  schemaDefaults: {
    imageAnchorName: '',
  },
  data: {
    transferred: ecs.boolean,
  },
  stateMachine: ({world, eid, schemaAttribute, dataAttribute}) => {
    ecs.defineState('default')
      .initial()
      .listen(world.events.globalId, 'reality.imagefound', (e) => {
        const {name} = e.data as any
        const {imageAnchorName} = schemaAttribute.get(eid)
        const {imageAnchor} = schemaAttribute.get(eid)
        const {contentToTransfer} = schemaAttribute.get(eid)
        const {worldRoot} = schemaAttribute.get(eid)

        if (name === imageAnchorName) {

          if (this.transferred) return
          this.transferred = true

          // store transform for the content attachd to image target

          // re-parent the content from the image target to the world (SLAM)
          world.setParent(contentToTransfer, worldRoot)

          // restore content's world transform now that it is pinned to world
          // world.transform.setWorldTransform()
        }
      })
  },
})

(I havent’ been able to figure out how to store the worldTransform without TypeError(s).)

Can anyone help me out with this, or at least point me in the right direction?
Thank you!!

I’m really close to releasing this as an example space in the Image Target sample project, however I’m currently blocked by a bug with the current implementation. I’ll do some more digging today to see if there’s a workaround I can do to get it released.

EDIT: Check the Image Target sample project :smiling_face_with_sunglasses:

Fantastic! I see the “Toggle SLAM” option in the Spaces selector, and it works beautifully!
Thank you, @GeorgeButler !!

1 Like

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.