예제 #1
0
        protected void Invalidate(TerrainPatch p)
        {
            var r = p.PixelBox(Transform);

            r.Inflate(2, 2);
            Invalidate(r);
        }
예제 #2
0
        static float[,] GetHeightMap(TerrainPatch[] Terrain)
        {
            float average = 23;

            float[,] height = new float[256, 256];
            for (int x = 0; x < 256; x++)
            {
                for (int y = 0; y < 256; y++)
                {
                    int patchX = x / 16;
                    int patchY = y / 16;

                    TerrainPatch patch = Terrain[patchY * 16 + patchX];
                    if (patch != null)
                    {
                        height[x, y] = average = patch.Data[(y % 16) * 16 + (x % 16)];
                    }
                    else
                    {
                        height[x, y] = average;
                    }
                }
            }
            return(height);
        }
        public void SaveTerrainRaw32(string path)
        {
            var patches = Client.Network.CurrentSim.Terrain;

            if (patches != null)
            {
                int count = 0;
                for (int i = 0; i < patches.Length; i++)
                {
                    if (patches[i] != null)
                    {
                        ++count;
                    }
                }

                Logger.Log(count + " terrain patches have been received for the current simulator", Helpers.LogLevel.Info);
            }
            else
            {
                Logger.Log("No terrain information received for the current simulator", Helpers.LogLevel.Info);
                return;
            }
            try
            {
                using (
                    FileStream stream = new FileStream(path, FileMode.Create,
                                                       FileAccess.Write))
                {
                    for (int y = 0; y < 256; y++)
                    {
                        for (int x = 0; x < 256; x++)
                        {
                            int xBlock = x / 16;
                            int yBlock = y / 16;
                            int xOff   = x - (xBlock * 16);
                            int yOff   = y - (yBlock * 16);

                            TerrainPatch patch = patches[yBlock * 16 + xBlock];
                            float        t     = 0f;

                            if (patch != null)
                            {
                                t = patch.Data[yOff * 16 + xOff];
                            }
                            else
                            {
                                Logger.Log(String.Format("Skipping missing patch at {0},{1}", xBlock, yBlock),
                                           Helpers.LogLevel.Warning);
                            }

                            stream.Write(BitConverter.GetBytes(t), 0, 4);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log("Failed saving terrain: " + ex.Message, Helpers.LogLevel.Error);
            }
        }
예제 #4
0
    /// <summary> Creates a CubeFace </summary>
    /// <param name="parent">Associated parent reference as a QuadTree sibling</param>
    /// <param name="pos">Position vector to render the cubeface at</param>
    /// <param name="left">The x axis of the plane</param>
    /// <param name="forward">The z axis of the plane</param>
    /// <param name="scale">The scale of the plane</param>
    /// <param name="size">The number of vertices in length/width to create (segments)</param>
    private void Initialize(TerrainPatch parent, Vector3 pos, Vector3 left, Vector3 forward, float scale)
    {
        pos.y         = terrain.GetHeightAt(pos.x + terrain.scale / 2, pos.z + terrain.scale / 2) * Terrain.heightScalar;
        this.bound    = new Bounds(pos, new Vector3(scale, scale, scale));
        this.parent   = parent;
        this.scale    = scale;
        this.center   = pos;
        this.position = pos;
        this.left     = left;
        this.forward  = forward;

        // Centre the plane!
        position -= left * (scale / 2);
        position -= forward * (scale / 2);

        gameObject          = new GameObject("TerrainPatch_" + scale + "_" + 2 + "_" + pos.ToString());
        gameObject.isStatic = true;
        gameObject.layer    = 8; // To Raycast neighbours

        material = new Material(Shader.Find("Standard"));
        filter   = gameObject.AddComponent <MeshFilter>();
        renderer = gameObject.AddComponent <MeshRenderer>();
        //collider = gameObject.AddComponent<MeshCollider>();


        // Ensure hierarchy
        if (parent != null)
        {
            gameObject.transform.parent = parent.gameObject.transform;
        }

        //Generate();
    }
예제 #5
0
        public TerrainPatch ToTerrainPatch()
        {
            var tp = TerrainPatch.FromId(Id);

            tp.Step = Step;
            return(tp);
        }
예제 #6
0
        internal static float[] MakeCPUMatrices(TerrainPatch target)
        {
            var cpu_matrixes_size = target.Height * target.Width * 12;
            var r      = new float[cpu_matrixes_size];
            var height = target.Height;
            var width  = target.Width;

            for (var l = 0; l < height; l++)
            {
                for (var s = 0; s < width; s++)
                {
                    var mat = target.Matrices[l][s];
                    var pos = (l * width + s) * 12;

                    r[pos++] = (float)mat.Row0.X;
                    r[pos++] = (float)mat.Row1.X;
                    r[pos++] = (float)mat.Row2.X;
                    r[pos++] = (float)mat.Row3.X;

                    r[pos++] = (float)mat.Row0.Y;
                    r[pos++] = (float)mat.Row1.Y;
                    r[pos++] = (float)mat.Row2.Y;
                    r[pos++] = (float)mat.Row3.Y;

                    r[pos++] = (float)mat.Row0.Z;
                    r[pos++] = (float)mat.Row1.Z;
                    r[pos++] = (float)mat.Row2.Z;
                    r[pos++] = (float)mat.Row3.Z;
                }
            }
            return(r);
        }
예제 #7
0
        private void Load(List <TerrainPatch> patches)
        {
            if (patches.Count < 1)
            {
                return;
            }
            var patchSize = TerrainPatch.DefaultSize;
            var ids       = patches.Select(p => p.Id).ToList();
            var minline   = ids.Min(p => p.Y);
            var maxline   = ids.Max(p => p.Y);
            var minsample = ids.Min(p => p.X);
            var maxsample = ids.Max(p => p.X);

            PatchBounds = new Rectangle(minsample, minline, maxsample - minsample + 1, maxline - minline + 1);
            _patchArray = new TerrainPatch[PatchBounds.Height, PatchBounds.Width];
            for (var line = 0; line < PatchBounds.Height; line++)
            {
                for (var sample = 0; sample < PatchBounds.Width; sample++)
                {
                    _patchArray[line, sample] = new TerrainPatch {
                        Line = (line + PatchBounds.Top) * patchSize, Sample = (sample + PatchBounds.Left) * patchSize, Height = patchSize, Width = patchSize, Step = 1
                    }
                }
            }
            ;
            pnlTiles.Size = new Size(PatchBounds.Width * patchSize, PatchBounds.Height * patchSize);
            _transform    = new DisplayTransform {
                OffsetX = -PatchBounds.Left * patchSize, OffsetY = -PatchBounds.Top * patchSize, Scale = 1f
            };
            pnlScroll.Invalidate();
            pnlTiles.Invalidate();
        }
예제 #8
0
        public override void Run()
        {
            base.Run();

            var patch = TerrainPatch.FromId(147, 72);

            Console.WriteLine(@"Generating safe havens");
            var safe_haven_gen = new SafeHavenGenerator {
                Region = patch.Bounds, WriteHorizons = false
            };

            safe_haven_gen.WriteSafeHavenGeotiffs(OutputPath);

            Console.WriteLine(@"Generating average Earth and average Sun patches");
            var(start, stop, step) = StudyInterval.SiteStudyPeriod.GetInterval();
            var gen = new TileLightingProductManager
            {
                //MainWindow = MainWindow,
                Selection               = patch.Bounds,
                IntervalStart           = start,
                IntervalStop            = stop,
                IntervalStep            = step,
                ObserverHeightInMeters  = 0,
                EarthMultipathThreshold = 2f,
                GenerateAverageSun      = true,
                GenerateAverageEarth    = true
            };

            gen.GenerateAverageSunEarthPatches();

            Console.WriteLine(@"Finished.");
        }
예제 #9
0
    /// <summary>
    /// Creates a terrain
    ///     using 6 planes normalized around the origin
    /// </summary>
    /// <param name="name">The terrain name (duh)</param>
    /// <param name="scale">The scale of the terrain (radius)</param>
    public Terrain(string name, float scale, Texture2D heightmap, Transform parent, float detailLevel, float minResolution)
    {
        this.scale         = scale;
        this.heightmap     = heightmap;
        this.detailLevel   = detailLevel;
        this.minResolution = minResolution;
        var hs = scale / 2;

        quadSize   = (int)scale + 1;
        quadMatrix = new int[quadSize * quadSize];
        for (int x = 0; x < quadSize; ++x)
        {
            for (int z = 0; z < quadSize; ++z)
            {
                quadMatrix[z * quadSize + x] = 1;
            }
        }

        // Chuck it into a single game object for neatness
        terrain = new GameObject(name);
        terrain.transform.parent = parent.transform;

        face = new TerrainPatch(new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1), scale, this);
        face.gameObject.transform.parent = terrain.transform;

        PropagateRoughness();
    }
예제 #10
0
    /// <summary>
    /// Turns a plane's vertices into a segment of a sphere
    ///  - Processes neighbour faces in order to remove gaps/tears
    /// </summary>
    /// <param name="face">The face in question (aint it an ugly one?)</param>
    private void FinalizeFace(TerrainPatch face)
    {
        if (face.finalized)
        {
            return;
        }

        var verts = face.mesh.vertices;

        for (int i = 0; i < verts.Length; i++)
        {
            //    //verts[i] = verts[i].normalized * (scale + noise(verts[i], 2, 1.7f, 0.1f, scale / size));
            //verts[i].y += noise(verts[i], 2, 1.7f, 0.1f, 10);
            float hs = scale / 2;
            //float u = (verts[i].x + hs) / scale;
            //float v = (verts[i].z + hs) / scale;
            //verts[i].y = heightmap.GetPixelBilinear(u, v).grayscale * 20;
            verts[i].y = GetHeightAt(verts[i].x + hs, verts[i].z + hs) * heightScalar;
        }

        face.mesh.vertices = verts;

        face.mesh.RecalculateNormals();
        face.mesh.RecalculateBounds();

        face.Texturize();

        face.filter.sharedMesh = face.mesh;
        //face.collider.sharedMesh = face.mesh;

        face.finalized = true;
    }
예제 #11
0
        void FillRangeLimit(TerrainPatch center)
        {
            var center_line   = center.Line;
            var center_sample = center.Sample;

            Debug.Assert(cpu_range_limit.Length == cpu_slope_size);
            var min = (double)(2 * TerrainPatch.DefaultSize);
            var max = (double)(TerrainPatch.DEM_size - 2 * TerrainPatch.DefaultSize);

            for (var i = 0; i < cpu_range_limit.Length; i++)
            {
                var ray_rad  = Math.PI * 2f * i / cpu_slope_size; // 0 deg in ME frame points toward the earth
                var ray_cos  = Math.Cos(ray_rad);                 // varies the line
                var ray_sin  = Math.Sin(ray_rad);                 // varies the sample
                var farthest = 0;
                for (var j = 0; j < cpu_range.Length; j++)
                {
                    var range       = cpu_range[j];
                    var caster_line = center_line + ray_sin * range;
                    if (caster_line < min || caster_line > max)
                    {
                        break;
                    }
                    var caster_sample = center_sample + ray_cos * range;
                    if (caster_sample < min || caster_sample > max)
                    {
                        break;
                    }
                    farthest = j;
                }
                cpu_range_limit[i] = farthest;
            }
        }
예제 #12
0
        public void GenerateRiseHeight(string path, Rectangle region)
        {
            var queue = TerrainPatch.EnumerateIds(TerrainPatch.CoveringIdRectangle(region)).Select(id => TerrainPatch.FromId(id)).ToList();
            var pairs = GenerateRiseHeightPatches(queue);
            var ary   = new float[region.Height, region.Width];

            var region_width  = region.Width;
            var region_height = region.Height;

            foreach (var(patch, data) in pairs)
            {
                var xoffset = patch.Sample - region.Left;
                var yoffset = patch.Line - region.Top;
                for (var row_src = 0; row_src < TerrainPatch.DefaultSize; row_src++)
                {
                    var row_dst = row_src + yoffset;
                    if (row_dst >= region_height || row_dst < 0)
                    {
                        continue;
                    }
                    for (var col_src = 0; col_src < TerrainPatch.DefaultSize; col_src++)
                    {
                        var col_dst = col_src + xoffset;
                        if (col_dst >= region_width || col_dst < 0)
                        {
                            continue;                                          // This can be faster if I don't clip per pixel.  Later.
                        }
                        ary[row_dst, col_dst] = data[row_src * TerrainPatch.DefaultSize + col_src];
                    }
                }
            }

            GeotiffHelper.WriteArrayAsGeotiff(ary, region, path);
        }
예제 #13
0
        public void GenerateHeightField(TerrainPatch patch)
        {
            using (var context = new Context())
            {
                AcceleratorId aid = Accelerator.Accelerators.Where(id => id.AcceleratorType == AcceleratorType.Cuda).FirstOrDefault();
                if (aid.AcceleratorType != AcceleratorType.Cuda)
                {
                    Console.WriteLine(@"There is no CUDA accelerator present.  Doing nothing.");
                    return;
                }
                using (var accelerator = Accelerator.Create(context, aid))
                    using (var gpu_dem = accelerator.Allocate <short>(ViperEnvironment.Terrain.Data.Length))
                        using (var gpu_range = accelerator.Allocate <float>(cpu_range.Length))
                            using (var gpu_slope = accelerator.Allocate <float>(cpu_slope.Length))
                                using (var gpu_rise = accelerator.Allocate <short>(TerrainPatch.DefaultSize * TerrainPatch.DefaultSize))
                                {
                                    gpu_dem.CopyFrom(ViperEnvironment.Terrain.Data, 0, 0, ViperEnvironment.Terrain.Data.Length);
                                    gpu_range.CopyFrom(cpu_range, 0, 0, cpu_range.Length);

                                    var launchDimension = new Index2(TerrainPatch.DefaultSize, TerrainPatch.DefaultSize);

                                    var kernel1 = accelerator.LoadStreamKernel <Index2, ArrayView <short>, ArrayView <float>, ArrayView <short>, int, int>(RiseKernel1);
                                }
            }
        }
        // Return all times from start to stop.  Also return the indexes of the times at which the earth elevation reaches a minima
        void GetLowEarthTimes(DateTime outer_start, DateTime outer_stop, out List <DateTime> all_times, out List <int> indices_of_minima_earth_elevation)
        {
            var center      = new Point(Region.Left + Region.Width / 2, Region.Top + Region.Height / 2);
            var centerPatch = ViperEnvironment.GetPatch(TerrainPatch.LineSampleToId(center));

            centerPatch.FillMatrices(ViperEnvironment.Terrain);

            // Generate the time / elevation pairs
            all_times = new List <DateTime>();
            for (var time = outer_start; time <= outer_stop; time += Step)
            {
                all_times.Add(time);
            }
            var earth_elevations = all_times.Select(t =>
            {
                centerPatch.GetAzEl(CSpice.EarthPosition(t), 0, 0, out float _, out float earth_elevation_rad);
                return(earth_elevation_rad);
            }).ToList();

            // Find minima
            indices_of_minima_earth_elevation = new List <int>();
            for (var i = 1; i < earth_elevations.Count - 1; i++)
            {
                if (Start <= all_times[i] && all_times[i] <= Stop && earth_elevations[i - 1] > earth_elevations[i] && earth_elevations[i] < earth_elevations[i + 1])
                {
                    indices_of_minima_earth_elevation.Add(i);
                }
            }
        }
예제 #15
0
        TerrainPatch GetCenterPatch()
        {
            var pt     = new Point(TerrainPatch.DEM_size / 2, TerrainPatch.DEM_size / 2);
            var center = TerrainPatch.FromLineSample(pt.Y, pt.X);

            center.FillMatrices(ViperEnvironment.Terrain);
            return(center);
        }
        /// <summary>
        /// Map over the fraction of the sun's disk visible times Cos(theta) - theta is the angle between the sun and normal
        /// </summary>
        /// <param name="line"></param>
        /// <param name="sample"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="step"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public bool MapOverSunContribution(int line, int sample, DateTime start, DateTime stop, TimeSpan step, Action <DateTime, float> action)
        {
            var id    = TerrainPatch.LineSampleToId(line, sample);
            var patch = GetPatch(id);

            if (patch == null)
            {
                return(false);
            }

            var cross = GetSurfaceNormal(line, sample);

            var y_offset = line - patch.Line;
            var x_offset = sample - patch.Sample;
            var mat      = patch.Matrices[y_offset][x_offset];
            var horizon  = patch.Horizons[y_offset][x_offset];

            if (!horizon.IsDegrees)
            {
                lock (horizon)
                    horizon.ConvertSlopeToDegrees();
            }

            var cache = SunVectorCache.GetSingleton();
            var temp  = new Vector3d();

            for (var time = start; time <= stop; time += step)
            {
                var sunvec = cache.SunPosition(time);
                TerrainPatch.Transform(ref sunvec, ref mat, ref temp);

                var sun_x       = temp[0];
                var sun_y       = temp[1];
                var sun_z       = temp[2];
                var azimuth_rad = Math.Atan2(sun_y, sun_x) + Math.PI;  // [0,2PI]
                var azimuth_deg = (float)(azimuth_rad * 180d / Math.PI);

                var alen          = Math.Sqrt(sun_x * sun_x + sun_y * sun_y);
                var slope         = sun_z / alen;
                var elevation_deg = ((float)Math.Atan(slope)) * 180f / 3.141592653589f;
                var sunfrac       = horizon.SunFraction2(azimuth_deg, elevation_deg);

                //if (line == 17522 && sample == 12388)
                //{
                //    Console.WriteLine($"{line},{sample}, time={time} elevation_deg={elevation_deg} sun={sunfrac}");
                //}

                sunvec.NormalizeFast();  // Normalize before calculating surface temp
                var dot         = Vector3d.Dot(sunvec, cross);
                var sun_contrib = dot < 0d ? 0d : sunfrac * dot;
                //if (sun_contrib > 0)
                //    Console.WriteLine(sun_contrib);
                action(time, (float)sun_contrib);
            }
            return(true);
        }
예제 #17
0
        public override void Run()
        {
            base.Run();
            var patch          = TerrainPatch.FromId(147, 72);
            var safe_haven_gen = new SafeHavenGenerator {
                Region = patch.Bounds, WriteHorizons = true
            };

            safe_haven_gen.WriteSafeHavenGeotiffs(OutputPath);
        }
예제 #18
0
        public void Test1()
        {
            To   = TerrainPatch.FromId(new Point(103, 138));
            From = TerrainPatch.FromId(new Point(103, 139));

            To.FillPointsAndMatrices(Terrain);
            From.FillPoints(Terrain);
            To.UpdateHorizonBugHunt(From);
            Console.WriteLine(@"Test1 finished.");
        }
예제 #19
0
        public void ExtendExistingPatches()
        {
            if (MaxSpread != 177)
            {
                throw new Exception($"Unexpected value of MaxSpread={MaxSpread}");
            }
            var filenames = (new DirectoryInfo(LunarHorizon.HorizonsRoot)).EnumerateFiles("*.bin").Select(fi => fi.FullName).ToList();

            foreach (var filename in filenames)
            {
                var patch     = TerrainPatch.ReadFrom(filename);
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                Console.WriteLine($"Starting [{patch.Line},{patch.Sample}] ...");
                patch.FillPointsAndMatrices(Terrain);
                try
                {
                    var far_field = new List <TerrainPatch>();
                    if (MapView != null)
                    {
                        MapView.ProcessingPatches = new List <TerrainPatch> {
                            patch
                        }
                    }
                    ;
                    var options = new ParallelOptions {
                        MaxDegreeOfParallelism = MaxDegreeOfParallelism
                    };
                    for (var i = 1; i < MaxSpread; i++)
                    {
                        var other1 = patch.SurroundingPatches(i).Where(p => !patch.ShadowCasters.Contains(p.Id)).ToList();
                        Parallel.ForEach(other1, options, o => o.FillPoints(Terrain));
                        var other2 = other1.Where(patch.IsOverHorizon).ToList();
                        if (MapView != null)
                        {
                            far_field.AddRange(other2);
                            MapView.FarPatches = far_field;
                            MapView.Invalidate();
                        }
                        Parallel.ForEach(other2, options, o => patch.UpdateHorizon(o));
                    }
                    patch.Write();
                    patch.InitializeHorizons();  // Unload the horizon data (100MB)
                    stopwatch.Stop();
                    var seconds_per_patch = far_field.Count == 0 ? 0f : (stopwatch.ElapsedMilliseconds / 1000f) / far_field.Count;
                    Console.WriteLine($"  Finished [{patch.Line},{patch.Sample}] time={stopwatch.Elapsed}.  sec/patch={seconds_per_patch}");
                }
                catch (Exception e1)
                {
                    Console.WriteLine(e1);
                    Console.WriteLine(e1.StackTrace);
                }
            }
        }
예제 #20
0
 void DisableRenderer(TerrainPatch patch)
 {
     patch.renderer.enabled = false;
     if (patch.tree != null)
     {
         for (int i = 0; i < patch.tree.Length; i++)
         {
             DisableRenderer(patch.tree[i]);
         }
     }
 }
예제 #21
0
        /// <summary>
        /// Build the terrain.
        /// </summary>
        public void BuildTerrain()
        {
            if (Heightmap == null)
            {
                return;
            }

            int width = Heightmap.Width;
            int depth = Heightmap.Depth;

            // Clear the terrain patches.
            Patches.Clear();

            // Compute the world matrix to place the terrain in the middle of the scene.
//            _world = Matrix.Identity;//Matrix.CreateTranslation(width*-0.5f, 0.0f, depth*-0.5f);

            // Create the terrain patches.
            const int patchWidth  = 16;
            const int patchDepth  = 16;
            int       patchCountX = width / patchWidth;
            int       patchCountZ = depth / patchDepth;

            PatchRows    = patchCountX;
            PatchColumns = patchCountZ;

            for (int x = 0; x < patchCountX; ++x)
            {
                for (int z = 0; z < patchCountZ; ++z)
                {
                    // It is necessary to use patch width and depths of +1 otherwise there will be
                    // gaps between the patches.. [0,15] and [16,31] have a gap of one unit!
                    var patch = new TerrainPatch(Game, Heightmap, World, patchWidth + 1, patchDepth + 1,
                                                 x * patchWidth, z * patchDepth);
//                        x*(patchWidth - 1), z*(patchDepth - 1));

                    Patches.Add(patch);
                }
            }

            // Find the minimum bounding box that covers all patches
            BoundingBox box = Patches[0].BoundingBox;

            foreach (TerrainPatch patch in Patches)
            {
                box = BoundingBox.CreateMerged(box, patch.BoundingBox);
            }

            BoundingBox = box;
            PatchCount  = Patches.Count;

            _vertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPositionNormalTexture.VertexElements);
        }
        private static void PopulatePatch(ICollection <Vector3> trees, TerrainPatch patch)
        {
            int treeDistanceZ = patch.Depth / 1;
            int treeDistanceX = patch.Width / 1;

            for (int z = 0; z < patch.Depth; z += treeDistanceZ)
            {
                for (int x = 0; x < patch.Width; x += treeDistanceX)
                {
                    int index = z * patch.Width + x;
                    trees.Add(patch.Geometry[index].Position);
                }
            }
        }
예제 #23
0
 public static bool EqualsMatrices(TerrainPatch a, TerrainPatch b)
 {
     for (var line = 0; line < TerrainPatch.DefaultSize; line++)
     {
         for (var sample = 0; sample < TerrainPatch.DefaultSize; sample++)
         {
             if (!a.Matrices[line][sample].Equals(b.Matrices[line][sample]))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
예제 #24
0
        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (lbPatches.SelectedItems.Count != 2)
            {
                MessageBox.Show("Please select exactly two patches");
                return;
            }
            var selected = lbPatches.SelectedItems;

            patch1 = new TerrainPatch();
            patch1.Load(Path.Combine(patch_dir, (selected[0] as string) + ".bin"));
            patch2 = new TerrainPatch();
            patch2.Load(Path.Combine(patch_dir, (selected[1] as string) + ".bin"));
        }
예제 #25
0
        Bitmap GetBitmap(TerrainPatch p)
        {
            switch (RenderMode)
            {
            case PatchRenderMode.AzEl:
                return(p.Horizons != null?p.GetShadows(azimuth_deg, elevation_deg) : p.GetHillshade());

            case PatchRenderMode.ShadowCaster:
                return(p.Horizons != null?p.GetShadows(ShadowCaster) : p.GetHillshade());

            case PatchRenderMode.Hillshade:
            default:
                return(p.GetHillshade());
            }
        }
예제 #26
0
        public override void Run()
        {
            base.Run();
            var patch = TerrainPatch.FromId(147, 72);
            var queue = new List <TerrainPatch> {
                patch
            };
            var gpu = new GPUHorizons {
                Terrain = ViperEnvironment.Terrain
            };

            Console.WriteLine("Running the queue");
            gpu.RunQueue(queue, unloadHorizons: false, writeHorizons: false);
            Console.WriteLine("Finished running the queue");
        }
예제 #27
0
        // maybe replace this with a transpiler that duplicates everything that is done to m_surfaceMapA?
        static void Postfix(TerrainPatch __instance)
        {
            if (Settings.TempDisable || Settings.EraseClipping.value)
            {
                return;
            }
#if DEBUG
            Debug.Log("resizing patch (" + __instance.m_x + "|" + __instance.m_z + ")");
#endif
            Texture2D original    = __instance.m_surfaceMapA;
            Texture2D replacement = SubstituteTextureManager.GetOrCreateSubstituteTexture(__instance);

            replacement.Resize(original.width, original.height, original.format, false);
            replacement.wrapMode   = original.wrapMode;
            replacement.filterMode = original.filterMode;
        }
예제 #28
0
        private void CopyPointsToCpuArray(TerrainPatch caster, Vector3d basePoint, float[] cpu_caster_points)
        {
            var ptr = 0;

            for (var line = 0; line < TerrainPatch.DefaultSize; line++)
            {
                var row = caster.Points[line];
                for (var sample = 0; sample < TerrainPatch.DefaultSize; sample++)
                {
                    var vec = row[sample] - basePoint;
                    cpu_caster_points[ptr++] = (float)vec.X;
                    cpu_caster_points[ptr++] = (float)vec.Y;
                    cpu_caster_points[ptr++] = (float)vec.Z;
                }
            }
        }
예제 #29
0
        void FillAzimuthElevation()
        {
            var       center_patch = GetCenterPatch();
            var       center_pt    = center_patch.PointInPatch(new Point(TerrainPatch.DEM_size / 2, TerrainPatch.DEM_size / 2));
            var       mat          = center_patch.Matrices[center_pt.Y][center_pt.X];
            const int per_degree   = 4;
            const int count        = 360 * per_degree;
            var       slope_array  = Enumerable.Range(0, count).Select(i => float.MinValue).ToArray();
            var       vec_array    = new PointF[count];
            var       stop         = TileLightingProductManager.MetonicCycleStop;
            var       step         = TileLightingProductManager.MetonicCycleStep;
            var       temp         = new Vector3d();

            for (var time = TileLightingProductManager.MetonicCycleStart; time <= stop; time += step)
            {
                var sun = CSpice.SunPosition(time);
                TerrainPatch.Transform(ref sun, ref mat, ref temp);
                var sun_x       = temp[0];
                var sun_y       = temp[1];
                var sun_z       = temp[2];
                var azimuth_rad = Math.Atan2(sun_y, sun_x) + Math.PI;  // [0,2PI]
                var azimuth_deg = azimuth_rad * 180d / Math.PI;
                var index       = (int)(azimuth_deg * per_degree);
                var alen        = Math.Sqrt(sun_x * sun_x + sun_y * sun_y);
                var slope       = (float)(sun_z / alen);
                if (slope > slope_array[index])
                {
                    slope_array[index] = slope;
                    vec_array[index]   = new PointF((float)(sun_x / alen), (float)(sun_y / alen));
                }
            }
            var slope_list = new List <float>();
            var vec_list   = new List <PointF>();

            for (var i = 0; i < slope_array.Length; i++)
            {
                var s = slope_array[i];
                if (s > float.MinValue)
                {
                    slope_list.Add(s);
                    vec_list.Add(vec_array[i]);
                }
            }
            cpu_slope    = slope_array.ToArray();
            cpu_vector_x = vec_list.Select(p => p.X).ToArray();
            cpu_vector_y = vec_list.Select(p => p.Y).ToArray();
        }
 public void GetHorizonBoxes(List <Point> ids, Action <List <Rectangle> > callback) =>
 Task.Run(() =>
 {
     var gpuProcessor = MainWindow.Processor as GPUProcessor;
     var rectangles   = new List <Rectangle>();
     foreach (var id in ids)
     {
         gpuProcessor.RunQueue(new List <TerrainPatch> {
             TerrainPatch.FromId(id)
         }, null, writeHorizons: false);
         if (gpuProcessor.BoundingBox.HasValue)
         {
             rectangles.Add(gpuProcessor.BoundingBox.Value);
         }
     }
     callback(rectangles);
 });