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; }
public static void kernel_V_Sin(Index pos, ArrayView <float> output, ArrayView <float> arr) { int x = pos.X; output[x] = GPUMath.Sin(arr[x]); }
public static void _V_Sin(Index size, ArrayView <float> output, ArrayView <float> v) { var x = size.X; output[x] = GPUMath.Sin(v[x]); }