diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..63c5d37b51 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "C_Cpp.errorSquiggles": "disabled", + "files.associations": { + "cmath": "cpp" + } +} \ No newline at end of file diff --git a/application/F3DStarter.cxx b/application/F3DStarter.cxx index 0dc24a4fc3..ef6f5712ac 100644 --- a/application/F3DStarter.cxx +++ b/application/F3DStarter.cxx @@ -160,8 +160,8 @@ class F3DStarter::F3DInternals cam.resetToBounds(zoomFactor); } - cam.azimuth(camConf.CameraAzimuthAngle) - .elevation(camConf.CameraElevationAngle) + cam.addAzimuth(camConf.CameraAzimuthAngle) + .addElevation(camConf.CameraElevationAngle) .setCurrentAsDefault(); } diff --git a/java/Camera.java b/java/Camera.java index bf2f5aa31c..871e8324e5 100644 --- a/java/Camera.java +++ b/java/Camera.java @@ -8,9 +8,9 @@ public Camera(long nativeAddress) { public native void dolly(double val); public native void roll(double angle); - public native void azimuth(double angle); - public native void yaw(double angle); - public native void elevation(double angle); + public native void addAzimuth(double angle); + public native void addYaw(double angle); + public native void addElevation(double angle); public native void pitch(double angle); public native double[] getFocalPoint(); diff --git a/java/F3DJavaBindings.cxx b/java/F3DJavaBindings.cxx index adc1b907f2..8516838da2 100644 --- a/java/F3DJavaBindings.cxx +++ b/java/F3DJavaBindings.cxx @@ -136,21 +136,21 @@ extern "C" GetEngine(env, self)->getWindow().getCamera().roll(angle); } - JNIEXPORT void JAVA_BIND(Camera, azimuth)(JNIEnv* env, jobject self, jdouble angle) + JNIEXPORT void JNICALL JAVA_BIND(Camera, addAzimuth)(JNIEnv* env, jobject self, jdouble angle) { - GetEngine(env, self)->getWindow().getCamera().azimuth(angle); + GetEngine(env, self)->getWindow().getCamera().addAzimuth(angle); } - JNIEXPORT void JAVA_BIND(Camera, yaw)(JNIEnv* env, jobject self, jdouble angle) + JNIEXPORT void JNICALL JAVA_BIND(Camera, addYaw)(JNIEnv* env, jobject self, jdouble angle) { - GetEngine(env, self)->getWindow().getCamera().yaw(angle); + GetEngine(env, self)->getWindow().getCamera().addYaw(angle); } - JNIEXPORT void JAVA_BIND(Camera, elevation)(JNIEnv* env, jobject self, jdouble angle) + JNIEXPORT void JNICALL JAVA_BIND(Camera, addElevation)(JNIEnv* env, jobject self, jdouble angle) { - GetEngine(env, self)->getWindow().getCamera().elevation(angle); + GetEngine(env, self)->getWindow().getCamera().addElevation(angle); } - + JNIEXPORT void JAVA_BIND(Camera, pitch)(JNIEnv* env, jobject self, jdouble angle) { GetEngine(env, self)->getWindow().getCamera().pitch(angle); diff --git a/library/private/camera_impl.h b/library/private/camera_impl.h index 17173d74ca..b34bf9f05d 100644 --- a/library/private/camera_impl.h +++ b/library/private/camera_impl.h @@ -50,14 +50,17 @@ 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; camera& zoom(double factor) override; camera& roll(angle_deg_t angle) override; - camera& azimuth(angle_deg_t angle) override; - camera& yaw(angle_deg_t angle) override; - camera& elevation(angle_deg_t angle) override; + camera& addAzimuth(angle_deg_t angle) override; + camera& addYaw(angle_deg_t angle) override; + camera& addElevation(angle_deg_t angle) override; camera& pitch(angle_deg_t angle) override; camera& setCurrentAsDefault() override; diff --git a/library/public/camera.h b/library/public/camera.h index 670afec571..53af247dd3 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. @@ -63,11 +72,11 @@ class F3D_EXPORT camera /** Rotate the camera about its forward axis. */ virtual camera& roll(angle_deg_t angle) = 0; /** Rotate the camera about its vertical axis, centered at the focal point. */ - virtual camera& azimuth(angle_deg_t angle) = 0; + virtual camera& addAzimuth(angle_deg_t angle) = 0; /** Rotate the camera about its vertical axis, centered the camera's position. */ - virtual camera& yaw(angle_deg_t angle) = 0; + virtual camera& addYaw(angle_deg_t angle) = 0; /** Rotate the camera about its horizontal axis, centered at the focal point. */ - virtual camera& elevation(angle_deg_t angle) = 0; + virtual camera& addElevation(angle_deg_t angle) = 0; /** Rotate the camera about its horizontal axis, centered the camera's position. */ virtual camera& pitch(angle_deg_t angle) = 0; diff --git a/library/src/camera_impl.cxx b/library/src/camera_impl.cxx index 68e72f9635..cfbf85ceee 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) { @@ -215,7 +264,7 @@ camera& camera_impl::roll(angle_deg_t angle) } //---------------------------------------------------------------------------- -camera& camera_impl::azimuth(angle_deg_t angle) +camera& camera_impl::addAzimuth(angle_deg_t angle) { vtkCamera* cam = this->GetVTKCamera(); cam->Azimuth(angle); @@ -225,7 +274,7 @@ camera& camera_impl::azimuth(angle_deg_t angle) } //---------------------------------------------------------------------------- -camera& camera_impl::yaw(angle_deg_t angle) +camera& camera_impl::addYaw(angle_deg_t angle) { vtkCamera* cam = this->GetVTKCamera(); cam->Yaw(angle); @@ -235,7 +284,7 @@ camera& camera_impl::yaw(angle_deg_t angle) } //---------------------------------------------------------------------------- -camera& camera_impl::elevation(angle_deg_t angle) +camera& camera_impl::addElevation(angle_deg_t angle) { vtkCamera* cam = this->GetVTKCamera(); cam->Elevation(angle); diff --git a/library/testing/TestSDKCamera.cxx b/library/testing/TestSDKCamera.cxx index 3210f4f210..4525f4d987 100644 --- a/library/testing/TestSDKCamera.cxx +++ b/library/testing/TestSDKCamera.cxx @@ -121,7 +121,7 @@ int TestSDKCamera(int argc, char* argv[]) } // Test azimuth - cam.azimuth(90); + cam.addAzimuth(90); f3d::point3_t expectedPos = { 0., -11., -1. }; f3d::point3_t expectedFoc = { 0., 0., -1. }; f3d::vector3_t expectedUp = { 1., 0., 0. }; @@ -141,6 +141,23 @@ int TestSDKCamera(int argc, char* argv[]) return EXIT_FAILURE; } + // Test getAzimuth + f3d::angle_deg_t azimuth = cam.getAzimuth(); + if (!compareDouble(azimuth, 90.0)) + { + std::cerr << "getAzimuth is not behaving as expected:" << std::endl; + std::cerr << std::setprecision(12) << "azimuth: " << azimuth << " != 90.0" << std::endl; + return EXIT_FAILURE; + } + double viewDirProj[2] = { 1.0, 1.0 }; + double dotProduct = viewDirProj[0] * viewDirProj[0] + viewDirProj[1] * viewDirProj[1]; + const double epsilon = std::numeric_limits::epsilon(); + if (dotProduct < epsilon) + { + std::cerr << "Dot product is lesser than epsilon, returning failure." << std::endl; + return EXIT_FAILURE; + } + // Test roll cam.roll(90); expectedUp = { 0., 0., -1. }; @@ -161,7 +178,7 @@ int TestSDKCamera(int argc, char* argv[]) } // Test yaw - cam.yaw(90); + cam.addYaw(90); expectedFoc = { 11., -11., -1. }; pos = cam.getPosition(); foc = cam.getFocalPoint(); @@ -179,8 +196,22 @@ int TestSDKCamera(int argc, char* argv[]) return EXIT_FAILURE; } + // Test getYaw + f3d::angle_deg_t yaw = cam.getYaw(); + if (!compareDouble(yaw, 90.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; + } + if (dotProduct < epsilon) + { + std::cerr << "Dot product is lesser than epsilon, returning failure." << std::endl; + return EXIT_FAILURE; + } + // Test elevation - cam.elevation(90); + cam.addElevation(90); expectedPos = { 11., -11., -12. }; expectedUp = { 1., 0., 0. }; pos = cam.getPosition(); @@ -199,6 +230,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 2465e22fca..ac8b925698 100644 --- a/python/F3DPythonBindings.cxx +++ b/python/F3DPythonBindings.cxx @@ -339,9 +339,12 @@ PYBIND11_MODULE(pyf3d, module) .def("pan", &f3d::camera::pan, py::arg("right"), py::arg("up"), py::arg("forward") = 0.0) .def("zoom", &f3d::camera::zoom) .def("roll", &f3d::camera::roll) - .def("azimuth", &f3d::camera::azimuth) - .def("yaw", &f3d::camera::yaw) - .def("elevation", &f3d::camera::elevation) + .def("add_azimuth", &f3d::camera::addAzimuth) + .def("add_yaw", &f3d::camera::addYaw) + .def("add_elevation", &f3d::camera::addElevation) + .def_property_readonly("azimuth", &f3d::camera::getAzimuth) + .def_property_readonly("yaw", &f3d::camera::getYaw) + .def_property_readonly("elevation", &f3d::camera::getElevation) .def("pitch", &f3d::camera::pitch) .def("set_current_as_default", &f3d::camera::setCurrentAsDefault) .def("reset_to_default", &f3d::camera::resetToDefault) diff --git a/python/testing/test_camera.py b/python/testing/test_camera.py index 1341ddb74b..cab6086376 100644 --- a/python/testing/test_camera.py +++ b/python/testing/test_camera.py @@ -80,9 +80,9 @@ def test_moves(): camera.dolly(10) angle = 30 camera.roll(angle) - camera.azimuth(angle) - camera.yaw(angle) - camera.elevation(angle) + camera.add_azimuth(angle) + camera.add_yaw(angle) + camera.add_elevation(angle) camera.pitch(angle)