Closed fire closed 2 years ago
My plan for that currently is to cache a copy of the vertex array and the current blend shape values within the QuadMesh that would only get updated by blendshapes and used by skinning. I wrote something like that some time ago in gdscript and it worked quite well for me to when a blendshape value changes unapply the last one and then apply the new one after. Don't know if that's a good solution though.
Added like that in fcbe43bb2a3b19cb093b17d8eb525768eb21e612
There's still some things missing though. A big problem is reloading the scene won't load in the values again (they do get saved, maybe I'm just missing a function).
It's normal that values on the mesh that aren't in an animation is lost.
That glb crashes.
AnimatedMorphCube.zip
That glb crashes. AnimatedMorphCube.zip
Not a blend shape issue, forgot to handle meshes without uv's (uv array is null)
Blend shape animation failure with test cases. The plate is normal. Subdiv 2.
Appearance of a working import. (ignore the plate)
Thanks for giving some examples! Animations are likely not working because animation player differentiates between blend shape tracks and non blend shape tracks.
One can fix this by calling a simple script that creates value tracks for all BlendShape tracks, I'll probably add this to the importer.
for animation_library_name in get_animation_library_list():
var anim_lib:AnimationLibrary=get_animation_library(animation_library_name)
for animation_name in anim_lib.get_animation_list():
var animation: Animation=anim_lib.get_animation(animation_name)
for track_idx in range(0, animation.get_track_count()):
if animation.track_get_type(track_idx)==Animation.TYPE_BLEND_SHAPE:
var fake_anim=animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(fake_anim, animation.track_get_path(track_idx))
for key_idx in range(0, animation.track_get_key_count(track_idx)):
var val=animation.track_get_key_value(track_idx, key_idx)
var time=animation.track_get_key_time(track_idx, key_idx)
var transition=animation.track_get_key_transition(track_idx, key_idx)
animation.track_insert_key(fake_anim, time, val, transition)
animation.track_swap(track_idx, fake_anim)
animation.remove_track(fake_anim)
The reason this is an issue is because blend shapes aren't actual blend shapes in this. If the set_blend_shape_value is overrideable (I don't think they are) this wouldn't be an issue..
I can propose set_blend_shape_value to be override able.
Are there any other requests?
Here are the two apis. https://docs.godotengine.org/en/latest/classes/class_meshinstance3d.html and https://docs.godotengine.org/en/latest/classes/class_importermeshinstance3d.html
MeshInstance3D | ImporterMeshInstance3D |
---|---|
set_mesh(value) | set_mesh(value) |
get_mesh() | get_mesh() |
set_skeleton_path(value) | set_skeleton_path(value) |
get_skeleton_path() | get_skeleton_path() |
set_skin(value) | set_skin(value) |
get_skin() | get_skin() |
void create_convex_collision ( bool clean=true, bool simplify=false ) | |
void create_debug_tangents ( ) | |
void create_multiple_convex_collisions ( ) | |
void create_trimesh_collision ( ) | |
int find_blend_shape_by_name ( StringName name ) | |
get_active_material ( int surface ) const | |
get_blend_shape_count ( ) const | |
get_blend_shape_value ( int blend_shape_idx ) const | |
get_surface_override_material ( int surface ) const | |
int get_surface_override_material_count ( ) const | |
void set_blend_shape_value ( int blend_shape_idx, float value ) | |
void set_surface_override_material ( int surface, Material material ) |
I can propose set_blend_shape_value to be override able.
Are there any other requests?
That'd be great! I think to make it work with AnimationPlayer BlendShape tracks the functions
find_blend_shape_by_name
and set_blend_shape_value
are necessary. The two getters for count and value would be nice but not really needed for this.
I have bound all the methods in MeshInstance3D, ImporterMeshInstance3D, and ImporterMesh. PR and proposal in a bit.
As far as I know they should already be exposed... will photo a photo
As far as I know they should already be exposed... will photo a photo
ah great you included "as virtual methods". They already are overridable the actual change would be to make them virtual to allow giving custom values to calls like this: https://github.com/godotengine/godot/blob/61644f1dbe5389ed02a13f0940b05699db645919/scene/animation/animation_player.cpp#L309 where the node gets casted to MeshInstance
can you reply in the proposal?
I think you got this to work.
I think you got this to work.
I was able to get blend shapes working as virtuals in https://github.com/tefusion/godot/commit/b7950af5171493dee483ec7780381f329e5d364a, but trying to get everything else working with MeshInstance3D was still too tedious with many workarounds everywhere to the point of giving up. To make it less tedious set_mesh would also need to be virtual, but then some internal stuff doesn't get set or the skeleton access etc.. For the first release to the asset lib of this SubdivMeshInstance3D will just be a GeometryInstance. We should probably add that quick converter script to the importer for animation tracks then. (The only loss of not inheriting from MeshInstance3D then is the EditorPlugin)
But yeah blend shapes mostly work now, I'll open another issue for the meshinstance extension in here and maybe keep a tracker of what would be needed there.
Design required.