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

Duplicate accessors are not handled properly in builder classes #104

Closed
javagl opened this issue Mar 20, 2024 · 0 comments · Fixed by #103
Closed

Duplicate accessors are not handled properly in builder classes #104

javagl opened this issue Mar 20, 2024 · 0 comments · Fixed by #103

Comments

@javagl
Copy link
Owner

javagl commented Mar 20, 2024

The GltfModelBuilder can accept a SceneModel, and will "traverse" the scene, adding all AccessorModel instances that it finds, and assemble the final accessor/bufferView/buffer structure based on that.

Currently, this does not properly handle duplicate accessors. As a pseudocode example, there could be two mesh primitives that refer to identical indices, but different positions:

indices = [0, 1, 2]
positionsA = [...]
positionsB = [...]
meshPrimitiveA = { indices, positionsA }
meshPrimitiveB = { indices, positionsB }

In this case, it will try to add the AccessorModel for the indices twice. (This was actually only noticed due to a pending change in 7c7b678 )

The builder should be smart enough to detect this case, and handle it accordingly.

An example that causes duplicate data (or maybe even invalid data, or an error message in the state of #103 respectively) is here:

import java.io.IOException;

import de.javagl.jgltf.impl.v2.GlTF;
import de.javagl.jgltf.model.GltfModel;
import de.javagl.jgltf.model.creation.GltfModelBuilder;
import de.javagl.jgltf.model.creation.MeshPrimitiveModels;
import de.javagl.jgltf.model.impl.DefaultGltfModel;
import de.javagl.jgltf.model.impl.DefaultMeshModel;
import de.javagl.jgltf.model.impl.DefaultMeshPrimitiveModel;
import de.javagl.jgltf.model.impl.DefaultNodeModel;
import de.javagl.jgltf.model.impl.DefaultSceneModel;
import de.javagl.jgltf.model.io.GltfWriter;
import de.javagl.jgltf.model.io.v2.GltfAssetV2;
import de.javagl.jgltf.model.io.v2.GltfAssetsV2;

public class DuplicateAccessorsExample
{
    public static void main(String[] args) throws Exception
    {
        GltfModel gltfModel = createGltfModel();
        printEmbedded(gltfModel);
    }
    
    private static GltfModel createGltfModel()
    {
        // Create a mesh primitive
        int indices[] = { 0, 1, 2 };
        float positions[] =
        {
            0.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            0.5f, 1.0f, 0.0f
        };
        DefaultMeshPrimitiveModel meshPrimitiveModel =
            MeshPrimitiveModels.create(indices, positions, null, null);
        
        DefaultSceneModel sceneModel = new DefaultSceneModel();
        
        // Use the same mesh primitive model (with the same accessors)
        // in two different meshes, and add them to the scene
        DefaultMeshModel meshModel0 = new DefaultMeshModel();
        meshModel0.addMeshPrimitiveModel(meshPrimitiveModel);
        DefaultNodeModel nodeModel0 = new DefaultNodeModel();
        nodeModel0.addMeshModel(meshModel0);
        sceneModel.addNode(nodeModel0);

        DefaultMeshModel meshModel1 = new DefaultMeshModel();
        meshModel1.addMeshPrimitiveModel(meshPrimitiveModel);
        DefaultNodeModel nodeModel1 = new DefaultNodeModel();
        nodeModel1.addMeshModel(meshModel1);
        sceneModel.addNode(nodeModel1);
        
        // Pass the scene to the model builder. It will take care
        // of the other model elements that are contained in the scene.
        // (I.e. the mesh primitive and its accessors, and the material 
        // and its textures)
        GltfModelBuilder gltfModelBuilder = GltfModelBuilder.create();
        gltfModelBuilder.addSceneModel(sceneModel);
        DefaultGltfModel gltfModel = gltfModelBuilder.build();

        return gltfModel;
    }
    
    private static void printEmbedded(GltfModel gltfModel) throws IOException 
    {
        GltfAssetV2 asset = GltfAssetsV2.createEmbedded(gltfModel);
        GlTF gltf = asset.getGltf();
        GltfWriter gltfWriter = new GltfWriter();
        gltfWriter.setIndenting(true);
        gltfWriter.write(gltf, System.out);
    }
}
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

Successfully merging a pull request may close this issue.

1 participant