ksons / gltf-blender-importer

Blender glTF 2.0 Importer
MIT License
214 stars 36 forks source link

Better material view, better world-space positions, lights #36

Closed scurest closed 5 years ago

scurest commented 6 years ago

Before/after for this PR

before

Materials

Materials now use the correct alpha mode in the Material view.

World-space Positions

There are several changes intended to make world-space positions closer to being correct.

First, pursuant to https://github.com/KhronosGroup/glTF/issues/1270, if a skin doesn't specify a skeleton property, we insert an armature for it at the lowest common ancestor of its joints. If the joints belong to different trees, the armature gets inserted joining together the roots. I've assumed, without justification from the spec AFAICT, that if a skeleton property is specified, it's going to be a (possibly improper) ancestor of the joints and we still insert the armature there is that case.

Second, objects which are the children of bones are, I believe, now positioned correctly. These are the ones that were previously marked with a [!!] by 7688ae2b so users would know they were wrong.

Third, I've thought more carefully about bone rotations and how they interact with everything. There is a long comment in vforest.py about them. For one thing, I noticed that in order to get them to work we can't have an arbitrary rotation, it has to be (up to sign) a permutation of the basis vectors. Since the direction of the bone is determined by the direction of the +Y axis, any rotation which carries the +Y axis into the desired axis should be equally good, so we only need to decide which axis is desired. There are three options for the user for picking the axis:

Note that in all cases every bone gets the same rotation, but the code could handle per-bone rotations if we ever want it to.

The following things cause world space positions to still be wrong:

Vforest creation has become somewhat complex so I moved it out into its own file. I tried to restructure it as a series of passes that gradually change the original glTF tree into the Blender tree.

scurest commented 6 years ago

I pushed some more changes. We can now handle scales on bones as long as they are homogeneous (ie. are just scalar multiplication) :sparkles: :sparkles: The way this works is that I assumed by fiat that the scaling in the coordinate changes commute with rotations. This is, of course, true for homogeneous scalings, but isn't true in general. But this assumption, together with restricting bone rotations to being (up to sign) a permutation of the basis vectors makes all the algebra come out really nicely; the resulting local-to-parent matrices are TR and the animation curves don't have to be resampled. Please see the long comment in vforest.py for a more detailed description.

Honestly, I'm really happy with this solution, especially since I'm not even sure supporting more general scalings is even possible. I think it strikes the right balance between supporting more glTF files and simplicity of implementation. Anything more complicated than this (I toyed with interchanging rotations and scalings by approximating a solution r', s' to Scale[s] Rot[r] = Rot[r'] Scale[s'] for example) is almost certain to lose the property that a pose's new translation depends only on its old translation (and not the old rotation or scaling), etc., and losing this would force us to resample the animation curves. Blender doesn't even support non-unit scalings on bones, so supporting homogeneous scalings is already pretty good, and if people need support for non-homogeneous scalings they should import into a DCC program that actually supports that!

Bone rotations are no longer chosen by a vote. We just choose them locally. This lets us adjust bones in a single pass. The user interface is still the same as I described above and the user can still select a constant rotation over all the bones if they want. Bone lengths may be slightly nicer in some cases now too.

If eg. Monster is made into single Armature, it will now animate correctly (previously it wouldn't because the skin's root node has a non-unit scaling). It also improves a few other models I've been trying.


I also have an implementation of KHR_lights_punctual that is merged in. Its based on the implementation of KHR_lights done by @cinghiale and @giorgiomarcias back in... April? ^^; Cf #22. I listed all the extensions we support in the readme now too.

(It was kind of hard to keep it in a separate branch since creating lights is bound up with the vforest/scene stuff.)

scurest commented 6 years ago

Automatic bone placement has been improved a bit. The hip bone in the first before/after picture is better

wolfie

I also fixed a bug where I picked the wrong rotation for bones that had negative scaling. For example, this model had a scaling of (-1,-1,-1) on the right shoulder. Notice that the bones were backwards in the before picture.

before

scurest commented 6 years ago

@ksons You there? I think the importer's come a pretty long way. I was hoping you could get these PRs merged and make a 0.4 release.