visual_catalog.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "visual_catalog.h"
  2. #include "../core/component.h"
  3. #include <QFile>
  4. #include <QJsonArray>
  5. #include <QJsonDocument>
  6. #include <QJsonObject>
  7. namespace Game::Visuals {
  8. VisualDef::MeshKind meshKindFromString(const QString &s) {
  9. const QString t = s.trimmed().toLower();
  10. if (t == "quad")
  11. return VisualDef::MeshKind::Quad;
  12. if (t == "plane")
  13. return VisualDef::MeshKind::Plane;
  14. if (t == "cube")
  15. return VisualDef::MeshKind::Cube;
  16. if (t == "capsule")
  17. return VisualDef::MeshKind::Capsule;
  18. if (t == "ring")
  19. return VisualDef::MeshKind::Ring;
  20. return VisualDef::MeshKind::None;
  21. }
  22. static Engine::Core::RenderableComponent::MeshKind
  23. toRenderableMesh(VisualDef::MeshKind k) {
  24. using RM = Engine::Core::RenderableComponent::MeshKind;
  25. switch (k) {
  26. case VisualDef::MeshKind::Quad:
  27. return RM::Quad;
  28. case VisualDef::MeshKind::Plane:
  29. return RM::Plane;
  30. case VisualDef::MeshKind::Cube:
  31. return RM::Cube;
  32. case VisualDef::MeshKind::Capsule:
  33. return RM::Capsule;
  34. case VisualDef::MeshKind::Ring:
  35. return RM::Ring;
  36. default:
  37. return RM::None;
  38. }
  39. }
  40. bool VisualCatalog::loadFromJsonFile(const QString &path, QString *outError) {
  41. QFile f(path);
  42. if (!f.open(QIODevice::ReadOnly)) {
  43. if (outError)
  44. *outError = QString("Failed to open visuals file: %1").arg(path);
  45. return false;
  46. }
  47. const QByteArray data = f.readAll();
  48. f.close();
  49. QJsonParseError perr{};
  50. const QJsonDocument doc = QJsonDocument::fromJson(data, &perr);
  51. if (doc.isNull()) {
  52. if (outError)
  53. *outError = QString("JSON parse error at %1: %2")
  54. .arg(perr.offset)
  55. .arg(perr.errorString());
  56. return false;
  57. }
  58. QJsonObject root = doc.object();
  59. QJsonObject units = root.value("units").toObject();
  60. for (auto it = units.begin(); it != units.end(); ++it) {
  61. VisualDef def;
  62. QJsonObject o = it.value().toObject();
  63. def.mesh = meshKindFromString(o.value("mesh").toString("cube"));
  64. QJsonArray col = o.value("color").toArray();
  65. if (col.size() == 3)
  66. def.color =
  67. QVector3D(float(col[0].toDouble(1.0)), float(col[1].toDouble(1.0)),
  68. float(col[2].toDouble(1.0)));
  69. def.texture = o.value("texture").toString("");
  70. m_units.emplace(it.key().toStdString(), def);
  71. }
  72. return true;
  73. }
  74. bool VisualCatalog::lookup(const std::string &unitType, VisualDef &out) const {
  75. auto it = m_units.find(unitType);
  76. if (it == m_units.end())
  77. return false;
  78. out = it->second;
  79. return true;
  80. }
  81. void applyToRenderable(const VisualDef &def,
  82. Engine::Core::RenderableComponent &r) {
  83. r.mesh = toRenderableMesh(def.mesh);
  84. r.color[0] = def.color.x();
  85. r.color[1] = def.color.y();
  86. r.color[2] = def.color.z();
  87. if (!def.texture.isEmpty()) {
  88. r.texturePath = def.texture.toStdString();
  89. }
  90. }
  91. } // namespace Game::Visuals