Skip to content

Commit

Permalink
Add support for interlaced polarized 3d screens
Browse files Browse the repository at this point in the history
Add (experimental) support for topbottom as well as sidebyside 3d mode
  • Loading branch information
sapier authored and sapier committed May 17, 2014
1 parent d9f6f9e commit 09970b7
Show file tree
Hide file tree
Showing 17 changed files with 909 additions and 423 deletions.
12 changes: 9 additions & 3 deletions minetest.conf.example
Expand Up @@ -127,9 +127,15 @@
#view_bobbing_amount = 1.0
# Amount of fall bobbing (0 = no fall bobbing, 1.0 = normal, 2.0 = double)
#fall_bobbing_amount = 0.0
# Anaglyph stereo
#anaglyph = false
#anaglyph_strength = 0.1
# 3d support,
# right now:
# "none" = no 3d output,
# "anaglyph" = cyan/magenta color 3d,
# "interlaced" = odd/even line based polarisation screen support,
# "topbottom" = split screen top boton,
# "sidebyside" = split screen side by side
#3d_mode = none
#3d_paralax_strength = 0.025
# In-game chat console background color (R,G,B)
#console_color = (0,0,0)
# In-game chat console background alpha (opaqueness, between 0 and 255)
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Expand Up @@ -460,6 +460,7 @@ set(minetest_SRCS
guiEngine.cpp
guiFileSelectMenu.cpp
convert_json.cpp
drawscene.cpp
${minetest_SCRIPT_SRCS}
)

Expand Down
79 changes: 52 additions & 27 deletions src/camera.cpp
Expand Up @@ -82,7 +82,9 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
m_wield_change_timer(0.125),
m_wield_mesh_next(NULL),
m_previous_playeritem(-1),
m_previous_itemname("")
m_previous_itemname(""),

m_camera_mode(CAMERA_MODE_FIRST)
{
//dstream<<__FUNCTION_NAME<<std::endl;

Expand Down Expand Up @@ -159,8 +161,10 @@ void Camera::step(f32 dtime)
if(m_wield_change_timer > 0.125)
m_wield_change_timer = 0.125;

if(m_wield_change_timer >= 0 && was_under_zero) {
if(m_wield_mesh_next) {
if(m_wield_change_timer >= 0 && was_under_zero)
{
if(m_wield_mesh_next)
{
m_wieldnode->setMesh(m_wield_mesh_next);
m_wieldnode->setVisible(true);
} else {
Expand Down Expand Up @@ -189,11 +193,14 @@ void Camera::step(f32 dtime)
#endif
#if 1
// Animation is getting turned off
if(m_view_bobbing_anim < 0.25){
if(m_view_bobbing_anim < 0.25)
{
m_view_bobbing_anim -= offset;
} else if(m_view_bobbing_anim > 0.75){
} else if(m_view_bobbing_anim > 0.75) {
m_view_bobbing_anim += offset;
} if(m_view_bobbing_anim < 0.5){
}
if(m_view_bobbing_anim < 0.5)
{
m_view_bobbing_anim += offset;
if(m_view_bobbing_anim > 0.5)
m_view_bobbing_anim = 0.5;
Expand All @@ -217,7 +224,8 @@ void Camera::step(f32 dtime)
bool step = (was == 0 ||
(was < 0.5f && m_view_bobbing_anim >= 0.5f) ||
(was > 0.5f && m_view_bobbing_anim <= 0.5f));
if(step){
if(step)
{
MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep");
m_gamedef->event()->put(e);
}
Expand All @@ -237,10 +245,11 @@ void Camera::step(f32 dtime)
float lim = 0.15;
if(m_digging_anim_was < lim && m_digging_anim >= lim)
{
if(m_digging_button == 0){
if(m_digging_button == 0)
{
MtEvent *e = new SimpleTriggerEvent("CameraPunchLeft");
m_gamedef->event()->put(e);
} else if(m_digging_button == 1){
} else if(m_digging_button == 1) {
MtEvent *e = new SimpleTriggerEvent("CameraPunchRight");
m_gamedef->event()->put(e);
}
Expand All @@ -249,8 +258,7 @@ void Camera::step(f32 dtime)
}

void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
f32 tool_reload_ratio,
int current_camera_mode, ClientEnvironment &c_env)
f32 tool_reload_ratio, ClientEnvironment &c_env)
{
// Get player position
// Smooth the movement when walking up stairs
Expand Down Expand Up @@ -278,7 +286,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,

// Fall bobbing animation
float fall_bobbing = 0;
if(player->camera_impact >= 1 && current_camera_mode < CAMERA_MODE_THIRD)
if(player->camera_impact >= 1 && m_camera_mode < CAMERA_MODE_THIRD)
{
if(m_view_bobbing_fall == -1) // Effect took place and has finished
player->camera_impact = m_view_bobbing_fall = 0;
Expand All @@ -297,7 +305,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,

// Calculate players eye offset for different camera modes
v3f PlayerEyeOffset = player->getEyeOffset();
if (current_camera_mode == CAMERA_MODE_FIRST)
if (m_camera_mode == CAMERA_MODE_FIRST)
PlayerEyeOffset += player->eye_offset_first;
else
PlayerEyeOffset += player->eye_offset_third;
Expand All @@ -312,7 +320,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
v3f rel_cam_target = v3f(0,0,1);
v3f rel_cam_up = v3f(0,1,0);

if (m_view_bobbing_anim != 0 && current_camera_mode < CAMERA_MODE_THIRD)
if (m_view_bobbing_anim != 0 && m_camera_mode < CAMERA_MODE_THIRD)
{
f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
Expand Down Expand Up @@ -365,16 +373,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
v3f my_cp = m_camera_position;

// Reposition the camera for third person view
if (current_camera_mode > CAMERA_MODE_FIRST) {
if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
if (m_camera_mode > CAMERA_MODE_FIRST)
{
if (m_camera_mode == CAMERA_MODE_THIRD_FRONT)
m_camera_direction *= -1;

my_cp.Y += 2;

// Calculate new position
bool abort = false;
for (int i = BS; i <= BS*2; i++) {
for (int i = BS; i <= BS*2; i++)
{
my_cp.X = m_camera_position.X + m_camera_direction.X*-i;
my_cp.Z = m_camera_position.Z + m_camera_direction.Z*-i;
if (i > 12)
Expand All @@ -384,7 +393,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
INodeDefManager *nodemgr = m_gamedef->ndef();
MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS));
const ContentFeatures& features = nodemgr->get(n);
if(features.walkable) {
if(features.walkable)
{
my_cp.X += m_camera_direction.X*-1*-BS/2;
my_cp.Z += m_camera_direction.Z*-1*-BS/2;
my_cp.Y += m_camera_direction.Y*-1*-BS/2;
Expand Down Expand Up @@ -413,7 +423,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
m_cameranode->setTarget(my_cp-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction);

// update the camera position in front-view mode to render blocks behind player
if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
if (m_camera_mode == CAMERA_MODE_THIRD_FRONT)
m_camera_position = my_cp;

// Get FOV setting
Expand All @@ -439,7 +449,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
wield_position.Y -= 40 + m_wield_change_timer*320;
else
wield_position.Y -= 40 - m_wield_change_timer*320;
if(m_digging_anim < 0.05 || m_digging_anim > 0.5){
if(m_digging_anim < 0.05 || m_digging_anim > 0.5)
{
f32 frac = 1.0;
if(m_digging_anim > 0.5)
frac = 2.0 * (m_digging_anim - 0.5);
Expand Down Expand Up @@ -468,8 +479,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * M_PI));
quat_slerp.toEuler(wield_rotation);
wield_rotation *= core::RADTODEG;
}
else {
} else {
f32 bobfrac = my_modf(m_view_bobbing_anim);
wield_position.X -= sin(bobfrac*M_PI*2.0) * 3.0;
wield_position.Y += sin(my_modf(bobfrac*2.0)*M_PI) * 3.0;
Expand Down Expand Up @@ -654,12 +664,14 @@ void Camera::wield(const ItemStack &item, u16 playeritem)
std::string itemname = item.getDefinition(idef).name;
m_wield_mesh_next = idef->getWieldMesh(itemname, m_gamedef);
if(playeritem != m_previous_playeritem &&
!(m_previous_itemname == "" && itemname == "")) {
!(m_previous_itemname == "" && itemname == ""))
{
m_previous_playeritem = playeritem;
m_previous_itemname = itemname;
if(m_wield_change_timer >= 0.125)
m_wield_change_timer = -0.125;
else if(m_wield_change_timer > 0) {
else if(m_wield_change_timer > 0)
{
m_wield_change_timer = -m_wield_change_timer;
}
} else {
Expand All @@ -670,7 +682,8 @@ void Camera::wield(const ItemStack &item, u16 playeritem)
m_wieldnode->setVisible(false);
}
m_wield_mesh_next = NULL;
if(m_previous_itemname != itemname) {
if(m_previous_itemname != itemname)
{
m_previous_itemname = itemname;
m_wield_change_timer = 0;
}
Expand All @@ -679,7 +692,7 @@ void Camera::wield(const ItemStack &item, u16 playeritem)
}
}

void Camera::drawWieldedTool()
void Camera::drawWieldedTool(irr::core::matrix4* translation)
{
// Set vertex colors of wield mesh according to light level
u8 li = m_wieldlight;
Expand All @@ -695,5 +708,17 @@ void Camera::drawWieldedTool()
cam->setFOV(72.0*M_PI/180.0);
cam->setNearValue(0.1);
cam->setFarValue(100);
if (translation != NULL)
{
irr::core::matrix4 startMatrix = cam->getAbsoluteTransformation();
irr::core::vector3df focusPoint = (cam->getTarget()
- cam->getAbsolutePosition()).setLength(1)
+ cam->getAbsolutePosition();

irr::core::vector3df camera_pos =
(startMatrix * *translation).getTranslation();
cam->setPosition(camera_pos);
cam->setTarget(focusPoint);
}
m_wieldmgr->drawAll();
}
25 changes: 21 additions & 4 deletions src/camera.h
Expand Up @@ -33,7 +33,7 @@ class LocalPlayer;
struct MapDrawControl;
class IGameDef;

enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};

/*
Client camera class, manages the player and camera scene nodes, the viewing distance
Expand Down Expand Up @@ -117,8 +117,7 @@ class Camera
// 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,
int current_camera_mode, ClientEnvironment &c_env);
f32 tool_reload_ratio, ClientEnvironment &c_env);

// Render distance feedback loop
void updateViewingRange(f32 frametime_in, f32 busytime_in);
Expand All @@ -133,7 +132,23 @@ class Camera
// Draw the wielded tool.
// This has to happen *after* the main scene is drawn.
// Warning: This clears the Z buffer.
void drawWieldedTool();
void drawWieldedTool(irr::core::matrix4* translation=NULL);

// Toggle the current camera mode
void toggleCameraMode() {
if (m_camera_mode == CAMERA_MODE_FIRST)
m_camera_mode = CAMERA_MODE_THIRD;
else if (m_camera_mode == CAMERA_MODE_THIRD)
m_camera_mode = CAMERA_MODE_THIRD_FRONT;
else
m_camera_mode = CAMERA_MODE_FIRST;
}

//read the current camera mode
inline CameraMode getCameraMode()
{
return m_camera_mode;
}

private:
// Nodes
Expand Down Expand Up @@ -196,6 +211,8 @@ class Camera
scene::IMesh *m_wield_mesh_next;
u16 m_previous_playeritem;
std::string m_previous_itemname;

CameraMode m_camera_mode;
};

#endif
11 changes: 5 additions & 6 deletions src/client.cpp
Expand Up @@ -51,6 +51,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/directiontables.h"
#include "util/pointedthing.h"
#include "version.h"
#include "drawscene.h"

extern gui::IGUIEnvironment* guienv;

/*
QueuedMeshUpdate
Expand Down Expand Up @@ -2648,10 +2651,6 @@ float Client::mediaReceiveProgress()
return 1.0; // downloader only exists when not yet done
}

void draw_load_screen(const std::wstring &text,
IrrlichtDevice* device, gui::IGUIFont* font,
float dtime=0 ,int percent=0, bool clouds=true);

void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
{
infostream<<"Client::afterContentReceived() started"<<std::endl;
Expand Down Expand Up @@ -2680,7 +2679,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
{
verbosestream<<"Updating item textures and meshes"<<std::endl;
wchar_t* text = wgettext("Item textures...");
draw_load_screen(text,device,font,0,0);
draw_load_screen(text, device, guienv, font, 0, 0);
std::set<std::string> names = m_itemdef->getAll();
size_t size = names.size();
size_t count = 0;
Expand All @@ -2693,7 +2692,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
count++;
percent = count*100/size;
if (count%50 == 0) // only update every 50 item
draw_load_screen(text,device,font,0,percent);
draw_load_screen(text, device, guienv, font, 0, percent);
}
delete[] text;
}
Expand Down
8 changes: 4 additions & 4 deletions src/clientmap.cpp
Expand Up @@ -856,7 +856,7 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
return ret;
}

void ClientMap::renderPostFx()
void ClientMap::renderPostFx(CameraMode cam_mode)
{
INodeDefManager *nodemgr = m_gamedef->ndef();

Expand All @@ -867,16 +867,16 @@ void ClientMap::renderPostFx()
v3f camera_position = m_camera_position;
m_camera_mutex.Unlock();

LocalPlayer *player = m_client->getEnv().getLocalPlayer();

MapNode n = getNodeNoEx(floatToInt(camera_position, BS));

// - If the player is in a solid node, make everything black.
// - If the player is in liquid, draw a semi-transparent overlay.
// - Do not if player is in third person mode
const ContentFeatures& features = nodemgr->get(n);
video::SColor post_effect_color = features.post_effect_color;
if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")) && player->camera_mode == CAMERA_MODE_FIRST)
if(features.solidness == 2 && !(g_settings->getBool("noclip") &&
m_gamedef->checkLocalPrivilege("noclip")) &&
cam_mode == CAMERA_MODE_FIRST)
{
post_effect_color = video::SColor(255, 0, 0, 0);
}
Expand Down
3 changes: 2 additions & 1 deletion src/clientmap.h
Expand Up @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

#include "irrlichttypes_extrabloated.h"
#include "map.h"
#include "camera.h"
#include <set>
#include <map>

Expand Down Expand Up @@ -126,7 +127,7 @@ class ClientMap : public Map, public scene::ISceneNode
int getBackgroundBrightness(float max_d, u32 daylight_factor,
int oldvalue, bool *sunlight_seen_result);

void renderPostFx();
void renderPostFx(CameraMode cam_mode);

// For debug printing
virtual void PrintInfo(std::ostream &out);
Expand Down

0 comments on commit 09970b7

Please sign in to comment.