openrr / mesh-loader

Fast parser for 3D-model-formats.
Apache License 2.0
4 stars 2 forks source link

COLLADA - Materials missing not None in Scene #67

Open EtaLoop opened 5 days ago

EtaLoop commented 5 days ago

If some materials are omitted, there are not set to None in Scene. Instead there are Some with default values. I don't know if that's the behavior wanted. If that the case, it would be nice to see that in the documentation ;-)

Example :

let cube = r##"<?xml version="1.0" encoding="utf-8"?>
    <COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <asset>
        <contributor>
        <author>Blender User</author>
        <authoring_tool>Blender 2.79.0 commit date:2018-03-22, commit time:14:10, hash:f4dc9f9d68b</authoring_tool>
        </contributor>
        <created>2018-11-19T22:54:36</created>
        <modified>2018-11-19T22:54:36</modified>
        <unit name="meter" meter="1"/>
        <up_axis>Z_UP</up_axis>
    </asset>
    <library_images/>
    <library_effects>
        <effect id="Material-effect">
        <profile_COMMON>
            <technique sid="common">
            <phong>
                <specular>
                <color sid="specular">0.5 0.5 0.5 1</color>
                </specular>
            </phong>
            </technique>
        </profile_COMMON>
        </effect>
    </library_effects>
    <library_materials>
        <material id="Material-material" name="Material">
            <instance_effect url="#Material-effect"/>
        </material>
    </library_materials>
    <library_geometries>
        <geometry id="Cube_001-mesh" name="Cube.001">
        <mesh>
            <source id="Cube_001-mesh-positions">
            <float_array id="Cube_001-mesh-positions-array" count="24">-0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5</float_array>
            <technique_common>
                <accessor source="#Cube_001-mesh-positions-array" count="8" stride="3">
                <param name="X" type="float"/>
                <param name="Y" type="float"/>
                <param name="Z" type="float"/>
                </accessor>
            </technique_common>
            </source>
            <source id="Cube_001-mesh-normals">
            <float_array id="Cube_001-mesh-normals-array" count="18">-1 0 0 0 1 0 1 0 0 0 -1 0 0 0 -1 0 0 1</float_array>
            <technique_common>
                <accessor source="#Cube_001-mesh-normals-array" count="6" stride="3">
                <param name="X" type="float"/>
                <param name="Y" type="float"/>
                <param name="Z" type="float"/>
                </accessor>
            </technique_common>
            </source>
            <vertices id="Cube_001-mesh-vertices">
            <input semantic="POSITION" source="#Cube_001-mesh-positions"/>
            </vertices>
            <triangles material="Material-material" count="12">
            <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
            <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
            <p>1 0 2 0 0 0 3 1 6 1 2 1 7 2 4 2 6 2 5 3 0 3 4 3 6 4 0 4 2 4 3 5 5 5 7 5 1 0 3 0 2 0 3 1 7 1 6 1 7 2 5 2 4 2 5 3 1 3 0 3 6 4 4 4 0 4 3 5 1 5 5 5</p>
            </triangles>
        </mesh>
        </geometry>
    </library_geometries>
    <library_controllers/>
    <library_visual_scenes>
        <visual_scene id="Scene" name="Scene">
        <node id="Cube" name="Cube" type="NODE">
            <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
            <instance_geometry url="#Cube_001-mesh" name="Cube">
            <bind_material>
                <technique_common>
                <instance_material symbol="Material-material" target="#Material-material"/>
                </technique_common>
            </bind_material>
            </instance_geometry>
        </node>
        </visual_scene>
    </library_visual_scenes>
    <scene>
        <instance_visual_scene url="#Scene"/>
    </scene>
    </COLLADA>
    "##;

    let scene = mesh_loader::collada::from_str(&cube);

    if let Ok(scene) = scene {
        println!("mat : {:?}", scene.materials);
        assert_eq!(scene.materials[0].color.emissive, None);
        assert_eq!(scene.materials[0].color.ambient, None);
        assert_eq!(scene.materials[0].index_of_refraction, None);
        assert_eq!(scene.materials[0].color.diffuse, None);
        assert_eq!(scene.materials[0].shininess, None);
    }
taiki-e commented 5 days ago

The relevant code is here, and IIRC the behavior here is mostly refers that of assimp. (However, some of it is specified in the spec.)

https://github.com/openrr/mesh-loader/blob/44ad13656d4b5009f4fb6b172c206d1b9860c18d/src/collada/effect.rs#L439-L450

We refer to the behavior of assimp because this library was started to replace the use of assimp in our other projects, and it was more convenient to have the same behavior. And the STL parser has a similar behavior.

https://github.com/openrr/mesh-loader/blob/44ad13656d4b5009f4fb6b172c206d1b9860c18d/src/stl/mod.rs#L147-L148

That said, the OBJ parser, which was added later than these two parsers, does not have this behavior (defaults to None), and in fact, it may make sense to all parsers do the same as the OBJ parser (aside from the default value specified in the spec).

https://github.com/openrr/mesh-loader/blob/44ad13656d4b5009f4fb6b172c206d1b9860c18d/src/obj/mod.rs#L1189-L1205

EtaLoop commented 4 days ago

Ok I understand :+1: