SceneControllerEditor.cs 5.37 KB
Newer Older
1
2
3
using UnityEngine;
using UnityEditor;
using System.Linq;
Sebastian Höffner's avatar
Sebastian Höffner committed
4
5
using SimpleJSON;
using System.IO;
6
using System.Collections.Generic;
7
8
9
10
11
12
13

namespace dlu
{

[CustomEditor(typeof(SceneController))]
public class SceneControllerEditor : Editor
{
14
15
    private bool showLabels = false;

16
    private JSONArray sceneJson;
17
18
19
20
21
22
23
    private JSONArray instructionJson;

    public SceneControllerEditor()
    {
        JSONNode.VectorContainerType = JSONContainerType.Object;
        JSONNode.QuaternionContainerType = JSONContainerType.Object;
    }
24
25
26
27

    public override void OnInspectorGUI()
    {
        SceneController sc = (SceneController) target;
28
29
30
31
        if (sc.semanticBehaviours == null || GUILayout.Button("Refresh list of semantic labels"))
        {
            sc.semanticBehaviours = sc.FindSemanticLabels();
        }
32

33
34
35
        EditorGUILayout.Space();
        base.DrawDefaultInspector();
        ImportInstruction(sc);
36

Sebastian Höffner's avatar
Sebastian Höffner committed
37
        EditorGUILayout.Space();
38
        ExportContext(sc);
39
40

        EditorGUILayout.Space();
41
        ShowSemanticLabels(sc);
42

43
44
    }

45
    private void ShowSemanticLabels(SceneController sc)
46
47
48
49
    {
        showLabels = EditorGUILayout.BeginFoldoutHeaderGroup(showLabels, "Semantic labels");
        if (showLabels)
        {
50
            foreach (SemanticBehaviour sb in sc.semanticBehaviours)
51
            {
52
                string label = sb.GetComponent<InstanceIdentifier>().name;
53
                // Fill dict
54
                if (sb.is_a.Count() > 0)
55
                {
56
                    label += $" a {sb.is_a.Split('#')[1]}";
57
                }
58
                EditorGUILayout.ObjectField(label, sb.gameObject, typeof(GameObject), true);
59
60
            }
        }
Sebastian Höffner's avatar
Sebastian Höffner committed
61
62
63
64
65
66

        EditorGUILayout.EndFoldoutHeaderGroup();
    }

    private void ExportContext(SceneController sc)
    {
67
        string exportFile = EditorGUILayout.TextField("Export Context File", "Assets/DLU/Resources/context.json");
68
        sceneJson = GenerateContextJSON(sc);
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
        if (GUILayout.Button("Export to file"))
        {
            File.WriteAllText(exportFile, sceneJson.ToString());
        }
        EditorGUILayout.TextArea(sceneJson == null ? "" : sceneJson.ToString());
    }

    private void ImportInstruction(SceneController sc)
    {
        if (sc.instruction == null || GUILayout.Button("Import instruction JSON"))
        {
            sc.instruction = sc.LoadInstruction(sc.importInstructionFile);
        }
        EditorGUILayout.TextArea(sc.instruction == null ? "" : sc.instruction.ToString());
    }


86
    public JSONArray GenerateContextJSON(SceneController sc)
87
88
    {
        Dictionary<string, JSONObject> sceneDict = new Dictionary<string, JSONObject>();
Sebastian Höffner's avatar
Sebastian Höffner committed
89

90
        JSONArray sceneArray = new JSONArray();
91
        foreach (SemanticBehaviour sb in sc.semanticBehaviours)
Sebastian Höffner's avatar
Sebastian Höffner committed
92
        {
93
94
95
96
            JSONObject jsonObject = null;
            string name = sb.GetComponent<InstanceIdentifier>().name;

            if (!sceneDict.ContainsKey(name))
97
            {
98
99
100
101
102
103
104
                jsonObject = new JSONObject();
                jsonObject.Add("name", name);
                jsonObject.Add("is_a", new JSONArray());
                jsonObject.Add("components", new JSONObject());

                sceneDict[name] = jsonObject;
                sceneArray.Add(sceneDict[name]);
105
            }
106
107
108
109
110

            jsonObject = sceneDict[name];
            jsonObject["is_a"].Add(sb.is_a);

            switch (sb)
Sebastian Höffner's avatar
Sebastian Höffner committed
111
            {
112
113
114
115
116
                case Entity entity: Write(jsonObject, entity); break;
                case DesignedContainer designedContainer: Write(jsonObject, designedContainer); break;
                default:
                    Debug.LogWarning($"No Write handler for SemanticBehaviour \"{sb.GetType().Name}\"");
                    break;
Sebastian Höffner's avatar
Sebastian Höffner committed
117
118
            }
        }
119
120
121
122
123
124
125
126
127
128
        return sceneArray;
    }

    private void Write(JSONObject jsonObject, Entity entity)
    {
        JSONObject transform = new JSONObject();
        transform["position"] = entity.transform.position;
        transform["orientation"] = entity.transform.rotation;
        jsonObject["components"]["transform"] = transform;

129
        Vector3 scale = entity.transform.lossyScale;
130
131
132
133
        MeshFilter meshFilter = entity.GetComponent<MeshFilter>();
        if (meshFilter != null)
        {
            Mesh mesh = meshFilter.sharedMesh;
134
135
136
137
138
139
            Vector3 boundsCenterWorld = mesh.bounds.center;
            boundsCenterWorld.Scale(scale);
            Vector3 boundsExtentsWorld = mesh.bounds.center;
            boundsExtentsWorld.Scale(scale);
            Vector3 boundsSizeWorld = mesh.bounds.center;
            boundsSizeWorld.Scale(scale);
140
            JSONObject bounds = new JSONObject();
141
142
143
            bounds["center"] = boundsCenterWorld;
            bounds["extents"] = boundsExtentsWorld;
            bounds["size"] = boundsSizeWorld;
144
145
146
            jsonObject["components"]["bounds"] = bounds;
        }
    }
Sebastian Höffner's avatar
Sebastian Höffner committed
147

148
149
150
151
152
153
154
155
156
157
158
159
160
    private void Write(JSONObject jsonObject, DesignedContainer designedContainer)
    {
        JSONArray containment = new JSONArray();
        foreach (Collider collider in designedContainer.containmentParts)
        {
            JSONObject part = new JSONObject();
            part.Add("type", collider.GetType().Name);
            part.Add("center", collider.bounds.center);
            part.Add("size", collider.bounds.size);
            part.Add("extents", collider.bounds.extents);
            containment.Add(part);
        }
        jsonObject["components"]["containerVolume"] = containment;
161
162
163
164
    }
}

}