Merge branch 'master' of https://github.com/Zylann/godot_voxel
commit
182352e903
|
@ -7,7 +7,24 @@
|
|||
// Faster version of Mesh::create_trimesh_shape()
|
||||
// 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> face_points;
|
||||
int face_points_size = 0;
|
||||
|
||||
//find the correct size for face_points
|
||||
for(int i = 0; i < surfaces.size(); i++) {
|
||||
const Array &surface_arrays = surfaces[i];
|
||||
PoolVector<int> indices = surface_arrays[Mesh::ARRAY_INDEX];
|
||||
|
||||
face_points_size += indices.size();
|
||||
}
|
||||
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];
|
||||
|
@ -16,21 +33,21 @@ static Ref<ConcavePolygonShape> create_concave_polygon_shape(Array surface_array
|
|||
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;
|
||||
face_points.resize(face_points_count);
|
||||
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 i = 0; i < face_points_count; ++i) {
|
||||
w[i] = position_r[index_r[i]];
|
||||
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);
|
||||
shape->set_faces(face_points);
|
||||
return shape;
|
||||
|
@ -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.
|
||||
// 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)
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
// Visuals and physics
|
||||
|
||||
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);
|
||||
bool has_mesh() const;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ const uint32_t MAIN_THREAD_MESHING_BUDGET_MS = 8;
|
|||
namespace {
|
||||
|
||||
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;
|
||||
mesh.instance();
|
||||
|
@ -32,10 +32,6 @@ Ref<ArrayMesh> build_mesh(const Vector<Array> surfaces, Mesh::PrimitiveType prim
|
|||
continue;
|
||||
}
|
||||
|
||||
if (collidable_surface != nullptr && collidable_surface->empty()) {
|
||||
*collidable_surface = surface;
|
||||
}
|
||||
|
||||
mesh->add_surface_from_arrays(primitive, surface, Array(), compression_flags);
|
||||
mesh->surface_set_material(surface_index, material);
|
||||
// No multi-material supported yet
|
||||
|
@ -1197,20 +1193,18 @@ void VoxelLodTerrain::_process() {
|
|||
|
||||
const VoxelMesher::Output mesh_data = ob.data.smooth_surfaces;
|
||||
|
||||
// TODO Allow multiple collision surfaces
|
||||
Array collidable_surface;
|
||||
Ref<ArrayMesh> mesh = build_mesh(
|
||||
mesh_data.surfaces,
|
||||
mesh_data.primitive_type,
|
||||
mesh_data.compression_flags,
|
||||
_material, &collidable_surface);
|
||||
_material);
|
||||
|
||||
bool has_collision = _generate_collisions;
|
||||
if (has_collision && _collision_lod_count != -1) {
|
||||
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);
|
||||
|
@ -1220,7 +1214,7 @@ void VoxelLodTerrain::_process() {
|
|||
mesh_data.transition_surfaces[dir],
|
||||
mesh_data.primitive_type,
|
||||
mesh_data.compression_flags,
|
||||
_material, nullptr);
|
||||
_material);
|
||||
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Optional, but I guess it might spare some memory
|
||||
|
@ -1013,8 +1013,7 @@ void VoxelTerrain::_process() {
|
|||
Ref<ArrayMesh> mesh;
|
||||
mesh.instance();
|
||||
|
||||
// TODO Allow multiple collision surfaces
|
||||
Array collidable_surface;
|
||||
Vector<Array> collidable_surfaces; //need to put both blocky and smooth surfaces into one list
|
||||
|
||||
int surface_index = 0;
|
||||
const VoxelMeshUpdater::OutputBlockData &data = ob.data;
|
||||
|
@ -1030,9 +1029,7 @@ void VoxelTerrain::_process() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (collidable_surface.empty()) {
|
||||
collidable_surface = surface;
|
||||
}
|
||||
collidable_surfaces.push_back(surface);
|
||||
|
||||
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]);
|
||||
|
@ -1051,9 +1048,7 @@ void VoxelTerrain::_process() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (collidable_surface.empty()) {
|
||||
collidable_surface = surface;
|
||||
}
|
||||
collidable_surfaces.push_back(surface);
|
||||
|
||||
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]);
|
||||
|
@ -1064,7 +1059,7 @@ void VoxelTerrain::_process() {
|
|||
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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue