示例#1
0
        public static void calculateMountainDistance(int seed, DualMesh mesh, int[] peak_t, Float spacing, Float jaggedness, NativeArray <Float> t_distance)
        {
            int randIndex = 0;

            for (var i = 0; i < t_distance.Length; ++i)
            {
                t_distance[i] = -1f;
            }

            var queue_t = new List <int>(peak_t);

            for (var i = 0; i < queue_t.Count; i++)
            {
                var current_t = queue_t[i];
                for (var j = 0; j < 3; j++)
                {
                    var s          = 3 * current_t + j;
                    var neighbor_t = mesh.s_outer_t(s);
                    if (t_distance[neighbor_t] == -1f)
                    {
                        var rf1       = Rander.randFloat(seed, randIndex++);
                        var rf2       = Rander.randFloat(seed, randIndex++);
                        var increment = spacing * (1 + jaggedness * (rf1 - rf2));
                        t_distance[neighbor_t] = t_distance[current_t] + increment;
                        queue_t.Add(neighbor_t);
                    }
                }
            }
        }
示例#2
0
        /**********************************************************************
         * Plates
         */
        static HashSet <int> pickRandomRegions(DualMesh mesh, int N, int seed)
        {
            var randInt    = Rander.makeRandInt(seed);
            var numRegions = mesh.numRegions;

            var chosen_r = new HashSet <int>();

            while (chosen_r.Count < N && chosen_r.Count < numRegions)
            {
                chosen_r.Add(randInt(numRegions));
            }
            return(chosen_r);
        }
示例#3
0
        private static void assignTriangleCenters(DualMesh mesh, NativeArray <double> r_xyz, NativeArray <double> t_xyz)
        {
            var numTriangles = mesh.numTriangles;
            var _r_xyz       = (double *)NativeArrayUnsafeUtility.GetUnsafePtr(r_xyz);
            var _t_xyz       = (double *)NativeArrayUnsafeUtility.GetUnsafePtr(t_xyz);

            Action <int> action = t =>
            {
                int a      = mesh.s_begin_r(3 * t + 0),
                         b = mesh.s_begin_r(3 * t + 1),
                         c = mesh.s_begin_r(3 * t + 2);
                CentroidOfTriangle(_r_xyz, a, b, c, _t_xyz, t);
            };

            //for (var t = 0; t < numTriangles; t++) action(t);
            Parallel.For(0, numTriangles, action);
        }
示例#4
0
        public _MapJobs(DualMesh.Graph graph, short[] peaks_index, Float spacing)
        {
            mesh     = new DualMesh(graph);
            riverTex = RiverTexture.createDefault();

            peaks_t = createPeaks(peaks_index, mesh.numBoundaryRegions);

            config = new Config()
            {
                seed            = -1,
                island          = -1,
                mountain_jagged = -1,
                wind_angle_deg  = -1,
            };

            elevation = new NativeArray <Float>(CANVAS_SIZE * CANVAS_SIZE, Allocator.Persistent);
            preNoise  = new PreNoise();

            t_elevation         = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);
            t_mountain_distance = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);

            r_elevation = new NativeArray <Float>(mesh.numRegions, Allocator.Persistent);

            r_wind_sort  = new NativeArray <Float>(mesh.numRegions, Allocator.Persistent);
            wind_order_r = new NativeArray <int>(mesh.numRegions, Allocator.Persistent);
            r_rainfall   = new NativeArray <Float>(mesh.numRegions, Allocator.Persistent);
            r_humidity   = new NativeArray <Float>(mesh.numRegions, Allocator.Persistent);
            t_moisture   = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);

            order_t       = new NativeArray <int>(mesh.numTriangles + 1, Allocator.Persistent);
            t_downslope_s = new NativeArray <int>(mesh.numTriangles, Allocator.Persistent);
            t_flow        = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);
            s_flow        = new NativeArray <Float>(mesh.numSides, Allocator.Persistent);

            rivers_v3 = new NativeArray <Vector3>(mesh.numSides, Allocator.Persistent);
            rivers_uv = new NativeArray <Vector2>(mesh.numSides, Allocator.Persistent);
            land_v3   = new NativeArray <Vector3>(mesh.numRegions + mesh.numTriangles, Allocator.Persistent);
            land_uv   = new NativeArray <Vector2>(mesh.numRegions + mesh.numTriangles, Allocator.Persistent);
            land_i    = new NativeArray <int>(mesh.numSolidSides * 3, Allocator.Persistent);
        }
示例#5
0
        /* Distance from any point in seeds_r to all other points, but
         * don't go past any point in stop_r */
        static Float[] assignDistanceField(DualMesh mesh, HashSet <int> seeds_r, HashSet <int> stop_r, int seed = 123)
        {
            var randInt    = Rander.makeRandInt(seed);
            var numRegions = mesh.numRegions;
            var r_distance = new Float[numRegions];

            for (int i = 0; i < numRegions; ++i)
            {
                r_distance[i] = Float.PositiveInfinity;
            }

            var queue = new List <int>();

            foreach (var r in seeds_r)
            {
                queue.Add(r);
                r_distance[r] = 0;
            }

            /* Random search adapted from breadth first search */
            for (var queue_out = 0; queue_out < queue.Count; queue_out++)
            {
                var pos       = queue_out + randInt(queue.Count - queue_out);
                var current_r = queue[pos];
                queue[pos] = queue[queue_out];
                var out_r = mesh.r_circulate_r(current_r);
                foreach (var neighbor_r in out_r)
                {
                    if (r_distance[neighbor_r] == Float.PositiveInfinity && !stop_r.Contains(neighbor_r))
                    {
                        r_distance[neighbor_r] = r_distance[current_r] + 1;
                        queue.Add(neighbor_r);
                    }
                }
            }
            return(r_distance);
            // TODO: possible enhancement: keep track of which seed is closest
            // to this point, so that we can assign variable mountain/ocean
            // elevation to each seed instead of them always being +1/-1
        }
示例#6
0
        void generateMesh(int N, int P, Float jitter, int seed)
        {
            if (mesh != null)
            {
                disposeMesh();
            }

            // 噪音只初始化一次就好
            if (simplex == null)
            {
                simplex = new SimplexNoise(seed);
            }

            DualMesh      m;
            List <double> d;

            DualMesh.makeSphere(N, jitter, seed, out m, out d);

            mesh  = m;
            r_xyz = new NativeArray <double>(d.ToArray(), Allocator.Persistent);
            t_xyz = new NativeArray <double>(mesh.numSides, Allocator.Persistent);
            assignTriangleCenters(mesh, r_xyz, t_xyz);

            r_elevation = new NativeArray <Float>(mesh.numRegions, Allocator.Persistent);
            r_moisture  = new NativeArray <Float>(mesh.numRegions, Allocator.Persistent);
            t_elevation = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);
            t_moisture  = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);

            t_downflow_s = new NativeArray <int>(mesh.numTriangles, Allocator.Persistent);
            // order_t[0] 保存个数
            order_t = new NativeArray <int>(mesh.numTriangles + 1, Allocator.Persistent);
            t_flow  = new NativeArray <Float>(mesh.numTriangles, Allocator.Persistent);
            // numSides = numTriangles * 3
            s_flow = new NativeArray <Float>(mesh.numSides, Allocator.Persistent);

            r_plate   = new NativeArray <int>(mesh.numRegions, Allocator.Persistent);
            plate_vec = new NativeArray <Vector3>(mesh.numRegions, Allocator.Persistent);

            Debug.Log($"generateMesh N:{N} P:{P} jitter:{jitter} seed:{seed} region:{mesh.numRegions} tri:{mesh.numTriangles}");
        }
示例#7
0
    public static void makeSphere(int N, double jitter, int seed, out DualMesh mesh, out List <double> d)
    {
        var latlong = generateFibonacciSphere(N, jitter, seed);
        //DebugHelper.SaveArray("generateFibonacciSphere.txt", latlong);
        var r_xyz = new List <double>();

        for (var r = 0; r < latlong.Count / 2; r++)
        {
            pushCartesianFromSpherical(r_xyz, latlong[2 * r], latlong[2 * r + 1]);
        }

        var r_xy = stereographicProjection(r_xyz);
        //DebugHelper.SaveArray("stereographicProjection.txt", r_xy);
        var delaunay = new Delaunator(r_xy.ToArray());

        /* TODO: rotate an existing point into this spot instead of creating one */
        r_xyz.AddRange(new double[] { 0, 0, 1 });
        addSouthPoleToMesh(r_xyz.Count / 3 - 1, delaunay);

        var dummy_r_vertex = new Float2[N + 1];

        dummy_r_vertex[0] = new Float2(0, 0);
        for (var i = 1; i < N + 1; i++)
        {
            dummy_r_vertex[i] = dummy_r_vertex[0];
        }

        mesh = new DualMesh(new Graph()
        {
            numBoundaryRegions = 0,
            numSolidSides      = delaunay.triangles.Length,
            _r_vertex          = dummy_r_vertex,
            _triangles         = delaunay.triangles,
            _halfedges         = delaunay.halfedges,
        });
        d = r_xyz;
    }
示例#8
0
        static HashSet <int> generatePlates(
            DualMesh mesh,
            NativeArray <double> r_xyz,
            int P, int N, int seed,
            /** output */
            NativeArray <int> r_plate,
            NativeArray <Vector3> plate_vec
            )
        {
            //r_plate.fill(-1);
            for (var i = 0; i < r_plate.Length; ++i)
            {
                r_plate[i] = -1;
            }

            var plate_r = pickRandomRegions(mesh, Math.Min(P, N), seed);
            var queue   = new List <int>(plate_r);

            foreach (var r in queue)
            {
                r_plate[r] = r;
            }

            var randInt = Rander.makeRandInt(seed);

            /* In Breadth First Search (BFS) the queue will be all elements in
             * queue[queue_out ... queue.length-1]. Pushing onto the queue
             * adds an element to the end, increasing queue.length. Popping
             * from the queue removes an element from the beginning by
             * increasing queue_out.
             *
             * To add variety, use a random search instead of a breadth first
             * search. The frontier of elements to be expanded is still
             * queue[queue_out ... queue.length-1], but pick a random element
             * to pop instead of the earliest one. Do this by swapping
             * queue[pos] and queue[queue_out].
             */
            for (var queue_out = 0; queue_out < queue.Count; queue_out++)
            {
                var pos       = queue_out + randInt(queue.Count - queue_out);
                var current_r = queue[pos];
                queue[pos] = queue[queue_out];
                var out_r = mesh.r_circulate_r(current_r);
                foreach (var neighbor_r in out_r)
                {
                    if (r_plate[neighbor_r] == -1)
                    {
                        r_plate[neighbor_r] = r_plate[current_r];
                        queue.Add(neighbor_r);
                    }
                }
            }
            //DebugHelper.SaveArray("plate_r.txt", plate_r);
            //DebugHelper.SaveArray("queue.txt", queue);

            Vector3 xyz(int i)
            {
                return(new Vector3((float)r_xyz[i + 0], (float)r_xyz[i + 1], (float)r_xyz[i + 2]));
            }

            // Assign a random movement vector for each plate
            foreach (var center_r in plate_r)
            {
                var     neighbor_r = mesh.r_circulate_r(center_r)[0];
                Vector3 p0         = xyz(3 * center_r),
                        p1         = xyz(3 * neighbor_r);
                plate_vec[center_r] = (p1 - p0).normalized;
                //Debug.Log($"{center_r}, {neighbor_r} {plate_vec[center_r].x},{plate_vec[center_r].y},{plate_vec[center_r].z}");
            }

            return(plate_r);
        }