3
votes

I am attempting to load a collada file using three.js and the collada loader. I am leveraging the three.js documentation, but can't seem to get the file to render on screen. What I want to achieve is a very basic import of the collada file into a scene, no animation required. The errors I am receiving are as follows:

unhandled Surface prop: format_hint
Can not convert Transform of type lookat

The XHR output is showing 100% load of the .dae file, and I can browse to the location of the stored file in a browser and view it as XML. I currently have the mime type set to application/xml in IIS.

Here is my current code. What am I missing?:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - loaders - collada loader</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <script src="scripts/three.min.js"></script>
    <script src="scripts/ColladaLoader.js"></script>
    <script src="scripts/jquery-2.1.4.min.js"></script>
    <script src="scripts/bootstrap.min.js"></script>
    <link href="css/bootstrap.min.css" rel="stylesheet" />
</head>

<body>
    <h1>Box Example</h1>
    <p>This example loads an collada file</p>

    <div id="webGL-container"></div>

    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        var renderer = new THREE.WebGLRenderer();

        renderer.setClearColor(0xff0000);
        renderer.setSize(window.innerWidth, window.innerHeight);

        camera.position.x = 40;
        camera.position.y = 40;
        camera.position.z = 40;

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

        loader.load(
            // resource URL
            'models/box.dae',

            // Function when resource is loaded
            function (collada) {
                scene.add(collada.scene);
            },
            // Function called when download progresses
            function (xhr) {
                console.log((xhr.loaded / xhr.total * 100) + '% loaded');
            }
        );

        camera.lookAt(scene.position);

        renderer.render(scene, camera);
        $("#webGL-container").append(renderer.domElement);
    </script>
</body>
</html>

Per the advice offered, here is version 2:

    var scene;;
    var camera;
    var renderer;
    var loader;

    function init() {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    renderer = new THREE.WebGLRenderer();


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

    camera.position.x = 40;
    camera.position.y = 40;
    camera.position.z = 40;

    // instantiate a loader
    loader = new THREE.ColladaLoader();


        loader.load(
            // resource URL
            'models/box.dae',

            // Function when resource is loaded
            function (collada) {
                scene.add(collada.scene);
            },
            // Function called when download progresses
            function (xhr) {
                console.log((xhr.loaded / xhr.total * 100) + '% loaded');
            }
        );

        camera.lookAt(scene.position);
        $("#webGL-container").append(renderer.domElement);

    };



    function animate() {
        requestAnimationFrame(animate);

        renderer.render(scene, camera);
    }

    init();
    animate();

Update 3: I have been able to get the core .DAE file to render, but it is missing the texture (currently showing the box as all black):

    var scene;
    var camera;
    var renderer;
    var box;

    // instantiate a loader
    var loader = new THREE.ColladaLoader();
    loader.options.convertUpAxis = true;
    loader.load('models//box.dae', function (collada) {

        box = collada.scene;

        box.traverse(function (child) {

            if (child instanceof THREE.SkinnedMesh) {

                var animation = new THREE.Animation(child, child.geometry.animation);
                animation.play();

            }
        });

        box.scale.x = box.scale.y = box.scale.z = .2;
        box.updateMatrix();

        init();
        animate();
    });


    function init() {
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        renderer = new THREE.WebGLRenderer();

        renderer.setClearColor(0xdddddd);
        renderer.setSize(window.innerWidth, window.innerHeight);

        scene.add(box);

        camera.position.x = 40;
        camera.position.y = 40;
        camera.position.z = 40;

        camera.lookAt(scene.position);
    }

    function animate() {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
        $("#webGL-container").append(renderer.domElement);
    }
1
does the file load in threejs.org/editor ?gaitat
It loads, as it does with the "Monster" Collada 3D example, but I require a more basic example of how to load.Kode

1 Answers

2
votes

You are hitting the asynchronous loading of javascript. When you call renderer.render() your scene is still empty because the model has not downloaded yet. Put the code you have in an init() function and then create an animate() function and call them as such:

function animate() {
    requestAnimationFrame( animate );
    renderer.render( scene, camera );
}

init();
animate();

The variables scene, camera, renderer you should make global.