Actualmente estoy tratando de cambiar la geometría de un cubo en tres js a la de una esfera después de un cierto intervalo de tiempo o un clic de evento. He intentado cambiar la propiedad de la geometría de Three.BoxGeometry a Three.SphereGeometry pero no he tenido suerte. También intenté implementar algunas "soluciones" que encontré, pero también me topé con una pared.
Esto es lo que tenía inicialmente:
export class ThreeJSService { geometry: THREE.BoxGeometry; camera: THREE.PerspectiveCamera; cube: THREE.Mesh; movingObject; renderer: THREE.WebGLRenderer; scene: THREE.Scene; texture: THREE.Texture; /** * Setups scene for 3d objects */ constructor() { this.scene = new THREE.Scene(); this.texture = new THREE.TextureLoader().load('assets/apartment_background.png'); this.scene.background = this.texture; this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); this.renderer = new THREE.WebGLRenderer(); this.geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); const material = new THREE.MeshBasicMaterial( {color: 0x348713} ); this.cube = new THREE.Mesh( this.geometry, material ); this.movingObject = { object: this.cube, geometry: this.geometry, direction: { x: 0.03, y: 0, }, }; } /** * Sets all the requirements needed for the scene * @param {HTMLElement} parent The element to attach to */ setup(parent: HTMLElement) { const canvas = this.renderer.domElement; this.scene.add( this.cube ); this.camera.position.z = 5; parent.appendChild(canvas); } // transform() { // for ( var i = 0, l = this.geometry.vertices.length; i < l; i ++ ) { // // var vertex = this.geometry.vertices[ i ]; // vertex.normalize().multiplyScalar( 550 ); // // // After a certain interval change the geometry from Cylinder to Sphere // // } // } /** * Provides animation to the rendered object. Makes the cube move and sends it to another direction when getting to the border * @param {number | undefined} headerHeight The height of the header */ animate() { const header = document.getElementById('header')?.clientHeight; this.renderer.setSize( window.innerWidth, window.innerHeight - (header ? header : 0)); this.movingObject.object.rotateX(0.01); this.movingObject.object.rotateY(0.01); requestAnimationFrame( this.animate.bind(this) ); this.renderer.render( this.scene, this.camera ); this.movingObject.object.position.x += this.movingObject.direction.x; // Check if the position of the cube is on the border if (this.cube.position.x > 7.3 || this.cube.position.x < -7.3) { this.movingObject.direction.x = -this.movingObject.direction.x; } }¡Cualquier ayuda sería muy apreciada!
Aquí hay un ejemplo en vivo completo que muestra que una geometría se reemplaza después de dos segundos.
let camera, scene, renderer; init(); render(); function init() { camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10); camera.position.set(2, 2, 2); camera.lookAt(0, 0, 0); scene = new THREE.Scene(); geometry = new THREE.BoxGeometry(); material = new THREE.MeshNormalMaterial(); mesh = new THREE.Mesh(geometry, material); scene.add(mesh); renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); setTimeout(function() { mesh.geometry.dispose(); mesh.geometry = new THREE.SphereGeometry(); render(); }, 2000); } function render() { renderer.render(scene, camera); } body { margin: 0; } <script src="https://cdn.jsdelivr.net/npm/three@0.141/build/three.min.js"></script>Me las arreglé para hacerlo funcionar. Esta es mi solución:
changeShape() { this.interval = (Math.floor(Math.random() * (400 + 1)) * 1000); // this.interval = Math.floor((Math.random() * (20 - 10 + 10)) + 10) * 1000; if (this.switch) { setTimeout(() => { this.movingObject.object.geometry.dispose(); this.movingObject.object.geometry = new THREE.CylinderGeometry(0.5, 0.5, 2); this.switch = false; // console.log(this.interval); }, this.interval); } else { setTimeout(() => { this.movingObject.object.geometry.dispose(); this.movingObject.object.geometry = new THREE.SphereGeometry(0.5, 8, 8); this.switch = true; // console.log(this.interval); }, this.interval); } }¡Gracias por la ayuda!