forked from Zylann/godot_heightmap_module
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmesherbak.cpp
104 lines (84 loc) · 3.04 KB
/
mesherbak.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "height_map_mesher.h"
// TODO Is this already in engine?
template <typename T>
void copy_to(PoolVector<T> &to, Vector<T> &from) {
to.resize(from.size());
typename PoolVector<T>::Write w = to.write();
for (int i = 0; i < from.size(); ++i) {
w[i] = from[i];
}
from.clear();
}
Ref<Mesh> HeightMapMesher::make_chunk(Params params, const HeightMapData &data) {
_output_vertices.clear();
_output_normals.clear();
_output_colors.clear();
_output_indices.clear();
if (!params.smooth) {
; // TODO Faceted version
//return make_chunk_faceted(params, data)
}
int stride = 1 << params.lod;
Point2i max = params.origin + params.size * stride;
Point2i terrain_size = data.size();
if (max.y >= terrain_size.y)
max.y = terrain_size.y;
if (max.x >= terrain_size.x)
max.x = terrain_size.x;
// Vector2 uv_scale = Vector2(
// 1.0 / static_cast<real_t>(terrain_size_x),
// 1.0 / static_cast<real_t>(terrain_size_y));
// Note: UVs aren't needed because they can be deduced from world positions
// Make central part
Point2i pos;
for (pos.y = params.origin.y; pos.y <= max.y; pos.y += stride) {
for (pos.x = params.origin.x; pos.x <= max.x; pos.x += stride) {
_output_vertices.push_back(Vector3(
pos.x - params.origin.x,
data.heights.get(pos),
pos.y - params.origin.y));
_output_colors.push_back(data.colors.get(pos));
_output_normals.push_back(data.normals.get(pos));
}
}
if (_output_vertices.size() == 0) {
print_line("No vertices generated!");
return Ref<Mesh>();
}
int i = 0;
for (pos.y = 0; pos.y < params.size.y; ++pos.y) {
for (pos.x = 0; pos.x < params.size.x; ++pos.x) {
_output_indices.push_back(i);
_output_indices.push_back(i + params.size.x + 2);
_output_indices.push_back(i + params.size.x + 1);
_output_indices.push_back(i);
_output_indices.push_back(i + 1);
_output_indices.push_back(i + params.size.x + 2);
++i;
}
++i;
}
PoolVector<Vector3> pool_vertices;
PoolVector<Vector3> pool_normals;
PoolVector<Color> pool_colors;
PoolVector<int> pool_indices;
copy_to(pool_vertices, _output_vertices);
copy_to(pool_normals, _output_normals);
copy_to(pool_colors, _output_colors);
copy_to(pool_indices, _output_indices);
Array arrays;
arrays.resize(Mesh::ARRAY_MAX);
arrays[Mesh::ARRAY_VERTEX] = pool_vertices;
arrays[Mesh::ARRAY_NORMAL] = pool_normals;
arrays[Mesh::ARRAY_COLOR] = pool_colors;
arrays[Mesh::ARRAY_INDEX] = pool_indices;
//Ref<ArrayMesh> mesh_ref(memnew(ArrayMesh));
Ref<ArrayMesh> mesh_ref;
mesh_ref->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays);
_output_vertices.clear();
_output_normals.clear();
_output_colors.clear();
_output_indices.clear();
arrays.clear();
return mesh_ref;
}