static void NearHorizonKernel1(
            Index index,       // Horizon angle as integer
            int target_line,   // row within the 128 x 128 target patch
            int target_sample, // column
            int line_offset,
            int sample_offset,
            int points_rows,
            int points_columns,
            float d_min,
            float d_max,
            float d_step,
            ArrayView <float> points,
            ArrayView <float> matrices,
            ArrayView <float> horizon,
            ArrayView <float> test_floats)
        {
            //if (index == 0)
            //{
            //    var delme = 1;
            //}

            // Copy the matrix into registers
            var pos = (target_line * TerrainPatch.DefaultSize + target_sample) * 12;

            var row0x = matrices[pos++];
            var row1x = matrices[pos++];
            var row2x = matrices[pos++];
            var row3x = matrices[pos++];

            var row0y = matrices[pos++];
            var row1y = matrices[pos++];
            var row2y = matrices[pos++];
            var row3y = matrices[pos++];

            var row0z = matrices[pos++];
            var row1z = matrices[pos++];
            var row2z = matrices[pos++];
            var row3z = matrices[pos];

            // Work out the location of the central point in the point array
            float center_line   = target_line + line_offset;
            float center_sample = target_sample + sample_offset;

            var caster_line_max   = (float)points_rows - 1;
            var caster_sample_max = (float)points_columns - 1;

            // Work out the direction vector
            var ray_angle = 3.141592653589f * 2f * index / (TerrainPatch.NearHorizonOversample * Horizon.HorizonSamples);
            var ray_cos   = GPUMath.Cos(ray_angle);
            var ray_sin   = GPUMath.Sin(ray_angle);

            // Work out the direction in horizon space (the horizon offset).  This duplicates the calculation of the first point.
            // I'm duplicating code rather than refactoring, because there would be a lot of values to pass
            float azimuth_rad;
            {
                var d             = 1f;
                var caster_line   = center_line + ray_sin * d;
                var caster_sample = center_sample + ray_cos * d;

                var x1 = (int)caster_sample;  // Calculate the caster point by interpolating between four points from the points array
                var y1 = (int)caster_line;
                int x2 = x1 + 1;
                int y2 = y1 + 1;

                var q11_offset = 3 * (y1 * points_columns + x1);  // (y1, x1);
                var q11        = new Vector3(points[q11_offset], points[q11_offset + 1], points[q11_offset + 2]);

                var q12_offset = 3 * (y2 * points_columns + x1);  // (y2, x1);
                var q12        = new Vector3(points[q12_offset], points[q12_offset + 1], points[q12_offset + 2]);

                // First interpolation across rows (line)
                var q1_line = q11 + (caster_line - y1) * (q12 - q11);

                var q21_offset = 3 * (y1 * points_columns + x2);  // (y1, x2);
                var q21        = new Vector3(points[q21_offset], points[q21_offset + 1], points[q21_offset + 2]);

                var q22_offset = 3 * (y2 * points_columns + x2);  // (y2, x2);
                var q22        = new Vector3(points[q22_offset], points[q22_offset + 1], points[q22_offset + 2]);

                // Second interpolation across rows
                var q2_line = q21 + (caster_line - y1) * (q22 - q21);

                // Interpolate across samples
                var caster = q1_line + (caster_sample - x1) * (q2_line - q1_line);

                // Break out the coordinates
                var x_patch = caster.X;
                var y_patch = caster.Y;
                var z_patch = caster.Z;

                // Transform the point to the local frame
                var x = x_patch * row0x + y_patch * row1x + z_patch * row2x + row3x;
                var y = x_patch * row0y + y_patch * row1y + z_patch * row2y + row3y;
                var z = x_patch * row0z + y_patch * row1z + z_patch * row2z + row3z;

                // Adjust for solar array height (this is temporary, and I'm not sure we want this in the final version)
                z -= ObserverHeight;                            // meters

                azimuth_rad = GPUMath.Atan2(y, x) + GPUMath.PI; // [0,2PI]
            }

            var normalized_azimuth = (Horizon.HorizonSamples - 1) * azimuth_rad / (2d * Math.PI);  // range [0,1)
            var horizon_offset     = (int)(0.5d + normalized_azimuth);

            Debug.Assert(horizon_offset >= 0 && horizon_offset < Horizon.HorizonSamples);

            // index is which direction in [target_line,target_sample]'s horizon we're working on, but could be oversamples
            var horizon_index = (target_line * TerrainPatch.DefaultSize + target_sample) * Horizon.HorizonSamples + horizon_offset;
            var highest_slope = horizon[horizon_index];

            //test_floats[index] = ray_sin;

            for (var d = d_min; d <= d_max; d += d_step)
            {
                // Generate the location of the caster point in the points array
                var caster_line   = center_line + ray_sin * d;
                var caster_sample = center_sample + ray_cos * d;

                test_floats[index] = caster_sample;

                /*{
                 *  var idx = index == 2160 ? 7 : 11;
                 *  test_floats[idx] = d;
                 *  test_floats[idx + 1] = ray_angle;
                 *  test_floats[idx + 2] = caster_line - line_offset;
                 *  test_floats[idx + 3] = caster_sample - sample_offset;
                 * }*/

                if (caster_line < 1f || caster_line > caster_line_max || caster_sample < 1f || caster_sample > caster_sample_max)
                {
                    break;
                }

                // Calculate the caster point by interpolating between four points from the points array
                var x1 = (int)caster_sample;
                var y1 = (int)caster_line;
                int x2 = x1 + 1;
                int y2 = y1 + 1;

                var q11_offset = 3 * (y1 * points_columns + x1);  // (y1, x1);
                var q11        = new Vector3(points[q11_offset], points[q11_offset + 1], points[q11_offset + 2]);

                var q12_offset = 3 * (y2 * points_columns + x1);  // (y2, x1);
                var q12        = new Vector3(points[q12_offset], points[q12_offset + 1], points[q12_offset + 2]);

                // First interpolation across rows (line)
                var q1_line = q11 + (caster_line - y1) * (q12 - q11);

                var q21_offset = 3 * (y1 * points_columns + x2);  // (y1, x2);
                var q21        = new Vector3(points[q21_offset], points[q21_offset + 1], points[q21_offset + 2]);

                var q22_offset = 3 * (y2 * points_columns + x2);  // (y2, x2);
                var q22        = new Vector3(points[q22_offset], points[q22_offset + 1], points[q22_offset + 2]);

                // Second interpolation across rows
                var q2_line = q21 + (caster_line - y1) * (q22 - q21);

                // Interpolate across samples
                var caster = q1_line + (caster_sample - x1) * (q2_line - q1_line);

                // Break out the coordinates
                var x_patch = caster.X;
                var y_patch = caster.Y;
                var z_patch = caster.Z;

                // Transform the point to the local frame
                var x = x_patch * row0x + y_patch * row1x + z_patch * row2x + row3x;
                var y = x_patch * row0y + y_patch * row1y + z_patch * row2y + row3y;
                var z = x_patch * row0z + y_patch * row1z + z_patch * row2z + row3z;

                var alen  = GPUMath.Sqrt(x * x + y * y);
                var slope = z / alen;

                if (slope > highest_slope)
                {
                    highest_slope = slope;
                }

                /*if (target_line==0 && target_sample==0 && index == 0)
                 * {
                 *  test_floats[0] = slope;
                 *  test_floats[1] = x_patch;
                 *  test_floats[2] = y_patch;
                 *  test_floats[3] = z_patch;
                 *  test_floats[4] = x;
                 *  test_floats[5] = y;
                 *  test_floats[6] = z;
                 * }*/
            }

            horizon[horizon_index] = highest_slope;
        }
Esempio n. 2
0
        public static void kernel_V_Sin(Index pos, ArrayView <float> output, ArrayView <float> arr)
        {
            int x = pos.X;

            output[x] = GPUMath.Sin(arr[x]);
        }
Esempio n. 3
0
        public static void _V_Sin(Index size, ArrayView <float> output, ArrayView <float> v)
        {
            var x = size.X;

            output[x] = GPUMath.Sin(v[x]);
        }