コード例 #1
0
        public override void Generate(TileData data, StopToken stop)
        {
            if (!enabled)
            {
                return;
            }
            MatrixWorld probMatrix = data.ReadInletProduct(this);

            if (factor < float.Epsilon)
            {
                factor = 1;
            }

            Noise random = new Noise(data.random, seed);

            float square = data.area.active.worldSize.x * data.area.active.worldSize.z; //note using the real size, density should not depend on margins
            float count  = square * (density / 1000000);                                //number of items per terrain

            PosTab posTab = new PosTab((Vector3)data.area.full.worldPos, (Vector3)data.area.full.worldSize * factor, 16);

            RandomScatter((int)count, uniformity, (Vector3)data.area.full.worldPos, (Vector3)data.area.full.worldSize * factor, posTab, random, probMatrix, stop: null);
            TransitionsList transitions = posTab.ToTransitionsList();



            data.StoreProduct(this, transitions);
        }
コード例 #2
0
        public static void RandomScatter(int count, float uniformity, Vector3 offset, Vector3 size, PosTab posTab, Noise rnd, MatrixWorld prob, StopToken stop = null)
        {
            //int candidatesNum = (int)(uniformity*100);

            int candidatesNum = 100;

            if (candidatesNum < 1)
            {
                candidatesNum = 1;
            }

            for (int i = 0; i < count; i++)
            {
                if (stop != null && stop.stop)
                {
                    return;
                }

                float bestCandidateX = 0;
                float bestCandidateZ = 0;
                float bestDist       = 0;

                for (int c = 0; c < candidatesNum; c++)
                {
                    float candidateX = (offset.x + 1) + (rnd.Random((int)posTab.pos.x, (int)posTab.pos.z, i * candidatesNum + c, 0) * (size.x - 2.01f));           //TODO: do not use pos since it changes between preview/full
                    float candidateZ = (offset.z + 1) + (rnd.Random((int)posTab.pos.x, (int)posTab.pos.z, i * candidatesNum + c, 1) * (size.z - 2.01f));

                    //checking if candidate is the furthest one
                    Transition closest = posTab.Closest(candidateX, candidateZ, minDist: 0.001f);
                    float      dist    = (closest.pos.x - candidateX) * (closest.pos.x - candidateX) + (closest.pos.z - candidateZ) * (closest.pos.z - candidateZ);

                    //distance to the edge
                    float bd = (candidateX - offset.x) * 2; if (bd * bd < dist)
                    {
                        dist = bd * bd;
                    }
                    bd = (candidateZ - offset.z) * 2; if (bd * bd < dist)
                    {
                        dist = bd * bd;
                    }
                    bd = (offset.x + size.x - candidateX) * 2; if (bd * bd < dist)
                    {
                        dist = bd * bd;
                    }
                    bd = (offset.z + size.z - candidateZ) * 2; if (bd * bd < dist)
                    {
                        dist = bd * bd;
                    }

                    //probability
                    if (prob != null)
                    {
                        float probValue = prob.GetWorldInterpolatedValue(candidateX, candidateZ);
                        dist *= probValue;
                    }

                    if (dist > bestDist)
                    {
                        bestDist = dist; bestCandidateX = candidateX; bestCandidateZ = candidateZ;
                    }
                }

                if (bestDist > 0.001f)               //adding only if some suitable candidate found
                {
                    Transition trs = new Transition(bestCandidateX, bestCandidateZ);
                    posTab.Add(trs);
                }
            }
            posTab.Flush();
        }