Skip to content

Commit

Permalink
Oculus Rift|Renderer: Prevent cheating by peeking through surfaces
Browse files Browse the repository at this point in the history
In Oculus Rift (head tracked) mode, putting one's head physically
through walls and planes results in a black screen.

Todo for later: The blanking out should occur at near clip distance.
  • Loading branch information
skyjake committed Aug 24, 2014
1 parent beac774 commit ec8ca3c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
10 changes: 10 additions & 0 deletions doomsday/client/include/world/worldsystem.h
Expand Up @@ -34,6 +34,7 @@
#include <de/liblegacy.h>
#include <de/Error>
#include <de/Observers>
#include <de/Vector>
#include <de/System>

#ifdef __CLIENT__
Expand Down Expand Up @@ -152,6 +153,15 @@ class WorldSystem : public de::System
*/
Hand &hand(coord_t *distance = 0) const;

/**
* Determines if a point is in the void.
*
* @param pos Point.
*
* @return @c true, if the point is outside any of the world's maps.
*/
bool isPointInVoid(de::Vector3d const &pos) const;

#endif // __CLIENT__

private:
Expand Down
10 changes: 9 additions & 1 deletion doomsday/client/src/render/viewports.cpp
Expand Up @@ -892,6 +892,14 @@ DENG_EXTERN_C void R_RenderPlayerView(int num)
setupViewMatrix();
setupPlayerSprites();

if(ClientApp::vr().mode() == VRConfig::OculusRift &&
ClientApp::worldSystem().isPointInVoid(Rend_EyeOrigin().xzy()))
{
// Putting one's head in the wall will cause a blank screen.
GLState::current().target().clear(GLTarget::Color);
return;
}

// Hide the viewPlayer's mobj?
int oldFlags = 0;
if(!(player->shared.flags & DDPF_CHASECAM))
Expand Down Expand Up @@ -1023,7 +1031,7 @@ static void clearViewPorts()
if(!plr->shared.inGame || !(plr->shared.flags & DDPF_LOCAL))
continue;

if(P_IsInVoid(plr))
if(P_IsInVoid(plr) || !ClientApp::worldSystem().hasMap())
{
bits |= GL_COLOR_BUFFER_BIT;
break;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/world/map.cpp
Expand Up @@ -2799,7 +2799,7 @@ BspLeaf &Map::bspLeafAt(Vector2d const &point) const

int side = bspNode.partition().pointOnSide(point) < 0;

// Decend to the child subspace on "this" side.
// Descend to the child subspace on "this" side.
bspElement = bspNode.childPtr(side);
}

Expand Down
34 changes: 34 additions & 0 deletions doomsday/client/src/world/worldsystem.cpp
Expand Up @@ -907,6 +907,40 @@ void WorldSystem::endFrame()
DENG2_FOR_AUDIENCE(FrameEnd, i) i->worldSystemFrameEnds();
}

bool WorldSystem::isPointInVoid(Vector3d const &pos) const
{
// Everything is void if there is no map.
if(!hasMap()) return true;

SectorCluster const *cluster = map().clusterAt(pos);
if(!cluster) return true;

// Check the planes of the cluster.
if(cluster->visCeiling().surface().hasSkyMaskedMaterial())
{
coord_t const skyCeil = cluster->sector().map().skyFixCeiling();
if(skyCeil < DDMAXFLOAT && pos.z > skyCeil)
return true;
}
else if(pos.z > cluster->visCeiling().heightSmoothed())
{
return true;
}

if(cluster->visFloor().surface().hasSkyMaskedMaterial())
{
coord_t const skyFloor = cluster->sector().map().skyFixFloor();
if(skyFloor > DDMINFLOAT && pos.z < skyFloor)
return true;
}
else if(pos.z < cluster->visFloor().heightSmoothed())
{
return true;
}

return false; // Not in the void.
}

#endif // __CLIENT__

void WorldSystem::consoleRegister() // static
Expand Down

0 comments on commit ec8ca3c

Please sign in to comment.