aboutsummaryrefslogtreecommitdiff
path: root/extension/src/MapMesh.cpp
diff options
context:
space:
mode:
author Hop311 <hop3114@gmail.com>2023-03-30 23:50:50 +0200
committer Spartan322 <Megacake1234@gmail.com>2023-04-14 17:16:02 +0200
commitc0d76b78d3762e6eec3ed1c62618be84c5b7559b (patch)
treeacfcbeedd5a47136acdf883e791a297200b7d1b8 /extension/src/MapMesh.cpp
parent1f04a7827ae377372cb491ff0257a47d0d4c2967 (diff)
Add terrain map
With Directional movement using WASD With Directional movement using arrow keys With Click-Drag movement using middle mouse button With Province identifiers With Province shape loading With Province rendering With Province selection With Province overview panel With Color lookup texture
Diffstat (limited to 'extension/src/MapMesh.cpp')
-rw-r--r--extension/src/MapMesh.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/extension/src/MapMesh.cpp b/extension/src/MapMesh.cpp
new file mode 100644
index 0000000..f0fc819
--- /dev/null
+++ b/extension/src/MapMesh.cpp
@@ -0,0 +1,151 @@
+#include "MapMesh.hpp"
+
+#include <godot_cpp/templates/vector.hpp>
+
+using namespace godot;
+using namespace OpenVic2;
+
+void MapMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_aspect_ratio", "ratio"), &MapMesh::set_aspect_ratio);
+ ClassDB::bind_method(D_METHOD("get_aspect_ratio"), &MapMesh::get_aspect_ratio);
+
+ ClassDB::bind_method(D_METHOD("set_repeat_proportion", "proportion"), &MapMesh::set_repeat_proportion);
+ ClassDB::bind_method(D_METHOD("get_repeat_proportion"), &MapMesh::get_repeat_proportion);
+
+ ClassDB::bind_method(D_METHOD("set_subdivide_width", "divisions"), &MapMesh::set_subdivide_width);
+ ClassDB::bind_method(D_METHOD("get_subdivide_width"), &MapMesh::get_subdivide_width);
+
+ ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &MapMesh::set_subdivide_depth);
+ ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &MapMesh::get_subdivide_depth);
+
+ ClassDB::bind_method(D_METHOD("get_core_aabb"), &MapMesh::get_core_aabb);
+ ClassDB::bind_method(D_METHOD("is_valid_uv_coord"), &MapMesh::is_valid_uv_coord);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "aspect_ratio", PROPERTY_HINT_NONE, "suffix:m"), "set_aspect_ratio", "get_aspect_ratio");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "repeat_proportion", PROPERTY_HINT_NONE, "suffix:m"), "set_repeat_proportion", "get_repeat_proportion");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth");
+}
+
+void MapMesh::_request_update() {
+ // Hack to trigger _update_lightmap_size and _request_update in PrimitiveMesh
+ set_add_uv2(get_add_uv2());
+}
+
+void MapMesh::set_aspect_ratio(const float ratio) {
+ aspect_ratio = ratio;
+ _request_update();
+}
+
+float MapMesh::get_aspect_ratio() const {
+ return aspect_ratio;
+}
+
+void MapMesh::set_repeat_proportion(const float proportion) {
+ repeat_proportion = proportion;
+ _request_update();
+}
+
+float MapMesh::get_repeat_proportion() const {
+ return repeat_proportion;
+}
+
+void MapMesh::set_subdivide_width(const int divisions) {
+ subdivide_w = divisions > 0 ? divisions : 0;
+ _request_update();
+}
+
+int MapMesh::get_subdivide_width() const {
+ return subdivide_w;
+}
+
+void MapMesh::set_subdivide_depth(const int divisions) {
+ subdivide_d = divisions > 0 ? divisions : 0;
+ _request_update();
+}
+
+int MapMesh::get_subdivide_depth() const {
+ return subdivide_d;
+}
+
+AABB MapMesh::get_core_aabb() const {
+ const Vector3 size{ aspect_ratio, 0.0f, 1.0f };
+ return AABB{ size * -0.5f, size };
+}
+
+bool MapMesh::is_valid_uv_coord(godot::Vector2 const& uv) const {
+ return 0.0f <= uv.y && uv.y <= 1.0f;
+}
+
+Array MapMesh::_create_mesh_array() const {
+ Array arr;
+ arr.resize(Mesh::ARRAY_MAX);
+
+ const int vertex_count = (subdivide_w + 2) * (subdivide_d + 2);
+ const int indice_count = (subdivide_w + 1) * (subdivide_d + 1) * 6;
+
+ PackedVector3Array points;
+ PackedVector3Array normals;
+ PackedFloat32Array tangents;
+ PackedVector2Array uvs;
+ PackedInt32Array indices;
+
+ points.resize(vertex_count);
+ normals.resize(vertex_count);
+ tangents.resize(vertex_count * 4);
+ uvs.resize(vertex_count);
+ indices.resize(indice_count);
+
+ static const Vector3 normal{ 0.0f, 1.0f, 0.0f };
+ const Size2 uv_size{ 1.0f + 2.0f * repeat_proportion, 1.0f };
+ const Size2 size{ aspect_ratio * uv_size.x, uv_size.y }, start_pos = size * -0.5f;
+
+ int point_index = 0, thisrow = 0, prevrow = 0, indice_index = 0;
+ Vector2 subdivide_step{ 1.0f / (subdivide_w + 1.0f) , 1.0f / (subdivide_d + 1.0f) };
+ Vector3 point{ 0.0f, 0.0f, start_pos.y };
+ Vector2 point_step = subdivide_step * size;
+ Vector2 uv{}, uv_step = subdivide_step * uv_size;
+
+ for (int j = 0; j <= subdivide_d + 1; ++j) {
+ point.x = start_pos.x;
+ uv.x = -repeat_proportion;
+
+ for (int i = 0; i <= subdivide_w + 1; ++i) {
+
+ points[point_index] = point;
+ normals[point_index] = normal;
+ tangents[point_index * 4 + 0] = 1.0f;
+ tangents[point_index * 4 + 1] = 0.0f;
+ tangents[point_index * 4 + 2] = 0.0f;
+ tangents[point_index * 4 + 3] = 1.0f;
+ uvs[point_index] = uv;
+ point_index++;
+
+ if (i > 0 && j > 0) {
+ indices[indice_index + 0] = prevrow + i - 1;
+ indices[indice_index + 1] = prevrow + i;
+ indices[indice_index + 2] = thisrow + i - 1;
+ indices[indice_index + 3] = prevrow + i;
+ indices[indice_index + 4] = thisrow + i;
+ indices[indice_index + 5] = thisrow + i - 1;
+ indice_index += 6;
+ }
+
+ point.x += point_step.x;
+ uv.x += uv_step.x;
+ }
+
+ point.z += point_step.y;
+ uv.y += uv_step.y;
+ prevrow = thisrow;
+ thisrow = point_index;
+ }
+
+ arr[Mesh::ARRAY_VERTEX] = points;
+ arr[Mesh::ARRAY_NORMAL] = normals;
+ arr[Mesh::ARRAY_TANGENT] = tangents;
+ arr[Mesh::ARRAY_TEX_UV] = uvs;
+ arr[Mesh::ARRAY_INDEX] = indices;
+
+ return arr;
+}