3

I am working on an aframe project where runtime loading of 3D object is required. I have read A-Frame documentations, and aframe doesn't seem to support runtime assets loading at all.

I discovered this aframe-asset-on-demand-component by protyze (https://github.com/protyze/aframe-asset-on-demand-component) and it seems to allow runtime loading of img, audio and video. But its documentation does not indicate the possibility of loading 3D objects like files in .obj or .dae at runtime.

Has anyone tried using the above-mentioned component to achieve runtime loading of 3D objects? Or is there any alternative ways to achieve this purpose?

Felix
  • 77
  • 1
  • 9
  • Technically _all_ models are loaded at runtime in A-Frame... unless you mean something different? Like the user selects models from a dropdown or drag-and-drops the file into the window? – Don McCurdy Mar 14 '18 at 04:39

3 Answers3

8

Ignore <a-assets> since that is for pre-runtime network preloading.

Just set the model component with setAttribute:

el.setAttribute('gltf-model', 'path/to/model.gltf')

or

el.setAttribute('obj-model', {obj: 'path/to/model.obj'})

ngokevin
  • 12,980
  • 2
  • 38
  • 84
  • Worked for me! Thank you very much. The 'src' isn't the correct attribute though, it should be 'obj' instead. Again thank you for your answer. – Felix Mar 14 '18 at 12:48
  • i am using Vue and i render the gltf model on component and alays get this error ```components:gltf-model:warn Unexpected token < in JSON at position 0 ``` , i really get stuck for this :(. can u help me how to debug this – Zum Dummi Apr 18 '19 at 05:37
1

@ngokevin, Great answer! I've created plunker demo for that.

https://plnkr.co/edit/yOmsxOSSfkVuX7c739Q1?p=info

<a-scene embedded arjs="sourceType: webcam;">
        <a-gltf-model id="lantern" src="#lantern" position="" 0 0 0"></a-gltf-model>
        <a-marker-camera preset="hiro"></a-marker-camera>
</a-scene>

<script>
        var lantern = document.getElementById('lantern');

        setTimeout(() => {
            alert('duck');
            lantern.setAttribute('gltf-model', 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Duck/glTF/Duck.gltf');
        }, 3000);

        setTimeout(() => {
            alert('cesium');
            lantern.setAttribute('gltf-model', 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/CesiumMan/glTF/CesiumMan.gltf');
        }, 9000);
    </script>
Marian Turchyn
  • 519
  • 5
  • 6
0

You can create a custom component that will use one of the three.js loaders, to load the model when you want to:

// instantiate a loader
var loader = new THREE.OBJLoader();

// load a resource
loader.load(
  // resource URL
  'models/monster.obj',
  // called when resource is loaded
  function ( object ) {

    scene.add( object );

  },
  // called when loading is in progresses
  function ( xhr ) {

    console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

  },
  // called when loading has errors
  function ( error ) {

    console.log( 'An error happened' );

  }
);

Links to three.js docs: Do a search for loaders to see all the ones available that you can use in an a-frame component: https://threejs.org/docs/#examples/loaders/OBJLoader

A-frame components using the threejs loaders: https://github.com/aframevr/aframe/blob/master/src/components/obj-model.js https://github.com/aframevr/aframe/blob/master/src/components/collada-model.js

Noam Almosnino
  • 866
  • 1
  • 6
  • 8
  • 2
    Not sure if this is what the OP means, but it could be even easier if adding an (existing) component on the fly: `el.setAttribute('gltf-model', {src: 'path/to/model.gltf'})` – Don McCurdy Mar 14 '18 at 04:40
  • Ah yes much simpler :) – Noam Almosnino Mar 14 '18 at 04:41
  • I think `gltf-model` is unfortunately a single-prop component so `el.setAttribute('gltf-model', 'path/to/model.gltf')`. Will post as answer – ngokevin Mar 14 '18 at 07:28
  • Appreciate your answer! the solution suggested by ngokevin worked for me and appears to be much simpler. – Felix Mar 14 '18 at 12:51