Add some more hacks to make planet seem more realistic
parent
50f8a37297
commit
8f6ef3764f
|
@ -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;
|
||||
|
||||
|
|
28
src/game.cpp
28
src/game.cpp
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue