public IEnumerator LoadAll(List <int> detailLevelsToFilter)
        {
            yield return(_manager.StartCoroutine(LoadMetadata(detailLevelsToFilter)));

            foreach (var detailLevel in DetailLevels)
            {
                var maxBoundingBoxQuery = string.Format("{0},{1},{2}/{3},{4},{5}",
                                                        detailLevel.WorldBoundsMin.x,
                                                        detailLevel.WorldBoundsMin.y,
                                                        detailLevel.WorldBoundsMin.z,
                                                        detailLevel.WorldBoundsMax.x,
                                                        detailLevel.WorldBoundsMax.y,
                                                        detailLevel.WorldBoundsMax.z
                                                        );

                var cubesUrl = _versionUrl + "query/" + detailLevel.Name + "/" +
                               maxBoundingBoxQuery;

                var loader = WwwExtensions.CreateWWW(cubesUrl, true);
                yield return(loader);

                var parsedContent = JSON.Parse(loader.GetDecompressedText());
                if (!parsedContent[StatusKey].Value.Equals(OkValue))
                {
                    Debug.LogError("Failure getting cube query against: " + cubesUrl);
                    yield break;
                }

                var parsedCubes = parsedContent[ResultKey].AsArray;
                detailLevel.Cubes  = new PyriteCube[parsedCubes.Count];
                detailLevel.Octree = new OcTree <CubeBounds>();
                for (var l = 0; l < detailLevel.Cubes.Length; l++)
                {
                    detailLevel.Cubes[l] = new PyriteCube
                    {
                        X = parsedCubes[l][0].AsInt,
                        Y = parsedCubes[l][1].AsInt,
                        Z = parsedCubes[l][2].AsInt
                    };
                    var min = new Vector3(detailLevel.Cubes[l].X, detailLevel.Cubes[l].Y, detailLevel.Cubes[l].Z);
                    var max = min + Vector3.one;
                    detailLevel.Octree.Add(new CubeBounds {
                        BoundingBox = new BoundingBox(min, max)
                    });
                }

                detailLevel.Octree.UpdateTree();
            }
            Loaded = true;
        }
        public IEnumerator Load3X3(string reference, Vector3 queryPosition)
        {
            yield return(_manager.StartCoroutine(LoadMetadata()));

            var cubesUrl = _versionUrl +
                           string.Format("query/3x3/{0}/{1},{2},{3}", reference, queryPosition.x, queryPosition.y,
                                         queryPosition.z);

            var loader = WwwExtensions.CreateWWW(cubesUrl, true);

            yield return(loader);

            var parsedContent = JSON.Parse(loader.GetDecompressedText());

            if (!parsedContent[StatusKey].Value.Equals(OkValue))
            {
                Debug.LogError("Failure getting cube query against: " + cubesUrl);
                yield break;
            }

            var parsedCubeGroups = parsedContent[ResultKey].AsArray;

            for (var l = 0; l < parsedCubeGroups.Count; l++)
            {
                string lodName          = parsedCubeGroups[l][NameKey];
                var    detailLevelindex = Int32.Parse(lodName.Substring(1)) - 1;
                var    parsedCubes      = parsedCubeGroups[l][CubesKey].AsArray;
                DetailLevels[detailLevelindex].Cubes = new PyriteCube[parsedCubes.Count];
                for (var c = 0; c < parsedCubes.Count; c++)
                {
                    DetailLevels[detailLevelindex].Cubes[c] = new PyriteCube
                    {
                        X = parsedCubes[c][0].AsInt,
                        Y = parsedCubes[c][1].AsInt,
                        Z = parsedCubes[c][2].AsInt
                    };
                }
            }
        }
        private IEnumerator LoadMetadata(List <int> detailLevelsToFilter = null)
        {
            Debug.Log("Metadata query started against: " + _setUrl);
            WWW loader = WwwExtensions.CreateWWW(_setUrl);

            yield return(loader);

            var parsedContent = JSON.Parse(loader.GetDecompressedText());

            if (!parsedContent[StatusKey].Value.Equals(OkValue))
            {
                Debug.LogError("Failure getting set info for " + SetName);
                yield break;
            }
            loader = WwwExtensions.CreateWWW(_versionUrl);
            yield return(loader);

            parsedContent = JSON.Parse(loader.GetDecompressedText());
            if (!parsedContent[StatusKey].Value.Equals(OkValue))
            {
                Debug.LogError("Failure getting set version info for " + SetName + " - " + Version);
                yield break;
            }
            var parsedDetailLevels = parsedContent[ResultKey][DetailLevelsKey].AsArray;
            var sortedDetailLevels = new SortedDictionary <int, PyriteSetVersionDetailLevel>();

            for (var k = 0; k < parsedDetailLevels.Count; k++)
            {
                var detailLevel = new PyriteSetVersionDetailLevel
                {
                    Name  = parsedDetailLevels[k][NameKey],
                    Query = this
                };

                detailLevel.Value = Int32.Parse(detailLevel.Name.Substring(1));

                if (detailLevelsToFilter != null && detailLevelsToFilter.Contains(detailLevel.Value))
                {
                    Debug.Log("Skipping lod " + detailLevel.Value);
                    continue;
                }

                sortedDetailLevels[detailLevel.Value] = detailLevel;
                detailLevel.SetSize = new Vector3(
                    parsedDetailLevels[k][SetSizeKey][XKey].AsFloat,
                    parsedDetailLevels[k][SetSizeKey][YKey].AsFloat,
                    parsedDetailLevels[k][SetSizeKey][ZKey].AsFloat
                    );

                detailLevel.TextureSetSize = new Vector2(
                    parsedDetailLevels[k][TextureSetSizeKey][XKey].AsFloat,
                    parsedDetailLevels[k][TextureSetSizeKey][YKey].AsFloat
                    );

                detailLevel.ModelBoundsMax = new Vector3(
                    parsedDetailLevels[k][ModelBoundsKey][MaxKey][XKey].AsFloat,
                    parsedDetailLevels[k][ModelBoundsKey][MaxKey][YKey].AsFloat,
                    parsedDetailLevels[k][ModelBoundsKey][MaxKey][ZKey].AsFloat
                    );

                detailLevel.ModelBoundsMin = new Vector3(
                    parsedDetailLevels[k][ModelBoundsKey][MinKey][XKey].AsFloat,
                    parsedDetailLevels[k][ModelBoundsKey][MinKey][YKey].AsFloat,
                    parsedDetailLevels[k][ModelBoundsKey][MinKey][ZKey].AsFloat
                    );

                detailLevel.WorldBoundsMax = new Vector3(
                    parsedDetailLevels[k][WorldBoundsKey][MaxKey][XKey].AsFloat,
                    parsedDetailLevels[k][WorldBoundsKey][MaxKey][YKey].AsFloat,
                    parsedDetailLevels[k][WorldBoundsKey][MaxKey][ZKey].AsFloat
                    );

                detailLevel.WorldBoundsMin = new Vector3(
                    parsedDetailLevels[k][WorldBoundsKey][MinKey][XKey].AsFloat,
                    parsedDetailLevels[k][WorldBoundsKey][MinKey][YKey].AsFloat,
                    parsedDetailLevels[k][WorldBoundsKey][MinKey][ZKey].AsFloat
                    );

                detailLevel.WorldCubeScale = new Vector3(
                    parsedDetailLevels[k][WorldCubeScaleKey][XKey].AsFloat,
                    parsedDetailLevels[k][WorldCubeScaleKey][YKey].AsFloat,
                    parsedDetailLevels[k][WorldCubeScaleKey][ZKey].AsFloat);

                detailLevel.UpgradeDistance = detailLevel.WorldCubeScale.magnitude * _upgradeFactor + _upgradeConstant;

                detailLevel.DowngradeDistance = detailLevel.WorldCubeScale.magnitude * _downgradeFactor +
                                                _downgradeConstant;

                detailLevel.WorldBoundsSize =
                    detailLevel.WorldBoundsMax -
                    detailLevel.WorldBoundsMin;
            }

            DetailLevels = sortedDetailLevels.Values.ToArray();

            for (var i = DetailLevels.Length - 1; i > 0; i--)
            {
                if (DetailLevels[i].Value != DetailLevels[i - 1].Value + 1)
                {
                    DetailLevels[i].UpgradeDistance   *= 0.5f;
                    DetailLevels[i].DowngradeDistance *= 0.5f;
                }
            }
            Debug.Log("Metadata query completed.");
        }