1
0
forked from 0ad/0ad

# Fixes to the line segment frustum test.

This was SVN commit r4245.
This commit is contained in:
Matei 2006-08-25 19:31:01 +00:00
parent 147d4f2bd3
commit 9fc485c9a6
4 changed files with 31 additions and 35 deletions

View File

@ -17,6 +17,7 @@
#include "Frustum.h"
#include "maths/Bound.h"
#include "maths/MathUtil.h"
CFrustum::CFrustum ()
{
@ -52,13 +53,22 @@ bool CFrustum::IsPointVisible (const CVector3D &point) const
return true;
}
bool CFrustum::DoesSegmentIntersect(const CVector3D& start, const CVector3D &end)
bool CFrustum::DoesSegmentIntersect(const CVector3D& startRef, const CVector3D &endRef)
{
CVector3D start = startRef;
CVector3D end = endRef;
if(IsPointVisible(start) || IsPointVisible(end))
return true;
CVector3D intersect;
for ( int i = 0; i<m_NumPlanes; ++i )
{
if ( m_aPlanes[i].FindLineSegIntersection(start, end, &intersect) )
return true;
{
if ( IsPointVisible( intersect ) )
return true;
}
}
return false;
}

View File

@ -14,6 +14,7 @@
#include "precompiled.h"
#include "Plane.h"
#include "MathUtil.h"
CPlane::CPlane ()
{
@ -74,9 +75,11 @@ PLANESIDE CPlane::ClassifyPoint (const CVector3D &point) const
m_Norm.Z * point.Z +
m_Dist;
if (Dist > 0.0f)
const float EPS = 0.001f;
if (Dist > EPS)
return PS_FRONT;
else if (Dist < 0.0f)
else if (Dist < -EPS)
return PS_BACK;
return PS_ON;
@ -99,31 +102,14 @@ float CPlane::DistanceToPlane (const CVector3D &point) const
//plane. Returns false if there is no intersection
bool CPlane::FindLineSegIntersection (const CVector3D &start, const CVector3D &end, CVector3D *intsect)
{
PLANESIDE StartS, EndS;
CVector3D Dir;
float Length;
//work out where each point is
StartS = ClassifyPoint (start);
EndS = ClassifyPoint (end);
float dist1 = DistanceToPlane( start );
float dist2 = DistanceToPlane( end );
//if they are not on opposite sides of the plane return false
if (StartS == EndS)
if( (dist1 < 0 && dist2 < 0) || (dist1 >= 0 && dist2 >= 0) )
return false;
//work out a normalized vector in the direction start to end
Dir = end - start;
Dir.Normalize ();
//a bit of algebra to work out how much we need to scale
//this direction vector to get to the plane
Length = -m_Norm.Dot(start)/m_Norm.Dot(Dir);
//scale it by this amount
Dir *= Length;
//workout actual position vector of impact
*intsect = start + Dir;
float t = (-dist1) / (dist2-dist1);
*intsect = Interpolate( start, end, t );
return true;
}

View File

@ -214,13 +214,13 @@ void CTerritoryManager::renderTerritories()
std::vector<CTerritory*>::iterator terr=m_Territories.begin();
glEnable(GL_LINE_SMOOTH);
glLineWidth(1.4f);
glColor3f(1.0f, 1.0f, 1.0f);
for ( ; terr != m_Territories.end(); ++terr )
{
std::vector<CVector2D>::iterator it=(*terr)->boundary.begin()+1;
const SPlayerColour& col = (*terr)->owner->GetColour();
glColor3f(col.r, col.g, col.b);
glBegin(GL_LINE_STRIP);
//const SPlayerColour& col = (*terr)->owner->GetColour();
//glColor3f(col.r, col.g, col.b);
for ( ; it != (*terr)->boundary.end(); ++it )
{
@ -229,6 +229,7 @@ void CTerritoryManager::renderTerritories()
if ( !frustum.DoesSegmentIntersect(prev, front) )
continue;
glBegin(GL_LINE_STRIP);
float iterf = (front - prev).GetLength() / TERRITORY_PRECISION_STEP;
for ( float i=0; i<iterf; i+= TERRITORY_PRECISION_STEP )
{
@ -236,6 +237,7 @@ void CTerritoryManager::renderTerritories()
glVertex3f(pos.x, pTerrain->getExactGroundLevel(pos)+.25f, pos.y);
}
glVertex3f(front.X, pTerrain->getExactGroundLevel(front.X, front.Z)+.25f, front.Z);
glEnd();
}
//Loop around
CVector2D first2D((*terr)->boundary.front()), back2D((*terr)->boundary.back());
@ -243,10 +245,9 @@ void CTerritoryManager::renderTerritories()
CVector3D back(back2D.x, pTerrain->getExactGroundLevel(back2D), back2D.y);
if ( !frustum.DoesSegmentIntersect(back, first) )
{
glEnd();
continue;
}
glBegin(GL_LINE_STRIP);
float iterf = (first - back).GetLength() / TERRITORY_PRECISION_STEP;
for ( float i=0; i<iterf; i+= TERRITORY_PRECISION_STEP )
{
@ -254,9 +255,8 @@ void CTerritoryManager::renderTerritories()
glVertex3f(pos.x, pTerrain->getExactGroundLevel(pos)+.25f, pos.y);
}
glVertex3f(first.X, pTerrain->getExactGroundLevel(first2D)+.25f, first.Z);
glEnd();
}
glDisable(GL_LINE_SMOOTH);
glLineWidth(1.0f);
glLineWidth(1.0f);
}

View File

@ -20,7 +20,7 @@
class CUnit;
class CPlayer;
const float TERRITORY_PRECISION_STEP = 1.0f / 6;
const float TERRITORY_PRECISION_STEP = 1.0f;
class CTerritory
{