visual_catalog.cpp 3.2 KB

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