mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.69k stars 35.37k forks source link

Collada importer breaks when bonelist and joints arrays don't match #5017

Closed kumavis closed 7 years ago

kumavis commented 10 years ago

The data looks like this:

bonelist
/* =>
[
  name: "joint5"
  parent: -1
  ...
,
  name: null
  parent: "joint5"
  ...
]
*/

joints
/* =>
["joint0", "joint1", "joint2", "joint3", "joint4", "joint5", "joint6", "joint7", "joint8", "joint9", "joint10", "joint11", "joint12"]
*/
bonelist.length
//=> 2
joints.length
//=> 13

note: this model was purchased, I don't know how it was exported.

The line that breaks here, b/c the sortedBones contains undefined elements

gero3 commented 10 years ago

I'm starting to think there are multiple skeletons in the dae file. And the first skeleton (the one three.js loads) seems incomplete. To check this, just search in the dae file for <skeleton>.If there are more then one skeleton in the same node(It should be inside an instance_controller node), then just remove the first skeleton. And test the file again. If it works, let us know, then we have to find a solution for multiple skeletons.

Also there is a problem with a joint that has no name (in the dae file this is called sid), these are static joints which aren't animated. We'll have to figure out if they are important to the scene.

@kumavis If it would be possible to share the dae file, It would be easier to debug. But since you said, it was purchased, It will probably be impossible.

kumavis commented 10 years ago

Looks like there are in fact quite a few!

<node id="node-droid_box" name="droid_box">
  <instance_controller url="#geom-droid_box-skin1">
    <skeleton>#node-Bone17</skeleton>
    <skeleton>#node-right_front_03</skeleton>
    <skeleton>#node-right_back_03</skeleton>
    <skeleton>#node-left_back_03</skeleton>
    <skeleton>#node-right_hand_02</skeleton>
    <skeleton>#node-spine_04</skeleton>
    <skeleton>#node-left_hand_02</skeleton>
    <skeleton>#node-left_front_03</skeleton>
    <bind_material>
      <technique_common>
        <instance_material symbol="box_mat_1" target="#box_mat-material">
          <bind_vertex_input semantic="CHANNEL1" input_semantic="TEXCOORD" input_set="1"/>
        </instance_material>
      </technique_common>
    </bind_material>
  </instance_controller>
</node>
crobi commented 10 years ago

You get multiple skeletons in blender (and probably other modeling tools) whenever your armature has multiple root nodes, i.e., if the bone hierarchy consists of several separate trees.

Here is a test file with multiple <skeleton> nodes - I have just used blender to insert an additional root node in the monster character by 3drt.com.

As I understand the COLLADA spec, the loader should do this:

This is almost what the loader does, it's probably enough to call flattenSkeleton for each instanceCtrl.skeleton and merge the resulting arrays into a single bonelist.

kumavis commented 10 years ago

my model is also from 3drt.com

Mugen87 commented 7 years ago

ColladaLoader2 should solve this problem. It handles skeletal animation more robust than its predecessor.