Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BlendShapes #8

Closed
fire opened this issue Sep 5, 2022 · 18 comments
Closed

Add BlendShapes #8

fire opened this issue Sep 5, 2022 · 18 comments
Labels
enhancement New feature or request

Comments

@fire
Copy link
Contributor

fire commented Sep 5, 2022

Design required.

@tefusion
Copy link
Owner

tefusion commented Sep 5, 2022

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.

@tefusion tefusion added the enhancement New feature or request label Sep 5, 2022
@tefusion
Copy link
Owner

tefusion commented Sep 7, 2022

Added like that in fcbe43b

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).

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

It's normal that values on the mesh that aren't in an animation is lost.

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

That glb crashes.
AnimatedMorphCube.zip

@tefusion
Copy link
Owner

tefusion commented Sep 7, 2022

That glb crashes. AnimatedMorphCube.zip

Not a blend shape issue, forgot to handle meshes without uv's (uv array is null)

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

Blend shape animation failure with test cases. The plate is normal. Subdiv 2.

image

godot-subdiv_main.zip

Appearance of a working import. (ignore the plate)

image

@tefusion
Copy link
Owner

tefusion commented Sep 7, 2022

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..

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

I can propose set_blend_shape_value to be override able.

Are there any other requests?

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

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 )

@tefusion
Copy link
Owner

tefusion commented Sep 7, 2022

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.

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

I have bound all the methods in MeshInstance3D, ImporterMeshInstance3D, and ImporterMesh. PR and proposal in a bit.

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

As far as I know they should already be exposed... will photo a photo

@tefusion
Copy link
Owner

tefusion commented Sep 7, 2022

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

@fire
Copy link
Contributor Author

fire commented Sep 7, 2022

can you reply in the proposal?

@fire
Copy link
Contributor Author

fire commented Oct 1, 2022

I think you got this to work.

@tefusion
Copy link
Owner

tefusion commented Oct 1, 2022

I think you got this to work.

I was able to get blend shapes working as virtuals in tefusion/godot@b7950af, 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)

@tefusion
Copy link
Owner

tefusion commented Oct 2, 2022

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.

@tefusion tefusion closed this as completed Oct 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants