Changed voxel scale to cell size x and y.

This commit is contained in:
Relintai 2022-02-24 15:50:47 +01:00
parent 936143b964
commit 7f68d5f794
11 changed files with 147 additions and 72 deletions

View File

@ -50,7 +50,8 @@ void Terrain2DMesherBlocky::add_chunk_normal(Ref<Terrain2DChunkDefault> chunk) {
int x_size = chunk->get_size_x();
int z_size = chunk->get_size_z();
float voxel_scale = get_voxel_scale();
int cell_size_x = get_cell_size_x();
int cell_size_y = get_cell_size_y();
uint8_t *channel_type = chunk->channel_get(_channel_index_type);
@ -159,11 +160,16 @@ void Terrain2DMesherBlocky::add_chunk_normal(Ref<Terrain2DChunkDefault> chunk) {
surface->transform_uv_scaled(Terrain2DSurface::TERRAIN_2D_SIDE_TOP, Vector2(1, 1), x % get_texture_scale(), z % get_texture_scale(), get_texture_scale())
};
int xx = (x + 1) * cell_size_x;
int xx1 = x * cell_size_x;
int yy = z * cell_size_y;
int yy1 = (z + 1) * cell_size_y;
Vector2 verts[] = {
Vector2(x + 1, z) * voxel_scale,
Vector2(x, z) * voxel_scale,
Vector2(x, z + 1) * voxel_scale,
Vector2(x + 1, z + 1) * voxel_scale
Vector2(xx1, yy),
Vector2(xx, yy),
Vector2(xx, yy1),
Vector2(xx1, yy1)
};
for (int i = 0; i < 4; ++i) {

View File

@ -63,8 +63,8 @@ void Terrain2DMesherDefault::_bake_colors(Ref<Terrain2DChunk> chunk) {
Vertex vertex = _vertices[i];
Vector2 vert = vertex.vertex;
unsigned int x = (unsigned int)(vert.x / _voxel_scale);
unsigned int y = (unsigned int)(vert.y / _voxel_scale);
unsigned int x = (unsigned int)(vert.x / _cell_size_x);
unsigned int y = (unsigned int)(vert.y / _cell_size_y);
if (chunk->validate_data_position(x, y)) {
int indx = chunk->get_data_index(x, y);
@ -129,9 +129,9 @@ void Terrain2DMesherDefault::_bake_liquid_colors(Ref<Terrain2DChunk> chunk) {
continue;
}
unsigned int x = (unsigned int)(vert.x / _voxel_scale);
unsigned int x = (unsigned int)(vert.x / _cell_size_x);
//unsigned int y = (unsigned int)(vert.y / _voxel_scale);
unsigned int y = (unsigned int)(vert.y / _voxel_scale);
unsigned int y = (unsigned int)(vert.y / _cell_size_y);
if (chunk->validate_data_position(x, y)) {
int indx = chunk->get_data_index(x, y);

View File

@ -127,11 +127,18 @@ void Terrain2DMesher::set_base_light_value(float value) {
_base_light_value = value;
}
float Terrain2DMesher::get_voxel_scale() const {
return _voxel_scale;
int Terrain2DMesher::get_cell_size_x() const {
return _cell_size_x;
}
void Terrain2DMesher::set_voxel_scale(const float voxel_scale) {
_voxel_scale = voxel_scale;
void Terrain2DMesher::set_cell_size_x(const int val) {
_cell_size_x = val;
}
int Terrain2DMesher::get_cell_size_y() const {
return _cell_size_y;
}
void Terrain2DMesher::set_cell_size_y(const int val) {
_cell_size_y = val;
}
Rect2 Terrain2DMesher::get_uv_margin() const {
@ -729,7 +736,8 @@ Terrain2DMesher::Terrain2DMesher(const Ref<Terrain2DLibrary> &library) {
_library = library;
_mesher_index = 0;
_voxel_scale = 1;
_cell_size_x = 32;
_cell_size_y = 32;
_ao_strength = 0.25;
_base_light_value = 0.5;
_uv_margin = Rect2(0, 0, 1, 1);
@ -741,7 +749,8 @@ Terrain2DMesher::Terrain2DMesher(const Ref<Terrain2DLibrary> &library) {
Terrain2DMesher::Terrain2DMesher() {
_mesher_index = 0;
_voxel_scale = 1;
_cell_size_x = 32;
_cell_size_y = 32;
_ao_strength = 0.25;
_base_light_value = 0.5;
_uv_margin = Rect2(0, 0, 1, 1);
@ -796,9 +805,13 @@ void Terrain2DMesher::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_material", "value"), &Terrain2DMesher::set_material);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material");
ClassDB::bind_method(D_METHOD("get_voxel_scale"), &Terrain2DMesher::get_voxel_scale);
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &Terrain2DMesher::set_voxel_scale);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
ClassDB::bind_method(D_METHOD("get_cell_size_x"), &Terrain2DMesher::get_cell_size_x);
ClassDB::bind_method(D_METHOD("set_cell_size_x", "value"), &Terrain2DMesher::set_cell_size_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_size_x"), "set_cell_size_x", "get_cell_size_x");
ClassDB::bind_method(D_METHOD("get_cell_size_y"), &Terrain2DMesher::get_cell_size_y);
ClassDB::bind_method(D_METHOD("set_cell_size_y", "value"), &Terrain2DMesher::set_cell_size_y);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_size_y"), "set_cell_size_y", "get_cell_size_y");
ClassDB::bind_method(D_METHOD("get_ao_strength"), &Terrain2DMesher::get_ao_strength);
ClassDB::bind_method(D_METHOD("set_ao_strength", "value"), &Terrain2DMesher::set_ao_strength);
@ -820,7 +833,6 @@ void Terrain2DMesher::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_mesh_data_resource_transform_colored", "mesh", "transform", "colors", "uv_rect"), &Terrain2DMesher::add_mesh_data_resource_transform_colored, DEFVAL(Rect2(0, 0, 1, 1)));
#endif
#if VERSION_MAJOR < 4
BIND_VMETHOD(MethodInfo("_add_mesher", PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "Terrain2DMesher")));
#else

View File

@ -30,12 +30,12 @@ SOFTWARE.
#ifndef Reference
#define Reference RefCounted
#endif
#include "core/templates/vector.h"
#include "core/math/color.h"
#include "core/templates/vector.h"
#else
#include "core/color.h"
#include "core/reference.h"
#include "core/vector.h"
#include "core/color.h"
#endif
#include "../defines.h"
@ -120,8 +120,11 @@ public:
float get_base_light_value() const;
void set_base_light_value(const float value);
float get_voxel_scale() const;
void set_voxel_scale(const float voxel_scale);
int get_cell_size_x() const;
void set_cell_size_x(const int val);
int get_cell_size_y() const;
void set_cell_size_y(const int val);
Rect2 get_uv_margin() const;
void set_uv_margin(const Rect2 margin);
@ -211,7 +214,8 @@ protected:
Ref<Terrain2DLibrary> _library;
Ref<Material> _material;
float _voxel_scale;
int _cell_size_x;
int _cell_size_y;
float _ao_strength;
float _base_light_value;

View File

@ -561,7 +561,7 @@ void Terrain2DChunkDefault::debug_mesh_send() {
}
void Terrain2DChunkDefault::draw_cross_voxels(Vector3 pos) {
pos *= _voxel_scale;
pos *= get_cell_size_x();
int size = _debug_mesh_array.size();
_debug_mesh_array.resize(_debug_mesh_array.size() + 6);
@ -577,7 +577,7 @@ void Terrain2DChunkDefault::draw_cross_voxels(Vector3 pos) {
}
void Terrain2DChunkDefault::draw_cross_voxels_fill(Vector3 pos, float fill) {
pos *= _voxel_scale;
pos *= get_cell_size_x();
int size = _debug_mesh_array.size();
_debug_mesh_array.resize(_debug_mesh_array.size() + 6);

View File

@ -54,7 +54,9 @@ PoolColorArray Terrain2DWorldDefault::get_vertex_colors(const Transform &transfo
for (int i = 0; i < vertices.size(); ++i) {
Vector3 v = transform.xform(vertices[i]);
Vector3 pos = v / get_voxel_scale();
Vector3 pos = v;
v.x /= get_cell_size_x();
v.z /= get_cell_size_y();
//Note: floor is needed to handle negative numbers proiberly
int x = static_cast<int>(Math::floor(pos.x / get_chunk_size_x()));

View File

@ -361,7 +361,8 @@ void Terrain2DTerrain2DJob::_reset() {
ERR_FAIL_COND(!_mesher.is_valid());
_mesher->set_voxel_scale(_chunk->get_voxel_scale());
_mesher->set_cell_size_x(_chunk->get_cell_size_x());
_mesher->set_cell_size_y(_chunk->get_cell_size_y());
Ref<Terrain2DChunkDefault> chunk = _chunk;
Ref<Terrain2DMesherDefault> md = _mesher;
@ -371,7 +372,8 @@ void Terrain2DTerrain2DJob::_reset() {
}
if (_liquid_mesher.is_valid()) {
_liquid_mesher->set_voxel_scale(_chunk->get_voxel_scale());
_liquid_mesher->set_cell_size_x(_chunk->get_cell_size_x());
_liquid_mesher->set_cell_size_y(_chunk->get_cell_size_y());
md = _liquid_mesher;

View File

@ -105,11 +105,11 @@ _FORCE_INLINE_ Vector2 Terrain2DChunk::get_position() const {
return Vector2(_position_x, _position_z);
}
_FORCE_INLINE_ Vector2 Terrain2DChunk::get_world_position() const {
return Vector2(_position_x * _size_x * _voxel_scale, _position_z * _size_z * _voxel_scale);
return Vector2(_position_x * _size_x * _cell_size_x, _position_z * _size_z * _cell_size_y);
}
_FORCE_INLINE_ Vector3 Terrain2DChunk::get_world_size() const {
return Vector3(_size_x * _voxel_scale, 0, _size_z * _voxel_scale);
return Vector3(_size_x * _cell_size_x, 0, _size_z * _cell_size_y);
}
_FORCE_INLINE_ AABB Terrain2DChunk::get_world_aabb() const {
@ -218,11 +218,18 @@ void Terrain2DChunk::set_library(const Ref<Terrain2DLibrary> &value) {
_library = value;
}
float Terrain2DChunk::get_voxel_scale() const {
return _voxel_scale;
int Terrain2DChunk::get_cell_size_x() const{
return _cell_size_x;
}
void Terrain2DChunk::set_voxel_scale(const float value) {
_voxel_scale = value;
void Terrain2DChunk::set_cell_size_x(const int value){
_cell_size_x = value;
}
int Terrain2DChunk::get_cell_size_y() const{
return _cell_size_y;
}
void Terrain2DChunk::set_cell_size_y(const int value) {
_cell_size_y = value;
}
Terrain2DWorld *Terrain2DChunk::get_voxel_world() const {
@ -624,9 +631,8 @@ int Terrain2DChunk::voxel_structure_get_count() const {
void Terrain2DChunk::voxel_structure_add_at_position(Ref<Terrain2DStructure> structure, const Vector3 &world_position) {
ERR_FAIL_COND(!structure.is_valid());
structure->set_position_x(static_cast<int>(world_position.x / _voxel_scale));
structure->set_position_y(static_cast<int>(world_position.y / _voxel_scale));
structure->set_position_z(static_cast<int>(world_position.z / _voxel_scale));
structure->set_position_x(static_cast<int>(world_position.x / _cell_size_x));
structure->set_position_y(static_cast<int>(world_position.y / _cell_size_y));
voxel_structure_add(structure);
}
@ -1081,7 +1087,8 @@ Terrain2DChunk::Terrain2DChunk() {
_dirty = false;
_state = TERRAIN_2D_CHUNK_STATE_OK;
_voxel_scale = 1;
_cell_size_x = 32;
_cell_size_y = 32;
_voxel_world = NULL;
@ -1240,7 +1247,7 @@ void Terrain2DChunk::_generation_physics_process(const float delta) {
void Terrain2DChunk::_world_transform_changed() {
Transform2D t;
t.set_origin( Vector2(_position_x * static_cast<int>(_size_x) * _voxel_scale, _position_z * static_cast<int>(_size_z) * _voxel_scale));
t.set_origin( Vector2(_position_x * static_cast<int>(_size_x) * _cell_size_x, _position_z * static_cast<int>(_size_z) * _cell_size_y));
set_transform(t);
@ -1435,9 +1442,13 @@ void Terrain2DChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_library", "value"), &Terrain2DChunk::set_library);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "Terrain2DLibrary"), "set_library", "get_library");
ClassDB::bind_method(D_METHOD("get_voxel_scale"), &Terrain2DChunk::get_voxel_scale);
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &Terrain2DChunk::set_voxel_scale);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
ClassDB::bind_method(D_METHOD("get_cell_size_x"), &Terrain2DChunk::get_cell_size_x);
ClassDB::bind_method(D_METHOD("set_cell_size_x", "value"), &Terrain2DChunk::set_cell_size_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_size_x"), "set_cell_size_x", "get_cell_size_x");
ClassDB::bind_method(D_METHOD("get_cell_size_y"), &Terrain2DChunk::get_cell_size_y);
ClassDB::bind_method(D_METHOD("set_cell_size_y", "value"), &Terrain2DChunk::set_cell_size_y);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_size_y"), "set_cell_size_y", "get_cell_size_y");
ClassDB::bind_method(D_METHOD("job_get", "index"), &Terrain2DChunk::job_get);
ClassDB::bind_method(D_METHOD("job_set", "index", "job"), &Terrain2DChunk::job_set);

View File

@ -183,8 +183,11 @@ public:
Ref<Terrain2DLibrary> get_library();
void set_library(const Ref<Terrain2DLibrary> &value);
float get_voxel_scale() const;
void set_voxel_scale(const float value);
int get_cell_size_x() const;
void set_cell_size_x(const int value);
int get_cell_size_y() const;
void set_cell_size_y(const int value);
Terrain2DWorld *get_voxel_world() const;
void set_voxel_world(Terrain2DWorld *world);
@ -420,7 +423,8 @@ protected:
Vector<uint8_t *> _channels;
float _voxel_scale;
int _cell_size_x;
int _cell_size_y;
int _current_job;
Vector<Ref<Terrain2DJob>> _jobs;

View File

@ -130,11 +130,11 @@ void Terrain2DWorld::set_level_generator(const Ref<Terrain2DLevelGenerator> &lev
_level_generator = level_generator;
}
float Terrain2DWorld::get_voxel_scale() const {
return _voxel_scale;
int Terrain2DWorld::get_cell_size_x() const{
return _cell_size_x;
}
void Terrain2DWorld::set_voxel_scale(const float value) {
_voxel_scale = value;
void Terrain2DWorld::set_cell_size_x(const int value){
_cell_size_x = value;
for (int i = 0; i < chunk_get_count(); ++i) {
Ref<Terrain2DChunk> c = chunk_get_index(i);
@ -142,7 +142,23 @@ void Terrain2DWorld::set_voxel_scale(const float value) {
if (!c.is_valid())
continue;
c->set_voxel_scale(_voxel_scale);
c->set_cell_size_x(_cell_size_x);
}
}
int Terrain2DWorld::get_cell_size_y() const{
return _cell_size_y;
}
void Terrain2DWorld::set_cell_size_y(const int value) {
_cell_size_y = value;
for (int i = 0; i < chunk_get_count(); ++i) {
Ref<Terrain2DChunk> c = chunk_get_index(i);
if (!c.is_valid())
continue;
c->set_cell_size_y(_cell_size_y);
}
}
@ -224,9 +240,8 @@ int Terrain2DWorld::voxel_structure_get_count() const {
void Terrain2DWorld::voxel_structure_add_at_position(Ref<Terrain2DStructure> structure, const Vector3 &world_position) {
ERR_FAIL_COND(!structure.is_valid());
structure->set_position_x(static_cast<int>(world_position.x / _voxel_scale));
structure->set_position_y(static_cast<int>(world_position.y / _voxel_scale));
structure->set_position_z(static_cast<int>(world_position.z / _voxel_scale));
structure->set_position_x(static_cast<int>(world_position.x / _cell_size_x));
structure->set_position_y(static_cast<int>(world_position.z / _cell_size_y));
voxel_structure_add(structure);
}
@ -337,7 +352,7 @@ Ref<Terrain2DChunk> Terrain2DWorld::chunk_remove_index(const int index) {
emit_signal("chunk_removed", chunk);
update();
return chunk;
}
@ -422,7 +437,9 @@ Ref<Terrain2DChunk> Terrain2DWorld::_create_chunk(const int x, const int z, Ref<
chunk->set_position(x, z);
chunk->set_library(_library);
chunk->set_voxel_scale(_voxel_scale);
chunk->set_cell_size_x(_cell_size_x);
chunk->set_cell_size_y(_cell_size_y);
chunk->set_size(_chunk_size_x, _chunk_size_z, _data_margin_start, _data_margin_end);
//chunk->set_translation(Vector3(x * _chunk_size_x * _voxel_scale, y * _chunk_size_y * _voxel_scale, z * _chunk_size_z * _voxel_scale));
@ -504,9 +521,9 @@ void Terrain2DWorld::_set_voxel_with_tool(const bool mode_add, const Vector3 hit
Vector3 pos;
if (mode_add) {
pos = (hit_position + (Vector3(0.1, 0.1, 0.1) * hit_normal * get_voxel_scale()));
pos = (hit_position + (Vector3(0.1, 0.1, 0.1) * hit_normal * _cell_size_x));
} else {
pos = (hit_position + (Vector3(0.1, 0.1, 0.1) * -hit_normal * get_voxel_scale()));
pos = (hit_position + (Vector3(0.1, 0.1, 0.1) * -hit_normal * _cell_size_x));
}
int channel_type = get_channel_index_info(Terrain2DWorld::CHANNEL_TYPE_INFO_TYPE);
@ -529,8 +546,8 @@ bool Terrain2DWorld::can_chunk_do_build_step() {
}
bool Terrain2DWorld::is_position_walkable(const Vector3 &p_pos) {
int x = static_cast<int>(Math::floor(p_pos.x / (_chunk_size_x * _voxel_scale)));
int z = static_cast<int>(Math::floor(p_pos.z / (_chunk_size_z * _voxel_scale)));
int x = static_cast<int>(Math::floor(p_pos.x / (_chunk_size_x * _cell_size_x)));
int z = static_cast<int>(Math::floor(p_pos.z / (_chunk_size_z * _cell_size_y)));
Ref<Terrain2DChunk> c = chunk_get(x, z);
@ -751,8 +768,10 @@ void Terrain2DWorld::lights_set(const Vector<Variant> &chunks) {
}
uint8_t Terrain2DWorld::get_voxel_at_world_position(const Vector3 &world_position, const int channel_index) {
Vector3 pos = world_position / get_voxel_scale();
Vector3 pos = world_position;
pos.x /= _cell_size_x;
pos.y /= _cell_size_y;
//Note: floor is needed to handle negative numbers properly
int x = static_cast<int>(Math::floor(pos.x / get_chunk_size_x()));
int z = static_cast<int>(Math::floor(pos.z / get_chunk_size_z()));
@ -777,7 +796,9 @@ uint8_t Terrain2DWorld::get_voxel_at_world_position(const Vector3 &world_positio
}
void Terrain2DWorld::set_voxel_at_world_position(const Vector3 &world_position, const uint8_t data, const int channel_index, const bool rebuild) {
Vector3 pos = world_position / get_voxel_scale();
Vector3 pos = world_position;
pos.x /= _cell_size_x;
pos.y /= _cell_size_y;
//Note: floor is needed to handle negative numbers properly
int x = static_cast<int>(Math::floor(pos.x / get_chunk_size_x()));
@ -838,7 +859,9 @@ void Terrain2DWorld::set_voxel_at_world_position(const Vector3 &world_position,
}
Ref<Terrain2DChunk> Terrain2DWorld::get_chunk_at_world_position(const Vector3 &world_position) {
Vector3 pos = world_position / get_voxel_scale();
Vector3 pos = world_position;
pos.x /= _cell_size_x;
pos.y /= _cell_size_y;
//Note: floor is needed to handle negative numbers proiberly
int x = static_cast<int>(Math::floor(pos.x / get_chunk_size_x()));
@ -847,7 +870,9 @@ Ref<Terrain2DChunk> Terrain2DWorld::get_chunk_at_world_position(const Vector3 &w
return chunk_get(x, z);
}
Ref<Terrain2DChunk> Terrain2DWorld::get_or_create_chunk_at_world_position(const Vector3 &world_position) {
Vector3 pos = world_position / get_voxel_scale();
Vector3 pos = world_position;
pos.x /= _cell_size_x;
pos.y /= _cell_size_y;
//Note: floor is needed to handle negative numbers proiberly
int x = static_cast<int>(Math::floor(pos.x / get_chunk_size_x()));
@ -877,7 +902,8 @@ Terrain2DWorld::Terrain2DWorld() {
_data_margin_start = 0;
_data_margin_end = 0;
_voxel_scale = 1;
_cell_size_x = 32;
_cell_size_y = 32;
_chunk_spawn_range = 4;
_player = NULL;
@ -1126,9 +1152,13 @@ void Terrain2DWorld::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_level_generator", "level_generator"), &Terrain2DWorld::set_level_generator);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "level_generator", PROPERTY_HINT_RESOURCE_TYPE, "Terrain2DLevelGenerator"), "set_level_generator", "get_level_generator");
ClassDB::bind_method(D_METHOD("get_voxel_scale"), &Terrain2DWorld::get_voxel_scale);
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &Terrain2DWorld::set_voxel_scale);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
ClassDB::bind_method(D_METHOD("get_cell_size_x"), &Terrain2DWorld::get_cell_size_x);
ClassDB::bind_method(D_METHOD("set_cell_size_x", "value"), &Terrain2DWorld::set_cell_size_x);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_size_x"), "set_cell_size_x", "get_cell_size_x");
ClassDB::bind_method(D_METHOD("get_cell_size_y"), &Terrain2DWorld::get_cell_size_y);
ClassDB::bind_method(D_METHOD("set_cell_size_y", "value"), &Terrain2DWorld::set_cell_size_y);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_size_y"), "set_cell_size_y", "get_cell_size_y");
ClassDB::bind_method(D_METHOD("get_chunk_spawn_range"), &Terrain2DWorld::get_chunk_spawn_range);
ClassDB::bind_method(D_METHOD("set_chunk_spawn_range", "value"), &Terrain2DWorld::set_chunk_spawn_range);

View File

@ -98,8 +98,11 @@ public:
Ref<Terrain2DLevelGenerator> get_level_generator() const;
void set_level_generator(const Ref<Terrain2DLevelGenerator> &level_generator);
float get_voxel_scale() const;
void set_voxel_scale(const float value);
int get_cell_size_x() const;
void set_cell_size_x(const int value);
int get_cell_size_y() const;
void set_cell_size_y(const int value);
int get_chunk_spawn_range() const;
void set_chunk_spawn_range(const int value);
@ -260,7 +263,8 @@ private:
Ref<Terrain2DLibrary> _library;
Ref<Terrain2DLevelGenerator> _level_generator;
float _voxel_scale;
int _cell_size_x;
int _cell_size_y;
int _chunk_spawn_range;
HashMap<IntPos, Ref<Terrain2DChunk>, IntPosHasher> _chunks;