feat: started work on terrain editor tools
This commit is contained in:
parent
a61b52806a
commit
ac139f01b6
11 changed files with 423 additions and 0 deletions
69
modules/terrain/terrain_chunk.cpp
Normal file
69
modules/terrain/terrain_chunk.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#include "terrain_chunk.h"
|
||||
#include "core/variant/variant.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "terrain/terrain.h"
|
||||
|
||||
void TerrainChunkMesh::_bind_methods() {}
|
||||
|
||||
void TerrainChunkMesh::generate_vertices() {
|
||||
ERR_FAIL_COND_EDMSG(this->terrain == nullptr, "TerrainChunkMesh::generate_vertices: no terrain assigned");
|
||||
ERR_FAIL_COND_EDMSG(this->size <= 0.f, "TerrainChunkMesh::generate_vertices: size <= 0");
|
||||
ERR_FAIL_COND_EDMSG(points_per_side() <= 0, "TerrainChunkMesh::generate_vertices: points per side <= 0");
|
||||
float const half_extent{ (float)this->size / 2.f };
|
||||
float const point_distance{ (float)this->size / ((float)points_per_side() - 1) };
|
||||
Vector3 origin{ this->get_global_position() - Vector3{ half_extent, 0, half_extent } };
|
||||
for (size_t x{ 0 }; x < points_per_side(); ++x) {
|
||||
for (size_t y{ 0 }; y < points_per_side(); ++y) {
|
||||
Vector2 const coordinate{ origin.x + point_distance * x, origin.z + point_distance * y };
|
||||
this->surface->set_uv({ (float)x / (float)points_per_side(), (float)y / (float)points_per_side() });
|
||||
this->surface->add_vertex({ coordinate.x - get_global_position().x, this->terrain->height_at(coordinate), coordinate.y - get_global_position().z });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainChunkMesh::generate_faces() {
|
||||
LocalVector<SurfaceTool::Vertex> &verts{ this->surface->get_vertex_array() };
|
||||
ERR_FAIL_COND_EDMSG(verts.size() == 0, "TerrainChunkMesh::generate_faces: no vertices in surface, call generate_vertices first");
|
||||
size_t const faces_per_side{ points_per_side() - 1 };
|
||||
for (size_t x{ 0 }; x < faces_per_side; ++x) {
|
||||
for (size_t y{ 0 }; y < faces_per_side; ++y) {
|
||||
size_t const tl{ x + y * points_per_side() };
|
||||
float tl_br{ verts[tl].vertex.distance_to(verts[tl + points_per_side() + 1].vertex) };
|
||||
float tr_bl{ verts[tl + 1].vertex.distance_to(verts[tl + points_per_side()].vertex) };
|
||||
if (tl_br < tr_bl) {
|
||||
surface->add_index(tl);
|
||||
surface->add_index(tl + points_per_side() + 1);
|
||||
surface->add_index(tl + 1);
|
||||
|
||||
surface->add_index(tl);
|
||||
surface->add_index(tl + points_per_side());
|
||||
surface->add_index(tl + points_per_side() + 1);
|
||||
} else {
|
||||
surface->add_index(tl + points_per_side());
|
||||
surface->add_index(tl + points_per_side() + 1);
|
||||
surface->add_index(tl + 1);
|
||||
|
||||
surface->add_index(tl + 1);
|
||||
surface->add_index(tl);
|
||||
surface->add_index(tl + points_per_side());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainChunkMesh::update_mesh() {
|
||||
ERR_FAIL_COND_EDMSG(this->size <= 0.f, "TerrainChunkMesh::generate: size <= 0");
|
||||
ERR_FAIL_COND_EDMSG(points_per_side() <= 0, "TerrainChunkMesh::generate: points per side <= 0");
|
||||
this->set_mesh(memnew(ArrayMesh));
|
||||
this->surface->clear();
|
||||
this->surface->begin(Mesh::PRIMITIVE_TRIANGLES);
|
||||
generate_vertices();
|
||||
generate_faces();
|
||||
this->surface->generate_normals();
|
||||
this->surface->generate_tangents();
|
||||
this->surface->commit(this->mesh);
|
||||
}
|
||||
|
||||
size_t TerrainChunkMesh::points_per_side() const {
|
||||
return this->size * this->detail;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue