Updating the coordinates of specific verticies of an object

Hey, I have built up a scene in three.js that essentially is just a camera spinning around an imported obj file.

Ideally I want to create a function that updates the coordinates of some of their vertices of the object (to specifically warp certain areas of the mesh by multiplying the x, y and z coordinates by a scalar value), but I’m lost at how to access the vertices from my imported obj, and then how they can be updated every frame (because from what I could tell from my research there is a special way to update an object’s geometry by deleting the old geometry and creating a new one or something similar.

I’d like to apologize in advance if its something obvious, as I am relatively new to three and I’ve been trying to find a solution of this on-and-off for a month and couldn’t find anything on stackoverflow or otherwise. I feel like I am also confusing the object and the geometry of the object, which wouldnt help.

My main.js can be found below, and the current state of the animation can be found here.

Thanks :slight_smile: ,
Matt

var yourAudio = document.getElementById('myAudio'),
	ctrl = document.getElementById('button'),
	isPlaying = false;

ctrl.onclick = function () {
	if (isPlaying) {
		yourAudio.pause();
		isPlaying = false;
	} else {
		yourAudio.play();
		isPlaying = true;
	}
};

//

var container;

var camera, scene, renderer;

var mouseX = 0, mouseY = 0;

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

var object;

init();
animate();


function init() {

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

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

	// 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 = 0;
		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/UV_Grid_Sm.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 THREE.OBJLoader( manager );

	loader.load( 'models/obj/low poly brain only.obj', function ( obj ) {

		object = obj;

	}, 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 );
	//document.addEventListener( 'timeadvance', getMilliseconds(), 0 );

	//

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

}

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() {

	if (isPlaying) {
		var x = camera.position.x;
		var z = camera.position.z;
	
		camera.position.x = x * Math.cos(0.01) + z * Math.sin(0.01);
		camera.position.z = z * Math.cos(0.01) - x * Math.sin(0.01);

		camera.lookAt( scene.position );
	};
	
	obj.geometry
	renderer.render( scene, camera );

}

Hi!
Could you add explanatory pictures of the desired effect/result?
So far, it’s not so clear what you want to achieve.

1 Like

Yeah sure, sorry.

You can find it running here
(click anywhere except the buttons to play)

My final goal is for the mesh to act sort of like an audio visualizer, that expands and contracts essentially based on the volume of audio playing through the browser.

So for example, I would like to have the whole object increase in size (scale).

If possible I also want to move different parts of mesh differently (eg the top and bottom moving independently of the middle) if possible.

So I guess I’m wondering:

  • How to scale the size of the whole object
  • How to move different groups of vertices of the same object differently

When I visualize it I assume it would look sort of like a heart beating, where the majority of the heart moves every beat, but some parts move more than others.

Thanks

The whole object scaling is
obj.scale.setScalar( scaling_value )
it will scale your object uniformly on all axes.

Or you can use
obj.scale.set ( xscale, yscale, zscale ) independent scaling on axes.

But for operating with group of vertices, the way I see is using shaders.

1 Like