public static void exportPhysXScene()
    {
        var path = EditorUtility.SaveFilePanel("Export PhysXScene", Application.dataPath + "/..", "pxscene", string.Empty);

        if (path == null || path.Length == 0)
        {
            return;
        }

        System.Collections.Generic.List <GameObject> terrainTrees = new System.Collections.Generic.List <GameObject>();
        foreach (var terrain in Terrain.activeTerrains)
        {
            var tt = new GameObject("__Trees");
            terrainTrees.Add(tt);
            tt.transform.SetParent(tt.transform, false);
            var td = terrain.terrainData;
            foreach (var ti in td.treeInstances)
            {
                var tp = td.treePrototypes[ti.prototypeIndex];
                var go = Object.Instantiate <GameObject>(tp.prefab, tt.transform, false);
                go.transform.localPosition = Vector3.Scale(ti.position, td.size);
                go.transform.localRotation = Quaternion.Euler(0, ti.rotation, 0);
                go.transform.localScale    = new Vector3(ti.widthScale, ti.heightScale, ti.widthScale);
            }
        }

        HashSet <Collider> m_excludes = new HashSet <Collider>();

        foreach (var dv in Object.FindObjectsOfType <DoorView>())
        {
            foreach (var col in dv.GetComponentsInChildren <Collider>())
            {
                m_excludes.Add(col);
            }
        }


        PxMeshDictionary     meshes = new PxMeshDictionary();
        List <PxSceneObject> objs   = new System.Collections.Generic.List <PxSceneObject>();

        foreach (var box in Object.FindObjectsOfType <BoxCollider>())
        {
            if (!m_excludes.Contains(box))
            {
                objs.Add(new PxBoxCollider(box));
            }
        }

        foreach (var capsule in Object.FindObjectsOfType <CapsuleCollider>())
        {
            if (!m_excludes.Contains(capsule))
            {
                objs.Add(new PxCapsuleCollider(capsule));
            }
        }

        foreach (var mesh in Object.FindObjectsOfType <MeshCollider>())
        {
            if (!mesh.convex && mesh.sharedMesh != null)
            {
                if (!m_excludes.Contains(mesh))
                {
                    objs.Add(new PxMeshCollider(mesh, meshes));
                }
            }
        }

        foreach (var terrain in Object.FindObjectsOfType <TerrainCollider>())
        {
            if (terrain.terrainData != null)
            {
                if (!m_excludes.Contains(terrain))
                {
                    objs.Add(new PxTerrainCollider(terrain));
                }
            }
        }

        foreach (var tt in terrainTrees)
        {
            Object.DestroyImmediate(tt);
        }
        terrainTrees.Clear();

        using (var file = new FileStream(path, FileMode.Create)) {
            var bw = new BinaryWriter(file);
            bw.Write(new byte[] { (byte)'P', (byte)'X', (byte)'S', 0 });
            var meshArray = meshes.toArray();
            bw.Write(meshArray.Length);
            for (int i = 0; i < meshArray.Length; ++i)
            {
                meshArray[i].save(bw);
            }
            bw.Write(objs.Count);
            for (int i = 0; i < objs.Count; ++i)
            {
                objs[i].save(bw);
            }
        }

        EditorUtility.DisplayDialog("Export PhysXScene", "Success", "Ok");

        //var root = new GameObject("PhysXScene");

        //foreach (var mesh in meshes.toArray()) {
        //    mesh.dump(root.transform);
        //}

        //foreach (var obj in objs) {
        //    obj.dump(root.transform);
        //}
    }
 public PxMeshCollider(MeshCollider source, PxMeshDictionary meshDictionary)
 {
     _setPositionAndRotation(source.transform);
     scale = source.transform.lossyScale;
     mesh  = meshDictionary.buildMesh(source.sharedMesh);
 }