Browse Source

Implement manual rotation around normal, prepare compensation

Johannes Kreutz 2 years ago
parent
commit
159895b3eb

BIN
testdata/glasRotate.trackproj


BIN
testdata/testRotate.3mf


+ 88 - 28
trackpoint-app/gui/EditWidget.ui

@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>508</width>
-    <height>914</height>
+    <height>1040</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -40,7 +40,7 @@
         <x>0</x>
         <y>0</y>
         <width>506</width>
-        <height>917</height>
+        <height>1038</height>
        </rect>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_7">
@@ -329,8 +329,8 @@
             <property name="spacing">
              <number>-1</number>
             </property>
-            <item row="0" column="0">
-             <widget class="QLabel" name="normalModLabel">
+            <item row="1" column="0">
+             <widget class="QLabel" name="normalModLabelX">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                 <horstretch>0</horstretch>
@@ -338,12 +338,29 @@
                </sizepolicy>
               </property>
               <property name="text">
-               <string>Rotation around axis</string>
+               <string>X:</string>
               </property>
              </widget>
             </item>
-            <item row="2" column="0">
-             <widget class="QLabel" name="normalModLabelY">
+            <item row="4" column="0">
+             <widget class="QLabel" name="rotateAroundNormalLabel">
+              <property name="text">
+               <string>Rotate around normal:</string>
+              </property>
+             </widget>
+            </item>
+            <item row="4" column="1">
+             <widget class="QDoubleSpinBox" name="rotateAroundNormal">
+              <property name="decimals">
+               <number>2</number>
+              </property>
+              <property name="maximum">
+               <double>360.000000000000000</double>
+              </property>
+             </widget>
+            </item>
+            <item row="3" column="0">
+             <widget class="QLabel" name="normalModLabelZ">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                 <horstretch>0</horstretch>
@@ -351,12 +368,12 @@
                </sizepolicy>
               </property>
               <property name="text">
-               <string>Y:</string>
+               <string>Z:</string>
               </property>
              </widget>
             </item>
-            <item row="1" column="1">
-             <widget class="QDoubleSpinBox" name="normalModX">
+            <item row="2" column="1">
+             <widget class="QDoubleSpinBox" name="normalModY">
               <property name="decimals">
                <number>2</number>
               </property>
@@ -371,8 +388,8 @@
               </property>
              </widget>
             </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="normalModLabelX">
+            <item row="0" column="0">
+             <widget class="QLabel" name="normalModLabel">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                 <horstretch>0</horstretch>
@@ -380,12 +397,28 @@
                </sizepolicy>
               </property>
               <property name="text">
-               <string>X:</string>
+               <string>Rotation around axis</string>
               </property>
              </widget>
             </item>
-            <item row="3" column="0">
-             <widget class="QLabel" name="normalModLabelZ">
+            <item row="3" column="1">
+             <widget class="QDoubleSpinBox" name="normalModZ">
+              <property name="decimals">
+               <number>2</number>
+              </property>
+              <property name="minimum">
+               <double>0.000000000000000</double>
+              </property>
+              <property name="maximum">
+               <double>360.000000000000000</double>
+              </property>
+              <property name="singleStep">
+               <double>1.000000000000000</double>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="0">
+             <widget class="QLabel" name="normalModLabelY">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
                 <horstretch>0</horstretch>
@@ -393,12 +426,12 @@
                </sizepolicy>
               </property>
               <property name="text">
-               <string>Z:</string>
+               <string>Y:</string>
               </property>
              </widget>
             </item>
-            <item row="2" column="1">
-             <widget class="QDoubleSpinBox" name="normalModY">
+            <item row="1" column="1">
+             <widget class="QDoubleSpinBox" name="normalModX">
               <property name="decimals">
                <number>2</number>
               </property>
@@ -413,19 +446,26 @@
               </property>
              </widget>
             </item>
-            <item row="3" column="1">
-             <widget class="QDoubleSpinBox" name="normalModZ">
-              <property name="decimals">
-               <number>2</number>
+            <item row="5" column="0">
+             <widget class="QLabel" name="compensationLabel">
+              <property name="text">
+               <string>Compensation:</string>
               </property>
-              <property name="minimum">
-               <double>0.000000000000000</double>
+             </widget>
+            </item>
+            <item row="5" column="1">
+             <widget class="QCheckBox" name="compensation">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
               </property>
-              <property name="maximum">
-               <double>360.000000000000000</double>
+              <property name="text">
+               <string/>
               </property>
-              <property name="singleStep">
-               <double>1.000000000000000</double>
+              <property name="checked">
+               <bool>true</bool>
               </property>
              </widget>
             </item>
@@ -836,6 +876,26 @@
             </property>
            </widget>
           </item>
+          <item>
+           <widget class="QProgressBar" name="exportProgress">
+            <property name="maximum">
+             <number>3</number>
+            </property>
+            <property name="value">
+             <number>1</number>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="exportLabel">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="text">
+             <string>Export running: 1 of 3</string>
+            </property>
+           </widget>
+          </item>
          </layout>
         </widget>
        </item>

+ 1 - 1
trackpoint-app/include/ActionPoint.hpp

@@ -7,7 +7,7 @@
 
 class ActionPoint: public TrackPoint {
 public:
-  ActionPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const std::string identifier = ACTIONPOINT_DEFAULT_IDENFIFIER);
+  ActionPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const std::string identifier = ACTIONPOINT_DEFAULT_IDENFIFIER);
   std::string getIdentifier();
   ActionPointSettings getActionPointSettings();
   void updateActionPointSettings(ActionPointSettings settings);

+ 1 - 1
trackpoint-app/include/EMFTrackPoint.hpp

@@ -7,7 +7,7 @@
 
 class EMFTrackPoint: public TrackPoint {
 public:
-  EMFTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const double width = EMFTRACK_DEFAULT_WIDTH, const double height = EMFTRACK_DEFAULT_HEIGHT, const double depth = EMFTRACK_DEFAULT_DEPTH);
+  EMFTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const double width = EMFTRACK_DEFAULT_WIDTH, const double height = EMFTRACK_DEFAULT_HEIGHT, const double depth = EMFTRACK_DEFAULT_DEPTH);
   double getWidth();
   double getHeight();
   double getDepth();

+ 4 - 0
trackpoint-app/include/EditWidget.hpp

@@ -36,6 +36,10 @@ private slots:
   void updateNormalModifier();
   void resetNormalModifier();
   void setNormalModifier(osg::Vec3 normalModifier);
+  void updateNormalRotation(bool reset = false);
+  void setNormalRotation(float normalRotation);
+  void updateCompensation(bool reset = false);
+  void setCompensation(bool compensation);
   void updateOptiTrackSettings(bool reset = false);
   void setOptiTrackSettings(double length, double radius);
   void updateEMFTrackSettings(bool reset = false);

+ 1 - 1
trackpoint-app/include/OptiTrackPoint.hpp

@@ -7,7 +7,7 @@
 
 class OptiTrackPoint: public TrackPoint {
 public:
-  OptiTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const double length = OPTITRACK_DEFAULT_LENGTH, const double radius = OPTITRACK_DEFAULT_RADIUS);
+  OptiTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const double length = OPTITRACK_DEFAULT_LENGTH, const double radius = OPTITRACK_DEFAULT_RADIUS);
   double getLength();
   double getRadius();
   OptiTrackSettings getOptiTrackSettings();

+ 2 - 2
trackpoint-app/include/PointShape.hpp

@@ -16,11 +16,11 @@
 class PointShape {
 public:
   static void loadSteamvrThread();
-  PointShape(const osg::ref_ptr<osg::Group> renderRoot, const ActiveTrackingSystem activeTrackingSystem, osg::Vec3f point, osg::Vec3f normal, osg::Vec3f normalModifier);
+  PointShape(const osg::ref_ptr<osg::Group> renderRoot, const ActiveTrackingSystem activeTrackingSystem, osg::Vec3f point, osg::Vec3f normal, osg::Vec3f normalModifier, float normalRotation);
   ~PointShape();
   void moveTo(osg::Vec3f position);
   void setNormalModifier(osg::Vec3f normalModifier);
-  void rotateToNormalVector(osg::Vec3f normal);
+  void rotateToNormalVector(osg::Vec3f normal, float normalRotation);
   void setVisibility(bool mode);
   void setColor(osg::Vec4 color);
   void setupOptiTrack(OptiTrackSettings optiTrackSettings);

+ 10 - 0
trackpoint-app/include/ProjectStore.hpp

@@ -54,6 +54,14 @@ public:
   void updateNormalModifier(osg::Vec3 modifier);
   // Return normal modifier
   osg::Vec3 getNormalModifier();
+  // Update normal rotation
+  void updateNormalRotation(float normalRotation);
+  // Return normal rotation
+  float getNormalRotation();
+  // Update compensation
+  void updateCompensation(bool compensation);
+  // Return compensation
+  bool getCompensation();
   // OPTITRACK
   // Get all OptiTrack points
   std::vector<OptiTrackPoint*> getOptiTrackPoints();
@@ -100,6 +108,8 @@ private:
   SteamVRTrackSettings _steamVrTrackSettings = SteamVRTrackSettings {STEAMVR_DEFAULT_LENGTH};
   ActionPointSettings _actionPointSettings = ActionPointSettings {ACTIONPOINT_DEFAULT_IDENFIFIER};
   osg::Vec3 _normalModifier = osg::Vec3(0.0f, 0.0f, 0.0f);
+  float _normalRotation = 0.0f;
+  bool _compensation = true;
   void load3mfLib();
   void reset();
   void render3MFMesh();

+ 1 - 1
trackpoint-app/include/SteamVRTrackPoint.hpp

@@ -7,7 +7,7 @@
 
 class SteamVRTrackPoint: public TrackPoint {
 public:
-  SteamVRTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const double length = STEAMVR_DEFAULT_LENGTH);
+  SteamVRTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const double length = STEAMVR_DEFAULT_LENGTH);
   double getLength();
   SteamVRTrackSettings getSteamVRTrackSettings();
   void updateSteamVRTrackSettings(SteamVRTrackSettings settings);

+ 7 - 1
trackpoint-app/include/TrackPoint.hpp

@@ -6,14 +6,18 @@
 
 class TrackPoint {
 public:
-  TrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier);
+  TrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation);
   osg::Vec3 getTranslation();
   osg::Vec3 getRotation();
   osg::Vec3 getNormal();
   osg::Vec3 getNormalModifier();
   osg::Vec3 getTrackPoint();
+  float getNormalRotation();
+  bool getCompensation();
   void updateNormalModifier(osg::Vec3 normalModifier);
   void updatePositions(osg::Vec3 origin);
+  void updateNormalRotation(float normalRotation);
+  void updateCompensation(bool compensation);
 
 protected:
   osg::ref_ptr<osg::MatrixTransform> _translationGroup;
@@ -23,4 +27,6 @@ protected:
   osg::Vec3 _origin;
   osg::Vec3 _normal;
   osg::Vec3 _normalModifier;
+  float _normalRotation;
+  bool _compensation;
 };

+ 1 - 1
trackpoint-app/src/ActionPoint.cpp

@@ -1,7 +1,7 @@
 // Include own headers
 #include "ActionPoint.hpp"
 
-ActionPoint::ActionPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const std::string identifier): TrackPoint(point, normal, normalModifier) {
+ActionPoint::ActionPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const std::string identifier): TrackPoint(point, normal, normalModifier, normalRotation, compensation) {
   _identifier = identifier;
 }
 

+ 1 - 1
trackpoint-app/src/EMFTrackPoint.cpp

@@ -1,7 +1,7 @@
 // Include own headers
 #include "EMFTrackPoint.hpp"
 
-EMFTrackPoint::EMFTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const double width, const double height, const double depth): TrackPoint(point, normal, normalModifier) {
+EMFTrackPoint::EMFTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const double width, const double height, const double depth): TrackPoint(point, normal, normalModifier, normalRotation, compensation) {
   _width = width;
   _height = height;
   _depth = depth;

+ 52 - 0
trackpoint-app/src/EditWidget.cpp

@@ -27,6 +27,8 @@ EditWidget::EditWidget(QWidget* parent): QWidget(parent), ui(new Ui::EditWidget)
   QObject::connect(ui->normalModX, &QDoubleSpinBox::valueChanged, this, &EditWidget::updateNormalModifier);
   QObject::connect(ui->normalModY, &QDoubleSpinBox::valueChanged, this, &EditWidget::updateNormalModifier);
   QObject::connect(ui->normalModZ, &QDoubleSpinBox::valueChanged, this, &EditWidget::updateNormalModifier);
+  QObject::connect(ui->rotateAroundNormal, &QDoubleSpinBox::valueChanged, this, [=](){ this->updateNormalRotation(false); });
+  QObject::connect(ui->compensation, &QCheckBox::stateChanged, this, [=](){ this->updateCompensation(false); });
   QObject::connect(ui->modifierReset, &QPushButton::clicked, this, &EditWidget::resetNormalModifier);
   // OptiTrack settings
   QObject::connect(ui->optiTrackLength, &QDoubleSpinBox::valueChanged, this, [=](){ this->updateOptiTrackSettings(false); });
@@ -50,6 +52,8 @@ EditWidget::EditWidget(QWidget* parent): QWidget(parent), ui(new Ui::EditWidget)
   if (!OpenScadRenderer::openScadAvailable()) {
     ui->exportGroup->setEnabled(false);
   }
+  ui->exportProgress->setVisible(false);
+  ui->exportLabel->setVisible(false);
 }
 
 EditWidget::~EditWidget() {
@@ -244,6 +248,54 @@ void EditWidget::setNormalModifier(osg::Vec3 normalModifier) {
   ui->normalModZ->setValue(normalModifier.z());
 }
 
+void EditWidget::updateNormalRotation(bool reset) {
+  float normalRotation;
+  if (reset) {
+    normalRotation = 0.0f;
+  } else {
+    normalRotation = ui->rotateAroundNormal->value();
+  }
+  if (selectedPoint < 0) {
+    MainWindow::getInstance()->getStore()->updateNormalRotation(normalRotation);
+    MainWindow::getInstance()->getOsgWidget()->getPicker()->updateRenderer();
+  } else {
+    ActiveTrackingSystem activeTrackingSystem = getSelectedTrackingSystem();
+    MainWindow::getInstance()->getStore()->getTrackPointById(selectedPoint, activeTrackingSystem)->updateNormalRotation(normalRotation);
+    MainWindow::getInstance()->getOsgWidget()->getPointRenderer()->render(activeTrackingSystem);
+    MainWindow::getInstance()->getStore()->projectModified();
+  }
+}
+
+void EditWidget::setNormalRotation(float normalRotation) {
+  ui->rotateAroundNormal->value();
+}
+
+void EditWidget::updateCompensation(bool reset) {
+  bool compensation;
+  if (reset) {
+    compensation = true;
+  } else {
+    compensation = ui->compensation->checkState() == Qt::Checked ? true : false;
+  }
+  if (selectedPoint < 0) {
+    MainWindow::getInstance()->getStore()->updateCompensation(compensation);
+    MainWindow::getInstance()->getOsgWidget()->getPicker()->updateRenderer();
+  } else {
+    ActiveTrackingSystem activeTrackingSystem = getSelectedTrackingSystem();
+    MainWindow::getInstance()->getStore()->getTrackPointById(selectedPoint, activeTrackingSystem)->updateCompensation(compensation);
+    MainWindow::getInstance()->getOsgWidget()->getPointRenderer()->render(activeTrackingSystem);
+    MainWindow::getInstance()->getStore()->projectModified();
+  }
+}
+
+void EditWidget::setCompensation(bool compensation) {
+  if (compensation) {
+    ui->compensation->setCheckState(Qt::Checked);
+  } else {
+    ui->compensation->setCheckState(Qt::Unchecked);
+  }
+}
+
 void EditWidget::updateOptiTrackSettings(bool reset) {
   OptiTrackSettings settings;
   if (reset) {

+ 2 - 2
trackpoint-app/src/OptiTrackPoint.cpp

@@ -1,14 +1,14 @@
 // Include own headers
 #include "OptiTrackPoint.hpp"
 
-OptiTrackPoint::OptiTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const double length, const double radius): TrackPoint(point, normal, normalModifier) {
+OptiTrackPoint::OptiTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const double length, const double radius): TrackPoint(point, normal, normalModifier, normalRotation, compensation) {
   _length = length;
   _radius = radius;
   updateShift();
 }
 
 double OptiTrackPoint::getLength() {
-  return _length;
+  return _length;// + MeshTools::compensationLength(_normal, _normalModifier, _radius);
 }
 
 double OptiTrackPoint::getRadius() {

+ 6 - 5
trackpoint-app/src/PickHandler.cpp

@@ -157,24 +157,24 @@ void PickHandler::updateRenderer() {
   switch(activeTrackingSystem) {
     case OptiTrack: {
       OptiTrackSettings settings = MainWindow::getInstance()->getStore()->getOptiTrackSettings();
-      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f));
+      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), 0.0f);
       _shape->setupOptiTrack(settings);
       break;
     }
     case EMFTrack: {
       EMFTrackSettings settings = MainWindow::getInstance()->getStore()->getEMFTrackSettings();
-      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f));
+      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), 0.0f);
       _shape->setupEMFTrack(settings);
       break;
     }
     case SteamVRTrack: {
       SteamVRTrackSettings settings = MainWindow::getInstance()->getStore()->getSteamVRTrackSettings();
-      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f));
+      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), 0.0f);
       _shape->setupSteamVRTrack(settings);
       break;
     }
     case ActionPoints: {
-      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f));
+      _shape = new PointShape(_selectionSwitch, activeTrackingSystem, osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 0.0f), 0.0f);
       _shape->setupActionPoints();
       break;
     }
@@ -196,11 +196,12 @@ void PickHandler::rotateToNormalVector(osg::Vec3f normal) {
   MainWindow::getInstance()->getEditWiget()->updateNormals(normal);
   if (_shape) {
     osg::Vec3 modifier = MainWindow::getInstance()->getStore()->getNormalModifier();
+    float normalRotation = MainWindow::getInstance()->getStore()->getNormalRotation();
     ActiveTrackingSystem activeTrackingSystem = MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem();
     if (activeTrackingSystem == EMFTrack) {
       normal = normal.operator*(-1.0f);
     }
-    _shape->rotateToNormalVector(normal);
+    _shape->rotateToNormalVector(normal, normalRotation);
     _shape->setNormalModifier(modifier);
   }
 }

+ 6 - 4
trackpoint-app/src/PointShape.cpp

@@ -10,7 +10,7 @@
 #include <osgUtil/MeshOptimizers>
 #include "lib3mf_implicit.hpp"
 
-PointShape::PointShape(const osg::ref_ptr<osg::Group> renderRoot, const ActiveTrackingSystem activeTrackingSystem, osg::Vec3f point, osg::Vec3f normal, osg::Vec3f normalModifier) {
+PointShape::PointShape(const osg::ref_ptr<osg::Group> renderRoot, const ActiveTrackingSystem activeTrackingSystem, osg::Vec3f point, osg::Vec3f normal, osg::Vec3f normalModifier, float normalRotation) {
   _renderRoot = renderRoot;
   _activeTrackingSystem = activeTrackingSystem;
 
@@ -32,7 +32,7 @@ PointShape::PointShape(const osg::ref_ptr<osg::Group> renderRoot, const ActiveTr
 
   moveTo(point);
   setNormalModifier(normalModifier);
-  rotateToNormalVector(normal);
+  rotateToNormalVector(normal, normalRotation);
 }
 
 PointShape::~PointShape() {
@@ -47,11 +47,13 @@ void PointShape::setNormalModifier(osg::Vec3f normalModifier) {
   _normalModifier = normalModifier;
 }
 
-void PointShape::rotateToNormalVector(osg::Vec3f normal) {
+void PointShape::rotateToNormalVector(osg::Vec3f normal, float normalRotation) {
   osg::Matrix modifierRotation = osg::Matrix::rotate(_normalModifier.x() * M_PI / 180, osg::Vec3(1.0f, 0.0f, 0.0f), _normalModifier.y() * M_PI / 180, osg::Vec3(0.0f, 1.0f, 0.0f), _normalModifier.z() * M_PI / 180, osg::Vec3(0.0f, 0.0f, 1.0f));
   normal = modifierRotation.preMult(normal);
   normal.normalize();
-  _selectionRotateGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal));
+  osg::Matrix matrix = osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal);
+  matrix = matrix.operator*(osg::Matrix::rotate(normalRotation * M_PI / 180, normal));
+  _selectionRotateGroup->setMatrix(matrix);
   if (_activeTrackingSystem == OptiTrack || _activeTrackingSystem == SteamVRTrack) {
     osg::Vec3f movementVector = normal.operator*(_optiTrackSteamVRLength / 2);
     _selectionMoveToEndGroup->setMatrix(osg::Matrix::translate(movementVector));

+ 34 - 9
trackpoint-app/src/ProjectStore.cpp

@@ -158,7 +158,8 @@ bool ProjectStore::exportProject(std::string path, ExportSettings settings) {
       osg::Vec3 trackNormal = point->getNormal();
       json pointData = {
         {"point", {trackPoint.x(), trackPoint.y(), trackPoint.z()}},
-        {"normal", {trackNormal.x(), trackNormal.y(), trackNormal.z()}}
+        {"normal", {trackNormal.x(), trackNormal.y(), trackNormal.z()}},
+        {"rotation", point->getNormalRotation()}
       };
       trackpointData.push_back(pointData);
     }
@@ -254,23 +255,23 @@ TrackPoint* ProjectStore::getTrackPointById(int id, ActiveTrackingSystem activeT
 void ProjectStore::addTrackPoint(osg::Vec3 point, osg::Vec3 normal, ActiveTrackingSystem activeTrackingSystem) {
   switch(activeTrackingSystem) {
     case OptiTrack: {
-      OptiTrackPoint* optiTrackPoint = new OptiTrackPoint(point, normal, _normalModifier, _optiTrackSettings.length, _optiTrackSettings.radius);
+      OptiTrackPoint* optiTrackPoint = new OptiTrackPoint(point, normal, _normalModifier, _normalRotation, _compensation, _optiTrackSettings.length, _optiTrackSettings.radius);
       _optiTrackPoints.push_back(optiTrackPoint);
       break;
     }
     case EMFTrack: {
       normal = normal.operator*(-1.0f);
-      EMFTrackPoint* emfTrackPoint = new EMFTrackPoint(point, normal, _normalModifier, _emfTrackSettings.width, _emfTrackSettings.height, _emfTrackSettings.depth);
+      EMFTrackPoint* emfTrackPoint = new EMFTrackPoint(point, normal, _normalModifier, _normalRotation, _compensation, _emfTrackSettings.width, _emfTrackSettings.height, _emfTrackSettings.depth);
       _emfTrackPoints.push_back(emfTrackPoint);
       break;
     }
     case SteamVRTrack: {
-      SteamVRTrackPoint* steamVrTrackPoint = new SteamVRTrackPoint(point, normal, _normalModifier, _steamVrTrackSettings.length);
+      SteamVRTrackPoint* steamVrTrackPoint = new SteamVRTrackPoint(point, normal, _normalModifier, _normalRotation, _compensation, _steamVrTrackSettings.length);
       _steamVrTrackPoints.push_back(steamVrTrackPoint);
       break;
     }
     case ActionPoints: {
-      ActionPoint* actionPoint = new ActionPoint(point, normal, _normalModifier, _actionPointSettings.identifier);
+      ActionPoint* actionPoint = new ActionPoint(point, normal, _normalModifier, _normalRotation, _compensation, _actionPointSettings.identifier);
       _actionPoints.push_back(actionPoint);
       break;
     }
@@ -327,6 +328,22 @@ osg::Vec3 ProjectStore::getNormalModifier() {
   return _normalModifier;
 }
 
+void ProjectStore::updateNormalRotation(float normalRotation) {
+  _normalRotation = normalRotation;
+}
+
+float ProjectStore::getNormalRotation() {
+  return _normalRotation;
+}
+
+void ProjectStore::updateCompensation(bool compensation) {
+  _compensation = compensation;
+}
+
+bool ProjectStore::getCompensation() {
+  return _compensation;
+}
+
 std::vector<OptiTrackPoint*> ProjectStore::getOptiTrackPoints() {
   return _optiTrackPoints;
 }
@@ -444,6 +461,8 @@ void ProjectStore::updateMetaData() {
       {"point", osgVecToStdVec(optiTrackPoint->getTranslation())},
       {"normal", osgVecToStdVec(optiTrackPoint->getNormal())},
       {"normalModifier", osgVecToStdVec(optiTrackPoint->getNormalModifier())},
+      {"normalRotation", optiTrackPoint->getNormalRotation()},
+      {"compensation", optiTrackPoint->getCompensation()},
       {"length", optiTrackPoint->getLength()},
       {"radius", optiTrackPoint->getRadius()}
     });
@@ -460,6 +479,8 @@ void ProjectStore::updateMetaData() {
       {"point", osgVecToStdVec(emfTrackPoint->getTranslation())},
       {"normal", osgVecToStdVec(emfTrackPoint->getNormal())},
       {"normalModifier", osgVecToStdVec(emfTrackPoint->getNormalModifier())},
+      {"normalRotation", emfTrackPoint->getNormalRotation()},
+      {"compensation", emfTrackPoint->getCompensation()},
       {"width", emfTrackPoint->getWidth()},
       {"height", emfTrackPoint->getHeight()},
       {"depth", emfTrackPoint->getDepth()}
@@ -477,6 +498,8 @@ void ProjectStore::updateMetaData() {
       {"point", osgVecToStdVec(steamVrTrackPoint->getTranslation())},
       {"normal", osgVecToStdVec(steamVrTrackPoint->getNormal())},
       {"normalModifier", osgVecToStdVec(steamVrTrackPoint->getNormalModifier())},
+      {"normalRotation", steamVrTrackPoint->getNormalRotation()},
+      {"compensation", steamVrTrackPoint->getCompensation()},
       {"length", steamVrTrackPoint->getLength()}
     });
   }
@@ -492,6 +515,8 @@ void ProjectStore::updateMetaData() {
       {"point", osgVecToStdVec(actionPoint->getTranslation())},
       {"normal", osgVecToStdVec(actionPoint->getNormal())},
       {"normalModifier", osgVecToStdVec(actionPoint->getNormalModifier())},
+      {"normalRotation", actionPoint->getNormalRotation()},
+      {"compensation", actionPoint->getCompensation()},
       {"identifier", actionPoint->getIdentifier()}
     });
   }
@@ -520,7 +545,7 @@ void ProjectStore::loadMetaData() {
       osg::Vec3f point = osg::Vec3f(pointData["point"][0], pointData["point"][1], pointData["point"][2]);
       osg::Vec3f normal = osg::Vec3f(pointData["normal"][0], pointData["normal"][1], pointData["normal"][2]);
       osg::Vec3f normalModifier = osg::Vec3f(pointData["normalModifier"][0], pointData["normalModifier"][1], pointData["normalModifier"][2]);
-      OptiTrackPoint* optiTrackPoint = new OptiTrackPoint(point, normal, normalModifier, static_cast<double>(pointData["length"]), static_cast<double>(pointData["radius"]));
+      OptiTrackPoint* optiTrackPoint = new OptiTrackPoint(point, normal, normalModifier, static_cast<float>(pointData["normalRotation"]), static_cast<bool>(pointData["compensation"]), static_cast<double>(pointData["length"]), static_cast<double>(pointData["radius"]));
       _optiTrackPoints.push_back(optiTrackPoint);
     }
   } catch (Lib3MF::ELib3MFException &e) {
@@ -535,7 +560,7 @@ void ProjectStore::loadMetaData() {
       osg::Vec3f point = osg::Vec3f(pointData["point"][0], pointData["point"][1], pointData["point"][2]);
       osg::Vec3f normal = osg::Vec3f(pointData["normal"][0], pointData["normal"][1], pointData["normal"][2]);
       osg::Vec3f normalModifier = osg::Vec3f(pointData["normalModifier"][0], pointData["normalModifier"][1], pointData["normalModifier"][2]);
-      EMFTrackPoint* emfTrackPoint = new EMFTrackPoint(point, normal, normalModifier, static_cast<double>(pointData["width"]), static_cast<double>(pointData["height"]), static_cast<double>(pointData["depth"]));
+      EMFTrackPoint* emfTrackPoint = new EMFTrackPoint(point, normal, normalModifier, static_cast<float>(pointData["normalRotation"]), static_cast<bool>(pointData["compensation"]), static_cast<double>(pointData["width"]), static_cast<double>(pointData["height"]), static_cast<double>(pointData["depth"]));
       _emfTrackPoints.push_back(emfTrackPoint);
     }
   } catch (Lib3MF::ELib3MFException &e) {
@@ -550,7 +575,7 @@ void ProjectStore::loadMetaData() {
       osg::Vec3f point = osg::Vec3f(pointData["point"][0], pointData["point"][1], pointData["point"][2]);
       osg::Vec3f normal = osg::Vec3f(pointData["normal"][0], pointData["normal"][1], pointData["normal"][2]);
       osg::Vec3f normalModifier = osg::Vec3f(pointData["normalModifier"][0], pointData["normalModifier"][1], pointData["normalModifier"][2]);
-      SteamVRTrackPoint* steamVrTrackPoint = new SteamVRTrackPoint(point, normal, normalModifier, static_cast<double>(pointData["length"]));
+      SteamVRTrackPoint* steamVrTrackPoint = new SteamVRTrackPoint(point, normal, normalModifier, static_cast<float>(pointData["normalRotation"]), static_cast<bool>(pointData["compensation"]), static_cast<double>(pointData["length"]));
       _steamVrTrackPoints.push_back(steamVrTrackPoint);
     }
   } catch (Lib3MF::ELib3MFException &e) {
@@ -565,7 +590,7 @@ void ProjectStore::loadMetaData() {
       osg::Vec3f point = osg::Vec3f(pointData["point"][0], pointData["point"][1], pointData["point"][2]);
       osg::Vec3f normal = osg::Vec3f(pointData["normal"][0], pointData["normal"][1], pointData["normal"][2]);
       osg::Vec3f normalModifier = osg::Vec3f(pointData["normalModifier"][0], pointData["normalModifier"][1], pointData["normalModifier"][2]);
-      ActionPoint* actionPoint = new ActionPoint(point, normal, normalModifier, pointData["identifier"]);
+      ActionPoint* actionPoint = new ActionPoint(point, normal, normalModifier, static_cast<float>(pointData["normalRotation"]), static_cast<bool>(pointData["compensation"]), pointData["identifier"]);
       _actionPoints.push_back(actionPoint);
     }
   } catch (Lib3MF::ELib3MFException &e) {

+ 1 - 1
trackpoint-app/src/SteamVRTrackPoint.cpp

@@ -1,7 +1,7 @@
 // Include own headers
 #include "SteamVRTrackPoint.hpp"
 
-SteamVRTrackPoint::SteamVRTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const double length): TrackPoint(point, normal, normalModifier) {
+SteamVRTrackPoint::SteamVRTrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation, const double length): TrackPoint(point, normal, normalModifier, normalRotation, compensation) {
   _length = length;
   updateShift();
 }

+ 23 - 1
trackpoint-app/src/TrackPoint.cpp

@@ -4,10 +4,12 @@
 // Include modules
 #include "OSGWidget.hpp"
 
-TrackPoint::TrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier) {
+TrackPoint::TrackPoint(const osg::Vec3 point, const osg::Vec3 normal, const osg::Vec3 normalModifier, const float normalRotation, const bool compensation) {
   _origin = point;
   _normal = normal;
   _normalModifier = normalModifier;
+  _normalRotation = normalRotation;
+  _compensation = compensation;
 }
 
 osg::Vec3 TrackPoint::getTranslation() {
@@ -22,6 +24,10 @@ osg::Vec3 TrackPoint::getRotation() {
   // From https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
   osg::Quat quat = osg::Quat(0.0f, 0.0f, 0.0f, 0.0f);
   quat.makeRotate(start, finalNormal);
+  osg::Matrix matrix;
+  quat.get(matrix);
+  matrix = matrix.operator*(osg::Matrix::rotate(_normalRotation * M_PI / 180, finalNormal));
+  quat.set(matrix);
 
   float sinr_cosp = 2 * (quat.w() * quat.x() + quat.y() * quat.z());
   float cosr_cosp = 1 - 2 * (quat.x() * quat.x() + quat.y() * quat.y());
@@ -54,6 +60,14 @@ osg::Vec3 TrackPoint::getTrackPoint() {
   return _trackOrigin;
 }
 
+float TrackPoint::getNormalRotation() {
+  return _normalRotation;
+}
+
+bool TrackPoint::getCompensation() {
+  return _compensation;
+}
+
 void TrackPoint::updateNormalModifier(osg::Vec3 normalModifier) {
   _normalModifier = normalModifier;
 }
@@ -61,3 +75,11 @@ void TrackPoint::updateNormalModifier(osg::Vec3 normalModifier) {
 void TrackPoint::updatePositions(osg::Vec3 origin) {
   _origin = origin;
 }
+
+void TrackPoint::updateNormalRotation(float normalRotation) {
+  _normalRotation = normalRotation;
+}
+
+void TrackPoint::updateCompensation(bool compensation) {
+  _compensation = compensation;
+}

+ 2 - 2
trackpoint-app/src/TrackPointRenderer.cpp

@@ -76,7 +76,7 @@ void TrackPointRenderer::clear() {
 }
 
 PointShape* TrackPointRenderer::addPointShape(TrackPoint* point, ActiveTrackingSystem activeTrackingSystem) {
-  PointShape* newShape = new PointShape(_renderRoot, activeTrackingSystem, point->getTranslation(), point->getNormal(), point->getNormalModifier());
+  PointShape* newShape = new PointShape(_renderRoot, activeTrackingSystem, point->getTranslation(), point->getNormal(), point->getNormalModifier(), point->getNormalRotation());
   return newShape;
 }
 
@@ -86,6 +86,6 @@ void TrackPointRenderer::commonSetupPointShape(PointShape* shape, TrackPoint* po
   } else {
     shape->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 0.2f));
   }
-  shape->rotateToNormalVector(point->getNormal());
+  shape->rotateToNormalVector(point->getNormal(), point->getNormalRotation());
   _shapes.push_back(shape);
 }