Three.js Collada - dispose() 和释放内存(垃圾收集)的正确方法是什么? [英] Three.js Collada - What's the proper way to dispose() and release memory (garbage collection)?

查看:24
本文介绍了Three.js Collada - dispose() 和释放内存(垃圾收集)的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经通过 ColladaLoader 成功导入了一个 .dae 场景.

I've successfully imported a .dae scene via ColladaLoader.

问题是,我需要在几个 .dae 文件之间切换.

The problem is, I need to switch between several .dae files.

我似乎无法正确实现 dispose 方法.

I can't seem to implement the dispose method properly.

        dae.traverse(function(obj) {

            console.log('unloading ' + obj.id);

            scene.remove(obj);

            if(obj.geometry)
                obj.geometry.dispose();
            if(obj.material)
                obj.material.dispose();
            if(obj.mesh)
                obj.mesh.dispose();
            if(obj.texture)
                obj.texture.dispose();

        });

        scene.remove(dae);

我可能做错了什么?

非常感谢!

这是完整的代码.

    var renderer = null;
    var scene = null;
    var camera = null;
    var controls = null;
    var dae = null;
    //var loader = null;

    function init() {


        renderer = new THREE.WebGLRenderer( { alpha: 1, antialias: true, clearColor: 0xffffff } );
        renderer.setSize( 800, 600 );

        var elem = $('.main3d')[0];
        elem.appendChild( renderer.domElement );

        scene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera( 20, 800/600, 1, 1000 );
        camera.position.set( 0, -100, 50 );
        //camera.lookAt( scene.position );
        controls = new THREE.TrackballControls( camera, renderer.domElement );

        var light = new THREE.AmbientLight( 0xffffff ); // soft white light
        scene.add( light );

        threeAnimate();


    }

    function load(url) {
        loader = new THREE.ColladaLoader();

            loader.load(url, function (collada) {
                dae = collada.scene;
                scene.add(dae);

            });

    }

    function unload() {

        dae.traverse(function(obj) {

            console.log('unloading ' + obj.id);

            scene.remove(obj);

            if(obj.geometry)
                obj.geometry.dispose();
            if(obj.material)
                obj.material.dispose();
            if(obj.mesh)
                obj.mesh.dispose();
            if(obj.texture)
                obj.texture.dispose();

        });

        scene.remove(dae);

    }

    var animFrame = null;
    function animate()  {

        animFrame = requestAnimationFrame( threeAnimate );
        renderer.render( scene, camera );
        controls.update();

    }

推荐答案

这应该可以:

function disposeNode (node)
{
    if (node instanceof THREE.Mesh)
    {
        if (node.geometry)
        {
            node.geometry.dispose ();
        }

        if (node.material)
        {
            if (node.material instanceof THREE.MeshFaceMaterial)
            {
                $.each (node.material.materials, function (idx, mtrl)
                {
                    if (mtrl.map)               mtrl.map.dispose ();
                    if (mtrl.lightMap)          mtrl.lightMap.dispose ();
                    if (mtrl.bumpMap)           mtrl.bumpMap.dispose ();
                    if (mtrl.normalMap)         mtrl.normalMap.dispose ();
                    if (mtrl.specularMap)       mtrl.specularMap.dispose ();
                    if (mtrl.envMap)            mtrl.envMap.dispose ();
                    if (mtrl.alphaMap)          mtrl.alphaMap.dispose();
                    if (mtrl.aoMap)             mtrl.aoMap.dispose();
                    if (mtrl.displacementMap)   mtrl.displacementMap.dispose();
                    if (mtrl.emissiveMap)       mtrl.emissiveMap.dispose();
                    if (mtrl.gradientMap)       mtrl.gradientMap.dispose();
                    if (mtrl.metalnessMap)      mtrl.metalnessMap.dispose();
                    if (mtrl.roughnessMap)      mtrl.roughnessMap.dispose();

                    mtrl.dispose ();    // disposes any programs associated with the material
                });
            }
            else
            {
                if (node.material.map)              node.material.map.dispose ();
                if (node.material.lightMap)         node.material.lightMap.dispose ();
                if (node.material.bumpMap)          node.material.bumpMap.dispose ();
                if (node.material.normalMap)        node.material.normalMap.dispose ();
                if (node.material.specularMap)      node.material.specularMap.dispose ();
                if (node.material.envMap)           node.material.envMap.dispose ();
                if (node.material.alphaMap)         node.material.alphaMap.dispose();
                if (node.material.aoMap)            node.material.aoMap.dispose();
                if (node.material.displacementMap)  node.material.displacementMap.dispose();
                if (node.material.emissiveMap)      node.material.emissiveMap.dispose();
                if (node.material.gradientMap)      node.material.gradientMap.dispose();
                if (node.material.metalnessMap)     node.material.metalnessMap.dispose();
                if (node.material.roughnessMap)     node.material.roughnessMap.dispose();

                node.material.dispose ();   // disposes any programs associated with the material
            }
        }
    }
}   // disposeNode

function disposeHierarchy (node, callback)
{
    for (var i = node.children.length - 1; i >= 0; i--)
    {
        var child = node.children[i];
        disposeHierarchy (child, callback);
        callback (child);
    }
}

你使用它

disposeHierarchy (YOUR_OBJECT3D, disposeNode);

这篇关于Three.js Collada - dispose() 和释放内存(垃圾收集)的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆