Add some more hacks to make planet seem more realistic
Original 8f6ef3764f
Authored by Jeija on May 18, 2016
master
parent
d88f1ce6ed
commit
102ac5b205
|
@ -159,6 +159,8 @@ void ClientMap::updateDrawList()
|
|||
// No occlusion culling when free_move is on and camera is
|
||||
// inside ground
|
||||
bool occlusion_culling_enabled = true;
|
||||
if (g_settings->getBool("planet_enable"))
|
||||
occlusion_culling_enabled = false;
|
||||
if (g_settings->getBool("free_move")) {
|
||||
MapNode n = getNodeNoEx(cam_pos_nodes);
|
||||
if (n.getContent() == CONTENT_IGNORE ||
|
||||
|
@ -194,14 +196,52 @@ void ClientMap::updateDrawList()
|
|||
if (block->mesh)
|
||||
block->mesh->updateCameraOffset(m_camera_offset);
|
||||
|
||||
float range = 100000 * BS;
|
||||
if (!m_control.range_all)
|
||||
range = m_control.wanted_range * BS;
|
||||
/*
|
||||
* Planet: Since the planet is actually just a flat map that wraps around
|
||||
* a seemingly spherical object, there are 9 possible minimal distances to
|
||||
* the same mapblock, because the end of the map on one side is the beginning
|
||||
* of the map on the other side again. Find the minimal distance from the player
|
||||
* to this mapblock.
|
||||
*/
|
||||
if (block->mesh != NULL && g_settings->getBool("planet_enable")) {
|
||||
// Round planet circumference up to even number of mapblocks, in nodes
|
||||
int planet_circumference = ceil(g_settings->getU16("planet_radius") * M_PI) * 2 * MAP_BLOCKSIZE;
|
||||
|
||||
float mindist = (cam_pos_nodes - block->getPos() * MAP_BLOCKSIZE).getLength();
|
||||
int offset_minimal_x = 0, offset_minimal_z = 0;
|
||||
for (int wrapx = -1; wrapx <= 1; ++wrapx)
|
||||
for (int wrapz = -1; wrapz <= 1; ++wrapz) {
|
||||
float distx = cam_pos_nodes.X - (block->getPos().X * MAP_BLOCKSIZE + wrapx * planet_circumference);
|
||||
float distz = cam_pos_nodes.Z - (block->getPos().Z * MAP_BLOCKSIZE + wrapz * planet_circumference);
|
||||
float dist = sqrt(distx * distx + distz * distz);
|
||||
|
||||
if (dist < mindist) {
|
||||
mindist = dist;
|
||||
offset_minimal_x = wrapx * planet_circumference;
|
||||
offset_minimal_z = wrapz * planet_circumference;
|
||||
}
|
||||
}
|
||||
block->mesh->updatePlanetOffset(-v3s16(offset_minimal_x, 0, offset_minimal_z));
|
||||
|
||||
// No need to render blocks deeper inside the planet than its radius
|
||||
// or on the other side of the planet
|
||||
if (block->getPos().Y < -g_settings->getU16("planet_radius"))
|
||||
continue;
|
||||
|
||||
if (mindist > planet_circumference / 4)
|
||||
continue;
|
||||
}
|
||||
|
||||
float d = 0.0;
|
||||
if (!isBlockInSight(block->getPos(), camera_position,
|
||||
camera_direction, camera_fov, range, &d))
|
||||
continue;
|
||||
if (!g_settings->getBool("planet_enable")) {
|
||||
float range = 100000 * BS;
|
||||
if (m_control.range_all == false)
|
||||
range = m_control.wanted_range * BS;
|
||||
|
||||
if (!isBlockInSight(block->getPos(), camera_position,
|
||||
camera_direction, camera_fov, range, &d))
|
||||
continue;
|
||||
}
|
||||
|
||||
blocks_in_range++;
|
||||
|
||||
|
@ -231,6 +271,20 @@ void ClientMap::updateDrawList()
|
|||
d > m_control.wanted_range * BS)
|
||||
continue;
|
||||
|
||||
// Planet: Make sure block inside of planet bounds
|
||||
if (g_settings->getBool("planet_enable")) {
|
||||
// Round planet circumference up to even number of mapblocks
|
||||
int planet_circumference_blocks = ceil(g_settings->getU16("planet_radius") * M_PI) * 2;
|
||||
if (block->getPos().X > planet_circumference_blocks / 2 - 1)
|
||||
continue;
|
||||
if (block->getPos().X < -planet_circumference_blocks / 2)
|
||||
continue;
|
||||
if (block->getPos().Z > planet_circumference_blocks / 2 - 1)
|
||||
continue;
|
||||
if (block->getPos().Z < -planet_circumference_blocks / 2)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to set
|
||||
block->refGrab();
|
||||
m_drawlist[block->getPos()] = block;
|
||||
|
@ -370,7 +424,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||
continue;
|
||||
|
||||
float d = 0.0;
|
||||
if (!isBlockInSight(block->getPos(), camera_position,
|
||||
if (!g_settings->getBool("planet_enable") && !isBlockInSight(block->getPos(), camera_position,
|
||||
camera_direction, camera_fov, 100000 * BS, &d))
|
||||
continue;
|
||||
|
||||
|
|
29
src/game.cpp
29
src/game.cpp
|
@ -744,6 +744,7 @@ protected:
|
|||
const ToolCapabilities &playeritem_toolcap, f32 dtime);
|
||||
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
||||
const CameraOrientation &cam);
|
||||
void handlePlanet();
|
||||
void updateProfilerGraphs(ProfilerGraph *graph);
|
||||
|
||||
// Misc
|
||||
|
@ -883,6 +884,7 @@ private:
|
|||
bool m_invert_mouse = false;
|
||||
bool m_first_loop_after_window_activation = false;
|
||||
bool m_camera_offset_changed = false;
|
||||
bool m_planet_warp_changed = false;
|
||||
|
||||
bool m_does_lost_focus_pause_game = false;
|
||||
|
||||
|
@ -1118,12 +1120,37 @@ void Game::run()
|
|||
// Update if minimap has been disabled by the server
|
||||
m_game_ui->m_flags.show_minimap &= client->shouldShowMinimap();
|
||||
|
||||
handlePlanet();
|
||||
|
||||
if (m_does_lost_focus_pause_game && !device->isWindowFocused() && !isMenuActive()) {
|
||||
showPauseMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::handlePlanet() {
|
||||
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||
|
||||
// Quick hack: Teleport to other side of planet at planet edges
|
||||
if (g_settings->getBool("planet_enable")) {
|
||||
// Round planet circumference up to even number of blocks, value in x/z coordinates
|
||||
int planet_circumference = ceil(g_settings->getU16("planet_radius") * M_PI) * BS * MAP_BLOCKSIZE * 2;
|
||||
v3f playerpos = player->getPosition();
|
||||
if (playerpos.X > planet_circumference / 2 - 0.5 * BS)
|
||||
playerpos.X = -(float)planet_circumference / 2 - 0.5 * BS;
|
||||
if (playerpos.X < -planet_circumference / 2 - 0.5 * BS)
|
||||
playerpos.X = (float)planet_circumference / 2 - 0.5 * BS;
|
||||
if (playerpos.Z > planet_circumference / 2 - 0.5 * BS)
|
||||
playerpos.Z = -(float)planet_circumference / 2 - 0.5 * BS;
|
||||
if (playerpos.Z < -planet_circumference / 2 - 0.5 * BS)
|
||||
playerpos.Z = (float)planet_circumference / 2 - 0.5 * BS;
|
||||
|
||||
m_planet_warp_changed = player->getPosition() != playerpos;
|
||||
|
||||
player->setPosition(playerpos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Game::shutdown()
|
||||
{
|
||||
|
@ -3769,7 +3796,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
|||
v3f camera_direction = camera->getDirection();
|
||||
if (runData.update_draw_list_timer >= 0.2
|
||||
|| runData.update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2
|
||||
|| m_camera_offset_changed) {
|
||||
|| m_camera_offset_changed || m_planet_warp_changed) {
|
||||
runData.update_draw_list_timer = 0;
|
||||
client->getEnv().getClientMap().updateDrawList();
|
||||
runData.update_draw_list_last_cam_dir = camera_direction;
|
||||
|
|
|
@ -690,20 +690,6 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
|
|||
incH * physics_override_speed * slip_factor);
|
||||
accelerateVertical(speedV * physics_override_speed,
|
||||
incV * physics_override_speed);
|
||||
|
||||
// Quick hack: Teleport to other side of planet at planet edges
|
||||
if (g_settings->getBool("planet_enable")) {
|
||||
float planet_circumference = g_settings->getU16("planet_radius") * MAP_BLOCKSIZE * BS * 2 * M_PI;
|
||||
std::cout << "circumference: " << planet_circumference << ", X and Z " << m_position.X << " " << m_position.Z << std::endl;
|
||||
if (m_position.X > planet_circumference / 2)
|
||||
m_position.X = -(float)planet_circumference / 2;
|
||||
if (m_position.X < -planet_circumference / 2)
|
||||
m_position.X = (float)planet_circumference / 2;
|
||||
if (m_position.Z > planet_circumference / 2)
|
||||
m_position.Z = -(float)planet_circumference / 2;
|
||||
if (m_position.Z < -planet_circumference / 2)
|
||||
m_position.Z = (float)planet_circumference / 2;
|
||||
}
|
||||
}
|
||||
|
||||
v3s16 LocalPlayer::getStandingNodePos()
|
||||
|
|
|
@ -1022,7 +1022,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
|||
m_shdrsrc(data->m_client->getShaderSource()),
|
||||
m_animation_force_timer(0), // force initial animation
|
||||
m_last_crack(-1),
|
||||
m_last_daynight_ratio((u32) -1)
|
||||
m_last_daynight_ratio((u32) -1),
|
||||
m_planet_offset(v3s16(0, 0, 0))
|
||||
{
|
||||
for (auto &m : m_mesh)
|
||||
m = new scene::SMesh();
|
||||
|
@ -1268,6 +1269,17 @@ MapBlockMesh::~MapBlockMesh()
|
|||
delete m_minimap_mapblock;
|
||||
}
|
||||
|
||||
void MapBlockMesh::updatePlanetOffset(v3s16 planet_offset) {
|
||||
if (planet_offset != m_planet_offset) {
|
||||
for (scene::IMesh *m : m_mesh) {
|
||||
translateMesh(m, intToFloat(m_planet_offset - planet_offset, BS));
|
||||
if (m_enable_vbo)
|
||||
m->setDirty();
|
||||
}
|
||||
m_planet_offset = planet_offset;
|
||||
}
|
||||
}
|
||||
|
||||
bool MapBlockMesh::animate(bool faraway, float time, int crack,
|
||||
u32 daynight_ratio)
|
||||
{
|
||||
|
|
|
@ -133,6 +133,7 @@ public:
|
|||
}
|
||||
|
||||
void updateCameraOffset(v3s16 camera_offset);
|
||||
void updatePlanetOffset(v3s16 planet_offset);
|
||||
|
||||
private:
|
||||
scene::IMesh *m_mesh[MAX_TILE_LAYERS];
|
||||
|
@ -171,6 +172,9 @@ private:
|
|||
|
||||
// Camera offset info -> do we have to translate the mesh?
|
||||
v3s16 m_camera_offset;
|
||||
|
||||
// Mesh offset that is caused by the map wrapping around when rendering in planet mode
|
||||
v3s16 m_planet_offset;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue