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

Blender exporter skinned mesh fix #8412

Merged
merged 3 commits into from
Mar 19, 2016

Conversation

phfatmonkey
Copy link
Contributor

Fixes issue with skinned meshes being flipped 90 degrees on their sides.

  • Skinned meshes now work with hierarchies turned on and off

The transformations between the mesh and the bones were inconsistent. While static mesh verts were properly transformed, it didn't take into account the bone transformations, resulting in skinned meshes with undesirable deformations.

Notes

  • Skinned meshes must be exported when skinned mesh is currently in bind pose.
  • Must select 'Pose' from Skeletal Animations drop down in Exporter options. Currently 'Rest' doesn't work.

@repsac Please test future modifications with one of the marine Blender files included in #8410. Use examples/webgl_animation_skinning_blending.html. Thanks.

Related to issues #8317 and #8337

@mrdoob
Copy link
Owner

mrdoob commented Mar 18, 2016

Skinned meshes must be exported when skinned mesh is currently in bind pose.
Must select 'Pose' from Skeletal Animations drop down in Exporter options. Currently 'Rest' doesn't work.

Is there a way of adding a note about that in the exporter panel itself?

@phfatmonkey
Copy link
Contributor Author

I can leave a note in the exporter and then remove the 'Rest' option.

…k; Added tooltip note when hovering over dropdown to inform user that mesh must be in bind pose when exporting
@mrdoob
Copy link
Owner

mrdoob commented Mar 19, 2016

Yay!

mrdoob added a commit that referenced this pull request Mar 19, 2016
…sh-Fix

Blender exporter skinned mesh fix
@mrdoob mrdoob merged commit 5c7290a into mrdoob:dev Mar 19, 2016
@mrdoob
Copy link
Owner

mrdoob commented Mar 19, 2016

Thanks!

@mrdoob
Copy link
Owner

mrdoob commented Mar 19, 2016

@arturitu could you test this?

@arturitu
Copy link
Contributor

I just tried the marine Blender files included in #8410 with the new exporter and the last Blender (2.76b) and seems to works fine (but I'm not sure if there are any difference with the actual examples/webgl_animation_skinning_blending.html in the r76dev that works too).

Related: I tried to implement with my 'hero' dummy but I found my own problems using MultiMaterial, I removed to try this, but found other one with THREE.KeyframeTrack because my blend character exports some 'tracks' that I don't know how to remove.

"animations":[{ "tracks":[{ "keys":[], "type":"vector3", "name":"Hero.position" },{ "keys":[], "type":"vector3", "name":"Hero.scale" },{ "keys":[], "type":"quaternion", "name":"Hero.quaternion" }], "fps":24, "name":"default" }],

Surely is problem of how I made this blend character.

@arturitu
Copy link
Contributor

If I modify that part of json to...
"animations":[{ "tracks":[], "fps":24, "name":"default" }],
...and works fine with the new exporter: http://unboring.net/lab/8412/
(but I suppose is a problem of how I animated the character file)

@phfatmonkey
Copy link
Contributor Author

I saw that too, with some meshes. I think it's because you have an animation on the skinned mesh itself, i.e. not the armature. There's a method in there called animated_xform, and it tries to pull the tracks from the mesh and sometimes fails to find any. In THREE I was getting an error with some meshes but not all that I tried, but the model still loaded and displayed properly.

@arturitu To remove a track that you can't get rid of, go into the NLA Editor and unlock the track on the skinned mesh and then delete it. Save and reopen and the action should be gone. That may fix that error you were getting.

@arturitu
Copy link
Contributor

Works great, yesterday I made a hand model with 3 animations with Blender exported with the new addon to be controllers on a HTC Vive WebVR demo (I will upload the blend files to the cute cubes project repo today)

Demo of the hand working here > http://unboring.net/lab/hand_76dev/ (use the up,down,left arrow keys to play animations)

Thanks,

@AndrewRayCode
Copy link
Contributor

Bone animations are currently being clobbered on the dev version of the exporter.

Blender:

blender-clobber-1

Three:

blender-clobber-2

I reduced it down to only two bones to make the problem more visually obvious. When trying to debug it with multiple bones, it's easy to see something is wrong, but hard to tell what.

@phfatmonkey
Copy link
Contributor Author

@delvarworld Have you uploaded these .blend files somewhere so I can take a look at them?

@AndrewRayCode
Copy link
Contributor

@phfatmonkey here you go. Two named animations, "Idle" is the rest pose, "Walk" is the broken animation pictured above.
test-export.blend.zip

@tschw
Copy link
Contributor

tschw commented Apr 15, 2016

Maybe something collides with 9ae28c8 now, so the rotation happens twice...

@phfatmonkey
Copy link
Contributor Author

@delvarworld Here's my export. I think it looks right:

exported_leg_animation

A couple things I did:

  • The animation needs to be in the bind pose when exported. I just exported it while the 'Idle pose was the current one, since that's already in the bind pose. In the previous version I think the 'Rest' option was supposed to take care if that but it wasn't working so I removed that option until it gets sorted out.
  • Were you getting any console errors? I don't think we can have any keyframes or animations on skinned meshes, and I noticed there were a bunch of console errors because it was looking for animation on the skinned mesh that it couldn't find. This error showed up for me too after the exporter was changed to the new format (roughly r69 I think). To fix the errors you may need to go to the NLA Editor in Blender, unlock and delete all animations on any skinned meshes.

Outside of those two things I'm not sure what could be going on. You confirmed you're using the exporter on the latest dev branch and not the master, correct?

@AndrewRayCode
Copy link
Contributor

AndrewRayCode commented Apr 16, 2016

@phfatmonkey well it's comforting to know that under some alignment of the stars it works 😄 I will try to find the difference between your setup and mine.

What code are you using to animate the object? In my case it's:

const mesh = new THREE.SkinnedMesh(
    geometry,
    new THREE.MeshPhongMaterial()
);
mesh.material.skinning = true;
group.add( mesh );

const mixer = new THREE.AnimationMixer( mesh );
mixer.clipAction( mesh.geometry.animations[ 2 ] ).play();

A screenshot of your exporter settings would also be helpful, although I doubt the problem lies there.

@AndrewRayCode
Copy link
Contributor

Can you also upload the json file you exported so I can compare yours to mine? If you changed the blender file can you upload that as well?

Are any of these different?

  • Blender 2.77
  • Importer version 1.5.0 from Three dev source code (last commit ff054272d12d9dfa872cbce6a6d08ef7efaba38c shown by git log -- utils/exporters/blender/addons/io_three). As in clone this project, check out dev, copy that folder to Blender addons folder.
  • Three r75 (not dev build)
  • Did not modify the Blend file before exporting
  • Exported in object mode with the mesh selected
  • Exported on frame 1
  • In the "Dope Sheet" panel with "Action Editor" selected as the sub menu, with "Idle" being the selected animation
  • Exported with these settings:

settings

I tried going to the NLA Editor, unlocking the icons, selecting each sub track thing "Action Stash" and deleting it, saving Blender and restarting and verifying they're gone, then re-exporting. Same thing.

I've tried importing the marine JSON file from this page and it imports fine and the animation plays correctly.

I've been struggling trying to export a simple animation from Blender to ThreeJS for 4 days straight now. It's blocking the development of the rest of my game. I greatly appreciate your help here. I'm at my wit's end and don't know what else to test. I'm probably doing something wrong somewhere since the other model loads fine but I have no idea how to debug this toolchain.

@phfatmonkey
Copy link
Contributor Author

@delvarworld The only difference I see is I export the Scene and use the Object Loader. I also export the hierarchy but I don't think that matters. I think webgl_animation_skinning_blending.html would be a good example of how to use that.

Also, make sure you're using the latest version of three as well. @insominx fixed an issue recently that you'll also need to make sure skinned meshes work properly. The issue you were having may have been partly due to the Blender exporter and partly due to Three itself, but that should be fixed now.

@insominx
Copy link
Contributor

Right as @phfatmonkey said, it may no longer work with just the JsonLoader. Check out what BlendCharacter.js does on the dev branch:

var loader = new THREE.ObjectLoader();
loader.load( url, function( loadedObject ) {

    // The exporter does not currently allow exporting a skinned mesh by itself
    // so we must fish it out of the hierarchy it is embedded in (scene)
    loadedObject.traverse( function( object ) {

        if ( object instanceof THREE.SkinnedMesh ) {

            scope.skinnedMesh = object;

        }

    } );
...

@AndrewRayCode
Copy link
Contributor

Yup I finally got the simple animation to work after digging through BlendCharacter.js over the weekend. I'm going to try to tackle the complex animation file today. There's a lot of unspoken assumptions that will break this process. If you want rigged animations: You can't export a single selected mesh. You can't load it with the JSONLoader. You must check the hierarchy tab. You must load it with the ObjectLoader.

This is counter intuitive because the model being exported is JSON. If I didn't manually inspect the source code of BlendCharacter.js I wouldn't have seen the ObjectLoader, and even then it wouldn't have been obvious why the vanilla JSON loader won't work here. I suspect there are still some bugs in the toolchain, possibly around the JSON loader, possibly around the AnimationHelper class, possibly in the exporter. I will try to narrow down what causes issues.

Thanks for the help!

@insominx
Copy link
Contributor

You're totally right. The process is fragile. Before @phfatmonkey and I jumped in, there was no working process at all. So, one step at a time :)

@@ -374,7 +378,7 @@ def matrix(obj, options):
parent_inverted = obj.parent.matrix_world.inverted(mathutils.Matrix())
return parent_inverted * obj.matrix_world
else:
return AXIS_CONVERSION * obj.matrix_world
Copy link
Owner

@mrdoob mrdoob Apr 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, AXIS_CONVERSION is no longer used? Wouldn't this break everything else? Maybe this is why normals broke?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, we're not using AXIS_CONVERSION anymore. It was incorrectly converting the transform matrix on the skinned meshes--it worked ok on static meshes--so I removed it and the manually flipped the YZ axis as we did with an older version of the exporter.

However, I kept it in there because we may want to go back to that method. Do we want to keep using an axis conversion matrix to apply a transform at run-time? Is there an advantage to doing it this way instead of grabbing the individual vert/bone transforms? What was the thought process behind that method?

The normals were broken because I forgot to do the same fix that I did to the verts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, this yz flip was fixed for normals in #8647

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the thought process behind that method?

Unfortunately, the guy that wrote that code is no longer active in the project...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Maybe we just remove that then, since it was only half working before.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phfatmonkey Second change in mesh.py:

  •    vertices_.extend((vertex.co.x, vertex.co.z, -vertex.co.y))
    

is not in new exporter version, it still:
vertices_.extend((vertex.co.x, vertex.co.y, vertex.co.z))

and was generating 90º degrees rotate in mesh

@MaikSoriano
Copy link

Three.js r77, this is happening right now and I have tried diferents parameters with the blender exporter. Idk what is wrong but I'm block with this issue:

https://www.youtube.com/watch?v=5ujqS3nm5RQ

@AndrewRayCode
Copy link
Contributor

AndrewRayCode commented Jun 12, 2016

@MaikSoriano you probably need to do this:

You need to reset your mesh location, rotation and scale in Blender before export. You should probably do this before rigging but it might be fine doing it after. Select your mesh, and hit Ctrl-A, then pick "rotation", then repeat for location and scale. Do the same for your armature. This applies any local translations directly to the object.

I've compiled a list of every known issue with the Blender exporter for fast referencing. The above quote is from this list:

https://gist.github.com/AndrewRayCode/746be166c3008a03167206aec4a46531

@MaikSoriano
Copy link

MaikSoriano commented Jun 12, 2016

@delvarworld Thanks, but unfortunately same result...

I have already tried that, and add the first and last keyframe too.

As you can see I'm using an example file. Just opening and exporting it. It is supposed that this file have been exported correctly before because the original example works... so I don't understand anything

@MaikSoriano
Copy link

MaikSoriano commented Jun 13, 2016

@delvarworld Ok, I "solved" the problem. If you check in [files changed] you can se this change in mesh.py:

-        vertices_.extend((vertex.co.x, vertex.co.y, vertex.co.z))
+        vertices_.extend((vertex.co.x, vertex.co.z, -vertex.co.y))

but if you download the final version (or dev version) this change is not apply.

@phfatmonkey
Copy link
Contributor Author

@MaikSoriano The current exporter does not work with the scene exporter when exporting skinned meshes--results are exactly as you said: verts are flipped on the YZ axes.

I made some changes to the exporter recently but they were overwritten with a later pull request in an effort to support the legacy JSON Loader, which a lot of people still use. However, if you grab the exporter from PR #8647 you should be able to export the Scene.

In the future, the exporter will need to be reconfigured so the Scene Loader is made the priority.

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

Successfully merging this pull request may close these issues.

8 participants