//-----------------------------------------------------------------------
//
//
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
//-----------------------------------------------------------------------
// Modifications copyright © 2020 Unity Technologies ApS
#if AR_FOUNDATION_PRESENT || PACKAGE_DOCS_GENERATION
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Unity.XR.CoreUtils;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.XR.Interaction.Toolkit.Utilities;
namespace UnityEngine.XR.Interaction.Toolkit.AR
{
///
/// Provides helper functions for common functionality to transform objects in AR.
///
[Obsolete("GestureTransformationUtility has been replaced in function by the ARTransformer. Please use the ARTransformer instead.")]
public static class GestureTransformationUtility
{
///
/// Represents the alignment of a plane where translation is allowed.
///
///
///
public enum GestureTranslationMode
{
///
/// Allow translation when the plane is horizontal.
///
Horizontal,
///
/// Allow translation when the plane is vertical.
///
Vertical,
///
/// Allow translation on any plane.
///
Any,
}
///
/// Max amount (inches) to offset the screen touch in .
/// The actual amount depends on the angle of the camera relative.
/// The further downward the camera is angled, the more the screen touch is offset.
///
const float k_MaxScreenTouchOffset = 0.4f;
///
/// In , when the camera is closer than this value to the object,
/// reduce how much the object hovers.
///
const float k_HoverDistanceThreshold = 1f;
static XROrigin s_XROrigin;
#pragma warning disable CS0618 // ARSessionOrigin is deprecated in 5.0, but kept to support older AR Foundation versions
static ARSessionOrigin s_ARSessionOrigin;
#pragma warning restore CS0618
static ARRaycastManager s_ARRaycastManager;
static ARPlaneManager s_ARPlaneManager;
static readonly List s_Hits = new List();
static bool TryGetTrackableManager([CanBeNull] XROrigin sessionOrigin, out ARRaycastManager raycastManager) =>
TryGetTrackableManager(sessionOrigin, ref s_ARRaycastManager, out raycastManager);
static bool TryGetTrackableManager([CanBeNull] XROrigin sessionOrigin, out ARPlaneManager planeManager) =>
TryGetTrackableManager(sessionOrigin, ref s_ARPlaneManager, out planeManager);
static bool TryGetTrackableManager([CanBeNull] XROrigin sessionOrigin, ref T cachedManager, out T manager)
{
// This method is used to get the Trackable Manager component on the XROrigin GameObject
// by caching the manager component from the most recently used XROrigin.
// There is typically only one XROrigin, so this serves as a simple cache to avoid
// doing a GetComponent call to get the manager component each time.
if (sessionOrigin == null)
{
if (s_XROrigin == null)
{
cachedManager = default;
if (!ComponentLocatorUtility.TryFindComponent(out s_XROrigin))
{
Debug.LogWarning($"Could not find {nameof(XROrigin)} in scene.");
manager = default;
return false;
}
}
}
else if (sessionOrigin != s_XROrigin)
{
s_XROrigin = sessionOrigin;
cachedManager = default;
}
// The cached Trackable Managers are associated with an XROrigin.
// Update and use cached version
var found = cachedManager != null || s_XROrigin.TryGetComponent(out cachedManager);
manager = cachedManager;
return found;
}
static bool TryGetSessionOrigin(out XROrigin sessionOrigin)
{
if (s_XROrigin == null)
{
if (!ComponentLocatorUtility.TryFindComponent(out s_XROrigin))
{
Debug.LogWarning($"Could not find {nameof(XROrigin)} in scene.");
sessionOrigin = s_XROrigin;
return false;
}
}
sessionOrigin = s_XROrigin;
return true;
}
#region Deprecated ARSessionOrigin overloads
#pragma warning disable CS0618 // ARSessionOrigin is deprecated in 5.0, but kept to support older AR Foundation versions
static bool TryGetTrackableManager([CanBeNull] ARSessionOrigin sessionOrigin, out ARRaycastManager raycastManager) =>
TryGetTrackableManager(sessionOrigin, ref s_ARRaycastManager, out raycastManager);
static bool TryGetTrackableManager([CanBeNull] ARSessionOrigin sessionOrigin, out ARPlaneManager planeManager) =>
TryGetTrackableManager(sessionOrigin, ref s_ARPlaneManager, out planeManager);
static bool TryGetTrackableManager([CanBeNull] ARSessionOrigin sessionOrigin, ref T cachedManager, out T manager)
{
// This method is used to get the Trackable Manager component on the ARSessionOrigin GameObject
// by caching the manager component from the most recently used ARSessionOrigin.
// There is typically only one ARSessionOrigin, so this serves as a simple cache to avoid
// doing a GetComponent call to get the manager component each time.
if (sessionOrigin == null)
{
if (s_ARSessionOrigin == null)
{
cachedManager = default;
if (!ComponentLocatorUtility.TryFindComponent(out s_ARSessionOrigin))
{
Debug.LogWarning($"Could not find {nameof(ARSessionOrigin)} in scene.");
manager = default;
return false;
}
}
}
else if (sessionOrigin != s_ARSessionOrigin)
{
s_ARSessionOrigin = sessionOrigin;
cachedManager = default;
}
// The cached Trackable Managers are associated with an ARSessionOrigin.
// Update and use cached version
var found = cachedManager != null || s_ARSessionOrigin.TryGetComponent(out cachedManager);
manager = cachedManager;
return found;
}
static bool TryGetSessionOrigin(out ARSessionOrigin sessionOrigin)
{
if (s_ARSessionOrigin == null)
{
if (!ComponentLocatorUtility.TryFindComponent(out s_ARSessionOrigin))
{
Debug.LogWarning($"Could not find {nameof(ARSessionOrigin)} in scene.");
sessionOrigin = s_ARSessionOrigin;
return false;
}
}
sessionOrigin = s_ARSessionOrigin;
return true;
}
#pragma warning restore CS0618
#endregion
///
/// Cast a ray from a point in screen space against trackables, i.e., detected features such as planes.
/// Can optionally fallback to hit test against Colliders in the loaded Scenes when no trackables were hit.
///
///
/// Unity uses the 3D physics scene of the camera when performing the fallback ray cast.
///
/// The point, in device screen pixels, from which to cast.
/// Contents are replaced with the ray cast results, if successful.
/// The used for ray casting.
/// (Optional) The types of trackables to cast against.
/// (Optional) The that Unity uses during an additional ray cast when no trackables are hit.
/// Defaults to Nothing which skips the fallback ray cast.
/// Returns if the ray cast hit a trackable in the or if the fallback ray cast hit.
/// Otherwise, returns .
public static bool Raycast(
Vector2 screenPoint,
List hitResults,
XROrigin sessionOrigin,
#if AR_FOUNDATION_4_2_OR_NEWER
TrackableType trackableTypes = TrackableType.AllTypes,
#else
TrackableType trackableTypes = TrackableType.All,
#endif
int fallbackLayerMask = 0)
{
if ((sessionOrigin != null || TryGetSessionOrigin(out sessionOrigin)) &&
TryGetTrackableManager(sessionOrigin, out ARRaycastManager raycastManager) &&
raycastManager.Raycast(screenPoint, hitResults, trackableTypes))
{
return true;
}
// No hits on trackables, try debug planes
hitResults.Clear();
const TrackableType hitType = TrackableType.PlaneWithinPolygon;
if (fallbackLayerMask == 0 || (trackableTypes & hitType) == 0)
return false;
var camera = sessionOrigin != null ? sessionOrigin.Camera : Camera.main;
if (camera == null)
return false;
var ray = camera.ScreenPointToRay(screenPoint);
if (camera.gameObject.scene.GetPhysicsScene().Raycast(ray.origin, ray.direction, out var hit, Mathf.Infinity, fallbackLayerMask))
{
var transform = sessionOrigin != null ? sessionOrigin.transform : hit.collider.transform;
hitResults.Add(new ARRaycastHit(
new XRRaycastHit(
TrackableId.invalidId,
new Pose(hit.point, Quaternion.LookRotation(Vector3.forward, hit.normal)),
hit.distance,
hitType),
hit.distance,
#if AR_FOUNDATION_4_1_OR_NEWER
transform, null));
#else
transform));
#endif
return true;
}
return false;
}
///
/// Calculates the best position to place an object in AR based on screen position.
/// Could be used for tapping a location on the screen, dragging an object, or using a fixed
/// cursor in the center of the screen for placing and moving objects.
///
/// Returns the best placement position.
/// Position of the parent anchor, i.e., where the
/// object is before translation starts.
/// Location on the screen in pixels to place the object at.
/// The starting height of the plane to place the object on.
/// How much should the object hover above the groundingPlane
/// before it has been placed.
/// The maximum distance allowed to translate the object.
/// The translation mode, indicating the plane types allowed.
///
/// The used for ray casting.
/// (Optional) The types of trackables to cast against.
/// (Optional) The that Unity uses during
/// an additional ray cast when no trackables are hit. Defaults to Nothing which skips the fallback ray cast.
///
/// Unity places objects along the x/z of the grounding plane. When placed on an AR plane
/// below the grounding plane, the object will drop straight down onto it in world space.
/// This prevents the object from being pushed deeper into the scene when moving from a
/// higher plane to a lower plane. When moving from a lower plane to a higher plane, this
/// function returns a new groundingPlane to replace the old one.
///
public static Placement GetBestPlacementPosition(
Vector3 currentAnchorPosition,
Vector2 screenPosition,
float groundingPlaneHeight,
float hoverOffset,
float maxTranslationDistance,
GestureTranslationMode gestureTranslationMode,
XROrigin sessionOrigin,
TrackableType trackableTypes = TrackableType.PlaneWithinPolygon,
int fallbackLayerMask = 0)
{
var result = new Placement();
if (sessionOrigin == null)
TryGetSessionOrigin(out sessionOrigin);
var camera = sessionOrigin != null ? sessionOrigin.Camera : Camera.main;
if (camera == null)
return result;
var cameraTransform = camera.transform;
result.updatedGroundingPlaneHeight = groundingPlaneHeight;
// Get the angle between the camera and the object's down direction.
var angle = 90f - Vector3.Angle(cameraTransform.forward, Vector3.down);
var touchOffsetRatio = Mathf.Clamp01(angle / 90f);
var screenTouchOffset = touchOffsetRatio * k_MaxScreenTouchOffset;
screenPosition.y += GestureTouchesUtility.InchesToPixels(screenTouchOffset);
var hoverRatio = Mathf.Clamp01(angle / 45f);
hoverOffset *= hoverRatio;
var distance = (cameraTransform.position - currentAnchorPosition).magnitude;
var distanceHoverRatio = Mathf.Clamp01(distance / k_HoverDistanceThreshold);
hoverOffset *= distanceHoverRatio;
// The best estimate of the point in the plane where the object will be placed:
Vector3 groundingPoint;
// Get the ray to cast into the scene from the perspective of the camera.
if (Raycast(screenPosition, s_Hits, sessionOrigin, trackableTypes, fallbackLayerMask))
{
if (!TryGetTrackableManager(sessionOrigin, out ARPlaneManager planeManager))
return result;
var firstHit = s_Hits[0];
var plane = planeManager.GetPlane(firstHit.trackableId);
if (plane == null || IsPlaneTypeAllowed(gestureTranslationMode, plane.alignment))
{
// Avoid detecting the back of existing planes.
if (Vector3.Dot(cameraTransform.position - firstHit.pose.position,
firstHit.pose.rotation * Vector3.up) < 0f)
return result;
// Don't allow hovering for vertical or horizontal downward facing planes.
if (plane == null ||
plane.alignment == PlaneAlignment.Vertical ||
plane.alignment == PlaneAlignment.HorizontalDown ||
plane.alignment == PlaneAlignment.HorizontalUp)
{
groundingPoint = LimitTranslation(
firstHit.pose.position, currentAnchorPosition, maxTranslationDistance);
if (plane != null)
{
result.placementPlane = plane;
result.hasPlane = true;
}
result.hasPlacementPosition = true;
result.placementPosition = groundingPoint;
result.hasHoveringPosition = true;
result.hoveringPosition = groundingPoint;
result.updatedGroundingPlaneHeight = groundingPoint.y;
result.placementRotation = firstHit.pose.rotation;
return result;
}
}
else
{
// Plane type not allowed.
return result;
}
}
// Return early if the camera is pointing upwards.
if (angle < 0f)
{
return result;
}
// If the grounding point is lower than the current grounding plane height, or if the
// ray cast did not return a hit, then we extend the grounding plane to infinity, and do
// a new ray cast into the scene from the perspective of the camera.
var cameraRay = camera.ScreenPointToRay(screenPosition);
var groundingPlane =
new Plane(Vector3.up, new Vector3(0f, groundingPlaneHeight, 0f));
// Find the hovering position by casting from the camera onto the grounding plane
// and offsetting the result by the hover offset.
if (groundingPlane.Raycast(cameraRay, out var enter))
{
groundingPoint = LimitTranslation(
cameraRay.GetPoint(enter), currentAnchorPosition, maxTranslationDistance);
result.hasHoveringPosition = true;
result.hoveringPosition = groundingPoint + (Vector3.up * hoverOffset);
}
else
{
// If we can't successfully cast onto the groundingPlane, just return early.
return result;
}
return result;
}
///
/// Limits the translation to the maximum distance allowed.
///
/// Returns the new target position, limited so that the object does not translate more
/// than the maximum allowed distance.
/// Desired position.
/// Current position.
/// Max translation distance.
static Vector3 LimitTranslation(Vector3 desiredPosition, Vector3 currentPosition, float maxTranslationDistance)
{
if ((desiredPosition - currentPosition).sqrMagnitude > Mathf.Pow(maxTranslationDistance, 2f))
{
return currentPosition + (
(desiredPosition - currentPosition).normalized * maxTranslationDistance);
}
return desiredPosition;
}
static bool IsPlaneTypeAllowed(GestureTranslationMode gestureTranslationMode, PlaneAlignment planeAlignment)
{
if (gestureTranslationMode == GestureTranslationMode.Any)
{
return true;
}
if (gestureTranslationMode == GestureTranslationMode.Horizontal &&
(planeAlignment == PlaneAlignment.HorizontalDown ||
planeAlignment == PlaneAlignment.HorizontalUp))
{
return true;
}
if (gestureTranslationMode == GestureTranslationMode.Vertical &&
planeAlignment == PlaneAlignment.Vertical)
{
return true;
}
return false;
}
///
/// Result of the function
/// that indicates if a placement position
/// was found and information about the placement position.
///
public partial struct Placement
{
///
/// if this Placement has a valid value, otherwise .
///
///
public bool hasHoveringPosition { get; set; }
///
/// The position that the object should be displayed at before the placement has been
/// confirmed.
///
///
public Vector3 hoveringPosition { get; set; }
///
/// if this Placement has a valid value, otherwise .
///
///
public bool hasPlacementPosition { get; set; }
///
/// The resulting position that the object should be placed at.
///
///
public Vector3 placementPosition { get; set; }
///
/// The resulting rotation that the object should have.
///
public Quaternion placementRotation { get; set; }
///
/// if this Placement has a , otherwise .
///
///
public bool hasPlane { get; set; }
///
/// The ARPlane
/// that the object is being placed on.
///
///
public ARPlane placementPlane { get; set; }
///
/// The resulting starting height of the plane that the object is being placed along.
///
public float updatedGroundingPlaneHeight { get; set; }
}
///
/// Cast a ray from a point in screen space against trackables, i.e., detected features such as planes.
/// Can optionally fallback to hit test against Colliders in the loaded Scenes when no trackables were hit.
///
/// The point, in device screen pixels, from which to cast.
/// Contents are replaced with the ray cast results, if successful.
/// The used for ray casting.
/// (Optional) The types of trackables to cast against.
/// (Optional) The that Unity uses during an additional ray cast when no trackables are hit.
/// Defaults to Nothing which skips the fallback ray cast.
/// Returns if the ray cast hit a trackable in the or if the fallback ray cast hit.
/// Otherwise, returns .
[Obsolete("Raycast with the ARSessionOrigin parameter has been deprecated. Use Raycast with the XROrigin parameter instead.")]
public static bool Raycast(
Vector2 screenPoint,
List hitResults,
ARSessionOrigin sessionOrigin,
TrackableType trackableTypes = TrackableType.All,
int fallbackLayerMask = 0)
{
if ((sessionOrigin != null || TryGetSessionOrigin(out sessionOrigin)) &&
TryGetTrackableManager(sessionOrigin, out ARRaycastManager raycastManager) &&
raycastManager.Raycast(screenPoint, hitResults, trackableTypes))
{
return true;
}
// No hits on trackables, try debug planes
hitResults.Clear();
const TrackableType hitType = TrackableType.PlaneWithinPolygon;
if (fallbackLayerMask == 0 || (trackableTypes & hitType) == 0)
return false;
var camera = sessionOrigin != null ? sessionOrigin.camera : Camera.main;
if (camera == null)
return false;
var ray = camera.ScreenPointToRay(screenPoint);
if (Physics.Raycast(ray, out var hit, Mathf.Infinity, fallbackLayerMask))
{
hitResults.Add(new ARRaycastHit(
new XRRaycastHit(
TrackableId.invalidId,
new Pose(hit.point, Quaternion.LookRotation(Vector3.forward, hit.normal)),
hit.distance,
hitType),
hit.distance,
sessionOrigin != null ? sessionOrigin.transform : hit.collider.transform));
return true;
}
return false;
}
///
/// Calculates the best position to place an object in AR based on screen position.
/// Could be used for tapping a location on the screen, dragging an object, or using a fixed
/// cursor in the center of the screen for placing and moving objects.
///
/// Returns the best placement position.
/// Position of the parent anchor, i.e., where the
/// object is before translation starts.
/// Location on the screen in pixels to place the object at.
/// The starting height of the plane to place the object on.
/// How much should the object hover above the groundingPlane
/// before it has been placed.
/// The maximum distance allowed to translate the object.
/// The translation mode, indicating the plane types allowed.
///
/// The used for ray casting.
/// (Optional) The types of trackables to cast against.
/// (Optional) The that Unity uses during
/// an additional ray cast when no trackables are hit. Defaults to Nothing which skips the fallback ray cast.
///
/// Unity places objects along the x/z of the grounding plane. When placed on an AR plane
/// below the grounding plane, the object will drop straight down onto it in world space.
/// This prevents the object from being pushed deeper into the scene when moving from a
/// higher plane to a lower plane. When moving from a lower plane to a higher plane, this
/// function returns a new groundingPlane to replace the old one.
///
[Obsolete("GetBestPlacementPosition with the ARSessionOrigin parameter has been deprecated. Use GetBestPlacementPosition with the XROrigin parameter instead.")]
public static Placement GetBestPlacementPosition(
Vector3 currentAnchorPosition,
Vector2 screenPosition,
float groundingPlaneHeight,
float hoverOffset,
float maxTranslationDistance,
GestureTranslationMode gestureTranslationMode,
ARSessionOrigin sessionOrigin,
TrackableType trackableTypes = TrackableType.PlaneWithinPolygon,
int fallbackLayerMask = 0)
{
var result = new Placement();
if (sessionOrigin == null)
TryGetSessionOrigin(out sessionOrigin);
var camera = sessionOrigin != null ? sessionOrigin.camera : Camera.main;
if (camera == null)
return result;
var cameraTransform = camera.transform;
result.updatedGroundingPlaneHeight = groundingPlaneHeight;
// Get the angle between the camera and the object's down direction.
var angle = 90f - Vector3.Angle(cameraTransform.forward, Vector3.down);
var touchOffsetRatio = Mathf.Clamp01(angle / 90f);
var screenTouchOffset = touchOffsetRatio * k_MaxScreenTouchOffset;
screenPosition.y += GestureTouchesUtility.InchesToPixels(screenTouchOffset);
var hoverRatio = Mathf.Clamp01(angle / 45f);
hoverOffset *= hoverRatio;
var distance = (cameraTransform.position - currentAnchorPosition).magnitude;
var distanceHoverRatio = Mathf.Clamp01(distance / k_HoverDistanceThreshold);
hoverOffset *= distanceHoverRatio;
// The best estimate of the point in the plane where the object will be placed:
Vector3 groundingPoint;
// Get the ray to cast into the scene from the perspective of the camera.
if (Raycast(screenPosition, s_Hits, sessionOrigin, trackableTypes, fallbackLayerMask))
{
if (!TryGetTrackableManager(sessionOrigin, out ARPlaneManager planeManager))
return result;
var firstHit = s_Hits[0];
var plane = planeManager.GetPlane(firstHit.trackableId);
if (plane == null || IsPlaneTypeAllowed(gestureTranslationMode, plane.alignment))
{
// Avoid detecting the back of existing planes.
if (Vector3.Dot(cameraTransform.position - firstHit.pose.position,
firstHit.pose.rotation * Vector3.up) < 0f)
return result;
// Don't allow hovering for vertical or horizontal downward facing planes.
if (plane == null ||
plane.alignment == PlaneAlignment.Vertical ||
plane.alignment == PlaneAlignment.HorizontalDown ||
plane.alignment == PlaneAlignment.HorizontalUp)
{
groundingPoint = LimitTranslation(
firstHit.pose.position, currentAnchorPosition, maxTranslationDistance);
if (plane != null)
{
result.placementPlane = plane;
result.hasPlane = true;
}
result.hasPlacementPosition = true;
result.placementPosition = groundingPoint;
result.hasHoveringPosition = true;
result.hoveringPosition = groundingPoint;
result.updatedGroundingPlaneHeight = groundingPoint.y;
result.placementRotation = firstHit.pose.rotation;
return result;
}
}
else
{
// Plane type not allowed.
return result;
}
}
// Return early if the camera is pointing upwards.
if (angle < 0f)
{
return result;
}
// If the grounding point is lower than the current grounding plane height, or if the
// ray cast did not return a hit, then we extend the grounding plane to infinity, and do
// a new ray cast into the scene from the perspective of the camera.
var cameraRay = camera.ScreenPointToRay(screenPosition);
var groundingPlane =
new Plane(Vector3.up, new Vector3(0f, groundingPlaneHeight, 0f));
// Find the hovering position by casting from the camera onto the grounding plane
// and offsetting the result by the hover offset.
if (groundingPlane.Raycast(cameraRay, out var enter))
{
groundingPoint = LimitTranslation(
cameraRay.GetPoint(enter), currentAnchorPosition, maxTranslationDistance);
result.hasHoveringPosition = true;
result.hoveringPosition = groundingPoint + (Vector3.up * hoverOffset);
}
else
{
// If we can't successfully cast onto the groundingPlane, just return early.
return result;
}
return result;
}
///
/// Cast a ray from a point in screen space against trackables, i.e., detected features such as planes.
///
/// The point, in device screen pixels, from which to cast.
/// Contents are replaced with the ray cast results, if successful.
/// (Optional) The types of trackables to cast against.
/// Returns if the ray cast hit a trackable in the .
/// Otherwise, returns .
[Obsolete("Raycast has been deprecated. Use Raycast with updated signature instead.")]
public static bool Raycast(Vector2 screenPoint, List hitResults, TrackableType trackableTypes = TrackableType.All)
{
// For backwards compatibility, use the TestPlanes layer value from the AR examples project.
const int fallbackLayerMask = 1 << 9;
return Raycast(screenPoint, hitResults, (ARSessionOrigin)null, trackableTypes, fallbackLayerMask);
}
///
/// Calculates the best position to place an object in AR based on screen position.
/// Could be used for tapping a location on the screen, dragging an object, or using a fixed
/// cursor in the center of the screen for placing and moving objects.
///
/// Returns the best placement position.
/// Position of the parent anchor, i.e., where the
/// object is before translation starts.
/// Location on the screen in pixels to place the object at.
/// The starting height of the plane to place the object on.
/// How much should the object hover above the groundingPlane
/// before it has been placed.
/// The maximum distance allowed to translate the object.
/// The translation mode, indicating the plane types allowed.
///
///
/// Unity places objects along the x/z of the grounding plane. When placed on an AR plane
/// below the grounding plane, the object will drop straight down onto it in world space.
/// This prevents the object from being pushed deeper into the scene when moving from a
/// higher plane to a lower plane. When moving from a lower plane to a higher plane, this
/// function returns a new groundingPlane to replace the old one.
///
[Obsolete("GetBestPlacementPosition has been deprecated. Use GetBestPlacementPosition with updated signature instead.")]
public static Placement GetBestPlacementPosition(
Vector3 currentAnchorPosition,
Vector2 screenPos,
float groundingPlaneHeight,
float hoverOffset,
float maxTranslationDistance,
GestureTranslationMode gestureTranslationMode)
{
// For backwards compatibility, use the TestPlanes layer value from the AR examples project.
const int fallbackLayerMask = 1 << 9;
return GetBestPlacementPosition(currentAnchorPosition,
screenPos,
groundingPlaneHeight,
hoverOffset,
maxTranslationDistance,
gestureTranslationMode,
(ARSessionOrigin)null,
fallbackLayerMask: fallbackLayerMask);
}
public partial struct Placement
{
#pragma warning disable IDE1006 // Naming Styles
///
[Obsolete("HasHoveringPosition has been deprecated. Use hasHoveringPosition instead. (UnityUpgradable) -> hasHoveringPosition")]
public bool HasHoveringPosition
{
get => hasHoveringPosition;
set => hasHoveringPosition = value;
}
///
[Obsolete("HoveringPosition has been deprecated. Use hoveringPosition instead. (UnityUpgradable) -> hoveringPosition")]
public Vector3 HoveringPosition
{
get => hoveringPosition;
set => hoveringPosition = value;
}
///
[Obsolete("HasPlacementPosition has been deprecated. Use hasPlacementPosition instead. (UnityUpgradable) -> hasPlacementPosition")]
public bool HasPlacementPosition
{
get => hasPlacementPosition;
set => hasPlacementPosition = value;
}
///
[Obsolete("PlacementPosition has been deprecated. Use placementPosition instead. (UnityUpgradable) -> placementPosition")]
public Vector3 PlacementPosition
{
get => placementPosition;
set => placementPosition = value;
}
///
[Obsolete("PlacementRotation has been deprecated. Use placementRotation instead. (UnityUpgradable) -> placementRotation")]
public Quaternion PlacementRotation
{
get => placementRotation;
set => placementRotation = value;
}
///
[Obsolete("HasPlane has been deprecated. Use hasPlane instead. (UnityUpgradable) -> hasPlane")]
public bool HasPlane
{
get => hasPlane;
set => hasPlane = value;
}
///
[Obsolete("PlacementPlane has been deprecated. Use placementPlane instead. (UnityUpgradable) -> placementPlane")]
public ARPlane PlacementPlane
{
get => placementPlane;
set => placementPlane = value;
}
///
[Obsolete("UpdatedGroundingPlaneHeight has been deprecated. Use updatedGroundingPlaneHeight instead. (UnityUpgradable) -> updatedGroundingPlaneHeight")]
public float UpdatedGroundingPlaneHeight
{
get => updatedGroundingPlaneHeight;
set => updatedGroundingPlaneHeight = value;
}
#pragma warning restore IDE1006 // Naming Styles
}
}
}
#endif