简体   繁体   中英

Three.js Change Model Source onclick

im have been playing with the examples but since my knowledge is very limited because im a bit dumb, i cant figure out how to change the Model Source of the OBJLoader on click to load a different a model.

I have created a variable "var: name" and have place it as the en source in " loader.load( 'models/obj/goku/' + name, function"

I want to be able to create anchors where the name of the object is the Text of the anchor, but i am unable to change the source 1st.

Any help is greatly appreciated, thanks.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - loaders - OBJ loader</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link type="text/css" rel="stylesheet" href="main.css">
    </head>

    <body>
        <div id="info">
        <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader test
        </div>
<a onclick="changename('GameBoy');">click</a>
        <script type="module">

            import * as THREE from '../build/three.module.js';

            import { OBJLoader } from './jsm/loaders/OBJLoader.js';

    import { OrbitControls } from './jsm/controls/OrbitControls.js';

            var container;

            var camera, scene, renderer;

            var mouseX = 0, mouseY = 0;

            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;
var controls;
            var object;

var name ="Engine.obj";


             init();
            animate();

function changename(newname){

name = newname;

}


            function init() {

                container = document.createElement( 'div' );
                document.body.appendChild( container );

                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.z = 250;

                // scene

                scene = new THREE.Scene();

                var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
                scene.add( ambientLight );

                var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
                camera.add( pointLight );
                scene.add( camera );



                // manager

                function loadModel() {

                    object.traverse( function ( child ) {

                        if ( child.isMesh ) child.material.map = texture;

                    } );

                    object.position.y = -20;
                    scene.add( object );

                }

                var manager = new THREE.LoadingManager( loadModel );

                manager.onProgress = function ( item, loaded, total ) {

                    console.log( item, loaded, total );

                };

                // texture

                var textureLoader = new THREE.TextureLoader( manager );

                var texture = textureLoader.load( 'textures/hardwood2_diffuse.jpg' );

                // model

                function onProgress( xhr ) {

                    if ( xhr.lengthComputable ) {

                        var percentComplete = xhr.loaded / xhr.total * 100;
                        console.log( 'model ' + Math.round( percentComplete, 2 ) + '% downloaded' );

                    }

                }

                function onError() {}

                var loader = new OBJLoader( manager );

                loader.load( 'models/obj/goku/' + name, function ( obj ) {

                    object = obj;
object.position.x = 0;
object.position.z = 1;
object.scale.set(0.5,0.5,0.5);


                }, onProgress, onError );

                //

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );

                // document.addEventListener( 'mousemove', onDocumentMouseMove, false );

                //

                window.addEventListener( 'resize', onWindowResize, false );


                // controls

                controls = new OrbitControls( camera, renderer.domElement );

                //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)

                controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
                controls.dampingFactor = 0.05;

                // controls.screenSpacePanning = true;

                // controls.minDistance = 100;
                // controls.maxDistance = 500;

                // controls.maxPolarAngle = Math.PI / 2;
            }

            function onWindowResize() {

                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

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

            }



            // function onDocumentMouseMove( event ) {
            //
            //  mouseX = ( event.clientX - windowHalfX ) / 2;
            //  mouseY = ( event.clientY - windowHalfY ) / 2;
            //
            // }

            //

            function animate() {

                requestAnimationFrame( animate );
                render();

            }

            function render() {

                // camera.position.x += ( mouseX - camera.position.x ) * .05;
                // camera.position.y += ( - mouseY - camera.position.y ) * .05;

                // camera.lookAt( scene.position );

                renderer.render( scene, camera );
controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true

            }

        </script>

    </body>
</html>

When working with modules, you can't refer to module scope functions like so:

<a onclick="changename('GameBoy');">click</a>

That does not work since changename() only exists in module but not in global scope. You have to add the click event listener by defining an id for your link/button and then select it like so:

const element = document.getElementById( 'myButton' );
element.addEventListener( 'click', changename );

Notice that you can't pass the newname parameter like in your original code. Consider to store it in a data attribute if you want to reuse the function.

Even if you register the event listener like that, your code will not work as intended. Simply because changename() only changes the name but does not trigger a new call of OBJLoader.load() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM