Added view frustum culling to the visible stars traversal. Over 2x improvement in frame rate with lots of stars enabled. This class rocks.

This commit is contained in:
Chris Laurel 2001-05-07 02:06:25 +00:00
parent faaaef0636
commit e2bebdc193
2 changed files with 89 additions and 17 deletions

View file

@ -46,9 +46,31 @@ void StarOctree::insertStar(const Star& star)
void StarOctree::processVisibleStars(StarHandler& starHandler,
const Point3f& position,
const Quatf& orientation,
float fovY,
float aspectRatio,
float limitingMag) const
{
root->processVisibleStars(starHandler, position, limitingMag, scale);
// Compute the bounding planes of an infinite view frustum
Planef frustumPlanes[5];
Vec3f planeNormals[5];
Mat3f rot = orientation.toMatrix3();
float h = (float) tan(fovY / 2);
float w = h * aspectRatio;
planeNormals[0] = Vec3f(0, 1, -h);
planeNormals[1] = Vec3f(0, -1, -h);
planeNormals[2] = Vec3f(1, 0, -w);
planeNormals[3] = Vec3f(-1, 0, -w);
planeNormals[4] = Vec3f(0, 0, -1);
for (int i = 0; i < 5; i++)
{
planeNormals[i].normalize();
planeNormals[i] = planeNormals[i] * rot;
frustumPlanes[i] = Planef(planeNormals[i], position);
}
root->processVisibleStars(starHandler, position, frustumPlanes,
limitingMag, scale);
}
int StarOctree::countNodes() const
@ -56,6 +78,11 @@ int StarOctree::countNodes() const
return 1 + root->countChildren();
}
int StarOctree::countStars() const
{
return root->countStars();
}
StarOctreeNode::StarOctreeNode(const Point3f& _center, float _luminosity) :
stars(NULL), children(NULL), center(_center), luminosity(_luminosity)
@ -68,8 +95,7 @@ StarOctreeNode::~StarOctreeNode()
{
for (int i = 0; i < 8; i++)
{
if (children[i] != NULL)
delete children[i];
delete children[i];
}
}
}
@ -129,30 +155,51 @@ void StarOctreeNode::insertStar(const Star& star, float scale)
void StarOctreeNode::processVisibleStars(StarHandler& starHandler,
const Point3f& position,
const Planef* frustumPlanes,
float limitingMag,
float scale) const
{
// See if this node lies within the view frustum
{
for (int i = 0; i < 5; i++)
{
const Planef* plane = frustumPlanes + i;
float r = scale * (abs(plane->normal.x) +
abs(plane->normal.y) +
abs(plane->normal.z));
if (plane->normal * Vec3f(center.x, center.y, center.z) - plane->d < -r)
return;
}
}
// Process the stars in this node
if (stars != NULL)
{
for (vector<const Star*>::const_iterator iter = stars->begin();
iter != stars->end(); iter++)
{
float distance = (position - (*iter)->getPosition()).length();
float appMag = astro::lumToAppMag((*iter)->getLuminosity(), distance);
if (appMag < limitingMag)
starHandler.process(**iter, distance, appMag);
}
}
// Compute the distance to node; this is equal to the distance to
// the center of the node minus the radius of the node, scale * sqrt3.
float distance = (position - center).length() - scale * sqrt3;
if (distance <= 0 || astro::lumToAppMag(luminosity, distance) <= limitingMag)
{
// Process the stars in this node
if (stars != NULL)
{
for (vector<const Star*>::const_iterator iter = stars->begin();
iter != stars->end(); iter++)
starHandler.process(**iter);
}
// Recurse into the child nodes
if (children != NULL)
{
for (int i = 0; i < 8; i++)
{
if (children[i] != NULL)
children[i]->processVisibleStars(starHandler, position, limitingMag,
scale * 0.5f);
children[i]->processVisibleStars(starHandler,
position,
frustumPlanes,
limitingMag,
scale * 0.5f);
}
}
}
@ -202,6 +249,8 @@ void StarOctreeNode::sortStarsIntoChildNodes()
children[childIndex(*star, center)]->addStar(*star);
}
}
stars->resize(nBrightStars);
}
@ -215,9 +264,24 @@ int StarOctreeNode::countChildren() const
{
int nChildren = 0;
for (int i = 0; i < 8; i++)
if (children[i] != NULL)
nChildren += 1 + children[i]->countChildren();
nChildren += 1 + children[i]->countChildren();
return nChildren;
}
}
int StarOctreeNode::countStars() const
{
int nStars = stars == NULL ? 0 : stars->size();
if (children != NULL)
{
for (int i = 0; i < 8; i++)
{
nStars += children[i]->countStars();
}
}
return nStars;
}

View file

@ -11,6 +11,8 @@
#define _OCTREE_H_
#include <vector>
#include "quaternion.h"
#include "plane.h"
#include "star.h"
@ -20,7 +22,7 @@ class StarHandler
StarHandler() {};
virtual ~StarHandler() {};
virtual void process(const Star&) = 0;
virtual void process(const Star& star, float distance, float appMag) = 0;
};
@ -33,9 +35,11 @@ class StarOctreeNode
void insertStar(const Star&, float);
void processVisibleStars(StarHandler& starHandler,
const Point3f& position,
const Planef* frustumPlanes,
float limitingMag,
float scale) const;
int countChildren() const;
int countStars() const;
private:
void addStar(const Star&);
@ -59,8 +63,12 @@ class StarOctree
void insertStar(const Star&);
void processVisibleStars(StarHandler& starHandler,
const Point3f& position,
const Quatf& orientation,
float fovY,
float aspectRatio,
float limitingMag) const;
int countNodes() const;
int countStars() const;
private:
StarOctreeNode* root;