Exemplo n.º 1
0
    void Start()
    {
        // Disable the pointer graphic (until the user holds down on the touchpad)
        Pointer.enabled = false;

        // Standard plane mesh used for "fade out" graphic when you teleport
        // This way you don't need to supply a simple plane mesh in the inspector
        PlaneMesh = new Mesh();
        Vector3[] verts = new Vector3[]
        {
            new Vector3(-1, -1, 0),
            new Vector3(-1, 1, 0),
            new Vector3(1, 1, 0),
            new Vector3(1, -1, 0)
        };
        int[] elts = new int[] { 0, 1, 2, 0, 2, 3 };
        PlaneMesh.vertices = verts;
        PlaneMesh.triangles = elts;
        PlaneMesh.RecalculateBounds();

        // Set some standard variables
        MaterialFadeID = Shader.PropertyToID("_Fade");
        EnabledAnimatorID = Animator.StringToHash("Enabled");

        RoomBorder = GetComponent<BorderRenderer>();

        Vector3 p0, p1, p2, p3;
        if (GetChaperoneBounds(out p0, out p1, out p2, out p3))
        {
            BorderPointSet p = new BorderPointSet(new Vector3[] {
                    p0, p1, p2, p3, p0
                });
            RoomBorder.Points = new BorderPointSet[]
            {
                p
            };
        }

        RoomBorder.enabled = false;
    }
Exemplo n.º 2
0
    void Start()
    {
        int round = 0;

        foreach (ViveHand controls in Controller)
        {
            controls.SourceNumber = round;
            round += 1;
        }
        // Disable the pointer graphic (until the user holds down on the touchpad)
        Pointer.enabled = false;

        // Ensure we mark the player as not teleporting
        CurrentTeleportState = TeleportState.None;

        // Standard plane mesh used for "fade out" graphic when you teleport
        // This way you don't need to supply a simple plane mesh in the inspector
        PlaneMesh = new Mesh();
        Vector3[] verts = new Vector3[]
        {
            new Vector3(-1, -1, 0),
            new Vector3(-1, 1, 0),
            new Vector3(1, 1, 0),
            new Vector3(1, -1, 0)
        };
        int[] elts = new int[] { 0, 1, 2, 0, 2, 3 };
        PlaneMesh.vertices  = verts;
        PlaneMesh.triangles = elts;
        PlaneMesh.RecalculateBounds();

        if (FadeMaterial != null)
        {
            FadeMaterialInstance = new Material(FadeMaterial);
        }
        // Set some standard variables
        MaterialFadeID    = Shader.PropertyToID("_Fade");
        EnabledAnimatorID = Animator.StringToHash("Enabled");

        RoomBorder = GetComponent <BorderRenderer>();

        Vector3 p0, p1, p2, p3;

        if (GetChaperoneBounds(out p0, out p1, out p2, out p3))
        {
            // Rotate to match camera rig rotation
            var originRotationMatrix = Matrix4x4.TRS(Vector3.zero, OriginTransform.rotation, Vector3.one);

            BorderPointSet p = new BorderPointSet(new Vector3[] {
                originRotationMatrix *p0,
                originRotationMatrix *p1,
                originRotationMatrix *p2,
                originRotationMatrix *p3,
                originRotationMatrix *p0,
            });
            RoomBorder.Points = new BorderPointSet[]
            {
                p
            };
        }

        RoomBorder.enabled = false;
    }
Exemplo n.º 3
0
    void Update()
    {
        //if (isLocalPlayer)
        //{
        // If we are currently teleporting (ie handling the fade in/out transition)...
        if (CurrentTeleportState == TeleportState.Teleporting)
        {
            // Wait until half of the teleport time has passed before the next event (note: both the switch from fade
            // out to fade in and the switch from fade in to stop the animation is half of the fade duration)
            if (Time.time - TeleportTimeMarker >= TeleportFadeDuration / 2)
            {
                if (FadingIn)
                {
                    // We have finished fading in
                    CurrentTeleportState = TeleportState.None;
                }
                else
                {
                    // We have finished fading out - time to teleport!
                    Vector3 offset = OriginTransform.position - HeadTransform.position;
                    offset.y = 0;
                    OriginTransform.position = Pointer.SelectedPoint + offset;
                    //OriginTransform.GetComponent<NavMeshAgent>().destination = OriginTransform.position;


                    //control direction youre looking
                    if (heldLong)
                    {
                        OriginTransform.localEulerAngles = viewController.localEulerAngles;
                        heldLong      = false;
                        firstPadPress = true;
                    }
                }

                TeleportTimeMarker = Time.time;
                FadingIn           = !FadingIn;
            }
        }
        // At this point, we are NOT actively teleporting.  So now we care about controller input.
        else if (CurrentTeleportState == TeleportState.Selecting)
        {
            Debug.Assert(ActiveController != null);

            // Here, there is an active controller - that is, the user is holding down on the trackpad.
            // Poll controller for pertinent button data
            int  index          = (int)ActiveController.index;
            var  device         = SteamVR_Controller.Input(index);
            bool shouldTeleport = device.GetPressUp(SteamVR_Controller.ButtonMask.Touchpad);
            bool shouldCancel   = device.GetPressUp(SteamVR_Controller.ButtonMask.Grip);
            if (shouldTeleport || shouldCancel)
            {
                // If the user has decided to teleport (ie lets go of touchpad) then remove all visual indicators
                // related to selecting things and actually teleport
                // If the user has decided to cancel (ie squeezes grip button) then remove visual indicators and do nothing
                if (shouldTeleport && Pointer.PointOnNavMesh)
                {
                    // Begin teleport sequence
                    CurrentTeleportState = TeleportState.Teleporting;
                    TeleportTimeMarker   = Time.time;
                }
                else
                {
                    CurrentTeleportState = TeleportState.None;
                    heldLong             = false;
                    firstPadPress        = true;
                }


                // Reset active controller, disable pointer, disable visual indicators
                ActiveController   = null;
                Pointer.enabled    = false;
                RoomBorder.enabled = false;
                //RoomBorder.Transpose = Matrix4x4.TRS(OriginTransform.position, Quaternion.identity, Vector3.one);
                if (NavmeshAnimator != null)
                {
                    NavmeshAnimator.SetBool(EnabledAnimatorID, false);
                }

                Pointer.transform.parent     = null;
                Pointer.transform.position   = Vector3.zero;
                Pointer.transform.rotation   = Quaternion.identity;
                Pointer.transform.localScale = Vector3.one;
            }
            else
            {
                // The user is still deciding where to teleport and has the touchpad held down.
                // Note: rendering of the parabolic pointer / marker is done in ParabolicPointer
                Vector3 offset = HeadTransform.position - OriginTransform.position;
                offset.y = 0;

                // Render representation of where the chaperone bounds will be after teleporting
                RoomBorder.enabled   = Pointer.PointOnNavMesh;
                RoomBorder.Transpose = Matrix4x4.TRS(Pointer.SelectedPoint - offset, Quaternion.identity, Vector3.one);

                // Haptic feedback click every [HaptickClickAngleStep] degrees
                if (Pointer.CurrentParabolaAngleY >= 45) // Don't click when at max degrees
                {
                    LastClickAngle = Pointer.CurrentPointVector;
                }

                float angleClickDiff = Vector3.Angle(LastClickAngle, Pointer.CurrentPointVector);
                if (IsClicking && Mathf.Abs(angleClickDiff) > HapticClickAngleStep)
                {
                    LastClickAngle = Pointer.CurrentPointVector;
                    if (Pointer.PointOnNavMesh)
                    {
                        device.TriggerHapticPulse();
                    }
                }

                // Trigger a stronger haptic pulse when "entering" a teleportable surface
                if (Pointer.PointOnNavMesh && !IsClicking)
                {
                    IsClicking = true;
                    device.TriggerHapticPulse(750);
                    LastClickAngle = Pointer.CurrentPointVector;
                }
                else if (!Pointer.PointOnNavMesh && IsClicking)
                {
                    IsClicking = false;
                }

                //control rotation of the box
                if (heldLong)
                {
                    viewController.localEulerAngles = OriginTransform.localEulerAngles;

                    newRotate = Mathf.Atan2(device.GetAxis().y, device.GetAxis().x) * Mathf.Rad2Deg - 90;
                    viewController.localEulerAngles = new Vector3(0, ((viewController.localEulerAngles.y - newRotate)), 0);


                    Vector3 p0, p1, p2, p3;
                    if (GetChaperoneBounds(out p0, out p1, out p2, out p3))
                    {
                        // Rotate to match camera rig rotation
                        var originRotationMatrix = Matrix4x4.TRS(Vector3.zero, viewController.rotation, Vector3.one);

                        BorderPointSet p = new BorderPointSet(new Vector3[] {
                            originRotationMatrix *p0,
                            originRotationMatrix *p1,
                            originRotationMatrix *p2,
                            originRotationMatrix *p3,
                            originRotationMatrix *p0,
                        });
                        RoomBorder.Points = new BorderPointSet[]
                        {
                            p
                        };
                    }
                }
                if (firstPadPress)
                {
                    StartCoroutine(WaitHold());
                    firstPadPress = false;
                }
            }
        }
        else //CurrentTeleportState == TeleportState.None
        {
            // At this point the user is not holding down on the touchpad at all or has canceled a teleport and hasn't
            // let go of the touchpad.  So we wait for the user to press the touchpad and enable visual indicators
            // if necessary.
            foreach (SteamVR_TrackedObject obj in Controllers)
            {
                int index = (int)obj.index;
                if (index == -1)
                {
                    continue;
                }

                var device = SteamVR_Controller.Input(index);
                if (device.GetPressDown(SteamVR_Controller.ButtonMask.Touchpad))
                {
                    // Set active controller to this controller, and enable the parabolic pointer and visual indicators
                    // that the user can use to determine where they are able to teleport.
                    ActiveController = obj;

                    Pointer.transform.parent        = obj.transform;
                    Pointer.transform.localPosition = Vector3.zero;
                    Pointer.transform.localRotation = Quaternion.identity;
                    Pointer.transform.localScale    = Vector3.one;
                    Pointer.enabled = true;

                    CurrentTeleportState = TeleportState.Selecting;

                    if (NavmeshAnimator != null)
                    {
                        NavmeshAnimator.SetBool(EnabledAnimatorID, true);
                    }

                    Pointer.ForceUpdateCurrentAngle();
                    LastClickAngle = Pointer.CurrentPointVector;
                    IsClicking     = Pointer.PointOnNavMesh;
                }
            }
        }
    }
Exemplo n.º 4
0
    /// \brief Given some mesh m, calculates a number of polylines that border the mesh.  This may return more than
    /// one polyline if, for example, the mesh has holes in it or if the mesh is separated in two pieces.
    /// \param m input mesh
    /// \returns array of cyclic polylines
    private static BorderPointSet[] FindBorderEdges(Mesh m)
    {
        // First, get together all the edges in the mesh and find out
        // how many times each edge is used.  Edges that are only used
        // once are border edges.

        // Key: edges (note that because of how the hashcode / equals() is set up, two equivalent edges will effectively
        //      be equal)
        // Value: How many times this edge shows up in the mesh.  Any keys with a value of 1 are border edges.
        Dictionary <Edge, int> edges = new Dictionary <Edge, int>();

        for (int x = 0; x < m.triangles.Length / 3; x++)
        {
            int p1 = m.triangles[x * 3];
            int p2 = m.triangles[x * 3 + 1];
            int p3 = m.triangles[x * 3 + 2];

            Edge[] e = new Edge[3];
            e[0] = new Edge(p1, p2);
            e[1] = new Edge(p2, p3);
            e[2] = new Edge(p3, p1);

            foreach (Edge d in e)
            {
                int curval;
                edges.TryGetValue(d, out curval); // 0 if nonexistant
                edges[d] = curval + 1;
            }
        }

        // Next, consolidate all of the border edges into one List<Edge>
        List <Edge> border = new List <Edge>();

        foreach (KeyValuePair <Edge, int> p in edges)
        {
            if (p.Value == 1) // border edge == edge only used once.
            {
                border.Add(p.Key);
            }
        }

        // Perform the following routine:
        // 1. Pick any unvisited edge segment [v_start,v_next] and add these vertices to the polygon loop.
        // 2. Find the unvisited edge segment [v_i,v_j] that has either v_i = v_next or v_j = v_next and add the
        //    other vertex (the one not equal to v_next) to the polygon loop. Reset v_next as this newly added vertex,
        //    mark the edge as visited and continue from 2.
        // 3. Traversal is done when we get back to v_start.
        // Source: http://stackoverflow.com/questions/14108553/get-border-edges-of-mesh-in-winding-order
        bool[] visited   = new bool[border.Count];
        bool   finished  = false;
        int    cur_index = 0;

        List <Vector3[]> ret = new List <Vector3[]>();

        while (!finished)
        {
            int[]     raw = FindPolylineFromEdges(cur_index, visited, border);
            Vector3[] fmt = new Vector3[raw.Length];
            for (int x = 0; x < raw.Length; x++)
            {
                fmt[x] = m.vertices[raw[x]];
            }
            ret.Add(fmt);

            finished = true;
            for (int x = 0; x < visited.Length; x++)
            {
                if (!visited[x])
                {
                    cur_index = x;
                    finished  = false;
                    break;
                }
            }
        }

        BorderPointSet[] ret_set = new BorderPointSet[ret.Count];
        for (int x = 0; x < ret.Count; x++)
        {
            ret_set[x] = new BorderPointSet(ret[x]);
        }
        return(ret_set);
    }
    /// \brief Given some mesh m, calculates a number of polylines that border the mesh.  This may return more than
    ///        one polyline if, for example, the mesh has holes in it or if the mesh is separated in two pieces.
    ///
    /// \param m input mesh
    /// \returns array of cyclic polylines
    private static BorderPointSet[] FindBorderEdges(Mesh m)
    {
        // First, get together all the edges in the mesh and find out
        // how many times each edge is used.  Edges that are only used
        // once are border edges.

        // Key: edges (note that because of how the hashcode / equals() is set up, two equivalent edges will effectively
        //      be equal)
        // Value: How many times this edge shows up in the mesh.  Any keys with a value of 1 are border edges.
        Dictionary<Edge, int> edges = new Dictionary<Edge, int>();
        for (int x = 0; x < m.triangles.Length / 3; x++)
        {
            int p1 = m.triangles[x * 3];
            int p2 = m.triangles[x * 3 + 1];
            int p3 = m.triangles[x * 3 + 2];

            Edge[] e = new Edge[3];
            e[0] = new Edge(p1, p2);
            e[1] = new Edge(p2, p3);
            e[2] = new Edge(p3, p1);

            foreach (Edge d in e) {
                int curval;
                edges.TryGetValue(d, out curval); // 0 if nonexistant
                edges[d] = curval + 1;
            }
        }

        // Next, consolidate all of the border edges into one List<Edge>
        List<Edge> border = new List<Edge>();
        foreach (KeyValuePair<Edge, int> p in edges)
        {
            if (p.Value == 1) // border edge == edge only used once.
                border.Add(p.Key);
        }

        // Perform the following routine:
        // 1. Pick any unvisited edge segment [v_start,v_next] and add these vertices to the polygon loop.
        // 2. Find the unvisited edge segment [v_i,v_j] that has either v_i = v_next or v_j = v_next and add the
        //    other vertex (the one not equal to v_next) to the polygon loop. Reset v_next as this newly added vertex,
        //    mark the edge as visited and continue from 2.
        // 3. Traversal is done when we get back to v_start.
        // Source: http://stackoverflow.com/questions/14108553/get-border-edges-of-mesh-in-winding-order
        bool[] visited = new bool[border.Count];
        bool finished = false;
        int cur_index = 0;

        List<Vector3[]> ret = new List<Vector3[]>();

        while(!finished)
        {
            int[] raw = FindPolylineFromEdges(cur_index, visited, border);
            Vector3[] fmt = new Vector3[raw.Length];
            for (int x = 0; x < raw.Length; x++)
                fmt[x] = m.vertices[raw[x]];
            ret.Add(fmt);

            finished = true;
            for (int x=0;x<visited.Length;x++) {
                if (!visited[x])
                {
                    cur_index = x;
                    finished = false;
                    break;
                }
            }
        }

        BorderPointSet[] ret_set = new BorderPointSet[ret.Count];
        for (int x = 0; x < ret.Count; x++)
        {
            ret_set[x] = new BorderPointSet(ret[x]);
        }
        return ret_set;
    }