/// <summary>
		/// Gets the vegetation voxel based on position, biome and a random value
		/// </summary>
		/// <returns>The vegetation.</returns>
		/// <param name="biome">Biome.</param>
		/// <param name="random">Random.</param>
		public VoxelDefinition GetVegetation (BiomeDefinition biome, float random) {
			float acumProb = 0;
			int index = 0;
			for (int t = 0; t < biome.vegetation.Length; t++) {
				acumProb += biome.vegetation [t].probability;
				if (random < acumProb) {
					index = t;
					break;
				}
			}
			return biome.vegetation [index].vegetation;
		}
 void ToggleBiomes(bool visible)
 {
     for (int k = 0; k < world.biomes.Length; k++)
     {
         BiomeDefinition biome = world.biomes [k];
         if (biome == null)
         {
             continue;
         }
         biome.showInBiomeMap = visible;
     }
 }
        void CalcBiome()
        {
            BiomeDefinition biome = env.GetBiome(inputAltitude, inputMoisture);

            if (biome == null)
            {
                biomeTestResult = "No matching biome.";
            }
            else
            {
                biomeTestResult = "Matching biome: " + biome.name + ".";
            }
        }
        void InitBiomes()
        {
            biomeLookUp = new BiomeDefinition[441];             // 21 * 21
            if (world == null)
            {
                return;
            }
            if (world.biomes == null)
            {
                return;
            }

            for (int b = 0; b < world.biomes.Length; b++)
            {
                BiomeDefinition biome = world.biomes [b];
                if (biome == null || biome.zones == null)
                {
                    continue;
                }
                for (int z = 0; z < biome.zones.Length; z++)
                {
                    BiomeZone zone = biome.zones [z];
                    for (int elevation = 0; elevation <= 20; elevation++)
                    {
                        float e = elevation / 20f;
                        for (int moisture = 0; moisture <= 20; moisture++)
                        {
                            float m = moisture / 20f;
                            if (e >= zone.elevationMin && e <= zone.elevationMax && m >= zone.moistureMin && m <= zone.moistureMax)
                            {
                                biomeLookUp [elevation * 21 + moisture] = biome;
                            }
                        }
                    }
                }
                if (biome.ores == null)
                {
                    biome.ores = new BiomeOre[0];
                }
            }

            SetBiomeDefaultColors(false);
        }
        void DrawLegend(Color color, string text, BiomeDefinition biome)
        {
            Rect space = EditorGUILayout.BeginHorizontal();

            space.position += new Vector2(5, 0);
            space.width     = 16;
            space.height    = 16;
            Color prevColor = GUI.color;

            GUI.color = color;
            EditorGUI.DrawPreviewTexture(space, Texture2D.whiteTexture);
            space.position += new Vector2(20, 0);
            space.width     = 20;
            if (biome != null)
            {
                GUI.color = biome.showInBiomeMap ? prevColor : new Color(prevColor.r, prevColor.g, prevColor.b, 0.4f);
            }
            else
            {
                GUI.color = prevColor;
            }
            space.width = 20;
            if (biome != null)
            {
                biome.showInBiomeMap = EditorGUI.Toggle(space, biome.showInBiomeMap);
                space.width          = 35;
                space.position      += new Vector2(20, 0);
                if (GUI.Button(space, "->"))
                {
                    Selection.activeObject = biome;
                }
                space.position += new Vector2(35, 0);
            }
            space.width = 120;
            EditorGUI.LabelField(space, text);
            GUI.color = prevColor;
            EditorGUILayout.BeginVertical();
            GUILayout.Space(20);
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
        }
Exemplo n.º 6
0
 /// <summary>
 /// Assigns a color to each biome.
 /// </summary>
 public void SetBiomeDefaultColors(bool force)
 {
     if (world != null)
     {
         if (world.biomes != null)
         {
             for (int b = 0; b < world.biomes.Length; b++)
             {
                 BiomeDefinition biome = world.biomes [b];
                 if (biome == null || biome.zones == null)
                 {
                     continue;
                 }
                 if (force || biome.biomeMapColor.a == 0)
                 {
                     long    color      = distinctColors [b % distinctColors.Length];
                     Color32 biomeColor = new Color32((byte)(color >> 16), (byte)((color >> 8) & 255), (byte)(color & 255), 255);
                     biome.biomeMapColor = biomeColor;
                 }
             }
         }
     }
 }
Exemplo n.º 7
0
        /// <summary>
        /// Paints the terrain inside the chunk defined by its central "position"
        /// </summary>
        /// <returns><c>true</c>, if terrain was painted, <c>false</c> otherwise.</returns>
        /// <param name="position">Central position of the chunk.</param>
        public override bool PaintChunk(VoxelChunk chunk)
        {
            Vector3 position = chunk.position;

            if (position.y + 8 < minHeight)
            {
                chunk.isAboveSurface = false;
                return(false);
            }
            int bedrockRow = -1;

            if ((object)bedrockVoxel != null && position.y < minHeight + 8)
            {
                bedrockRow = (int)(minHeight - (position.y - 8) + 1) * ONE_Y_ROW;
            }
            position.x -= 8;
            position.y -= 8;
            position.z -= 8;
            Vector3 pos;

            int waterLevel = env.waterLevel > 0 ? env.waterLevel : -1;

            Voxel[] voxels = chunk.voxels;

            bool hasContent     = false;
            bool isAboveSurface = false;

            generation++;
            env.GetHeightMapInfoFast(position.x, position.z, heightChunkData);

            // iterate 256 slice of chunk (z/x plane = 16*16 positions)
            for (int arrayIndex = 0; arrayIndex < 256; arrayIndex++)
            {
                float groundLevel  = heightChunkData [arrayIndex].groundLevel;
                float surfaceLevel = waterLevel > groundLevel ? waterLevel : groundLevel;
                if (surfaceLevel < position.y)
                {
                    // position is above terrain or water
                    isAboveSurface = true;
                    continue;
                }
                BiomeDefinition biome = heightChunkData [arrayIndex].biome;
                if ((object)biome == null)
                {
                    biome = world.defaultBiome;
                    if ((object)biome == null)
                    {
                        continue;
                    }
                }

                int y = (int)(surfaceLevel - position.y);
                if (y > 15)
                {
                    y = 15;
                }
                pos.y = position.y + y;
                pos.x = position.x + (arrayIndex & 0xF);
                pos.z = position.z + (arrayIndex >> 4);

                // Place voxels
                int voxelIndex = y * ONE_Y_ROW + arrayIndex;
                if (pos.y > groundLevel)
                {
                    // water above terrain
                    if (pos.y == surfaceLevel)
                    {
                        isAboveSurface = true;
                    }
                    while (pos.y > groundLevel && voxelIndex >= 0)
                    {
                        voxels [voxelIndex].Set(waterVoxel);
                        voxelIndex -= ONE_Y_ROW;
                        pos.y--;
                    }
                }
                else if (pos.y == groundLevel)
                {
                    isAboveSurface = true;
                    if (voxels [voxelIndex].hasContent == 0)
                    {
                        if (paintShore && pos.y == waterLevel)
                        {
                            // this is on the shore, place a shoreVoxel
                            voxels [voxelIndex].Set(shoreVoxel);
                        }
                        else
                        {
                            // we're at the surface of the biome => draw the voxel top of the biome and also check for random vegetation and trees
                            voxels [voxelIndex].Set(biome.voxelTop);
#if UNITY_EDITOR
                            if (!env.draftModeActive)
                            {
#endif
                            // Check tree probability
                            if (pos.y > waterLevel)
                            {
                                float rn = WorldRand.GetValue(pos);
                                if (env.enableTrees && biome.treeDensity > 0 && rn < biome.treeDensity && biome.trees.Length > 0)
                                {
                                    // request one tree at this position
                                    env.RequestTreeCreation(chunk, pos, env.GetTree(biome.trees, rn / biome.treeDensity));
                                }
                                else if (env.enableVegetation && biome.vegetationDensity > 0 && rn < biome.vegetationDensity && biome.vegetation.Length > 0)
                                {
                                    if (voxelIndex >= 15 * ONE_Y_ROW)
                                    {
                                        // request one vegetation voxel one position above which means the chunk above this one
                                        env.RequestVegetationCreation(chunk.top, voxelIndex - ONE_Y_ROW * 15, env.GetVegetation(biome, rn / biome.vegetationDensity));
                                    }
                                    else
                                    {
                                        // directly place a vegetation voxel above this voxel
                                        voxels [voxelIndex + ONE_Y_ROW].Set(env.GetVegetation(biome, rn / biome.vegetationDensity));
                                        env.vegetationCreated++;
                                    }
                                }
                            }
#if UNITY_EDITOR
                        }
#endif
                        }
                    }
                    voxelIndex -= ONE_Y_ROW;
                }

                // Continue filling down
                biome.biomeGeneration = generation;
                while (voxelIndex > bedrockRow)
                {
                    if (voxels [voxelIndex].hasContent == 0)
                    {
                        voxels [voxelIndex].SetFastOpaque(biome.voxelDirt);
                    }
                    voxelIndex -= ONE_Y_ROW;
                }
                if (bedrockRow >= 0)
                {
                    voxels [voxelIndex].SetFastOpaque(bedrockVoxel);
                }
                hasContent = true;
            }

            // Spawn random ore
            if (addOre)
            {
                // Check if there's any ore in this chunk (randomly)
                float noiseValue = WorldRand.GetValue(chunk.position);
                for (int b = 0; b < world.biomes.Length; b++)
                {
                    BiomeDefinition biome = world.biomes [b];
                    if (biome.biomeGeneration != generation)
                    {
                        continue;
                    }
                    for (int o = 0; o < biome.ores.Length; o++)
                    {
                        if (biome.ores [o].ore == null)
                        {
                            continue;
                        }
                        if (biome.ores [o].probabilityMin <= noiseValue && biome.ores [o].probabilityMax >= noiseValue)
                        {
                            // ore picked; determine the number of veins in this chunk
                            int veinsCount = biome.ores [o].veinsCountMin + (int)(WorldRand.GetValue() * (biome.ores [o].veinsCountMax - biome.ores [o].veinsCountMin + 1f));
                            for (int vein = 0; vein < veinsCount; vein++)
                            {
                                Vector3 veinPos = chunk.position;
                                veinPos.x += vein;
                                // Determine random vein position in the chunk
                                Vector3 v  = WorldRand.GetVector3(veinPos, 16);
                                int     px = (int)v.x;
                                int     py = (int)v.y;
                                int     pz = (int)v.z;
                                veinPos = env.GetVoxelPosition(veinPos, px, py, pz);
                                int oreIndex = py * ONE_Y_ROW + pz * ONE_Z_ROW + px;
                                int veinSize = biome.ores [o].veinMinSize + (oreIndex % (biome.ores [o].veinMaxSize - biome.ores [o].veinMinSize + 1));
                                // span ore vein
                                SpawnOre(chunk, biome.ores [o].ore, veinPos, px, py, pz, veinSize, biome.ores [o].depthMin, biome.ores [o].depthMax);
                            }
                            break;
                        }
                    }
                }
            }

            // Finish, return
            chunk.isAboveSurface = isAboveSurface;
            return(hasContent);
        }
        void RefreshBiomeTexture()
        {
            if (biomeTex == null || biomeTex.width != mapResolution)
            {
                biomeTex = new Texture2D(mapResolution, mapResolution, TextureFormat.ARGB32, false);
            }

            int width  = biomeTex.width;
            int height = biomeTex.height;

            Color[] colors = new Color[width * height];

            if (env == null || tg == null)
            {
                colors.Fill <Color> (new Color(0, 0.5f, 0, 0.5f));
            }
            else
            {
                env.SetBiomeDefaultColors(false);
                colors.Fill <Color> (Misc.colorTransparent);

                // reset biome stats
                for (int k = 0; k < world.biomes.Length; k++)
                {
                    if (world.biomes [k] != null)
                    {
                        world.biomes [k].biomeMapOccurrences = 0;
                    }
                }
                // draw biome colors
                for (int j = 0; j < height; j++)
                {
                    float z  = (maxZ - minZ) * (float)j / height + minZ;
                    int   jj = j * width;
                    for (int k = 0; k < width; k++)
                    {
                        float         x    = (maxX - minX) * (float)k / width + minX;
                        HeightMapInfo info = env.GetTerrainInfo(x, z);
                        if (info.groundLevel <= tg.waterLevel)
                        {
                            colors [jj + k] = waterColor;
                        }
                        else
                        {
                            BiomeDefinition biome = info.biome;
                            if (biome == null)
                            {
                                continue;
                            }
                            biome.biomeMapOccurrences++;
                            if (biome.showInBiomeMap)
                            {
                                colors [jj + k] = biome.biomeMapColor;
                            }
                        }
                    }
                }

                int   gridCount = (int)((maxZ - minZ) / gridStep);
                Color gridColor = new Color(64, 64, 64, 0.2f);
                // draw horizontal grid lines
                for (int j = 0; j <= gridCount; j++)
                {
                    int y = (int)((height - 1f) * j / gridCount);
                    for (int k = 0; k < width; k++)
                    {
                        colors [y * width + k] = gridColor;
                    }
                }
                gridCount = (int)((maxX - minX) / gridStep);
                // draw vertical grid lines
                for (int j = 0; j <= gridCount; j++)
                {
                    int x = (int)((width - 1f) * j / gridCount);
                    for (int k = 0; k < height; k++)
                    {
                        colors [k * width + x] = gridColor;
                    }
                }
            }

            biomeTex.SetPixels(colors);
            biomeTex.Apply();
        }
        void OnGUI()
        {
            if (env == null)
            {
                env = VoxelPlayEnvironment.instance;
                if (env == null)
                {
                    world = null;
                }
                EditorGUILayout.HelpBox("Biome Explorer cannot find a Voxel Play Environment instance in the current scene.", MessageType.Error);
                GUIUtility.ExitGUI();
            }
            else
            {
                world = env.world;
            }

            if (world == null)
            {
                EditorGUILayout.HelpBox("Assign a World Definition to the Voxel Play Environment instance.", MessageType.Warning);
                GUIUtility.ExitGUI();
            }

            if (terrainTex == null || moistureTex == null)
            {
                RefreshTextures();
                GUIUtility.ExitGUI();
            }

            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);

            if (titleLabelStyle == null)
            {
                titleLabelStyle = new GUIStyle(EditorStyles.label);
            }
            titleLabelStyle.normal.textColor = titleColor;
            titleLabelStyle.fontStyle        = FontStyle.Bold;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.HelpBox("Preview terrain generation and biome distribution based on current settings.", MessageType.Info);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Separator();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Min X", GUILayout.Width(100));
            proposedMinX = EditorGUILayout.FloatField(proposedMinX, GUILayout.MaxWidth(120));
            EditorGUILayout.LabelField("Max X", GUILayout.Width(100));
            proposedMaxX = EditorGUILayout.FloatField(proposedMaxX, GUILayout.MaxWidth(120));
            if (GUILayout.Button("<<", GUILayout.Width(40)))
            {
                float shift = (maxX - minX) * 0.5f;
                proposedMinX  -= shift;
                proposedMaxX  -= shift;
                requestRefresh = true;
            }
            if (GUILayout.Button("<", GUILayout.Width(40)))
            {
                float shift = (maxX - minX) * 0.1f;
                proposedMinX  -= shift;
                proposedMaxX  -= shift;
                requestRefresh = true;
            }
            if (GUILayout.Button(">", GUILayout.Width(40)))
            {
                float shift = (maxX - minX) * 0.1f;
                proposedMinX  += shift;
                proposedMaxX  += shift;
                requestRefresh = true;
            }
            if (GUILayout.Button(">>", GUILayout.Width(40)))
            {
                float shift = (maxX - minX) * 0.5f;
                proposedMinX  += shift;
                proposedMaxX  += shift;
                requestRefresh = true;
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Min Z", GUILayout.Width(100));
            proposedMinZ = EditorGUILayout.FloatField(proposedMinZ, GUILayout.MaxWidth(120));
            EditorGUILayout.LabelField("Max Z", GUILayout.Width(100));
            proposedMaxZ = EditorGUILayout.FloatField(proposedMaxZ, GUILayout.MaxWidth(120));
            if (GUILayout.Button("<<", GUILayout.Width(40)))
            {
                float shift = (maxZ - minZ) * 0.5f;
                proposedMinZ  -= shift;
                proposedMaxZ  -= shift;
                proposedSliceZ = (proposedMinZ + proposedMaxZ) * 0.5f;
                requestRefresh = true;
            }
            if (GUILayout.Button("<", GUILayout.Width(40)))
            {
                float shift = (maxZ - minZ) * 0.1f;
                proposedMinZ  -= shift;
                proposedMaxZ  -= shift;
                proposedSliceZ = (proposedMinZ + proposedMaxZ) * 0.5f;
                requestRefresh = true;
            }
            if (GUILayout.Button(">", GUILayout.Width(40)))
            {
                float shift = (maxZ - minZ) * 0.1f;
                proposedMinZ  += shift;
                proposedMaxZ  += shift;
                proposedSliceZ = (proposedMinZ + proposedMaxZ) * 0.5f;
                requestRefresh = true;
            }
            if (GUILayout.Button(">>", GUILayout.Width(40)))
            {
                float shift = (maxZ - minZ) * 0.5f;
                proposedMinZ  += shift;
                proposedMaxZ  += shift;
                proposedSliceZ = (proposedMinZ + proposedMaxZ) * 0.5f;
                requestRefresh = true;
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Slice Z", GUILayout.Width(100));
            proposedSliceZ = EditorGUILayout.FloatField(proposedSliceZ, GUILayout.MaxWidth(120));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button(new GUIContent("Refresh Window", "Refresh textures to reflect new filters."), GUILayout.Width(140)))
            {
                requestRefresh = true;
            }
            if (GUILayout.Button(new GUIContent("-> World Definition", "Show World Definition in the inspector."), GUILayout.Width(140)))
            {
                Selection.activeObject = world;
            }
            if (GUILayout.Button(new GUIContent("-> Terrain Generator", "Show Terrain Generator in the inspector."), GUILayout.Width(140)))
            {
                Selection.activeObject = tg;
            }
            if (GUILayout.Button(new GUIContent("-> Environment", "Show Voxel Play Environment in the inspector."), GUILayout.Width(140)))
            {
                Selection.activeGameObject = env.gameObject;
            }
            if (GUILayout.Button(new GUIContent("Reload Config", "Resets heightmaps and biome cache and initializes terrain generator."), GUILayout.Width(140)))
            {
                env.NotifyTerrainGeneratorConfigurationChanged();
                requestRefresh = true;
                GUIUtility.ExitGUI();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Separator();
            Rect space;

            if (previewTextureMat == null)
            {
                previewTextureMat = Resources.Load <Material> ("VoxelPlay/PreviewTexture");
            }

            // Draw heightmap distribution
            if (terrainTex != null)
            {
                EditorGUILayout.LabelField(new GUIContent("Height Map Preview"), titleLabelStyle);
                space        = EditorGUILayout.BeginVertical();
                space.width -= 20;
                GUILayout.Space(terrainTex.height);
                EditorGUILayout.EndVertical();

                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(15);
                space.position += new Vector2(15, 0);
                EditorGUI.DrawPreviewTexture(space, terrainTex, previewTextureMat);
                GUILayout.Space(5);
                EditorGUILayout.EndHorizontal();

                // Draw 0-1 range
                space.position -= new Vector2(15, 0);
                EditorGUI.LabelField(space, "1");
                space.position += new Vector2(0, space.height - 10f);
                EditorGUI.LabelField(space, "0");

                // Draw x-axis labels
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(15);
                EditorGUILayout.LabelField("Min X = " + minX);
                labelStyle.alignment = TextAnchor.MiddleCenter;
                EditorGUILayout.LabelField("Slize Z = " + sliceZ + " / Min Y = " + calcMinAltitude.ToString("F3") + " / Max Y = " + calcMaxAltitude.ToString("F3"), labelStyle);
                labelStyle.alignment = TextAnchor.MiddleRight;
                EditorGUILayout.LabelField("Max X = " + maxX, labelStyle);
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.Separator();
            EditorGUILayout.Separator();


            // Draw moisture distribution
            if (terrainTex != null)
            {
                EditorGUILayout.LabelField(new GUIContent("Moisture Preview"), titleLabelStyle);
                space        = EditorGUILayout.BeginVertical();
                space.width -= 20;
                GUILayout.Space(moistureTex.height);
                EditorGUILayout.EndVertical();

                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(15);
                space.position += new Vector2(15, 0);
                EditorGUI.DrawPreviewTexture(space, moistureTex, previewTextureMat);
                GUILayout.Space(5);
                EditorGUILayout.EndHorizontal();

                // Draw 0-1 range
                space.position -= new Vector2(15, 0);
                EditorGUI.LabelField(space, "1");
                space.position += new Vector2(0, space.height - 10f);
                EditorGUI.LabelField(space, "0");

                // Draw x-axis labels
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(15);
                EditorGUILayout.LabelField("Min X = " + minX);
                labelStyle.alignment = TextAnchor.MiddleCenter;
                EditorGUILayout.LabelField("Slize Z = " + sliceZ + " / Min Y = " + calcMinMoisture.ToString("F3") + " / Max Y = " + calcMaxMoisture.ToString("F3"), labelStyle);
                labelStyle.alignment = TextAnchor.MiddleRight;
                EditorGUILayout.LabelField("Max X = " + maxX, labelStyle);
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.Separator();
            EditorGUILayout.Separator();


            if (world.biomes != null && biomeTex != null)
            {
                // Draw heightmap texture
                EditorGUILayout.LabelField(new GUIContent("Biome Map Preview"), titleLabelStyle);

                EditorGUILayout.BeginHorizontal();

                // Biome legend
                EditorGUILayout.BeginVertical(GUILayout.MaxWidth(180));
                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Hide All", GUILayout.Width(80)))
                {
                    ToggleBiomes(false);
                    requestRefresh = true;
                }
                if (GUILayout.Button("Show All", GUILayout.Width(80)))
                {
                    ToggleBiomes(true);
                    requestRefresh = true;
                }
                if (GUILayout.Button("Default Colors", GUILayout.Width(120)))
                {
                    env.SetBiomeDefaultColors(true);
                    requestRefresh = true;
                }
                EditorGUILayout.EndHorizontal();
                EditorGUI.BeginChangeCheck();
                for (int k = 0; k < world.biomes.Length; k++)
                {
                    BiomeDefinition biome = world.biomes [k];
                    if (biome == null)
                    {
                        continue;
                    }
                    float perc = 100f * (float)biome.biomeMapOccurrences / (biomeTex.width * biomeTex.height);
                    DrawLegend(biome.biomeMapColor, biome.name + " (" + perc.ToString("F2") + "%)", biome);
                }
                DrawLegend(waterColor, "Water", null);

                if (EditorGUI.EndChangeCheck())
                {
                    requestRefresh = true;
                }
                EditorGUILayout.Separator();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Grid Size", GUILayout.Width(100));
                gridStep = EditorGUILayout.IntField(gridStep, GUILayout.Width(60));
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Texture Size", GUILayout.Width(100));
                mapResolution = EditorGUILayout.IntField(mapResolution, GUILayout.Width(60));
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Separator();
                EditorGUILayout.Separator();
                // Tester
                EditorGUILayout.LabelField(new GUIContent("Biome Tester"), titleLabelStyle);
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Altitude?", GUILayout.Width(100));
                inputAltitude = EditorGUILayout.Slider(inputAltitude, 0, 1, GUILayout.Width(130));
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Moisture?", GUILayout.Width(100));
                inputMoisture = EditorGUILayout.Slider(inputMoisture, 0, 1, GUILayout.Width(130));
                EditorGUILayout.EndHorizontal();
                if (EditorGUI.EndChangeCheck())
                {
                    CalcBiome();
                }
                EditorGUILayout.LabelField(biomeTestResult);
                EditorGUILayout.EndVertical();

                // Biome map
                space = EditorGUILayout.BeginVertical();
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndVertical();
                EditorGUI.DrawPreviewTexture(space, biomeTex, previewTextureMat, ScaleMode.ScaleToFit);

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Separator();
            }

            if (requestRefresh)
            {
                RefreshTextures();
            }
        }
Exemplo n.º 10
0
        void LoadWorldTextures()
        {
            requireTextureArrayUpdate = false;

            // Init texture array
            if (worldTextures == null)
            {
                worldTextures = new List <WorldTexture> ();
            }
            else
            {
                worldTextures.Clear();
            }
            if (worldTexturesDict == null)
            {
                worldTexturesDict = new Dictionary <Texture2D, int> ();
            }
            else
            {
                worldTexturesDict.Clear();
            }

            // Clear definitions
            if (voxelDefinitions != null)
            {
                // Voxel Definitions no longer are added to the dictionary, clear the index field.
                for (int k = 0; k < voxelDefinitionsCount; k++)
                {
                    if (voxelDefinitions [k] != null)
                    {
                        voxelDefinitions [k].Reset();
                    }
                }
            }
            else
            {
                voxelDefinitions = new VoxelDefinition[128];
            }
            voxelDefinitionsCount = 0;
            if (voxelDefinitionsDict == null)
            {
                voxelDefinitionsDict = new Dictionary <string, VoxelDefinition> ();
            }
            else
            {
                voxelDefinitionsDict.Clear();
            }
            if (sessionUserVoxels == null)
            {
                sessionUserVoxels = new List <VoxelDefinition> ();
            }

            // The null voxel definition
            VoxelDefinition nullVoxelDefinition = ScriptableObject.CreateInstance <VoxelDefinition> ();

            nullVoxelDefinition.hidden         = true;
            nullVoxelDefinition.canBeCollected = false;
            nullVoxelDefinition.name           = "Null";
            AddVoxelTextures(nullVoxelDefinition);

            // Check default voxel
            if (defaultVoxel == null)
            {
                defaultVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/DefaultVoxel");
            }
            AddVoxelTextures(defaultVoxel);

            // Add all biome textures
            if (world.biomes != null)
            {
                for (int k = 0; k < world.biomes.Length; k++)
                {
                    BiomeDefinition biome = world.biomes [k];
                    if (biome == null)
                    {
                        continue;
                    }
                    AddVoxelTextures(biome.voxelTop);
                    if (biome.voxelTop.biomeDirtCounterpart == null)
                    {
                        biome.voxelTop.biomeDirtCounterpart = biome.voxelDirt;
                    }
                    AddVoxelTextures(biome.voxelDirt);
                    if (biome.vegetation != null)
                    {
                        for (int v = 0; v < biome.vegetation.Length; v++)
                        {
                            AddVoxelTextures(biome.vegetation [v].vegetation);
                        }
                    }
                    if (biome.trees != null)
                    {
                        for (int t = 0; t < biome.trees.Length; t++)
                        {
                            ModelDefinition tree = biome.trees [t].tree;
                            if (tree == null)
                            {
                                continue;
                            }
                            for (int b = 0; b < tree.bits.Length; b++)
                            {
                                AddVoxelTextures(tree.bits [b].voxelDefinition);
                            }
                        }
                    }
                    if (biome.ores != null)
                    {
                        for (int v = 0; v < biome.ores.Length; v++)
                        {
                            // ensure proper size
                            if (biome.ores [v].veinMinSize == biome.ores [v].veinMaxSize && biome.ores [v].veinMaxSize == 0)
                            {
                                biome.ores [v].veinMinSize   = 2;
                                biome.ores [v].veinMaxSize   = 6;
                                biome.ores [v].veinsCountMin = 1;
                                biome.ores [v].veinsCountMax = 2;
                            }
                            AddVoxelTextures(biome.ores [v].ore);
                        }
                    }
                }
            }

            // Special voxels
            if (world.cloudVoxel == null)
            {
                world.cloudVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/VoxelCloud");
            }
            AddVoxelTextures(world.cloudVoxel);

            // Add additional world voxels
            if (world.moreVoxels != null)
            {
                for (int k = 0; k < world.moreVoxels.Length; k++)
                {
                    AddVoxelTextures(world.moreVoxels [k]);
                }
            }

            // Add all items' textures are available
            if (world.items != null)
            {
                int itemCount = world.items.Length;
                for (int k = 0; k < itemCount; k++)
                {
                    ItemDefinition item = world.items [k];
                    if (item.category == ItemCategory.Voxel)
                    {
                        AddVoxelTextures(item.voxelType);
                    }
                }
            }


            // Add any other voxel found inside Defaults
            VoxelDefinition[] vdd = Resources.LoadAll <VoxelDefinition> ("VoxelPlay/Defaults");
            for (int k = 0; k < vdd.Length; k++)
            {
                AddVoxelTextures(vdd [k]);
            }

            // Add any other voxel found inside World directory
            vdd = Resources.LoadAll <VoxelDefinition> ("Worlds/" + world.name);
            for (int k = 0; k < vdd.Length; k++)
            {
                AddVoxelTextures(vdd [k]);
            }

            // Add any other voxel found inside a resource directory with same name of world (if not placed into Worlds directory)
            vdd = Resources.LoadAll <VoxelDefinition> (world.name);
            for (int k = 0; k < vdd.Length; k++)
            {
                AddVoxelTextures(vdd [k]);
            }

            // Add user provided voxels during playtime
            int count = sessionUserVoxels.Count;

            for (int k = 0; k < count; k++)
            {
                AddVoxelTextures(sessionUserVoxels [k]);
            }

            // Unload textures (doesn't work at runtime on PC! this commented section should be removed)
//			#if !UNITY_EDITOR
//			for (int k = 0; k < voxelDefinitionsCount; k++) {
//				VoxelDefinition vd = voxelDefinitions [k];
//				if (vd.index == 0)
//					continue;
//				if (vd.textureTop != null)
//					Resources.UnloadAsset (vd.textureTop);
//				if (vd.textureTopEmission != null)
//					Resources.UnloadAsset (vd.textureTopEmission);
//				if (vd.textureTopNRM != null)
//					Resources.UnloadAsset (vd.textureTopNRM);
//				if (vd.textureTopDISP != null)
//					Resources.UnloadAsset (vd.textureTopDISP);
//				if (vd.textureLeft != null)
//					Resources.UnloadAsset (vd.textureLeft);
//				if (vd.textureLeftEmission != null)
//					Resources.UnloadAsset (vd.textureLeftEmission);
//				if (vd.textureLeftNRM != null)
//					Resources.UnloadAsset (vd.textureLeftNRM);
//				if (vd.textureLeftDISP != null)
//					Resources.UnloadAsset (vd.textureLeftDISP);
//				if (vd.textureRight != null)
//					Resources.UnloadAsset (vd.textureRight);
//				if (vd.textureRightEmission != null)
//					Resources.UnloadAsset (vd.textureRightEmission);
//				if (vd.textureRightNRM != null)
//					Resources.UnloadAsset (vd.textureRightNRM);
//				if (vd.textureRightDISP != null)
//					Resources.UnloadAsset (vd.textureRightDISP);
//				if (vd.textureBottom != null)
//					Resources.UnloadAsset (vd.textureBottom);
//				if (vd.textureBottomEmission != null)
//					Resources.UnloadAsset (vd.textureBottomEmission);
//				if (vd.textureBottomNRM != null)
//					Resources.UnloadAsset (vd.textureBottomNRM);
//				if (vd.textureBottomDISP != null)
//					Resources.UnloadAsset (vd.textureBottomDISP);
//				if (vd.textureSide != null)
//					Resources.UnloadAsset (vd.textureSide);
//				if (vd.textureSideEmission != null)
//					Resources.UnloadAsset (vd.textureSideEmission);
//				if (vd.textureSideNRM != null)
//					Resources.UnloadAsset (vd.textureSideNRM);
//				if (vd.textureSideDISP != null)
//					Resources.UnloadAsset (vd.textureSideDISP);
//				if (vd.textureForward != null)
//					Resources.UnloadAsset (vd.textureForward);
//				if (vd.textureForwardEmission != null)
//					Resources.UnloadAsset (vd.textureForwardEmission);
//				if (vd.textureForwardNRM != null)
//					Resources.UnloadAsset (vd.textureForwardNRM);
//				if (vd.textureForwardDISP != null)
//					Resources.UnloadAsset (vd.textureForwardDISP);
//			}
//			#endif

            // Create array texture
            int textureCount = worldTextures.Count;

            if (textureCount > 0)
            {
                Texture2DArray pointFilterTextureArray = new Texture2DArray(textureSize, textureSize, textureCount, TextureFormat.ARGB32, hqFiltering);
                if (enableReliefMapping || !enableSmoothLighting)
                {
                    pointFilterTextureArray.wrapMode = TextureWrapMode.Repeat;
                }
                else
                {
                    pointFilterTextureArray.wrapMode = TextureWrapMode.Clamp;
                }
                pointFilterTextureArray.filterMode = hqFiltering ? FilterMode.Bilinear : FilterMode.Point;
                pointFilterTextureArray.mipMapBias = -mipMapBias;
                for (int k = 0; k < textureCount; k++)
                {
                    if (worldTextures [k].colorsAndEmission != null)
                    {
                        pointFilterTextureArray.SetPixels32(worldTextures [k].colorsAndEmission, k);
                    }
                    else if (worldTextures [k].normalsAndElevation != null)
                    {
                        pointFilterTextureArray.SetPixels32(worldTextures [k].normalsAndElevation, k);
                    }
                }
                worldTextures.Clear();

                pointFilterTextureArray.Apply(hqFiltering, true);

                // Assign textures to materials
                for (int k = 0; k < materials.Length; k++)
                {
                    if (materials[k] != null && materials[k].HasProperty("_MainTex"))
                    {
                        materials[k].SetTexture("_MainTex", pointFilterTextureArray);
                    }
                }

                if (modelHighlightMat == null)
                {
                    modelHighlightMat = Instantiate <Material> (Resources.Load <Material> ("VoxelPlay/Materials/VP Highlight Model")) as Material;
                }
                modelHighlightMat.SetTexture("_MainTex", pointFilterTextureArray);
            }
        }
        void LoadWorldTextures()
        {
            requireTextureArrayUpdate = false;

            // Init texture array
            if (worldTextures == null)
            {
                worldTextures = new List <WorldTexture> ();
            }
            else
            {
                worldTextures.Clear();
            }
            if (worldTexturesDict == null)
            {
                worldTexturesDict = new Dictionary <Texture2D, int> ();
            }
            else
            {
                worldTexturesDict.Clear();
            }

            // Clear definitions
            if (voxelDefinitions != null)
            {
                // Voxel Definitions no longer are added to the dictionary, clear the index field.
                for (int k = 0; k < voxelDefinitionsCount; k++)
                {
                    if (voxelDefinitions [k] != null)
                    {
                        voxelDefinitions [k].Reset();
                    }
                }
            }
            else
            {
                voxelDefinitions = new VoxelDefinition [128];
            }
            voxelDefinitionsCount = 0;
            if (voxelDefinitionsDict == null)
            {
                voxelDefinitionsDict = new Dictionary <string, VoxelDefinition> ();
            }
            else
            {
                voxelDefinitionsDict.Clear();
            }
            if (sessionUserVoxels == null)
            {
                sessionUserVoxels = new List <VoxelDefinition> ();
            }

            // The null voxel definition
            VoxelDefinition nullVoxelDefinition = ScriptableObject.CreateInstance <VoxelDefinition> ();

            nullVoxelDefinition.name           = "Null";
            nullVoxelDefinition.hidden         = true;
            nullVoxelDefinition.canBeCollected = false;
            nullVoxelDefinition.ignoresRayCast = true;
            nullVoxelDefinition.renderType     = RenderType.Empty;
            AddVoxelTextures(nullVoxelDefinition);

            // Check default voxel
            if (defaultVoxel == null)
            {
                defaultVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/DefaultVoxel");
            }
            AddVoxelTextures(defaultVoxel);

            // Add all biome textures
            if (world.biomes != null)
            {
                for (int k = 0; k < world.biomes.Length; k++)
                {
                    BiomeDefinition biome = world.biomes [k];
                    if (biome == null)
                    {
                        continue;
                    }
                    if (biome.voxelTop != null)
                    {
                        AddVoxelTextures(biome.voxelTop);
                        if (biome.voxelTop.biomeDirtCounterpart == null)
                        {
                            biome.voxelTop.biomeDirtCounterpart = biome.voxelDirt;
                        }
                    }
                    AddVoxelTextures(biome.voxelDirt);
                    if (biome.vegetation != null)
                    {
                        for (int v = 0; v < biome.vegetation.Length; v++)
                        {
                            AddVoxelTextures(biome.vegetation [v].vegetation);
                        }
                    }
                    if (biome.trees != null)
                    {
                        for (int t = 0; t < biome.trees.Length; t++)
                        {
                            ModelDefinition tree = biome.trees [t].tree;
                            if (tree == null)
                            {
                                continue;
                            }
                            for (int b = 0; b < tree.bits.Length; b++)
                            {
                                AddVoxelTextures(tree.bits [b].voxelDefinition);
                            }
                        }
                    }
                    if (biome.ores != null)
                    {
                        for (int v = 0; v < biome.ores.Length; v++)
                        {
                            // ensure proper size
                            if (biome.ores [v].veinMinSize == biome.ores [v].veinMaxSize && biome.ores [v].veinMaxSize == 0)
                            {
                                biome.ores [v].veinMinSize   = 2;
                                biome.ores [v].veinMaxSize   = 6;
                                biome.ores [v].veinsCountMin = 1;
                                biome.ores [v].veinsCountMax = 2;
                            }
                            AddVoxelTextures(biome.ores [v].ore);
                        }
                    }
                }
            }

            // Special voxels
            if (enableClouds)
            {
                if (world.cloudVoxel == null)
                {
                    world.cloudVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/VoxelCloud");
                }
                AddVoxelTextures(world.cloudVoxel);
            }

            // Add additional world voxels
            if (world.moreVoxels != null)
            {
                for (int k = 0; k < world.moreVoxels.Length; k++)
                {
                    AddVoxelTextures(world.moreVoxels [k]);
                }
            }

            // Add all items' textures are available
            if (world.items != null)
            {
                int itemCount = world.items.Length;
                for (int k = 0; k < itemCount; k++)
                {
                    ItemDefinition item = world.items [k];
                    if (item != null && item.category == ItemCategory.Voxel)
                    {
                        AddVoxelTextures(item.voxelType);
                    }
                }
            }

            // Add any other voxel found inside Defaults
            VoxelDefinition [] vdd = Resources.LoadAll <VoxelDefinition> ("VoxelPlay/Defaults");
            for (int k = 0; k < vdd.Length; k++)
            {
                AddVoxelTextures(vdd [k]);
            }

            // Add any other voxel found inside World directory
            if (!string.IsNullOrEmpty(world.name))
            {
                vdd = Resources.LoadAll <VoxelDefinition> ("Worlds/" + world.name);
                for (int k = 0; k < vdd.Length; k++)
                {
                    AddVoxelTextures(vdd [k]);
                }

                // Add any other voxel found inside a resource directory with same name of world (if not placed into Worlds directory)
                vdd = Resources.LoadAll <VoxelDefinition> (world.name);
                for (int k = 0; k < vdd.Length; k++)
                {
                    AddVoxelTextures(vdd [k]);
                }
            }

            // Add any other voxel found inside a resource directory under the world definition asset
            if (!string.IsNullOrEmpty(world.resourceLocation))
            {
                vdd = Resources.LoadAll <VoxelDefinition> (world.resourceLocation);
                for (int k = 0; k < vdd.Length; k++)
                {
                    AddVoxelTextures(vdd [k]);
                }
            }

            // Add connected textures
            ConnectedTexture [] ctt = Resources.LoadAll <ConnectedTexture> ("");
            for (int k = 0; k < ctt.Length; k++)
            {
                ConnectedTexture ct = ctt [k];
                VoxelDefinition  vd = ctt [k].voxelDefinition;
                if (vd == null || vd.index == 0)
                {
                    continue;
                }
                for (int j = 0; j < ct.config.Length; j++)
                {
                    ct.config [j].textureIndex = AddTexture(ct.config [j].texture, null, null, null);
                }
                ct.Init();
            }

            // Add user provided voxels during playtime
            int count = sessionUserVoxels.Count;

            for (int k = 0; k < count; k++)
            {
                AddVoxelTextures(sessionUserVoxels [k]);
            }
            sessionUserVoxelsLastIndex = voxelDefinitionsCount - 1;

            // Add transparent voxel definitions for the see-through effect
            if (seeThrough)
            {
                int lastOne = voxelDefinitionsCount; // this loop will add voxels so end at the last regular voxel definition (don't process see-through versions)
                for (int k = 0; k < lastOne; k++)
                {
                    VoxelDefinition vd = voxelDefinitions [k];
                    if (vd.renderType == RenderType.CutoutCross)
                    {
                        vd.seeThroughMode = SeeThroughMode.FullyInvisible;
                    }
                    else
                    {
                        if (vd.seeThroughMode == SeeThroughMode.Transparency)
                        {
                            if (vd.renderType.supportsAlphaSeeThrough())
                            {
                                vd.seeThroughVoxelTempTransp = CreateSeeThroughVoxelDefinition(vd);
                            }
                            else
                            {
                                vd.seeThroughMode = SeeThroughMode.FullyInvisible;
                            }
                        }
                    }
                }
            }

            // Create array texture
            int textureCount = worldTextures.Count;

            if (textureCount > 0)
            {
                Texture2DArray pointFilterTextureArray = new Texture2DArray(textureSize, textureSize, textureCount, TextureFormat.ARGB32, hqFiltering);
                if (enableReliefMapping || !enableSmoothLighting)
                {
                    pointFilterTextureArray.wrapMode = TextureWrapMode.Repeat;
                }
                else
                {
                    pointFilterTextureArray.wrapMode = TextureWrapMode.Clamp;
                }
                pointFilterTextureArray.filterMode = hqFiltering ? FilterMode.Bilinear : FilterMode.Point;
                pointFilterTextureArray.mipMapBias = -mipMapBias;
                for (int k = 0; k < textureCount; k++)
                {
                    if (worldTextures [k].colorsAndEmission != null)
                    {
                        pointFilterTextureArray.SetPixels32(worldTextures [k].colorsAndEmission, k);
                    }
                    else if (worldTextures [k].normalsAndElevation != null)
                    {
                        pointFilterTextureArray.SetPixels32(worldTextures [k].normalsAndElevation, k);
                    }
                }
                worldTextures.Clear();

                pointFilterTextureArray.Apply(hqFiltering, true);

                // Assign textures to materials
                if (renderingMaterials != null)
                {
                    for (int k = 0; k < renderingMaterials.Length; k++)
                    {
                        if (renderingMaterials [k].usesTextureArray)
                        {
                            Material mat = renderingMaterials [k].material;
                            if (mat != null && mat.HasProperty("_MainTex"))
                            {
                                mat.SetTexture("_MainTex", pointFilterTextureArray);
                            }
                        }
                    }
                }
                matDynamicOpaque.SetTexture("_MainTex", pointFilterTextureArray);
                matDynamicCutout.SetTexture("_MainTex", pointFilterTextureArray);

                if (modelHighlightMat == null)
                {
                    modelHighlightMat = Instantiate <Material> (Resources.Load <Material> ("VoxelPlay/Materials/VP Highlight Model")) as Material;
                }
                modelHighlightMat.SetTexture("_MainTex", pointFilterTextureArray);
            }
        }