Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic Collada Loading in Three.js

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);
}
like image 652
Kode Avatar asked Oct 23 '25 15:10

Kode


1 Answers

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.

like image 96
gaitat Avatar answered Oct 25 '25 03:10

gaitat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!