public InternalGazePointer(GazeProvider gazeProvider, string pointerName, IMixedRealityInputSource inputSourceParent, LayerMask[] raycastLayerMasks, float pointerExtent, Transform gazeTransform, BaseRayStabilizer stabilizer)
     : base(pointerName, inputSourceParent)
 {
     this.gazeProvider             = gazeProvider;
     PrioritizedLayerMasksOverride = raycastLayerMasks;
     this.pointerExtent            = pointerExtent;
     this.gazeTransform            = gazeTransform;
     this.stabilizer      = stabilizer;
     IsInteractionEnabled = true;
 }
Example #2
0
 /// <summary>
 /// Get a camera position from either a stabilizer or the Camera itself
 /// </summary>
 /// <param name="stabilizer"></param>
 /// <returns></returns>
 private static Vector3 GetCameraPosition(BaseRayStabilizer stabilizer)
 {
     return(stabilizer != null
         ? stabilizer.StablePosition
         : CameraCache.Main.transform.position);
 }
Example #3
0
        /// <summary>
        /// Looks where an object must be placed if it is not to intersect with other objects, or the spatial map
        /// Can be used to place an object on top of another object (or at a distance from it).
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="maxDistance"></param>
        /// <param name="distanceFromObstruction"></param>
        /// <param name="layerMask"></param>
        /// <param name="stabilizer"></param>
        /// <param name="showDebugLines"></param>
        /// <returns></returns>
        public static Vector3 GetObjectBeforeObstruction(GameObject obj, float maxDistance = 2,
                                                         float distanceFromObstruction     = 0.02f, int layerMask      = Physics.DefaultRaycastLayers,
                                                         BaseRayStabilizer stabilizer      = null, bool showDebugLines = false)
        {
            var totalBounds = obj.GetEncapsulatingBounds();

            var headRay = stabilizer != null
                ? stabilizer.StableRay
                : new Ray(CameraCache.Main.transform.position, CameraCache.Main.transform.forward);


            // Project the object forward, get all hits *except those involving child objects of the main object*
            var hits = Physics.BoxCastAll(GetCameraPosition(stabilizer),
                                          totalBounds.extents, headRay.direction,
                                          Quaternion.identity, maxDistance, layerMask)
                       .Where(h => !h.transform.IsChildOf(obj.transform)).ToList();

            // This factor compensates for the fact object center and bounds center for some reason are not always the same
            var centerCorrection = obj.transform.position - totalBounds.center;

            if (showDebugLines)
            {
                BoxCastHelper.DrawBoxCastBox(GetCameraPosition(stabilizer),
                                             totalBounds.extents, headRay.direction,
                                             Quaternion.identity, maxDistance, Color.green);
            }

            var orderedHits = hits.OrderBy(p => p.distance).Where(q => q.distance > 0.1f).ToList();

            if (orderedHits.Any())
            {
                var closestHit = orderedHits.First();
                //Find the closest hit - we need to move the object forward to that position

                //We need a vector from the camera to the hit...
                var hitVector = closestHit.point - GetCameraPosition(stabilizer);

                //But the hit needs to be projected on our dead ahead vector, as the first hit may not be right in front of us
                var gazeVector         = CalculatePositionDeadAhead(closestHit.distance * 2) - GetCameraPosition(stabilizer);
                var projectedHitVector = Vector3.Project(hitVector, gazeVector);
#if UNITY_EDITOR
                if (showDebugLines)
                {
                    Debug.DrawLine(GetCameraPosition(stabilizer), closestHit.point, Color.yellow);
                    Debug.DrawRay(GetCameraPosition(stabilizer), gazeVector, Color.blue);
                    Debug.DrawRay(GetCameraPosition(stabilizer), projectedHitVector, Color.magenta);
                    BoxCastHelper.DrawBox(totalBounds.center, totalBounds.extents, Quaternion.identity, Color.red);
                }
#endif

                //If we use the projectedHitVector to add to the cameraposition, the CENTER of our object will end up
                // against the obstruction, so we need to know who much the object is extending from the center in the direction of the hit.
                // So we make a ray from the center that intersects with the object's own bounds.
                var   edgeRay = new Ray(totalBounds.center, projectedHitVector);
                float edgeDistance;
                if (totalBounds.IntersectRay(edgeRay, out edgeDistance))
                {
                    if (showDebugLines)
                    {
                        Debug.DrawRay(totalBounds.center, projectedHitVector.normalized * Mathf.Abs(edgeDistance + distanceFromObstruction),
                                      Color.cyan);
                    }
                }

                // The new position is not camera position plus the projected hit vector, minus distance to the edge and a possible extra distance
                // we want to keep.
                return(GetCameraPosition(stabilizer) +
                       projectedHitVector - projectedHitVector.normalized * Mathf.Abs(edgeDistance + distanceFromObstruction) +
                       centerCorrection);
            }

            return(CalculatePositionDeadAhead(maxDistance, stabilizer) + centerCorrection);
        }
Example #4
0
 public static Vector3 CalculatePositionDeadAhead(float distance = 2.0f, BaseRayStabilizer stabilizer = null)
 {
     return(stabilizer != null
         ? stabilizer.StableRay.origin + stabilizer.StableRay.direction.normalized * distance
         : Camera.main.transform.position + Camera.main.transform.forward.normalized * distance);
 }