| | |
| |
|
| | #include <gtest/gtest.h> |
| |
|
| | #include <array> |
| | #include <cmath> |
| |
|
| | #include <Inventor/SbMatrix.h> |
| | #include <Inventor/SbRotation.h> |
| | #include <Inventor/SbViewVolume.h> |
| | #include <Base/Converter.h> |
| | #include <Base/Tools.h> |
| | #include <Gui/Camera.h> |
| | #include <Gui/Utilities.h> |
| |
|
| | #include <src/App/InitApplication.h> |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | using Base::convertTo; |
| | using Base::Rotation; |
| | using Base::toRadians; |
| | using Base::Vector3d; |
| |
|
| | namespace |
| | { |
| |
|
| | Rotation buildAxonometricRotation(double alphaRad, double betaRad) |
| | { |
| | const auto p1 = Rotation(Vector3d::UnitX, toRadians<float>(90.0)); |
| | const auto p2 = Rotation(Vector3d::UnitZ, alphaRad); |
| | const auto p3 = Rotation(p2.multVec(Vector3d::UnitX), betaRad); |
| | const auto p4 = p3 * p2 * p1; |
| |
|
| | return p4; |
| | } |
| |
|
| | |
| | std::array<double, 3> getProjectedLengths(const SbRotation& rot) |
| | { |
| | |
| | |
| | |
| | SbViewVolume volume; |
| | |
| | volume.ortho(-10, 10, -10, 10, -10, 10); |
| |
|
| | volume.rotateCamera(rot); |
| | const auto matrix = volume.getMatrix(); |
| |
|
| | |
| | SbVec3f vo, vx, vy, vz; |
| | matrix.multVecMatrix(SbVec3f(0, 0, 0), vo); |
| | matrix.multVecMatrix(SbVec3f(10, 0, 0), vx); |
| | matrix.multVecMatrix(SbVec3f(0, 10, 0), vy); |
| | matrix.multVecMatrix(SbVec3f(0, 0, 10), vz); |
| |
|
| | |
| | vo[2] = 0; |
| | vx[2] = 0; |
| | vy[2] = 0; |
| | vz[2] = 0; |
| |
|
| | |
| | return {(vx - vo).length(), (vy - vo).length(), (vz - vo).length()}; |
| | } |
| |
|
| | } |
| |
|
| | class CameraPrecalculatedQuaternions: public ::testing::Test |
| | { |
| | protected: |
| | static void SetUpTestSuite() |
| | { |
| | tests::initApplication(); |
| | } |
| | }; |
| |
|
| | TEST_F(CameraPrecalculatedQuaternions, testIsometric) |
| | { |
| | |
| | double alpha = toRadians(45.0f); |
| | double beta = std::asin(-std::sqrt(1.0 / 3.0)); |
| |
|
| | const Rotation actual = buildAxonometricRotation(alpha, beta); |
| | const Rotation expected = convertTo<Rotation>(Gui::Camera::isometric()); |
| |
|
| | EXPECT_TRUE(actual.isSame(expected, 1e-6)); |
| | } |
| |
|
| | TEST_F(CameraPrecalculatedQuaternions, testDimetric) |
| | { |
| | |
| | double alpha = std::asin(std::sqrt(1.0 / 8.0)); |
| | double beta = -std::asin(1.0 / 3.0); |
| |
|
| | const Rotation actual = buildAxonometricRotation(alpha, beta); |
| | const Rotation expected = convertTo<Rotation>(Gui::Camera::dimetric()); |
| |
|
| | EXPECT_TRUE(actual.isSame(expected, 1e-6)); |
| | } |
| |
|
| | TEST_F(CameraPrecalculatedQuaternions, testTrimetric) |
| | { |
| | |
| | double alpha = toRadians(30.0); |
| | double beta = toRadians(-35.0); |
| |
|
| | const Rotation actual = buildAxonometricRotation(alpha, beta); |
| | const Rotation expected = convertTo<Rotation>(Gui::Camera::trimetric()); |
| |
|
| | EXPECT_TRUE(actual.isSame(expected, 1e-6)); |
| | } |
| |
|
| |
|
| | class CameraRotation: public ::testing::Test |
| | { |
| | protected: |
| | static void SetUpTestSuite() |
| | { |
| | tests::initApplication(); |
| | } |
| | }; |
| |
|
| | TEST_F(CameraRotation, testIsometricProjection) |
| | { |
| | auto rot = Gui::Camera::isometric(); |
| | auto lengths = getProjectedLengths(rot); |
| |
|
| | |
| | EXPECT_NEAR(lengths[0], lengths[1], 1e-6); |
| | EXPECT_NEAR(lengths[0], lengths[2], 1e-6); |
| | EXPECT_NEAR(lengths[1], lengths[2], 1e-6); |
| | } |
| |
|
| | TEST_F(CameraRotation, testDimetricProjection) |
| | { |
| | const auto rot = Gui::Camera::dimetric(); |
| | const auto lengths = getProjectedLengths(rot); |
| |
|
| | |
| | const std::initializer_list<std::pair<double, double>> pairs = { |
| | {lengths[0], lengths[1]}, |
| | {lengths[1], lengths[2]}, |
| | {lengths[0], lengths[2]}, |
| | }; |
| |
|
| | constexpr double tolerance = 1e-6; |
| | const auto isSimilar = [&](std::pair<double, double> lengths) -> bool { |
| | return std::abs(lengths.first - lengths.second) < tolerance; |
| | }; |
| |
|
| | unsigned similarCount = std::ranges::count_if(pairs, isSimilar); |
| |
|
| | EXPECT_EQ(similarCount, 1); |
| | } |
| |
|
| | TEST_F(CameraRotation, testTrimetricProjection) |
| | { |
| | auto rot = Gui::Camera::trimetric(); |
| | auto lengths = getProjectedLengths(rot); |
| |
|
| | |
| | EXPECT_GT(std::abs(lengths[0] - lengths[1]), 1e-3); |
| | EXPECT_GT(std::abs(lengths[1] - lengths[2]), 1e-3); |
| | EXPECT_GT(std::abs(lengths[0] - lengths[2]), 1e-3); |
| | } |
| |
|