void cTerrainGen2D::OverlaySlopes(double delta_range, double delta_min, double delta_max, double init_slope, int beg_idx, int end_idx, cRand& rand, std::vector<float>& out_data) { double curr_slope = init_slope; double curr_delta_h = 0; assert(beg_idx < out_data.size()); assert(end_idx <= out_data.size()); assert(delta_min < delta_max); double delta_mean = 0.5 * (delta_min + delta_max); double delta_diff = 0.5 * (delta_max - delta_min); for (int i = beg_idx; i < end_idx; ++i) { const double w = 0.1; double delta = rand.RandDouble(0, delta_range); double sign_rand = rand.RandDouble(-1, 1); double sign_threshold = (curr_slope - delta_mean) / delta_diff; bool neg = sign_rand < sign_threshold; delta = (neg) ? -delta : delta; curr_slope += delta; curr_delta_h += curr_slope * gVertSpacing; out_data[i] += static_cast<float>(curr_delta_h); } }
double cTerrainGen2D::BuildNarrowGaps(double width, const tParams& params, cRand& rand, std::vector<float>& out_data) { double spacing_min = params[eParamsNarrowGapSpacingMin]; double spacing_max = params[eParamsNarrowGapSpacingMax]; double dist_min = params[eParamsNarrowGapDistMin]; double dist_max = params[eParamsNarrowGapDistMax]; double gap_w_min = params[eParamsNarrowGapWidthMin]; double gap_w_max = params[eParamsNarrowGapWidthMax]; double gap_d_min = params[eParamsNarrowGapDepthMin]; double gap_d_max = params[eParamsNarrowGapDepthMax]; int count_min = std::max(1, static_cast<int>(params[eParamsNarrowGapCountMin])); int count_max = std::max(1, static_cast<int>(params[eParamsNarrowGapCountMax])); double total_w = 0; while (total_w < width) { double spacing = rand.RandDouble(spacing_min, spacing_max); int count = rand.RandInt(count_min, count_max + 1); for (int i = 0; i < count; ++i) { double w = rand.RandDouble(gap_w_min, gap_w_max); double d = rand.RandDouble(gap_d_min, gap_d_max); double curr_w = AddBox(spacing, w, d, out_data); total_w += curr_w; spacing = rand.RandDouble(dist_min, dist_max); } } return total_w; }
void cTerrainGen2D::OverlayBumps(double min_delta_h, double max_delta_h, int beg_idx, int end_idx, cRand& rand, std::vector<float>& out_data) { double curr_slope = 0; double curr_delta_h = 0; assert(beg_idx < out_data.size()); assert(end_idx <= out_data.size()); for (int i = beg_idx; i < end_idx - 1; ++i) { double delta = rand.RandSign() * rand.RandDouble(min_delta_h, max_delta_h); out_data[i] += static_cast<float>(delta); } }
double cTerrainGen2D::BuildMixed(double width, const tParams& params, cRand& rand, std::vector<float>& out_data) { double total_w = 0; const int num_types = 3; const double dummy_w = gVertSpacing; while (total_w < width) { double curr_w = 0; int rand_type = rand.RandInt(0, num_types); if (rand_type == 0) { curr_w = BuildGaps(dummy_w, params, rand, out_data); } else if (rand_type == 1) { curr_w = BuildSteps(dummy_w, params, rand, out_data); } else if (rand_type == 2) { curr_w = BuildWalls(dummy_w, params, rand, out_data); } total_w += curr_w; } return total_w; }
double cTerrainGen2D::BuildSteps(double width, const tParams& params, cRand& rand, std::vector<float>& out_data) { double spacing_min = params[eParamsStepSpacingMin]; double spacing_max = params[eParamsStepSpacingMax]; double step_h0_min = params[eParamsStepHeight0Min]; double step_h0_max = params[eParamsStepHeight0Max]; double step_h1_min = params[eParamsStepHeight1Min]; double step_h1_max = params[eParamsStepHeight1Max]; double total_w = 0; while (total_w < width) { double min_h = 0; double max_h = 0; bool valid_h0 = (step_h0_min != 0 || step_h0_max != 0); bool valid_h1 = (step_h1_min != 0 || step_h1_max != 0); if (valid_h0 && valid_h1) { bool heads = rand.FlipCoin(); min_h = (heads) ? step_h0_min : step_h1_min; max_h = (heads) ? step_h0_max : step_h1_max; } else if (valid_h0) { min_h = step_h0_min; max_h = step_h0_max; } else { min_h = step_h1_min; max_h = step_h1_max; } double w = rand.RandDouble(spacing_min, spacing_max); double h = rand.RandDouble(min_h, max_h); double curr_w = AddStep(w, h, out_data); total_w += curr_w; } return total_w; }
double cTerrainGen2D::BuildWalls(double width, const tParams& params, cRand& rand, std::vector<float>& out_data) { double spacing_min = params[eParamsWallSpacingMin]; double spacing_max = params[eParamsWallSpacingMax]; double wall_w_min = params[eParamsWallWidthMin]; double wall_w_max = params[eParamsWallWidthMax]; double wall_g_min = params[eParamsWallHeightMin]; double wall_g_max = params[eParamsWallHeightMax]; double total_w = 0; while (total_w < width) { double spacing = rand.RandDouble(spacing_min, spacing_max); double w = rand.RandDouble(wall_w_min, wall_w_max); double h = rand.RandDouble(wall_g_min, wall_g_max); double curr_w = AddBox(spacing, w, h, out_data); total_w += curr_w; } return total_w; }
double cTerrainGen2D::BuildGaps(double width, const tParams& params, cRand& rand, std::vector<float>& out_data) { double spacing_min = params[eParamsGapSpacingMin]; double spacing_max = params[eParamsGapSpacingMax]; double gap_w_min = params[eParamsGapWidthMin]; double gap_w_max = params[eParamsGapWidthMax]; double gap_d_min = params[eParamsGapDepthMin]; double gap_d_max = params[eParamsGapDepthMax]; double total_w = 0; while (total_w < width) { double spacing = rand.RandDouble(spacing_min, spacing_max); double w = rand.RandDouble(gap_w_min, gap_w_max); double d = rand.RandDouble(gap_d_min, gap_d_max); double curr_w = AddBox(spacing, w, d, out_data); total_w += curr_w; } return total_w; }
void cTerrainGen3D::AddStairs(const tVector& origin, const Eigen::Vector2i& start_coord, const tVector& size, double spacing_min, double spacing_max, double step_h_min, double step_h_max, const Eigen::Vector2i& out_res, cRand& rand, std::vector<float>& out_data, std::vector<int>& out_flags) { const double pad = 1; int res_x = CalcResX(size[0]); int res_z = CalcResX(size[2]); int num_verts = res_x * res_z; //double last_step_z = origin[2]; //double current_spacing = rand.RandDouble(spacing_min, spacing_max); //double current_height = 0; double randomness = rand.RandDouble(); for (int j = 0; j < res_z; ++j) { //Check the new step and reset the height if we are done with the last step double z = origin[2] + (j / (res_z - 1.0)) * size[2]; /* if (z > (last_step_z + current_spacing)) { last_step_z = z; current_height += cMathUtil::Sign(z)*rand.RandDouble(step_h_min, step_h_max); current_spacing = rand.RandDouble(spacing_min, spacing_max); } */ size_t coord_z = j + start_coord[1]; for (int i = 0; i < res_x; ++i) { size_t coord_x = i + start_coord[0]; size_t idx = coord_z * out_res[0] + coord_x; double x = origin[0] + (i / (res_x - 1.0)) * size[0]; x = cMathUtil::Sign(x) * std::max(0.0, (std::abs(x) - pad)); double h = (std::floor(x*2))*0.1/2; //rand.Seed(h); //h += rand.RandDouble(step_h_min, step_h_max); h += cMathUtil::RandDoubleSeed(h*randomness)*(step_h_max-step_h_min)+step_h_min; int curr_flags = 1 << eVertFlagEnableTex; out_data[idx] = h; out_flags[idx] = curr_flags; } } }
double cTerrainGen2D::BuildCliffs(double width, const tParams& params, cRand& rand, std::vector<float>& out_data) { double spacing_min = params[eParamsCliffSpacingMin]; double spacing_max = params[eParamsCliffSpacingMax]; double cliff_h0_min = params[eParamsCliffHeight0Min]; double cliff_h0_max = params[eParamsCliffHeight0Max]; double cliff_h1_min = params[eParamsCliffHeight1Min]; double cliff_h1_max = params[eParamsCliffHeight1Max]; int mini_count_max = static_cast<int>(params[eParamsCliffMiniCountMax]); double bump_h_min = params[eParamsBumpHeightMin]; double bump_h_max = params[eParamsBumpHeightMax]; const double delta_range = std::abs(params[eParamsSlopeDeltaRange]); const double delta_min = params[eParamsSlopeDeltaMin]; const double delta_max = params[eParamsSlopeDeltaMax]; int beg_idx = static_cast<int>(out_data.size()); double total_w = 0; while (total_w < width) { double min_h = 0; double max_h = 0; bool valid_h0 = (cliff_h0_min != 0 || cliff_h0_max != 0); bool valid_h1 = (cliff_h1_min != 0 || cliff_h1_max != 0); if (valid_h0 && valid_h1) { bool heads = rand.FlipCoin(); min_h = (heads) ? cliff_h0_min : cliff_h1_min; max_h = (heads) ? cliff_h0_max : cliff_h1_max; } else if (valid_h0) { min_h = cliff_h0_min; max_h = cliff_h0_max; } else { min_h = cliff_h1_min; max_h = cliff_h1_max; } double w = rand.RandDouble(spacing_min, spacing_max); double h = rand.RandDouble(min_h, max_h); double curr_w = 0; double curr_delta_h = 0; int num_mini = rand.RandInt(0, mini_count_max + 1); for (int i = 0; i < num_mini + 1; ++i) { const double mini_w = (i == 0) ? w : 0.1; double mini_h = rand.RandDouble(curr_delta_h, h); mini_h = (i == num_mini) ? h : mini_h; double dh = mini_h - curr_delta_h; curr_w += AddStep(mini_w, dh, out_data); curr_delta_h = mini_h; } total_w += curr_w; } int end_idx = static_cast<int>(out_data.size()); OverlaySlopes(delta_range, delta_min, delta_max, 0, beg_idx, end_idx, rand, out_data); OverlayBumps(bump_h_min, bump_h_max, beg_idx, end_idx, rand, out_data); return total_w; }