diff options
| author | Rémi Verschelde <rverschelde@gmail.com> | 2023-10-24 10:54:23 +0200 |
|---|---|---|
| committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-10-24 10:54:23 +0200 |
| commit | 261fe7ce6afd85cc792d61955070c5e82b5f33dd (patch) | |
| tree | 3b1141d10616e29efca1daa82ea6bc30d766d40a | |
| parent | bc5d5978eabb2e943096a193c40d2e8643ef30e3 (diff) | |
| parent | 8f9cd4e1e3af46234c37c948b9607b3b31464b5a (diff) | |
| download | redot-engine-261fe7ce6afd85cc792d61955070c5e82b5f33dd.tar.gz | |
Merge pull request #83704 from clayjohn/misc-mesh-fixes
Some more fixes for compressed meshes
| -rw-r--r-- | drivers/gles3/storage/mesh_storage.cpp | 10 | ||||
| -rw-r--r-- | editor/import/resource_importer_obj.cpp | 12 | ||||
| -rw-r--r-- | editor/import/resource_importer_scene.cpp | 2 | ||||
| -rw-r--r-- | scene/resources/importer_mesh.cpp | 6 | ||||
| -rw-r--r-- | scene/resources/mesh.cpp | 9 | ||||
| -rw-r--r-- | servers/rendering/renderer_rd/pipeline_cache_rd.h | 2 | ||||
| -rw-r--r-- | servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp | 8 | ||||
| -rw-r--r-- | servers/rendering/renderer_rd/storage_rd/mesh_storage.h | 4 | ||||
| -rw-r--r-- | servers/rendering_server.cpp | 32 | ||||
| -rw-r--r-- | servers/rendering_server.h | 2 |
10 files changed, 45 insertions, 42 deletions
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index eca0423a35..3213fa3775 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -202,12 +202,10 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) if (surface_version != uint64_t(RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION)) { RS::get_singleton()->fix_surface_compatibility(new_surface); surface_version = new_surface.format & (uint64_t(RS::ARRAY_FLAG_FORMAT_VERSION_MASK) << RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT); - ERR_FAIL_COND_MSG(surface_version != uint64_t(RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION), - "Surface version provided (" + - itos((surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK) + - ") does not match current version (" + - itos((uint64_t(RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION) >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK) + - ")"); + ERR_FAIL_COND_MSG(surface_version != RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION, + vformat("Surface version provided (%d) does not match current version (%d).", + (surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK, + (RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK)); } #endif diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index eec3d30bc9..646831ca24 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -226,11 +226,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ bool generate_tangents = p_generate_tangents; Vector3 scale_mesh = p_scale_mesh; Vector3 offset_mesh = p_offset_mesh; - uint64_t mesh_flags = RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; - - if (p_disable_compression) { - mesh_flags = 0; - } Vector<Vector3> vertices; Vector<Vector3> normals; @@ -374,6 +369,11 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ } } } else if (/*l.begins_with("g ") ||*/ l.begins_with("usemtl ") || (l.begins_with("o ") || f->eof_reached())) { //commit group to mesh + uint64_t mesh_flags = RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; + + if (p_disable_compression) { + mesh_flags = 0; + } //groups are too annoying if (surf_tool->get_vertex_array().size()) { //another group going on, commit it @@ -385,7 +385,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ surf_tool->generate_tangents(); } else { // We need tangents in order to compress vertex data. So disable if tangents aren't generated. - mesh_flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; + mesh_flags = 0; } surf_tool->index(); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 33c2b0e238..f9c989dc20 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -2371,7 +2371,7 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM Error err = OK; HashMap<StringName, Variant> options_dupe = p_options; - Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, options_dupe, nullptr, &err); + Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS | EditorSceneFormatImporter::IMPORT_FORCE_DISABLE_MESH_COMPRESSION, options_dupe, nullptr, &err); if (!scene || err != OK) { return nullptr; } diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index c7ee277a1b..1f4171c072 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -868,7 +868,7 @@ void ImporterMesh::_set_data(const Dictionary &p_data) { if (s.has("material")) { material = s["material"]; } - uint32_t flags = 0; + uint64_t flags = 0; if (s.has("flags")) { flags = s["flags"]; } @@ -909,9 +909,7 @@ Dictionary ImporterMesh::_get_data() const { d["name"] = surfaces[i].name; } - if (surfaces[i].flags != 0) { - d["flags"] = surfaces[i].flags; - } + d["flags"] = surfaces[i].flags; surface_arr.push_back(d); } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 2aabf14203..25a65b5cc4 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1639,6 +1639,11 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { uint64_t surface_version = surface.format & (ARRAY_FLAG_FORMAT_VERSION_MASK << ARRAY_FLAG_FORMAT_VERSION_SHIFT); if (surface_version != ARRAY_FLAG_FORMAT_CURRENT_VERSION) { RS::get_singleton()->fix_surface_compatibility(surface, get_path()); + surface_version = surface.format & (RS::ARRAY_FLAG_FORMAT_VERSION_MASK << RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT); + ERR_FAIL_COND_MSG(surface_version != RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION, + vformat("Surface version provided (%d) does not match current version (%d).", + (surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK, + (RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK)); } #endif @@ -2008,17 +2013,19 @@ void ArrayMesh::regen_normal_maps() { return; } Vector<Ref<SurfaceTool>> surfs; + Vector<uint64_t> formats; for (int i = 0; i < get_surface_count(); i++) { Ref<SurfaceTool> st = memnew(SurfaceTool); st->create_from(Ref<ArrayMesh>(this), i); surfs.push_back(st); + formats.push_back(surface_get_format(i)); } clear_surfaces(); for (int i = 0; i < surfs.size(); i++) { surfs.write[i]->generate_tangents(); - surfs.write[i]->commit(Ref<ArrayMesh>(this)); + surfs.write[i]->commit(Ref<ArrayMesh>(this), formats[i]); } } diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h index 2f1e79b397..0ebebd0540 100644 --- a/servers/rendering/renderer_rd/pipeline_cache_rd.h +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h @@ -38,7 +38,7 @@ class PipelineCacheRD { SpinLock spin_lock; RID shader; - uint32_t input_mask; + uint64_t input_mask; RD::RenderPrimitive render_primitive; RD::PipelineRasterizationState rasterization_state; diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 36ce1e38c6..3710ac0eed 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -359,11 +359,9 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) RS::get_singleton()->fix_surface_compatibility(new_surface); surface_version = new_surface.format & (RS::ARRAY_FLAG_FORMAT_VERSION_MASK << RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT); ERR_FAIL_COND_MSG(surface_version != RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION, - "Surface version provided (" + - itos((surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK) + - ") does not match current version (" + - itos((RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK) + - ")"); + vformat("Surface version provided (%d) does not match current version (%d).", + (surface_version >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK, + (RS::ARRAY_FLAG_FORMAT_CURRENT_VERSION >> RS::ARRAY_FLAG_FORMAT_VERSION_SHIFT) & RS::ARRAY_FLAG_FORMAT_VERSION_MASK)); } #endif diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index f03334baac..db54816e09 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -469,7 +469,7 @@ public: } } - _FORCE_INLINE_ void mesh_surface_get_vertex_arrays_and_format(void *p_surface, uint32_t p_input_mask, bool p_input_motion_vectors, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) { + _FORCE_INLINE_ void mesh_surface_get_vertex_arrays_and_format(void *p_surface, uint64_t p_input_mask, bool p_input_motion_vectors, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) { Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); s->version_lock.lock(); @@ -501,7 +501,7 @@ public: s->version_lock.unlock(); } - _FORCE_INLINE_ void mesh_instance_surface_get_vertex_arrays_and_format(RID p_mesh_instance, uint64_t p_surface_index, uint32_t p_input_mask, bool p_input_motion_vectors, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) { + _FORCE_INLINE_ void mesh_instance_surface_get_vertex_arrays_and_format(RID p_mesh_instance, uint64_t p_surface_index, uint64_t p_input_mask, bool p_input_motion_vectors, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) { MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance); ERR_FAIL_NULL(mi); Mesh *mesh = mi->mesh; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 952d479651..cc42c5a3fb 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -323,16 +323,18 @@ RID RenderingServer::get_white_texture() { } void _get_axis_angle(const Vector3 &p_normal, const Vector4 &p_tangent, float &r_angle, Vector3 &r_axis) { - Vector3 tangent = Vector3(p_tangent.x, p_tangent.y, p_tangent.z); + Vector3 normal = p_normal.normalized(); + Vector3 tangent = Vector3(p_tangent.x, p_tangent.y, p_tangent.z).normalized(); float d = p_tangent.w; - Vector3 binormal = p_normal.cross(tangent); + Vector3 binormal = normal.cross(tangent).normalized(); + real_t angle; - r_angle = Math::acos((tangent.x + binormal.y + p_normal.z - 1.0) / 2.0); - float denom = 2.0 * Math::sin(r_angle); - r_axis.x = (p_normal.y - binormal.z) / denom; - r_axis.y = (tangent.z - p_normal.x) / denom; - r_axis.z = (binormal.x - tangent.y) / denom; - r_axis.normalize(); + Basis tbn = Basis(); + tbn.rows[0] = tangent; + tbn.rows[1] = binormal; + tbn.rows[2] = normal; + tbn.get_axis_angle(r_axis, angle); + r_angle = float(angle); if (d < 0.0) { r_angle = CLAMP((1.0 - r_angle / Math_PI) * 0.5, 0.0, 0.49999); @@ -346,13 +348,11 @@ void _get_axis_angle(const Vector3 &p_normal, const Vector4 &p_tangent, float &r void _get_tbn_from_axis_angle(const Vector3 &p_axis, float p_angle, Vector3 &r_normal, Vector4 &r_tangent) { float binormal_sign = p_angle > 0.5 ? 1.0 : -1.0; float angle = Math::abs(p_angle * 2.0 - 1.0) * Math_PI; - float c = cos(angle); - float s = sin(angle); - Vector3 omc_axis = (1.0 - c) * p_axis; - Vector3 s_axis = s * p_axis; - Vector3 tan = omc_axis.x * p_axis + Vector3(c, -s_axis.z, s_axis.y); + + Basis tbn = Basis(p_axis, angle); + Vector3 tan = tbn.rows[0]; r_tangent = Vector4(tan.x, tan.y, tan.z, binormal_sign); - r_normal = omc_axis.z * p_axis + Vector3(-s_axis.y, s_axis.x, c); + r_normal = tbn.rows[2]; } Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_normal_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb, Vector4 &r_uv_scale) { @@ -1194,7 +1194,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa format |= RS::ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY; } - if (format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES && ((format & RS::ARRAY_FORMAT_NORMAL) || (format & RS::ARRAY_FORMAT_TANGENT))) { + if ((format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && ((format & RS::ARRAY_FORMAT_NORMAL) || (format & RS::ARRAY_FORMAT_TANGENT))) { // If using normals or tangents, then we need all three. ERR_FAIL_COND_V_MSG(!(format & RS::ARRAY_FORMAT_VERTEX), ERR_INVALID_PARAMETER, "Can't use compression flag 'ARRAY_FLAG_COMPRESS_ATTRIBUTES' while using normals or tangents without vertex array."); ERR_FAIL_COND_V_MSG(!(format & RS::ARRAY_FORMAT_NORMAL), ERR_INVALID_PARAMETER, "Can't use compression flag 'ARRAY_FLAG_COMPRESS_ATTRIBUTES' while using tangents without normal array."); @@ -1399,7 +1399,7 @@ Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t tangentsw[j * 4 + 3] = tan.w; } ret[RS::ARRAY_NORMAL] = normals; - ret[RS::ARRAY_FORMAT_TANGENT] = tangents; + ret[RS::ARRAY_TANGENT] = tangents; } else { for (int j = 0; j < p_vertex_len; j++) { diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 5b8c16e7fe..fb658aaee8 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -298,6 +298,8 @@ public: ARRAY_FLAG_FORMAT_VERSION_MASK = 0xFF, // 8 bits version }; + static_assert(sizeof(ArrayFormat) == 8, "ArrayFormat should be 64 bits long."); + enum PrimitiveType { PRIMITIVE_POINTS, PRIMITIVE_LINES, |
