public SerialiableNavMesh AsSerialiableNavMesh()
    {
        SerialiableNavMesh ret = new SerialiableNavMesh();

        if (connections != null)
        {
            ret.connections = FUtils.FlatMap(connections.Keys, from =>
                                             FUtils.Map(connections[from], to => new CellConnection(from, to)));
        }
        else
        {
            ret.connections = new List <CellConnection>();
        }

        if (positions != null)
        {
            ret.positions = FUtils.Map(positions.Keys, from =>
                                       new CellPosition(from, positions[from]));
        }
        else
        {
            ret.positions = new List <CellPosition>();
        }

        return(ret);
    }
    public override void OnImportAsset(AssetImportContext ctx)
    {
        var text       = File.ReadAllText(ctx.assetPath);
        var rjObj      = JsonUtility.FromJson <RJObj>(text);
        var rjMesh     = rjObj.mesh;
        var rjVertices = rjMesh.vertices;

        List <Material> materialList = new List <Material>();
        var             mesh         = new Mesh();

        mesh.name         = rjObj.name + "Mesh";
        mesh.subMeshCount = rjMesh.materials.Count;

        int rootIndex        = getGroupIndex(rjObj.groups, "Root");
        int attachPointIndex = getGroupIndex(rjObj.groups, "AttachPoint");

        var mV   = new List <Vector3>();
        var mN   = new List <Vector3>();
        var mUVA = new List <List <Vector2> >();
        var mEA  = new List <List <int> >();

        for (int layerIndex = 0; layerIndex < rjMesh.uvLayers.Count; ++layerIndex)
        {
            mUVA.Add(new List <Vector2>());
        }

        Vector3 rootVector        = Vector3.zero;
        Vector3 attachPointVector = Vector3.zero;

        foreach (RJVector vector in rjMesh.vertices)
        {
            if (vector.groups.Contains(rootIndex))
            {
                rootVector = toVector3(vector.p);
                Debug.Log("Root Vector: " + rootVector);
            }
            if (vector.groups.Contains(attachPointIndex))
            {
                attachPointVector = toVector3(vector.p);
                Debug.Log("Attach Point: " + attachPointVector);
            }
        }

        for (int materialIndex = 0; materialIndex < rjMesh.materials.Count; ++materialIndex)
        {
            RJMaterial rjMaterial   = rjMesh.materials[materialIndex];
            string     materialPath = "Assets/" + rjMaterial.name + ".mat";
            Material   material     = AssetDatabase.LoadAssetAtPath("Assets/Space/Materials/" + rjMaterial.name + ".mat", typeof(Material)) as Material;
            if (material == null)
            {
                throw new Exception("Cannot load material " + materialPath);
            }
            materialList.Add(material);

            var mE = new List <int>();

            foreach (int faceIndex in Enumerable.Range(0, rjMesh.faces.Count))
            {
                RJFace face = rjMesh.faces[faceIndex];

                if (face.materialIndex != materialIndex)
                {
                    continue;
                }

                List <int> vs        = face.vertexIndexes;
                int        baseIndex = mV.Count;
                foreach (int vIndex in face.vertexIndexes)
                {
                    mV.Add(toVector3(rjVertices[vIndex]));
                    mN.Add(toVector3(face.normal));
                }

                if (vs.Count == 3)
                {
                    mE.Add(baseIndex + 0);
                    mE.Add(baseIndex + 1);
                    mE.Add(baseIndex + 2);
                }
                else if (vs.Count == 4)
                {
                    mE.Add(baseIndex + 0);
                    mE.Add(baseIndex + 1);
                    mE.Add(baseIndex + 2);

                    mE.Add(baseIndex + 0);
                    mE.Add(baseIndex + 2);
                    mE.Add(baseIndex + 3);
                }
                else
                {
                    throw new Exception("Unexpected number of verticies in face count=" + vs.Count);
                }

                for (int layerIndex = 0; layerIndex < rjMesh.uvLayers.Count; ++layerIndex)
                {
                    RJUVLayer uvLayer = rjMesh.uvLayers[layerIndex];
                    var       uvList  = uvLayer.faces[faceIndex].uvList;

                    if (uvList.Count != vs.Count)
                    {
                        throw new Exception("Diffing verticies and uvLists vCount=" + vs.Count + " uvList.Count=" + uvList.Count);
                    }
                    foreach (RJVector rjVector in uvList)
                    {
                        mUVA[layerIndex].Add(toVector2(rjVector));
                    }
                }
            }
            mEA.Add(mE);
        }

        mV = FUtils.Map(mV, v => v - rootVector);
        mesh.SetVertices(mV);
        mesh.SetNormals(mN);

        for (int layerIndex = 0; layerIndex < rjMesh.uvLayers.Count; ++layerIndex)
        {
            mesh.SetUVs(layerIndex, mUVA[layerIndex]);
        }

        for (int materialIndex = 0; materialIndex < rjMesh.materials.Count; ++materialIndex)
        {
            mesh.SetTriangles(mEA[materialIndex], materialIndex);
        }

        GameObject gameObject = new GameObject(rjObj.name);

        GameObject attachPoint = new GameObject("AttachPoint");

        attachPoint.transform.parent        = gameObject.transform;
        attachPoint.transform.localPosition = attachPointVector;

        MeshFilter meshFilter = gameObject.AddComponent <MeshFilter>();

        meshFilter.sharedMesh = mesh;

        var meshRenderer = gameObject.AddComponent <MeshRenderer>();

        meshRenderer.materials = materialList.ToArray();

        ctx.AddObjectToAsset("mesh", mesh);
        ctx.AddObjectToAsset("main", gameObject);

        ctx.SetMainObject(gameObject);
    }