Add some more hacks to make planet seem more realistic

master
Jeija 2016-05-18 12:37:30 +02:00
parent 50f8a37297
commit 8f6ef3764f
5 changed files with 104 additions and 24 deletions

View File

@ -242,18 +242,56 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
Compare block position to camera position, skip
if not seen on display
*/
if (block->mesh != NULL)
block->mesh->updateCameraOffset(m_camera_offset);
float range = 100000 * BS;
if (m_control.range_all == false)
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;
}
// This is ugly (spherical distance limit?)
/*if(m_control.range_all == false &&
@ -281,6 +319,8 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
// 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 ||
@ -330,6 +370,20 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
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;
@ -476,7 +530,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;

View File

@ -1481,6 +1481,7 @@ struct VolatileRunFlags {
bool disable_camera_update;
bool first_loop_after_window_activation;
bool camera_offset_changed;
bool planet_warp_changed;
};
@ -1610,6 +1611,7 @@ protected:
f32 dtime);
void updateFrame(ProfilerGraph *graph, RunStats *stats, GameRunData *runData,
f32 dtime, const VolatileRunFlags &flags, const CameraOrientation &cam);
void handlePlanet(VolatileRunFlags *flags);
void updateGui(float *statustext_time, const RunStats &stats,
const GameRunData& runData, f32 dtime, const VolatileRunFlags &flags,
const CameraOrientation &cam);
@ -1934,6 +1936,7 @@ void Game::run()
// Update if minimap has been disabled by the server
flags.show_minimap &= !client->isMinimapDisabledByServer();
handlePlanet(&flags);
}
}
@ -4132,7 +4135,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats,
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
|| flags.camera_offset_changed) {
|| flags.camera_offset_changed || flags.planet_warp_changed) {
runData->update_draw_list_timer = 0;
client->getEnv().getClientMap().updateDrawList(driver);
runData->update_draw_list_last_cam_dir = camera_direction;
@ -4223,6 +4226,29 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats,
g_profiler->graphAdd("mainloop_draw", stats->drawtime / 1000.0f);
}
void Game::handlePlanet(VolatileRunFlags *flags) {
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;
flags->planet_warp_changed = player->getPosition() != playerpos;
player->setPosition(playerpos);
}
}
inline static const char *yawToDirectionString(int yaw)
{

View File

@ -617,20 +617,6 @@ void LocalPlayer::applyControl(float dtime)
// Accelerate to target speed with maximum increment
accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed);
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()

View File

@ -1033,7 +1033,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_last_crack(-1),
m_crack_materials(),
m_last_daynight_ratio((u32) -1),
m_daynight_diffs()
m_daynight_diffs(),
m_planet_offset(v3s16(0, 0, 0))
{
m_enable_shaders = data->m_use_shaders;
m_use_tangent_vertices = data->m_use_tangent_vertices;
@ -1401,6 +1402,15 @@ void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
}
}
void MapBlockMesh::updatePlanetOffset(v3s16 planet_offset) {
if (planet_offset != m_planet_offset) {
translateMesh(m_mesh, intToFloat(m_planet_offset - planet_offset, BS));
if (m_enable_vbo)
m_mesh->setDirty();
m_planet_offset = planet_offset;
}
}
/*
MeshCollector
*/

View File

@ -123,6 +123,7 @@ public:
}
void updateCameraOffset(v3s16 camera_offset);
void updatePlanetOffset(v3s16 planet_offset);
private:
scene::IMesh *m_mesh;
@ -160,6 +161,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;
};