mrdoob / three.js

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

Metadata and model name in JSONLoader #1696

Closed mastershadow closed 9 years ago

mastershadow commented 12 years ago

Hello!!!

I think that would be great to have metadata (custom attributes?) and model name available in the callback function for the loader. What do you think?

Tnx Eduard

mrdoob commented 12 years ago

Could you write an snippet that illustrates what you mean?

slehoun commented 10 years ago

What I think mastershadow has in mind is this. Developer would add custom property to JSON file:

//JSON_model_be778700-c17e-40ec-aa85-ee5c8fc4ce79.js
{
    "metadata" :
    {
        "formatVersion" : 3.1,
        "generatedBy" : "Blender 2.7 Exporter",
        "vertices" : 900,
        "faces" : 480,
        "normals" : 142,
        "colors" : 0,
        "uvs" : [],
        "materials" : 1,
        "morphTargets" : 0,
        "bones" : 0,
        // ADDED CUSTOM PROPERTY HERE:
        "ID" : "be778700-c17e-40ec-aa85-ee5c8fc4ce79" // CUSTOM PROPERTY, perhaps some uid
    },

    "scale" : 1.000000,

    "materials" : [ {
        "DbgColor" : 15658734,
        "DbgIndex" : 0,
        "DbgName" : "material_4",
        "blending" : "NormalBlending",
// JSON continues ....

You could then identify exact JSON file in loader's callback function with value of that property:

// ...
function loadModels(modelInfo)
{
    for (var i = 0; i < modelInfo.paths.length; i++)
    {
        loader = new THREE.JSONLoader();
        loader.load(modelInfo.paths[i], loaderCallback);
    }
}

function loaderCallback(geometry, materials, ID) // ADDED ID PARAMETER TO CALLBACK FUNCTION
{
    var currentMaterial = new THREE.MeshFaceMaterial(materials);
    var currentObject = new THREE.Mesh(geometry, currentMaterial);
    scene.add(currentObject);
    methodThatProcessesMeshFurther(ID);
}
// ...

The methodThatProcessesMeshFurther(ID) can then for example store uuid of Geometry (and link it with appropriate file) to manipulate it further via user input.

I ran into similar problem lately. I have database of multiple JSONs. Each file represents different part of model that can be manipulated by user in certain way. User-manipulation possibilities are different for each part/JSON file. The problem is, once I load JSONs into the scene, I cannot link them with the files they have been loaded from. I have to maintain link between geometry and its metadata (for example available materials for different parts of geometry–user manipulation possibilities) statically in the code, which is not quite elegant.

(I found the method of splitting geometry into multiple JSONs with their custom metadata defined in separate files to work best for me. Except for the problem stated above. I could not figure out better way to do this yet.)

mrdoob commented 10 years ago

I think it's easier to just do this...

var loader = new THREE.XHRLoader();
loader.load( 'file.json', function ( text ) {

    var json = JSON.parse( text ); // here you have access to the whole json.
    var model = new THREE.ObjectLoader().parse( json );

} );