Esempio n. 1
0
        RefCellObjInfo[] GetRefCellObjInfos(CELLRecord cell)
        {
            var refCellObjInfos = new RefCellObjInfo[cell.RefObjs.Length];

            for (var i = 0; i < cell.RefObjs.Length; i++)
            {
                var refObjInfo = new RefCellObjInfo
                {
                    RefObj = cell.RefObjs[i]
                };
                // Get the record the RefObjDataGroup references.
                var refObj = (CELLRecord.RefObj)refObjInfo.RefObj;
                _data.objectsByIDString.TryGetValue(refObj.Name, out refObjInfo.ReferencedRecord);
                if (refObjInfo.ReferencedRecord != null)
                {
                    var modelFileName = RecordUtils.GetModelFileName(refObjInfo.ReferencedRecord);
                    // If the model file name is valid, store the model file path.
                    if (!string.IsNullOrEmpty(modelFileName))
                    {
                        refObjInfo.ModelFilePath = modelFileName;
                    }
                }
                refCellObjInfos[i] = refObjInfo;
            }
            return(refCellObjInfos);
        }
Esempio n. 2
0
        private RefCellObjInfo[] GetRefCellObjInfos(CELLRecord CELL)
        {
            RefCellObjInfo[] refCellObjInfos = new RefCellObjInfo[CELL.refObjDataGroups.Count];
            for (int i = 0; i < CELL.refObjDataGroups.Count; i++)
            {
                var refObjInfo = new RefCellObjInfo();
                refObjInfo.refObjDataGroup = CELL.refObjDataGroups[i];

                // Get the record the RefObjDataGroup references.
                dataReader.MorrowindESMFile.objectsByIDString.TryGetValue(refObjInfo.refObjDataGroup.NAME.value, out refObjInfo.referencedRecord);

                if (refObjInfo.referencedRecord != null)
                {
                    var modelFileName = ESM.RecordUtils.GetModelFileName(refObjInfo.referencedRecord);

                    // If the model file name is valid, store the model file path.
                    if (!string.IsNullOrEmpty(modelFileName))
                    {
                        refObjInfo.modelFilePath = "meshes\\" + modelFileName;
                    }
                }

                refCellObjInfos[i] = refObjInfo;
            }

            return(refCellObjInfos);
        }
Esempio n. 3
0
        void ReadGroup(Header header, bool loadAll, StreamSink.DataInfo info)
        {
            if (GroupByLabel == null)
            {
                GroupByLabel = new Dictionary <string, RecordGroup>();
            }
            if (!GroupByLabel.TryGetValue(header.Label, out var group))
            {
                GroupByLabel.Add(header.Label, group = new RecordGroup(_streamSink, FilePath));
            }
            else
            {
                group = new RecordGroup(_streamSink, FilePath)
                {
                    Next = group
                }
            };

            if (_r[0] != null)
            {
                using (_r[0]) CELLRecord.ReadFixed(_r[0], header, group);
            }
            if (_r[1] != null)
            {
                using (_r[1]) LANDRecord.ReadTerrain(_r[1], header, group);
            }
            //if (_r[2] != null) using (_r[2]) DYNARecord.ReadNonfixed(_r[2], header, group);
        }
    }
Esempio n. 4
0
 public InRangeCellInfo(GameObject gameObject, GameObject objectsContainerGameObject, CELLRecord cellRecord, IEnumerator objectsCreationCoroutine)
 {
     this.gameObject = gameObject;
     this.objectsContainerGameObject = objectsContainerGameObject;
     this.cellRecord = cellRecord;
     this.objectsCreationCoroutine = objectsCreationCoroutine;
 }
Esempio n. 5
0
 private void OpenDoor(DoorComponent component)
 {
     if (!component.doorData.leadsToAnotherCell)
     {
         component.Interact();
     }
     else
     {
         // The door leads to another cell, so destroy all currently loaded cells.
         _cellManager.DestroyAllCells();
         // Move the player.
         _playerTransform.position         = component.doorData.doorExitPos;
         _playerTransform.localEulerAngles = new Vector3(0, component.doorData.doorExitOrientation.eulerAngles.y, 0);
         // Load the new cell.
         CELLRecord newCell;
         if (component.doorData.leadsToInteriorCell)
         {
             var cellInfo = _cellManager.StartCreatingInteriorCell(component.doorData.doorExitName);
             _temporalLoadBalancer.WaitForTask(cellInfo.objectsCreationCoroutine);
             newCell = (CELLRecord)cellInfo.cellRecord;
             OnInteriorCell(newCell);
         }
         else
         {
             var cellIndices = _cellManager.GetExteriorCellIndices(component.doorData.doorExitPos);
             newCell = _data.FindExteriorCellRecord(cellIndices);
             _cellManager.UpdateExteriorCells(_playerCameraObj.transform.position, true, CellRadiusOnLoad);
             OnExteriorCell(newCell);
         }
         _currentCell = newCell;
     }
 }
Esempio n. 6
0
        RefCellObjInfo[] GetRefCellObjInfos(CELLRecord cell)
        {
            if (_data.Format != GameFormatId.TES3)
            {
                return(new RefCellObjInfo[0]);
            }
            var refCellObjInfos = new RefCellObjInfo[cell.RefObjs.Count];

            for (var i = 0; i < cell.RefObjs.Count; i++)
            {
                var refObjInfo = new RefCellObjInfo
                {
                    RefObj = cell.RefObjs[i]
                };
                // Get the record the RefObjDataGroup references.
                var refObj = (CELLRecord.RefObj)refObjInfo.RefObj;
                _data._MANYsById.TryGetValue(refObj.EDID.Value, out refObjInfo.ReferencedRecord);
                if (refObjInfo.ReferencedRecord != null)
                {
                    var modelFileName = (refObjInfo.ReferencedRecord is IHaveMODL modl ? modl.MODL.Value : null);
                    // If the model file name is valid, store the model file path.
                    if (!string.IsNullOrEmpty(modelFileName))
                    {
                        refObjInfo.ModelFilePath = "meshes\\" + modelFileName;
                    }
                }
                refCellObjInfos[i] = refObjInfo;
            }
            return(refCellObjInfos);
        }
Esempio n. 7
0
        public InRangeCellInfo StartInstantiatingCell(CELLRecord cell)
        {
            Debug.Assert(cell != null);
            string     cellObjName = null;
            LANDRecord land        = null;

            if (!cell.IsInterior)
            {
                cellObjName = string.Format("cell-{0:00}x{1:00}", cell.GridId.x, cell.GridId.y);
                land        = _data.FindLANDRecord(cell.GridId);
            }
            else
            {
                cellObjName = cell.Name;
            }
            var cellObj = new GameObject(cellObjName)
            {
                tag = "Cell"
            };
            var cellObjectsContainer = new GameObject("objects");

            cellObjectsContainer.transform.parent = cellObj.transform;
            var cellObjectsCreationCoroutine = InstantiateCellObjectsCoroutine(cell, land, cellObj, cellObjectsContainer);

            _loadBalancer.AddTask(cellObjectsCreationCoroutine);
            return(new InRangeCellInfo(cellObj, cellObjectsContainer, cell, cellObjectsCreationCoroutine));
        }
Esempio n. 8
0
        public InRangeCellInfo StartInstantiatingCell(CELLRecord CELL)
        {
            Debug.Assert(CELL != null);

            string     cellObjName = null;
            LANDRecord LAND        = null;

            if (!CELL.isInterior)
            {
                cellObjName = "cell " + CELL.gridCoords.ToString();
                LAND        = dataReader.FindLANDRecord(CELL.gridCoords);
            }
            else
            {
                cellObjName = CELL.NAME.value;
            }

            var cellObj = new GameObject(cellObjName);

            cellObj.tag = "Cell";

            var cellObjectsContainer = new GameObject("objects");

            cellObjectsContainer.transform.parent = cellObj.transform;

            var cellObjectsCreationCoroutine = InstantiateCellObjectsCoroutine(CELL, LAND, cellObj, cellObjectsContainer);

            temporalLoadBalancer.AddTask(cellObjectsCreationCoroutine);

            return(new InRangeCellInfo(cellObj, cellObjectsContainer, CELL, cellObjectsCreationCoroutine));
        }
Esempio n. 9
0
        /// <summary>
        /// Instantiates an object in a cell. Called by InstantiateCellObjectsCoroutine after the object's assets have been pre-loaded.
        /// </summary>
        private void InstantiatePreLoadedCellObject(CELLRecord CELL, GameObject parent, RefCellObjInfo refCellObjInfo)
        {
            if (refCellObjInfo.referencedRecord != null)
            {
                GameObject modelObj = null;

                // If the object has a model, instantiate it.
                if (refCellObjInfo.modelFilePath != null)
                {
                    modelObj = theNIFManager.InstantiateNIF(refCellObjInfo.modelFilePath);
                    PostProcessInstantiatedCellObject(modelObj, refCellObjInfo);

                    modelObj.transform.parent = parent.transform;
                }

                // If the object has a light, instantiate it.
                if (refCellObjInfo.referencedRecord is LIGHRecord)
                {
                    var lightObj = InstantiateLight((LIGHRecord)refCellObjInfo.referencedRecord, CELL.isInterior);

                    // If the object also has a model, parent the model to the light.
                    if (modelObj != null)
                    {
                        // Some NIF files have nodes named "AttachLight". Parent it to the light if it exists.
                        GameObject attachLightObj = GameObjectUtils.FindChildRecursively(modelObj, "AttachLight");

                        if (attachLightObj == null)
                        {
                            //attachLightObj = GameObjectUtils.FindChildWithNameSubstringRecursively(modelObj, "Emitter");
                            attachLightObj = modelObj;
                        }

                        if (attachLightObj != null)
                        {
                            lightObj.transform.position = attachLightObj.transform.position;
                            lightObj.transform.rotation = attachLightObj.transform.rotation;

                            lightObj.transform.parent = attachLightObj.transform;
                        }
                        else // If there is no "AttachLight", center the light in the model's bounds.
                        {
                            lightObj.transform.position = GameObjectUtils.CalcVisualBoundsRecursive(modelObj).center;
                            lightObj.transform.rotation = modelObj.transform.rotation;

                            lightObj.transform.parent = modelObj.transform;
                        }
                    }
                    else // If the light has no associated model, instantiate the light as a standalone object.
                    {
                        PostProcessInstantiatedCellObject(lightObj, refCellObjInfo);
                        lightObj.transform.parent = parent.transform;
                    }
                }
            }

            /*else
             *          {
             *                  Debug.Log("Unknown Object: " + refCellObjInfo.refObjDataGroup.NAME.value);
             *          }*/
        }
Esempio n. 10
0
 private void OnExteriorCell(CELLRecord CELL)
 {
     RenderSettings.ambientLight = _defaultAmbientColor;
     _sunObj.SetActive(true);
     //_waterObj.transform.position = Vector3.zero;
     //_waterObj.SetActive(true);
     //_underwaterEffect.enabled = true;
     //_underwaterEffect.Level = 0.0f;
 }
Esempio n. 11
0
        /// <summary>
        /// Spawns the player outside using the position of the player.
        /// </summary>
        /// <param name="playerPrefab">The player prefab.</param>
        /// <param name="position">The target position of the player.</param>
        public void SpawnPlayerOutside(GameObject playerPrefab, Vector3 position)
        {
            var cellIndices = _cellManager.GetExteriorCellIndices(position);

            _currentCell = _data.FindExteriorCellRecord(cellIndices);
            CreatePlayer(playerPrefab, position, out _playerCameraObj);
            _cellManager.UpdateExteriorCells(_playerCameraObj.transform.position, true, CellRadiusOnLoad);
            OnExteriorCell(_currentCell);
        }
Esempio n. 12
0
        /// <summary>
        /// A coroutine that instantiates the terrain for, and all objects in, a cell.
        /// </summary>
        private IEnumerator InstantiateCellObjectsCoroutine(CELLRecord CELL, LANDRecord LAND, GameObject cellObj, GameObject cellObjectsContainer)
        {
            // Start pre-loading all required textures for the terrain.
            if (LAND != null)
            {
                var landTextureFilePaths = GetLANDTextureFilePaths(LAND);

                if (landTextureFilePaths != null)
                {
                    foreach (var landTextureFilePath in landTextureFilePaths)
                    {
                        textureManager.PreloadTextureFileAsync(landTextureFilePath);
                    }
                }

                yield return(null);
            }

            // Extract information about referenced objects.
            var refCellObjInfos = GetRefCellObjInfos(CELL);

            yield return(null);

            // Start pre-loading all required files for referenced objects. The NIF manager will load the textures as well.
            foreach (var refCellObjInfo in refCellObjInfos)
            {
                if (refCellObjInfo.modelFilePath != null)
                {
                    nifManager.PreloadNifFileAsync(refCellObjInfo.modelFilePath);
                }
            }
            yield return(null);

            // Instantiate terrain.
            if (LAND != null)
            {
                var instantiateLANDTaskEnumerator = InstantiateLANDCoroutine(LAND, cellObj);

                // Run the LAND instantiation coroutine.
                while (instantiateLANDTaskEnumerator.MoveNext())
                {
                    // Yield every time InstantiateLANDCoroutine does to avoid doing too much work in one frame.
                    yield return(null);
                }

                // Yield after InstantiateLANDCoroutine has finished to avoid doing too much work in one frame.
                yield return(null);
            }

            // Instantiate objects.
            foreach (var refCellObjInfo in refCellObjInfos)
            {
                InstantiateCellObject(CELL, cellObjectsContainer, refCellObjInfo);
                yield return(null);
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Spawns the player outside using the cell's grid coordinates.
        /// </summary>
        /// <param name="playerPrefab">The player prefab.</param>
        /// <param name="gridCoords">The grid coordinates.</param>
        /// <param name="position">The target position of the player.</param>
        public void SpawnPlayerOutside(GameObject playerPrefab, Vector2i gridCoords, Vector3 position)
        {
            _currentCell = _data.FindExteriorCellRecord(gridCoords);
            Debug.Assert(_currentCell != null);
            CreatePlayer(playerPrefab, position, out _playerCameraObj);
            var cellInfo = _cellManager.StartCreatingExteriorCell(gridCoords);

            _temporalLoadBalancer.WaitForTask(cellInfo.objectsCreationCoroutine);
            OnExteriorCell(_currentCell);
        }
Esempio n. 14
0
        /// <summary>
        /// Spawns the player inside. Be carefull, the name of the cell is not the same for each languages.
        /// Use it with the correct name.
        /// </summary>
        /// <param name="playerPrefab">The player prefab.</param>
        /// <param name="interiorCellName">The name of the desired cell.</param>
        /// <param name="position">The target position of the player.</param>
        public void SpawnPlayerInside(GameObject playerPrefab, string interiorCellName, Vector3 position)
        {
            _currentCell = _data.FindInteriorCellRecord(interiorCellName);
            Debug.Assert(_currentCell != null);
            CreatePlayer(playerPrefab, position, out _playerCameraObj);
            var cellInfo = _cellManager.StartCreatingInteriorCell(interiorCellName);

            _temporalLoadBalancer.WaitForTask(cellInfo.objectsCreationCoroutine);
            OnInteriorCell(_currentCell);
        }
Esempio n. 15
0
        /// <summary>
        /// Spawns the player outside using the position of the player.
        /// </summary>
        /// <param name="playerPrefab">The player prefab.</param>
        /// <param name="position">The target position of the player.</param>
        public void SpawnPlayerOutside(GameObject playerPrefab, Vector3 position)
        {
            var cellIndices = GetExteriorCellIndices(position);

            _currentCell = dataReader.FindExteriorCellRecord(cellIndices);

            CreatePlayer(playerPrefab, position, out playerCameraObj);

            UpdateExteriorCells(true, cellRadiusOnLoad);
            OnExteriorCell(_currentCell);
        }
Esempio n. 16
0
        /// <summary>
        /// A coroutine that instantiates the terrain for, and all objects in, a cell.
        /// </summary>
        IEnumerator InstantiateCellObjectsCoroutine(CELLRecord cell, LANDRecord land, GameObject cellObj, GameObject cellObjectsContainer)
        {
            cell.Read();
            // Start pre-loading all required textures for the terrain.
            if (land != null)
            {
                land.Read();
                var landTextureFilePaths = GetLANDTextureFilePaths(land);
                if (landTextureFilePaths != null)
                {
                    foreach (var landTextureFilePath in landTextureFilePaths)
                    {
                        _assetPack.PreloadTextureTask(landTextureFilePath);
                    }
                }
                yield return(null);
            }
            // Extract information about referenced objects.
            var refCellObjInfos = GetRefCellObjInfos(cell);

            yield return(null);

            // Start pre-loading all required files for referenced objects. The NIF manager will load the textures as well.
            foreach (var refCellObjInfo in refCellObjInfos)
            {
                if (refCellObjInfo.ModelFilePath != null)
                {
                    _assetPack.PreloadObjectTask(refCellObjInfo.ModelFilePath);
                }
            }
            yield return(null);

            // Instantiate terrain.
            if (land != null)
            {
                var instantiateLANDTaskEnumerator = InstantiateLANDCoroutine(land, cellObj);
                // Run the LAND instantiation coroutine.
                while (instantiateLANDTaskEnumerator.MoveNext())
                {
                    // Yield every time InstantiateLANDCoroutine does to avoid doing too much work in one frame.
                    yield return(null);
                }
                // Yield after InstantiateLANDCoroutine has finished to avoid doing too much work in one frame.
                yield return(null);
            }
            // Instantiate objects.
            foreach (var refCellObjInfo in refCellObjInfos)
            {
                InstantiateCellObject(cell, cellObjectsContainer, refCellObjInfo);
                yield return(null);
            }
        }
Esempio n. 17
0
 /// <summary>
 /// Instantiates an object in a cell. Called by InstantiateCellObjectsCoroutine after the object's assets have been pre-loaded.
 /// </summary>
 void InstantiateCellObject(CELLRecord cell, GameObject parent, RefCellObjInfo refCellObjInfo)
 {
     if (refCellObjInfo.ReferencedRecord != null)
     {
         GameObject modelObj = null;
         // If the object has a model, instantiate it.
         if (refCellObjInfo.ModelFilePath != null)
         {
             modelObj = _asset.CreateObject(refCellObjInfo.ModelFilePath);
             PostProcessInstantiatedCellObject(modelObj, refCellObjInfo);
             modelObj.transform.parent = parent.transform;
         }
         // If the object has a light, instantiate it.
         if (refCellObjInfo.ReferencedRecord is LIGHRecord)
         {
             var lightObj = InstantiateLight((LIGHRecord)refCellObjInfo.ReferencedRecord, cell.IsInterior);
             // If the object also has a model, parent the model to the light.
             if (modelObj != null)
             {
                 // Some SIF files have nodes named "AttachLight". Parent it to the light if it exists.
                 var attachLightObj = GameObjectUtils.FindChildRecursively(modelObj, "AttachLight");
                 if (attachLightObj == null)
                 {
                     //attachLightObj = GameObjectUtils.FindChildWithNameSubstringRecursively(modelObj, "Emitter");
                     attachLightObj = modelObj;
                 }
                 if (attachLightObj != null)
                 {
                     lightObj.transform.position = attachLightObj.transform.position;
                     lightObj.transform.rotation = attachLightObj.transform.rotation;
                     lightObj.transform.parent   = attachLightObj.transform;
                 }
                 else // If there is no "AttachLight", center the light in the model's bounds.
                 {
                     lightObj.transform.position = GameObjectUtils.CalcVisualBoundsRecursive(modelObj).center;
                     lightObj.transform.rotation = modelObj.transform.rotation;
                     lightObj.transform.parent   = modelObj.transform;
                 }
             }
             else // If the light has no associated model, instantiate the light as a standalone object.
             {
                 PostProcessInstantiatedCellObject(lightObj, refCellObjInfo);
                 lightObj.transform.parent = parent.transform;
             }
         }
     }
     else
     {
         Utils.Log("Unknown Object: " + ((CELLRecord.RefObj)refCellObjInfo.RefObj).Name);
     }
 }
Esempio n. 18
0
        /// <summary>
        /// Spawns the player inside using the cell's grid coordinates.
        /// </summary>
        /// <param name="playerPrefab">The player prefab.</param>
        /// <param name="gridCoords">The grid coordinates.</param>
        /// <param name="position">The target position of the player.</param>
        public void SpawnPlayerInside(GameObject playerPrefab, Vector2i gridCoords, Vector3 position)
        {
            _currentCell = dataReader.FindInteriorCellRecord(gridCoords);

            Debug.Assert(_currentCell != null);

            CreatePlayer(playerPrefab, position, out playerCameraObj);

            var cellInfo = CreateInteriorCell(gridCoords);

            temporalLoadBalancer.WaitForTask(cellInfo.creationCoroutine);

            OnInteriorCell(_currentCell);
        }
Esempio n. 19
0
 private void OnInteriorCell(CELLRecord CELL)
 {
     if (CELL.AMBI != null)
     {
         RenderSettings.ambientLight = ColorUtils.B8G8R8ToColor32(CELL.AMBI.ambientColor);
     }
     _sunObj.SetActive(false);
     //_underwaterEffect.enabled = CELL.WHGT != null;
     //if (CELL.WHGT != null)
     //{
     //    var offset = 1.6f; // Interiors cells needs this offset to render at the correct location.
     //    _waterObj.transform.position = new Vector3(0, (CELL.WHGT.value / Convert.meterInMWUnits) - offset, 0);
     //    _waterObj.SetActive(true);
     //    _underwaterEffect.Level = _waterObj.transform.position.y;
     //}
     //else _waterObj.SetActive(false);
 }
Esempio n. 20
0
        public CELLRecord FindInteriorCellRecord(Vector2i gridCoords)
        {
            List <Record> records = MorrowindESMFile.GetRecordsOfType <CELLRecord>();
            CELLRecord    CELL    = null;

            for (int i = 0, l = records.Count; i < l; i++)
            {
                CELL = (CELLRecord)records[i];

                if (CELL.gridCoords.x == gridCoords.x && CELL.gridCoords.y == gridCoords.y)
                {
                    return(CELL);
                }
            }

            return(null);
        }
Esempio n. 21
0
        public CELLRecord FindInteriorCellRecord(string cellName)
        {
            List <Record> records = MorrowindESMFile.GetRecordsOfType <CELLRecord>();
            CELLRecord    CELL    = null;

            for (int i = 0, l = records.Count; i < l; i++)
            {
                CELL = (CELLRecord)records[i];

                if (CELL.NAME.value == cellName)
                {
                    return(CELL);
                }
            }

            return(null);
        }
Esempio n. 22
0
        public InRangeCellInfo StartInstantiatingCell(CELLRecord cell)
        {
            Assert(cell != null);
            var cellObjName = "cell " + cell.GridId.ToString();
            var land        = _dataPack.FindLANDRecord(cell.GridId);
            var cellObj     = new GameObject(cellObjName)
            {
                tag = "Cell"
            };
            var cellObjectsContainer = new GameObject("objects");

            cellObjectsContainer.transform.parent = cellObj.transform;
            var cellObjectsCreationCoroutine = InstantiateCellObjectsCoroutine(cell, land, cellObj, cellObjectsContainer);

            _loadBalancer.AddTask(cellObjectsCreationCoroutine);
            return(new InRangeCellInfo(cellObj, cellObjectsContainer, cell, cellObjectsCreationCoroutine));
        }
Esempio n. 23
0
        private void OpenDoor(DoorComponent component)
        {
            if (!component.doorData.leadsToAnotherCell)
            {
                component.Interact();
            }
            else
            {
                // The door leads to another cell, so destroy all currently loaded cells.
                DestroyAllCells();

                // Move the player.
                playerTransform.position         = component.doorData.doorExitPos;
                playerTransform.localEulerAngles = new Vector3(0, component.doorData.doorExitOrientation.eulerAngles.y, 0);

                // Load the new cell.
                CELLRecord newCell;

                if (component.doorData.leadsToInteriorCell)
                {
                    newCell = dataReader.FindInteriorCellRecord(component.doorData.doorExitName);

                    var cellInfo = InstantiateCell(newCell);
                    temporalLoadBalancer.WaitForTask(cellInfo.creationCoroutine);

                    cellObjects[Vector2i.zero] = cellInfo;

                    OnInteriorCell(newCell);
                }
                else
                {
                    var cellIndices = GetExteriorCellIndices(component.doorData.doorExitPos);
                    newCell = dataReader.FindExteriorCellRecord(cellIndices);

                    UpdateExteriorCells(true, cellRadiusOnLoad);

                    OnExteriorCell(newCell);
                }

                _currentCell = newCell;
            }
        }
Esempio n. 24
0
 RefCellObjInfo[] GetRefCellObjInfos(CELLRecord cell)
 {
     return(new RefCellObjInfo[0]);
     //if (_dataPack.Format != GameFormat.TES3) return new RefCellObjInfo[0];
     //var refCellObjInfos = new RefCellObjInfo[cell.RefObjs.Count];
     //for (var i = 0; i < cell.RefObjs.Count; i++)
     //{
     //    var refObjInfo = new RefCellObjInfo { RefObj = cell.RefObjs[i] };
     //    // Get the record the RefObjDataGroup references.
     //    var refObj = (CELLRecord.RefObj)refObjInfo.RefObj;
     //    _dataPack.MANYsById.TryGetValue(refObj.EDID.Value, out refObjInfo.ReferencedRecord);
     //    if (refObjInfo.ReferencedRecord != null)
     //    {
     //        var modelFileName = refObjInfo.ReferencedRecord is IHaveMODL modl ? modl.MODL.Value : null;
     //        // If the model file name is valid, store the model file path.
     //        if (!string.IsNullOrEmpty(modelFileName))
     //            refObjInfo.ModelFilePath = "meshes/" + modelFileName;
     //    }
     //    refCellObjInfos[i] = refObjInfo;
     //}
     //return refCellObjInfos;
 }
Esempio n. 25
0
        /// <summary>
        /// A coroutine that instantiates the terrain for, and all objects in, a cell.
        /// </summary>
        private IEnumerator InstantiateCellObjectsCoroutine(CELLRecord CELL, LANDRecord LAND, GameObject cellObj, GameObject cellObjectsContainer)
        {
            // Return before doing any work to provide an IEnumerator handle to the coroutine.
            yield return(null);

            // Instantiate terrain.
            if (LAND != null)
            {
                var instantiateLANDTaskEnumerator = InstantiateLANDCoroutine(LAND, cellObj);

                // Run the LAND instantiation coroutine.
                while (instantiateLANDTaskEnumerator.MoveNext())
                {
                    // Yield every time InstantiateLANDCoroutine does to avoid doing too much work in one frame.
                    yield return(null);
                }

                // Yield after InstantiateLANDCoroutine has finished to avoid doing too much work in one frame.
                yield return(null);
            }

            // Extract information about referenced objects. Do this all at once because it's fast.
            RefCellObjInfo[] refCellObjInfos = new RefCellObjInfo[CELL.refObjDataGroups.Count];

            for (int i = 0; i < CELL.refObjDataGroups.Count; i++)
            {
                var refObjInfo = new RefCellObjInfo();
                refObjInfo.refObjDataGroup = CELL.refObjDataGroups[i];

                // Get the record the RefObjDataGroup references.
                dataReader.MorrowindESMFile.objectsByIDString.TryGetValue(refObjInfo.refObjDataGroup.NAME.value, out refObjInfo.referencedRecord);

                if (refObjInfo.referencedRecord != null)
                {
                    var modelFileName = ESM.RecordUtils.GetModelFileName(refObjInfo.referencedRecord);

                    // If the model file name is valid, store the model file path.
                    if ((modelFileName != null) && (modelFileName != ""))
                    {
                        refObjInfo.modelFilePath = "meshes\\" + modelFileName;
                    }
                }

                refCellObjInfos[i] = refObjInfo;
            }

            yield return(null);

            // Start loading all required assets in background threads.
            foreach (var refCellObjInfo in refCellObjInfos)
            {
                if (refCellObjInfo.modelFilePath != null)
                {
                    theNIFManager.PreLoadNIFAsync(refCellObjInfo.modelFilePath);

                    yield return(null);
                }
            }

            yield return(null);

            // Instantiate objects when they are done loading, or if they don't need to load.
            int instantiatedObjectCount = 0;

            while (instantiatedObjectCount < refCellObjInfos.Length)
            {
                foreach (var refCellObjInfo in refCellObjInfos)
                {
                    // Ignore objects that have already been instantiated.
                    if (refCellObjInfo.isInstantiated)
                    {
                        continue;
                    }

                    // If the referenced object has a model and it has just finished pre-loading, instantiate the model.
                    if (refCellObjInfo.modelFilePath != null)
                    {
                        Debug.Assert(!refCellObjInfo.isDonePreLoading);

                        // Update isDonePreloading.
                        refCellObjInfo.isDonePreLoading = theNIFManager.IsDonePreLoading(refCellObjInfo.modelFilePath);

                        // If the model just finished pre-loading, instantiate it.
                        if (refCellObjInfo.isDonePreLoading)
                        {
                            InstantiatePreLoadedCellObject(CELL, cellObjectsContainer, refCellObjInfo);
                            refCellObjInfo.isInstantiated = true;

                            instantiatedObjectCount++;

                            yield return(null);
                        }
                    }
                    else // If the referenced object doesn't have a model, there is no loading to be done, so try to instantiate it.
                    {
                        InstantiatePreLoadedCellObject(CELL, cellObjectsContainer, refCellObjInfo);
                        refCellObjInfo.isInstantiated = true;

                        instantiatedObjectCount++;

                        yield return(null);
                    }
                }

                // Yield after every foreach to prevent spinning if all models are loading.
                yield return(null);
            }
        }
Esempio n. 26
0
        private void UpdateExteriorCells(bool immediate = false, int cellRadiusOverride = -1)
        {
            var cameraCellIndices = GetExteriorCellIndices(playerCameraObj.transform.position);

            _currentCell = dataReader.FindExteriorCellRecord(cameraCellIndices);

            var cellRadius = (cellRadiusOverride >= 0) ? cellRadiusOverride : this.cellRadius;
            var minCellX   = cameraCellIndices.x - cellRadius;
            var maxCellX   = cameraCellIndices.x + cellRadius;
            var minCellY   = cameraCellIndices.y - cellRadius;
            var maxCellY   = cameraCellIndices.y + cellRadius;

            // Destroy out of range cells.
            var outOfRangeCellIndices = new List <Vector2i>();

            foreach (var KVPair in cellObjects)
            {
                if ((KVPair.Key.x < minCellX) || (KVPair.Key.x > maxCellX) || (KVPair.Key.y < minCellY) || (KVPair.Key.y > maxCellY))
                {
                    outOfRangeCellIndices.Add(KVPair.Key);
                }
            }

            foreach (var cellIndices in outOfRangeCellIndices)
            {
                DestroyExteriorCell(cellIndices);
            }

            // Create new cells.
            for (int r = 0; r <= cellRadius; r++)
            {
                for (int x = minCellX; x <= maxCellX; x++)
                {
                    for (int y = minCellY; y <= maxCellY; y++)
                    {
                        var cellIndices = new Vector2i(x, y);

                        var cellXDistance = Mathf.Abs(cameraCellIndices.x - cellIndices.x);
                        var cellYDistance = Mathf.Abs(cameraCellIndices.y - cellIndices.y);
                        var cellDistance  = Mathf.Max(cellXDistance, cellYDistance);

                        if ((cellDistance == r) && !cellObjects.ContainsKey(cellIndices))
                        {
                            var cellInfo = CreateExteriorCell(cellIndices);

                            if ((cellInfo != null) && immediate)
                            {
                                temporalLoadBalancer.WaitForTask(cellInfo.creationCoroutine);
                            }
                        }
                    }
                }
            }

            // Update LODs.
            foreach (var keyValuePair in cellObjects)
            {
                Vector2i        cellIndices = keyValuePair.Key;
                InRangeCellInfo cellInfo    = keyValuePair.Value;

                var cellXDistance = Mathf.Abs(cameraCellIndices.x - cellIndices.x);
                var cellYDistance = Mathf.Abs(cameraCellIndices.y - cellIndices.y);
                var cellDistance  = Mathf.Max(cellXDistance, cellYDistance);

                if (cellDistance <= detailRadius)
                {
                    if (!cellInfo.objectsContainerGameObject.activeSelf)
                    {
                        cellInfo.objectsContainerGameObject.SetActive(true);
                    }
                }
                else
                {
                    if (cellInfo.objectsContainerGameObject.activeSelf)
                    {
                        cellInfo.objectsContainerGameObject.SetActive(false);
                    }
                }
            }
        }