05: Loading external models

Using a couple of Three.js plugins you can load external models in to your scene. The plugins are:

OBJLoader lets you load .obj format models, and MTLLoader lets you load .mtl material definitions to apply textures to the models.

You can grab models from anywhere you like, or model them yourself in something like 3DS Max or Blender.

If you can’t find the model you like as an .obj and .mtl, I’ve found that you can use an online service such as http://www.greentoken.de/onlineconv/ to convert them.

Adding models to your scene

First of all you need to load the OBJLoader and MTLLoader plugins

<script src="OBJLoader.js"></script>
<script src="MTLLoader.js"></script>

And then for each model you’ll need to create an instance of MTLLoader to preload the materials, create an instance of OBJLoader to load the model and then finally add them to your scene.

var modelsToLoad = ['Stormtrooper', 'R2D2'];
modelsToLoad.forEach(function (model, i) {
    var mtlLoader = new THREE.MTLLoader();
    var objLoader = new THREE.OBJLoader();

    // Load the material, e.g. 'Stormtrooper.mtl'
    mtlLoader.load(model+'.mtl', function (materials) {
        materials.preload();
        objLoader.setMaterials(materials);

        // Load the object, e.g. 'Stormtrooper.obj'
        objLoader.load(model+'.obj', function (object) {
            // Object can be scaled, positioned, etc. like any mesh
            object.scale.set(.5, .5, .5);
            scene.add(object);
        });
    });
});

These aren’t the droids you’re looking for

Though loaded models are treated just like any other mesh, I’ve found that raycasting doesn’t behave the same. For todays hack I wanted to have some logic for when you stare at a specific model but nothing was happening.

To get around this, I added the model as a child of an Object3D and then positioned a regular BoxGeometry mesh over that:

    // ... mostly as before
    objLoader.load(model+'.obj', function (object) {
        var parent = new THREE.Object3D();
        object.scale.set(.5, .5, .5);
        parent.add(object);

        // Using my core.js helper for building things
        var cube = core.build(
            'BoxGeometry', [18, 30, 18],
            'MeshLambertMaterial', [{
                color: 0xffffff,
                // make it transparent
                transparent: true,
                opacity: 0
            }]
        );
        // you will want to position/scale the cube
        // before making it transparent

        // add the cube
        parent.add(cube);

        // add the Object3D to the scene
        scene.add(parent);
    });

Now I’m able to raycast the transparent cube rather than the model.

I’m using vreticle.js again to handle raycasting, and Howler.js for loading/playing sounds.

Cardboctober day 5

View this Cardboctober hackView the source code on Github

View the other submissions for day 5 on the Cardboctober website.

Check out all of my other Cardoctober posts here: /cardboctober.

[Comments]

Want to comment? You can do so via Github.
Comments via Github are currently closed.

[Webmentions]

Want to reply? I've hooked up Webmentions, so give it a go!