InstantPlacementPoint

public class InstantPlacementPoint

Trackable Instant Placement point returned by Frame.hitTestInstantPlacement(float, float, float) .

If ARCore has an accurate 3D pose for the InstantPlacementPoint returned by Frame.hitTestInstantPlacement(float, float, float) it will start with tracking method InstantPlacementPoint.TrackingMethod.FULL_TRACKING . Otherwise, it will start with tracking method InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE , and will transition to InstantPlacementPoint.TrackingMethod.FULL_TRACKING once ARCore has an accurate 3D pose. Once the tracking method is InstantPlacementPoint.TrackingMethod.FULL_TRACKING it will not revert to InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE .

When the tracking method changes from InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE in one frame to InstantPlacementPoint.TrackingMethod.FULL_TRACKING in the next frame, the pose will jump from its initial location based on the provided approximate distance to a new location at an accurate distance.

This instantaneous change in pose will change the apparent scale of any objects that are anchored to the InstantPlacementPoint . That is, an object will suddenly appear larger or smaller than it was in the previous frame.

To avoid the visual jump due to the sudden change in apparent object scale, use the following procedure:

  1. Keep track of the pose and tracking method of the InstantPlacementPoint in each frame.
  2. Wait for the tracking method to change to InstantPlacementPoint.TrackingMethod.FULL_TRACKING .
  3. Use the pose from the previous frame and the pose in the current frame to determine the object's distance to the device in both frames.
  4. Calculate the apparent change in scale due to the change in distance from the camera.
  5. Adjust the scale of the object to counteract the perceived change in scale, so that visually the object does not appear to change in size.
  6. Optionally, smoothly adjust the scale of the object back to its original value over several frames.

The following snippet shows how to use Instant Placement to place one object. The wrapper below shows how to use steps 1 through 5 to avoid the visual jump.

  class 
 ArPlacementActivity 
  
 { 
  
 private 
  
 Session 
  
 session 
  
 = 
  
 null 
 ; 
  
 private 
  
 placementIsDone 
  
 = 
  
 false 
 ; 
  
 public 
  
 void 
  
 createSession 
 () 
  
 { 
  
 session 
  
 = 
  
 new 
  
 Session 
 ( 
 this 
 ); 
  
 Config 
  
 config 
  
 = 
  
 new 
  
 Config 
 ( 
 session 
 ); 
  
 config 
 . 
 setInstantPlacementMode 
 ( 
 InstantPlacementMode 
 . 
 LOCAL_Y_UP 
 ); 
  
 session 
 . 
 configure 
 ( 
 config 
 ); 
  
 } 
  
 public 
  
 void 
  
 onDrawFrame 
 ( 
 GL10 
  
 gl 
 ) 
  
 { 
  
 Frame 
  
 frame 
  
 = 
  
 session 
 . 
 update 
 (); 
  
 // Place an object on tap. 
  
 if 
  
 ( 
 ! 
 placementIsDone 
 && 
 didUserTap 
 ()) 
  
 { 
  
 // Use estimated distance from the user's device to the real world, based 
  
 // on how we expect the app to be used by users. 
  
 float 
  
 approximateDistanceMeters 
  
 = 
  
 1.0f 
 ; 
  
 List<HitResult> 
  
 results 
  
 = 
  
 frame 
 . 
 hitTestInstantPlacement 
 ( 
 tapX 
 , 
  
 tapY 
 , 
  
 approximateDistanceMeters 
 ); 
  
 if 
  
 ( 
 ! 
 results 
 . 
 isEmpty 
 ()) 
  
 { 
  
 HitResult 
  
 hit 
  
 = 
  
 results 
 . 
 get 
 ( 
 0 
 ); 
  
 InstantPlacementPoint 
  
 point 
  
 = 
  
 ( 
 InstantPlacementPoint 
 ) 
  
 hit 
 . 
 getTrackable 
 (); 
  
 anchor 
  
 = 
  
 point 
 . 
 createAnchor 
 ( 
 point 
 . 
 getPose 
 ()); 
  
 placementIsDone 
  
 = 
  
 true 
 ; 
  
 disableInstantPlacement 
 (); 
  
 } 
  
 } 
  
 } 
  
 private 
  
 void 
  
 disableInstantPlacement 
 () 
  
 { 
  
 // When the placement is done, you can disable Instant Placement to save computing. 
  
 Config 
  
 config 
  
 = 
  
 new 
  
 Config 
 ( 
 session 
 ); 
  
 config 
 . 
 setInstantPlacementMode 
 ( 
 InstantPlacementMode 
 . 
 DISABLED 
 ); 
  
 session 
 . 
 configure 
 ( 
 config 
 ); 
  
 } 
  
 } 
 

This wrapper of InstantPlacementPoint can be used to offset the apparent scale shift that occurs when the tracking method changes from InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE to InstantPlacementPoint.TrackingMethod.FULL_TRACKING . For AR experiences where a sudden apparent scale change is acceptable, no wrapper is required.

  class 
 WrappedInstantPlacement 
  
 { 
  
 public 
  
 InstantPlacementPoint 
  
 point 
 ; 
  
 public 
  
 TrackingMethod 
  
 previousTrackingMethod 
 ; 
  
 public 
  
 float 
  
 previousDistanceToCamera 
 ; 
  
 public 
  
 float 
  
 scaleFactor 
  
 = 
  
 1.0f 
 ; 
  
 public 
  
 WrappedInstantPlacement 
 ( 
  
 InstantPlacementPoint 
  
 point 
 , 
  
 TrackingMethod 
  
 previousTrackingMethod 
 , 
  
 float 
  
 previousDistanceToCamera 
 ) 
  
 { 
  
 this 
 . 
 point 
  
 = 
  
 point 
 ; 
  
 this 
 . 
 previousTrackingMethod 
  
 = 
  
 previousTrackingMethod 
 ; 
  
 this 
 . 
 previousDistanceToCamera 
  
 = 
  
 previousDistanceToCamera 
 ; 
  
 } 
  
 } 
  
 ArrayList<WrappedInstantPlacement> 
  
 wrappedPoints 
  
 = 
  
 new 
  
 ArrayList<WrappedInstantPlacement> 
 (); 
  
 public 
  
 void 
  
 onDrawFrame 
 ( 
 GL10 
  
 gl 
 ) 
  
 { 
  
 Frame 
  
 frame 
  
 = 
  
 session 
 . 
 update 
 (); 
  
 // Place an object on tap. 
  
 if 
  
 ( 
 didUserTap 
 ()) 
  
 { 
  
 // Use estimated distance from the user's device to the real world, based 
  
 // on how we expect the app to be used by users. 
  
 float 
  
 approximateDistanceMeters 
  
 = 
  
 2.0f 
 ; 
  
 // Returns a single result if the hit test was successful. 
  
 List<HitResult> 
  
 results 
  
 = 
  
 frame 
 . 
 hitTestInstantPlacement 
 ( 
 tapX 
 , 
  
 tapY 
 , 
  
 approximateDistanceMeters 
 ); 
  
 for 
  
 ( 
 HitResult 
  
 hit 
  
 : 
  
 results 
 ) 
  
 { 
  
 InstantPlacementPoint 
  
 point 
  
 = 
  
 ( 
 InstantPlacementPoint 
 ) 
  
 hit 
 . 
 getTrackable 
 (); 
  
 wrappedPoints 
 . 
 add 
 ( 
  
 new 
  
 WrappedInstantPlacement 
 ( 
 point 
 , 
  
 point 
 . 
 getTrackingMethod 
 (), 
  
 distance 
 ( 
 camera 
 . 
 getPose 
 (), 
  
 point 
 . 
 getPose 
 ()))); 
  
 } 
  
 } 
  
 for 
  
 ( 
 WrappedInstantPlacement 
  
 wrappedPoint 
  
 : 
  
 wrappedPoints 
 ) 
  
 { 
  
 InstantPlacementPoint 
  
 point 
  
 = 
  
 wrappedPoint 
 . 
 point 
 ; 
  
 if 
  
 ( 
 point 
 . 
 getTrackingState 
 () 
  
 == 
  
 TrackingState 
 . 
 STOPPED 
 ) 
  
 { 
  
 wrappedPoints 
 . 
 remove 
 ( 
 wrappedPoint 
 ); 
  
 continue 
 ; 
  
 } 
  
 if 
  
 ( 
 point 
 . 
 getTrackingState 
 () 
  
 == 
  
 TrackingState 
 . 
 PAUSED 
 ) 
  
 { 
  
 continue 
 ; 
  
 } 
  
 if 
  
 ( 
 point 
 . 
 getTrackingMethod 
 () 
  
 == 
  
 TrackingMethod 
 . 
 SCREENSPACE_WITH_APPROXIMATE_DISTANCE 
 ) 
  
 { 
  
 // Continue to use estimated depth and pose. Record distance to camera for use in 
  
 // the next frame if the transition to full tracking happens. 
  
 wrappedPoint 
 . 
 previousDistanceToCamera 
  
 = 
  
 distance 
 ( 
 point 
 . 
 getPose 
 (), 
  
 camera 
 . 
 getPose 
 ()); 
  
 } 
  
 else 
  
 if 
  
 ( 
 point 
 . 
 getTrackingMethod 
 () 
  
 == 
  
 TrackingMethod 
 . 
 FULL_TRACKING 
 ) 
  
 { 
  
 if 
  
 ( 
 wrappedPoint 
 . 
 previousPoseType 
  
 == 
  
 TrackingMethod 
 . 
 SCREENSPACE_WITH_APPROXIMATE_DISTANCE 
 ) 
  
 { 
  
 // Transition from estimated pose to real pose. Adjust object scale to 
  
 // counter-act apparent change is size due to pose jump. 
  
 wrappedPoint 
 . 
 scaleFactor 
  
 = 
  
 distance 
 ( 
 point 
 . 
 getPose 
 (), 
  
 camera 
 . 
 getPose 
 ()) 
  
 / 
  
 wrappedPoint 
 . 
 previousDistanceToCamera 
 ); 
  
 // TODO: Apply the scale factor to the model. 
  
 // ... 
  
 previousPoseType 
  
 = 
  
 TrackingMethod 
 . 
 FULL_TRACKING 
 ; 
  
 } 
  
 } 
  
 } 
  
 } 
 

Nested Classes

Public Methods

Anchor
createAnchor ( Pose pose)
Creates an anchor that is attached to this trackable, using the given initial pose in the world coordinate space.
boolean
equals ( Object obj)
Indicates whether some other object is a Trackable referencing the same logical trackable as this one.
Collection < Anchor >
getAnchors ()
Gets the Anchors attached to this trackable.
Pose
getPose ()
Gets the pose of the Instant Placement point.
InstantPlacementPoint.TrackingMethod
TrackingState
getTrackingState ()
Gets this trackable's TrackingState .
int
hashCode ()
Returns a hash code value for the object.

Inherited Methods

Public Methods

createAnchor

 public 
  
  Anchor 
 
  
 createAnchor 
 ( 
  
  Pose 
 
  
 pose 
 ) 

Creates an anchor that is attached to this trackable, using the given initial pose in the world coordinate space. The type of trackable will determine the semantics of attachment and how the anchor's pose will be updated to maintain this relationship. Note that the relative offset between the pose of multiple anchors attached to a trackable may adjust slightly over time as ARCore updates its model of the world.

Details
Parameters
pose

equals

 public 
  
 boolean 
  
 equals 
 ( 
  
  Object 
 
  
 obj 
 ) 

Indicates whether some other object is a Trackable referencing the same logical trackable as this one.

Details
Parameters
obj
the reference object with which to compare.
Returns
true if this object is the same as the obj argument; false otherwise.
See Also

getAnchors

 public 
  
  Collection 
 
< Anchor 
>  
 getAnchors 
 () 

Gets the Anchors attached to this trackable.

getPose

 public 
  
  Pose 
 
  
 getPose 
 () 

Gets the pose of the Instant Placement point. Use getTrackingMethod() to determine whether depth and scale are accurate or are based on the estimated depth provided to Frame.hitTestInstantPlacement(float, float, float) .

If the tracking method is InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE , the pose will be based on the approximate distance provided to Frame.hitTestInstantPlacement(float, float, float) .

When the tracking method changes from InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE to InstantPlacementPoint.TrackingMethod.FULL_TRACKING , there will be a noticeable pose jump as the depth changes, from one that's estimated based on the approximate distance provided to Frame.hitTestInstantPlacement(float, float, float) to the actual distance as determined by ARCore.

Consequently, the on-screen size, or apparent scale, of any object anchored to the pose will appear to change abruptly. To prevent a visible pop in 3D asset size when the tracking method changes, the scale of the object can be adjusted to counteract the apparent scale change when the tracking method changes. See the InstantPlacementPoint class-level documentation for an example.

getTrackingMethod

 public 
  
  InstantPlacementPoint 
 . 
 TrackingMethod 
 
  
 getTrackingMethod 
 () 

getTrackingState

 public 
  
  TrackingState 
 
  
 getTrackingState 
 () 

Gets this trackable's TrackingState .

hashCode

 public 
  
 int 
  
 hashCode 
 () 

Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by HashMap .

Details
Returns
a hash code value for this object.
See Also
Design a Mobile Site
View Site in Mobile | Classic
Share by: