//-------------------------------------------------
 private void CheckForSpawnPoint()
 {
     foreach (VRTRIXTeleportMarkerBase teleportMarker in teleportMarkers)
     {
         VRTRIXGloveTelportPoint teleportPoint = teleportMarker as VRTRIXGloveTelportPoint;
         if (teleportPoint && teleportPoint.playerSpawnPoint)
         {
             teleportingToMarker = teleportMarker;
             TeleportPlayer();
             break;
         }
     }
 }
        //-------------------------------------------------
        private void TryTeleportPlayer()
        {
            if (visible && !teleporting)
            {
                if (pointedAtTeleportMarker != null && pointedAtTeleportMarker.locked == false)
                {
                    Debug.Log("pointedAtTeleportMarker: " + pointedAtTeleportMarker);
                    //Pointing at an unlocked teleport marker
                    teleportingToMarker = pointedAtTeleportMarker;
                    InitiateTeleportFade();

                    //CancelTeleportHint();
                }
            }
        }
        //-------------------------------------------------
        private void HighlightSelected(VRTRIXTeleportMarkerBase hitTeleportMarker)
        {
            if (pointedAtTeleportMarker != hitTeleportMarker) //Pointing at a new teleport marker
            {
                if (pointedAtTeleportMarker != null)
                {
                    pointedAtTeleportMarker.Highlight(false);
                }

                if (hitTeleportMarker != null)
                {
                    hitTeleportMarker.Highlight(true);

                    prevPointedAtPosition = pointedAtPosition;
                    PlayPointerHaptic(!hitTeleportMarker.locked);

                    PlayAudioClip(reticleAudioSource, goodHighlightSound);

                    loopingAudioSource.volume = loopingAudioMaxVolume;
                }
                else if (pointedAtTeleportMarker != null)
                {
                    PlayAudioClip(reticleAudioSource, badHighlightSound);

                    loopingAudioSource.volume = 0.0f;
                }
            }
            else if (hitTeleportMarker != null) //Pointing at the same teleport marker
            {
                if (Vector3.Distance(prevPointedAtPosition, pointedAtPosition) > 1.0f)
                {
                    prevPointedAtPosition = pointedAtPosition;
                    PlayPointerHaptic(!hitTeleportMarker.locked);
                }
            }
        }
        //-------------------------------------------------
        private void ShowPointer(VRTRIXGloveGrab newPointerHand, VRTRIXGloveGrab oldPointerHand)
        {
            if (!visible)
            {
                pointedAtTeleportMarker = null;
                pointerShowStartTime    = Time.time;
                visible    = true;
                meshFading = true;

                teleportPointerObject.SetActive(false);
                teleportArc.Show();

                foreach (VRTRIXTeleportMarkerBase teleportMarker in teleportMarkers)
                {
                    if (teleportMarker.markerActive && teleportMarker.ShouldActivate(player.feetPositionGuess))
                    {
                        teleportMarker.gameObject.SetActive(true);
                        teleportMarker.Highlight(false);
                    }
                }

                startingFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
                movedFeetFarEnough = false;

                if (onDeactivateObjectTransform.gameObject.activeSelf)
                {
                    onDeactivateObjectTransform.gameObject.SetActive(false);
                }
                onActivateObjectTransform.gameObject.SetActive(true);

                loopingAudioSource.clip = pointerLoopSound;
                loopingAudioSource.loop = true;
                loopingAudioSource.Play();
                loopingAudioSource.volume = 0.0f;
            }


            if (oldPointerHand)
            {
                if (ShouldOverrideHoverLock())
                {
                    //Restore the original hovering interactable on the hand
                    if (originalHoverLockState == true)
                    {
                        oldPointerHand.HoverLock(originalHoveringInteractable);
                    }
                    else
                    {
                        oldPointerHand.HoverUnlock(null);
                    }
                }
            }

            pointerHand = newPointerHand;

            if (visible && oldPointerHand != pointerHand)
            {
                PlayAudioClip(pointerAudioSource, pointerStartSound);
            }

            if (pointerHand)
            {
                pointerStartTransform = GetPointerStartTransform(pointerHand);
                //print(pointerStartTransform);

                if (pointerHand.currentAttachedObject != null)
                {
                    allowTeleportWhileAttached = pointerHand.currentAttachedObject.GetComponent <VRTRIXAllowTeleportWhileAttachedToHand>();
                }

                //Keep track of any existing hovering interactable on the hand
                originalHoverLockState       = pointerHand.hoverLocked;
                originalHoveringInteractable = pointerHand.hoveringInteractable;

                if (ShouldOverrideHoverLock())
                {
                    pointerHand.HoverLock(null);
                }

                pointerAudioSource.transform.SetParent(pointerStartTransform);
                pointerAudioSource.transform.localPosition = Vector3.zero;

                loopingAudioSource.transform.SetParent(pointerStartTransform);
                loopingAudioSource.transform.localPosition = Vector3.zero;
            }
        }
        //-------------------------------------------------
        private void UpdatePointer()
        {
            Vector3 pointerStart = pointerStartTransform.position;
            Vector3 pointerEnd;
            Vector3 pointerDir          = -pointerStartTransform.right;
            bool    hitSomething        = false;
            bool    showPlayAreaPreview = false;
            Vector3 playerFeetOffset    = player.trackingOriginTransform.position - player.feetPositionGuess;

            Vector3 arcVelocity = pointerDir * arcDistance;

            VRTRIXTeleportMarkerBase hitTeleportMarker = null;

            //Check pointer angle
            float dotUp             = Vector3.Dot(pointerDir, Vector3.up);
            float dotForward        = Vector3.Dot(pointerDir, player.hmdTransform.forward);
            bool  pointerAtBadAngle = false;

            if ((dotForward > 0 && dotUp > 0.75f) || (dotForward < 0.0f && dotUp > 0.5f))
            {
                pointerAtBadAngle = true;
            }

            //Trace to see if the pointer hit anything
            RaycastHit hitInfo;

            teleportArc.SetArcData(pointerStart, arcVelocity, true, pointerAtBadAngle);
            if (teleportArc.DrawArc(out hitInfo))
            {
                hitSomething      = true;
                hitTeleportMarker = hitInfo.collider.GetComponentInParent <VRTRIXTeleportMarkerBase>();
            }

            if (pointerAtBadAngle)
            {
                hitTeleportMarker = null;
            }

            HighlightSelected(hitTeleportMarker);

            if (hitTeleportMarker != null) //Hit a teleport marker
            {
                if (hitTeleportMarker.locked)
                {
                    teleportArc.SetColor(pointerLockedColor);
#if (UNITY_5_4)
                    pointerLineRenderer.SetColors(pointerLockedColor, pointerLockedColor);
#else
                    pointerLineRenderer.startColor = pointerLockedColor;
                    pointerLineRenderer.endColor   = pointerLockedColor;
#endif
                    destinationReticleTransform.gameObject.SetActive(false);
                }
                else
                {
                    teleportArc.SetColor(pointerValidColor);
#if (UNITY_5_4)
                    pointerLineRenderer.SetColors(pointerValidColor, pointerValidColor);
#else
                    pointerLineRenderer.startColor = pointerValidColor;
                    pointerLineRenderer.endColor   = pointerValidColor;
#endif
                    destinationReticleTransform.gameObject.SetActive(hitTeleportMarker.showReticle);
                }

                offsetReticleTransform.gameObject.SetActive(true);

                invalidReticleTransform.gameObject.SetActive(false);
                Debug.Log("hitTeleportMarker: " + hitTeleportMarker);
                pointedAtTeleportMarker = hitTeleportMarker;
                pointedAtPosition       = hitInfo.point;

                if (showPlayAreaMarker)
                {
                    //Show the play area marker if this is a teleport area
                    VRTRIXGloveTelportArea teleportArea = pointedAtTeleportMarker as VRTRIXGloveTelportArea;
                    if (teleportArea != null && !teleportArea.locked && playAreaPreviewTransform != null)
                    {
                        Vector3 offsetToUse = playerFeetOffset;

                        //Adjust the actual offset to prevent the play area marker from moving too much
                        if (!movedFeetFarEnough)
                        {
                            float distanceFromStartingOffset = Vector3.Distance(playerFeetOffset, startingFeetOffset);
                            if (distanceFromStartingOffset < 0.1f)
                            {
                                offsetToUse = startingFeetOffset;
                            }
                            else if (distanceFromStartingOffset < 0.4f)
                            {
                                offsetToUse = Vector3.Lerp(startingFeetOffset, playerFeetOffset, (distanceFromStartingOffset - 0.1f) / 0.3f);
                            }
                            else
                            {
                                movedFeetFarEnough = true;
                            }
                        }

                        playAreaPreviewTransform.position = pointedAtPosition + offsetToUse;

                        showPlayAreaPreview = true;
                    }
                }

                pointerEnd = hitInfo.point;
            }
            else //Hit neither
            {
                destinationReticleTransform.gameObject.SetActive(false);
                offsetReticleTransform.gameObject.SetActive(false);

                teleportArc.SetColor(pointerInvalidColor);
#if (UNITY_5_4)
                pointerLineRenderer.SetColors(pointerInvalidColor, pointerInvalidColor);
#else
                pointerLineRenderer.startColor = pointerInvalidColor;
                pointerLineRenderer.endColor   = pointerInvalidColor;
#endif
                invalidReticleTransform.gameObject.SetActive(!pointerAtBadAngle);

                //Orient the invalid reticle to the normal of the trace hit point
                Vector3 normalToUse = hitInfo.normal;
                float   angle       = Vector3.Angle(hitInfo.normal, Vector3.up);
                if (angle < 15.0f)
                {
                    normalToUse = Vector3.up;
                }
                invalidReticleTargetRotation     = Quaternion.FromToRotation(Vector3.up, normalToUse);
                invalidReticleTransform.rotation = Quaternion.Slerp(invalidReticleTransform.rotation, invalidReticleTargetRotation, 0.1f);

                //Scale the invalid reticle based on the distance from the player
                float distanceFromPlayer         = Vector3.Distance(hitInfo.point, player.hmdTransform.position);
                float invalidReticleCurrentScale = Util.RemapNumberClamped(distanceFromPlayer, invalidReticleMinScaleDistance, invalidReticleMaxScaleDistance, invalidReticleMinScale, invalidReticleMaxScale);
                invalidReticleScale.x = invalidReticleCurrentScale;
                invalidReticleScale.y = invalidReticleCurrentScale;
                invalidReticleScale.z = invalidReticleCurrentScale;
                invalidReticleTransform.transform.localScale = invalidReticleScale;

                pointedAtTeleportMarker = null;

                if (hitSomething)
                {
                    pointerEnd = hitInfo.point;
                }
                else
                {
                    pointerEnd = teleportArc.GetArcPositionAtTime(teleportArc.arcDuration);
                }

                //Debug floor
                if (debugFloor)
                {
                    floorDebugSphere.gameObject.SetActive(false);
                    floorDebugLine.gameObject.SetActive(false);
                }
            }

            if (playAreaPreviewTransform != null)
            {
                playAreaPreviewTransform.gameObject.SetActive(showPlayAreaPreview);
            }

            if (!showOffsetReticle)
            {
                offsetReticleTransform.gameObject.SetActive(false);
            }

            destinationReticleTransform.position = pointedAtPosition;
            invalidReticleTransform.position     = pointerEnd;
            onActivateObjectTransform.position   = pointerEnd;
            onDeactivateObjectTransform.position = pointerEnd;
            offsetReticleTransform.position      = pointerEnd - playerFeetOffset;

            reticleAudioSource.transform.position = pointedAtPosition;

            pointerLineRenderer.SetPosition(0, pointerStart);
            pointerLineRenderer.SetPosition(1, pointerEnd);
        }