Skip to content

piston_collada does not respect the differences between IDREF_array, Name_array and SIDREF_array #49

@zraktvor

Description

@zraktvor

Expectation

The COLLADA-Specification lists different ways to reference nodes.
Among them are the elements IDREF_array(page 5-44), Name_array(page 5-94) and SIDREF_array(page 5-130).
To correctly treat them, piston_collada should use their values as references to the attributes id, name and sid respectively.

Problem

Currently piston_collada loads a Name_array with the joint_names here:

let joint_input = (self.get_input(joints_element, "JOINT"))?;
let joint_names = (self.get_array_for_input(skin_element, joint_input))?;

and then later compares them with Joint.name here:

if let Some((joint_index, _)) = skeleton
.joints
.iter()
.enumerate()
.find(|&(_, j)| &j.name == joint_name)
{
vertex_joint_weights.joints[next_index] = joint_index;
vertex_joint_weights.weights[next_index] =
bind_data.weights[vertex_weight.weight];
} else {
error!("Couldn't find joint: {}", joint_name);
}

But Joint.name was set the id attribute here:

let joint_name = joint_element.get_attribute("id", None).unwrap().to_string();

This bug is not caught by the existing cache files, because name and id are the same there.
The incorrect handling is not only a derivation from the spec, but leads to incorrect handling of actual exported collada files.
In the following examples from other projects, is visible that both Blender and ColladaMaya may set the the name attribute to a different value then the idattribute and mean the name attribute in Name_array.

Example1

In three.js is the following example, where the Name_array with the joints here:
https://github.com/mrdoob/three.js/blob/c7d06c02e302ab9c20fe8b33eade4b61c6712654/examples/models/collada/skin_and_morph.dae#L385-L393

refers to the node here, where the referenced name joint1 is in the name attribute and not the id attribute:
https://github.com/mrdoob/three.js/blob/c7d06c02e302ab9c20fe8b33eade4b61c6712654/examples/models/collada/skin_and_morph.dae#L552-L555

Example2

As a more complex example, where blender does this, serves the following file from the game 0AD, where the Name_array here:
https://github.com/0ad/0ad/blob/412f1d0da275a12df16e140fca7523590e5f7cfe/binaries/data/mods/public/art/meshes/skeletal/elephant_asian_male.dae#L86-L88

references the nodes from here onwards always by there name:
https://github.com/0ad/0ad/blob/412f1d0da275a12df16e140fca7523590e5f7cfe/binaries/data/mods/public/art/meshes/skeletal/elephant_asian_male.dae#L449-L474

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions