/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * 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. */ using UnityEngine; namespace Oculus.Interaction.Surfaces { /// /// Used for interaction with circular surfaces. Computes the closest world point on a coordinate plane defined by the X and Y axes of the transform, within a provided radius from the transform’s origin. /// public class CircleSurface : MonoBehaviour, ISurfacePatch { /// /// The circle will lay upon this plane, with the circle's center at the plane surface's origin. /// [Tooltip("The circle will lay upon this plane, with " + "the circle's center at the plane surface's origin.")] [SerializeField] private PlaneSurface _planeSurface; /// /// The radius of the circle, scaled by the lossy scale of the transform. /// [Tooltip("The radius of the circle.")] [SerializeField] private float _radius = 0.1f; public Transform Transform => _planeSurface.Transform; public ISurface BackingSurface => _planeSurface; protected virtual void Start() { this.AssertField(_planeSurface, nameof(_planeSurface)); } public bool Raycast(in Ray ray, out SurfaceHit hit, float maxDistance = 0) { if (!_planeSurface.Raycast(ray, out hit, maxDistance)) { return false; } Vector3 hitPointLocal = Transform.InverseTransformPoint(hit.Point); return Vector3.SqrMagnitude(hitPointLocal) <= (_radius * _radius); } // Closest point to circle is computed by projecting point to the plane // the circle is on and then clamping to the circle public bool ClosestSurfacePoint(in Vector3 point, out SurfaceHit hit, float maxDistance = 0) { if (!_planeSurface.ClosestSurfacePoint(point, out hit, maxDistance)) { return false; } Vector3 hitPointLocal = Transform.InverseTransformPoint(hit.Point); Vector3 clampedLocal = Vector3.ClampMagnitude(hitPointLocal, _radius); Vector3 clampedWorld = Transform.TransformPoint(clampedLocal); hit.Point = clampedWorld; hit.Distance = Vector3.Distance(point, clampedWorld); return maxDistance <= 0 || hit.Distance <= maxDistance; } #region Inject [System.Obsolete("Use " + nameof(InjectAllCircleSurface) + " instead.")] public void InjectAllCircleProximityField(PlaneSurface planeSurface) { InjectAllCircleSurface(planeSurface); } public void InjectAllCircleSurface(PlaneSurface planeSurface) { InjectPlaneSurface(planeSurface); } public void InjectPlaneSurface(PlaneSurface planeSurface) { _planeSurface = planeSurface; } public void InjectOptionalRadius(float radius) { _radius = radius; } #endregion } }