Add bake_fps for FBXDocument, GLTFDocument and both import-export.
This commit is contained in:
parent
b947c53ddc
commit
24f56008ac
13 changed files with 76 additions and 35 deletions
|
@ -80,6 +80,7 @@ Node *EditorSceneFormatImporterUFBX::import_scene(const String &p_path, uint32_t
|
||||||
state->set_import_as_skeleton_bones(true);
|
state->set_import_as_skeleton_bones(true);
|
||||||
}
|
}
|
||||||
p_flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
|
p_flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
|
||||||
|
state->set_bake_fps(p_options["animation/fps"]);
|
||||||
Error err = fbx->append_from_file(path, state, p_flags, p_path.get_base_dir());
|
Error err = fbx->append_from_file(path, state, p_flags, p_path.get_base_dir());
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
if (r_err) {
|
if (r_err) {
|
||||||
|
@ -87,7 +88,7 @@ Node *EditorSceneFormatImporterUFBX::import_scene(const String &p_path, uint32_t
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return fbx->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], false);
|
return fbx->generate_scene(state, state->get_bake_fps(), (bool)p_options["animation/trimming"], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant EditorSceneFormatImporterUFBX::get_option_visibility(const String &p_path, bool p_for_animation,
|
Variant EditorSceneFormatImporterUFBX::get_option_visibility(const String &p_path, bool p_for_animation,
|
||||||
|
|
|
@ -1381,6 +1381,10 @@ Error FBXDocument::_parse_animations(Ref<FBXState> p_state) {
|
||||||
additional_data["time_end"] = fbx_anim_stack->time_end;
|
additional_data["time_end"] = fbx_anim_stack->time_end;
|
||||||
animation->set_additional_data("GODOT_animation_time_begin_time_end", additional_data);
|
animation->set_additional_data("GODOT_animation_time_begin_time_end", additional_data);
|
||||||
ufbx_bake_opts opts = {};
|
ufbx_bake_opts opts = {};
|
||||||
|
opts.resample_rate = p_state->get_bake_fps();
|
||||||
|
opts.minimum_sample_rate = p_state->get_bake_fps();
|
||||||
|
opts.max_keyframe_segments = 1024;
|
||||||
|
|
||||||
ufbx_error error;
|
ufbx_error error;
|
||||||
ufbx_unique_ptr<ufbx_baked_anim> fbx_baked_anim{ ufbx_bake_anim(fbx_scene, fbx_anim_stack->anim, &opts, &error) };
|
ufbx_unique_ptr<ufbx_baked_anim> fbx_baked_anim{ ufbx_bake_anim(fbx_scene, fbx_anim_stack->anim, &opts, &error) };
|
||||||
if (!fbx_baked_anim) {
|
if (!fbx_baked_anim) {
|
||||||
|
@ -1759,7 +1763,7 @@ void FBXDocument::_generate_skeleton_bone_node(Ref<FBXState> p_state, const GLTF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXDocument::_import_animation(Ref<FBXState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks) {
|
void FBXDocument::_import_animation(Ref<FBXState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks) {
|
||||||
Ref<GLTFAnimation> anim = p_state->animations[p_index];
|
Ref<GLTFAnimation> anim = p_state->animations[p_index];
|
||||||
|
|
||||||
String anim_name = anim->get_name();
|
String anim_name = anim->get_name();
|
||||||
|
@ -1771,7 +1775,7 @@ void FBXDocument::_import_animation(Ref<FBXState> p_state, AnimationPlayer *p_an
|
||||||
Ref<Animation> animation;
|
Ref<Animation> animation;
|
||||||
animation.instantiate();
|
animation.instantiate();
|
||||||
animation->set_name(anim_name);
|
animation->set_name(anim_name);
|
||||||
animation->set_step(1.0 / p_bake_fps);
|
animation->set_step(1.0 / p_state->get_bake_fps());
|
||||||
|
|
||||||
if (anim->get_loop()) {
|
if (anim->get_loop()) {
|
||||||
animation->set_loop_mode(Animation::LOOP_LINEAR);
|
animation->set_loop_mode(Animation::LOOP_LINEAR);
|
||||||
|
@ -2118,6 +2122,7 @@ Node *FBXDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool
|
||||||
ERR_FAIL_COND_V(state.is_null(), nullptr);
|
ERR_FAIL_COND_V(state.is_null(), nullptr);
|
||||||
ERR_FAIL_NULL_V(state, nullptr);
|
ERR_FAIL_NULL_V(state, nullptr);
|
||||||
ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
|
ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
|
||||||
|
p_state->set_bake_fps(p_bake_fps);
|
||||||
GLTFNodeIndex fbx_root = state->root_nodes.write[0];
|
GLTFNodeIndex fbx_root = state->root_nodes.write[0];
|
||||||
Node *fbx_root_node = state->get_scene_node(fbx_root);
|
Node *fbx_root_node = state->get_scene_node(fbx_root);
|
||||||
Node *root = fbx_root_node;
|
Node *root = fbx_root_node;
|
||||||
|
@ -2131,7 +2136,7 @@ Node *FBXDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool
|
||||||
root->add_child(ap, true);
|
root->add_child(ap, true);
|
||||||
ap->set_owner(root);
|
ap->set_owner(root);
|
||||||
for (int i = 0; i < state->animations.size(); i++) {
|
for (int i = 0; i < state->animations.size(); i++) {
|
||||||
_import_animation(state, ap, i, p_bake_fps, p_trimming, p_remove_immutable_tracks);
|
_import_animation(state, ap, i, p_trimming, p_remove_immutable_tracks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ERR_FAIL_NULL_V(root, nullptr);
|
ERR_FAIL_NULL_V(root, nullptr);
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
void _generate_scene_node(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
void _generate_scene_node(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
||||||
void _generate_skeleton_bone_node(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
void _generate_skeleton_bone_node(Ref<FBXState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
||||||
void _import_animation(Ref<FBXState> p_state, AnimationPlayer *p_animation_player,
|
void _import_animation(Ref<FBXState> p_state, AnimationPlayer *p_animation_player,
|
||||||
const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks);
|
const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks);
|
||||||
Error _parse(Ref<FBXState> p_state, String p_path, Ref<FileAccess> p_file);
|
Error _parse(Ref<FBXState> p_state, String p_path, Ref<FileAccess> p_file);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
<param index="3" name="remove_immutable_tracks" type="bool" default="true" />
|
<param index="3" name="remove_immutable_tracks" type="bool" default="true" />
|
||||||
<description>
|
<description>
|
||||||
Takes a [GLTFState] object through the [param state] parameter and returns a Godot Engine scene node.
|
Takes a [GLTFState] object through the [param state] parameter and returns a Godot Engine scene node.
|
||||||
|
The [param bake_fps] parameter overrides the bake_fps in [param state].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="register_gltf_document_extension" qualifiers="static">
|
<method name="register_gltf_document_extension" qualifiers="static">
|
||||||
|
|
|
@ -275,6 +275,9 @@
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="bake_fps" type="float" setter="set_bake_fps" getter="get_bake_fps" default="30.0">
|
||||||
|
The baking fps of the animation for either import or export.
|
||||||
|
</member>
|
||||||
<member name="base_path" type="String" setter="set_base_path" getter="get_base_path" default="""">
|
<member name="base_path" type="String" setter="set_base_path" getter="get_base_path" default="""">
|
||||||
The folder path associated with this GLTF data. This is used to find other files the GLTF file references, like images or binary buffers. This will be set during import when appending from a file, and will be set during export when writing to a file.
|
The folder path associated with this GLTF data. This is used to find other files the GLTF file references, like images or binary buffers. This will be set during import when appending from a file, and will be set during export when writing to a file.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -107,6 +107,7 @@ void SceneExporterGLTFPlugin::_export_scene_as_gltf(const String &p_file_path) {
|
||||||
state->set_copyright(_export_settings->get_copyright());
|
state->set_copyright(_export_settings->get_copyright());
|
||||||
int32_t flags = 0;
|
int32_t flags = 0;
|
||||||
flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
|
flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
|
||||||
|
state->set_bake_fps(_export_settings->get_bake_fps());
|
||||||
Error err = _gltf_document->append_from_scene(root, state, flags);
|
Error err = _gltf_document->append_from_scene(root, state, flags);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err)));
|
ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err)));
|
||||||
|
|
|
@ -182,4 +182,16 @@ void EditorSceneExporterGLTFSettings::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_copyright"), &EditorSceneExporterGLTFSettings::get_copyright);
|
ClassDB::bind_method(D_METHOD("get_copyright"), &EditorSceneExporterGLTFSettings::get_copyright);
|
||||||
ClassDB::bind_method(D_METHOD("set_copyright", "copyright"), &EditorSceneExporterGLTFSettings::set_copyright);
|
ClassDB::bind_method(D_METHOD("set_copyright", "copyright"), &EditorSceneExporterGLTFSettings::set_copyright);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "copyright", PROPERTY_HINT_PLACEHOLDER_TEXT, "Example: 2014 Godette"), "set_copyright", "get_copyright");
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "copyright", PROPERTY_HINT_PLACEHOLDER_TEXT, "Example: 2014 Godette"), "set_copyright", "get_copyright");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_bake_fps"), &EditorSceneExporterGLTFSettings::get_bake_fps);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bake_fps", "bake_fps"), &EditorSceneExporterGLTFSettings::set_bake_fps);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_fps"), "set_bake_fps", "get_bake_fps");
|
||||||
|
}
|
||||||
|
|
||||||
|
double EditorSceneExporterGLTFSettings::get_bake_fps() const {
|
||||||
|
return _bake_fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSceneExporterGLTFSettings::set_bake_fps(const double p_bake_fps) {
|
||||||
|
_bake_fps = p_bake_fps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ class EditorSceneExporterGLTFSettings : public RefCounted {
|
||||||
HashMap<String, Ref<GLTFDocumentExtension>> _config_name_to_extension_map;
|
HashMap<String, Ref<GLTFDocumentExtension>> _config_name_to_extension_map;
|
||||||
|
|
||||||
String _copyright;
|
String _copyright;
|
||||||
|
double _bake_fps = 30.0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -58,6 +59,9 @@ public:
|
||||||
|
|
||||||
String get_copyright() const;
|
String get_copyright() const;
|
||||||
void set_copyright(const String &p_copyright);
|
void set_copyright(const String &p_copyright);
|
||||||
|
|
||||||
|
double get_bake_fps() const;
|
||||||
|
void set_bake_fps(const double p_bake_fps);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TOOLS_ENABLED
|
#endif // TOOLS_ENABLED
|
||||||
|
|
|
@ -62,6 +62,7 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
|
||||||
if (p_options.has(SNAME("nodes/import_as_skeleton_bones")) ? (bool)p_options[SNAME("nodes/import_as_skeleton_bones")] : false) {
|
if (p_options.has(SNAME("nodes/import_as_skeleton_bones")) ? (bool)p_options[SNAME("nodes/import_as_skeleton_bones")] : false) {
|
||||||
state->set_import_as_skeleton_bones(true);
|
state->set_import_as_skeleton_bones(true);
|
||||||
}
|
}
|
||||||
|
state->set_bake_fps(p_options["animation/fps"]);
|
||||||
Error err = gltf->append_from_file(p_path, state, p_flags);
|
Error err = gltf->append_from_file(p_path, state, p_flags);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
if (r_err) {
|
if (r_err) {
|
||||||
|
@ -75,9 +76,9 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
|
||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
bool trimming = p_options.has("animation/trimming") ? (bool)p_options["animation/trimming"] : false;
|
bool trimming = p_options.has("animation/trimming") ? (bool)p_options["animation/trimming"] : false;
|
||||||
return gltf->generate_scene(state, (float)p_options["animation/fps"], trimming, false);
|
return gltf->generate_scene(state, state->get_bake_fps(), trimming, false);
|
||||||
#else
|
#else
|
||||||
return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], false);
|
return gltf->generate_scene(state, state->get_bake_fps(), (bool)p_options["animation/trimming"], false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4860,7 +4860,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> p_state) {
|
||||||
t["sampler"] = samplers.size();
|
t["sampler"] = samplers.size();
|
||||||
Dictionary s;
|
Dictionary s;
|
||||||
Vector<real_t> times;
|
Vector<real_t> times;
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
{
|
{
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
|
@ -5902,7 +5902,8 @@ T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T
|
||||||
ERR_FAIL_V(p_values[0]);
|
ERR_FAIL_V(p_values[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks) {
|
void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks) {
|
||||||
|
ERR_FAIL_COND(p_state.is_null());
|
||||||
Ref<GLTFAnimation> anim = p_state->animations[p_index];
|
Ref<GLTFAnimation> anim = p_state->animations[p_index];
|
||||||
|
|
||||||
String anim_name = anim->get_name();
|
String anim_name = anim->get_name();
|
||||||
|
@ -5914,7 +5915,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_
|
||||||
Ref<Animation> animation;
|
Ref<Animation> animation;
|
||||||
animation.instantiate();
|
animation.instantiate();
|
||||||
animation->set_name(anim_name);
|
animation->set_name(anim_name);
|
||||||
animation->set_step(1.0 / p_bake_fps);
|
animation->set_step(1.0 / p_state->get_bake_fps());
|
||||||
|
|
||||||
if (anim->get_loop()) {
|
if (anim->get_loop()) {
|
||||||
animation->set_loop_mode(Animation::LOOP_LINEAR);
|
animation->set_loop_mode(Animation::LOOP_LINEAR);
|
||||||
|
@ -6081,7 +6082,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const double increment = 1.0 / p_bake_fps;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = anim_start;
|
double time = anim_start;
|
||||||
|
|
||||||
Vector3 base_pos;
|
Vector3 base_pos;
|
||||||
|
@ -6158,7 +6159,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / p_bake_fps;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6372,7 +6373,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
p_track.scale_track.times.clear();
|
p_track.scale_track.times.clear();
|
||||||
p_track.scale_track.values.clear();
|
p_track.scale_track.values.clear();
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6407,7 +6408,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
p_track.position_track.times.clear();
|
p_track.position_track.times.clear();
|
||||||
p_track.position_track.values.clear();
|
p_track.position_track.values.clear();
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6442,7 +6443,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
p_track.rotation_track.times.clear();
|
p_track.rotation_track.times.clear();
|
||||||
p_track.rotation_track.values.clear();
|
p_track.rotation_track.values.clear();
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6482,7 +6483,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
p_track.position_track.times.clear();
|
p_track.position_track.times.clear();
|
||||||
p_track.position_track.values.clear();
|
p_track.position_track.values.clear();
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6515,7 +6516,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
p_track.rotation_track.times.clear();
|
p_track.rotation_track.times.clear();
|
||||||
p_track.rotation_track.values.clear();
|
p_track.rotation_track.values.clear();
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6551,7 +6552,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
p_track.scale_track.times.clear();
|
p_track.scale_track.times.clear();
|
||||||
p_track.scale_track.values.clear();
|
p_track.scale_track.values.clear();
|
||||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||||
const double increment = 1.0 / BAKE_FPS;
|
const double increment = 1.0 / p_state->get_bake_fps();
|
||||||
double time = 0.0;
|
double time = 0.0;
|
||||||
bool last = false;
|
bool last = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -6577,14 +6578,14 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (track_type == Animation::TYPE_BEZIER) {
|
} else if (track_type == Animation::TYPE_BEZIER) {
|
||||||
const int32_t keys = anim_end * BAKE_FPS;
|
const int32_t keys = anim_end * p_state->get_bake_fps();
|
||||||
if (path.contains(":scale")) {
|
if (path.contains(":scale")) {
|
||||||
if (!p_track.scale_track.times.size()) {
|
if (!p_track.scale_track.times.size()) {
|
||||||
p_track.scale_track.interpolation = gltf_interpolation;
|
p_track.scale_track.interpolation = gltf_interpolation;
|
||||||
Vector<real_t> new_times;
|
Vector<real_t> new_times;
|
||||||
new_times.resize(keys);
|
new_times.resize(keys);
|
||||||
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
||||||
new_times.write[key_i] = key_i / BAKE_FPS;
|
new_times.write[key_i] = key_i / p_state->get_bake_fps();
|
||||||
}
|
}
|
||||||
p_track.scale_track.times = new_times;
|
p_track.scale_track.times = new_times;
|
||||||
|
|
||||||
|
@ -6597,11 +6598,11 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
||||||
Vector3 bezier_track = p_track.scale_track.values[key_i];
|
Vector3 bezier_track = p_track.scale_track.values[key_i];
|
||||||
if (path.contains(":scale:x")) {
|
if (path.contains(":scale:x")) {
|
||||||
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":scale:y")) {
|
} else if (path.contains(":scale:y")) {
|
||||||
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":scale:z")) {
|
} else if (path.contains(":scale:z")) {
|
||||||
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
}
|
}
|
||||||
p_track.scale_track.values.write[key_i] = bezier_track;
|
p_track.scale_track.values.write[key_i] = bezier_track;
|
||||||
}
|
}
|
||||||
|
@ -6612,7 +6613,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
Vector<real_t> new_times;
|
Vector<real_t> new_times;
|
||||||
new_times.resize(keys);
|
new_times.resize(keys);
|
||||||
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
||||||
new_times.write[key_i] = key_i / BAKE_FPS;
|
new_times.write[key_i] = key_i / p_state->get_bake_fps();
|
||||||
}
|
}
|
||||||
p_track.position_track.times = new_times;
|
p_track.position_track.times = new_times;
|
||||||
|
|
||||||
|
@ -6622,11 +6623,11 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
||||||
Vector3 bezier_track = p_track.position_track.values[key_i];
|
Vector3 bezier_track = p_track.position_track.values[key_i];
|
||||||
if (path.contains(":position:x")) {
|
if (path.contains(":position:x")) {
|
||||||
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":position:y")) {
|
} else if (path.contains(":position:y")) {
|
||||||
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":position:z")) {
|
} else if (path.contains(":position:z")) {
|
||||||
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
}
|
}
|
||||||
p_track.position_track.values.write[key_i] = bezier_track;
|
p_track.position_track.values.write[key_i] = bezier_track;
|
||||||
}
|
}
|
||||||
|
@ -6636,7 +6637,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
Vector<real_t> new_times;
|
Vector<real_t> new_times;
|
||||||
new_times.resize(keys);
|
new_times.resize(keys);
|
||||||
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
||||||
new_times.write[key_i] = key_i / BAKE_FPS;
|
new_times.write[key_i] = key_i / p_state->get_bake_fps();
|
||||||
}
|
}
|
||||||
p_track.rotation_track.times = new_times;
|
p_track.rotation_track.times = new_times;
|
||||||
|
|
||||||
|
@ -6645,13 +6646,13 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> p_sta
|
||||||
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
for (int32_t key_i = 0; key_i < keys; key_i++) {
|
||||||
Quaternion bezier_track = p_track.rotation_track.values[key_i];
|
Quaternion bezier_track = p_track.rotation_track.values[key_i];
|
||||||
if (path.contains(":rotation:x")) {
|
if (path.contains(":rotation:x")) {
|
||||||
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":rotation:y")) {
|
} else if (path.contains(":rotation:y")) {
|
||||||
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":rotation:z")) {
|
} else if (path.contains(":rotation:z")) {
|
||||||
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
} else if (path.contains(":rotation:w")) {
|
} else if (path.contains(":rotation:w")) {
|
||||||
bezier_track.w = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
|
bezier_track.w = p_animation->bezier_track_interpolate(p_track_i, key_i / p_state->get_bake_fps());
|
||||||
}
|
}
|
||||||
p_track.rotation_track.values.write[key_i] = bezier_track;
|
p_track.rotation_track.values.write[key_i] = bezier_track;
|
||||||
}
|
}
|
||||||
|
@ -7305,6 +7306,7 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, boo
|
||||||
ERR_FAIL_NULL_V(state, nullptr);
|
ERR_FAIL_NULL_V(state, nullptr);
|
||||||
ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
|
ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
|
||||||
Error err = OK;
|
Error err = OK;
|
||||||
|
p_state->set_bake_fps(p_bake_fps);
|
||||||
Node *root = _generate_scene_node_tree(state);
|
Node *root = _generate_scene_node_tree(state);
|
||||||
ERR_FAIL_NULL_V(root, nullptr);
|
ERR_FAIL_NULL_V(root, nullptr);
|
||||||
_process_mesh_instances(state, root);
|
_process_mesh_instances(state, root);
|
||||||
|
@ -7313,7 +7315,7 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, boo
|
||||||
root->add_child(ap, true);
|
root->add_child(ap, true);
|
||||||
ap->set_owner(root);
|
ap->set_owner(root);
|
||||||
for (int i = 0; i < state->animations.size(); i++) {
|
for (int i = 0; i < state->animations.size(); i++) {
|
||||||
_import_animation(state, ap, i, p_bake_fps, p_trimming, p_remove_immutable_tracks);
|
_import_animation(state, ap, i, p_trimming, p_remove_immutable_tracks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (KeyValue<GLTFNodeIndex, Node *> E : state->scene_nodes) {
|
for (KeyValue<GLTFNodeIndex, Node *> E : state->scene_nodes) {
|
||||||
|
|
|
@ -75,7 +75,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const float BAKE_FPS = 30.0f;
|
|
||||||
int _naming_version = 1;
|
int _naming_version = 1;
|
||||||
String _image_format = "PNG";
|
String _image_format = "PNG";
|
||||||
float _lossy_quality = 0.75f;
|
float _lossy_quality = 0.75f;
|
||||||
|
@ -328,7 +327,7 @@ public:
|
||||||
void _generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
void _generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
||||||
void _generate_skeleton_bone_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
void _generate_skeleton_bone_node(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index, Node *p_scene_parent, Node *p_scene_root);
|
||||||
void _import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player,
|
void _import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player,
|
||||||
const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks);
|
const GLTFAnimationIndex p_index, const bool p_trimming, const bool p_remove_immutable_tracks);
|
||||||
void _convert_mesh_instances(Ref<GLTFState> p_state);
|
void _convert_mesh_instances(Ref<GLTFState> p_state);
|
||||||
GLTFCameraIndex _convert_camera(Ref<GLTFState> p_state, Camera3D *p_camera);
|
GLTFCameraIndex _convert_camera(Ref<GLTFState> p_state, Camera3D *p_camera);
|
||||||
void _convert_light_to_gltf(Light3D *p_light, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node);
|
void _convert_light_to_gltf(Light3D *p_light, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node);
|
||||||
|
|
|
@ -100,6 +100,8 @@ void GLTFState::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_additional_data", "extension_name", "additional_data"), &GLTFState::set_additional_data);
|
ClassDB::bind_method(D_METHOD("set_additional_data", "extension_name", "additional_data"), &GLTFState::set_additional_data);
|
||||||
ClassDB::bind_method(D_METHOD("get_handle_binary_image"), &GLTFState::get_handle_binary_image);
|
ClassDB::bind_method(D_METHOD("get_handle_binary_image"), &GLTFState::get_handle_binary_image);
|
||||||
ClassDB::bind_method(D_METHOD("set_handle_binary_image", "method"), &GLTFState::set_handle_binary_image);
|
ClassDB::bind_method(D_METHOD("set_handle_binary_image", "method"), &GLTFState::set_handle_binary_image);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bake_fps", "value"), &GLTFState::set_bake_fps);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_bake_fps"), &GLTFState::get_bake_fps);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "json"), "set_json", "get_json"); // Dictionary
|
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "json"), "set_json", "get_json"); // Dictionary
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "major_version"), "set_major_version", "get_major_version"); // int
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "major_version"), "set_major_version", "get_major_version"); // int
|
||||||
|
@ -130,6 +132,7 @@ void GLTFState::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "import_as_skeleton_bones"), "set_import_as_skeleton_bones", "get_import_as_skeleton_bones"); // bool
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "import_as_skeleton_bones"), "set_import_as_skeleton_bones", "get_import_as_skeleton_bones"); // bool
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>>
|
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>>
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "handle_binary_image", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed as Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_handle_binary_image", "get_handle_binary_image"); // enum
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "handle_binary_image", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed as Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_handle_binary_image", "get_handle_binary_image"); // enum
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_fps"), "set_bake_fps", "get_bake_fps");
|
||||||
|
|
||||||
BIND_CONSTANT(HANDLE_BINARY_DISCARD_TEXTURES);
|
BIND_CONSTANT(HANDLE_BINARY_DISCARD_TEXTURES);
|
||||||
BIND_CONSTANT(HANDLE_BINARY_EXTRACT_TEXTURES);
|
BIND_CONSTANT(HANDLE_BINARY_EXTRACT_TEXTURES);
|
||||||
|
|
|
@ -57,6 +57,7 @@ protected:
|
||||||
int minor_version = 0;
|
int minor_version = 0;
|
||||||
String copyright;
|
String copyright;
|
||||||
Vector<uint8_t> glb_data;
|
Vector<uint8_t> glb_data;
|
||||||
|
double bake_fps = 30.0;
|
||||||
|
|
||||||
bool use_named_skin_binds = false;
|
bool use_named_skin_binds = false;
|
||||||
bool use_khr_texture_transform = false;
|
bool use_khr_texture_transform = false;
|
||||||
|
@ -108,6 +109,14 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
double get_bake_fps() const {
|
||||||
|
return bake_fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_bake_fps(double value) {
|
||||||
|
bake_fps = value;
|
||||||
|
}
|
||||||
|
|
||||||
void add_used_extension(const String &p_extension, bool p_required = false);
|
void add_used_extension(const String &p_extension, bool p_required = false);
|
||||||
GLTFBufferViewIndex append_data_to_buffers(const Vector<uint8_t> &p_data, const bool p_deduplication);
|
GLTFBufferViewIndex append_data_to_buffers(const Vector<uint8_t> &p_data, const bool p_deduplication);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue