楊理翔
楊理翔

Reputation: 21

Syntax problem when using THREE.TextureLoader

I'm trying a panoramic viewer code which its three.js version is r68,and I update the three.js version into r121 in order to use raycaster function. The problem happen when I revise the code:

var texture = THREE.ImageUtils.loadTexture('img/pano2.jpg', new THREE.UVMapping(), function() { 
init();
animate();                                                                                                        
});

into

var loader = new THREE.TextureLoader();
loader.load(
    'img/demo.jpg',
    function(texture){
        var material = new THREE.MeshBasicMaterial({map: texture});
},
    function(){
        init();
        animate();
},
    function ( err ) {
        console.error( 'An error happened.' );
    }
);

No error pop up but the render function(included in init function) and animate function doesn't progress. I'm not sure it's texture's problem or init function's problem. If somebody can give me some suggestion, I'll be really grateful.

I take this as my reference:

  1. https://threejs.org/docs/#api/en/loaders/TextureLoader

  2. Three.TextureLoader is not loading images files

And here is my full code:

<!DOCTYPE html>
<html>
    <head>
        <title>Panorama1</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            html{
                margin: 0;
                padding: 0;      
                text-align: center;
            }
            body {
                font-size: 18px;
                line-height: 1.5em;
                position: relative;
                width: 100%;
                height: 100%;
                margin: 40px auto;
                padding: 0;
                display: inline-block;
                /*max-width: 100%;
                /*max-width: 1440px;*/
                overflow-x: hidden;
            }
            a{
                color: #528CE0;
            }
            #demo{
                /* comment for fixed dimentsions */
                position: relative;
                width: 1440px;
                height: 650px;

                margin: 0 auto;
                overflow: hidden;
                cursor: move; /* fallback if grab cursor is unsupported */
                cursor: grab;
                cursor: -moz-grab;
                cursor: -webkit-grab;
            }
            #demo:active { 
                cursor: grabbing;
                cursor: -moz-grabbing;
                cursor: -webkit-grabbing;
            }
            #log{
                position: absolute;
                background: #fff;
                padding: 20px;
                bottom: 20px;
                left: 20px;
                width: 150px;
                font: normal 12px/18px Monospace, Arial, Helvetical, sans-serif;
                text-align: left;
                border: 3px double #ddd;
            }
            #description{
                display: inline-block;
                width: 100%;
                max-width: 600px;
                text-align: left;
            }
        </style>
    </head>
    <body>
        <h1>A panoramic experiment with Three.JS</h1>
        <h2>pano1</h2>
        <div id="demo">
            <div id="log"></div>
        </div>        
        <div id="description">
        </div>
        <script src="libs/threejs/build/three.min.js"></script>
        <script>
            "use strict";
            var camera,
            scene,
            element = document.getElementById('demo'), // Inject scene into this
            renderer,
            onPointerDownPointerX,
            onPointerDownPointerY,
            onPointerDownLon,
            onPointerDownLat,
            fov = 45, // Field of View
            isUserInteracting = false,
            lon = 0,
            lat = 0,
            phi = 0,
            theta = 0,
            onMouseDownMouseX = 0,
            onMouseDownMouseY = 0,
            onMouseDownLon = 0,
            onMouseDownLat = 0,
            width = 1440, // int || window.innerWidth
            height = 650, // int || window.innerHeight
            ratio = width / height;
            var mouse = new THREE.Vector2();
            var loader = new THREE.TextureLoader();
            loader.load(
                'img/demo.jpg',
                function(texture){
                    var material = new THREE.MeshBasicMaterial({map: texture});
                },
                function(){
                    init();
                    animate();
                },
                function ( err ) {
                console.error( 'An error happened.' );
                }
            );
            //const loader = new THREE.TextureLoader();

            //var texture = THREE.ImageUtils.loadTexture('img/pano2.jpg', new THREE.UVMapping(), function() {
            //init();
            //animate();
            //});
            function init() {
                camera = new THREE.PerspectiveCamera(fov, ratio, 1, 1000);
                scene = new THREE.Scene();
                var mesh = new THREE.Mesh(new THREE.SphereGeometry(500, 60, 40), material);
                mesh.scale.x = -1;
                scene.add(mesh);
                renderer = new THREE.WebGLRenderer({antialias: true});
                renderer.setSize(width, height);
                element.appendChild(renderer.domElement);
                element.addEventListener('mousedown', onDocumentMouseDown, false);
                element.addEventListener('mousewheel', onDocumentMouseWheel, false);
                element.addEventListener('DOMMouseScroll', onDocumentMouseWheel, false);
                window.addEventListener('resize', onWindowResized, false);
                onWindowResized(null);
            }
        
            function animate() {
                requestAnimationFrame(animate);
                render();
            }
            function render() {
                var raycaster = new THREE.Raycaster();
                raycaster.setFromCamera( mouse, camera );
                lat = Math.max(-85, Math.min(85, lat));
                phi = THREE.Math.degToRad(90 - lat);
                theta = THREE.Math.degToRad(lon);
                camera.position.x = 100 * Math.sin(phi) * Math.cos(theta);
                camera.position.y = 100 * Math.cos(phi);
                camera.position.z = 100 * Math.sin(phi) * Math.sin(theta);
                var log = ("x: " + camera.position.x);
                log = log + ("<br/>y: " + camera.position.y);
                log = log + ("<br/>z: " + camera.position.z);
                log = log + ("<br/>fov: " + fov);
                document.getElementById('log').innerHTML = log;
                camera.lookAt(scene.position);
                renderer.render(scene, camera);
            }
            function onWindowResized(event) {
            //    renderer.setSize(window.innerWidth, window.innerHeight);
            //    camera.projectionMatrix.makePerspective(fov, window.innerWidth / window.innerHeight, 1, 1100);
                renderer.setSize(width, height);
                camera.updateProjectionMatrix();
            }
            function onDocumentMouseDown(event) {
                event.preventDefault();
                onPointerDownPointerX = event.clientX;
                onPointerDownPointerY = event.clientY;
                onPointerDownLon = lon;
                onPointerDownLat = lat;
                isUserInteracting = true;
                element.addEventListener('mousemove', onDocumentMouseMove, false);
                element.addEventListener('mouseup', onDocumentMouseUp, false);
            }
            function onDocumentMouseMove(event) {
                if (fov < 10){
                lon = (event.clientX - onPointerDownPointerX) * -0.01 + onPointerDownLon;
                lat = (event.clientY - onPointerDownPointerY) * -0.01 + onPointerDownLat;
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
                }
                else{
                lon = (event.clientX - onPointerDownPointerX) * -0.175 + onPointerDownLon;
                lat = (event.clientY - onPointerDownPointerY) * -0.175 + onPointerDownLat;
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
                }
            }
            function onDocumentMouseUp(event) {
                isUserInteracting = false;
                element.removeEventListener('mousemove', onDocumentMouseMove, false);
                element.removeEventListener('mouseup', onDocumentMouseUp, false);
            }
            function onDocumentMouseWheel(event) {
                // WebKit
                if (event.wheelDeltaY) {
                    fov -= event.wheelDeltaY * 0.05;
                 // Opera / Explorer 9
                } else if (event.wheelDelta) {
                    fov -= event.wheelDelta * 0.05;
                    // Firefox
                } else if (event.detail) {
                    fov += event.detail * 1.0;
                }
                if (fov < 1 || fov > 55) {
                    fov = (fov < 1) ? 1 : 55;
                }
                camera.updateProjectionMatrix();

            }
        </script> 
    </body>
</html>

The origin code is :

<!DOCTYPE html>
<html>
    <head>
        <title>Panorama2</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            html{
                margin: 0;
                padding: 0;      
                text-align: center;
            }
            body {
                font-size: 18px;
                line-height: 1.5em;
                position: relative;
                width: 100%;
                height: 100%;
                margin: 40px auto;
                padding: 0;
                display: inline-block;
                /*max-width: 100%;
                /*max-width: 1440px;*/
                overflow-x: hidden;
            }
            a{
                color: #528CE0;
            }
            #demo{
                /* comment for fixed dimentsions */
                position: relative;
                width: 1440px;
                height: 650px;

                margin: 0 auto;
                overflow: hidden;
                cursor: move; /* fallback if grab cursor is unsupported */
                cursor: grab;
                cursor: -moz-grab;
                cursor: -webkit-grab;
            }
            #demo:active { 
                cursor: grabbing;
                cursor: -moz-grabbing;
                cursor: -webkit-grabbing;
            }
            #log{
                position: absolute;
                background: #fff;
                padding: 20px;
                bottom: 20px;
                left: 20px;
                width: 150px;
                font: normal 12px/18px Monospace, Arial, Helvetical, sans-serif;
                text-align: left;
                border: 3px double #ddd;
            }
            #description{
                display: inline-block;
                width: 100%;
                max-width: 600px;
                text-align: left;
            }
        </style>
    </head>
    <body>
        <h1>A panoramic experiment with Three.JS</h1>
        <h2>pano2</h2>
        <div id="demo">
            <div id="log"></div>
        </div>        
        <div id="description">
        </div>
        <script src="libs/threejs/build/three.min.js"></script>
        <script>
            "use strict";
            var camera,
            scene,
            element = document.getElementById('demo'), // Inject scene into this
            renderer,
            onPointerDownPointerX,
            onPointerDownPointerY,
            onPointerDownLon,
            onPointerDownLat,
            fov = 45, // Field of View
            isUserInteracting = false,
            lon = 0,
            lat = 0,
            phi = 0,
            theta = 0,
            onMouseDownMouseX = 0,
            onMouseDownMouseY = 0,
            onMouseDownLon = 0,
            onMouseDownLat = 0,
            width = 1440, // int || window.innerWidth
            height = 650, // int || window.innerHeight
            ratio = width / height;
            var texture = THREE.ImageUtils.loadTexture('img/pano2.jpg', new THREE.UVMapping(), function() {
            init();
            animate();
            });
            function init() {
                camera = new THREE.PerspectiveCamera(fov, ratio, 1, 1000);
                scene = new THREE.Scene();
                var mesh = new THREE.Mesh(new THREE.SphereGeometry(500, 60, 40), new THREE.MeshBasicMaterial({map: texture}));
                mesh.scale.x = -1;
                scene.add(mesh);
                renderer = new THREE.WebGLRenderer({antialias: true});
                renderer.setSize(width, height);
                element.appendChild(renderer.domElement);
                element.addEventListener('mousedown', onDocumentMouseDown, false);
                element.addEventListener('mousewheel', onDocumentMouseWheel, false);
                element.addEventListener('DOMMouseScroll', onDocumentMouseWheel, false);
                window.addEventListener('resize', onWindowResized, false);
                onWindowResized(null);
            }
            function onWindowResized(event) {
            //    renderer.setSize(window.innerWidth, window.innerHeight);
            //    camera.projectionMatrix.makePerspective(fov, window.innerWidth / window.innerHeight, 1, 1100);
                renderer.setSize(width, height);
                camera.projectionMatrix.makePerspective(fov, ratio, 1, 1100);
            }
            function onDocumentMouseDown(event) {
                event.preventDefault();
                onPointerDownPointerX = event.clientX;
                onPointerDownPointerY = event.clientY;
                onPointerDownLon = lon;
                onPointerDownLat = lat;
                isUserInteracting = true;
                element.addEventListener('mousemove', onDocumentMouseMove, false);
                element.addEventListener('mouseup', onDocumentMouseUp, false);
            }
            function onDocumentMouseMove(event) {
                if (fov < 10){
                lon = (event.clientX - onPointerDownPointerX) * -0.01 + onPointerDownLon;
                lat = (event.clientY - onPointerDownPointerY) * -0.01 + onPointerDownLat;
                }
                else{
                lon = (event.clientX - onPointerDownPointerX) * -0.175 + onPointerDownLon;
                lat = (event.clientY - onPointerDownPointerY) * -0.175 + onPointerDownLat;
                }
            }
            function onDocumentMouseUp(event) {
                isUserInteracting = false;
                element.removeEventListener('mousemove', onDocumentMouseMove, false);
                element.removeEventListener('mouseup', onDocumentMouseUp, false);
            }
            function onDocumentMouseWheel(event) {
                // WebKit
                if (event.wheelDeltaY) {
                    fov -= event.wheelDeltaY * 0.05;
                 // Opera / Explorer 9
                } else if (event.wheelDelta) {
                    fov -= event.wheelDelta * 0.05;
                    // Firefox
                } else if (event.detail) {
                    fov += event.detail * 1.0;
                }
                if (fov < 1 || fov > 55) {
                    fov = (fov < 1) ? 1 : 55;
                }
                camera.projectionMatrix.makePerspective(fov, ratio, 1, 1100);
            }
            function animate() {
                requestAnimationFrame(animate);
                render();
            }
            function render() {
                lat = Math.max(-85, Math.min(85, lat));
                phi = THREE.Math.degToRad(90 - lat);
                theta = THREE.Math.degToRad(lon);
                camera.position.x = 100 * Math.sin(phi) * Math.cos(theta);
                camera.position.y = 100 * Math.cos(phi);
                camera.position.z = 100 * Math.sin(phi) * Math.sin(theta);
                var log = ("x: " + camera.position.x);
                log = log + ("<br/>y: " + camera.position.y);
                log = log + ("<br/>z: " + camera.position.z);
                log = log + ("<br/>fov: " + fov);
                document.getElementById('log').innerHTML = log;
                camera.lookAt(scene.position);
                renderer.render(scene, camera);
            }
    
        </script> 
    </body>
</html>

Here is the link to the source code:

https://github.com/NorikDavtian/ThreeJS-360-Panorama

Thanks for your reading !

update: after trying @prisoner849 's suggestion,the init function and animate function run properly,but the scene still in black both in Chorme or firefox enter image description here

Upvotes: 2

Views: 434

Answers (1)

prisoner849
prisoner849

Reputation: 17596

Try it this way:

var material; // as a global variable

...

loader.load(
    'img/demo.jpg',
    function(texture){
        material = new THREE.MeshBasicMaterial({map: texture});
        init();
        animate();
    },
    undefined,
    function ( err ) {
        console.error( 'An error happened.' );
    }
);

In your current option, you call init() and animate() in onProgress callback. Whereas you need to call them in onLoad, thus right after material = new THREE.MeshBasicMaterial({map: texture});.

Upvotes: 2

Related Questions