mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 22:27:55 -05:00
Fix crash in Camera::computeFitViewEyePosition with parallel dir/up
dir^up becomes a zero vector when the view direction and up vector are parallel, producing an invalid zero-normal plane. Plane::distanceToOrigin() then asserts/aborts (CVF_ASSERT, always active). Fall back to an arbitrary axis to compute a valid right vector in this degenerate case.
This commit is contained in:
1 parent
b0e8d0b62c
commit
1a6c29a319
4 files changed
+62
-1
No files matched your search
@@ -168,6 +168,7 @@ set(SOURCE_UNITTEST_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPolygonInViewCollection-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSurfaceInViewCollection-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimViewController-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/CvfCameraCrashTriage-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaNameUniquenessTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifVtkSurfaceImporter-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifVtkReader-Test.cpp
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
#include "cvfCamera.h"
|
||||
|
||||
using namespace cvf;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// computeFitViewEyePosition() used to assert/abort (CVF_ASSERT in Plane::distanceToOrigin) when
|
||||
/// the view direction and up vector are parallel: dir^up then becomes a zero vector, producing an
|
||||
/// invalid (zero-normal) plane used internally. Reproduces the crash reported from
|
||||
/// caf::Viewer::zoomAll() with a degenerate camera orientation.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( CvfCameraCrashTriageTest, FitViewWithParallelDirAndUpDoesNotCrash )
|
||||
{
|
||||
Camera c;
|
||||
|
||||
BoundingBox bb;
|
||||
bb.add( Vec3d( 0, 0, 0 ) );
|
||||
bb.add( Vec3d( 1, 1, 1 ) );
|
||||
|
||||
Vec3d inViewDir( 0, 0, 1 );
|
||||
Vec3d inUp( 0, 0, 1 );
|
||||
double coverageFactor = 0.9;
|
||||
|
||||
Vec3d eye = Camera::computeFitViewEyePosition( bb, inViewDir, inUp, coverageFactor, c.fieldOfViewYDeg(), 1.0 );
|
||||
|
||||
EXPECT_FALSE( eye.isUndefined() );
|
||||
}
|
||||
@@ -306,7 +306,14 @@ Vec3d Camera::computeFitViewEyePosition(const BoundingBox& boundingBox, const Ve
|
||||
|
||||
cvf::Vec3d upNorm = up.getNormalized();
|
||||
cvf::Vec3d right = dir^up;
|
||||
right.normalize();
|
||||
if (!right.normalize())
|
||||
{
|
||||
// dir and up are parallel (degenerate camera orientation). Fall back to an arbitrary axis
|
||||
// not parallel to dir to still produce a valid right vector.
|
||||
const cvf::Vec3d& fallbackAxis = (cvf::Math::abs(dir.x()) < 0.9) ? cvf::Vec3d::X_AXIS : cvf::Vec3d::Y_AXIS;
|
||||
right = dir^fallbackAxis;
|
||||
right.normalize();
|
||||
}
|
||||
cvf::Vec3d boxEyeNorm = (-dir).getNormalized();
|
||||
|
||||
cvf::Plane planeTop;
|
||||
|
||||
@@ -184,6 +184,30 @@ TEST(CameraTest, FitView)
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// computeFitViewEyePosition() used to assert/abort (CVF_ASSERT in Plane::distanceToOrigin) when
|
||||
/// the view direction and up vector are parallel: dir^up then becomes a zero vector, producing an
|
||||
/// invalid (zero-normal) plane used internally. Reproduces the crash reported from
|
||||
/// caf::Viewer::zoomAll() with a degenerate camera orientation.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(CameraTest, FitViewWithParallelDirAndUpDoesNotCrash)
|
||||
{
|
||||
Camera c;
|
||||
|
||||
BoundingBox bb;
|
||||
bb.add(Vec3d(0, 0, 0));
|
||||
bb.add(Vec3d(1, 1, 1));
|
||||
|
||||
Vec3d inViewDir(0, 0, 1);
|
||||
Vec3d inUp(0, 0, 1);
|
||||
double coverageFactor = 0.9;
|
||||
|
||||
Vec3d eye = Camera::computeFitViewEyePosition(bb, inViewDir, inUp, coverageFactor, c.fieldOfViewYDeg(), 1.0);
|
||||
|
||||
EXPECT_FALSE(eye.isUndefined());
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user