Example #1
0
        private void FailGetGeometryBufferRequest(LoadCubeRequest loadRequest, string modelPath)
        {
            CheckIfBackgroundThread();
            loadRequest.Failures++;
            lock (_eboCache)
            {
                // Remove the 'in progress' marker from the cache
                _eboCache.Remove(modelPath);
            }

            if (RETRY_LIMIT > loadRequest.Failures)
            {
                Debug.LogError("Retry limit hit for: " + modelPath);
                Debug.LogError("Cube load failed for " + loadRequest);

                // Let another depenent cube try
                lock (_dependentCubes)
                {
                    LinkedList <LoadCubeRequest> dependentRequests;
                    if (_dependentCubes.TryGetValue(modelPath, out dependentRequests))
                    {
                        var request = dependentRequests.Last.Value;
                        dependentRequests.RemoveLast();
                        _loadGeometryBufferQueue.ConcurrentEnqueue(request).Wait();
                    }
                }
            }
            else
            {
                // Queue for retry
                _loadGeometryBufferQueue.ConcurrentEnqueue(loadRequest).Wait();
            }
        }
 private void CancelRequest()
 {
     if (_loadCubeRequest != null)
     {
         _loadCubeRequest.Cancelled = true;
         _loadCubeRequest           = null;
     }
 }
        private IEnumerator RequestCubeLoad()
        {
            CancelRequest();
            _loadCubeRequest = new LoadCubeRequest(_x, _y, _z, _lodIndex, _pyriteQuery, createdObject =>
            {
                DestroyChildren();
                _cubes.Add(createdObject);
                StartCoroutine(StopRenderCheck(Camera.main));
            });

            return(_manager.EnqueueLoadCubeRequest(_loadCubeRequest));
        }
Example #4
0
 private IEnumerator BuildCubeRequest(LoadCubeRequest loadRequest)
 {
     Build(
         loadRequest.GeometryBuffer,
         loadRequest.MaterialData,
         loadRequest.X,
         loadRequest.Y,
         loadRequest.Z,
         loadRequest.LodIndex,
         loadRequest.gameObject);
     yield break;
 }
Example #5
0
        void RequestCube(int X, int Y, int Z, int detailLevel, GameObject refObj)
        {
            if (HideModelMesh)
            {
                return;
            }

            //var loadRequest = new LoadCubeRequest(X, Y, Z, detailLevel, pyriteQuery, cubeObj => { refObj = cubeObj; });
            var loadRequest = new LoadCubeRequest(X, Y, Z, detailLevel, refObj);

            StartCoroutine(EnqueueLoadCubeRequest(loadRequest));
        }
Example #6
0
        private IEnumerator AddDependentRequest(LoadCubeRequest dependentRequest, string dependencyKey)
        {
            // Model is in the process of being constructed. Add request to dependency list
            while (!Monitor.TryEnter(_dependentCubes))
            {
                yield return(null);
            }
            LinkedList <LoadCubeRequest> dependentRequests;

            if (!_dependentCubes.TryGetValue(dependencyKey, out dependentRequests))
            {
                dependentRequests = new LinkedList <LoadCubeRequest>();
                _dependentCubes.Add(dependencyKey, dependentRequests);
            }
            dependentRequests.AddLast(dependentRequest);
            Monitor.Exit(_dependentCubes);
        }
        // Determine the next appropriate queue for the request
        private void MoveRequestForward(LoadCubeRequest loadRequest)
        {
#if !UNITY_WSA
            var onMainThread = _mainThread.Equals(Thread.CurrentThread);
#else
            // Can't check for UIThread yet on Windows Store Apps so assume we are not (trying to StartCoroutine will fail otherwise)
            var onMainThread = false;
#endif

            if (loadRequest.GeometryBuffer == null)
            {
                if (onMainThread)
                {
                    StartCoroutine(_loadGeometryBufferQueue.ConcurrentEnqueue(loadRequest));
                }
                else
                {
                    _loadGeometryBufferQueue.ConcurrentEnqueue(loadRequest).Wait();
                }
            }
            else if (loadRequest.MaterialData == null)
            {
                if (onMainThread)
                {
                    StartCoroutine(_loadMaterialQueue.ConcurrentEnqueue(loadRequest));
                }
                else
                {
                    _loadMaterialQueue.ConcurrentEnqueue(loadRequest).Wait();
                }
            }
            else
            {
                if (onMainThread)
                {
                    StartCoroutine(_buildCubeRequests.ConcurrentEnqueue(loadRequest));
                }
                else
                {
                    _buildCubeRequests.ConcurrentEnqueue(loadRequest).Wait();
                }
            }
        }
Example #8
0
        private void MoveRequestForward(LoadCubeRequest loadRequest)
        {
            #if !UNITY_WSA
            var onMainThread = _mainThread.Equals(Thread.CurrentThread);
#else
            var onMainThread = false;
#endif
            if (loadRequest.GeometryBuffer == null)
            {
                if (onMainThread)
                {
                    StartCoroutine(_loadGeometryBufferQueue.ConcurrentEnqueue(loadRequest));
                }
                else
                {
                    _loadGeometryBufferQueue.ConcurrentEnqueue(loadRequest).Wait();
                }
            }
            else if (loadRequest.MaterialData == null)
            {
                if (onMainThread)
                {
                    StartCoroutine(_loadMaterialQueue.ConcurrentEnqueue(loadRequest));
                }
                else
                {
                    _loadMaterialQueue.ConcurrentEnqueue(loadRequest).Wait();
                }
            }
            else
            {
                if (onMainThread)
                {
                    StartCoroutine(_buildCubeRequests.ConcurrentEnqueue(loadRequest));
                }
                else
                {
                    _buildCubeRequests.ConcurrentEnqueue(loadRequest).Wait();
                }
            }
        }
Example #9
0
        private IEnumerator GetModelForRequest(LoadCubeRequest loadRequest)
        {
            //var modelPath = loadRequest.Query.GetModelPath(loadRequest.LodIndex, loadRequest.X, loadRequest.Y, loadRequest.Z);
            var modelPath = pyriteQuery.GetModelPath(loadRequest.LodIndex, loadRequest.X, loadRequest.Y, loadRequest.Z);

            while (!Monitor.TryEnter(_eboCache))
            {
                yield return(null);
            }
            // If the geometry data is being loaded or this is the first request to load it add the request the dependency list
            if (!_eboCache.ContainsKey(modelPath) || _eboCache[modelPath] == null)
            {
                yield return(StartCoroutine(AddDependentRequest(loadRequest, modelPath)));

                if (!_eboCache.ContainsKey(modelPath))
                {
                    // Model data was not present in cache nor has any request started constructing it
                    //EboCacheMisses++;

                    _eboCache[modelPath] = null;
                    if (UseWwwForEbo)
                    {
                        var cachePath = CacheWebRequest.GetCacheFilePath(modelPath);
                        WWW modelWww;
                        if (CacheWebRequest.IsItemInCache(cachePath))
                        {
                            //FileCacheHits++;
                            modelWww = new WWW("file:///" + cachePath);
                            yield return(modelWww);
                        }
                        else
                        {
                            //FileCacheMisses++;
                            modelWww = new WWW(modelPath);
                            yield return(modelWww);

                            CacheWebRequest.AddToCache(cachePath, modelWww.bytes);
                        }

                        GeometryBuffer buffer =
                            new GeometryBuffer(_geometryBufferAltitudeTransform, true)
                        {
                            Buffer = modelWww.bytes
                        };
                        buffer.Process();
                        _eboCache[modelPath] = buffer;
                        yield return(StartCoroutine(SucceedGetGeometryBufferRequest(modelPath, buffer)));
                    }
                    else
                    {
                        CacheWebRequest.GetBytes(modelPath, modelResponse =>
                        {
                            lock (_eboCache)
                            {
                                if (modelResponse.Status == CacheWebRequest.CacheWebResponseStatus.Error)
                                {
                                    Debug.LogError("Error getting model [" + modelPath + "] " +
                                                   modelResponse.ErrorMessage);
                                    FailGetGeometryBufferRequest(loadRequest, modelPath);
                                }
                                else if (modelResponse.Status == CacheWebRequest.CacheWebResponseStatus.Cancelled)
                                {
                                    _eboCache.Remove(modelPath);
                                }
                                else
                                {
                                    if (modelResponse.IsCacheHit)
                                    {
                                        //FileCacheHits++;
                                    }
                                    else
                                    {
                                        //FileCacheMisses++;
                                    }

                                    GeometryBuffer buffer =
                                        new GeometryBuffer(_geometryBufferAltitudeTransform, true)
                                    {
                                        Buffer = modelResponse.Content
                                    };
                                    buffer.Process();
                                    _eboCache[modelPath] = buffer;
                                    SucceedGetGeometryBufferRequest(modelPath, buffer).Wait();
                                }
                            }
                        }, DependentRequestsExistBlocking);
                    }
                }
            }
            else // The model data was in the cache
            {
                // Model was constructed move request to next step
                //EboCacheHits++;
                loadRequest.GeometryBuffer = _eboCache[modelPath];
                MoveRequestForward(loadRequest);
            }
            Monitor.Exit(_eboCache);
        }
Example #10
0
        private IEnumerator GetMaterialForRequest(LoadCubeRequest loadRequest)
        {
            //var pyriteLevel = loadRequest.Query.DetailLevels[loadRequest.LodIndex];
            //var textureCoordinates = pyriteLevel.TextureCoordinatesForCube(loadRequest.X, loadRequest.Y);
            //var texturePath = loadRequest.Query.GetTexturePath(loadRequest.LodIndex, (int)textureCoordinates.x, (int)textureCoordinates.y);

            var pyriteLevel        = pyriteQuery.DetailLevels[loadRequest.LodIndex];
            var textureCoordinates = pyriteLevel.TextureCoordinatesForCube(loadRequest.X, loadRequest.Y);
            var texturePath        = pyriteQuery.GetTexturePath(loadRequest.LodIndex, (int)textureCoordinates.x, (int)textureCoordinates.y);

            while (!Monitor.TryEnter(MaterialDataCache))
            {
                yield return(null);
            }
            // If the material data is not in the cache or in the middle of being constructed add this request as a dependency
            if (!MaterialDataCache.ContainsKey(texturePath) || MaterialDataCache[texturePath] == null)
            {
                // Add this request to list of requests that is waiting for the data
                yield return(StartCoroutine(AddDependentRequest(loadRequest, texturePath)));

                // Check if this is the first request for material (or it isn't in the cache)
                if (!MaterialDataCache.ContainsKey(texturePath))
                {
                    if (UseWwwForTextures)
                    {
                        // Material data was not in cache nor being constructed
                        // Set to null to signal to other tasks that the key is in the process
                        // of being filled
                        MaterialDataCache[texturePath] = null;
                        var materialData = CubeBuilderHelpers.GetDefaultMaterialData(
                            (int)textureCoordinates.x,
                            (int)textureCoordinates.y,
                            loadRequest.LodIndex,
                            texturePath);
                        var cachePath = CacheWebRequest.GetCacheFilePath(texturePath);
                        if (!CacheFill)
                        {
                            WWW textureWww; // = new WWW(texturePath);
                            if (CacheWebRequest.IsItemInCache(cachePath))
                            {
                                textureWww = new WWW("file:///" + cachePath);
                                yield return(textureWww);
                            }
                            else
                            {
                                textureWww = new WWW(texturePath);
                                yield return(textureWww);

                                CacheWebRequest.AddToCache(cachePath, textureWww.bytes);
                            }
                            materialData.DiffuseTex      = textureWww.texture;
                            materialData.DiffuseTex.name = materialData.Name;
                        }
                        MaterialDataCache[texturePath] = materialData;
                        MaterialDataCache.AddRef(texturePath);
                        // Move forward dependent requests that wanted this material data
                        yield return(StartCoroutine(SucceedGetMaterialDataRequests(texturePath, materialData)));
                    }
                    else
                    {
                        // Material data was not in cache nor being constructed
                        // Set to null to signal to other tasks that the key is in the process
                        // of being filled
                        MaterialDataCache[texturePath] = null;
                        var materialData = CubeBuilderHelpers.GetDefaultMaterialData(
                            (int)textureCoordinates.x,
                            (int)textureCoordinates.y,
                            loadRequest.LodIndex,
                            texturePath);
                        _partiallyConstructedMaterialDatas[texturePath] = materialData;

                        CacheWebRequest.GetBytes(texturePath, textureResponse =>
                        {
                            CheckIfBackgroundThread();
                            if (textureResponse.Status == CacheWebRequest.CacheWebResponseStatus.Error)
                            {
                                Debug.LogError("Error getting texture [" + texturePath + "] " + textureResponse.ErrorMessage);
                                FailGetMaterialDataRequest(loadRequest, texturePath);
                            }
                            else if (textureResponse.Status == CacheWebRequest.CacheWebResponseStatus.Cancelled)
                            {
                                lock (MaterialDataCache)
                                {
                                    MaterialDataCache.Remove(texturePath);
                                }
                            }
                            else
                            {
                                if (textureResponse.IsCacheHit)
                                {
                                    //FileCacheHits++;
                                }
                                else
                                {
                                    //FileCacheMisses++;
                                }
                                _texturesReadyForMaterialDataConstruction.ConcurrentEnqueue(
                                    new KeyValuePair <string, byte[]>(texturePath, textureResponse.Content)).Wait();
                            }
                        }, DependentRequestsExistBlocking);
                    }
                }
            }
            else // The material was in the cache
            {
                // Material data ready get it and move on
                //MaterialCacheHits++;
                loadRequest.MaterialData = MaterialDataCache[texturePath];
                MaterialDataCache.AddRef(texturePath);
                MoveRequestForward(loadRequest);
            }
            Monitor.Exit(MaterialDataCache);
        }
Example #11
0
 public IEnumerator EnqueueLoadCubeRequest(LoadCubeRequest loadRequest)
 {
     yield return(StartCoroutine(_loadMaterialQueue.ConcurrentEnqueue(loadRequest)));
 }
        protected virtual IEnumerator Load()
        {
            _pyriteQuery = new PyriteQuery(this, SetName, ModelVersion, PyriteServer, UpgradeFactor, UpgradeConstant,
                                           DowngradeFactor, DowngradeConstant);
            yield return(StartCoroutine(_pyriteQuery.LoadAll(FilterDetailLevels ? DetailLevelsToFilter : null)));

            var initialDetailLevelIndex = DetailLevel - 1;

            if (UseCameraDetection)
            {
                initialDetailLevelIndex = _pyriteQuery.DetailLevels.Length - 1;
            }

            _pyriteLevel = _pyriteQuery.DetailLevels[initialDetailLevelIndex];

            var allOctCubes = _pyriteQuery.DetailLevels[initialDetailLevelIndex].Octree.AllItems();

            foreach (var octCube in allOctCubes)
            {
                var pCube   = CreateCubeFromCubeBounds(octCube);
                var x       = pCube.X;
                var y       = pCube.Y;
                var z       = pCube.Z;
                var cubePos = _pyriteLevel.GetWorldCoordinatesForCube(pCube);
                _geometryBufferAltitudeTransform = 0 - _pyriteLevel.ModelBoundsMin.z;

                if (UseCameraDetection)
                {
                    var detectionCube = ObjectPooler.Current.GetPooledObject(PlaceHolderCube);
                    detectionCube.transform.position = new Vector3(-cubePos.x,
                                                                   cubePos.z + _geometryBufferAltitudeTransform, -cubePos.y);
                    detectionCube.transform.rotation = Quaternion.identity;
                    var meshRenderer = detectionCube.GetComponent <MeshRenderer>();
                    meshRenderer.enabled = true;
                    detectionCube.GetComponent <IsRendered>()
                    .SetCubePosition(x, y, z, initialDetailLevelIndex, _pyriteQuery, this);

                    detectionCube.transform.localScale = new Vector3(
                        _pyriteLevel.WorldCubeScale.x,
                        _pyriteLevel.WorldCubeScale.z,
                        _pyriteLevel.WorldCubeScale.y);

                    detectionCube.SetActive(true);
                }
                else
                {
                    var loadRequest = new LoadCubeRequest(x, y, z, initialDetailLevelIndex, _pyriteQuery, null);
                    yield return(StartCoroutine(EnqueueLoadCubeRequest(loadRequest)));
                }
            }

            if (CameraRig != null)
            {
                // Hardcodes the coordinate inversions which are parameterized on the geometry buffer

                var min = new Vector3(
                    -_pyriteLevel.ModelBoundsMin.x,
                    _pyriteLevel.ModelBoundsMin.z + _geometryBufferAltitudeTransform,
                    -_pyriteLevel.ModelBoundsMin.y);
                var max = new Vector3(
                    -_pyriteLevel.ModelBoundsMax.x,
                    _pyriteLevel.ModelBoundsMax.z + _geometryBufferAltitudeTransform,
                    -_pyriteLevel.ModelBoundsMax.y);

                //Kainiemi: Some mechanism needed to inform InputManager about the transform change
                var inputManager = CameraRig.GetComponent <PyriteDemoClient.InputManager>();
                if (inputManager != null)
                {
                    // Give input manager position limits based on model bounds
                    var highestLod = _pyriteQuery.DetailLevels.First();
                    var lowestLod  = _pyriteQuery.DetailLevels.Last();
                    inputManager.SetInputLimits(
                        new Vector3(highestLod.ModelBoundsMin.x + lowestLod.WorldCubeScale.x / 2,
                                    highestLod.ModelBoundsMin.z + _geometryBufferAltitudeTransform +
                                    lowestLod.WorldCubeScale.z / 3,
                                    highestLod.ModelBoundsMin.y + lowestLod.WorldCubeScale.y / 2),
                        new Vector3(highestLod.ModelBoundsMax.x - lowestLod.WorldCubeScale.x / 2,
                                    highestLod.ModelBoundsMax.z + _geometryBufferAltitudeTransform +
                                    (lowestLod.WorldCubeScale.z * 1.5f),
                                    highestLod.ModelBoundsMax.y - lowestLod.WorldCubeScale.y / 2));

                    if (AutomateCameraPositionOnLoad)
                    {
                        var newCameraPosition = min + (max - min) / 1.5f;
                        newCameraPosition           += new Vector3(0, (max - min).y * 2f, 0);
                        CameraRig.transform.position = newCameraPosition;
                        inputManager.NotifyOnTransformChange(CameraRig.transform.position);
                    }
                    else
                    {
                        inputManager.NotifyReadyForControl();
                    }
                }
            }
        }
 // Used to create a and populate a game object for this request
 private IEnumerator BuildCubeRequest(LoadCubeRequest loadRequest)
 {
     Build(loadRequest.GeometryBuffer, loadRequest.MaterialData, loadRequest.X, loadRequest.Y, loadRequest.Z,
           loadRequest.Query.DetailLevels[loadRequest.LodIndex].Value, loadRequest.RegisterCreatedObjects);
     yield break;
 }
        protected override IEnumerator Load()
        {
            var pyriteQuery = new PyriteQuery(this, SetName, ModelVersion, PyriteServer);

            if (TargetGameObject != null)
            {
                var transformedPosition = new Vector3(
                    -TargetGameObject.transform.position.x,
                    -TargetGameObject.transform.position.z,
                    TargetGameObject.transform.position.y - 600
                    );

                yield return(StartCoroutine(pyriteQuery.Load3X3(Reference, transformedPosition)));
            }
            else
            {
                yield return(StartCoroutine(pyriteQuery.Load3X3(Reference, QueryPosition)));
            }

            var xmin = pyriteQuery.DetailLevels[0].WorldBoundsMax.x;
            var ymin = pyriteQuery.DetailLevels[0].WorldBoundsMax.y;
            var zmin = pyriteQuery.DetailLevels[0].WorldBoundsMax.z;
            var xmax = pyriteQuery.DetailLevels[0].WorldBoundsMin.x;
            var ymax = pyriteQuery.DetailLevels[0].WorldBoundsMin.y;
            var zmax = pyriteQuery.DetailLevels[0].WorldBoundsMin.z;

            var cubesToSkip = new Dictionary <int, HashSet <PyriteCube> >();

            foreach (var pyriteLevel in pyriteQuery.DetailLevels)
            {
                xmin = pyriteLevel.WorldBoundsMax.x;
                ymin = pyriteLevel.WorldBoundsMax.y;
                zmin = pyriteLevel.WorldBoundsMax.z;
                xmax = pyriteLevel.WorldBoundsMin.x;
                ymax = pyriteLevel.WorldBoundsMin.y;
                zmax = pyriteLevel.WorldBoundsMin.z;
                cubesToSkip[pyriteLevel.Value + 1] = new HashSet <PyriteCube>();
                if (!cubesToSkip.ContainsKey(pyriteLevel.Value))
                {
                    cubesToSkip[pyriteLevel.Value] = new HashSet <PyriteCube>();
                }

                for (var i = 0; i < pyriteLevel.Cubes.Length; i++)
                {
                    var x          = pyriteLevel.Cubes[i].X;
                    var y          = pyriteLevel.Cubes[i].Y;
                    var z          = pyriteLevel.Cubes[i].Z;
                    var cubeFactor = pyriteQuery.GetPreviousCubeFactor(pyriteLevel.Value - 1);
                    cubesToSkip[pyriteLevel.Value + 1].Add(new PyriteCube
                    {
                        X = x / (int)cubeFactor.x,
                        Y = y / (int)cubeFactor.y,
                        Z = z / (int)cubeFactor.z
                    });
                    if (cubesToSkip[pyriteLevel.Value].Contains(new PyriteCube {
                        X = x, Y = y, Z = z
                    }))
                    {
                        if (SkipLowerDetailedCubes)
                        {
                            continue;
                        }
                    }
                    var cubePos = pyriteLevel.GetWorldCoordinatesForCube(pyriteLevel.Cubes[i]);
                    xmin = Math.Min(cubePos.x, xmin);
                    ymin = Math.Min(cubePos.y, ymin);
                    zmin = Math.Min(cubePos.z, zmin);

                    xmax = Math.Max(cubePos.x, xmax);
                    ymax = Math.Max(cubePos.y, ymax);
                    zmax = Math.Max(cubePos.z, zmax);
                    var loadRequest = new LoadCubeRequest(x, y, z, pyriteLevel.Value - 1, pyriteQuery, null);
                    yield return(StartCoroutine(EnqueueLoadCubeRequest(loadRequest)));
                }
            }

            if (CameraRig != null)
            {
                // Hardcoding some values for now
                var min = new Vector3(xmin, ymin, zmin);
                var max = new Vector3(xmax, ymax, zmax);
                var newCameraPosition = min + (max - min) / 2.0f;
                newCameraPosition           += new Vector3(0, 0, (max - min).z * 1.4f);
                CameraRig.transform.position = newCameraPosition;

                CameraRig.transform.rotation = Quaternion.Euler(0, 180, 0);
            }
        }