You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.3 KiB
C++

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#ifdef _MSC_VER
#include <windows.h>
#include <GL/glu.h>
#include <GL/glut.h>
#elif __APPLE__
#include <GLUT/glut.h>
#include <OpenGl/glu.h>
#include <stdbool.h>
#else
#include <GL/glut.h>
#include <GL/glu.h>
#include <stdbool.h>
#endif
#ifndef __VIEWCULL_H__
#define __VIEWCULL_H__
namespace show{
///////////////////////// Variable declarations...
/** The 6 planes of the viewing frustum */
extern float frustum[6][4];
/** the modelview * projection matrix to map a model point to an onscreen coordinate */
extern float matrix[16];
/** some useful variables for faster calculation of the pixel coordinates */
extern short VP[4];
/** a unit vector pointing to the right of the screen */
extern float right[3];
/** how much detail is shown, 0 means everything is plotted */
extern short DETAIL;
extern double SX, SY, SZ, EX, EY, EZ;
extern float origin[3], dir[3]; /*ray */
extern float dist;
extern int rayX,rayY;
extern float rayVP[4];
#define NUMDIM 3
#define RIGHT 0
#define LEFT 1
#define MIDDLE 2
extern float minB[NUMDIM], maxB[NUMDIM]; /*box */
extern float coord[NUMDIM]; /* hit point */
template <class T> bool HitBoundingBox(const T center[3], T size )
{
minB[0] = center[0] - size;
minB[1] = center[1] - size;
minB[2] = center[2] - size;
maxB[0] = center[0] + size;
maxB[1] = center[1] + size;
maxB[2] = center[2] + size;
bool inside = true;
char quadrant[NUMDIM];
register int i;
int whichPlane;
float maxT[NUMDIM];
float candidatePlane[NUMDIM];
// Find candidate planes; this loop can be avoided if
// rays cast all from the eye(assume perpsective view)
for (i=0; i<NUMDIM; i++)
if(origin[i] < minB[i]) {
quadrant[i] = LEFT;
candidatePlane[i] = minB[i];
inside = false;
}else if (origin[i] > maxB[i]) {
quadrant[i] = RIGHT;
candidatePlane[i] = maxB[i];
inside = false;
}else {
candidatePlane[i] = 0.0;
quadrant[i] = MIDDLE;
}
// Ray origin inside bounding box
if(inside) {
return (true);
}
// Calculate T distances to candidate planes
for (i = 0; i < NUMDIM; i++)
if (quadrant[i] != MIDDLE && dir[i] !=0.)
maxT[i] = (candidatePlane[i]-origin[i]) / dir[i];
else
maxT[i] = -1.;
// Get largest of the maxT's for final choice of intersection
whichPlane = 0;
for (i = 1; i < NUMDIM; i++)
if (maxT[whichPlane] < maxT[i])
whichPlane = i;
// Check final candidate actually inside box
if (maxT[whichPlane] < 0.) return (false);
for (i = 0; i < NUMDIM; i++)
if (whichPlane != i) {
coord[i] = origin[i] + maxT[whichPlane] *dir[i];
if (coord[i] < minB[i] || coord[i] > maxB[i])
return (false);
} else {
coord[i] = candidatePlane[i];
}
return (true); // ray hits box
}
void calcRay(int x, int y, double znear, double zfar);
#include <float.h>
template <class T>
float RayDist(T *point)
{
return point[0] * dir[0] + point[1] * dir[1] + point[2] * dir[2] - dist;
}
template <class T>
short ScreenDist(T *point) {
float pn[3];
// x coordinate on screen, not normalized
pn[0] = point[0] * matrix[0] + point[1] * matrix[4] + point[2] * matrix[8] + matrix[12];
pn[1] = point[0] * matrix[1] + point[1] * matrix[5] + point[2] * matrix[9] + matrix[13];
// normalization
pn[2] = point[0] * matrix[3] + point[1] * matrix[7] + point[2] * matrix[11] + matrix[15];
// normalized x coordinate on screen
pn[0] /= pn[2];
pn[1] /= pn[2];
// true x coordinate in viewport coordinate system
//Xi = pn[0]*VP[0] + VP[1];
//fTempo[4]*0.5+0.5)*viewport[2]+viewport[0];
float XX = ( (pn[0])*rayVP[0] + rayVP[1]);
float YY = ( (pn[1])*rayVP[2] + rayVP[3]);
short dx, dy;
if (XX > rayX) dx = XX-rayX;
else dx = rayX-XX;
if (YY > rayY) dy = YY-rayY;
else dy = rayY-YY;
// for the benefit of visual studio's compiler cast to float
return sqrt((float)(dx*dx + dy*dy));
}
void ExtractFrustum(short detail);
void ExtractFrustum(float *frust[6]);
bool CubeInFrustum( float x, float y, float z, float size );
int CubeInFrustum2( float x, float y, float z, float size );
char PlaneAABB( float x, float y, float z, float size, float *plane );
void remViewport();
bool LOD(float x, float y, float z, float size);
int LOD2(float x, float y, float z, float size);
}
#endif