GLTFloader with annotation

Hello,

I am working on displaying a GLTF model in three.js. I would like to be able to add annotations to certain meshes. I am having a hard time trying to find information on how to implement this.

var camera, scene, renderer, canvas, controls, manager, backimg, loader2, loader, envMap;

        init();
        render();

        function init() {

            $('.loading-container > *:not(.onepix-imgloader)').fadeTo(0, 0);
            $('.onepix-imgloader').fadeIn();

            canvas = document.querySelector('#c');

            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20);
            camera.position.set(-1.8, 0.6, 2.7);

            scene = new THREE.Scene();

            manager = new THREE.LoadingManager();

            backimg = new THREE.TextureLoader().load("./render/dark.jpg");
            scene.background = backimg;

            function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
                var halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
                var halfFovY = THREE.Math.degToRad(camera.fov * .5);
                var distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
                // compute a unit vector that points in the direction the camera is now
                // in the xz plane from the center of the box
                var direction = (new THREE.Vector3())
                    .subVectors(camera.position, boxCenter)
                    .multiply(new THREE.Vector3(1, 0, 1))
                    .normalize();

                // move the camera to a position distance units way from the center
                // in whatever direction the camera was from the center already
                camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));

                // pick some near and far values for the frustum that
                // will contain the box.
                camera.near = boxSize / 100;
                camera.far = boxSize * 100;

                camera.updateProjectionMatrix();

                // point the camera to look at the center of the box
                camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
            }

            manager.onProgress = function (item, loaded, total) {
                console.log(item, loaded, total);
            };

            manager.onLoad = function () {
                console.log('all items loaded');
                allItemsLoaded();
            };

            loader2 = new THREE.RGBELoader()
           .setDataType(THREE.UnsignedByteType)
           .load('./render/textures/studio024.hdr', function (texture) { envMap = pmremGenerator.fromEquirectangular(texture).texture; });
          
            // model
            loader = new THREE.GLTFLoader(manager).setPath('./render/models/');

            var dracoLoader = new THREE.DRACOLoader(manager);
            dracoLoader.setDecoderPath('./js/libs/draco/');
            loader.setDRACOLoader(dracoLoader);

            var modeltoload = document.getElementById("modellist1").value;
            loader.load(modeltoload, function (gltf) {

                gltf.scene.traverse(function (child) {

                    if (child.isMesh) {

                        child.castShadow = true;
                        child.receiveShadow = true;
                        child.material.toneMapping = true;
                        child.material.SmoothShading = true;
                        child.material.envMap = envMap;

                        if (child.material.name === "Metal") {
                            child.material.metalness = 0.6;
                            child.material.roughness = 0.3;
                        }
                        if (child.material.name === "[Aluminum]1") {
                            child.material.metalness = 0.6;
                            child.material.roughness = 0.3;
                        }
                        if (child.material.name === "<auto>3") {
                            child.material.metalness = 0.6;
                            child.material.roughness = 0.3;
                        }

                        child.material.needsUpdate = true;
                        var mesh = child.clone();
                        scene.add(mesh);
                    }

                });


                var box = new THREE.Box3().setFromObject(gltf.scene);
                var boxSize = box.getSize(new THREE.Vector3()).length();
                var boxCenter = box.getCenter(new THREE.Vector3());

                // set the camera to frame the box
                frameArea(boxSize * 0.8, boxSize, boxCenter, camera);

                // update the Trackball controls to handle the new size //
                controls.maxDistance = boxSize * 2;
                controls.target.copy(boxCenter);
                controls.update();

            });

            renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.toneMapping = THREE.ACESFilmicToneMapping;
            renderer.toneMappingExposure = 0.8;
            renderer.outputEncoding = THREE.sRGBEncoding;

            var pmremGenerator = new THREE.PMREMGenerator(renderer);
            pmremGenerator.compileEquirectangularShader();

            // Add Lights //
            hemiLight = new THREE.HemisphereLight(0xffeeb1, 0x080820, 1);
            scene.add(hemiLight);

            // Controls //
            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.addEventListener('change', render); // use if there is no animation loop
            controls.minDistance = 0.5;
            controls.enablePan = false;
            controls.target.set(0, 0, -0.2);
            controls.update();

            window.addEventListener('resize', onWindowResize, false);

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);

            render();

        }

        function render() {

            renderer.render(scene, camera);

        }

        function allItemsLoaded() {
            $('.onepix-imgloader').fadeOut();
            $('.loading-container > *:not(.onepix-imgloader)').fadeTo(0, 100);
        }
    </script>
    <script>
        var elem = document.getElementById("container");
        function openFullscreen() {
            if (elem.requestFullscreen) {
                elem.requestFullscreen();
            } else if (elem.mozRequestFullScreen) { /* Firefox */
                elem.mozRequestFullScreen();
            } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
                elem.webkitRequestFullscreen();
            } else if (elem.msRequestFullscreen) { /* IE/Edge */
                elem.msRequestFullscreen();
            }
        }

Once you’ve loaded a model it doesn’t particularly matter what format it was originally. It’s just a THREE.Mesh. From that perspective, you don’t need anything glTF-specific here but can find some suggestions in How to create Sketchfab like annotations with Three.js?.