Пример #1
0
    public override void OnInspectorGUI()
    {
        GUIStyle bold_wrap = EditorStyles.boldLabel;

        bold_wrap.wordWrap = true;
        GUILayout.Label("Navmesh Preprocessor for HTC Vive Locomotion", bold_wrap);
        GUILayout.Label("Adrian Biagioli 2016", EditorStyles.miniLabel);

        GUILayout.Label("Before Using", bold_wrap);
        GUIStyle wrap = EditorStyles.label;

        wrap.wordWrap = true;
        GUILayout.Label(
            "Change your navmesh settings (Window > Navigation) to where you want the player to be able to navigate and bake the navmesh.  " +
            "Then click \"Update Navmesh Data\" below.  You may change the navigation settings back and rebake after you have updated.\n\nRecommended Settings:\n" +
            "Agent Radius: 0.25\nAgent Height: 2\nMax Slope: 0\nStep Height: 0\nDrop Height: 0\nJump Distance: 0\n",
            wrap);

        ViveNavMesh mesh = (ViveNavMesh)target;

        if (GUILayout.Button("Update Navmesh Data"))
        {
            mesh.SelectableMesh       = ConvertNavmeshToMesh(NavMesh.CalculateTriangulation(), 0);
            mesh.SelectableMeshBorder = FindBorderEdges(mesh.SelectableMesh);
        }

        EditorGUILayout.LabelField("Render Settings", EditorStyles.boldLabel);
        mesh.GroundMaterial = (Material)EditorGUILayout.ObjectField("Ground Material", mesh.GroundMaterial, typeof(Material), false);
        mesh.GroundAlpha    = EditorGUILayout.Slider("Ground Alpha", mesh.GroundAlpha, 0, 1);
    }
Пример #2
0
    // Sample a bunch of points along a parabolic curve until you hit gnd.  At that point, cut off the parabola
    // p0: starting point of parabola
    // v0: initial parabola velocity
    // a: initial acceleration
    // dist: distance between sample points
    // points: number of sample points
    // gnd: height of the ground, in meters above y=0
    // outPts: List that will be populated by new points
    private static bool CalculateParabolicCurve(Vector3 p0, Vector3 v0, Vector3 a, float dist, int points, ViveNavMesh nav, List<Vector3> outPts)
    {
        outPts.Clear();
        outPts.Add(p0);

        Vector3 last = p0;
        float t = 0;

        for(int i=0; i< points; i++)
        {
            t += dist / ParabolicCurveDeriv(v0, a, t).magnitude;
            Vector3 next = ParabolicCurve(p0, v0, a, t);

            Vector3 castHit;
            bool endOnNavmesh;
            bool cast = nav.Linecast(last, next, out endOnNavmesh, out castHit);
            if (cast)
            {
                outPts.Add(castHit);
                return endOnNavmesh;
            }
            else
                outPts.Add(next);

            last = next;
        }

        return false;
    }
Пример #3
0
    public void UpdateNavMesh()
    {
        ViveNavMesh mesh = (ViveNavMesh)target;

        Undo.RecordObject(mesh, "Update Navmesh Data");

        NavMeshTriangulation tri = NavMesh.CalculateTriangulation();

        Vector3[] verts = tri.vertices;
        int[]     tris  = tri.indices;
        int[]     areas = tri.areas;

        int vert_size = verts.Length;
        int tri_size  = tris.Length;

        RemoveMeshDuplicates(verts, tris, out vert_size, 0.01f);
        DewarpMesh(verts, mesh.DewarpingMethod, mesh.SampleRadius);
        CullNavmeshTriangulation(verts, tris, areas, p_area.intValue, mesh.IgnoreSlopedSurfaces, ref vert_size, ref tri_size);

        Mesh m = ConvertNavmeshToMesh(verts, tris, vert_size, tri_size);

        // Can't use SerializedProperties here because BorderPointSet doesn't derive from UnityEngine.Object
        mesh.SelectableMeshBorder = FindBorderEdges(m);

        serializedObject.Update();
        p_mesh.objectReferenceValue = m;
        serializedObject.ApplyModifiedPropertiesWithoutUndo();
        mesh.SelectableMesh = mesh.SelectableMesh; // Make sure that setter is called
    }
Пример #4
0
        private IEnumerator Start()
        {
            yield return(null);

            ToggleGosForPreview(true, _gosToHideInPreview);
            ToggleGosForPreview(false, _gosToShowInPreview);

            //If user has checked the "Is Test Scene" checkbox load the current scene
            if (_isTestScene)
            {
                //make sure we have a navmesh
                if (_navMesh == null)
                {
                    _navMesh = FindObjectOfType <ViveNavMesh>();
                    if (_navMesh != null)
                    {
                        _navMeshAnimator = _navMesh.GetComponent <Animator>();

                        ParabolicPointer pointer = FindObjectOfType <ParabolicPointer>();
                        if (pointer != null)
                        {
                            pointer.NavMesh = _navMesh;
                        }

                        TeleportVive teleporter = FindObjectOfType <TeleportVive>();
                        if (teleporter != null)
                        {
                            teleporter.NavAnimator = _navMeshAnimator;
                        }
                    }
                }

                LoadTestScene();
            }
        }
Пример #5
0
    // Sample a bunch of points along a parabolic curve until you hit gnd.  At that point, cut off the parabola
    // p0: starting point of parabola
    // v0: initial parabola velocity
    // a: initial acceleration
    // dist: distance between sample points
    // points: number of sample points
    // gnd: height of the ground, in meters above y=0
    // outPts: List that will be populated by new points
    private static bool CalculateParabolicCurve(Vector3 p0, Vector3 v0, Vector3 a, float dist, int points, ViveNavMesh nav, List <Vector3> outPts)
    {
        outPts.Clear();
        outPts.Add(p0);

        Vector3 last = p0;
        float   t    = 0;

        for (int i = 0; i < points; i++)
        {
            t += dist / ParabolicCurveDeriv(v0, a, t).magnitude;
            Vector3 next = ParabolicCurve(p0, v0, a, t);

            Vector3 castHit;
            bool    endOnNavmesh;
            bool    cast = nav.Linecast(last, next, out endOnNavmesh, out castHit);
            if (cast)
            {
                outPts.Add(castHit);
                return(endOnNavmesh);
            }
            else
            {
                outPts.Add(next);
            }

            last = next;
        }


        return(false);
    }
Пример #6
0
    public override void OnInspectorGUI()
    {
        GUIStyle bold_wrap = EditorStyles.boldLabel;

        bold_wrap.wordWrap = true;
        GUILayout.Label("Navmesh Preprocessor for HTC Vive Locomotion", bold_wrap);
        GUILayout.Label("Adrian Biagioli 2016", EditorStyles.miniLabel);

        GUILayout.Label("Before Using", bold_wrap);
        GUIStyle wrap = EditorStyles.label;

        wrap.wordWrap = true;
        GUILayout.Label(
            "Make sure you bake a Navigation Mesh (NavMesh) in Unity before continuing (Window > Navigation).  When you " +
            "are done, click \"Update Navmesh Data\" below.  This will update the graphic of the playable area " +
            "that the player will see in-game.\n",
            wrap);

        ViveNavMesh mesh = (ViveNavMesh)target;

        serializedObject.Update();

        // Area Mask //
        string[] areas      = GameObjectUtility.GetNavMeshAreaNames();
        int[]    area_index = new int[areas.Length];
        int      temp_mask  = 0;

        for (int x = 0; x < areas.Length; x++)
        {
            area_index[x] = GameObjectUtility.GetNavMeshAreaFromName(areas[x]);
            temp_mask    |= ((p_area.intValue >> area_index[x]) & 1) << x;
        }
        EditorGUI.BeginChangeCheck();
        temp_mask = EditorGUILayout.MaskField("Area Mask", temp_mask, areas);
        if (EditorGUI.EndChangeCheck())
        {
            p_area.intValue = 0;
            for (int x = 0; x < areas.Length; x++)
            {
                p_area.intValue |= (((temp_mask >> x) & 1) == 1 ? 0 : 1) << area_index[x];
            }
            p_area.intValue = ~p_area.intValue;
        }
        serializedObject.ApplyModifiedProperties();

        // Sanity check for Null properties //
        bool HasMesh = (mesh.SelectableMesh != null && mesh.SelectableMesh.vertexCount != 0) || (mesh.SelectableMeshBorder != null && mesh.SelectableMeshBorder.Length != 0);

        // Fixes below error message popping up with prefabs.  Kind of hacky but gets the job done
        bool isPrefab = EditorUtility.IsPersistent(target);

        if (isPrefab && mesh.SelectableMesh == null)
        {
            mesh.SelectableMesh = new Mesh();
        }

        bool MeshNull   = mesh.SelectableMesh == null;
        bool BorderNull = mesh.SelectableMeshBorder == null;

        if (MeshNull || BorderNull)
        {
            string str = "Internal Error: ";
            if (MeshNull)
            {
                str += "Selectable Mesh == null.  ";
            }
            if (BorderNull)
            {
                str += "Border point array == null.  ";
            }
            str += "This may lead to strange behavior or serialization.  Try updating the mesh or delete and recreate the Navmesh object.  ";
            str += "If you are able to consistently get a Vive Nav Mesh object into this state, please submit a bug report.";
            EditorGUILayout.HelpBox(str, MessageType.Error);
        }

        // Update / Clear Navmesh Data //
        if (GUILayout.Button("Update Navmesh Data"))
        {
            Undo.RecordObject(mesh, "Update Navmesh Data");

            UnityEngine.AI.NavMeshTriangulation tri = UnityEngine.AI.NavMesh.CalculateTriangulation();
            int vert_size, tri_size;
            CullNavmeshTriangulation(ref tri, p_area.intValue, out vert_size, out tri_size);

            Mesh m = ConvertNavmeshToMesh(tri, vert_size, tri_size);
            // Can't use SerializedProperties here because BorderPointSet doesn't derive from UnityEngine.Object
            mesh.SelectableMeshBorder = FindBorderEdges(m);

            serializedObject.Update();
            p_mesh.objectReferenceValue = m;
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.SelectableMesh = mesh.SelectableMesh; // Make sure that setter is called
        }

        GUI.enabled = HasMesh;
        if (GUILayout.Button("Clear Navmesh Data"))
        {
            Undo.RecordObject(mesh, "Clear Navmesh Data");

            // Note: Unity does not serialize "null" correctly so we set everything to empty objects
            Mesh m = new Mesh();

            serializedObject.Update();
            p_mesh.objectReferenceValue = m;
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.SelectableMesh = mesh.SelectableMesh; // Make sure setter is called

            mesh.SelectableMeshBorder = new BorderPointSet[0];
        }
        GUI.enabled = true;

        GUILayout.Label(HasMesh ? "Status: NavMesh Loaded" : "Status: No NavMesh Loaded");

        // Render Settings //
        EditorGUILayout.LabelField("Render Settings", EditorStyles.boldLabel);

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(p_material);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(mesh, "Change Ground Material");
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.GroundMaterial = mesh.GroundMaterial; // Reload material
        }

        EditorGUILayout.PropertyField(p_alpha);
        serializedObject.ApplyModifiedProperties();
    }
Пример #7
0
    public override void OnInspectorGUI()
    {
        GUIStyle bold_wrap = EditorStyles.boldLabel;

        bold_wrap.wordWrap = true;
        GUILayout.Label("Navmesh Preprocessor for HTC Vive Locomotion", bold_wrap);
        GUILayout.Label("Adrian Biagioli 2017", EditorStyles.miniLabel);

        GUILayout.Label("Before Using", bold_wrap);
        GUIStyle wrap = EditorStyles.label;

        wrap.wordWrap = true;
        GUILayout.Label(
            "Make sure you bake a Navigation Mesh (NavMesh) in Unity before continuing (Window > Navigation).  When you " +
            "are done, click \"Update Navmesh Data\" below.  This will update the graphic of the playable area " +
            "that the player will see in-game.\n", wrap);

        ViveNavMesh mesh = (ViveNavMesh)target;

        serializedObject.Update();

        // Area Mask //
        string[] areaNames  = GameObjectUtility.GetNavMeshAreaNames();
        int[]    area_index = new int[areaNames.Length];
        int      temp_mask  = 0;

        for (int x = 0; x < areaNames.Length; x++)
        {
            area_index[x] = GameObjectUtility.GetNavMeshAreaFromName(areaNames[x]);
            temp_mask    |= ((p_area.intValue >> area_index[x]) & 1) << x;
        }
        EditorGUI.BeginChangeCheck();
        temp_mask = EditorGUILayout.MaskField("Area Mask", temp_mask, areaNames);
        if (EditorGUI.EndChangeCheck())
        {
            p_area.intValue = 0;
            for (int x = 0; x < areaNames.Length; x++)
            {
                p_area.intValue |= (((temp_mask >> x) & 1) == 1 ? 0 : 1) << area_index[x];
            }
            p_area.intValue = ~p_area.intValue;
        }
        serializedObject.ApplyModifiedProperties();

        // Sanity check for Null properties //
        bool HasMesh = (mesh.SelectableMesh != null && mesh.SelectableMesh.vertexCount != 0) ||
                       (mesh.SelectableMeshBorder != null && mesh.SelectableMeshBorder.Length != 0);

        // Fixes below error message popping up with prefabs.  Kind of hacky but gets the job done
        bool isPrefab = EditorUtility.IsPersistent(target);

        if (isPrefab && mesh.SelectableMesh == null)
        {
            mesh.SelectableMesh = new Mesh();
        }

        bool MeshNull   = mesh.SelectableMesh == null;
        bool BorderNull = mesh.SelectableMeshBorder == null;

        if (MeshNull || BorderNull)
        {
            string str = "Internal Error: ";
            if (MeshNull)
            {
                str += "Selectable Mesh == null.  ";
            }
            if (BorderNull)
            {
                str += "Border point array == null.  ";
            }
            str +=
                "This may lead to strange behavior or serialization.  Try updating the mesh or delete and recreate the Navmesh object.  ";
            str += "If you are able to consistently get a Vive Nav Mesh object into this state, please submit a bug report.";
            EditorGUILayout.HelpBox(str, MessageType.Error);
        }

        // Update / Clear Navmesh Data //
        if (GUILayout.Button("Update Navmesh Data"))
        {
            Undo.RecordObject(mesh, "Update Navmesh Data");

            NavMeshTriangulation tri = NavMesh.CalculateTriangulation();

            Vector3[] verts = tri.vertices;
            int[]     tris  = tri.indices;
            int[]     areas = tri.areas;

            int vert_size = verts.Length;
            int tri_size  = tris.Length;
            RemoveMeshDuplicates(verts, tris, out vert_size, 0.01f);
            DewarpMesh(verts, mesh.DewarpingMethod, mesh.SampleRadius);
            CullNavmeshTriangulation(verts, tris, areas, p_area.intValue, mesh.IgnoreSlopedSurfaces, ref vert_size,
                                     ref tri_size);

            Mesh m = ConvertNavmeshToMesh(verts, tris, vert_size, tri_size);
            // Can't use SerializedProperties here because BorderPointSet doesn't derive from UnityEngine.Object
            mesh.SelectableMeshBorder = FindBorderEdges(m);

            serializedObject.Update();
            p_mesh.objectReferenceValue = m;
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.SelectableMesh = mesh.SelectableMesh; // Make sure that setter is called
        }

        GUI.enabled = HasMesh;
        if (GUILayout.Button("Clear Navmesh Data"))
        {
            Undo.RecordObject(mesh, "Clear Navmesh Data");

            // Note: Unity does not serialize "null" correctly so we set everything to empty objects
            Mesh m = new Mesh();

            serializedObject.Update();
            p_mesh.objectReferenceValue = m;
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.SelectableMesh = mesh.SelectableMesh; // Make sure setter is called

            mesh.SelectableMeshBorder = new BorderPointSet[0];
        }
        GUI.enabled = true;

        GUILayout.Label(HasMesh ? "Status: NavMesh Loaded" : "Status: No NavMesh Loaded");

        // Render Settings //
        EditorGUILayout.LabelField("Render Settings", EditorStyles.boldLabel);

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(p_material);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(mesh, "Change Ground Material");
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
            mesh.GroundMaterial = new Material((Material)p_material.objectReferenceValue); // Reload material
        }

        EditorGUILayout.PropertyField(p_alpha);
        serializedObject.ApplyModifiedProperties();

        // Raycast Settings //
        EditorGUILayout.LabelField("Raycast Settings", EditorStyles.boldLabel);

        int  temp_layer_mask        = p_layer_mask.intValue;
        bool temp_ignore_layer_mask = p_ignore_layer_mask.boolValue;

        EditorGUI.BeginChangeCheck();
        temp_layer_mask = LayerMaskField("Layer Mask", temp_layer_mask);
        if (EditorGUI.EndChangeCheck())
        {
            p_layer_mask.intValue = temp_layer_mask;
        }
        serializedObject.ApplyModifiedProperties();
        EditorGUI.BeginChangeCheck();
        temp_ignore_layer_mask = EditorGUILayout.Toggle("Ignore Layer Mask", temp_ignore_layer_mask);
        if (EditorGUI.EndChangeCheck())
        {
            p_ignore_layer_mask.boolValue = temp_ignore_layer_mask;
        }
        serializedObject.ApplyModifiedProperties();

        QueryTriggerInteraction temp_query_trigger_interaction =
            (QueryTriggerInteraction)p_query_trigger_interaction.intValue;

        EditorGUI.BeginChangeCheck();
        temp_query_trigger_interaction =
            (QueryTriggerInteraction)EditorGUILayout.EnumPopup("Query Trigger Interaction", temp_query_trigger_interaction);
        if (EditorGUI.EndChangeCheck())
        {
            p_query_trigger_interaction.intValue = (int)temp_query_trigger_interaction;
        }
        serializedObject.ApplyModifiedProperties();

        // Navmesh Settings //
        EditorGUILayout.LabelField("Navmesh Settings", EditorStyles.boldLabel);
        GUILayout.Label(
            "Make sure the sample radius below is equal to your Navmesh Voxel Size (see Advanced > Voxel Size " +
            "in the navigation window).  Increase this if the selection disk is not appearing.", wrap);
        EditorGUILayout.PropertyField(p_sample_radius);
        EditorGUILayout.PropertyField(p_ignore_sloped_surfaces);
        EditorGUILayout.PropertyField(p_dewarp_method);

        serializedObject.ApplyModifiedProperties();
    }