Archived

This topic is now archived and is closed to further replies.

MichaelNolan

Distance between a Point and a Triangle

Recommended Posts

Hi, Does anyone have any code which could tell me how to work out the distance between a point and a triangle during run-time of my game? I have searched the net but most of the stuff was pritty confusing. Thanks, Mike

Share this post


Link to post
Share on other sites
I have code, nicked from magic software. I don't pretend to fully understand it (it's not that hard, it's mostly linear algebra, but it worked straight away, so why bother reinventing the wheel), but it works a treat, and is fast.

Sphere/triangle/AABBTree collision

the sphere/triangle is based on estimating the squared distance between the sphere centre and the triangle. The code is in the sphere class, and is pretty straight forward.

if you have problems downloading, it's on my main page, or email me.

if you want the specific details of the implementation, it's all www.magic-software.com source documentation.


EDIT : bugger to Lycos. I switched to geocities, and it seems a lot smoother.

also, I might just as well post the code while I'm at it.


//-------------------------------------------------------------------

// Calculate the squared distance of a point to the triangle

//

// (http://www.magic-software.com)

//-------------------------------------------------------------------

float CTriangle::DistanceFromPoint(const Vector& P, float* pfSParam, float* pfTParam) const
{
if (!gpxVerts)
return 10000000.0f;

//-------------------------------------------------------------------

// 2 edges of the triangle

//-------------------------------------------------------------------

Vector E0 = (gpxVerts[i[1]]) - (gpxVerts[i[0]]);
Vector E1 = (gpxVerts[i[2]]) - (gpxVerts[i[0]]);

Vector kDiff = (gpxVerts[i[0]]) - P;
float fA00 = E0 * E0;
float fA01 = E0 * E1;
float fA11 = E1 * E1;
float fB0 = kDiff * E0;
float fB1 = kDiff * E1;
float fC = kDiff * kDiff;
float fDet = (float) fabs(fA00*fA11-fA01*fA01);
float fS = fA01*fB1-fA11*fB0;
float fT = fA01*fB0-fA00*fB1;
float fSqrDist;


//-------------------------------------------------------------------

// degenerate triangle

//-------------------------------------------------------------------

if (fabs(fDet) < 0.000000001f)
return 100000000.0f;

if ( fS + fT <= fDet )
{
if ( fS < (float)0.0 )
{
if ( fT < (float)0.0 ) // region 4

{
if ( fB0 < (float)0.0 )
{
fT = (float)0.0;
if ( -fB0 >= fA00 )
{
fS = (float)1.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = -fB0/fA00;
fSqrDist = fB0*fS+fC;
}
}
else
{
fS = (float)0.0;
if ( fB1 >= (float)0.0 )
{
fT = (float)0.0;
fSqrDist = fC;
}
else if ( -fB1 >= fA11 )
{
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fT = -fB1/fA11;
fSqrDist = fB1*fT+fC;
}
}
}
else // region 3

{
fS = (float)0.0;
if ( fB1 >= (float)0.0 )
{
fT = (float)0.0;
fSqrDist = fC;
}
else if ( -fB1 >= fA11 )
{
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fT = -fB1/fA11;
fSqrDist = fB1*fT+fC;
}
}
}
else if ( fT < (float)0.0 ) // region 5

{
fT = (float)0.0;
if ( fB0 >= (float)0.0 )
{
fS = (float)0.0;
fSqrDist = fC;
}
else if ( -fB0 >= fA00 )
{
fS = (float)1.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = -fB0/fA00;
fSqrDist = fB0*fS+fC;
}
}
else // region 0

{
// minimum at interior point

float fInvDet = ((float)1.0)/fDet;
fS *= fInvDet;
fT *= fInvDet;
fSqrDist = fS*(fA00*fS+fA01*fT+((float)2.0)*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
else
{
float fTmp0, fTmp1, fNumer, fDenom;

if ( fS < (float)0.0 ) // region 2

{
fTmp0 = fA01 + fB0;
fTmp1 = fA11 + fB1;
if ( fTmp1 > fTmp0 )
{
fNumer = fTmp1 - fTmp0;
fDenom = fA00-2.0f*fA01+fA11;
if ( fNumer >= fDenom )
{
fS = (float)1.0;
fT = (float)0.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = fNumer/fDenom;
fT = (float)1.0 - fS;
fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
else
{
fS = (float)0.0;
if ( fTmp1 <= (float)0.0 )
{
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else if ( fB1 >= (float)0.0 )
{
fT = (float)0.0;
fSqrDist = fC;
}
else
{
fT = -fB1/fA11;
fSqrDist = fB1*fT+fC;
}
}
}
else if ( fT < (float)0.0 ) // region 6

{
fTmp0 = fA01 + fB1;
fTmp1 = fA00 + fB0;
if ( fTmp1 > fTmp0 )
{
fNumer = fTmp1 - fTmp0;
fDenom = fA00-((float)2.0)*fA01+fA11;
if ( fNumer >= fDenom )
{
fT = (float)1.0;
fS = (float)0.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fT = fNumer/fDenom;
fS = (float)1.0 - fT;
fSqrDist = fS*(fA00*fS+fA01*fT+((float)2.0)*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
else
{
fT = (float)0.0;
if ( fTmp1 <= (float)0.0 )
{
fS = (float)1.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else if ( fB0 >= (float)0.0 )
{
fS = (float)0.0;
fSqrDist = fC;
}
else
{
fS = -fB0/fA00;
fSqrDist = fB0*fS+fC;
}
}
}
else // region 1

{
fNumer = fA11 + fB1 - fA01 - fB0;
if ( fNumer <= (float)0.0 )
{
fS = (float)0.0;
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fDenom = fA00-2.0f*fA01+fA11;
if ( fNumer >= fDenom )
{
fS = (float)1.0;
fT = (float)0.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = fNumer/fDenom;
fT = (float)1.0 - fS;
fSqrDist = fS*(fA00*fS+fA01*fT+((float)2.0)*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
}
}

if ( pfSParam )
*pfSParam = fS;

if ( pfTParam )
*pfTParam = fT;

return (float) fabs(fSqrDist);
}



sparam and tparam are parameters along the edges in the code. To get the closest point on the triangle, use sparam and tparam and do


void CTriangle::CalculatePoint(Vector& P, float s, float t) const
{
if (!gpxVerts)
return;

P = (gpxVerts[i[0]]) + (gpxVerts[i[1]] - gpxVerts[i[0]]) * s + (gpxVerts[i[2]] - gpxVerts[i[0]]) * t;
}


[edited by - oliii on April 20, 2004 4:49:25 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you''re not worried about being totally accurate, you could take the distance between your point and
1) one of the three vertices of the triangle.
2) the midpoint of one of the three sides of the triangle
3) the point that is the average of the three vertices
using the normal point-point distance formula. If you want to be more accurate (but slower) for numbers 1) and 2), return the closest distance of the 3 possibilities (neccesitating the calculation of 3 sqrts).

If you want the perfectly accurate distance, look up information on barycentric coordinates. However, the aforementioned methods usually suffice.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
(neccesitating the calculation of 3 sqrts).


For decent speed up, when ever possible compare the square of the distance instead.

In the case of checking the distance to all three vertex, you just saved two sqrts by waiting and only sqrt''ing the final answer. Depending what you are using it for, you may be able to save all three sqrts by returning the squared distance and having the rest of that part of the code using the squared distance as well (and just sqrt''ing the return value in the few other places you need the real distance)

Of course, you can only do this in places you are comparing the distance and don''t need the true distance



Drakonite

Shoot Pixels Not People

Share this post


Link to post
Share on other sites
Hi,

Thanks for your replies.

oliii i have a book on that (3D Game Engine Design) but i couldn''t really understand the math that''s why i posted this.

Note: i am in high-school.

Thanks Anyway,
Mike

Share this post


Link to post
Share on other sites
Hi,

I have tried that code. It dosen''t seem to work for me. Perhaps i''m not doing something correctly using OpenGL. Could somebody show me a correct way of using this code with OpenGL to get the distance between a triangle and a point.

Best Regards,
Mike

Share this post


Link to post
Share on other sites
Hi,

I have tried that code. It dosen''t seem to work for me. Perhaps i''m not doing something correctly using OpenGL. Could somebody show me a correct way of using this code with OpenGL to get the distance between a triangle and a point.

Best Regards,
Mike

Share this post


Link to post
Share on other sites
ok, since it''s unfinished business, here is a demo of that code (requires GLUT).


//------------------------------------------------------------

// libraries

//------------------------------------------------------------

#ifdef WIN32
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glut32.lib")
#endif

//------------------------------------------------------------

// includes

//------------------------------------------------------------

#include <gl/glut.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

//------------------------------------------------------------

// tools

//------------------------------------------------------------

#define UPDATE_FPS 30.0f
#define RED(c) (((c) & 0x00FF0000) >> 16)
#define GREEN(c) (((c) & 0x0000FF00) >> 8 )
#define BLUE(c) (((c) & 0x000000FF) >> 0 )
#define ALPHA(c) (((c) & 0xFF000000) >> 24)

int screen_w = 640, screen_h=480; // window size



// print a string at column ''x'', row ''y''

void print(int x, int y, u_int color, char* szFormat, ...)
{
static char szString[1024];

va_list Args;
va_start(Args, szFormat);
vsprintf(szString, szFormat, Args);
va_end (Args);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0f, screen_w, screen_h, 0.0f);

glColor4ub(RED(color), GREEN(color), BLUE(color), ALPHA(color));
glRasterPos2f(x * 8, y * 13);

char* chr = szString;

while(*chr)
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *(chr++));


glMatrixMode(GL_PROJECTION);
glPopMatrix();

glMatrixMode(GL_MODELVIEW);
glPopMatrix();

}

void glMultShadowMatrixf(GLfloat groundplane[4], GLfloat lightpos[4])
{
GLfloat shadowMat[4][4];

GLfloat dot;
const int X = 0;
const int Y = 1;
const int Z = 2;
const int W = 3;
/* Find dot product between light position vector and ground plane normal. */
dot = groundplane[X] * lightpos[X] +
groundplane[Y] * lightpos[Y] +
groundplane[Z] * lightpos[Z] +
groundplane[W] * lightpos[W];
shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
shadowMat[3][3] = dot - lightpos[W] * groundplane[W];

glMultMatrixf((GLfloat*) shadowMat);
}

//------------------------------------------------------------

// math tools

//------------------------------------------------------------

const float pi()
{
static const PI = atan(1.0f) * 4.0f;
return PI;
}

const float two_pi()
{
return 2.0f * pi();
}


float frand(float min, float max)
{
float t = rand() / (float) RAND_MAX;
return min + t * (max - min);
}

float dot(float* a, float* b)
{
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
}

void sub(float* a, float* b, float* c)
{
c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
c[2] = a[2] - b[2];
}

void add(float* a, float* b, float* c)
{
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
c[2] = a[2] + b[2];
}

void set(float* a, float* b)
{
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
}

void mul(float* a, float k)
{
a[0] *= k;
a[1] *= k;
a[2] *= k;
}
void InterpolatePoint(float* p, float* v0, float* v1, float* v2, float u, float v)
{
float e0[3];
float e1[3];
sub(v1, v0, e0);
sub(v2, v0, e1);

mul(e0, u);
mul(e1, v);
set(p, v0);
add(p, e0, p);
add(p, e1, p);
}

//-------------------------------------------------------------------

// Calculate the squared distance of a point to the triangle

//

// Nicked code from David Eberly''s most excelent physics site

// Don;t ask me how it works. It just does :)

// (http://www.magic-software.com)

//-------------------------------------------------------------------

float DistanceSquared(float* p, float* v0, float* v1, float* v2, float* u, float *v)
{
//-------------------------------------------------------------------

// 2 edges of the triangle

//-------------------------------------------------------------------

float e0[3];
float e1[3];
float kdiff[3];

sub(v1, v0, e0);
sub(v2, v0, e1);
sub(v0, p, kdiff);

float fA00 = dot(e0, e0);
float fA01 = dot(e0, e1);
float fA11 = dot(e1, e1);
float fB0 = dot(kdiff, e0);
float fB1 = dot(kdiff, e1);
float fC = dot(kdiff, kdiff);
float fDet = (float) fabs(fA00*fA11-fA01*fA01);
float fS = fA01*fB1-fA11*fB0;
float fT = fA01*fB0-fA00*fB1;
float fSqrDist;

if (fabs(fDet) < 0.00000001f)
return 100000000.0f;

if ( fS + fT <= fDet )
{
if ( fS < (float)0.0 )
{
if ( fT < (float)0.0 ) // region 4

{
if ( fB0 < (float)0.0 )
{
fT = (float)0.0;
if ( -fB0 >= fA00 )
{
fS = (float)1.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = -fB0/fA00;
fSqrDist = fB0*fS+fC;
}
}
else
{
fS = (float)0.0;
if ( fB1 >= (float)0.0 )
{
fT = (float)0.0;
fSqrDist = fC;
}
else if ( -fB1 >= fA11 )
{
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fT = -fB1/fA11;
fSqrDist = fB1*fT+fC;
}
}
}
else // region 3

{
fS = (float)0.0;
if ( fB1 >= (float)0.0 )
{
fT = (float)0.0;
fSqrDist = fC;
}
else if ( -fB1 >= fA11 )
{
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fT = -fB1/fA11;
fSqrDist = fB1*fT+fC;
}
}
}
else if ( fT < (float)0.0 ) // region 5

{
fT = (float)0.0;
if ( fB0 >= (float)0.0 )
{
fS = (float)0.0;
fSqrDist = fC;
}
else if ( -fB0 >= fA00 )
{
fS = (float)1.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = -fB0/fA00;
fSqrDist = fB0*fS+fC;
}
}
else // region 0

{
// minimum at interior point

float fInvDet = ((float)1.0)/fDet;
fS *= fInvDet;
fT *= fInvDet;
fSqrDist = fS*(fA00*fS+fA01*fT+((float)2.0)*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
else
{
float fTmp0, fTmp1, fNumer, fDenom;

if ( fS < (float)0.0 ) // region 2

{
fTmp0 = fA01 + fB0;
fTmp1 = fA11 + fB1;
if ( fTmp1 > fTmp0 )
{
fNumer = fTmp1 - fTmp0;
fDenom = fA00-2.0f*fA01+fA11;
if ( fNumer >= fDenom )
{
fS = (float)1.0;
fT = (float)0.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = fNumer/fDenom;
fT = (float)1.0 - fS;
fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
else
{
fS = (float)0.0;
if ( fTmp1 <= (float)0.0 )
{
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else if ( fB1 >= (float)0.0 )
{
fT = (float)0.0;
fSqrDist = fC;
}
else
{
fT = -fB1/fA11;
fSqrDist = fB1*fT+fC;
}
}
}
else if ( fT < (float)0.0 ) // region 6

{
fTmp0 = fA01 + fB1;
fTmp1 = fA00 + fB0;
if ( fTmp1 > fTmp0 )
{
fNumer = fTmp1 - fTmp0;
fDenom = fA00-((float)2.0)*fA01+fA11;
if ( fNumer >= fDenom )
{
fT = (float)1.0;
fS = (float)0.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fT = fNumer/fDenom;
fS = (float)1.0 - fT;
fSqrDist = fS*(fA00*fS+fA01*fT+((float)2.0)*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
else
{
fT = (float)0.0;
if ( fTmp1 <= (float)0.0 )
{
fS = (float)1.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else if ( fB0 >= (float)0.0 )
{
fS = (float)0.0;
fSqrDist = fC;
}
else
{
fS = -fB0/fA00;
fSqrDist = fB0*fS+fC;
}
}
}
else // region 1

{
fNumer = fA11 + fB1 - fA01 - fB0;
if ( fNumer <= (float)0.0 )
{
fS = (float)0.0;
fT = (float)1.0;
fSqrDist = fA11+((float)2.0)*fB1+fC;
}
else
{
fDenom = fA00-2.0f*fA01+fA11;
if ( fNumer >= fDenom )
{
fS = (float)1.0;
fT = (float)0.0;
fSqrDist = fA00+((float)2.0)*fB0+fC;
}
else
{
fS = fNumer/fDenom;
fT = (float)1.0 - fS;
fSqrDist = fS*(fA00*fS+fA01*fT+((float)2.0)*fB0) +
fT*(fA01*fS+fA11*fT+((float)2.0)*fB1)+fC;
}
}
}
}

if (u) *u = fS;
if (v) *v = fT;

return (float) fabs(fSqrDist);
}

void RandPoint(float* coords)
{
coords[0] = frand( 0, 10);
coords[1] = frand( 1, 10);
coords[2] = frand( 0, 10);
}




//------------------------------------------------------------

// game data

//------------------------------------------------------------

float a=0.0f, b = -pi() * 4.0f, r=20.0f; // camera

float tri[3][3]; // triangle points

float point[3]; // point to test

float ptri[3]; // closet pointon traingle

float d2; // distance of point to triangle, squared



//------------------------------------------------------------

// game functions

//------------------------------------------------------------

void Init()
{
RandPoint(tri[0]);
RandPoint(tri[1]);
RandPoint(tri[2]);
RandPoint(point);

}

void Update(void)
{
float u, v;
d2 = DistanceSquared(point, tri[0], tri[1], tri[2], &u, &v);
InterpolatePoint(ptri, tri[0], tri[1], tri[2], u, v);
}

void RenderObjects(float intensity = 1.0f)
{
glColor4f(1.0f*intensity, 0.0f, 0.0f, 0.6f);
glBegin(GL_TRIANGLES);
glVertex3fv(tri[0]);
glVertex3fv(tri[1]);
glVertex3fv(tri[2]);
glEnd();

glColor4f(1.0f*intensity, 1.0f*intensity, 1.0f*intensity, 0.6f);
glBegin(GL_POINTS);
glVertex3fv(point);
glVertex3fv(ptri);
glEnd();

glColor4f(0.8f*intensity, 1.0f * intensity, 0.8f* intensity, 0.6f);
glBegin(GL_LINES);
glVertex3fv(point);
glVertex3fv(ptri);
glEnd();
}


//------------------------------------------------------------

// opengl/glut

//------------------------------------------------------------

void RenderFloor()
{
//----------------------------------------------------------------

// Draw the floor

//----------------------------------------------------------------

glBegin(GL_QUADS);
glVertex3f(-100.0f, 0.0f, -100.0f);
glVertex3f(-100.0f, 0.0f, 100.0f);
glVertex3f( 100.0f, 0.0f, 100.0f);
glVertex3f( 100.0f, 0.0f, -100.0f);
glEnd();
}



void RenderShadow()
{
GLfloat groundplane[4] = { 0, 1, 0, 0 };
GLfloat lightpos [4] = { 0, 100, 0, 1 };

glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-10.0f, -10.0f);

glPushMatrix();
glMultShadowMatrixf(groundplane, lightpos);
RenderObjects(0.0f);
glPopMatrix();
glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL);
}
void Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 4/3.0f, 0.1f, 1000.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

float pos[3];
float dir[3];
float side[3];
float up[3];
dir[0] = sin(a) * cos(b);
dir[1] = sin(b);
dir[2] = cos(a) * cos(b);

side[0] = cos(a);
side[1] = 0.0f;
side[2] =-sin(a);

up[0] = dir[1] * side[2] - dir[2] * side[1];
up[1] = dir[2] * side[0] - dir[0] * side[2];
up[2] = dir[0] * side[1] - dir[1] * side[0];

pos[0] = dir[0] * r;
pos[1] = dir[1] * r;
pos[2] = dir[2] * r;

gluLookAt(pos[0], pos[1], pos[2], 0.0f, 0.0f, 0.0f, up[0], up[1], up[2]);

//----------------------------------------------------------------

// Render floor

//----------------------------------------------------------------

glColor4f(0.1f, 0.1f, 0.4f, 1.0f);
RenderFloor();

//----------------------------------------------------------------

// Draw the objects

//----------------------------------------------------------------

glLineWidth(1.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_BLEND);
glColor4f(1.0f, 0.5f, 0.5f, 0.6f);
RenderObjects();

glEnable(GL_BLEND);
glLineWidth(4.0f);
glPointSize(8.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor4f(1.0f, 0.5f, 0.5f, 0.6f);
RenderObjects();

//----------------------------------------------------------------

// Draw Shadow on floor

//----------------------------------------------------------------

glColor4f(0.0f, 0.0f, 0.0f, 0.6f);
RenderShadow();

print(1, 1, 0xFFFFFFFF, "----------------------------------");
print(1, 2, 0xFFFFFFFF, "- point / triangle distance demo -");
print(1, 3, 0xFFFFFFFF, "----------------------------------");
print(1, 4, 0xFFFFFFFF, "camera : a, w, s, d, -, +");
print(1, 5, 0xFFFFFFFF, "reset : ''space''");
print(1, 6, 0xFFFFFFFF, "exit : ''esc''");
print(1, 7, 0xFFA0FFA0, "----------------------------------");
print(1, 8, 0xFF00FF00, "distance : %f", sqrt(d2));
print(1, 9, 0xFFA0FFA0, "----------------------------------");

glutSwapBuffers();
}


void Timer(int timer)
{
Update();
Render();

glutTimerFunc(timer, Timer, 1000/UPDATE_FPS);
}

void Reshape(int w, int h)
{
screen_w = w;
screen_h = h;
glViewport(0, 0, w, h);
}
void Keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case ''-'':
case ''_'':
r += 0.4f;
break;
case ''+'':
case ''='':
r -= 0.4f;
break;
case ''a'':
a += pi() * 0.01f;
break;
case ''d'':
a -= pi() * 0.01f;
break;
case ''w'':
b += pi() * 0.01f;
break;
case ''s'':
b -= pi() * 0.01f;
break;
case 27:
exit(0);
break;
case '' '':
Init();
break;
}
}

void main(void)
{
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (screen_w, screen_h);
glutInitWindowPosition (100, 100);
glutCreateWindow ("physics demo");

glEnable (GL_POINT_SMOOTH);
glEnable (GL_LINE_SMOOTH);
glShadeModel (GL_SMOOTH);
glEnable (GL_NORMALIZE);
glEnable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
glDisable (GL_LIGHTING);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glutDisplayFunc(Render);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Keyboard);
glutTimerFunc(0, Timer, 1000/UPDATE_FPS);

Init();

glutMainLoop();
}

Share this post


Link to post
Share on other sites