Optimize/adjust blocks/ActiveObjects sent at the server based on client settings...
authorlhofhansl <lhofhansl@yahoo.com>
Wed, 30 Nov 2016 08:13:14 +0000 (00:13 -0800)
committerZeno- <kde.psych@gmail.com>
Wed, 30 Nov 2016 08:13:14 +0000 (18:13 +1000)
Optimize/adjust blocks and active blocks sent at the server based on client settings.

src/camera.cpp
src/client.cpp
src/clientiface.cpp
src/clientmap.h
src/content_sao.cpp
src/content_sao.h
src/localplayer.cpp
src/localplayer.h
src/network/networkprotocol.h
src/network/serverpackethandler.cpp
src/server.cpp

index b86f218fe95cae275658874f0fc6b59396e928a5..43980db1cc8efcd7684025bb85ff70b40e3530f3 100644 (file)
@@ -484,13 +484,12 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
 
 void Camera::updateViewingRange()
 {
+       f32 viewing_range = g_settings->getFloat("viewing_range");
+       m_draw_control.wanted_range = viewing_range;
        if (m_draw_control.range_all) {
                m_cameranode->setFarValue(100000.0);
                return;
        }
-
-       f32 viewing_range = g_settings->getFloat("viewing_range");
-       m_draw_control.wanted_range = viewing_range;
        m_cameranode->setFarValue((viewing_range < 2000) ? 2000 * BS : viewing_range * BS);
 }
 
index 3726f5bc478b0a903ad3dbde40daac253f74d344..5a3dc5df768fa2e6203d57c13d37fa45561e7991 100644 (file)
@@ -930,13 +930,16 @@ void Client::Send(NetworkPacket* pkt)
 }
 
 // Will fill up 12 + 12 + 4 + 4 + 4 bytes
-void writePlayerPos(LocalPlayer *myplayer, NetworkPacket *pkt)
+void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt)
 {
-       v3f pf         = myplayer->getPosition() * 100;
-       v3f sf         = myplayer->getSpeed() * 100;
-       s32 pitch      = myplayer->getPitch() * 100;
-       s32 yaw        = myplayer->getYaw() * 100;
-       u32 keyPressed = myplayer->keyPressed;
+       v3f pf           = myplayer->getPosition() * 100;
+       v3f sf           = myplayer->getSpeed() * 100;
+       s32 pitch        = myplayer->getPitch() * 100;
+       s32 yaw          = myplayer->getYaw() * 100;
+       u32 keyPressed   = myplayer->keyPressed;
+       // scaled by 80, so that pi can fit into a u8
+       u8 fov           = clientMap->getCameraFov() * 80;
+       u8 wanted_range  = clientMap->getControl().wanted_range / MAP_BLOCKSIZE;
 
        v3s32 position(pf.X, pf.Y, pf.Z);
        v3s32 speed(sf.X, sf.Y, sf.Z);
@@ -948,9 +951,11 @@ void writePlayerPos(LocalPlayer *myplayer, NetworkPacket *pkt)
                [12+12] s32 pitch*100
                [12+12+4] s32 yaw*100
                [12+12+4+4] u32 keyPressed
+               [12+12+4+4+1] u8 fov*80
+               [12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE
        */
-
        *pkt << position << speed << pitch << yaw << keyPressed;
+       *pkt << fov << wanted_range;
 }
 
 void Client::interact(u8 action, const PointedThing& pointed)
@@ -992,7 +997,7 @@ void Client::interact(u8 action, const PointedThing& pointed)
 
        pkt.putLongString(tmp_os.str());
 
-       writePlayerPos(myplayer, &pkt);
+       writePlayerPos(myplayer, &m_env.getClientMap(), &pkt);
 
        Send(&pkt);
 }
@@ -1296,19 +1301,30 @@ void Client::sendPlayerPos()
        if(myplayer == NULL)
                return;
 
+       ClientMap &map = m_env.getClientMap();
+
+       u8 camera_fov    = map.getCameraFov();
+       u8 wanted_range  = map.getControl().wanted_range;
+
        // Save bandwidth by only updating position when something changed
        if(myplayer->last_position        == myplayer->getPosition() &&
-                       myplayer->last_speed      == myplayer->getSpeed()    &&
-                       myplayer->last_pitch      == myplayer->getPitch()    &&
-                       myplayer->last_yaw        == myplayer->getYaw()      &&
-                       myplayer->last_keyPressed == myplayer->keyPressed)
+                       myplayer->last_speed        == myplayer->getSpeed()    &&
+                       myplayer->last_pitch        == myplayer->getPitch()    &&
+                       myplayer->last_yaw          == myplayer->getYaw()      &&
+                       myplayer->last_keyPressed   == myplayer->keyPressed    &&
+                       myplayer->last_camera_fov   == camera_fov              &&
+                       myplayer->last_wanted_range == wanted_range)
                return;
 
-       myplayer->last_position   = myplayer->getPosition();
-       myplayer->last_speed      = myplayer->getSpeed();
-       myplayer->last_pitch      = myplayer->getPitch();
-       myplayer->last_yaw        = myplayer->getYaw();
-       myplayer->last_keyPressed = myplayer->keyPressed;
+       myplayer->last_position     = myplayer->getPosition();
+       myplayer->last_speed        = myplayer->getSpeed();
+       myplayer->last_pitch        = myplayer->getPitch();
+       myplayer->last_yaw          = myplayer->getYaw();
+       myplayer->last_keyPressed   = myplayer->keyPressed;
+       myplayer->last_camera_fov   = camera_fov;
+       myplayer->last_wanted_range = wanted_range;
+
+       //infostream << "Sending Player Position information" << std::endl;
 
        u16 our_peer_id;
        {
@@ -1324,7 +1340,7 @@ void Client::sendPlayerPos()
 
        NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4);
 
-       writePlayerPos(myplayer, &pkt);
+       writePlayerPos(myplayer, &map, &pkt);
 
        Send(&pkt);
 }
index bdc16f31cae700a5ec63b9d44a666da3323099fe..abe878ecc328208bdab5c07b29490fce961a8239 100644 (file)
@@ -173,12 +173,20 @@ void RemoteClient::GetNextBlocks (
        */
        s32 new_nearest_unsent_d = -1;
 
-       const s16 full_d_max = g_settings->getS16("max_block_send_distance");
-       const s16 d_opt = g_settings->getS16("block_send_optimize_distance");
+       // get view range and camera fov from the client
+       s16 wanted_range = sao->getWantedRange();
+       float camera_fov = sao->getFov();
+       // if FOV, wanted_range are not available (old client), fall back to old default
+       if (wanted_range <= 0) wanted_range = 1000;
+       if (camera_fov <= 0) camera_fov = (72.0*M_PI/180) * 4./3.;
+
+       const s16 full_d_max = MYMIN(g_settings->getS16("max_block_send_distance"), wanted_range);
+       const s16 d_opt = MYMIN(g_settings->getS16("block_send_optimize_distance"), wanted_range);
        const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
+       //infostream << "Fov from client " << camera_fov << " full_d_max " << full_d_max << std::endl;
 
        s16 d_max = full_d_max;
-       s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
+       s16 d_max_gen = MYMIN(g_settings->getS16("max_block_generate_distance"), wanted_range);
 
        // Don't loop very much at a time
        s16 max_d_increment_at_time = 2;
@@ -242,7 +250,6 @@ void RemoteClient::GetNextBlocks (
                                FOV setting. The default of 72 degrees is fine.
                        */
 
-                       float camera_fov = (72.0*M_PI/180) * 4./3.;
                        if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, d_blocks_in_sight) == false)
                        {
                                continue;
index 8855eecf692660e63e5e1920e2107f298cabed83..cb686ff33c9ee4857290b2a8c5ff8db0e0fc2341 100644 (file)
@@ -138,7 +138,9 @@ public:
        {
                return (m_last_drawn_sectors.find(p) != m_last_drawn_sectors.end());
        }
-       
+
+       const MapDrawControl & getControl() const { return m_control; }
+       f32 getCameraFov() const { return m_camera_fov; }
 private:
        Client *m_client;
        
index 609673ed93e7873aa2dd07bcba5315f145ec3d9d..77ab51a02694afa919393e1e4f4d125841830a72 100644 (file)
@@ -781,6 +781,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer
        m_attachment_sent(false),
        m_breath(PLAYER_MAX_BREATH),
        m_pitch(0),
+       m_fov(0),
+       m_wanted_range(0),
        // public
        m_physics_override_speed(1),
        m_physics_override_jump(1),
@@ -1099,6 +1101,22 @@ void PlayerSAO::setYaw(const float yaw)
        UnitSAO::setYaw(yaw);
 }
 
+void PlayerSAO::setFov(const float fov)
+{
+       if (m_player && fov != m_fov)
+               m_player->setDirty(true);
+
+       m_fov = fov;
+}
+
+void PlayerSAO::setWantedRange(const s16 range)
+{
+       if (m_player && range != m_wanted_range)
+               m_player->setDirty(true);
+
+       m_wanted_range = range;
+}
+
 void PlayerSAO::setYawAndSend(const float yaw)
 {
        setYaw(yaw);
index c5b066f505249fffa99d48cb752632b1d9e45bf8..86255183d50e15fa80e34db4cf87d30a7f981088 100644 (file)
@@ -214,6 +214,10 @@ public:
        f32 getRadPitch() const { return m_pitch * core::DEGTORAD; }
        // Deprecated
        f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
+       void setFov(const float pitch);
+       f32 getFov() const { return m_fov; }
+       void setWantedRange(const s16 range);
+       s16 getWantedRange() const { return m_wanted_range; }
 
        /*
                Interaction interface
@@ -364,6 +368,8 @@ private:
        bool m_attachment_sent;
        u16 m_breath;
        f32 m_pitch;
+       f32 m_fov;
+       s16 m_wanted_range;
 public:
        float m_physics_override_speed;
        float m_physics_override_jump;
index 71efb23432d0d4cdff7bb34060c34dc16fa8d8aa..4d0ca0600091b56ea33b1e0a738126177821d61f 100644 (file)
@@ -56,6 +56,8 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name):
        last_pitch(0),
        last_yaw(0),
        last_keyPressed(0),
+       last_camera_fov(0),
+       last_wanted_range(0),
        camera_impact(0.f),
        last_animation(NO_ANIM),
        hotbar_image(""),
index 749f8f8ce352336def3973e308cd3068d5a43355..7a1cb7466496772028b9895204e9ea4058d564ea 100644 (file)
@@ -75,6 +75,8 @@ public:
        float last_pitch;
        float last_yaw;
        unsigned int last_keyPressed;
+       u8 last_camera_fov;
+       u8 last_wanted_range;
 
        float camera_impact;
 
index e3fcae0c68710ddaaefdac20302a7c088fcc4aa4..c9919e1c4828c7841216a23787b640cb84be0adf 100644 (file)
@@ -651,6 +651,8 @@ enum ToServerCommand
                [2+12+12] s32 pitch*100
                [2+12+12+4] s32 yaw*100
                [2+12+12+4+4] u32 keyPressed
+               [2+12+12+4+4+1] u8 fov*80
+               [2+12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE
        */
 
        TOSERVER_GOTBLOCKS = 0x24,
index 70eb0a8284135e65a6b6cbee62f2827b2563444c..5e50bb865d560fe2273565e5681f8723e99e05c4 100644 (file)
@@ -782,6 +782,7 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
 
        v3s32 ps, ss;
        s32 f32pitch, f32yaw;
+       u8 f32fov;
 
        *pkt >> ps;
        *pkt >> ss;
@@ -792,8 +793,18 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
        f32 yaw = (f32)f32yaw / 100.0;
        u32 keyPressed = 0;
 
+       // default behavior (in case an old client doesn't send these)
+       f32 fov = (72.0*M_PI/180) * 4./3.;
+       u8 wanted_range = 0;
+
        if (pkt->getRemainingBytes() >= 4)
                *pkt >> keyPressed;
+       if (pkt->getRemainingBytes() >= 1) {
+               *pkt >> f32fov;
+               fov = (f32)f32fov / 80.0;
+       }
+       if (pkt->getRemainingBytes() >= 1)
+               *pkt >> wanted_range;
 
        v3f position((f32)ps.X / 100.0, (f32)ps.Y / 100.0, (f32)ps.Z / 100.0);
        v3f speed((f32)ss.X / 100.0, (f32)ss.Y / 100.0, (f32)ss.Z / 100.0);
@@ -805,6 +816,8 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
        player->setSpeed(speed);
        playersao->setPitch(pitch);
        playersao->setYaw(yaw);
+       playersao->setFov(fov);
+       playersao->setWantedRange(wanted_range);
        player->keyPressed = keyPressed;
        player->control.up = (keyPressed & 1);
        player->control.down = (keyPressed & 2);
index fe67ac96e87f49c7d3b391eaaecac0f025cea9eb..c9d5c7129dbe3b57d58b5209f97d00efec74ee59 100644 (file)
@@ -705,11 +705,15 @@ void Server::AsyncRunStep(bool initial_step)
                        if (playersao == NULL)
                                continue;
 
+                       s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
+                       if (my_radius <= 0) my_radius = radius;
+                       //infostream << "Server: Active Radius " << my_radius << std::endl;
+
                        std::queue<u16> removed_objects;
                        std::queue<u16> added_objects;
-                       m_env->getRemovedActiveObjects(playersao, radius, player_radius,
+                       m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
                                        client->m_known_objects, removed_objects);
-                       m_env->getAddedActiveObjects(playersao, radius, player_radius,
+                       m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
                                        client->m_known_objects, added_objects);
 
                        // Ignore if nothing happened