From 0138c02bf8f6f14d12afe7579d6abcda24df062b Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 28 Jun 2020 19:02:49 +0200 Subject: [PATCH] Implemented meshing chunk's mesh data resources. --- meshers/voxel_mesher.cpp | 143 ++++++-------------------- world/default/voxel_chunk_default.cpp | 106 +++++++++++-------- world/default/voxel_chunk_default.h | 9 +- 3 files changed, 99 insertions(+), 159 deletions(-) diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 9f99f4d..497b16c 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -439,125 +439,46 @@ void VoxelMesher::add_mesh_data_resource(Ref mesh, const Vecto } void VoxelMesher::add_mesh_data_resource_transform(Ref mesh, const Transform transform, const Rect2 uv_rect) { - ERR_FAIL_COND(mesh->get_array().size() == 0); + if (mesh->get_array().size() == 0) + return; - Array verts = mesh->get_array().get(Mesh::ARRAY_VERTEX); + const Array &arr = mesh->get_array(); - for (int i = 0; i < verts.size(); ++i) { - Vector3 vert = verts[i]; + PoolVector3Array vertices = arr[Mesh::ARRAY_VERTEX]; + PoolVector3Array normals = arr[Mesh::ARRAY_NORMAL]; + PoolVector2Array uvs = arr[Mesh::ARRAY_TEX_UV]; + PoolColorArray colors = arr[Mesh::ARRAY_COLOR]; + PoolIntArray indices = arr[Mesh::ARRAY_INDEX]; - vert = transform.xform(vert); + if (vertices.size() == 0) + return; - add_vertex(vert); + int orig_vert_size = _vertices.size(); + + for (int i = 0; i < vertices.size(); ++i) { + if (normals.size() > 0) + add_normal(transform.basis.xform(normals[i])); + + if (normals.size() > 0) { + Vector2 uv = uvs[i]; + + uv.x = uv_rect.size.width * uv.x + uv_rect.position.x; + uv.y = uv_rect.size.height * uv.y + uv_rect.position.y; + + add_uv(uv); + } + + if (colors.size() > 0) + add_color(colors[i]); + + add_vertex(transform.xform(vertices[i])); } - if (mesh->get_array().size() <= Mesh::ARRAY_NORMAL) - return; - - Array normals = mesh->get_array().get(Mesh::ARRAY_NORMAL); - - for (int i = 0; i < normals.size(); ++i) { - Vector3 normal = normals[i]; - - normal = transform.basis.xform(normal); - - add_normal(normal); - } - - /* - if (mesh->get_array().size() <= Mesh::ARRAY_TANGENT) - return; - - Array tangents = mesh->get_array().get(Mesh::ARRAY_TANGENT); - - for (int i = 0; i < verts.size(); ++i) { - - Plane p(tangents[i * 4 + 0], tangents[i * 4 + 1], tangents[i * 4 + 2], tangents[i * 4 + 3]); - - Vector3 tangent = p.normal; - Vector3 binormal = p.normal.cross(tangent).normalized() * p.d; - - tangent = local_transform.basis.xform(tangent); - binormal = local_transform.basis.xform(binormal); - - add_t(normal); - add_binorm - }*/ - - if (mesh->get_array().size() <= Mesh::ARRAY_COLOR) - return; - - Array colors = mesh->get_array().get(Mesh::ARRAY_COLOR); - - for (int i = 0; i < colors.size(); ++i) { - Color color = colors[i]; - - add_color(color); - } - - if (mesh->get_array().size() <= Mesh::ARRAY_TEX_UV) - return; - - Array tex_uv = mesh->get_array().get(Mesh::ARRAY_TEX_UV); - - for (int i = 0; i < tex_uv.size(); ++i) { - Vector2 uv = tex_uv[i]; - - uv.x *= uv_rect.size.x; - uv.y *= uv_rect.size.y; - - uv.x += uv_rect.position.x; - uv.y += uv_rect.position.y; - - add_uv(uv); - } - - /* - if (mesh->get_array().size() <= Mesh::ARRAY_TEX_UV2) - return; - - Array tex_uv2 = mesh->get_array().get(Mesh::ARRAY_TEX_UV2); - - for (int i = 0; i < tex_uv.size(); ++i) { - Vector2 uv = tex_uv2[i]; - - add_uv2(uv); - }*/ - - /* - if (mesh->get_array().size() <= Mesh::ARRAY_BONES) - return; - - Array bones = mesh->get_array().get(Mesh::ARRAY_BONES); - - for (int i = 0; i < bones.size(); ++i) { - int bone = bones[i]; - - add_bone(bone); - }*/ - - /* - if (mesh->get_array().size() <= Mesh::ARRAY_WEIGHTS) - return; - - Array weights = mesh->get_array().get(Mesh::ARRAY_WEIGHTS); - - for (int i = 0; i < weights.size(); ++i) { - float weight = weights[i]; - - add_weight(weight); - }*/ - - if (mesh->get_array().size() <= Mesh::ARRAY_INDEX) - return; - - Array indices = mesh->get_array().get(Mesh::ARRAY_INDEX); - int ic = get_vertex_count() - verts.size(); + int orig_indices_count = _indices.size(); + _indices.resize(_indices.size() + indices.size()); for (int i = 0; i < indices.size(); ++i) { - int index = indices[i]; - - add_indices(ic + index); + _indices.set(orig_indices_count + i, orig_vert_size + indices[i]); } } #endif diff --git a/world/default/voxel_chunk_default.cpp b/world/default/voxel_chunk_default.cpp index 7d44bd3..d1cf372 100644 --- a/world/default/voxel_chunk_default.cpp +++ b/world/default/voxel_chunk_default.cpp @@ -1103,6 +1103,14 @@ VoxelChunkDefault::~VoxelChunkDefault() { } _lights.clear(); + +#if MESH_DATA_RESOURCE_PRESENT + for (int i = 0; i < _collider_bodies.size(); ++i) { + PhysicsServer::get_singleton()->free(_collider_bodies[i]); + } + + _collider_bodies.clear(); +#endif } void VoxelChunkDefault::_setup_channels() { @@ -1150,10 +1158,6 @@ void VoxelChunkDefault::_build_phase(int phase) { next_phase(); return; } - case BUILD_PHASE_PROP_SETUP: { - next_phase(); - return; - } case BUILD_PHASE_TERRARIN_MESH_SETUP: { for (int i = 0; i < _meshers.size(); ++i) { Ref mesher = _meshers.get(i); @@ -1199,15 +1203,11 @@ void VoxelChunkDefault::_build_phase(int phase) { } } - for (int i = 0; i < _prop_meshers.size(); ++i) { - Ref mesher = _prop_meshers.get(i); - - ERR_CONTINUE(!mesher.is_valid()); - - temp_arr_collider.append_array(mesher->build_collider()); - } - - if (temp_arr_collider.size() == 0 && temp_arr_collider_liquid.size() == 0 && temp_arr_collider_prop.size() == 0) { + if (temp_arr_collider.size() == 0 && temp_arr_collider_liquid.size() == 0 +#ifdef MESH_DATA_RESOURCE_PRESENT + && get_mesh_data_resource_count() == 0 +#endif + ) { next_phase(); return; } @@ -1245,16 +1245,6 @@ void VoxelChunkDefault::_build_phase(int phase) { temp_arr_collider_liquid.resize(0); } - if (temp_arr_collider_prop.size() != 0) { - if (!has_meshes(MESH_INDEX_PROP, MESH_TYPE_INDEX_BODY)) { - create_colliders(MESH_INDEX_PROP); - } - - PhysicsServer::get_singleton()->shape_set_data(get_mesh_rid(MESH_INDEX_PROP, MESH_TYPE_INDEX_SHAPE), temp_arr_collider_prop); - - temp_arr_collider_prop.resize(0); - } - next_phase(); return; @@ -1477,12 +1467,21 @@ void VoxelChunkDefault::_build_phase(int phase) { return; } - case BUILD_PHASE_PROP_MESH: { - if (_props.size() == 0) { +#ifdef MESH_DATA_RESOURCE_PRESENT + case BUILD_PHASE_MESH_DATA_RESOURCES: { + if (get_mesh_data_resource_count() == 0) { next_phase(); return; } + for (int i = 0; i < _meshers.size(); ++i) { + Ref m = _meshers.get(i); + + ERR_CONTINUE(!m.is_valid()); + + m->add_mesh_data_resource_transform(get_mesh_data_resource(i), get_mesh_data_resource_transform(i), get_mesh_data_resource_uv_rect(i)); + } + Ref mesher; for (int i = 0; i < _meshers.size(); ++i) { Ref m = _meshers.get(i); @@ -1533,8 +1532,8 @@ void VoxelChunkDefault::_build_phase(int phase) { VS::get_singleton()->mesh_add_surface_from_arrays(mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - if (_library->get_material(0).is_valid()) - VS::get_singleton()->mesh_surface_set_material(mesh_rid, 0, _library->get_material(0)->get_rid()); + if (_library->get_prop_material(0).is_valid()) + VS::get_singleton()->mesh_surface_set_material(mesh_rid, 0, _library->get_prop_material(0)->get_rid()); if ((_build_flags & BUILD_FLAG_CREATE_LODS) != 0) { if (_lod_num >= 1) { @@ -1543,8 +1542,8 @@ void VoxelChunkDefault::_build_phase(int phase) { VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 1), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - if (get_library()->get_material(1).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 1), 0, get_library()->get_material(1)->get_rid()); + if (get_library()->get_prop_material(1).is_valid()) + VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 1), 0, get_library()->get_prop_material(1)->get_rid()); } if (_lod_num >= 2) { @@ -1552,13 +1551,13 @@ void VoxelChunkDefault::_build_phase(int phase) { VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 2), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr2); - if (get_library()->get_material(2).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 2), 0, get_library()->get_material(2)->get_rid()); + if (get_library()->get_prop_material(2).is_valid()) + VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 2), 0, get_library()->get_prop_material(2)->get_rid()); } if (_lod_num >= 3) { - Ref mat = get_library()->get_material(0); - Ref spmat = get_library()->get_material(0); + Ref mat = get_library()->get_prop_material(0); + Ref spmat = get_library()->get_prop_material(0); Ref tex; if (mat.is_valid()) { @@ -1573,8 +1572,8 @@ void VoxelChunkDefault::_build_phase(int phase) { VisualServer::get_singleton()->mesh_add_surface_from_arrays(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 3), VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - if (get_library()->get_material(3).is_valid()) - VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 3), 0, get_library()->get_material(3)->get_rid()); + if (get_library()->get_prop_material(3).is_valid()) + VisualServer::get_singleton()->mesh_surface_set_material(get_mesh_rid_index(MESH_INDEX_PROP, MESH_TYPE_INDEX_MESH, 3), 0, get_library()->get_prop_material(3)->get_rid()); } } @@ -1607,6 +1606,7 @@ void VoxelChunkDefault::_build_phase(int phase) { return; } +#endif case BUILD_PHASE_FINALIZE: { update_transforms(); @@ -1650,16 +1650,31 @@ void VoxelChunkDefault::_build_phase_physics_process(int phase) { temp_arr_collider_liquid.resize(0); } - if (temp_arr_collider_prop.size() != 0) { - if (!has_meshes(MESH_INDEX_PROP, MESH_TYPE_INDEX_BODY)) { - create_colliders(MESH_INDEX_PROP); - } - - PhysicsServer::get_singleton()->shape_set_data(get_mesh_rid(MESH_INDEX_PROP, MESH_TYPE_INDEX_SHAPE), temp_arr_collider_prop); - - temp_arr_collider_prop.resize(0); +#if MESH_DATA_RESOURCE_PRESENT + for (int i = 0; i < _collider_bodies.size(); ++i) { + PhysicsServer::get_singleton()->free(_collider_bodies[i]); } + _collider_bodies.clear(); + + for (int i = 0; i < get_mesh_data_resource_count(); ++i) { + Ref mdr = get_mesh_data_resource(i); + + for (int j = 0; j < mdr->get_collision_shape_count(); ++i) { + Ref shape = mdr->get_collision_shape(j); + + if (!shape.is_valid()) { + continue; + } + + RID body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC); + PhysicsServer::get_singleton()->body_add_shape(body, shape->get_rid(), get_mesh_data_resource_transform(j)); + + _collider_bodies.push_back(body); + } + } +#endif + set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL); next_phase(); } @@ -1835,11 +1850,12 @@ void VoxelChunkDefault::_bind_methods() { BIND_CONSTANT(BUILD_PHASE_DONE); BIND_CONSTANT(BUILD_PHASE_SETUP); - BIND_CONSTANT(BUILD_PHASE_PROP_SETUP); BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_SETUP); BIND_CONSTANT(BUILD_PHASE_COLLIDER); BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH); - BIND_CONSTANT(BUILD_PHASE_PROP_MESH); +#ifdef MESH_DATA_RESOURCE_PRESENT + BIND_CONSTANT(BUILD_PHASE_MESH_DATA_RESOURCES); +#endif BIND_CONSTANT(BUILD_PHASE_LIGHTS); BIND_CONSTANT(BUILD_PHASE_FINALIZE); BIND_CONSTANT(BUILD_PHASE_MAX); diff --git a/world/default/voxel_chunk_default.h b/world/default/voxel_chunk_default.h index 12226fd..12d32e6 100644 --- a/world/default/voxel_chunk_default.h +++ b/world/default/voxel_chunk_default.h @@ -72,12 +72,13 @@ public: enum { BUILD_PHASE_DONE = 0, BUILD_PHASE_SETUP, - BUILD_PHASE_PROP_SETUP, BUILD_PHASE_TERRARIN_MESH_SETUP, BUILD_PHASE_COLLIDER, BUILD_PHASE_LIGHTS, BUILD_PHASE_TERRARIN_MESH, - BUILD_PHASE_PROP_MESH, +#ifdef MESH_DATA_RESOURCE_PRESENT + BUILD_PHASE_MESH_DATA_RESOURCES, +#endif BUILD_PHASE_FINALIZE, BUILD_PHASE_MAX }; @@ -286,11 +287,13 @@ protected: Array temp_array; PoolVector temp_arr_collider; PoolVector temp_arr_collider_liquid; - PoolVector temp_arr_collider_prop; ActiveBuildPhaseType _active_build_phase_type; Vector > _lights; +#if MESH_DATA_RESOURCE_PRESENT + Vector _collider_bodies; +#endif }; VARIANT_ENUM_CAST(VoxelChunkDefault::DefaultChannels);