示例#1
0
int MapgenV5::getSpawnLevelAtPoint(v2s16 p)
{

	float f = 0.55 + NoisePerlin2D(&noise_factor->np, p.X, p.Y, seed);
	if (f < 0.01)
		f = 0.01;
	else if (f >= 1.0)
		f *= 1.6;
	float h = NoisePerlin2D(&noise_height->np, p.X, p.Y, seed);

	// noise_height 'offset' is the average level of terrain. At least 50% of
	// terrain will be below this.
	// Raising the maximum spawn level above 'water_level + 16' is necessary
	// for when noise_height 'offset' is set much higher than water_level.
	s16 max_spawn_y = MYMAX(noise_height->np.offset, water_level + 16);

	// Starting spawn search at max_spawn_y + 128 ensures 128 nodes of open
	// space above spawn position. Avoids spawning in possibly sealed voids.
	for (s16 y = max_spawn_y + 128; y >= water_level; y--) {
		float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed);

		if (n_ground * f > y - h) {  // If solid
			if (y < water_level || y > max_spawn_y)
				return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point

			// y + 2 because y is surface and due to biome 'dust' nodes.
			return y + 2;
		}
	}
	// Unsuitable spawn position, no ground found
	return MAX_MAP_GENERATION_LIMIT;
}
示例#2
0
// For BiomeGen type 'BiomeGenOriginal'
float BiomeManager::getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat,
	NoiseParams &np_heat_blend, u64 seed)
{
	return
		NoisePerlin2D(&np_heat,       pos.X, pos.Z, seed) +
		NoisePerlin2D(&np_heat_blend, pos.X, pos.Z, seed);
}
示例#3
0
// For BiomeGen type 'BiomeGenOriginal'
float BiomeManager::getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity,
	NoiseParams &np_humidity_blend, u64 seed)
{
	return
		NoisePerlin2D(&np_humidity,       pos.X, pos.Z, seed) +
		NoisePerlin2D(&np_humidity_blend, pos.X, pos.Z, seed);
}
示例#4
0
int MapgenV5::getSpawnLevelAtPoint(v2s16 p)
{
	//TimeTaker t("getGroundLevelAtPoint", NULL, PRECISION_MICRO);

	float f = 0.55 + NoisePerlin2D(&noise_factor->np, p.X, p.Y, seed);
	if (f < 0.01)
		f = 0.01;
	else if (f >= 1.0)
		f *= 1.6;
	float h = NoisePerlin2D(&noise_height->np, p.X, p.Y, seed);

	for (s16 y = 128; y >= -128; y--) {
		float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed);

		if (n_ground * f > y - h) {  // If solid
			// If either top 2 nodes of search are solid this is inside a
			// mountain or floatland with possibly no space for the player to spawn.
			if (y >= 127) {
				return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
			} else {  // Ground below at least 2 nodes of empty space
				if (y <= water_level || y > water_level + 16)
					return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
				else
					return y;
			}
		}
	}

	//printf("getGroundLevelAtPoint: %dus\n", t.stop());
	return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn position, no ground found
}
float MapgenV7P::mountainLevelAtPoint(s16 x, s16 z)
{
	float mnt_h_n = NoisePerlin2D(&noise_mount_height->np, x, z, seed);
	float mnt_n = NoisePerlin2D(&noise_mountain->np, x, z, seed);

	return mnt_n * mnt_h_n;
}
示例#6
0
int MapgenV5::getGroundLevelAtPoint(v2s16 p)
{
	//TimeTaker t("getGroundLevelAtPoint", NULL, PRECISION_MICRO);

	float f = 0.55 + NoisePerlin2D(&noise_factor->np, p.X, p.Y, seed);
	if (f < 0.01)
		f = 0.01;
	else if (f >= 1.0)
		f *= 1.6;
	float h = NoisePerlin2D(&noise_height->np, p.X, p.Y, seed);

	s16 search_start = 128; // Only bother searching this range, actual
	s16 search_end = -128;  // ground level is rarely higher or lower.

	for (s16 y = search_start; y >= search_end; y--) {
		float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed);
		// If solid
		if (n_ground * f > y - h) {
			// If either top 2 nodes of search are solid this is inside a
			// mountain or floatland with no space for the player to spawn.
			if (y >= search_start - 1)
				return MAX_MAP_GENERATION_LIMIT;
			else
				return y; // Ground below at least 2 nodes of space
		}
	}

	//printf("getGroundLevelAtPoint: %dus\n", t.stop());
	return -MAX_MAP_GENERATION_LIMIT;
}
示例#7
0
int MapgenV5::getGroundLevelAtPoint(v2s16 p)
{
	//TimeTaker t("getGroundLevelAtPoint", NULL, PRECISION_MICRO);

	float f = 0.55 + NoisePerlin2D(&noise_factor->np, p.X, p.Y, seed);
	if (f < 0.01)
		f = 0.01;
	else if (f >= 1.0)
		f *= 1.6;
	float h = NoisePerlin2D(&noise_height->np, p.X, p.Y, seed);

	s16 search_top = water_level + 15;
	s16 search_base = water_level;

	s16 level = -31000;
	for (s16 y = search_top; y >= search_base; y--) {
		float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed);
		if (n_ground * f > y - h) {
			if (y >= search_top - 7)
				break;
			else
				level = y;
				break;
		}
	}

	//printf("getGroundLevelAtPoint: %dus\n", t.stop());
	return level;
}
示例#8
0
Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
	float heat      = NoisePerlin2D(&noise_heat->np, p.X, p.Z, seed);
	float humidity  = NoisePerlin2D(&noise_humidity->np, p.X, p.Z, seed);
	s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z);

	return bmgr->getBiome(heat, humidity, groundlevel);
}
示例#9
0
Biome *BiomeGenOriginal::calcBiomeAtPoint(v3s16 pos) const
{
	float heat =
		NoisePerlin2D(&m_params->np_heat,       pos.X, pos.Z, m_params->seed) +
		NoisePerlin2D(&m_params->np_heat_blend, pos.X, pos.Z, m_params->seed);
	float humidity =
		NoisePerlin2D(&m_params->np_humidity,       pos.X, pos.Z, m_params->seed) +
		NoisePerlin2D(&m_params->np_humidity_blend, pos.X, pos.Z, m_params->seed);

	return calcBiomeFromNoise(heat, humidity, pos.Y);
}
示例#10
0
float MapgenValleys::terrainLevelAtPoint(s16 x, s16 z)
{
	TerrainNoise tn;

	float rivers = NoisePerlin2D(&noise_rivers->np, x, z, seed);
	float valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed);
	float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed);

	tn.x = x;
	tn.z = z;
	tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed);
	tn.rivers = &rivers;
	tn.valley = &valley;
	tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed);
	tn.slope = &inter_valley_slope;
	tn.inter_valley_fill = 0.f;
	tn.cliffs = 0.f;
	tn.corr = 0.f;

	if (fast_terrain) {
		tn.inter_valley_fill = NoisePerlin2D(&noise_inter_valley_fill->np, x, z, seed);

		if (cliff_terrain)
			tn.cliffs = NoisePerlin2D(&noise_cliffs->np, x, z, seed);
		if (rugged_terrain)
			tn.corr = NoisePerlin2D(&noise_corr->np, x, z, seed);
	}

	return adjustedTerrainLevelFromNoise(&tn);
}
示例#11
0
float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
	float terrain_mod = NoisePerlin2DNoTxfm(noise_terrain_mod->np, x, z, seed);
	float hselect     = NoisePerlin2D(noise_height_select->np, x, z, seed);
	float persist     = abs(NoisePerlin2DNoTxfm(noise_terrain_persist->np, x, z, seed));

	noise_terrain_base->np->persist = persist;
	float terrain_base = NoisePerlin2D(noise_terrain_base->np, x, z, seed);
	float height_base  = terrain_base * terrain_mod;

	noise_terrain_alt->np->persist = persist;
	float height_alt = NoisePerlin2D(noise_terrain_alt->np, x, z, seed);

	return (height_base * hselect) + (height_alt * (1.0 - hselect));
}
示例#12
0
文件: biome.cpp 项目: BpTsTG/minetest
s16 BiomeDefManager::calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime) {
	//variant 1: full random
	//f32 heat = NoisePerlin3D(np_heat, p.X, env->getGameTime()/100, p.Z, seed);

	//variant 2: season change based on default heat map
	const f32 offset = 20; // = np_heat->offset
	const f32 scale  = 20; // = np_heat->scale
	const f32 range  = 20;
	f32 heat = NoisePerlin2D(np_heat, p.X, p.Z, seed); // 0..50..100

	heat -= np_heat->offset; // -50..0..+50

	// normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50,
	if (np_heat->scale)
		heat /= np_heat->scale / scale; //  -20..0..+20

	f32 seasonv = totaltime;
	seasonv /= 86400 * g_settings->getS16("year_days"); // season change speed
	seasonv += (f32)p.X / 3000; // you can walk to area with other season
	seasonv = sin(seasonv * M_PI);
	heat += (range * (heat < 0 ? 2 : 0.5)) * seasonv; // -60..0..30

	heat += offset; // -40..0..50
	heat += p.Y / -333; // upper=colder, lower=hotter, 3c per 1000

	// daily change, hotter at sun +4, colder at night -4
	heat += 8 * (sin(cycle_shift(timeofday, -0.25) * M_PI) - 0.5); //-44..20..54
	
	return heat;
}
示例#13
0
void MapgenV6::generateCaves(int max_stone_y)
{
	float cave_amount = NoisePerlin2D(np_cave, node_min.X, node_min.Y, seed);
	int volume_nodes = (node_max.X - node_min.X + 1) *
					   (node_max.Y - node_min.Y + 1) * MAP_BLOCKSIZE;
	cave_amount = MYMAX(0.0, cave_amount);
	u32 caves_count = cave_amount * volume_nodes / 50000;
	u32 bruises_count = 1;
	PseudoRandom ps(blockseed + 21343);
	PseudoRandom ps2(blockseed + 1032);

	if (ps.range(1, 6) == 1)
		bruises_count = ps.range(0, ps.range(0, 2));

	if (getBiome(v2s16(node_min.X, node_min.Z)) == BT_DESERT) {
		caves_count   /= 3;
		bruises_count /= 3;
	}

	for (u32 i = 0; i < caves_count + bruises_count; i++) {
		CavesV6 cave(ndef, &gennotify, water_level, c_water_source, c_lava_source);

		bool large_cave = (i >= caves_count);
		cave.makeCave(vm, node_min, node_max, &ps, &ps2,
			large_cave, max_stone_y, heightmap);
	}
}
示例#14
0
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
{
	// Base terrain calculation
	s16 y = baseTerrainLevelAtPoint(p.X, p.Y);

	// Ridge/river terrain calculation
	float width = 0.2;
	float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
	// if inside a river this is an unsuitable spawn point
	if (fabs(uwatern) <= width)
		return MAX_MAP_GENERATION_LIMIT;

	// Mountain terrain calculation
	int iters = 128;
	while (iters--) {
		if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) {  // Air, y is ground level
			if (y <= water_level || y > water_level + 16)
				return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
			else
				return y;
		}
		y++;
	}

	// Unsuitable spawn point, no ground surface found
	return MAX_MAP_GENERATION_LIMIT;
}
示例#15
0
bool MapgenV7::getMountainTerrainAtPoint(int x, int y, int z) {
	float mnt_h_n = NoisePerlin2D(&noise_mount_height->np, x, z, seed);
	float height_modifier = -((float)y / rangelim(mnt_h_n, 80.0, 150.0));
	float mnt_n = NoisePerlin3D(&noise_mountain->np, x, y, z, seed);

	return mnt_n + height_modifier >= 0.6;
}
示例#16
0
s16 BiomeManager::calcBlockHeat(v3POS p, uint64_t seed, float timeofday, float totaltime, bool use_weather) {
	//variant 1: full random
	//f32 heat = NoisePerlin3D(np_heat, p.X, env->getGameTime()/100, p.Z, seed);

	//variant 2: season change based on default heat map
	auto heat = NoisePerlin2D(&(mapgen_params->np_biome_heat), p.X, p.Z, seed); // -30..20..70

	if (use_weather) {
		f32 seasonv = totaltime;
		seasonv /= 86400 * year_days; // season change speed
		seasonv += (f32)p.X / weather_heat_width; // you can walk to area with other season
		seasonv = sin(seasonv * M_PI);
		//heat += (weather_heat_season * (heat < offset ? 2 : 0.5)) * seasonv; // -60..0..30
		heat += (weather_heat_season) * seasonv; // -60..0..30

		// daily change, hotter at sun +4, colder at night -4
		heat += weather_heat_daily * (sin(cycle_shift(timeofday, -0.25) * M_PI) - 0.5); //-64..0..34
	}
	heat += p.Y / weather_heat_height; // upper=colder, lower=hotter, 3c per 1000

	if (weather_hot_core && p.Y < -(MAX_MAP_GENERATION_LIMIT-weather_hot_core))
		heat += 6000 * (1.0-((float)(p.Y - -MAX_MAP_GENERATION_LIMIT)/weather_hot_core)); //hot core, later via realms

	return heat;
}
示例#17
0
void MapgenV6::generateCaves(int max_stone_y)
{
	float cave_amount = NoisePerlin2D(np_cave, node_min.X, node_min.Y, seed);
	int volume_nodes = (node_max.X - node_min.X + 1) *
					   (node_max.Y - node_min.Y + 1) * MAP_BLOCKSIZE;
	cave_amount = MYMAX(0.0, cave_amount);
	u32 caves_count = cave_amount * volume_nodes / 50000;
	u32 bruises_count = 1;
	PseudoRandom ps(blockseed + 21343);
	PseudoRandom ps2(blockseed + 1032);

	if (ps.range(1, 6) == 1)
		bruises_count = ps.range(0, ps.range(0, 2));

	if (getBiome(node_min) == BT_DESERT) {
		caves_count   /= 3;
		bruises_count /= 3;
	}

	for (u32 i = 0; i < caves_count + bruises_count; i++) {
		bool large_cave = (i >= caves_count);
		CaveV6 cave(this, &ps, &ps2, large_cave);

		cave.makeCave(node_min, node_max, max_stone_y);
	}
}
示例#18
0
int MapgenV7::getGroundLevelAtPoint(v2s16 p)
{
	// Base terrain calculation
	s16 y = baseTerrainLevelAtPoint(p.X, p.Y);

	// Ridge/river terrain calculation
	float width = 0.2;
	float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
	// actually computing the depth of the ridge is much more expensive;
	// if inside a river, simply guess
	if (fabs(uwatern) <= width)
		return water_level - 10;

	// Mountain terrain calculation
	int iters = 128; // don't even bother iterating more than 128 times..
	while (iters--) {
		//current point would have been air
		if (!getMountainTerrainAtPoint(p.X, y, p.Y))
			return y;

		y++;
	}

	return y;
}
示例#19
0
bool MapgenV7::getMountainTerrainAtPoint(s16 x, s16 y, s16 z)
{
	float mnt_h_n = NoisePerlin2D(&noise_mount_height->np, x, z, seed);
	float density_gradient = -((float)y / mnt_h_n);
	float mnt_n = NoisePerlin3D(&noise_mountain->np, x, y, z, seed);

	return mnt_n + density_gradient >= 0.0;
}
示例#20
0
//needs to be updated
float MapgenV7::baseTerrainLevelAtPoint(s16 x, s16 z)
{
	float hselect = NoisePerlin2D(&noise_height_select->np, x, z, seed);
	hselect = rangelim(hselect, 0.0, 1.0);

	float persist = NoisePerlin2D(&noise_terrain_persist->np, x, z, seed);

	noise_terrain_base->np.persist = persist;
	float height_base = NoisePerlin2D(&noise_terrain_base->np, x, z, seed);

	noise_terrain_alt->np.persist = persist;
	float height_alt = NoisePerlin2D(&noise_terrain_alt->np, x, z, seed);

	if (height_alt > height_base)
		return height_alt;

	return (height_base * hselect) + (height_alt * (1.0 - hselect));
}
示例#21
0
int LuaPerlinNoise::l_get2d(lua_State *L)
{
    NO_MAP_LOCK_REQUIRED;
    LuaPerlinNoise *o = checkobject(L, 1);
    v2f p = check_v2f(L, 2);
    lua_Number val = NoisePerlin2D(&o->np, p.X, p.Y, 0);
    lua_pushnumber(L, val);
    return 1;
}
示例#22
0
bool MapgenV6::getHaveAppleTree(v2s16 p)
{
	/*is_apple_tree = noise2d_perlin(
		0.5+(float)p.X/100, 0.5+(float)p.Z/100,
		data->seed+342902, 3, 0.45) > 0.2;*/

	float noise = NoisePerlin2D(np_apple_trees, p.X, p.Y, seed);

	return noise > 0.2;
}
示例#23
0
int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
	s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Y);
	float heat      = NoisePerlin2D(bmgr->np_heat, p.X, p.Y, seed);
	float humidity  = NoisePerlin2D(bmgr->np_humidity, p.X, p.Y, seed);
	Biome *b = bmgr->getBiome(heat, humidity, groundlevel);
	
	s16 y = groundlevel;
	if (y > water_level) {
		int iters = 1024; // don't even bother iterating more than 1024 times..
		while (iters--) {
			float ridgenoise = NoisePerlin3D(noise_ridge->np, p.X, y, p.Y, seed);
			if (ridgenoise * (float)(y * y) < 15.0)
				break;
			y--;
		}
	}

	return y + b->top_depth;
}
示例#24
0
void TestNoise::testNoise2dPoint()
{
	NoiseParams np_normal(20, 40, v3f(50, 50, 50), 9,  5, 0.6, 2.0);

	u32 i = 0;
	for (u32 y = 0; y != 10; y++)
	for (u32 x = 0; x != 10; x++, i++) {
		float actual   = NoisePerlin2D(&np_normal, x, y, 1337);
		float expected = expected_2d_results[i];
		UASSERT(fabs(actual - expected) <= 0.00001);
	}
}
示例#25
0
int MapgenFlat::getGroundLevelAtPoint(v2s16 p)
{
	float n_terrain = NoisePerlin2D(&noise_terrain->np, p.X, p.Y, seed);
	if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) {
		s16 depress = (lake_threshold - n_terrain) * lake_steepness;
		return ground_level - depress;
	} else if ((spflags & MGFLAT_HILLS) && n_terrain > hill_threshold) {
		s16 rise = (n_terrain - hill_threshold) * hill_steepness;
		return ground_level + rise;
	} else {
		return ground_level;
	}
}
示例#26
0
float MapgenV6::getTreeAmount(v2s16 p)
{
	/*double noise = noise2d_perlin(
			0.5+(float)p.X/125, 0.5+(float)p.Y/125,
			seed+2, 4, 0.66);*/

	float noise = NoisePerlin2D(np_trees, p.X, p.Y, seed);
	float zeroval = -0.39;
	if (noise < zeroval)
		return 0;
	else
		return 0.04 * (noise - zeroval) / (1.0 - zeroval);
}
示例#27
0
int MapgenValleys::getSpawnLevelAtPoint(v2s16 p)
{
	// Check to make sure this isn't a request for a location in a river.
	float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed);
	if (fabs(rivers) < river_size_factor)
		return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point

	s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
	if (level_at_point <= water_level ||
			level_at_point > water_level + 32)
		return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
	else
		return level_at_point;
}
示例#28
0
文件: biome.cpp 项目: BpTsTG/minetest
s16 BiomeDefManager::calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime) {

	f32 humidity = NoisePerlin2D(np_humidity, p.X, p.Z, seed);

	f32 seasonv = totaltime;
	seasonv /= 86400 * 2; // bad weather change speed (2 days)
	seasonv += (f32)p.Z / 300;
	humidity += 30 * sin(seasonv * M_PI);

	humidity += -12 * (sin(cycle_shift(timeofday, -0.1) * M_PI) - 0.5);
	humidity = rangelim(humidity, 0, 100);
	
	return humidity;
}
示例#29
0
float MapgenV6::getHumidity(v2s16 p)
{
	/*double noise = noise2d_perlin(
		0.5+(float)p.X/500, 0.5+(float)p.Y/500,
		seed+72384, 4, 0.66);
	noise = (noise + 1.0)/2.0;*/

	float noise = NoisePerlin2D(np_humidity, p.X, p.Y, seed);

	if (noise < 0.0)
		noise = 0.0;
	if (noise > 1.0)
		noise = 1.0;
	return noise;
}
示例#30
0
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
{
	// If rivers are enabled, first check if in a river
	if (spflags & MGV7_RIDGES) {
		float width = 0.2;
		float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
		if (fabs(uwatern) <= width)
			return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
	}

	// Terrain noise 'offset' is the average level of that terrain.
	// At least 50% of terrain will be below the higher of base and alt terrain
	// 'offset's.
	// Raising the maximum spawn level above 'water_level + 16' is necessary
	// for when terrain 'offset's are set much higher than water_level.
	s16 max_spawn_y = MYMAX(MYMAX(noise_terrain_alt->np.offset,
			noise_terrain_base->np.offset),
			water_level + 16);
	// Base terrain calculation
	s16 y = baseTerrainLevelAtPoint(p.X, p.Y);

	// If mountains are disabled, terrain level is base terrain level.
	// Avoids mid-air spawn where mountain terrain would have been.
	if (!(spflags & MGV7_MOUNTAINS)) {
		if (y < water_level || y > max_spawn_y)
			return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point

		// y + 2 because y is surface level and due to biome 'dust'
		return y + 2;
	}

	// Search upwards for first node without mountain terrain
	int iters = 256;
	while (iters > 0 && y <= max_spawn_y) {
		if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) {
			if (y <= water_level || y > max_spawn_y)
				return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point

			// y + 1 due to biome 'dust'
			return y + 1;
		}
		y++;
		iters--;
	}

	// Unsuitable spawn point
	return MAX_MAP_GENERATION_LIMIT;
}