Merge branch 'master' of https://github.com/Zylann/godot_voxel
commit
182352e903
|
@ -7,28 +7,45 @@
|
||||||
// Faster version of Mesh::create_trimesh_shape()
|
// Faster version of Mesh::create_trimesh_shape()
|
||||||
// See https://github.com/Zylann/godot_voxel/issues/54
|
// See https://github.com/Zylann/godot_voxel/issues/54
|
||||||
//
|
//
|
||||||
static Ref<ConcavePolygonShape> create_concave_polygon_shape(Array surface_arrays) {
|
static Ref<ConcavePolygonShape> create_concave_polygon_shape(Vector<Array> surfaces) {
|
||||||
|
|
||||||
PoolVector<Vector3> positions = surface_arrays[Mesh::ARRAY_VERTEX];
|
|
||||||
PoolVector<int> indices = surface_arrays[Mesh::ARRAY_INDEX];
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(positions.size() < 3, Ref<ConcavePolygonShape>());
|
|
||||||
ERR_FAIL_COND_V(indices.size() < 3, Ref<ConcavePolygonShape>());
|
|
||||||
ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ConcavePolygonShape>());
|
|
||||||
|
|
||||||
int face_points_count = indices.size();
|
|
||||||
|
|
||||||
PoolVector<Vector3> face_points;
|
PoolVector<Vector3> face_points;
|
||||||
face_points.resize(face_points_count);
|
int face_points_size = 0;
|
||||||
|
|
||||||
{
|
//find the correct size for face_points
|
||||||
PoolVector<Vector3>::Write w = face_points.write();
|
for(int i = 0; i < surfaces.size(); i++) {
|
||||||
PoolVector<int>::Read index_r = indices.read();
|
const Array &surface_arrays = surfaces[i];
|
||||||
PoolVector<Vector3>::Read position_r = positions.read();
|
PoolVector<int> indices = surface_arrays[Mesh::ARRAY_INDEX];
|
||||||
|
|
||||||
for (int i = 0; i < face_points_count; ++i) {
|
face_points_size += indices.size();
|
||||||
w[i] = position_r[index_r[i]];
|
}
|
||||||
|
face_points.resize(face_points_size);
|
||||||
|
|
||||||
|
//copy the points into it
|
||||||
|
int face_points_offset = 0;
|
||||||
|
for(int i = 0; i < surfaces.size(); i++) {
|
||||||
|
const Array &surface_arrays = surfaces[i];
|
||||||
|
|
||||||
|
PoolVector<Vector3> positions = surface_arrays[Mesh::ARRAY_VERTEX];
|
||||||
|
PoolVector<int> indices = surface_arrays[Mesh::ARRAY_INDEX];
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(positions.size() < 3, Ref<ConcavePolygonShape>());
|
||||||
|
ERR_FAIL_COND_V(indices.size() < 3, Ref<ConcavePolygonShape>());
|
||||||
|
ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ConcavePolygonShape>());
|
||||||
|
|
||||||
|
int face_points_count = face_points_offset + indices.size();
|
||||||
|
|
||||||
|
{
|
||||||
|
PoolVector<Vector3>::Write w = face_points.write();
|
||||||
|
PoolVector<int>::Read index_r = indices.read();
|
||||||
|
PoolVector<Vector3>::Read position_r = positions.read();
|
||||||
|
|
||||||
|
for (int p = face_points_offset; p < face_points_count; ++p) {
|
||||||
|
w[p] = position_r[index_r[p - face_points_offset]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
face_points_offset += indices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape);
|
Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape);
|
||||||
|
@ -85,7 +102,7 @@ void VoxelBlock::set_world(Ref<World> p_world) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelBlock::set_mesh(Ref<Mesh> mesh, Spatial *node, bool generate_collision, Array surface_arrays, bool debug_collision) {
|
void VoxelBlock::set_mesh(Ref<Mesh> mesh, Spatial *node, bool generate_collision, Vector<Array> surface_arrays, bool debug_collision) {
|
||||||
// TODO Don't add mesh instance to the world if it's not visible.
|
// TODO Don't add mesh instance to the world if it's not visible.
|
||||||
// I suspect Godot is trying to include invisible mesh instances into the culling process,
|
// I suspect Godot is trying to include invisible mesh instances into the culling process,
|
||||||
// which is killing performance when LOD is used (i.e many meshes are in pool but hidden)
|
// which is killing performance when LOD is used (i.e many meshes are in pool but hidden)
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
// Visuals and physics
|
// Visuals and physics
|
||||||
|
|
||||||
void set_world(Ref<World> p_world);
|
void set_world(Ref<World> p_world);
|
||||||
void set_mesh(Ref<Mesh> mesh, Spatial *node, bool generate_collision, Array surface_arrays, bool debug_collision);
|
void set_mesh(Ref<Mesh> mesh, Spatial *node, bool generate_collision, Vector<Array> surface_arrays, bool debug_collision);
|
||||||
void set_transition_mesh(Ref<Mesh> mesh, int side);
|
void set_transition_mesh(Ref<Mesh> mesh, int side);
|
||||||
bool has_mesh() const;
|
bool has_mesh() const;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ const uint32_t MAIN_THREAD_MESHING_BUDGET_MS = 8;
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
Ref<ArrayMesh> build_mesh(const Vector<Array> surfaces, Mesh::PrimitiveType primitive, int compression_flags,
|
Ref<ArrayMesh> build_mesh(const Vector<Array> surfaces, Mesh::PrimitiveType primitive, int compression_flags,
|
||||||
Ref<Material> material, Array *collidable_surface) {
|
Ref<Material> material) {
|
||||||
|
|
||||||
Ref<ArrayMesh> mesh;
|
Ref<ArrayMesh> mesh;
|
||||||
mesh.instance();
|
mesh.instance();
|
||||||
|
@ -32,10 +32,6 @@ Ref<ArrayMesh> build_mesh(const Vector<Array> surfaces, Mesh::PrimitiveType prim
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collidable_surface != nullptr && collidable_surface->empty()) {
|
|
||||||
*collidable_surface = surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->add_surface_from_arrays(primitive, surface, Array(), compression_flags);
|
mesh->add_surface_from_arrays(primitive, surface, Array(), compression_flags);
|
||||||
mesh->surface_set_material(surface_index, material);
|
mesh->surface_set_material(surface_index, material);
|
||||||
// No multi-material supported yet
|
// No multi-material supported yet
|
||||||
|
@ -1197,20 +1193,18 @@ void VoxelLodTerrain::_process() {
|
||||||
|
|
||||||
const VoxelMesher::Output mesh_data = ob.data.smooth_surfaces;
|
const VoxelMesher::Output mesh_data = ob.data.smooth_surfaces;
|
||||||
|
|
||||||
// TODO Allow multiple collision surfaces
|
|
||||||
Array collidable_surface;
|
|
||||||
Ref<ArrayMesh> mesh = build_mesh(
|
Ref<ArrayMesh> mesh = build_mesh(
|
||||||
mesh_data.surfaces,
|
mesh_data.surfaces,
|
||||||
mesh_data.primitive_type,
|
mesh_data.primitive_type,
|
||||||
mesh_data.compression_flags,
|
mesh_data.compression_flags,
|
||||||
_material, &collidable_surface);
|
_material);
|
||||||
|
|
||||||
bool has_collision = _generate_collisions;
|
bool has_collision = _generate_collisions;
|
||||||
if (has_collision && _collision_lod_count != -1) {
|
if (has_collision && _collision_lod_count != -1) {
|
||||||
has_collision = ob.lod < _collision_lod_count;
|
has_collision = ob.lod < _collision_lod_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
block->set_mesh(mesh, this, has_collision, collidable_surface, get_tree()->is_debugging_collisions_hint());
|
block->set_mesh(mesh, this, has_collision, mesh_data.surfaces, get_tree()->is_debugging_collisions_hint());
|
||||||
|
|
||||||
{
|
{
|
||||||
VOXEL_PROFILE_SCOPE(profile_process_receive_mesh_updates_block_update_transitions);
|
VOXEL_PROFILE_SCOPE(profile_process_receive_mesh_updates_block_update_transitions);
|
||||||
|
@ -1220,7 +1214,7 @@ void VoxelLodTerrain::_process() {
|
||||||
mesh_data.transition_surfaces[dir],
|
mesh_data.transition_surfaces[dir],
|
||||||
mesh_data.primitive_type,
|
mesh_data.primitive_type,
|
||||||
mesh_data.compression_flags,
|
mesh_data.compression_flags,
|
||||||
_material, nullptr);
|
_material);
|
||||||
|
|
||||||
block->set_transition_mesh(transition_mesh, dir);
|
block->set_transition_mesh(transition_mesh, dir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -928,7 +928,7 @@ void VoxelTerrain::_process() {
|
||||||
CRASH_COND(block->get_mesh_state() != VoxelBlock::MESH_UPDATE_NOT_SENT);
|
CRASH_COND(block->get_mesh_state() != VoxelBlock::MESH_UPDATE_NOT_SENT);
|
||||||
|
|
||||||
// The block contains empty voxels
|
// The block contains empty voxels
|
||||||
block->set_mesh(Ref<Mesh>(), this, _generate_collisions, Array(), get_tree()->is_debugging_collisions_hint());
|
block->set_mesh(Ref<Mesh>(), this, _generate_collisions, Vector<Array>(), get_tree()->is_debugging_collisions_hint());
|
||||||
block->set_mesh_state(VoxelBlock::MESH_UP_TO_DATE);
|
block->set_mesh_state(VoxelBlock::MESH_UP_TO_DATE);
|
||||||
|
|
||||||
// Optional, but I guess it might spare some memory
|
// Optional, but I guess it might spare some memory
|
||||||
|
@ -1013,8 +1013,7 @@ void VoxelTerrain::_process() {
|
||||||
Ref<ArrayMesh> mesh;
|
Ref<ArrayMesh> mesh;
|
||||||
mesh.instance();
|
mesh.instance();
|
||||||
|
|
||||||
// TODO Allow multiple collision surfaces
|
Vector<Array> collidable_surfaces; //need to put both blocky and smooth surfaces into one list
|
||||||
Array collidable_surface;
|
|
||||||
|
|
||||||
int surface_index = 0;
|
int surface_index = 0;
|
||||||
const VoxelMeshUpdater::OutputBlockData &data = ob.data;
|
const VoxelMeshUpdater::OutputBlockData &data = ob.data;
|
||||||
|
@ -1030,9 +1029,7 @@ void VoxelTerrain::_process() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collidable_surface.empty()) {
|
collidable_surfaces.push_back(surface);
|
||||||
collidable_surface = surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->add_surface_from_arrays(data.blocky_surfaces.primitive_type, surface, Array(), data.blocky_surfaces.compression_flags);
|
mesh->add_surface_from_arrays(data.blocky_surfaces.primitive_type, surface, Array(), data.blocky_surfaces.compression_flags);
|
||||||
mesh->surface_set_material(surface_index, _materials[i]);
|
mesh->surface_set_material(surface_index, _materials[i]);
|
||||||
|
@ -1051,9 +1048,7 @@ void VoxelTerrain::_process() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collidable_surface.empty()) {
|
collidable_surfaces.push_back(surface);
|
||||||
collidable_surface = surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->add_surface_from_arrays(data.smooth_surfaces.primitive_type, surface, Array(), data.smooth_surfaces.compression_flags);
|
mesh->add_surface_from_arrays(data.smooth_surfaces.primitive_type, surface, Array(), data.smooth_surfaces.compression_flags);
|
||||||
mesh->surface_set_material(surface_index, _materials[i]);
|
mesh->surface_set_material(surface_index, _materials[i]);
|
||||||
|
@ -1064,7 +1059,7 @@ void VoxelTerrain::_process() {
|
||||||
mesh = Ref<Mesh>();
|
mesh = Ref<Mesh>();
|
||||||
}
|
}
|
||||||
|
|
||||||
block->set_mesh(mesh, this, _generate_collisions, collidable_surface, get_tree()->is_debugging_collisions_hint());
|
block->set_mesh(mesh, this, _generate_collisions, collidable_surfaces, get_tree()->is_debugging_collisions_hint());
|
||||||
block->set_parent_visible(is_visible());
|
block->set_parent_visible(is_visible());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue