final names for ViewFrustum intersection tests

This commit is contained in:
Andrew Meadows 2016-02-23 14:16:01 -08:00
parent 5d1e283508
commit f964df6c97
9 changed files with 612 additions and 621 deletions

View file

@ -188,14 +188,14 @@ void Avatar::simulate(float deltaTime) {
// simple frustum check
float boundingRadius = getBoundingRadius();
bool inViewFrustum = (bool)(qApp->getViewFrustum()->sphereInFrustum(getPosition(), boundingRadius));
bool inView = qApp->getViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
{
PerformanceTimer perfTimer("hand");
getHand()->simulate(deltaTime, false);
}
if (_shouldAnimate && !_shouldSkipRender && inViewFrustum) {
if (_shouldAnimate && !_shouldSkipRender && inView) {
{
PerformanceTimer perfTimer("skeleton");
_skeletonModel.getRig()->copyJointsFromJointData(_jointData);
@ -400,7 +400,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
frustum = qApp->getDisplayViewFrustum();
}
if ((bool)(frustum->sphereInFrustum(getPosition(), boundingRadius))) {
if (frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) {
endRender();
return;
}
@ -516,7 +516,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
auto& frustum = *renderArgs->_viewFrustum;
auto textPosition = getDisplayNamePosition();
if ((bool)frustum.pointInFrustum(textPosition)) {
if (frustum.pointIntersectsFrustum(textPosition)) {
renderDisplayName(batch, frustum, textPosition);
}
}
@ -669,10 +669,10 @@ glm::vec3 Avatar::getDisplayNamePosition() const {
return namePosition;
}
Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const {
Q_ASSERT_X((bool)(frustum.pointInFrustum(textPosition)),
Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const {
Q_ASSERT_X(view.pointIntersectsFrustum(textPosition),
"Avatar::calculateDisplayNameTransform", "Text not in viewfrustum.");
glm::vec3 toFrustum = frustum.getPosition() - textPosition;
glm::vec3 toFrustum = view.getPosition() - textPosition;
// Compute orientation
// If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees
@ -694,7 +694,7 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons
return result;
}
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const {
void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const {
PROFILE_RANGE_BATCH(batch, __FUNCTION__);
bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats() && !isMyAvatar();
@ -702,7 +702,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co
// If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return
static const float CLIP_DISTANCE = 0.2f;
if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f
|| (glm::dot(frustum.getDirection(), getDisplayNamePosition() - frustum.getPosition()) <= CLIP_DISTANCE)) {
|| (glm::dot(view.getDirection(), getDisplayNamePosition() - view.getPosition()) <= CLIP_DISTANCE)) {
return;
}
auto renderer = textRenderer(DISPLAYNAME);
@ -743,7 +743,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co
(_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA);
// Compute display name transform
auto textTransform = calculateDisplayNameTransform(frustum, textPosition);
auto textTransform = calculateDisplayNameTransform(view, textPosition);
// Test on extent above insures abs(height) > 0.0f
textTransform.postScale(1.0f / height);
batch.setModelTransform(textTransform);

View file

@ -231,8 +231,8 @@ protected:
float getPelvisFloatingHeight() const;
glm::vec3 getDisplayNamePosition() const;
Transform calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const;
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const;
Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const;
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const;
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f);
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
virtual void fixupModelsInScene();

View file

@ -91,7 +91,7 @@ void OctreeHeadlessViewer::queryOctree() {
if (foundRootDetails) {
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
if (_viewFrustum.cubeIntersectsKeyhole(serverBounds)) {
if ((bool)(_viewFrustum.calculateCubeKeyholeIntersection(serverBounds))) {
inViewServers++;
}
}
@ -162,7 +162,7 @@ void OctreeHeadlessViewer::queryOctree() {
if (foundRootDetails) {
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
inView = _viewFrustum.cubeInFrustum(serverBounds);
inView = (bool)(_viewFrustum.calculateCubeKeyholeIntersection(serverBounds));
}
if (inView) {

View file

@ -130,33 +130,7 @@ const char* ViewFrustum::debugPlaneName (int plane) const {
return "Unknown";
}
ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point) const {
// only check against frustum
for(int i = 0; i < 6; ++i) {
float distance = _planes[i].distance(point);
if (distance < 0.0f) {
return OUTSIDE;
}
}
return INSIDE;
}
ViewFrustum::location ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const {
// only check against frustum
ViewFrustum::location result = INSIDE;
for(int i=0; i < 6; i++) {
float distance = _planes[i].distance(center);
if (distance < -radius) {
// This is outside the regular frustum, so just return the value from checking the keyhole
return OUTSIDE;
} else if (distance < radius) {
result = INTERSECT;
}
}
return result;
}
ViewFrustum::location ViewFrustum::cubeInFrustum(const AACube& cube) const {
ViewFrustum::location ViewFrustum::calculateCubeFrustumIntersection(const AACube& cube) const {
// only check against frustum
ViewFrustum::location result = INSIDE;
for(int i=0; i < 6; i++) {
@ -175,25 +149,6 @@ ViewFrustum::location ViewFrustum::cubeInFrustum(const AACube& cube) const {
return result;
}
ViewFrustum::location ViewFrustum::boxInFrustum(const AABox& box) const {
// only check against frustum
ViewFrustum::location result = INSIDE;
for(int i=0; i < 6; i++) {
const glm::vec3& normal = _planes[i].getNormal();
// check distance to farthest box point
if ( _planes[i].distance(box.getFarthestVertex(normal)) < 0.0f) {
return OUTSIDE;
} else {
// check distance to nearest box point
if (_planes[i].distance(box.getNearestVertex(normal)) < 0.0f) {
// box straddles the plane
result = INTERSECT;
}
}
}
return result;
}
const float HALF_SQRT_THREE = 0.8660254f;
ViewFrustum::location ViewFrustum::calculateCubeKeyholeIntersection(const AACube& cube) const {
@ -216,11 +171,47 @@ ViewFrustum::location ViewFrustum::calculateCubeKeyholeIntersection(const AACube
}
// check against frustum
ViewFrustum::location frustumResult = cubeInFrustum(cube);
ViewFrustum::location frustumResult = calculateCubeFrustumIntersection(cube);
return (frustumResult == OUTSIDE) ? sphereResult : frustumResult;
}
bool ViewFrustum::pointIntersectsFrustum(const glm::vec3& point) const {
// only check against frustum
for(int i = 0; i < 6; ++i) {
float distance = _planes[i].distance(point);
if (distance < 0.0f) {
return false;
}
}
return true;
}
bool ViewFrustum::sphereIntersectsFrustum(const glm::vec3& center, float radius) const {
// only check against frustum
for(int i=0; i < 6; i++) {
float distance = _planes[i].distance(center);
if (distance < -radius) {
// This is outside the regular frustum, so just return the value from checking the keyhole
return false;
}
}
return true;
}
bool ViewFrustum::boxIntersectsFrustum(const AABox& box) const {
// only check against frustum
ViewFrustum::location result = INSIDE;
for(int i=0; i < 6; i++) {
const glm::vec3& normal = _planes[i].getNormal();
// check distance to farthest box point
if ( _planes[i].distance(box.getFarthestVertex(normal)) < 0.0f) {
return false;
}
}
return true;
}
bool ViewFrustum::sphereIntersectsKeyhole(const glm::vec3& center, float radius) const {
// check positive touch against central sphere
if (glm::length(center - _position) <= (radius + _centerSphereRadius)) {

View file

@ -94,15 +94,15 @@ public:
typedef enum { OUTSIDE = 0, INTERSECT, INSIDE } location;
ViewFrustum::location pointInFrustum(const glm::vec3& point) const;
ViewFrustum::location sphereInFrustum(const glm::vec3& center, float radius) const;
ViewFrustum::location cubeInFrustum(const AACube& cube) const;
ViewFrustum::location boxInFrustum(const AABox& box) const;
/// @return INSIDE, INTERSECT, or OUTSIDE depending on how cube intersects the keyhole shape
ViewFrustum::location calculateCubeFrustumIntersection(const AACube& cube) const;
ViewFrustum::location calculateCubeKeyholeIntersection(const AACube& cube) const;
// more efficient methods when only need boolean result
bool pointIntersectsFrustum(const glm::vec3& point) const;
bool sphereIntersectsFrustum(const glm::vec3& center, float radius) const;
bool cubeIntersectsFrustum(const AACube& box) const;
bool boxIntersectsFrustum(const AABox& box) const;
bool sphereIntersectsKeyhole(const glm::vec3& center, float radius) const;
bool cubeIntersectsKeyhole(const AACube& cube) const;
bool boxIntersectsKeyhole(const AABox& box) const;

View file

@ -478,7 +478,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
glm::vec4 cubeColor(1.0f, 1.0f, 0.0f, 1.0f);
if (isSkinned) {
cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f);
} else if ((bool)(args->_viewFrustum->boxInFrustum(partBounds))) {
} else if (args->_viewFrustum->boxIntersectsFrustum(partBounds)) {
cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f);
}

View file

@ -39,12 +39,12 @@ void render::cullItems(const RenderContextPointer& renderContext, const CullFunc
// TODO: some entity types (like lights) might want to be rendered even
// when they are outside of the view frustum...
bool outOfView;
bool inView;
{
PerformanceTimer perfTimer("boxInFrustum");
outOfView = frustum->boxInFrustum(item.bound) == ViewFrustum::OUTSIDE;
PerformanceTimer perfTimer("boxIntersectsFrustum");
inView = frustum->boxIntersectsFrustum(item.bound);
}
if (!outOfView) {
if (inView) {
bool bigEnoughToRender;
{
PerformanceTimer perfTimer("shouldRender");
@ -238,7 +238,7 @@ void CullSpatialSelection::run(const SceneContextPointer& sceneContext, const Re
}
bool frustumTest(const AABox& bound) {
if (_args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE) {
if (!_args->_viewFrustum->boxIntersectsFrustum(bound)) {
_renderDetails._outOfView++;
return false;
}

File diff suppressed because it is too large Load diff

View file

@ -19,14 +19,14 @@ class ViewFrustumTests : public QObject {
private slots:
void testInit();
void testPointInFrustum();
void testSphereInFrustum();
void testCubeInFrustum();
void testBoxInFrustum();
void testCubeInKeyhole();
void testSphereTouchesKeyhole();
void testCubeTouchesKeyhole();
void testBoxTouchesKeyhole();
void testCubeFrustumIntersection();
void testCubeKeyholeIntersection();
void testPointIntersectsFrustum();
void testSphereIntersectsFrustum();
void testBoxIntersectsFrustum();
void testSphereIntersectsKeyhole();
void testCubeIntersectsKeyhole();
void testBoxIntersectsKeyhole();
};
#endif // hifi_ViewFruxtumTests_h