summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/fbx/data/fbx_skeleton.cpp7
-rw-r--r--modules/fbx/editor_scene_importer_fbx.cpp55
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp1
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out2
-rw-r--r--modules/gltf/gltf_document.cpp188
-rw-r--r--modules/gltf/gltf_document.h2
-rw-r--r--modules/lightmapper_rd/lm_common_inc.glsl4
-rw-r--r--modules/lightmapper_rd/lm_compute.glsl24
-rw-r--r--modules/lightmapper_rd/lm_raster.glsl12
-rw-r--r--modules/xatlas_unwrap/register_types.cpp2
11 files changed, 198 insertions, 109 deletions
diff --git a/modules/fbx/data/fbx_skeleton.cpp b/modules/fbx/data/fbx_skeleton.cpp
index 3dc163964c..11eed2576f 100644
--- a/modules/fbx/data/fbx_skeleton.cpp
+++ b/modules/fbx/data/fbx_skeleton.cpp
@@ -104,6 +104,13 @@ void FBXSkeleton::init_skeleton(const ImportState &state) {
print_verbose("working on bone: " + itos(bone_index) + " bone name:" + bone->bone_name);
skeleton->set_bone_rest(bone->godot_bone_id, get_unscaled_transform(bone->node->pivot_transform->LocalTransform, state.scale));
+ {
+ Transform3D base_xform = bone->node->pivot_transform->LocalTransform;
+
+ skeleton->set_bone_pose_position(bone_index, base_xform.origin);
+ skeleton->set_bone_pose_rotation(bone_index, base_xform.basis.get_rotation_quaternion());
+ skeleton->set_bone_pose_scale(bone_index, base_xform.basis.get_scale());
+ }
// lookup parent ID
if (bone->valid_parent && state.fbx_bone_map.has(bone->parent_bone_id)) {
diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp
index e4de204cf1..879f281292 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;
@@ -1206,21 +1227,15 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
AssetImportAnimation::INTERP_LINEAR);
}
- // node animations must also include pivots
- if (skeleton_bone >= 0) {
- Transform3D xform = Transform3D();
- xform.basis.set_quaternion_scale(rot, scale);
- xform.origin = pos;
- const Transform3D t = bone_rest.affine_inverse() * xform;
-
- // populate this again
- rot = t.basis.get_rotation_quaternion();
- rot.normalize();
- scale = t.basis.get_scale();
- pos = t.origin;
+ 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);
}
-
- animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
if (last) {
break;
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index a025a90b8c..6b57784b1c 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -470,6 +470,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
GDScriptParser::DataType container_type = resolve_datatype(p_type->container_type);
if (container_type.kind != GDScriptParser::DataType::VARIANT) {
+ container_type.is_meta_type = false;
result.set_container_element_type(container_type);
}
}
diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd
new file mode 100644
index 0000000000..9502f6e196
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.gd
@@ -0,0 +1,10 @@
+class Inner:
+ var prop = "Inner"
+
+
+var array: Array[Inner] = [Inner.new()]
+
+
+func test():
+ var element: Inner = array[0]
+ print(element.prop)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out
new file mode 100644
index 0000000000..8f250d2632
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_with_custom_class.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+Inner
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index ba98592600..11f30be5a4 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -4319,6 +4319,9 @@ Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) {
skeleton->add_bone(node->get_name());
skeleton->set_bone_rest(bone_index, node->xform);
+ skeleton->set_bone_pose_position(bone_index, node->position);
+ skeleton->set_bone_pose_rotation(bone_index, node->rotation.normalized());
+ skeleton->set_bone_pose_scale(bone_index, node->scale);
if (node->parent >= 0 && state->nodes[node->parent]->skeleton == skel_i) {
const int bone_parent = skeleton->find_bone(state->nodes[node->parent]->get_name());
@@ -5470,7 +5473,7 @@ void GLTFDocument::_convert_skeleton_to_gltf(Skeleton3D *p_skeleton3d, Ref<GLTFS
// Note that we cannot use _gen_unique_bone_name here, because glTF spec requires all node
// names to be unique regardless of whether or not they are used as joints.
joint_node->set_name(_gen_unique_name(state, skeleton->get_bone_name(bone_i)));
- Transform3D xform = skeleton->get_bone_rest(bone_i) * skeleton->get_bone_pose(bone_i);
+ Transform3D xform = skeleton->get_bone_pose(bone_i);
joint_node->scale = xform.basis.get_scale();
joint_node->rotation = xform.basis.get_rotation_quaternion();
joint_node->position = xform.origin;
@@ -5733,7 +5736,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 +5871,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 +5941,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,35 +5959,21 @@ 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);
+ animation->position_track_insert_key(position_idx, time, pos);
}
- 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);
+ animation->rotation_track_insert_key(rotation_idx, time, rot);
}
- 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);
+ animation->scale_track_insert_key(scale_idx, time, scale);
}
- if (gltf_node->skeleton >= 0) {
- Transform3D xform;
- xform.basis.set_quaternion_scale(rot, scale);
- xform.origin = pos;
-
- const Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton;
- const int bone_idx = skeleton->find_bone(gltf_node->get_name());
- xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform;
-
- rot = xform.basis.get_rotation_quaternion();
- rot.normalize();
- scale = xform.basis.get_scale();
- pos = xform.origin;
- }
-
- animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
-
if (last) {
break;
}
@@ -6042,7 +6089,7 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) {
} else {
if (skin.is_null()) {
// Note that gltf_skin_key should remain null, so these can share a reference.
- skin = skeleton->register_skin(nullptr)->get_skin();
+ skin = skeleton->create_skin_from_rest_transforms();
}
gltf_skin.instantiate();
gltf_skin->godot_skin = skin;
@@ -6145,7 +6192,7 @@ 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) {
+GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, int32_t p_track_i, GLTFNodeIndex p_node_i) {
Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i);
GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
@@ -6164,33 +6211,35 @@ 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;
- p_track.rotation_track.times = times;
- p_track.rotation_track.interpolation = gltf_interpolation;
+ if (track_type == Animation::TYPE_SCALE_3D) {
p_track.scale_track.times = times;
p_track.scale_track.interpolation = gltf_interpolation;
-
p_track.scale_track.values.resize(key_count);
- p_track.scale_track.interpolation = gltf_interpolation;
+ for (int32_t key_i = 0; key_i < key_count; key_i++) {
+ Vector3 scale;
+ Error err = p_animation->scale_track_get_key(p_track_i, key_i, &scale);
+ ERR_CONTINUE(err != OK);
+ p_track.scale_track.values.write[key_i] = scale;
+ }
+ } else if (track_type == Animation::TYPE_POSITION_3D) {
+ p_track.position_track.times = times;
p_track.position_track.values.resize(key_count);
p_track.position_track.interpolation = gltf_interpolation;
- p_track.rotation_track.values.resize(key_count);
- p_track.rotation_track.interpolation = gltf_interpolation;
for (int32_t key_i = 0; key_i < key_count; key_i++) {
Vector3 position;
+ Error err = p_animation->position_track_get_key(p_track_i, key_i, &position);
+ ERR_CONTINUE(err != OK);
+ p_track.position_track.values.write[key_i] = position;
+ }
+ } else if (track_type == Animation::TYPE_ROTATION_3D) {
+ p_track.rotation_track.times = times;
+ p_track.rotation_track.interpolation = gltf_interpolation;
+ p_track.rotation_track.values.resize(key_count);
+ for (int32_t key_i = 0; key_i < key_count; key_i++) {
Quaternion rotation;
- Vector3 scale;
- Error err = p_animation->transform_track_get_key(p_track_i, key_i, &position, &rotation, &scale);
+ Error err = p_animation->rotation_track_get_key(p_track_i, key_i, &rotation);
ERR_CONTINUE(err != OK);
- Transform3D xform;
- xform.basis.set_quaternion_scale(rotation, scale);
- xform.origin = position;
- xform = p_bone_rest * xform;
- p_track.position_track.values.write[key_i] = xform.get_origin();
- p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion();
- p_track.scale_track.values.write[key_i] = xform.basis.get_scale();
+ p_track.rotation_track.values.write[key_i] = rotation;
}
} else if (path.find(":transform") != -1) {
p_track.position_track.times = times;
@@ -6282,13 +6331,10 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
Vector3 bezier_track = p_track.scale_track.values[key_i];
if (path.find("/scale:x") != -1) {
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.x = p_bone_rest.affine_inverse().basis.get_scale().x * bezier_track.x;
} else if (path.find("/scale:y") != -1) {
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.y = p_bone_rest.affine_inverse().basis.get_scale().y * bezier_track.y;
} else if (path.find("/scale:z") != -1) {
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.z = p_bone_rest.affine_inverse().basis.get_scale().z * bezier_track.z;
}
p_track.scale_track.values.write[key_i] = bezier_track;
}
@@ -6311,19 +6357,15 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
Vector3 bezier_track = p_track.position_track.values[key_i];
if (path.find("/position:x") != -1) {
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.x = p_bone_rest.affine_inverse().origin.x * bezier_track.x;
} else if (path.find("/position:y") != -1) {
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.y = p_bone_rest.affine_inverse().origin.y * bezier_track.y;
} else if (path.find("/position:z") != -1) {
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.z = p_bone_rest.affine_inverse().origin.z * bezier_track.z;
}
p_track.position_track.values.write[key_i] = bezier_track;
}
}
}
-
return p_track;
}
@@ -6350,7 +6392,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (position_track_i) {
track = position_track_i->get();
}
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
+ track = _convert_animation_track(state, track, animation, track_i, node_index);
gltf_animation->get_tracks().insert(node_index, track);
}
}
@@ -6366,7 +6408,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (rotation_degree_track_i) {
track = rotation_degree_track_i->get();
}
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
+ track = _convert_animation_track(state, track, animation, track_i, node_index);
gltf_animation->get_tracks().insert(node_index, track);
}
}
@@ -6382,7 +6424,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (scale_track_i) {
track = scale_track_i->get();
}
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
+ track = _convert_animation_track(state, track, animation, track_i, node_index);
gltf_animation->get_tracks().insert(node_index, track);
}
}
@@ -6393,7 +6435,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
for (const KeyValue<GLTFNodeIndex, Node *> &transform_track_i : state->scene_nodes) {
if (transform_track_i.value == node) {
GLTFAnimation::Track track;
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, transform_track_i.key);
+ track = _convert_animation_track(state, track, animation, track_i, transform_track_i.key);
gltf_animation->get_tracks().insert(transform_track_i.key, track);
}
}
@@ -6470,7 +6512,6 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
Ref<GLTFSkeleton> skeleton_gltf = state->skeletons[skeleton_gltf_i];
int32_t bone = skeleton->find_bone(suffix);
ERR_CONTINUE(bone == -1);
- Transform3D xform = skeleton->get_bone_rest(bone);
if (!skeleton_gltf->godot_bone_node.has(bone)) {
continue;
}
@@ -6480,27 +6521,24 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (property_track_i) {
track = property_track_i->get();
}
- track = _convert_animation_track(state, track, animation, xform, track_i, node_i);
+ track = _convert_animation_track(state, track, animation, track_i, node_i);
gltf_animation->get_tracks()[node_i] = track;
}
}
} else if (String(orig_track_path).find(":") == -1) {
ERR_CONTINUE(!ap->get_parent());
- for (int32_t node_i = 0; node_i < ap->get_parent()->get_child_count(); node_i++) {
- const Node *child = ap->get_parent()->get_child(node_i);
- const Node *node = child->get_node_or_null(orig_track_path);
- for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) {
- if (scene_node_i.value == node) {
- GLTFNodeIndex node_index = scene_node_i.key;
- Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index);
- GLTFAnimation::Track track;
- if (node_track_i) {
- track = node_track_i->get();
- }
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
- gltf_animation->get_tracks().insert(node_index, track);
- break;
+ Node *godot_node = ap->get_parent()->get_node_or_null(orig_track_path);
+ for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) {
+ if (scene_node_i.value == godot_node) {
+ GLTFNodeIndex node_i = scene_node_i.key;
+ Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_i);
+ GLTFAnimation::Track track;
+ if (node_track_i) {
+ track = node_track_i->get();
}
+ track = _convert_animation_track(state, track, animation, track_i, node_i);
+ gltf_animation->get_tracks()[node_i] = track;
+ break;
}
}
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 7317c6a9a3..a1d82a4649 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -357,7 +357,7 @@ private:
String interpolation_to_string(const GLTFAnimation::Interpolation p_interp);
GLTFAnimation::Track _convert_animation_track(Ref<GLTFState> state,
GLTFAnimation::Track p_track,
- Ref<Animation> p_animation, Transform3D p_bone_rest,
+ Ref<Animation> p_animation,
int32_t p_track_i,
GLTFNodeIndex p_node_i);
Error _encode_buffer_bins(Ref<GLTFState> state, const String &p_path);
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;
diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp
index 8913ef1b65..58a6216b1e 100644
--- a/modules/xatlas_unwrap/register_types.cpp
+++ b/modules/xatlas_unwrap/register_types.cpp
@@ -114,7 +114,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
input_mesh.vertexPositionStride = sizeof(float) * 3;
input_mesh.vertexNormalData = p_normals;
input_mesh.vertexNormalStride = sizeof(uint32_t) * 3;
- input_mesh.vertexUvData = NULL;
+ input_mesh.vertexUvData = nullptr;
input_mesh.vertexUvStride = 0;
xatlas::ChartOptions chart_options;