コード例 #1
0
ファイル: MorrowindEngine.cs プロジェクト: sjb8100/TESUnityXR
        public MorrowindEngine(MorrowindDataReader mwDataReader, UIManager uiManager)
        {
            Debug.Assert(instance == null);

            instance             = this;
            dataReader           = mwDataReader;
            textureManager       = new TextureManager(dataReader);
            materialManager      = new MaterialManager(textureManager);
            nifManager           = new NIFManager(dataReader, materialManager);
            temporalLoadBalancer = new TemporalLoadBalancer();
            cellManager          = new CellManager(dataReader, textureManager, nifManager, temporalLoadBalancer);

            RenderSettings.ambientMode      = UnityEngine.Rendering.AmbientMode.Flat;
            RenderSettings.ambientIntensity = TESUnity.instance.ambientIntensity;

            sunObj = GameObjectUtils.CreateDirectionalLight(Vector3.zero, Quaternion.Euler(new Vector3(50, 330, 0)));
            sunObj.GetComponent <Light>().shadows = TESUnity.instance.renderSunShadows ? LightShadows.Soft : LightShadows.None;
            sunObj.SetActive(false);

            waterObj = GameObject.Instantiate(TESUnity.instance.waterPrefab);
            waterObj.SetActive(false);

            if (!TESUnity.instance.waterBackSideTransparent)
            {
                var side         = waterObj.transform.GetChild(0);
                var sideMaterial = side.GetComponent <Renderer>().sharedMaterial;
                sideMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                sideMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                sideMaterial.SetInt("_ZWrite", 1);
                sideMaterial.DisableKeyword("_ALPHATEST_ON");
                sideMaterial.DisableKeyword("_ALPHABLEND_ON");
                sideMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                sideMaterial.renderQueue = -1;
            }

            Cursor.SetCursor(textureManager.LoadTexture("tx_cursor", true), Vector2.zero, CursorMode.Auto);

            _uiManager        = uiManager;
            _uiManager.Active = true;
        }
コード例 #2
0
        /// <summary>
        /// Creates terrain representing a LAND record.
        /// </summary>
        private IEnumerator InstantiateLANDCoroutine(LANDRecord LAND, GameObject parent)
        {
            Debug.Assert(LAND != null);

            // Don't create anything if the LAND doesn't have height data.
            if (LAND.VHGT == null)
            {
                yield break;
            }

            // Return before doing any work to provide an IEnumerator handle to the coroutine.
            yield return(null);

            const int LAND_SIDE_LENGTH_IN_SAMPLES = 65;
            var       heights = new float[LAND_SIDE_LENGTH_IN_SAMPLES, LAND_SIDE_LENGTH_IN_SAMPLES];

            // Read in the heights in Morrowind units.
            const int VHGTIncrementToMWUnits = 8;
            float     rowOffset = LAND.VHGT.referenceHeight;

            for (int y = 0; y < LAND_SIDE_LENGTH_IN_SAMPLES; y++)
            {
                rowOffset    += LAND.VHGT.heightOffsets[y * LAND_SIDE_LENGTH_IN_SAMPLES];
                heights[y, 0] = VHGTIncrementToMWUnits * rowOffset;

                float colOffset = rowOffset;

                for (int x = 1; x < LAND_SIDE_LENGTH_IN_SAMPLES; x++)
                {
                    colOffset    += LAND.VHGT.heightOffsets[(y * LAND_SIDE_LENGTH_IN_SAMPLES) + x];
                    heights[y, x] = VHGTIncrementToMWUnits * colOffset;
                }
            }

            // Change the heights to percentages.
            float minHeight, maxHeight;

            ArrayUtils.GetExtrema(heights, out minHeight, out maxHeight);

            for (int y = 0; y < LAND_SIDE_LENGTH_IN_SAMPLES; y++)
            {
                for (int x = 0; x < LAND_SIDE_LENGTH_IN_SAMPLES; x++)
                {
                    heights[y, x] = Utils.ChangeRange(heights[y, x], minHeight, maxHeight, 0, 1);
                }
            }

            // Texture the terrain.
            SplatPrototype[] splatPrototypes = null;
            float[,,] alphaMap = null;

            const int LAND_TEXTURE_INDICES_COUNT = 256;
            var       textureIndices             = (LAND.VTEX != null) ? LAND.VTEX.textureIndices : new ushort[LAND_TEXTURE_INDICES_COUNT];

            // Create splat prototypes.
            var splatPrototypeList = new List <SplatPrototype>();
            var texInd2splatInd    = new Dictionary <ushort, int>();

            for (int i = 0; i < textureIndices.Length; i++)
            {
                short textureIndex = (short)((short)textureIndices[i] - 1);

                if (!texInd2splatInd.ContainsKey((ushort)textureIndex))
                {
                    // Load terrain texture.
                    string textureFilePath;

                    if (textureIndex < 0)
                    {
                        textureFilePath = defaultLandTextureFilePath;
                    }
                    else
                    {
                        var LTEX = dataReader.FindLTEXRecord(textureIndex);
                        textureFilePath = LTEX.DATA.value;
                    }

                    var texture = textureManager.LoadTexture(textureFilePath);

                    // Yield after loading each texture to avoid doing too much work on one frame.
                    yield return(null);

                    // Create the splat prototype.
                    var splat = new SplatPrototype();
                    splat.texture    = texture;
                    splat.smoothness = 0;
                    splat.metallic   = 0;
                    splat.tileSize   = new Vector2(6, 6);

                    // Update collections.
                    var splatIndex = splatPrototypeList.Count;
                    splatPrototypeList.Add(splat);
                    texInd2splatInd.Add((ushort)textureIndex, splatIndex);
                }
            }

            splatPrototypes = splatPrototypeList.ToArray();

            // Create the alpha map.
            int VTEX_ROWS    = 16;
            int VTEX_COLUMNS = VTEX_ROWS;

            alphaMap = new float[VTEX_ROWS, VTEX_COLUMNS, splatPrototypes.Length];

            for (int y = 0; y < VTEX_ROWS; y++)
            {
                var yMajor = y / 4;
                var yMinor = y - (yMajor * 4);

                for (int x = 0; x < VTEX_COLUMNS; x++)
                {
                    var xMajor = x / 4;
                    var xMinor = x - (xMajor * 4);

                    var texIndex = (short)((short)textureIndices[(yMajor * 64) + (xMajor * 16) + (yMinor * 4) + xMinor] - 1);

                    if (texIndex >= 0)
                    {
                        var splatIndex = texInd2splatInd[(ushort)texIndex];

                        alphaMap[y, x, splatIndex] = 1;
                    }
                    else
                    {
                        alphaMap[y, x, 0] = 1;
                    }
                }
            }

            // Yield before creating the terrain GameObject because it takes a while.
            yield return(null);

            // Create the terrain.
            var heightRange     = maxHeight - minHeight;
            var terrainPosition = new Vector3(Convert.exteriorCellSideLengthInMeters * LAND.gridCoords.x, minHeight / Convert.meterInMWUnits, Convert.exteriorCellSideLengthInMeters * LAND.gridCoords.y);

            var heightSampleDistance = Convert.exteriorCellSideLengthInMeters / (LAND_SIDE_LENGTH_IN_SAMPLES - 1);

            var terrain = GameObjectUtils.CreateTerrain(heights, heightRange / Convert.meterInMWUnits, heightSampleDistance, splatPrototypes, alphaMap, terrainPosition);

            terrain.GetComponent <Terrain>().materialType = Terrain.MaterialType.BuiltInLegacyDiffuse;

            terrain.transform.parent = parent.transform;
        }