float terrain_height(terrain* ter, vec2 position) { vec2 amount = vec2_fmod(position, 1.0); vec2 top_left = vec2_new(floor(position.x), floor(position.y)); vec2 top_right = vec2_new(ceil(position.x), floor(position.y)); vec2 bot_left = vec2_new(floor(position.x), ceil(position.y)); vec2 bot_right = vec2_new(ceil(position.x), ceil(position.y)); top_left.x = clamp(top_left.x, 0, ter->width-1); top_left.y = clamp(top_left.y, 0, ter->height-1); top_right.x = clamp(top_right.x, 0, ter->width-1); top_right.y = clamp(top_right.y, 0, ter->height-1); bot_left.x = clamp(bot_left.x, 0, ter->width-1); bot_left.y = clamp(bot_left.y, 0, ter->height-1); bot_right.x = clamp(bot_right.x, 0, ter->width-1); bot_right.y = clamp(bot_right.y, 0, ter->height-1); float s0 = ter->heightmap[(int)top_left.x + (int)top_left.y * ter->width]; float s1 = ter->heightmap[(int)top_right.x + (int)top_right.y * ter->width]; float s2 = ter->heightmap[(int)bot_left.x + (int)bot_left.y * ter->width]; float s3 = ter->heightmap[(int)bot_right.x + (int)bot_right.y * ter->width]; return bilinear_interp(s1, s0, s3, s2, amount.x, amount.y); }
void DeformPSROIPooling(const T *in_data, const VecInt &in_shape, const T *roi_data, const T *trans_data, const VecInt &trans_shape, int num_rois, int output_dim, int group_size, int pooled_size, int part_size, int sample_per_part, float spatial_scale, float trans_std, bool no_trans, T *out_data) { int batch = in_shape[0]; int in_c = in_shape[1], in_h = in_shape[2], in_w = in_shape[3]; int in_num = in_c * in_h * in_w, out_num = output_dim * pooled_size * pooled_size; int num_classes = no_trans ? 1 : trans_shape[1] / 2; int channels_each_class = no_trans ? output_dim : output_dim / num_classes; for (int n = 0; n < num_rois; ++n) { int roi_offset = 5 * n; int roi_batch_id = roi_data[roi_offset]; float roi_start_w = Util::round(roi_data[roi_offset + 1]) * spatial_scale - 0.5f; float roi_start_h = Util::round(roi_data[roi_offset + 2]) * spatial_scale - 0.5f; float roi_end_w = (Util::round(roi_data[roi_offset + 3]) + 1) * spatial_scale - 0.5f; float roi_end_h = (Util::round(roi_data[roi_offset + 4]) + 1) * spatial_scale - 0.5f; CHECK_GE(roi_batch_id, 0); CHECK_LT(roi_batch_id, batch); float roi_height = std::max(roi_end_h - roi_start_h, 0.1f); float roi_width = std::max(roi_end_w - roi_start_w, 0.1f); float bin_size_h = roi_height / static_cast<float>(pooled_size); float bin_size_w = roi_width / static_cast<float>(pooled_size); float sub_bin_size_h = bin_size_h / static_cast<float>(sample_per_part); float sub_bin_size_w = bin_size_w / static_cast<float>(sample_per_part); const T *batch_in_data = in_data + roi_batch_id * in_num; T *batch_out_data = out_data + n * out_num; for (int c = 0; c < output_dim; ++c) { for (int ph = 0; ph < pooled_size; ++ph) { for (int pw = 0; pw < pooled_size; ++pw) { auto part_h = static_cast<int>( std::floor(static_cast<float>(ph) / pooled_size * part_size)); auto part_w = static_cast<int>( std::floor(static_cast<float>(pw) / pooled_size * part_size)); int class_id = c / channels_each_class; T trans_x = no_trans ? static_cast<T>(0) : trans_data[(((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w] * trans_std; T trans_y = no_trans ? static_cast<T>(0) : trans_data[(((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w] * trans_std; float hstart = ph * bin_size_h + roi_start_h + trans_y * roi_height; float wstart = pw * bin_size_w + roi_start_w + trans_x * roi_width; int gh = ph * group_size / pooled_size; int gw = pw * group_size / pooled_size; gh = std::min(std::max(gh, 0), group_size - 1); gw = std::min(std::max(gw, 0), group_size - 1); int count = 0; int c_in = (c * group_size + gh) * group_size + gw; auto sum_val = static_cast<T>(0); for (int ih = 0; ih < sample_per_part; ++ih) { for (int iw = 0; iw < sample_per_part; ++iw) { float w = wstart + iw * sub_bin_size_w; float h = hstart + ih * sub_bin_size_h; if (w < -0.5f || w > in_w - 0.5f || h < -0.5f || h > in_h - 0.5f) { continue; } w = std::min(std::max(w, 0.f), in_w - 1.f); h = std::min(std::max(h, 0.f), in_h - 1.f); sum_val += bilinear_interp(batch_in_data + c_in * in_h * in_w, w, h, in_w, in_h); count++; } } int pool_index = (c * pooled_size + ph) * pooled_size + pw; batch_out_data[pool_index] = count == 0 ? T(0) : sum_val / count; } } } } }
static image* perlin_noise_generate(int x_size, int y_size, int octaves) { unsigned char* data = malloc(sizeof(char) * x_size * y_size); int i, x, y; /* Clear data to average */ for(x = 0; x < x_size; x++) for(y = 0; y < y_size; y++) { data[x + (y * x_size)] = 128; } srand(time(NULL)); debug("Generating perlin noise."); for(i = 0; i < octaves; i++ ) { float wavelength = pow( 2, i); float amplitude = pow( 0.5, octaves-i ); vec2 seed = vec2_new(rand(),rand()); debug("Octave: %i Wavelength: %f Amplitude: %f", i, wavelength, amplitude); for(x = 0; x < x_size; x++) for(y = 0; y < y_size; y++) { /* Four positions are required for tiling behaviour */ vec2 pos, pos_x, pos_y, pos_xy; pos = vec2_div( vec2_new(x, y) , wavelength ); pos_x = vec2_div( vec2_new(x - x_size, y) , wavelength ); pos_y = vec2_div( vec2_new(x, y - y_size) , wavelength ); pos_xy = vec2_div( vec2_new(x - x_size, y - y_size) , wavelength ); pos = vec2_add( pos, seed ); pos_x = vec2_add( pos_x, seed ); pos_y = vec2_add( pos_y, seed ); pos_xy = vec2_add( pos_xy, seed ); float val = perlin_noise2D(pos) * amplitude; float val_x = perlin_noise2D(pos_x) * amplitude; float val_y = perlin_noise2D(pos_y) * amplitude; float val_xy = perlin_noise2D(pos_xy) * amplitude; val = bilinear_interp(val_x, val, val_xy, val_y, (float)x/x_size, (float)y/y_size); data[x + (y * x_size)] += val * 128; } } unsigned char* image_data = malloc(sizeof(char) * 4 * x_size * y_size); for(x = 0; x < x_size; x++) for(y = 0; y < y_size; y++) { int amount = data[x + y * x_size]; image_data[x * 4 + y * x_size * 4 + 0] = amount; image_data[x * 4 + y * x_size * 4 + 1] = amount; image_data[x * 4 + y * x_size * 4 + 2] = amount; image_data[x * 4 + y * x_size * 4 + 3] = 255; } free(data); return image_new(x_size, y_size, image_data); }