diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/fbx/editor_scene_importer_fbx.cpp | 43 | ||||
| -rw-r--r-- | modules/gltf/gltf_document.cpp | 96 | ||||
| -rw-r--r-- | modules/lightmapper_rd/lm_common_inc.glsl | 4 | ||||
| -rw-r--r-- | modules/lightmapper_rd/lm_compute.glsl | 24 | ||||
| -rw-r--r-- | modules/lightmapper_rd/lm_raster.glsl | 12 |
5 files changed, 148 insertions, 31 deletions
diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index e4de204cf1..e90eab522f 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -1011,9 +1011,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // track count is 5. // next track id is 5. const uint64_t target_id = track.key; - int track_idx = animation->add_track(Animation::TYPE_TRANSFORM3D); - // animation->track_set_path(track_idx, node_path); Ref<FBXBone> bone; // note we must not run the below code if the entry doesn't exist, it will create dummy entries which is very bad. @@ -1037,22 +1035,21 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // if this is a skeleton mapped track we can just set the path for the track. // todo: implement node paths here at some + NodePath track_path; if (state.fbx_bone_map.size() > 0 && state.fbx_bone_map.has(target_id)) { if (bone->fbx_skeleton.is_valid() && bone.is_valid()) { Ref<FBXSkeleton> fbx_skeleton = bone->fbx_skeleton; String bone_path = state.root->get_path_to(fbx_skeleton->skeleton); bone_path += ":" + fbx_skeleton->skeleton->get_bone_name(bone->godot_bone_id); print_verbose("[doc] track bone path: " + bone_path); - NodePath path = bone_path; - animation->track_set_path(track_idx, path); + track_path = bone_path; } } else if (state.fbx_target_map.has(target_id)) { //print_verbose("[doc] we have a valid target for a node animation"); Ref<FBXNode> target_node = state.fbx_target_map[target_id]; if (target_node.is_valid() && target_node->godot_node != nullptr) { String node_path = state.root->get_path_to(target_node->godot_node); - NodePath path = node_path; - animation->track_set_path(track_idx, path); + track_path = node_path; //print_verbose("[doc] node animation path: " + node_path); } } else { @@ -1186,6 +1183,30 @@ Node3D *EditorSceneImporterFBX::_generate_scene( const Vector3 def_scale = scale_keys.has_default ? scale_keys.default_value : bone_rest.basis.get_scale(); print_verbose("track defaults: p(" + def_pos + ") s(" + def_scale + ") r(" + def_rot + ")"); + int position_idx = -1; + if (pos_values.size()) { + position_idx = animation->get_track_count(); + animation->add_track(Animation::TYPE_POSITION_3D); + animation->track_set_path(position_idx, track_path); + animation->track_set_imported(position_idx, true); + } + + int rotation_idx = -1; + if (pos_values.size()) { + rotation_idx = animation->get_track_count(); + animation->add_track(Animation::TYPE_ROTATION_3D); + animation->track_set_path(rotation_idx, track_path); + animation->track_set_imported(rotation_idx, true); + } + + int scale_idx = -1; + if (pos_values.size()) { + scale_idx = animation->get_track_count(); + animation->add_track(Animation::TYPE_SCALE_3D); + animation->track_set_path(scale_idx, track_path); + animation->track_set_imported(scale_idx, true); + } + while (true) { Vector3 pos = def_pos; Quaternion rot = def_rot; @@ -1220,7 +1241,15 @@ Node3D *EditorSceneImporterFBX::_generate_scene( pos = t.origin; } - animation->transform_track_insert_key(track_idx, time, pos, rot, scale); + if (position_idx >= 0) { + animation->position_track_insert_key(position_idx, time, pos); + } + if (rotation_idx >= 0) { + animation->rotation_track_insert_key(rotation_idx, time, rot); + } + if (scale_idx >= 0) { + animation->scale_track_insert_key(scale_idx, time, scale); + } if (last) { break; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index ba98592600..32540e7a22 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -5733,7 +5733,7 @@ struct EditorSceneImporterGLTFInterpolate<Quaternion> { template <class T> T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) { ERR_FAIL_COND_V(!p_values.size(), T()); - if (p_times.size() != p_values.size()) { + if (p_times.size() != (p_values.size() / (p_interp == GLTFAnimation::INTERP_CUBIC_SPLINE ? 3 : 1))) { ERR_PRINT_ONCE("The interpolated values are not corresponding to its times."); return p_values[0]; } @@ -5868,9 +5868,67 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, const bool transform_affects_skinned_mesh_instance = gltf_node->skeleton < 0 && gltf_node->skin >= 0; if ((track.rotation_track.values.size() || track.position_track.values.size() || track.scale_track.values.size()) && !transform_affects_skinned_mesh_instance) { //make transform track - int track_idx = animation->get_track_count(); - animation->add_track(Animation::TYPE_TRANSFORM3D); - animation->track_set_path(track_idx, transform_node_path); + int base_idx = animation->get_track_count(); + int position_idx = -1; + int rotation_idx = -1; + int scale_idx = -1; + + if (track.position_track.values.size()) { + Vector3 base_pos = state->nodes[track_i.key]->position; + bool not_default = false; //discard the track if all it contains is default values + for (int i = 0; i < track.position_track.times.size(); i++) { + Vector3 value = track.position_track.values[track.position_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i]; + if (!value.is_equal_approx(base_pos)) { + not_default = true; + break; + } + } + if (not_default) { + position_idx = base_idx; + animation->add_track(Animation::TYPE_POSITION_3D); + animation->track_set_path(position_idx, transform_node_path); + animation->track_set_imported(position_idx, true); //helps merging later + + base_idx++; + } + } + if (track.rotation_track.values.size()) { + Quaternion base_rot = state->nodes[track_i.key]->rotation.normalized(); + bool not_default = false; //discard the track if all it contains is default values + for (int i = 0; i < track.rotation_track.times.size(); i++) { + Quaternion value = track.rotation_track.values[track.rotation_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i].normalized(); + if (!value.is_equal_approx(base_rot)) { + not_default = true; + break; + } + } + if (not_default) { + rotation_idx = base_idx; + animation->add_track(Animation::TYPE_ROTATION_3D); + animation->track_set_path(rotation_idx, transform_node_path); + animation->track_set_imported(rotation_idx, true); //helps merging later + base_idx++; + } + } + if (track.scale_track.values.size()) { + Vector3 base_scale = state->nodes[track_i.key]->scale; + bool not_default = false; //discard the track if all it contains is default values + for (int i = 0; i < track.scale_track.times.size(); i++) { + Vector3 value = track.scale_track.values[track.scale_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i]; + if (!value.is_equal_approx(base_scale)) { + not_default = true; + break; + } + } + if (not_default) { + scale_idx = base_idx; + animation->add_track(Animation::TYPE_SCALE_3D); + animation->track_set_path(scale_idx, transform_node_path); + animation->track_set_imported(scale_idx, true); //helps merging later + base_idx++; + } + } + //first determine animation length const double increment = 1.0 / bake_fps; @@ -5880,15 +5938,15 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, Quaternion base_rot; Vector3 base_scale = Vector3(1, 1, 1); - if (!track.rotation_track.values.size()) { + if (rotation_idx == -1) { base_rot = state->nodes[track_i.key]->rotation.normalized(); } - if (!track.position_track.values.size()) { + if (position_idx == -1) { base_pos = state->nodes[track_i.key]->position; } - if (!track.scale_track.values.size()) { + if (scale_idx == -1) { base_scale = state->nodes[track_i.key]->scale; } @@ -5898,15 +5956,15 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, Quaternion rot = base_rot; Vector3 scale = base_scale; - if (track.position_track.times.size()) { + if (position_idx >= 0) { pos = _interpolate_track<Vector3>(track.position_track.times, track.position_track.values, time, track.position_track.interpolation); } - if (track.rotation_track.times.size()) { + if (rotation_idx >= 0) { rot = _interpolate_track<Quaternion>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation); } - if (track.scale_track.times.size()) { + if (scale_idx >= 0) { scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation); } @@ -5925,7 +5983,15 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, pos = xform.origin; } - animation->transform_track_insert_key(track_idx, time, pos, rot, scale); + if (position_idx >= 0) { + animation->position_track_insert_key(position_idx, time, pos); + } + if (rotation_idx >= 0) { + animation->rotation_track_insert_key(rotation_idx, time, rot); + } + if (scale_idx >= 0) { + animation->scale_track_insert_key(scale_idx, time, scale); + } if (last) { break; @@ -6146,6 +6212,10 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> state, Node *scene_roo } GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, Transform3D p_bone_rest, int32_t p_track_i, GLTFNodeIndex p_node_i) { +#ifndef _MSC_VER +#warning this needs to be redone +#endif +#if 0 Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i); GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; @@ -6164,6 +6234,8 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state for (int32_t key_i = 0; key_i < key_count; key_i++) { times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i); } + + if (track_type == Animation::TYPE_TRANSFORM3D) { p_track.position_track.times = times; p_track.position_track.interpolation = gltf_interpolation; @@ -6323,7 +6395,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state } } } - +#endif return p_track; } diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl index 22172d50e4..58523dc1f8 100644 --- a/modules/lightmapper_rd/lm_common_inc.glsl +++ b/modules/lightmapper_rd/lm_common_inc.glsl @@ -81,3 +81,7 @@ layout(set = 0, binding = 8) uniform texture2DArray albedo_tex; layout(set = 0, binding = 9) uniform texture2DArray emission_tex; layout(set = 0, binding = 10) uniform sampler linear_sampler; + +// Fragment action constants +const uint FA_NONE = 0; +const uint FA_SMOOTHEN_POSITION = 1; diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 25b334c5eb..6e5c9f25ba 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -148,7 +148,7 @@ uint trace_ray(vec3 p_from, vec3 p_to ivec3 icell = ivec3(from_cell); ivec3 iendcell = ivec3(to_cell); vec3 dir_cell = normalize(rel_cell); - vec3 delta = abs(1.0 / dir_cell); //vec3(length(rel_cell)) / rel_cell); + vec3 delta = min(abs(1.0 / dir_cell), params.grid_size); // use params.grid_size as max to prevent infinity values ivec3 step = ivec3(sign(rel_cell)); vec3 side = (sign(rel_cell) * (vec3(icell) - from_cell) + (sign(rel_cell) * 0.5) + 0.5) * delta; @@ -420,20 +420,22 @@ void main() { light = textureLod(sampler2DArray(source_light, linear_sampler), uvw, 0.0).rgb; active_rays += 1.0; - } else if (trace_result == RAY_MISS && params.env_transform[0][3] == 0.0) { // Use env_transform[0][3] to indicate when we are computing the first bounce - // Did not hit a triangle, reach out for the sky - vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir); + } else if (trace_result == RAY_MISS) { + if (params.env_transform[0][3] == 0.0) { // Use env_transform[0][3] to indicate when we are computing the first bounce + // Did not hit a triangle, reach out for the sky + vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir); - vec2 st = vec2( - atan(sky_dir.x, sky_dir.z), - acos(sky_dir.y)); + vec2 st = vec2( + atan(sky_dir.x, sky_dir.z), + acos(sky_dir.y)); - if (st.x < 0.0) - st.x += PI * 2.0; + if (st.x < 0.0) + st.x += PI * 2.0; - st /= vec2(PI * 2.0, PI); + st /= vec2(PI * 2.0, PI); - light = textureLod(sampler2D(environment, linear_sampler), st, 0.0).rgb; + light = textureLod(sampler2D(environment, linear_sampler), st, 0.0).rgb; + } active_rays += 1.0; } diff --git a/modules/lightmapper_rd/lm_raster.glsl b/modules/lightmapper_rd/lm_raster.glsl index 55ca193cc1..a86968a4f3 100644 --- a/modules/lightmapper_rd/lm_raster.glsl +++ b/modules/lightmapper_rd/lm_raster.glsl @@ -12,6 +12,7 @@ layout(location = 2) out vec2 uv_interp; layout(location = 3) out vec3 barycentric; layout(location = 4) flat out uvec3 vertex_indices; layout(location = 5) flat out vec3 face_normal; +layout(location = 6) flat out uint fragment_action; layout(push_constant, binding = 0, std430) uniform Params { vec2 atlas_size; @@ -49,6 +50,14 @@ void main() { face_normal = -normalize(cross((vertices.data[vertex_indices.x].position - vertices.data[vertex_indices.y].position), (vertices.data[vertex_indices.x].position - vertices.data[vertex_indices.z].position))); + { + const float FLAT_THRESHOLD = 0.99; + const vec3 norm_a = vec3(vertices.data[vertex_indices.x].normal_xy, vertices.data[vertex_indices.x].normal_z); + const vec3 norm_b = vec3(vertices.data[vertex_indices.y].normal_xy, vertices.data[vertex_indices.y].normal_z); + const vec3 norm_c = vec3(vertices.data[vertex_indices.z].normal_xy, vertices.data[vertex_indices.z].normal_z); + fragment_action = (dot(norm_a, norm_b) < FLAT_THRESHOLD || dot(norm_a, norm_c) < FLAT_THRESHOLD || dot(norm_b, norm_c) < FLAT_THRESHOLD) ? FA_SMOOTHEN_POSITION : FA_NONE; + } + gl_Position = vec4((uv_interp + params.uv_offset) * 2.0 - 1.0, 0.0001, 1.0); } @@ -78,6 +87,7 @@ layout(location = 2) in vec2 uv_interp; layout(location = 3) in vec3 barycentric; layout(location = 4) in flat uvec3 vertex_indices; layout(location = 5) in flat vec3 face_normal; +layout(location = 6) in flat uint fragment_action; layout(location = 0) out vec4 position; layout(location = 1) out vec4 normal; @@ -86,7 +96,7 @@ layout(location = 2) out vec4 unocclude; void main() { vec3 vertex_pos = vertex_interp; - { + if (fragment_action == FA_SMOOTHEN_POSITION) { // smooth out vertex position by interpolating its projection in the 3 normal planes (normal plane is created by vertex pos and normal) // because we don't want to interpolate inwards, normals found pointing inwards are pushed out. vec3 pos_a = vertices.data[vertex_indices.x].position; |