diff --git a/java/F3DJavaBindings.cxx b/java/F3DJavaBindings.cxx index f57a3be58f..e6cf340211 100644 --- a/java/F3DJavaBindings.cxx +++ b/java/F3DJavaBindings.cxx @@ -198,4 +198,4 @@ extern "C" { GetEngine(env, self)->getWindow().getCamera().resetToBounds(); } -} +} \ No newline at end of file diff --git a/library/private/camera_impl.h b/library/private/camera_impl.h index 17173d74ca..7b480d2751 100644 --- a/library/private/camera_impl.h +++ b/library/private/camera_impl.h @@ -50,6 +50,9 @@ class camera_impl : public camera camera& setState(const camera_state_t& state) override; camera_state_t getState() override; void getState(camera_state_t& state) override; + angle_deg_t getAzimuth() override; + angle_deg_t getYaw() override; + angle_deg_t getElevation() override; camera& dolly(double val) override; camera& pan(double right, double up, double forward) override; diff --git a/library/public/camera.h b/library/public/camera.h index 670afec571..4e8ec9ecf0 100644 --- a/library/public/camera.h +++ b/library/public/camera.h @@ -51,6 +51,15 @@ class F3D_EXPORT camera virtual void getState(camera_state_t& state) = 0; ///@} + ///@{ @name Orientation + /** Get the azimuth angle of the camera. */ + virtual angle_deg_t getAzimuth() = 0; + /** Get the yaw angle of the camera. */ + virtual angle_deg_t getYaw() = 0; + /** Get the elevation angle of the camera. */ + virtual angle_deg_t getElevation() = 0; + ///@} + ///@{ @name Manipulation /// Standard camera manipulation methods. Angles are in degrees. diff --git a/library/src/camera_impl.cxx b/library/src/camera_impl.cxx index 68e72f9635..13c11e8ba9 100644 --- a/library/src/camera_impl.cxx +++ b/library/src/camera_impl.cxx @@ -117,6 +117,55 @@ angle_deg_t camera_impl::getViewAngle() return angle; } +//---------------------------------------------------------------------------- +angle_deg_t camera_impl::getAzimuth() +{ + vtkCamera* cam = this->GetVTKCamera(); + double pos[3], foc[3]; + cam->GetPosition(pos); + cam->GetFocalPoint(foc); + double viewDir[3]; + vtkMath::Subtract(foc, pos, viewDir); + double viewDirProj[2] = { viewDir[0], viewDir[1] }; + if (vtkMath::Dot2D(viewDirProj, viewDirProj) < VTK_DBL_EPSILON) + { + return 0.0; + } + return vtkMath::DegreesFromRadians(atan2(viewDirProj[1], viewDirProj[0])); +} + +//---------------------------------------------------------------------------- +angle_deg_t camera_impl::getYaw() +{ + vtkCamera* cam = this->GetVTKCamera(); + double pos[3], foc[3]; + cam->GetPosition(pos); + cam->GetFocalPoint(foc); + double viewDir[3]; + vtkMath::Subtract(foc, pos, viewDir); + double viewDirProj[2] = { viewDir[0], viewDir[2] }; + if (vtkMath::Dot2D(viewDirProj, viewDirProj) < VTK_DBL_EPSILON) + { + return 0.0; + } + return vtkMath::DegreesFromRadians(atan2(viewDirProj[0], viewDirProj[1])); +} + +//---------------------------------------------------------------------------- +angle_deg_t camera_impl::getElevation() +{ + vtkCamera* cam = this->GetVTKCamera(); + double pos[3], foc[3]; + cam->GetPosition(pos); + cam->GetFocalPoint(foc); + + double viewDir[3]; + vtkMath::Subtract(foc, pos, viewDir); + vtkMath::Normalize(viewDir); + + return vtkMath::DegreesFromRadians(asin(viewDir[2])); +} + //---------------------------------------------------------------------------- void camera_impl::getViewAngle(angle_deg_t& angle) { diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index 44814b2e18..538a19d0d3 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -75,6 +75,7 @@ option(F3D_TESTING_ENABLE_EXTERNAL_QT "Test external QT" OFF) set(libf3dSDKTests_link_libs "") +find_package(VTK REQUIRED COMPONENTS CommonCore) if(F3D_TESTING_ENABLE_EXTERNAL_GLFW) find_package(glfw3 REQUIRED) list(APPEND libf3dSDKTests_list TestSDKExternalWindowGLFW.cxx) @@ -177,7 +178,7 @@ if(F3D_MODULE_UI AND NOT F3D_TESTING_ENABLE_LONG_TIMEOUT_TESTS) set_tests_properties(libf3d::TestSDKInteractorCallBack PROPERTIES DISABLED ON) endif() -target_link_libraries(libf3dSDKTests libf3d ${libf3dSDKTests_link_libs}) +target_link_libraries(libf3dSDKTests libf3d ${libf3dSDKTests_link_libs} VTK::CommonCore) # make sure the libf3d API is compatible with the right C++ standard set_target_properties(libf3dSDKTests PROPERTIES CXX_STANDARD 17) diff --git a/library/testing/TestSDKCamera.cxx b/library/testing/TestSDKCamera.cxx index 3210f4f210..4208fb4419 100644 --- a/library/testing/TestSDKCamera.cxx +++ b/library/testing/TestSDKCamera.cxx @@ -8,6 +8,7 @@ #include <iostream> #include <limits> #include <sstream> +#include <vtkMath.h> // TODO these methods should be put in types.h at some point. // https://github.com/f3d-app/f3d/issues/361 @@ -141,6 +142,19 @@ int TestSDKCamera(int argc, char* argv[]) return EXIT_FAILURE; } + // Test getAzimuth + f3d::point3_t tempPos = { 0.0, 0.0, 0.0 }; + f3d::point3_t tempFoc = { 0.0, 0.0, 1.0 }; + cam.setPosition(tempPos); + cam.setFocalPoint(tempFoc); + f3d::angle_deg_t azimuth = cam.getAzimuth(); + if (!compareDouble(azimuth, 0.0)) + { + std::cerr << "getAzimuth is not behaving as expected:" << std::endl; + std::cerr << std::setprecision(12) << "azimuth: " << azimuth << " != 0.0" << std::endl; + return EXIT_FAILURE; + } + // Test roll cam.roll(90); expectedUp = { 0., 0., -1. }; @@ -179,6 +193,19 @@ int TestSDKCamera(int argc, char* argv[]) return EXIT_FAILURE; } + // Test getYaw + // f3d::point3_t testPos = { 0.0, 0.0, 0.0 }; + f3d::point3_t termFoc = { 0.0, 0.0, 1.0 }; + // cam.setPosition(testPos); + cam.setFocalPoint(termFoc); + f3d::angle_deg_t yaw = cam.getYaw(); + if (!compareDouble(yaw, 0.0)) + { + std::cerr << "getYaw is not behaving as expected:" << std::endl; + std::cerr << std::setprecision(12) << "yaw: " << yaw << " != 0.0" << std::endl; + return EXIT_FAILURE; + } + // Test elevation cam.elevation(90); expectedPos = { 11., -11., -12. }; @@ -199,6 +226,10 @@ int TestSDKCamera(int argc, char* argv[]) return EXIT_FAILURE; } + // Test getElevation + double elevation = cam.getElevation(); + checkDouble(elevation, 90.0, "getElevation"); + // Test pitch cam.pitch(90); expectedFoc = { 22., -11., -12. }; diff --git a/python/F3DPythonBindings.cxx b/python/F3DPythonBindings.cxx index 71aa2c62db..4c3cf71c76 100644 --- a/python/F3DPythonBindings.cxx +++ b/python/F3DPythonBindings.cxx @@ -478,4 +478,4 @@ PYBIND11_MODULE(pyf3d, module) .def_static("set_use_coloring", &f3d::log::setUseColoring) .def_static("print", [](f3d::log::VerboseLevel& level, const std::string& message) { f3d::log::print(level, message); }); -} +} \ No newline at end of file