From 381bd46620ba23ea4c6c8559426c06a5cf5828ad Mon Sep 17 00:00:00 2001
From: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date: Mon, 4 Jul 2022 01:33:38 -0500
Subject: [PATCH] app/lib: implement correct vector3 and gui editors

---
 app/CMakeLists.txt  |  2 ++
 app/panels/mxob.cpp | 36 ++++++++++++++++++++++++++++++++++
 app/panels/mxob.h   |  5 +++++
 app/vector3edit.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++
 app/vector3edit.h   | 25 ++++++++++++++++++++++++
 lib/sitypes.cpp     | 28 ++++++++++-----------------
 lib/sitypes.h       | 21 +++-----------------
 lib/types.h         | 31 ++++++++++++++++++++++--------
 8 files changed, 151 insertions(+), 44 deletions(-)
 create mode 100644 app/vector3edit.cpp
 create mode 100644 app/vector3edit.h

diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index ad47ba9..3059880 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -26,6 +26,8 @@ set(PROJECT_SOURCES
   mainwindow.h
   objectmodel.cpp
   objectmodel.h
+  vector3edit.cpp
+  vector3edit.h
 )
 
 if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
diff --git a/app/panels/mxob.cpp b/app/panels/mxob.cpp
index ba96197..ce0844d 100644
--- a/app/panels/mxob.cpp
+++ b/app/panels/mxob.cpp
@@ -1,6 +1,7 @@
 #include "mxob.h"
 
 #include <sitypes.h>
+#include <QGroupBox>
 #include <QLabel>
 
 using namespace si;
@@ -48,6 +49,33 @@ MxObPanel::MxObPanel(QWidget *parent) :
   presenter_edit_ = new QLineEdit();
   layout()->addWidget(presenter_edit_, row, 1);
 
+  row++;
+
+  auto pos_grp = new QGroupBox(tr("Position"));
+  auto pos_lyt = new QVBoxLayout(pos_grp);
+  pos_lyt->setMargin(0);
+  pos_edit_ = new Vector3Edit();
+  pos_lyt->addWidget(pos_edit_);
+  layout()->addWidget(pos_grp, row, 0, 1, 2);
+
+  row++;
+
+  auto dir_grp = new QGroupBox(tr("Direction"));
+  auto dir_lyt = new QVBoxLayout(dir_grp);
+  dir_lyt->setMargin(0);
+  dir_edit_ = new Vector3Edit();
+  dir_lyt->addWidget(dir_edit_);
+  layout()->addWidget(dir_grp, row, 0, 1, 2);
+
+  row++;
+
+  auto up_grp = new QGroupBox(tr("Up"));
+  auto up_lyt = new QVBoxLayout(up_grp);
+  up_lyt->setMargin(0);
+  up_edit_ = new Vector3Edit();
+  up_lyt->addWidget(up_edit_);
+  layout()->addWidget(up_grp, row, 0, 1, 2);
+
   FinishLayout();
 }
 
@@ -58,9 +86,17 @@ void MxObPanel::OnOpeningData(si::Chunk *chunk)
   filename_edit_->setText(QString(chunk->data("FileName")));
   presenter_edit_->setText(QString(chunk->data("Presenter")));
   obj_id_edit_->setValue(chunk->data("ID"));
+
+  pos_edit_->SetValue(chunk->data("Position"));
+  dir_edit_->SetValue(chunk->data("Direction"));
+  up_edit_->SetValue(chunk->data("Up"));
 }
 
 void MxObPanel::OnClosingData(si::Chunk *chunk)
 {
   chunk->data("Type") = type_combo_->currentIndex();
+
+  chunk->data("Position") = pos_edit_->GetValue();
+  chunk->data("Direction") = dir_edit_->GetValue();
+  chunk->data("Up") = up_edit_->GetValue();
 }
diff --git a/app/panels/mxob.h b/app/panels/mxob.h
index c2dc6fc..214904e 100644
--- a/app/panels/mxob.h
+++ b/app/panels/mxob.h
@@ -6,6 +6,7 @@
 #include <QSpinBox>
 
 #include "panel.h"
+#include "vector3edit.h"
 
 class MxObPanel : public Panel
 {
@@ -24,6 +25,10 @@ private:
   QLineEdit *filename_edit_;
   QSpinBox *obj_id_edit_;
 
+  Vector3Edit *pos_edit_;
+  Vector3Edit *dir_edit_;
+  Vector3Edit *up_edit_;
+
 };
 
 #endif // MXOBPANEL_H
diff --git a/app/vector3edit.cpp b/app/vector3edit.cpp
new file mode 100644
index 0000000..c049bb3
--- /dev/null
+++ b/app/vector3edit.cpp
@@ -0,0 +1,47 @@
+#include "vector3edit.h"
+
+#include <QHBoxLayout>
+#include <QLabel>
+
+Vector3Edit::Vector3Edit(QWidget *parent) :
+  QWidget{parent}
+{
+  auto layout = new QHBoxLayout(this);
+
+  layout->addWidget(new QLabel("X"));
+
+  x_edit_ = new QDoubleSpinBox();
+  x_edit_->setMinimum(DBL_MIN);
+  x_edit_->setMaximum(DBL_MAX);
+  layout->addWidget(x_edit_);
+
+  layout->addStretch();
+
+  layout->addWidget(new QLabel("Y"));
+
+  y_edit_ = new QDoubleSpinBox();
+  y_edit_->setMinimum(DBL_MIN);
+  y_edit_->setMaximum(DBL_MAX);
+  layout->addWidget(y_edit_);
+
+  layout->addStretch();
+
+  layout->addWidget(new QLabel("Z"));
+
+  z_edit_ = new QDoubleSpinBox();
+  z_edit_->setMinimum(DBL_MIN);
+  z_edit_->setMaximum(DBL_MAX);
+  layout->addWidget(z_edit_);
+}
+
+si::Vector3 Vector3Edit::GetValue() const
+{
+  return si::Vector3(x_edit_->value(), y_edit_->value(), z_edit_->value());
+}
+
+void Vector3Edit::SetValue(const si::Vector3 &xyz)
+{
+  x_edit_->setValue(xyz.x);
+  y_edit_->setValue(xyz.y);
+  z_edit_->setValue(xyz.z);
+}
diff --git a/app/vector3edit.h b/app/vector3edit.h
new file mode 100644
index 0000000..8d749f6
--- /dev/null
+++ b/app/vector3edit.h
@@ -0,0 +1,25 @@
+#ifndef VECTOR3EDIT_H
+#define VECTOR3EDIT_H
+
+#include <QDoubleSpinBox>
+#include <QWidget>
+
+#include <types.h>
+
+class Vector3Edit : public QWidget
+{
+  Q_OBJECT
+public:
+  explicit Vector3Edit(QWidget *parent = nullptr);
+
+  si::Vector3 GetValue() const;
+  void SetValue(const si::Vector3 &xyz);
+
+private:
+  QDoubleSpinBox *x_edit_;
+  QDoubleSpinBox *y_edit_;
+  QDoubleSpinBox *z_edit_;
+
+};
+
+#endif // VECTOR3EDIT_H
diff --git a/lib/sitypes.cpp b/lib/sitypes.cpp
index 76c4a92..215cced 100644
--- a/lib/sitypes.cpp
+++ b/lib/sitypes.cpp
@@ -18,6 +18,13 @@ Data ReadU16(std::ifstream &is)
   return u;
 }
 
+Data ReadVector3(std::ifstream &is)
+{
+  Vector3 u;
+  is.read((char *) &u, sizeof(u));
+  return u;
+}
+
 Data ReadString(std::ifstream &is)
 {
   bytearray d;
@@ -132,24 +139,9 @@ void MxOb::Read(std::ifstream &is, DataMap &data, u32 version, u32 size)
   data["Unknown4"] = ReadU32(is);
   data["Unknown5"] = ReadU32(is);
   data["Unknown6"] = ReadU32(is);
-  data["Unknown7"] = ReadU32(is);
-  data["Unknown8"] = ReadU32(is);
-  data["Unknown9"] = ReadU32(is);
-  data["Unknown10"] = ReadU32(is);
-  data["Unknown11"] = ReadU32(is);
-  data["Unknown12"] = ReadU32(is);
-  data["Unknown13"] = ReadU32(is);
-  data["Unknown14"] = ReadU32(is);
-  data["Unknown15"] = ReadU32(is);
-  data["Unknown16"] = ReadU32(is);
-  data["Unknown17"] = ReadU32(is);
-  data["Unknown18"] = ReadU32(is);
-  data["Unknown19"] = ReadU32(is);
-  data["Unknown20"] = ReadU32(is);
-  data["Unknown21"] = ReadU32(is);
-  data["Unknown22"] = ReadU32(is);
-  data["Unknown23"] = ReadU32(is);
-  data["Unknown24"] = ReadU32(is);
+  data["Position"] = ReadVector3(is);
+  data["Direction"] = ReadVector3(is);
+  data["Up"] = ReadVector3(is);
 
   Data extra_sz = ReadU16(is);
   data["ExtraLength"] = extra_sz;
diff --git a/lib/sitypes.h b/lib/sitypes.h
index d1fdd4e..31060b4 100644
--- a/lib/sitypes.h
+++ b/lib/sitypes.h
@@ -120,24 +120,9 @@ public:
  * Unknown4    | 4        | u32              |
  * Unknown5    | 4        | u32              |
  * Unknown6    | 4        | u32              |
- * Unknown7    | 4        | u32              |
- * Unknown8    | 4        | u32              |
- * Unknown9    | 4        | u32              |
- * Unknown10   | 4        | u32              |
- * Unknown11   | 4        | u32              |
- * Unknown12   | 4        | u32              |
- * Unknown13   | 4        | u32              |
- * Unknown14   | 4        | u32              |
- * Unknown15   | 4        | u32              |
- * Unknown16   | 4        | u32              |
- * Unknown17   | 4        | u32              |
- * Unknown18   | 4        | u32              |
- * Unknown19   | 4        | u32              |
- * Unknown20   | 4        | u32              |
- * Unknown21   | 4        | u32              |
- * Unknown22   | 4        | u32              |
- * Unknown23   | 4        | u32              |
- * Unknown24   | 4        | u32              |
+ * Position    | 24       | Vector3          | Position
+ * Direction   | 24       | Vector3          | Position
+ * Up          | 24       | Vector3          | Position
  * ExtraLength | 2        | u16              |
  * ExtraData   | ExtraLength | bytearray     |
  * FileName    | Variable | string           | Original filename of the file represented by this object.
diff --git a/lib/types.h b/lib/types.h
index f676d14..43325cc 100644
--- a/lib/types.h
+++ b/lib/types.h
@@ -29,6 +29,22 @@ public:
 
 };
 
+class Vector3
+{
+public:
+  Vector3(){}
+  Vector3(f64 ix, f64 iy, f64 iz)
+  {
+    x = ix;
+    y = iy;
+    z = iz;
+  }
+
+  f64 x;
+  f64 y;
+  f64 z;
+};
+
 class Data
 {
 public:
@@ -39,6 +55,7 @@ public:
   }
 
   inline Data(const u32 &u) { set(u); }
+  inline Data(const Vector3 &u) { set(u); }
   inline Data(const bytearray &u) { set(u); }
   inline Data(const std::string &u)
   {
@@ -56,10 +73,16 @@ public:
     return data();
   }
 
+  inline operator Vector3() const
+  {
+    return toVector3();
+  }
+
   inline u16 toU16() const { return *data_.cast<si::u16>(); }
   inline s16 toS16() const { return *data_.cast<si::s16>(); }
   inline u32 toU32() const { return *data_.cast<si::u32>(); }
   inline s32 toS32() const { return *data_.cast<si::s32>(); }
+  inline Vector3 toVector3() const { return *data_.cast<si::Vector3>(); }
   inline const char *data() const { return data_.data(); };
   inline char *data() { return data_.data(); };
   inline const char *c_str() const { return this->data(); };
@@ -100,14 +123,6 @@ private:
 
 };
 
-class Vector3
-{
-public:
-  f32 x;
-  f32 y;
-  f32 z;
-};
-
 using DataMap = std::map<std::string, Data>;
 
 }