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

Godot 4 breaks animated 3d models (Godot 3 to 4 conversion issue) #76644

Open
Zireael07 opened this issue May 1, 2023 · 15 comments
Open

Godot 4 breaks animated 3d models (Godot 3 to 4 conversion issue) #76644

Zireael07 opened this issue May 1, 2023 · 15 comments

Comments

@Zireael07
Copy link
Contributor

Godot version

4.0.2

System information

Linux Manjaro, Intel Kaby Lake

Issue description

Just open the attached project. It's a free CC-licensed minimal project that was advertised as, and indeed, working in 3.x.

For comparison's sake, a glb reexport of the character is also included. This one at least animates properly, but I haven't been able to get bone attachments and physical bones to work.

Steps to reproduce

See above

Minimal reproduction project

modeltest.zip

@Zireael07
Copy link
Contributor Author

Still the case in 4.2.

I have an entire project that relies on this model in escn, and on bone attachments/physical bones. How do I unbreak that?

@Zireael07
Copy link
Contributor Author

Tried nuking all the changes in Git (which brings the project in discussion back to 3.x), and re-upgrading. Same effect, the model is broken in exactly the same way.

@fire
Copy link
Member

fire commented Dec 13, 2023

See detailed discussion on glb and lods on animated meshes. #84479

@Zireael07
Copy link
Contributor Author

Note that GLB works (more or less, requires redoing all the attachments), it's the ESCN that doesn't.

@nikitalita
Copy link
Contributor

This is due to Godot 4.x not having a compatibility layer for loading the old 3.x Skeleton and Animation resources (see #53689 for details):

  • Skeletons had a Transform pose property in 3.x, which was broken out to Vector3 pose_position; Quaternion pose_rotation; Vector3 pose_scalein 4.x
  • Animations used to have a transform track type, which was similarly broken out into position_3d, rotation_3d, and scale types

It wouldn't be too much effort to implement a compatibility layer here, and we already have a compatibility layer for the old 3.x Mesh format.

@nikitalita
Copy link
Contributor

Skeleton pose conversion is easy enough to handle in _set():
image

Animations are going to be tricky, though; Animation tracks are stored ini style:

image

This means that, upon load, each of those indexed properties gets set, one at a time, which complicates things. We need to split the transformation track up into position, rotation, and scale tracks, and we can't arbitrarily add tracks in the middle of a load, since the index of the tracks will change. I'm not really sure how to handle this.

@nikitalita
Copy link
Contributor

I have a WIP Solution up here: https://github.com/nikitalita/godot/tree/convert-escn

This converts all the animations, skeletons, and shaders into the new format.

Unfortunately, while all the resources in the escn load without errors now, the result comes out looking like this:
image

Trying to play any of the animations makes it look like this:
image

Banged my head against the wall for several hours trying to figure out why; no dice.

@fire , could you kindly take a look at this on my branch? I'm testing this with the repro project in the OP.

@fire
Copy link
Member

fire commented Dec 20, 2023

Here's some notes from https://chat.godotengine.org about godot 3 to godot 4.

October 12, 2023
[aaronfranke]
aaronfranke7:17 PM

In Godot's Skeleton3D node, the value passed into set_bone_pose_rotation that results in an unposed bone is the bone's rest rotation. This goes contrary to my expectations, because I would expect to be able to pass a value of no rotation into set_bone_pose_rotation in order to have the bone be in the rest position, such that the bone's actual rotation is rest * pose. This is how it works in Blender. Same with set_bone_pose_position and set_bone_pose_scale. Is this a known issue? Is there a plan to change this behavior in the next compatibility breakage?

[Lyuma]
Lyuma11:06 PM
aaronfranke you have pointed out the one key difference between Godot 3 and Godot 4 😉

[Lyuma]
Lyuma11:14 PM
I can give a lot of reasons why the new Godot 4 behavior is more desirable:

First, while the user experience of being able to pass Quaternion(0,0,0,1) to reset the rotation to rest was really pleasant., it created a lot of extra math internally to the skeleton: every time a pose was evaluated, it was required to also multiply the rest pose matrices at each step, so this added more code and more CPU overhead.

Not all meshes have a rest pose. In particular, animation skeletons imported from Maya for example might not have a defined rest pose, or the rest poses of each bone might be identity. This disparity might be confusing to users. This point is less of an issue due to point (3) but I still agree with the principle that the rest pose should be merely advisory, not required for the math to work.

The import retargeter has created a standard skeleton with a frame of reference for all human bones which can be relied on. If I set %GeneralSkeleton:LeftUpperArm rotation to Quaternion(0.707, 0, 0.707, 0), it will behave the same on every mesh imported with the retargeter. Multiplying in the rest rotation would not assist at all in the understanding of the meaning of a particular pose.

Godot 4 separated the bone pose into separate position, rotation and scale components. While position (and possibly scale) of individual bones may differ between humanoid armatures, the rotations are standardized, and the hips position values are actually also standardized when the skeleton scale is applied. So there is not the same danger that existed in Godot 3 of accidentally overwriting the rest position when assigning the bone pose.

Anyway that's my mini litany. I could go on, but I think the decision in Godot 4 to de-incorporate rest from bone pose was very sound and has made skeletons far easier to work with.

@Zireael07 Zireael07 changed the title Godot 4 breaks animated 3d models Godot 4 breaks animated 3d models (Godot 3 to 4 conversion issue) Dec 21, 2023
@nikitalita
Copy link
Contributor

@Zireael07 I now have it working; Your escn model imports fine and the animations play correctly now. Can you please test this to make sure that it works? https://github.com/nikitalita/godot/tree/convert-escn-2 (artifacts will show up here: https://github.com/nikitalita/godot/actions/runs/7304153146)

@fire
Copy link
Member

fire commented Dec 23, 2023

@nikitalita did you make a pr for this?

@nikitalita
Copy link
Contributor

I haven't made a PR yet because this involved changes to resource loading that probably won't be upstreamed in its current state. I had to add the ability to add special handlers for specific resource types to the loader, such that it forces the resource_format_text loader to load that resource as a MissingResource and then call the handler to instantiate the resource and set the properties.

@fire
Copy link
Member

fire commented Jan 23, 2024

#87050 was merged, can people check if this resolves?

@nikitalita
Copy link
Contributor

probably not, it doesn't fix the animations; I have to get #87106 into shape for merging for closing this

@Zireael07
Copy link
Contributor Author

@nikitalita I somehow missed that comment that @ - me, are the artifacts still available?

@nikitalita
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants