/Assets/GoogleVR/Scripts/UI/GvrReticlePointerImpl.cs
https://bitbucket.org/gcgmm/mm_2017-1_not_equipe-6 · C# · 177 lines · 92 code · 32 blank · 53 comment · 6 complexity · 6edbc9669baf75e5802c1d4677292ff0 MD5 · raw file
- // Copyright 2017 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.
- using UnityEngine;
- using UnityEngine.EventSystems;
- /// Draws a circular reticle in front of any object that the user points at.
- /// The circle dilates if the object is clickable.
- public class GvrReticlePointerImpl : GvrBasePointer {
- // The constants below are expsed for testing.
- // Minimum inner angle of the reticle (in degrees).
- public const float RETICLE_MIN_INNER_ANGLE = 0.0f;
- // Minimum outer angle of the reticle (in degrees).
- public const float RETICLE_MIN_OUTER_ANGLE = 0.5f;
- // Angle at which to expand the reticle when intersecting with an object
- // (in degrees).
- public const float RETICLE_GROWTH_ANGLE = 1.5f;
- // Minimum distance of the reticle (in meters).
- public const float RETICLE_DISTANCE_MIN = 0.45f;
- // Maximum distance of the reticle (in meters).
- public const float RETICLE_DISTANCE_MAX = 10.0f;
- /// Growth speed multiplier for the reticle.
- public float ReticleGrowthSpeed { private get; set; }
- public Material MaterialComp { private get; set; }
- // Current inner angle of the reticle (in degrees).
- // Exposed for testing.
- public float ReticleInnerAngle { get; private set; }
- // Current outer angle of the reticle (in degrees).
- // Exposed for testing.
- public float ReticleOuterAngle { get; private set; }
- // Current distance of the reticle (in meters).
- // Getter exposed for testing.
- public float ReticleDistanceInMeters { get; private set; }
- // Current inner and outer diameters of the reticle, before distance multiplication.
- // Getters exposed for testing.
- public float ReticleInnerDiameter { get; private set; }
- public float ReticleOuterDiameter { get; private set; }
- private Vector3 targetPoint = Vector3.zero;
- public override Vector3 LineEndPoint { get { return targetPoint; } }
- public override float MaxPointerDistance { get { return RETICLE_DISTANCE_MAX; } }
- public GvrReticlePointerImpl() {
- ReticleGrowthSpeed = 8.0f;
- ReticleInnerAngle = 0.0f;
- ReticleOuterAngle = 0.5f;
- ReticleDistanceInMeters = 10.0f;
- ReticleInnerDiameter = 0.0f;
- ReticleOuterDiameter = 0.0f;
- }
- public override void OnStart () {
- base.OnStart();
- }
- /// This is called when the 'BaseInputModule' system should be enabled.
- public override void OnInputModuleEnabled() {}
- /// This is called when the 'BaseInputModule' system should be disabled.
- public override void OnInputModuleDisabled() {}
- /// Called when the user is pointing at valid GameObject. This can be a 3D
- /// or UI element.
- ///
- /// The targetObject is the object the user is pointing at.
- /// The intersectionPosition is where the ray intersected with the targetObject.
- /// The intersectionRay is the ray that was cast to determine the intersection.
- public override void OnPointerEnter(RaycastResult rayastResult, Ray ray,
- bool isInteractive) {
- SetPointerTarget(rayastResult.worldPosition, isInteractive);
- }
- /// Called every frame the user is still pointing at a valid GameObject. This
- /// can be a 3D or UI element.
- ///
- /// The targetObject is the object the user is pointing at.
- /// The intersectionPosition is where the ray intersected with the targetObject.
- /// The intersectionRay is the ray that was cast to determine the intersection.
- public override void OnPointerHover(RaycastResult rayastResult, Ray ray,
- bool isInteractive) {
- SetPointerTarget(rayastResult.worldPosition, isInteractive);
- }
- /// Called when the user's look no longer intersects an object previously
- /// intersected with a ray projected from the camera.
- /// This is also called just before **OnInputModuleDisabled** and may have have any of
- /// the values set as **null**.
- public override void OnPointerExit(GameObject previousObject) {
- ReticleDistanceInMeters = RETICLE_DISTANCE_MAX;
- ReticleInnerAngle = RETICLE_MIN_INNER_ANGLE;
- ReticleOuterAngle = RETICLE_MIN_OUTER_ANGLE;
- }
- /// Called when a trigger event is initiated. This is practically when
- /// the user begins pressing the trigger.
- public override void OnPointerClickDown() {}
- /// Called when a trigger event is finished. This is practically when
- /// the user releases the trigger.
- public override void OnPointerClickUp() {}
- public override void GetPointerRadius(out float enterRadius, out float exitRadius) {
- float min_inner_angle_radians = Mathf.Deg2Rad * RETICLE_MIN_INNER_ANGLE;
- float max_inner_angle_radians = Mathf.Deg2Rad * (RETICLE_MIN_INNER_ANGLE + RETICLE_GROWTH_ANGLE);
- enterRadius = 2.0f * Mathf.Tan(min_inner_angle_radians);
- exitRadius = 2.0f * Mathf.Tan(max_inner_angle_radians);
- }
- public void UpdateDiameters() {
- ReticleDistanceInMeters =
- Mathf.Clamp(ReticleDistanceInMeters, RETICLE_DISTANCE_MIN, RETICLE_DISTANCE_MAX);
- if (ReticleInnerAngle < RETICLE_MIN_INNER_ANGLE) {
- ReticleInnerAngle = RETICLE_MIN_INNER_ANGLE;
- }
- if (ReticleOuterAngle < RETICLE_MIN_OUTER_ANGLE) {
- ReticleOuterAngle = RETICLE_MIN_OUTER_ANGLE;
- }
- float inner_half_angle_radians = Mathf.Deg2Rad * ReticleInnerAngle * 0.5f;
- float outer_half_angle_radians = Mathf.Deg2Rad * ReticleOuterAngle * 0.5f;
- float inner_diameter = 2.0f * Mathf.Tan(inner_half_angle_radians);
- float outer_diameter = 2.0f * Mathf.Tan(outer_half_angle_radians);
- ReticleInnerDiameter =
- Mathf.Lerp(ReticleInnerDiameter, inner_diameter, Time.deltaTime * ReticleGrowthSpeed);
- ReticleOuterDiameter =
- Mathf.Lerp(ReticleOuterDiameter, outer_diameter, Time.deltaTime * ReticleGrowthSpeed);
- MaterialComp.SetFloat("_InnerDiameter", ReticleInnerDiameter * ReticleDistanceInMeters);
- MaterialComp.SetFloat("_OuterDiameter", ReticleOuterDiameter * ReticleDistanceInMeters);
- MaterialComp.SetFloat("_DistanceInMeters", ReticleDistanceInMeters);
- }
- private bool SetPointerTarget(Vector3 target, bool interactive) {
- if (base.PointerTransform == null) {
- Debug.LogWarning("Cannot operate on a null pointer transform");
- return false;
- }
- targetPoint = target;
- Vector3 targetLocalPosition = base.PointerTransform.InverseTransformPoint(target);
- ReticleDistanceInMeters =
- Mathf.Clamp(targetLocalPosition.z, RETICLE_DISTANCE_MIN, RETICLE_DISTANCE_MAX);
- if (interactive) {
- ReticleInnerAngle = RETICLE_MIN_INNER_ANGLE + RETICLE_GROWTH_ANGLE;
- ReticleOuterAngle = RETICLE_MIN_OUTER_ANGLE + RETICLE_GROWTH_ANGLE;
- } else {
- ReticleInnerAngle = RETICLE_MIN_INNER_ANGLE;
- ReticleOuterAngle = RETICLE_MIN_OUTER_ANGLE;
- }
- return true;
- }
- }