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

io_three, Blender armature exporting - object center positions [bug] #11373

Closed
2 of 12 tasks
centerionware opened this issue May 22, 2017 · 7 comments
Closed
2 of 12 tasks

Comments

@centerionware
Copy link
Contributor

Description of the problem

I don't know if this has been covered already, but I can't find anything about it.

I've got a scene built in blender, with 30 some objects. Most of them export fine and load fine into threejs after rotating around their Z by 180 degrees. The ones with armatures though, are in the wrong position. They seem to forget their armatures position and the object position, and load with the difference between the armature position and object position as their position instead of one (or the other) (so almost near 0,0,0, but never on it).

If I set all the objects origins to the center (eg: shift+s, cursor to center, select all objects in object mode, ctrl+alt+shift+c , origin to cursor) it mostly works but seems to have issues with transparencies, although my transparency issues might be something else.

Here's an image, the animated objects directly by the player model are all in the wrong spot while everything else is correct.
bugged_loading

Three.js version
  • [x ] Dev
  • r85
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS
Hardware Requirements (graphics card, VR Device, ...)
@mrdoob
Copy link
Owner

mrdoob commented May 23, 2017

Could you share a test .blend file?

@centerionware
Copy link
Contributor Author

centerionware commented May 25, 2017

*Edit
Once I applied loc,rot,scale, exported as geometry instead of buffergeom, things started to work somewhat better
(See edit 2) in the editor for the test scene, although the floor plane was invisible with 'skinning' enabled on it, and the animated objects seem to be in the correct place. I need to make two materials it seems, because skinning is not liked when there are no bones attached to the objects using the materials. I may end up uploading the original scene I'm having troubles with to see if anyone can help me figure out what I'm doing wrong..
**Edit 2:
I forgot applying location puts the origin to the center of the scene. so once I selected everything, put origin to center of mass (control+alt+shift+c with everything selected) the animated objects again move to near origin, and there's some nifty screen tearing going on as well.

(https://github.com/mrdoob/three.js/files/1027677/multi_armature_test_scene.zip)
This is hopefully the new test files if I didn't screw up uploading somehow.
***/edit

apologies for the delay in response.
this is a small scene with a single material and texture with a few primitives, two armatures, two rest poses and two animations embedded, along with the json output from io_three
**Removed old file ***

I think it's got flipped normals on floor, but that's my fault for sure. I didn't spend much time making it, but it sure highlights this issue I think when loading it into the three/editor.
test_screen_shot

@centerionware
Copy link
Contributor Author

centerionware commented May 25, 2017

better test. Fixed normal on floor, saved export settings with geometry vs buffer. the bones seem to be in the right places according to the threejs editor, with the mesh near zero. I think somehow they need to be flipped - The bones should be near zero with the mesh at the global position, since the bones are the children of the mesh it make sense. In blender it's the other way around, with the mesh and bones both being siblings and children of the armature .
multi_armature_test_scene.zip

is: {
three.object.position = blender.(object.location-armature.location)
three. bone.position = bone_position
}

should be: {
three.object.position = blender.object.location
three.bone.position = blender.(armature.location-bone.location)
}

@centerionware
Copy link
Contributor Author

centerionware commented May 25, 2017

I finally got it exporting and loading.
I had to apply location (control+a) on just the armatures, leaving everything else. Then the positions of the objects are close to the same as the other objects exported into three, with the Y and Z flipped and X needing negation. So in my THREE.ObjectLoader() callback I added:

            if(obj.children.length > 0) {
                var has_bone = false;
                for(var i = 0; i < obj.children.length; i++)
                    if(obj.children[i] instanceof THREE.Bone)
                        has_bone = true;

                if(has_bone) {
                    var oy = obj.position.y;
                    obj.position.y = obj.position.z;
                    obj.position.z = oy;
                    obj.position.x *= -1;
                }
            }

And now they're all loading up into what appears to be the same places as every other object from threejs. If I do obj.rotateZ(3.14); after all is said and done, the textures all line up too. I suspect things are a mathematical mirror from blender in ways. (on the sphere, X in blender is 10 for example, and -10 when loading into threejs, but that i think is a seperate issue.)

@centerionware
Copy link
Contributor Author

Turns out the 'solution' above fixes everything if I only use location and scale keyframes in the poses. if I add any rotation things rotate around the wrong spot. The plane animation in the test above uses some rotation and gets stretched out. I went and added a third animated object, a cylinder with one bone that spins around Z offset on the X axis from the center of the scene, it rotates around a point that appears to be 2X away from the center.
multi_armature_test_scene.zip

@centerionware
Copy link
Contributor Author

I was able to get all the animations in the test scene running - only using 'apply location' on the armatures with everything else in the scene set to 'origin to geometry'. This method involves processing the output json and putting it through a fairly small function that modifies all the animation keys and the bone positions from the matrix on the objects.. I don't think it will hurt anything if all objects have had their locations applied because the matrix would then be 0,0,0, resulting in some additions and subtractions of zero so not changing anything. it may be able to run on all currently working stuff while fixing this issue if it's placed somewhere in the object loader before everything is parsed. Basically

function start_json_fixin(json_str) {
    var out = JSON.parse(json_str);
    debugger;
    for (var i = 0; i < out.object.children.length; i++) {
        for (var j = 0; j < out.geometries.length; j++) {
            if (out.geometries[j].uuid == out.object.children[i].geometry) {
                var matrix = out.object.children[i].matrix;
                for (var k = 0; k < out.geometries[j].data.bones.length; k++) {
                    var ijk = out.geometries[j].data.bones[k];
                    ijk.pos[0] -= matrix[12];
                    ijk.pos[1] -= matrix[14];
                    ijk.pos[2] += matrix[13];
                }
                for (var k = 0; k < out.geometries[j].data.animations.length; k++) {
                    for (var m = 0; m < out.geometries[j].data.animations[k].hierarchy.length; m++) {
                        for (var l = 0; l < out.geometries[j].data.animations[k].hierarchy[m].keys.length; l++) {
                            var ijkl = out.geometries[j].data.animations[k].hierarchy[m].keys[l];
                            ijkl.pos[0] -= matrix[12];
                            ijkl.pos[1] -= matrix[14];
                            ijkl.pos[2] += matrix[13];
                        }
                    }
                }
            }
        }
    }
    $("#outputJson").text(JSON.stringify(out));
}

@Mugen87
Copy link
Collaborator

Mugen87 commented May 31, 2018

The JSON Blender exporter has been removed with R93 (#14117).

Also see: https://threejs.org/docs/#manual/introduction/Loading-3D-models

@Mugen87 Mugen87 closed this as completed May 31, 2018
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

No branches or pull requests

3 participants