Как сделать переключение моделей без подключения GUI?

Мне нужно чтобы осуществлялось переключение 3D моделей без подключения {GUI} dat.gui.js. Т.е в данный момент модели переключаются в выпадающем списке select в GUI интерфейсе. Нужно чтобы переключение происходило без GUI в моей разметке по клику на button type="radio". Помогите пожалуйста, как это можно сделать? Код прилагается.

import * as THREE from './three.module.js';
import { GUI } from './dat.gui.module.js';
import { OrbitControls } from './OrbitControls.js';
import { GLTFLoader } from './GLTFLoader.js';
import { DDSLoader } from './DDSLoader.js';
import { DRACOLoader } from './DRACOLoader.js';
import { RGBELoader } from './RGBELoader.js';


var orbitControls;
			var container, camera, scene, renderer, loader;
			var gltf, background, envMap, mixer, gui, extensionControls;
            var clock = new THREE.Clock();
			var base_path = '/wp-content/themes/store/models/';

// Object info
let pack = { 
'293x273x21': {
url: base_path+'pack/293x273x21.gltf', cameraPos: new THREE.Vector3( 0.01, 0.3, 0.45 ), objectRotation: new THREE.Euler( 0, 3.2, 0 ), extensions: [ 'glTF' ], addEnvMap: true, addLights: true },
'300x200x40': {
    url: base_path+'pack/300x200x40.gltf',
    cameraPos: new THREE.Vector3( 0.01, 0.3, 0.45 ),
    objectRotation: new THREE.Euler( 0, 0, 0 ),
    extensions: [ 'glTF' ],
    addEnvMap: true,
    addLights: true
}};

let pencil =  { 
'71x27x187' :{url: base_path+'pencil/71x27x187.gltf',  models: 'cover_box', cameraPos: new THREE.Vector3( 0.01, 0.25, 0.2 ), objectRotation: new THREE.Euler( 0, 3.2, 0 ), extensions: [ 'glTF' ], addEnvMap: true, addLights: true}};

let hidden = { 
'85x80x60' : {
url: base_path+'hidden/85x80x60.gltf', models: 'hidden_box', cameraPos: new THREE.Vector3( 0.1, 0.2, 0.3 ), objectRotation: new THREE.Euler( 0, 3.2, 0 ), extensions: [ 'glTF' ], addEnvMap: true, addLights: true},
'90x50x32': {
	url: base_path+'/hidden/90x50x32.gltf',
    cameraPos: new THREE.Vector3( 0.01, 0.3, 0.2 ),
    objectRotation: new THREE.Euler( 0, 0, 0 ),
    extensions: [ 'glTF' ],
    addEnvMap: true,
    addLights: true
}};
let cover =  { 
'250х40х220' :{id: 'cover',   url: base_path+'cover/250x40x220.gltf',  models: 'cover_box', cameraPos: new THREE.Vector3( 0.01, 0.25, 0.2 ), objectRotation: new THREE.Euler( 0, 3.2, 0 ), extensions: [ 'glTF' ], addEnvMap: true, addLights: true}};

var scenes = [];

var counter = 0;

// Object URL init
let url1 = window.location.href; 
const splittedUrl = url1.split("?");
let id = splittedUrl[splittedUrl.length - 1];
if (id === url1) {
  scenes = pack;
}
else if (id === 'pack') {
  scenes = pack;
}
else if (id === 'pencil') {
  scenes = pencil;
}
else if (id === 'hidden') {
  scenes = hidden;
}
else if (id === 'cover') {
  scenes = cover;
}
// Size ID
var sizeID;
let box = document.getElementsByName(id);
box.forEach(box => {
    box.addEventListener('click', e => {
    const data_id = e.target.getAttribute('data-id');
    const size_val = e.target.getAttribute('value');
    counter = data_id;
    sizeID = size_val;
    console.log('Size: ' +size_val)
	})});
	
	// State
		var state = {
				scene: Object.keys( scenes )[ 0 ],
                extension: scenes[ Object.keys( scenes )[ 0 ] ].extensions[ 0 ],
                playAnimation: true,
			};

			function onload() {
				// container = document.getElementsByClassName( 'figure_3d' );
				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.outputEncoding = THREE.sRGBEncoding;
				renderer.physicallyCorrectLights = true;
                container = document.querySelector('.figure_3d');
                container.append( renderer.domElement );

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

				// Load background and generate envMap

				new RGBELoader()
					.setDataType( THREE.UnsignedByteType )
					.load(base_path+'venice_sunset_1k.hdr', function ( texture ) {

						envMap = pmremGenerator.fromEquirectangular( texture ).texture;
						pmremGenerator.dispose();

						background = envMap;

						//

						buildGUI();
						initScene( scenes[ state.scene ] );
						animate();

					} );

				var pmremGenerator = new THREE.PMREMGenerator( renderer );
				pmremGenerator.compileEquirectangularShader();

			}

			function initScene( sceneInfo ) {

				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0xFFFFFF );

				camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 0.001, 1000 );
				scene.add( camera );

				var spot1;

				if ( sceneInfo.addLights ) {
					var ambient = new THREE.AmbientLight( 0x222222 );
					scene.add( ambient );

					var directionalLight = new THREE.DirectionalLight( 0xdddddd, 4 );
					directionalLight.position.set( 0, 0, 1 ).normalize();
					scene.add( directionalLight );

					spot1 = new THREE.SpotLight( 0xffffff, 1 );
					spot1.position.set( 5, 10, 5 );
					spot1.angle = 0.50;
					spot1.penumbra = 0.75;
					spot1.intensity = 100;
					spot1.decay = 2;

					if ( sceneInfo.shadows ) {

						spot1.castShadow = true;
						spot1.shadow.bias = 0.0001;
						spot1.shadow.mapSize.width = 2048;
						spot1.shadow.mapSize.height = 2048;

					}

					scene.add( spot1 );

				}

				if ( sceneInfo.shadows ) {

					renderer.shadowMap.enabled = true;
					renderer.shadowMap.type = THREE.PCFSoftShadowMap;

				}

				// TODO: Reuse existing OrbitControls, GLTFLoaders, and so on

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

				if ( sceneInfo.addGround ) {

					var groundMaterial = new THREE.MeshPhongMaterial( { color: 0xFFFFFF } );
					var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry( 512, 512 ), groundMaterial );
					ground.receiveShadow = !! sceneInfo.shadows;

					if ( sceneInfo.groundPos ) {

						ground.position.copy( sceneInfo.groundPos );

					} else {

						ground.position.z = - 70;

					}

					ground.rotation.x = - Math.PI / 2;

					scene.add( ground );

				}
           // manager      

				loader = new GLTFLoader();
				var dracoLoader = new DRACOLoader();
				dracoLoader.setDecoderPath( './libs/draco/gltf/' );
				loader.setDRACOLoader( dracoLoader );

				loader.setDDSLoader( new DDSLoader() );

        var url = sceneInfo.url.replace( /%s/g, state.extension );

				if ( state.extension === 'glTF-Binary' ) {

					url = url.replace( '.gltf', '.glb' );

        }

				var loadStartTime = performance.now();

				loader.load( url, function ( data ) {

					gltf = data;

					var object = gltf.scene;

                    var basePath = '/wp-content/themes/store/models/';
                    // texture
                    var textures = [];
                  
                    var textureLoader = new THREE.TextureLoader();
                    textures.push(
                      textureLoader.load(basePath+'materials/white.png'),
                      textureLoader.load(basePath+'materials/grey.png'),
                      textureLoader.load(basePath+'materials/craft.png')
                      );
                      material_1.addEventListener("click", function(){setTexture(0);});
                      material_2.addEventListener("click", function(){setTexture(1);});
                      material_3.addEventListener("click", function(){setTexture(2);});
                    function setTexture (texIdx){
                        object.traverse(function(object) {
                          if (object.isMesh) {
                            object.material.map = textures[texIdx];
                          }
                        });
                      }
                    // setTexture(counter);
					console.info( 'Load time: ' + ( performance.now() - loadStartTime ).toFixed( 2 ) + ' ms.' );

					if ( sceneInfo.cameraPos ) {

						camera.position.copy( sceneInfo.cameraPos );

					}

					if ( sceneInfo.center ) {

						orbitControls.target.copy( sceneInfo.center );

					}

					if ( sceneInfo.objectPosition ) {

						object.position.copy( sceneInfo.objectPosition );

						if ( spot1 ) {

							spot1.target.position.copy( sceneInfo.objectPosition );

						}

					}

					if ( sceneInfo.objectRotation ) {

						object.rotation.copy( sceneInfo.objectRotation );

					}

					if ( sceneInfo.objectScale ) {

						object.scale.copy( sceneInfo.objectScale );

					}

					object.traverse( function ( node ) {

						if ( node.isMesh || node.isLight ) node.castShadow = true;

					} );

					var animations = gltf.animations;

					if ( animations && animations.length ) {

						mixer = new THREE.AnimationMixer( object );

						for ( var i = 0; i < animations.length; i ++ ) {

							var animation = animations[ i ];

							// There's .3333 seconds junk at the tail of the Monster animation that
							// keeps it from looping cleanly. Clip it at 3 seconds
							if ( sceneInfo.animationTime ) {

								animation.duration = sceneInfo.animationTime;

							}

							var action = mixer.clipAction( animation );

							if ( state.playAnimation ) action.play();

						}

					}

					scene.add( object );
					onWindowResize();

				}, undefined, function ( error ) {

					console.error( error );

				} );

			}
            function onWindowResize() {
                const maxValue = 550;
                var w = window.innerWidth;
                var h = window.innerHeight;
                w = innerWidth < maxValue ? innerWidth : maxValue;
                h = innerWidth < maxValue ? innerWidth : maxValue;
                // camera.aspect = container.offsetWidth / container.offsetHeight;
                camera.aspect = w / h;
                camera.updateProjectionMatrix();
                
                renderer.setSize( w, h );
                console.log('Object resized: ' + w + 'x' + h);
            
              }

			function animate() {

				requestAnimationFrame( animate );

				if ( mixer ) mixer.update( clock.getDelta() );

				orbitControls.update();

				render();

			}

			function render() {

				renderer.render( scene, camera );

			}

			function buildGUI() {
				gui = new GUI( { width: 330 } );
				gui.domElement.container;
                
				var sceneCtrl = gui.add( state, 'scene', Object.keys( scenes ) );
				sceneCtrl.onChange( reload );

				var animCtrl = gui.add( state, 'playAnimation' );
				animCtrl.onChange( toggleAnimations );

				updateGUI();

			}

			function updateGUI() {

				if ( extensionControls ) extensionControls.remove();

				var sceneInfo = scenes[ state.scene ];

				if ( sceneInfo.extensions.indexOf( state.extension ) === - 1 ) {

					state.extension = sceneInfo.extensions[ 0 ];

				}

				extensionControls = gui.add( state, 'extension', sceneInfo.extensions );
				extensionControls.onChange( reload );

			}

			function toggleAnimations() {

				for ( var i = 0; i < gltf.animations.length; i ++ ) {

					var clip = gltf.animations[ i ];
					var action = mixer.existingAction( clip );

					state.playAnimation ? action.play() : action.stop();

				}

			}

			function reload() {

				if ( loader && mixer ) mixer.stopAllAction();

				updateGUI();
				initScene( scenes[ state.scene ] );

			}

			onload();
> Здесь в зависимости от выбранной модели генерируются input'ы со
> значениями из базы. Их может быть 1-2, так и может быть 3-5 и более.
> Для этого написал функцию которая получает data-id или value текущей
> кликнутой кнопки и можно перезаписывать переменную для замены url'a
> или имени модели. Сейчас все модели захардкодил, но в идеале получать
> их json'ом.
> В идеале, если бы можно было кликая на кнопку выбора размера
> перезаписывать в переменных путь и имя модели, и не хранить данные о
> всех моделях. И после обновлять её на странице.

<div class="box_size">               
      <div class="col_size radio_type_1">
          <input name="pack" id="size_0_pack" data-id="0" type="radio" value="293x273x21">
          <label for="size_0_pack">293x273x21</label>
      </div>   
      <div class="col_size radio_type_1">
          <input name="pack" id="size_1_pack" data-id="1" type="radio" value="300x200x40">
          <label for="size_1_pack">300x200x40</label>
      </div>
</div>


Ответы (0 шт):