ComputeSphereVisibility function

- borrowed implementation of ComputeSphereVisibility from libwine
- added -lrt to Linux libs
dev-ui
Piotr Dziwinski 2012-07-18 21:47:47 +02:00
parent f364f378cf
commit 86ea086790
4 changed files with 108 additions and 3 deletions

View File

@ -5,6 +5,8 @@
# Configure options
option(DEBUG "Enable debug output" ON)
set(PLATFORM_LIBS "")
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(PLATFORM_WINDOWS 1)
set(PLATFORM_LINUX 0)
@ -13,6 +15,8 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(PLATFORM_WINDOWS 0)
set(PLATFORM_LINUX 1)
set(PLATFORM_OTHER 0)
# for clock_gettime
set(PLATFORM_LIBS "-lrt")
else()
set(PLATFORM_WINDOWS 0)
set(PLATFORM_LINUX 0)
@ -154,6 +158,7 @@ ${SDLIMAGE_LIBRARY}
${OPENGL_LIBRARY}
${PNG_LIBRARIES}
#CBot -- not yet WinAPI-independent
${PLATFORM_LIBS}
)
include_directories(. ${CMAKE_CURRENT_BINARY_DIR}

View File

@ -181,6 +181,24 @@ enum PrimitiveType
PRIMITIVE_TRIANGLE_STRIP
};
/**
\enum IntersectPlane
\brief Intersection plane of projection volume
These flags can be OR'd together. */
enum IntersectPlane
{
INTERSECT_PLANE_LEFT = 0x01,
INTERSECT_PLANE_RIGHT = 0x02,
INTERSECT_PLANE_TOP = 0x04,
INTERSECT_PLANE_BOTTOM = 0x08,
INTERSECT_PLANE_FRONT = 0x10,
INTERSECT_PLANE_BACK = 0x20,
INTERSECT_PLANE_ALL = INTERSECT_PLANE_LEFT | INTERSECT_PLANE_RIGHT |
INTERSECT_PLANE_TOP | INTERSECT_PLANE_BOTTOM |
INTERSECT_PLANE_FRONT | INTERSECT_PLANE_BACK
};
/*
Notes for rewriting DirectX code:
@ -324,9 +342,8 @@ public:
//! Renders primitive composed of vertices with multitexturing (2 textures)
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexTex2 *vertices, int vertexCount) = 0;
// TODO:
// virtual void ComputeSphereVisibility() = 0;
//! Tests whether a sphere intersects the 6 clipping planes of projection volume
virtual int ComputeSphereVisibility(Math::Vector center, float radius) = 0;
//! Enables/disables the given render state
virtual void SetRenderState(Gfx::RenderState state, bool enabled) = 0;

View File

@ -18,6 +18,7 @@
#include "common/image.h"
#include "graphics/opengl/gldevice.h"
#include "math/geometry.h"
#define GL_GLEXT_PROTOTYPES
@ -732,6 +733,87 @@ void Gfx::CGLDevice::DrawPrimitive(Gfx::PrimitiveType type, VertexTex2 *vertices
glEnd();
}
bool InPlane(Math::Vector normal, float originPlane, Math::Vector center, float radius)
{
float distance = (originPlane + Math::DotProduct(normal, center)) / normal.Length();
if (distance < -radius)
return true;
return false;
}
/*
The implementation of ComputeSphereVisibility is taken from libwine's device.c
Copyright of the WINE team, licensed under GNU LGPL v 2.1
*/
// TODO: testing
int Gfx::CGLDevice::ComputeSphereVisibility(Math::Vector center, float radius)
{
Math::Matrix m;
m.LoadIdentity();
m = Math::MultiplyMatrices(m, m_worldMat);
m = Math::MultiplyMatrices(m, m_viewMat);
m = Math::MultiplyMatrices(m, m_projectionMat);
Math::Vector vec[6];
float originPlane[6];
// Left plane
vec[0].x = m.Get(4, 1) + m.Get(1, 1);
vec[0].y = m.Get(4, 2) + m.Get(1, 2);
vec[0].z = m.Get(4, 3) + m.Get(1, 3);
originPlane[0] = m.Get(4, 4) + m.Get(1, 4);
// Right plane
vec[1].x = m.Get(4, 1) - m.Get(1, 1);
vec[1].y = m.Get(4, 2) - m.Get(1, 2);
vec[1].z = m.Get(4, 3) - m.Get(1, 3);
originPlane[1] = m.Get(4, 4) - m.Get(1, 4);
// Top plane
vec[2].x = m.Get(4, 1) - m.Get(2, 1);
vec[2].y = m.Get(4, 2) - m.Get(2, 2);
vec[2].z = m.Get(4, 3) - m.Get(2, 3);
originPlane[2] = m.Get(4, 4) - m.Get(2, 4);
// Bottom plane
vec[3].x = m.Get(4, 1) + m.Get(2, 1);
vec[3].y = m.Get(4, 2) + m.Get(2, 2);
vec[3].z = m.Get(4, 3) + m.Get(2, 3);
originPlane[3] = m.Get(4, 4) + m.Get(2, 4);
// Front plane
vec[4].x = m.Get(3, 1);
vec[4].y = m.Get(3, 2);
vec[4].z = m.Get(3, 3);
originPlane[4] = m.Get(3, 4);
// Back plane
vec[5].x = m.Get(4, 1) - m.Get(3, 1);
vec[5].y = m.Get(4, 2) - m.Get(3, 2);
vec[5].z = m.Get(4, 3) - m.Get(3, 3);
originPlane[5] = m.Get(4, 4) - m.Get(3, 4);
int result = 0;
if (InPlane(vec[0], originPlane[0], center, radius))
result |= Gfx::INTERSECT_PLANE_LEFT;
if (InPlane(vec[1], originPlane[1], center, radius))
result |= Gfx::INTERSECT_PLANE_RIGHT;
if (InPlane(vec[2], originPlane[2], center, radius))
result |= Gfx::INTERSECT_PLANE_TOP;
if (InPlane(vec[3], originPlane[3], center, radius))
result |= Gfx::INTERSECT_PLANE_BOTTOM;
if (InPlane(vec[4], originPlane[4], center, radius))
result |= Gfx::INTERSECT_PLANE_FRONT;
if (InPlane(vec[5], originPlane[5], center, radius))
result |= Gfx::INTERSECT_PLANE_BACK;
return result;
}
void Gfx::CGLDevice::SetRenderState(Gfx::RenderState state, bool enabled)
{
if (state == RENDER_STATE_DEPTH_WRITE)

View File

@ -117,6 +117,7 @@ public:
virtual void DrawPrimitive(Gfx::PrimitiveType type, Gfx::VertexCol *vertices, int vertexCount);
virtual void DrawPrimitive(Gfx::PrimitiveType type, VertexTex2 *vertices, int vertexCount);
virtual int ComputeSphereVisibility(Math::Vector center, float radius);
virtual void SetRenderState(Gfx::RenderState state, bool enabled);
virtual bool GetRenderState(Gfx::RenderState state);