#include "client/tile.h"
#include <ICameraSceneNode.h>
#include <ISceneNode.h>
+#include <plane3d.h>
+#include <array>
#include <list>
+#include "util/Optional.h"
class LocalPlayer;
struct MapDrawControl;
class Client;
+class RenderingEngine;
class WieldMeshSceneNode;
-struct Nametag {
+struct Nametag
+{
+ scene::ISceneNode *parent_node;
+ std::string text;
+ video::SColor textcolor;
+ Optional<video::SColor> bgcolor;
+ v3f pos;
+
Nametag(scene::ISceneNode *a_parent_node,
- const std::string &a_nametag_text,
- const video::SColor &a_nametag_color,
- const v3f &a_nametag_pos):
+ const std::string &text,
+ const video::SColor &textcolor,
+ const Optional<video::SColor> &bgcolor,
+ const v3f &pos):
parent_node(a_parent_node),
- nametag_text(a_nametag_text),
- nametag_color(a_nametag_color),
- nametag_pos(a_nametag_pos)
+ text(text),
+ textcolor(textcolor),
+ bgcolor(bgcolor),
+ pos(pos)
{
}
- scene::ISceneNode *parent_node;
- std::string nametag_text;
- video::SColor nametag_color;
- v3f nametag_pos;
+
+ video::SColor getBgColor(bool use_fallback) const
+ {
+ if (bgcolor)
+ return bgcolor.value();
+ else if (!use_fallback)
+ return video::SColor(0, 0, 0, 0);
+ else if (textcolor.getLuminance() > 186)
+ // Dark background for light text
+ return video::SColor(50, 50, 50, 50);
+ else
+ // Light background for dark text
+ return video::SColor(50, 255, 255, 255);
+ }
+};
+
+enum HandIndex { MAINHAND = 0, OFFHAND = 1 };
+
+class WieldNode
+{
+public:
+ WieldNode(HandIndex index, Client *client, scene::ISceneManager *mgr);
+ void step(f32 dtime);
+ void addArmInertia(f32 player_yaw, v3f camera_direction);
+ void update(video::SColor player_light_color, f32 view_bobbing_anim, f32 tool_reload_ratio);
+ void setDigging(s32 button);
+ void wield(const ItemStack &item);
+
+private:
+ HandIndex m_index;
+ int m_direction;
+
+ Client *m_client;
+ WieldMeshSceneNode *m_meshnode = nullptr;
+
+ // Digging animation frame (0 <= m_digging_anim < 1)
+ f32 m_digging_anim = 0.0f;
+
+ // If -1, no digging animation
+ // If 0, left-click digging animation
+ // If 1, right-click digging animation
+ s32 m_digging_button = -1;
+
+ // Animation when changing wielded item
+ f32 m_change_timer = 0.125f;
+ ItemStack m_item_next;
+ bool m_item_old = false;
+
+ // Last known light color of the player
+ video::SColor m_player_light_color;
+
+ // Arm inertia
+ v2f m_offset = v2f(55.0f, -35.0f);
+ v2f m_arm_dir;
+ v2f m_cam_vel;
+ v2f m_cam_vel_old;
+ v2f m_last_cam_pos;
};
enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
class Camera
{
public:
- Camera(MapDrawControl &draw_control, Client *client);
+ Camera(MapDrawControl &draw_control, Client *client, RenderingEngine *rendering_engine);
~Camera();
// Get camera scene node.
return MYMAX(m_fov_x, m_fov_y);
}
- // Checks if the constructor was able to create the scene nodes
- bool successfullyCreated(std::string &error_message);
+ // Returns a lambda that when called with an object's position and bounding-sphere
+ // radius (both in BS space) returns true if, and only if the object should be
+ // frustum-culled.
+ auto getFrustumCuller() const
+ {
+ return [planes = getFrustumCullPlanes(),
+ camera_offset = intToFloat(m_camera_offset, BS)
+ ](v3f position, f32 radius) {
+ v3f pos_camspace = position - camera_offset;
+ for (auto &plane : planes) {
+ if (plane.getDistanceTo(pos_camspace) > radius)
+ return true;
+ }
+ return false;
+ };
+ }
+
+ // Notify about new server-sent FOV and initialize smooth FOV transition
+ void notifyFovChange();
// Step the camera: updates the viewing range and view bobbing.
void step(f32 dtime);
// Update the camera from the local player's position.
- // busytime is used to adjust the viewing range.
- void update(LocalPlayer* player, f32 frametime, f32 busytime,
- f32 tool_reload_ratio);
+ void update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio);
// Update render distance
void updateViewingRange();
// Start digging animation
- // Pass 0 for left click, 1 for right click
- void setDigging(s32 button);
+ // button: Pass 0 for left click, 1 for right click
+ void setDigging(s32 button, HandIndex hand);
// Replace the wielded item mesh
- void wield(const ItemStack &item);
+ void wield(const ItemStack &item, HandIndex hand);
// Draw the wielded tool.
// This has to happen *after* the main scene is drawn.
}
Nametag *addNametag(scene::ISceneNode *parent_node,
- const std::string &nametag_text, video::SColor nametag_color,
- const v3f &pos);
+ const std::string &text, video::SColor textcolor,
+ Optional<video::SColor> bgcolor, const v3f &pos);
void removeNametag(Nametag *nametag);
- const std::list<Nametag *> &getNametags() { return m_nametags; }
-
void drawNametags();
inline void addArmInertia(f32 player_yaw);
private:
+ // Use getFrustumCuller().
+ // This helper just exists to decrease the header's number of includes.
+ std::array<core::plane3d<f32>, 4> getFrustumCullPlanes() const;
+
// Nodes
scene::ISceneNode *m_playernode = nullptr;
scene::ISceneNode *m_headnode = nullptr;
scene::ICameraSceneNode *m_cameranode = nullptr;
+ WieldNode *m_wieldnodes[2];
+
scene::ISceneManager *m_wieldmgr = nullptr;
- WieldMeshSceneNode *m_wieldnode = nullptr;
// draw control
MapDrawControl& m_draw_control;
Client *m_client;
+ // Default Client FOV (as defined by the "fov" setting)
+ f32 m_cache_fov;
+
// Absolute camera position
v3f m_camera_position;
// Absolute camera direction
// Camera offset
v3s16 m_camera_offset;
- v2f m_wieldmesh_offset = v2f(55.0f, -35.0f);
- v2f m_arm_dir;
- v2f m_cam_vel;
- v2f m_cam_vel_old;
- v2f m_last_cam_pos;
+ bool m_stepheight_smooth_active = false;
+
+ // Server-sent FOV variables
+ bool m_server_sent_fov = false;
+ f32 m_curr_fov_degrees, m_old_fov_degrees, m_target_fov_degrees;
+
+ // FOV transition variables
+ bool m_fov_transition_active = false;
+ f32 m_fov_diff, m_transition_time;
// Field of view and aspect ratio stuff
f32 m_aspect = 1.0f;
// Fall view bobbing
f32 m_view_bobbing_fall = 0.0f;
- // Digging animation frame (0 <= m_digging_anim < 1)
- f32 m_digging_anim = 0.0f;
- // If -1, no digging animation
- // If 0, left-click digging animation
- // If 1, right-click digging animation
- s32 m_digging_button = -1;
-
- // Animation when changing wielded item
- f32 m_wield_change_timer = 0.125f;
- ItemStack m_wield_item_next;
-
CameraMode m_camera_mode = CAMERA_MODE_FIRST;
f32 m_cache_fall_bobbing_amount;
f32 m_cache_view_bobbing_amount;
- f32 m_cache_fov;
bool m_arm_inertia;
std::list<Nametag *> m_nametags;
+ bool m_show_nametag_backgrounds;
+
+ // Last known light color of the player
+ video::SColor m_player_light_color;
};