示例#1
0
        // When we sort the sketches, we sort them into buckets while retaining order within those
        // buckets. We bucket the sketches using the gltf triangle count, but how we bucket depends on
        // whether we are sorting the liked sketches or the curated sketches.
        // Liked sketches get split into normal, complex (requires a warning), and impossible.
        // Curated sketches get bucketed by the nearest 100,000 triangles.
        private static int CompareSketchesByTriangleCountAndDownloadIndex(PolySketch a, PolySketch b)
        {
            int compareResult = CloudSketchComplexityBucket(a).CompareTo(CloudSketchComplexityBucket(b));

            // If both sketches are in the same grouping, sort them relative to download index.
            if (compareResult == 0)
            {
                return(a.m_DownloadIndex.CompareTo(b.m_DownloadIndex));
            }

            return(compareResult);
        }
示例#2
0
        public bool GetSketchIcon(int iSketchIndex, out Texture2D icon, out string[] authors,
                                  out string description)
        {
            description = null;
            if (iSketchIndex >= m_Sketches.Count)
            {
                icon    = null;
                authors = null;
                return(false);
            }
            PolySketch sketch = m_Sketches[iSketchIndex];

            icon    = sketch.Icon;
            authors = sketch.Authors;
            return(icon != null);
        }
示例#3
0
 // Read the icon textures for all sketches in m_RequestedIcons
 private IEnumerator TextureLoaderCoroutine()
 {
     while (m_RequestedIcons.Count > 0)
     {
         foreach (int i in m_RequestedIcons)
         {
             PolySketch sketch = m_Sketches[i];
             string     path   = sketch.PolySceneFileInfo.IconPath;
             if (sketch.PolySceneFileInfo.IconDownloaded)
             {
                 byte[]    data = File.ReadAllBytes(path);
                 Texture2D t    = new Texture2D(2, 2);
                 t.LoadImage(data);
                 sketch.Icon = t;
             }
             yield return(null);
         }
         m_RequestedIcons.RemoveAll(i => m_Sketches[i].Icon != null);
     }
 }
示例#4
0
 // Buckets the sketches into buckets 100000 tris in size.
 private static int CloudSketchComplexityBucket(PolySketch s)
 {
     return(s.PolySceneFileInfo.GltfTriangleCount / 100000);
 }
示例#5
0
        // Fetch asset metadata from server and populate m_Sketches
        private IEnumerator PopulateSketchesCoroutine()
        {
            // Replacement data structures that will be populated with incoming data.  These
            // temporary structures will be copied to the "live" structures in chunks, so
            // beware of modifications that may reference incomplete data.
            List <PolySketch> sketches = new List <PolySketch>();
            Dictionary <string, PolySketch> assetIds = new Dictionary <string, PolySketch>();

            bool fromEmpty       = m_AssetIds.Count == 0;
            int  loadSketchCount = 0;

            AssetLister lister             = null;
            List <PolySceneFileInfo> infos = new List <PolySceneFileInfo>();

            // If we don't have a connection to Poly and we're querying the Showcase, use
            // the json metadatas stored in resources, instead of trying to get them from Poly.
            if (VrAssetService.m_Instance.NoConnection && m_Type == SketchSetType.Curated)
            {
                TextAsset[] textAssets =
                    Resources.LoadAll <TextAsset>(SketchCatalog.kDefaultShowcaseSketchesFolder);
                for (int i = 0; i < textAssets.Length; ++i)
                {
                    JObject jo = JObject.Parse(textAssets[i].text);
                    infos.Add(new PolySceneFileInfo(jo));
                }
            }
            else
            {
                lister = m_AssetService.ListAssets(Type);
            }

            bool changed      = false;
            int  pagesFetched = 0;

            while (lister == null || lister.HasMore || assetIds.Count == 0)
            {
                if (sketches.Count >= 180)
                {
                    break; // Don't allow the sketchbook to become too big.
                }

                // lister will be null if we can't connect to Poly and we've pre-populated infos
                // with data from Resources.
                if (lister != null)
                {
                    using (var cr = lister.NextPage(infos))
                    {
                        while (true)
                        {
                            try
                            {
                                if (!cr.MoveNext())
                                {
                                    break;
                                }
                            }
                            catch (VrAssetServiceException e)
                            {
                                ControllerConsoleScript.m_Instance.AddNewLine(e.UserFriendly);
                                Debug.LogException(e);
                                yield break;
                            }
                            yield return(cr.Current);
                        }
                    }
                }
                if (infos.Count == 0)
                {
                    break;
                }
                if (m_CacheDir == null)
                {
                    yield break;
                }
                // Only cull the curated sketches.  If a user likes a sketch that's very high poly count,
                // there's no feedback to tell them why it didn't show up in their list.  b/123649719
                if (m_Type == SketchSetType.Curated)
                {
                    infos = infos.Where(x => x.GltfTriangleCount < m_MaximumSceneTriangles).ToList();
                }
                if (m_Type == SketchSetType.Curated && !assetIds.Keys.Contains(kIntroSketchAssetId))
                {
                    yield return(VrAssetService.m_Instance.InsertSketchInfo(
                                     kIntroSketchAssetId, kIntroSketchIndex, infos));
                }
                for (int i = 0; i < infos.Count; i++)
                {
                    PolySceneFileInfo info = infos[i];
                    PolySketch        sketch;
                    if (m_AssetIds.TryGetValue(info.AssetId, out sketch))
                    {
                        // We already have this sketch
                    }
                    else
                    {
                        sketch = new PolySketch(info);
                        sketch.m_DownloadIndex = loadSketchCount++;
                        // Set local paths
                        info.TiltPath = Path.Combine(m_CacheDir, String.Format("{0}.tilt", info.AssetId));
                        info.IconPath = Path.Combine(m_CacheDir, String.Format("{0}.png", info.AssetId));
                        changed       = true;
                    }
                    if (assetIds.ContainsKey(info.AssetId))
                    {
                        Debug.LogErrorFormat("VR Asset Service has returned two objects with asset id '{0}'.",
                                             info.AssetId);
                    }
                    else
                    {
                        sketches.Add(sketch);
                        assetIds.Add(info.AssetId, sketch);
                    }
                }
                infos.Clear();

                // Only download the files with every other page, otherwise the sketch pages change too often,
                // Which results in a bad user experience.
                if ((++pagesFetched & 1) == 0 || lister == null || !lister.HasMore)
                {
                    if (Type == SketchSetType.Curated)
                    {
                        sketches.Sort(CompareSketchesByTriangleCountAndDownloadIndex);
                    }

                    // If populating the set from new then show stuff as it comes in.
                    // (We don't have to worry about anything being removed)
                    if (fromEmpty)
                    {
                        yield return(DownloadFilesCoroutine(sketches));

                        RemoveFailedDownloads(sketches);
                        // Copying sketches to m_Sketches before sketches has completed populating is a bit
                        // dangerous, but as long as they're copied and then listeners are notified
                        // immediately afterward with OnChanged(), there data should be stable.
                        m_TotalCount = sketches.Count;
                        m_Sketches   = new List <PolySketch>(sketches);
                        m_AssetIds   = assetIds;
                        m_Ready      = true;
                        OnChanged();
                    }
                }
            }

            if (!fromEmpty)
            {
                // Find anything that was removed
                int removed = m_Sketches.Count(s => !assetIds.ContainsKey(s.PolySceneFileInfo.AssetId));
                if (removed > 0)
                {
                    changed = true;
                }

                // Download new files before we notify our listeners that we've got new stuff for them.
                if (changed)
                {
                    yield return(DownloadFilesCoroutine(sketches));

                    RemoveFailedDownloads(sketches);
                }

                // DeleteOldSketchesCoroutine relies on m_AssetIds being up to date, so set these before
                // we try to cull the herd.
                m_AssetIds = assetIds;
                if (changed)
                {
                    yield return(DeleteOldSketchesCoroutine());
                }

                // Set new data live
                m_TotalCount = sketches.Count;
                m_Sketches   = new List <PolySketch>(sketches);
                m_Ready      = true;
                if (changed)
                {
                    OnChanged();
                }
            }
            else
            {
                // On first run populate, take the time to clean out any cobwebs.
                // Note that this is particularly important for the curated sketches, which do not have
                // a periodic refresh, meaning old sketches will never been deleted in the other path.
                yield return(DeleteOldSketchesCoroutine());

                OnChanged();
            }
        }