如何在单个页面上显示多个3D模型?

时间:2018-12-26 07:18:49

标签: javascript three.js collada

我想在Threejs的单个画布中显示两个3d模型。为了完成此任务,我从Threejs官方网站上更改了this example。 此示例非常适合显示几何。

scene.add( new THREE.Mesh( geometry, material ) );

但是当我用

替换它时
var loadingManager = new THREE.LoadingManager();
var loader = new THREE.ColladaLoader( loadingManager );
loader.load( models[i], function ( collada ) {

    scene.add(collada.scene);

} );

连同所有其他必需模型一起出现,但是所有单独的模型都出现在单个场景中。

这是我正在使用的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - multiple elements</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        * {
            box-sizing: border-box;
            -moz-box-sizing: border-box;
        }

        body {
            color: #000;
            font-family:Monospace;
            font-size:13px;

            background-color: #fff;
            margin: 0;
        }

        #info {
            position: absolute;
            top: 0; width: 100%;
            padding: 5px;
            text-align:center;
        }

        #content {
            position: absolute;
            top: 0; width: 100%;
            z-index: 1;
            padding: 3em 0 0 0;
        }

        a {
            color: #0080ff;
        }

        #c {
            position: absolute;
            left: 0;
            width: 100%;
            height: 100%;
        }

        .list-item {
            display: inline-block;
            margin: 1em;
            padding: 1em;
            box-shadow: 1px 2px 4px 0px rgba(0,0,0,0.25);
        }

        .list-item .scene {
            width: 200px;
            height: 200px;
        }

        .list-item .description {
            color: #888;
            font-family: sans-serif;
            font-size: large;
            width: 200px;
            margin-top: 0.5em;
        }
    </style>
</head>
<body>

    <canvas id="c"></canvas>

    <div id="content">
        <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - multiple elements - webgl</div>
    </div>

    <script src="build/three.js"></script>
    <script src="examples/OrbitControls.js"></script>
    <script src="examples/ColladaLoader.js"></script>
    <script src="examples/Detector.js"></script>

    <script id="template" type="notjs">
        <div class="scene"></div>
        <div class="description">Scene $</div>
    </script>
    <script>

        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

        var canvas;

        var scenes = [], renderer;

        init();
        animate();

        function init() {

            canvas = document.getElementById( "c" );

            models = ['elf/elf.dae', 'stormtrooper/stormtrooper.dae']

            var template = document.getElementById( "template" ).text;
            var content = document.getElementById( "content" );

            for ( var i =  0; i < 2; i ++ ) {

                var scene = new THREE.Scene();

                // make a list item
                var element = document.createElement( "div" );
                element.className = "list-item";
                element.innerHTML = template.replace( '$', i + 1 );

                // Look up the element that represents the area
                // we want to render the scene
                scene.userData.element = element.querySelector( ".scene" );
                content.appendChild( element );

                var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10 );
                camera.position.z = 2;
                scene.userData.camera = camera;

                var controls = new THREE.OrbitControls( scene.userData.camera, scene.userData.element );
                controls.minDistance = 2;
                controls.maxDistance = 5;
                controls.enablePan = false;
                controls.enableZoom = false;
                scene.userData.controls = controls;


                // scene.add( new THREE.Mesh( geometry, material ) );
                var loadingManager = new THREE.LoadingManager();
                var loader = new THREE.ColladaLoader( loadingManager );
                loader.load( models[i], function ( collada ) {

                    scene.add(collada.scene);

                } );

                scene.add( new THREE.HemisphereLight( 0xaaaaaa, 0x444444 ) );

                var light = new THREE.DirectionalLight( 0xffffff, 0.5 );
                light.position.set( 1, 1, 1 );
                scene.add( light );

                scenes.push( scene );

            }


            renderer = new THREE.WebGLRenderer( { canvas: canvas, antialias: true } );
            renderer.setClearColor( 0xffffff, 1 );
            renderer.setPixelRatio( window.devicePixelRatio );

        }

        function updateSize() {

            var width = canvas.clientWidth;
            var height = canvas.clientHeight;

            if ( canvas.width !== width || canvas.height !== height ) {

                renderer.setSize( width, height, false );

            }

        }

        function animate() {

            render();
            requestAnimationFrame( animate );

        }

        function render() {

            updateSize();

            canvas.style.transform = `translateY(${window.scrollY}px)`;

            renderer.setClearColor( 0xffffff );
            renderer.setScissorTest( false );
            renderer.clear();

            renderer.setClearColor( 0xe0e0e0 );
            renderer.setScissorTest( true );

            scenes.forEach( function( scene ) {

                // so something moves
                scene.children[ 0 ].rotation.y = Date.now() * 0.001;

                // get the element that is a place holder for where we want to
                // draw the scene
                var element = scene.userData.element;

                // get its position relative to the page's viewport
                var rect = element.getBoundingClientRect();

                // check if it's offscreen. If so skip it
                if ( rect.bottom < 0 || rect.top  > renderer.domElement.clientHeight ||
                     rect.right  < 0 || rect.left > renderer.domElement.clientWidth ) {

                    return;  // it's off screen

                }

                // set the viewport
                var width  = rect.right - rect.left;
                var height = rect.bottom - rect.top;
                var left   = rect.left;
                var top    = rect.top;

                renderer.setViewport( left, top, width, height );
                renderer.setScissor( left, top, width, height );

                var camera = scene.userData.camera;

                //camera.aspect = width / height; // not changing in this example
                //camera.updateProjectionMatrix();

                //scene.userData.controls.update();

                renderer.render( scene, camera );

            } );

        }

    </script>

</body>

然后here可以找到此代码中使用的所有模型和脚本。压缩文件包含所有代码。

0 个答案:

没有答案