Prev: Testing Points II Next: Testing Spheres

A class to implement the frustum functionality based on the radar approach is now presented. Note that the code itself is not optimized in any way, as the goal is only to serve as the tutorial companion. As opposed to the previous implementations, this class contains only the required data to make it work.

```class FrustumR{

public:
static enum {OUTSIDE, INTERSECT, INSIDE};

Vec3 cc; // camera position
Vec3 X,Y,Z; // the camera referential
float nearD, farD, width, height;

FrustumR::FrustumR();
FrustumR::~FrustumR();

void setCamInternals(float angle, float ratio, float nearD, float farD);
void setCamDef(Vec3 &p, Vec3 &l, Vec3 &u);
int pointInFrustum(Vec3 &p);
};```

The Methods: setCamInternals

This function takes exactly the same parameters as the function `gluPerspective`. Each time the perspective definitions change, for instance when a window is resized, this function should be called as well.

```#define ANG2RAD 3.14159265358979323846/180.0

void FrustumR::setCamInternals(float angle, float ratio, float nearD, float farD) {

// store the information
this->ratio = ratio;
this->nearD = nearD;
this->farD = farD;

// compute width and height of the near section
tang = (float)tan(ANG2RAD * angle * 0.5) ;
heigth = nearD * tang;
width = height * ratio;
}```

The function stores all the information, and computes the width and height of the rectangular sections of the near plane and stores them in height (near height) and width (near width).

The Methods: setCamDef

This function takes three vectors that contain the information for the `gluLookAt` function: the position of the camera, a point to where the camera is pointing and the up vector. Each time the camera position or orientation changes, this function should be called as well. Notice how the following function is much simpler than for the other methods of view frustum culling. There is no need to compute the planes anymore.

```void FrustumR::setCamDef(Vec3 &p, Vec3 &l, Vec3 &u) {

cc = p.copy();

// compute the Z axis of the camera referential
// this axis points in the same direction from
// the looking direction
Z = l - p;
Z.normalize();

// X axis of camera is the cross product of Z axis and given "up" vector
X = Z * u;
X.normalize();

// the real "up" vector is the cross product of X and Z
Y = X * Z;
}```

The Methods: pointInFrustum

Testing a point is also much simpler and more efficient:

```int FrustumR::pointInFrustum(Vec3 &p) {

float pcz,pcx,pcy,aux;

// compute vector from camera position to p
Vec3 v = p-camPos;

// compute and test the Z coordinate
pcz = v.innerProduct(-Z);
if (pcz > farD || pcz < nearD)

return(OUTSIDE);

// compute and test the Y coordinate
pcy = v.innerProduct(Y);
aux = pcz * tang;
if (pcy > aux || pcy < -aux)
return(OUTSIDE);

// compute and test the X coordinate
pcx = v.innerProduct(X);
aux = aux * ratio;
if (pcx > aux || pcx < -aux)
return(OUTSIDE);

return(INSIDE);
}```

 Prev: Testing Points II Next: Testing Spheres

### 4 Responses to “Radar Approach – Implementation”

1. In you setCamDef(Vec3 &p, Vec3 &l, Vec3 &u) method you should write somewhere that there are cross product multiplications, when you compute X and Y

// X axis of camera with given “up” vector and Z axis |->here shuld be cross
X = Z * u;
X.normalize();

// the real “up” vector is the dot product of X and Z |->here shuld be cross
Y = X * Z;

• Yes, I meant cross, not dot. Fixed it. Thanks for pointing it out.

2. Am I correct in assuming that

pcz = v.innerProduct(-Z);

is -Z because of right-handedness of your example?
So If I were to try this in left-handed I should use Z instead of -Z

• Actually, that is already OpenGL code.

This site uses Akismet to reduce spam. Learn how your comment data is processed.