Exemplo n.º 1
0
            public void OnGUI(Layout layout, bool selected, int num, object parent)
            {
                                #if VEGETATION_STUDIO_PRO
                VSProObjectsOutput   vsOut   = (VSProObjectsOutput)parent;
                VegetationPackagePro package = vsOut.package;                  //(VegetationPackagePro)vsOut.serializedPackage;
                VegetationSystemPro  system  = GameObject.FindObjectOfType <VegetationSystemPro>();
                Layer layer = vsOut.baseLayers[num];

                layout.margin = 20; layout.rightMargin = 5;
                layout.Par(20);

                input.DrawIcon(layout);

                if (package != null)
                {
                    int itemInfoIndex = package.VegetationInfoList.FindIndex(i => i.VegetationItemID == layer.id);
                    VegetationItemInfoPro itemInfo = itemInfoIndex >= 0 ? package.VegetationInfoList[itemInfoIndex] : null;

                    Texture2D icon = null;
                    if (itemInfo != null)
                    {
                                                #if UNITY_EDITOR
                        if (itemInfo.PrefabType == VegetationPrefabType.Mesh)
                        {
                            icon = AssetPreviewCache.GetAssetPreview(itemInfo.VegetationPrefab);
                        }
                        else
                        {
                            icon = AssetPreviewCache.GetAssetPreview(itemInfo.VegetationTexture);
                        }
                                                #endif
                    }
                    layout.Icon(icon, rect: layout.Inset(20), frame: true, alphaBlend: false);
                    layout.Inset(10);

                    itemInfoIndex = layout.Popup(itemInfoIndex, objectNames, rect: layout.Inset(layout.field.width - 20 - 45));
                    if (itemInfoIndex >= 0)
                    {
                        layer.id = package.VegetationInfoList[itemInfoIndex].VegetationItemID;
                    }
                }

                if (selected)
                {
                    layout.Toggle(ref relativeHeight, "Relative Height");
                    layout.Toggle(ref rotate, "Rotate");
                    layout.Toggle(ref takeTerrainNormal, "Incline by Terrain");
                    layout.Par(); layout.Toggle(ref scale, "Scale", rect: layout.Inset(60));
                    layout.disabled = !scale;
                    layout.Toggle(ref scaleY, rect: layout.Inset(18)); layout.Label("Y only", rect: layout.Inset(45));                     //if (layout.lastChange) scaleU = false;
                    layout.disabled = false;
                }
                                #endif
            }
Exemplo n.º 2
0
        public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null)
        {
            if (stop != null && stop(0))
            {
                return;
            }

            Noise noise = new Noise(12345, permutationCount: 128);            //to pick objects based on biome

            //find all of the biome masks - they will be used to determine object probability
            List <TupleSet <VSProObjectsOutput, Matrix> > allGensMasks = new List <TupleSet <VSProObjectsOutput, Matrix> >();

            foreach (VSProObjectsOutput gen in gens.GeneratorsOfType <VSProObjectsOutput>(onlyEnabled: true, checkBiomes: true))
            {
                Matrix biomeMask = null;
                if (gen.biome != null)
                {
                    object biomeMaskObj = gen.biome.mask.GetObject(results);
                    if (biomeMaskObj == null)
                    {
                        continue;                                           //adding nothing if biome has no mask
                    }
                    biomeMask = (Matrix)biomeMaskObj;
                    if (biomeMask == null)
                    {
                        continue;
                    }
                    if (biomeMask.IsEmpty())
                    {
                        continue;                                          //optimizing empty biomes
                    }
                }

                allGensMasks.Add(new TupleSet <VSProObjectsOutput, Matrix>(gen, biomeMask));
            }
            int allGensMasksCount = allGensMasks.Count;

            //biome rect to find array pos faster
            CoordRect biomeRect = new CoordRect();

            for (int g = 0; g < allGensMasksCount; g++)
            {
                if (allGensMasks[g].item2 != null)
                {
                    biomeRect = allGensMasks[g].item2.rect; break;
                }
            }

            //prepare biome mask values stack to re-use it to find per-coord biome
            float[] biomeVals = new float[allGensMasksCount];             //+1 for not using any object at all

            //preparing output
            Dictionary <string, List <ObjectPool.Transition> > transitions = new Dictionary <string, List <ObjectPool.Transition> >();

            //iterating all gens
            for (int g = 0; g < allGensMasksCount; g++)
            {
                VSProObjectsOutput gen = allGensMasks[g].item1;

                //iterating in layers
                for (int b = 0; b < gen.baseLayers.Length; b++)
                {
                    if (stop != null && stop(0))
                    {
                        return;                                            //checking stop before reading output
                    }
                    Layer layer = gen.baseLayers[b];

                    //loading objects from input
                    SpatialHash hash = (SpatialHash)gen.baseLayers[b].input.GetObject(results);
                    if (hash == null)
                    {
                        continue;
                    }

                    //finding/creating proper transitions list
                    List <ObjectPool.Transition> transitionsList;
                    if (!transitions.ContainsKey(layer.id))
                    {
                        transitionsList = new List <ObjectPool.Transition>(); transitions.Add(layer.id, transitionsList);
                    }
                    else
                    {
                        transitionsList = transitions[layer.id];
                    }

                    //filling instances (no need to check/add key in multidict)
                    foreach (SpatialObject obj in hash.AllObjs())
                    {
                        //blend biomes - calling continue if improper biome
                        if (biomeBlendType == BiomeBlendType.Sharp)
                        {
                            float biomeVal = 1;
                            if (allGensMasks[g].item2 != null)
                            {
                                biomeVal = allGensMasks[g].item2[obj.pos];
                            }
                            if (biomeVal < 0.5f)
                            {
                                continue;
                            }
                        }
                        else if (biomeBlendType == BiomeBlendType.AdditiveRandom)
                        {
                            float biomeVal = 1;
                            if (allGensMasks[g].item2 != null)
                            {
                                biomeVal = allGensMasks[g].item2[obj.pos];
                            }

                            float rnd = noise.Random((int)obj.pos.x, (int)obj.pos.y);

                            if (biomeVal > 0.5f)
                            {
                                rnd = 1 - rnd;
                            }

                            if (biomeVal < rnd)
                            {
                                continue;
                            }
                        }
                        else if (biomeBlendType == BiomeBlendType.NormalizedRandom)
                        {
                            //filling biome masks values
                            int pos = biomeRect.GetPos(obj.pos);

                            for (int i = 0; i < allGensMasksCount; i++)
                            {
                                if (allGensMasks[i].item2 != null)
                                {
                                    biomeVals[i] = allGensMasks[i].item2.array[pos];
                                }
                                else
                                {
                                    biomeVals[i] = 1;
                                }
                            }

                            //calculate normalized sum
                            float sum = 0;
                            for (int i = 0; i < biomeVals.Length; i++)
                            {
                                sum += biomeVals[i];
                            }
                            if (sum > 1)                             //note that if sum is <1 usedBiomeNum can exceed total number of biomes - it means that none object is used here
                            {
                                for (int i = 0; i < biomeVals.Length; i++)
                                {
                                    biomeVals[i] = biomeVals[i] / sum;
                                }
                            }

                            //finding used biome num
                            float rnd          = noise.Random((int)obj.pos.x, (int)obj.pos.y);
                            int   usedBiomeNum = biomeVals.Length;                           //none biome by default
                            sum = 0;
                            for (int i = 0; i < biomeVals.Length; i++)
                            {
                                sum += biomeVals[i];
                                if (sum > rnd)
                                {
                                    usedBiomeNum = i; break;
                                }
                            }

                            //disable object using biome mask
                            if (usedBiomeNum != g)
                            {
                                continue;
                            }
                        }
                        //scale mode is applied a bit later


                        //flooring
                        float terrainHeight = 0;
                        if (layer.relativeHeight && results.heights != null)                         //if checbox enabled and heights exist (at least one height generator is in the graph)
                        {
                            terrainHeight = results.heights.GetInterpolated(obj.pos.x, obj.pos.y);
                        }
                        if (terrainHeight > 1)
                        {
                            terrainHeight = 1;
                        }


                        //world-space object position
                        Vector3 position = new Vector3(
                            (obj.pos.x) / hash.size * terrainSize.dimensions,                              // relative (0-1) position * terrain dimension
                            (obj.height + terrainHeight) * terrainSize.height,
                            (obj.pos.y) / hash.size * terrainSize.dimensions);
                        position += MapMagic.position;

                        //rotation + taking terrain normal
                        Quaternion rotation;
                        float      objRotation = layer.rotate ? obj.rotation % 360 : 0;
                        if (layer.takeTerrainNormal)
                        {
                            Vector3 terrainNormal = GetTerrainNormal(obj.pos.x, obj.pos.y, results.heights, terrainSize.height, terrainSize.pixelSize);
                            Vector3 sideVector    = new Vector3(Mathf.Sin((obj.rotation + 90) * Mathf.Deg2Rad), 0, Mathf.Cos((obj.rotation + 90) * Mathf.Deg2Rad));
                            Vector3 frontVector   = Vector3.Cross(sideVector, terrainNormal);
                            rotation = Quaternion.LookRotation(frontVector, terrainNormal);
                        }
                        else
                        {
                            rotation = objRotation.EulerToQuat();
                        }

                        //scale + biome scale mode
                        Vector3 scale = layer.scale ? new Vector3(layer.scaleY ? 1 : obj.size, obj.size, layer.scaleY ? 1 : obj.size) : Vector3.one;

                        if (biomeBlendType == BiomeBlendType.Scale)
                        {
                            float biomeVal = 1;
                            if (allGensMasks[g].item2 != null)
                            {
                                biomeVal = allGensMasks[g].item2[obj.pos];
                            }
                            if (biomeVal < 0.001f)
                            {
                                continue;
                            }
                            scale *= biomeVal;
                        }

                        transitionsList.Add(new ObjectPool.Transition()
                        {
                            pos = position, rotation = rotation, scale = scale
                        });
                    }
                }
            }

            //queue apply
            if (stop != null && stop(0))
            {
                return;
            }
            results.apply.CheckAdd(typeof(VSProObjectsOutput), transitions, replace: true);
        }