wsgg
wsgg

Reputation: 984

Animate / update value of tube geometry path points

I made a TubeGeometry by passing in a SplineCurve3 / CatmullRomCurve3 path as a parameter.

I am trying to update the position of each of the path's points with geometry.parameters.path.points[1].y += 0.01; under requestAnimationFrame.

The values itself updates on console.log but the points dont move. How can i do this?

By the way, i'm not looking to move 'vertices' but rather the points of the path that shape how the tube is rendered.

var camera, scene, light, renderer, geometry, material, mesh;

init();
animate();


function init() {


    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);

	// default bg canvas color //
	renderer.setClearColor(0x00ff00);
	//  use device aspect ratio //
	// renderer.setPixelRatio(window.devicePixelRatio);
	// set size of canvas within window //
	renderer.setSize(window.innerWidth, window.innerHeight);


	// create camera //
	// params = field of view, aspect ratio, clipping of near objects, clipping of far objs 
	camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 3000);
	camera.position.z = 100;
	// create scene 
	scene = new THREE.Scene();

	// create ambient lighting, params -> color, intensity
	light = new THREE.AmbientLight(0xffffff, 0.5)
	// add light to scene
	scene.add(light)
	

	// create line, with params as x,y,z 
	var curve = new THREE.CatmullRomCurve3([
	    new THREE.Vector3( -60, 0, 0 ),
	    new THREE.Vector3( -50, 10, 0 ),
	    new THREE.Vector3( -40, 0, 0 ),
	    new THREE.Vector3( -30, -10, 0 ),
	    new THREE.Vector3( -20, 0, 0 ),
	    new THREE.Vector3( -10, 10, 0 ),
	    new THREE.Vector3( 0, 0, 0 ),
	    new THREE.Vector3( 10, -10, 0 ),
	    new THREE.Vector3( 20, 0, 0 ),
	    new THREE.Vector3( 30, 10, 0 ),
	    new THREE.Vector3( 40, 0, 0 ),
	    new THREE.Vector3( 50, -10, 0 ),
		new THREE.Vector3( 60, 0, 0 )
	]);

	curve.verticesNeedUpdate = true;


	for (i = 0; i < curve.points.length; i++) { 

		// this will get a number between 1 and 10;
		var num = Math.floor(Math.random()*10) + 1;
		num *= Math.floor(Math.random()*2) == 1 ? 1 : -1;

	    curve.points[i].y = num;
	    // console.log(curve.points[i].y);
	}

	geometry = new THREE.TubeGeometry(curve, 1000, 0.2, 8, false);
	geometry.dynamic = true;


	/* standard material */
	material = new THREE.MeshBasicMaterial({ 
		color: 0xff0000
	});

	// create mesh
	mesh = new THREE.Mesh(geometry, material);
	// set positon of line 
	mesh.position.set(0,0,-10);


	// add to scene 
	scene.add(mesh);

	document.body.appendChild(renderer.domElement);



} /* end init */



function onWindowResize() {
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize( window.innerWidth, window.innerHeight );
}

//console.log(geometry.parameters.path.points);


function animate() {

    requestAnimationFrame(animate);
    render();

}


function render() {

	// mesh.rotation.x += 0.01;
	// mesh.rotation.y += 0.01;

	geometry.parameters.path.points[1].y += 0.01;
    geometry.verticesNeedUpdate = true;
	//console.log(geometry.parameters.path.points[1].y)
	


	/* render scene and camera */
	renderer.render(scene,camera);

}
body {
	margin:0;
	overflow: hidden;
} 
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>

Upvotes: 1

Views: 1670

Answers (1)

TheJim01
TheJim01

Reputation: 8876

I wasn't able to get it working using TubeGeometry, but I did with TubeBufferGeometry. Luckily, there isn't much to change, because both use the curve path to define the mesh vertices. You're free to try to replicate this with TubeGeometry instead.

The main problem you're seeing though is that Tube(Buffer)Geometry BUILDS geometry, rather than IS geometry, and that's where the convenience ends. Updating the path does not trigger the geometry to rebuild. Instead, if you update your path, you must recreate the Tube(Buffer)Geometry.

In the code below, all I did was swap TubeBufferGeometry in place of TubeGeometry, changed geometry.verticesNeedUpdated to geometry.needsUpdate (this is how BufferGeometry handles updates), and added the line which re-builds the tube:

geometry.copy(new THREE.TubeBufferGeometry(geometry.parameters.path, 1000, 0.2, 8, false));

var camera, scene, light, renderer, geometry, material, mesh;

init();
animate();


function init() {


    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);

	// default bg canvas color //
	renderer.setClearColor(0x00ff00);
	//  use device aspect ratio //
	// renderer.setPixelRatio(window.devicePixelRatio);
	// set size of canvas within window //
	renderer.setSize(window.innerWidth, window.innerHeight);


	// create camera //
	// params = field of view, aspect ratio, clipping of near objects, clipping of far objs 
	camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 3000);
	camera.position.z = 100;
	// create scene 
	scene = new THREE.Scene();

	// create ambient lighting, params -> color, intensity
	light = new THREE.AmbientLight(0xffffff, 0.5)
	// add light to scene
	scene.add(light)
	

	// create line, with params as x,y,z 
	var curve = new THREE.CatmullRomCurve3([
	    new THREE.Vector3( -60, 0, 0 ),
	    new THREE.Vector3( -50, 10, 0 ),
	    new THREE.Vector3( -40, 0, 0 ),
	    new THREE.Vector3( -30, -10, 0 ),
	    new THREE.Vector3( -20, 0, 0 ),
	    new THREE.Vector3( -10, 10, 0 ),
	    new THREE.Vector3( 0, 0, 0 ),
	    new THREE.Vector3( 10, -10, 0 ),
	    new THREE.Vector3( 20, 0, 0 ),
	    new THREE.Vector3( 30, 10, 0 ),
	    new THREE.Vector3( 40, 0, 0 ),
	    new THREE.Vector3( 50, -10, 0 ),
		new THREE.Vector3( 60, 0, 0 )
	]);

	curve.verticesNeedUpdate = true;


	for (i = 0; i < curve.points.length; i++) { 

		// this will get a number between 1 and 10;
		var num = Math.floor(Math.random()*10) + 1;
		num *= Math.floor(Math.random()*2) == 1 ? 1 : -1;

	    curve.points[i].y = num;
	    // console.log(curve.points[i].y);
	}

	geometry = new THREE.TubeBufferGeometry(curve, 1000, 0.2, 8, false);
	geometry.dynamic = true;


	/* standard material */
	material = new THREE.MeshBasicMaterial({ 
		color: 0xff0000
	});

	// create mesh
	mesh = new THREE.Mesh(geometry, material);
	// set positon of line 
	mesh.position.set(0,0,-10);


	// add to scene 
	scene.add(mesh);

	document.body.appendChild(renderer.domElement);



} /* end init */



function onWindowResize() {
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize( window.innerWidth, window.innerHeight );
}

//console.log(geometry.parameters.path.points);


function animate() {

    requestAnimationFrame(animate);
    render();

}


function render() {

	// mesh.rotation.x += 0.01;
	// mesh.rotation.y += 0.01;

	geometry.parameters.path.points[3].y += 0.01;
  geometry.copy(new THREE.TubeBufferGeometry(geometry.parameters.path, 1000, 0.2, 8, false));
  geometry.needsUpdate = true;
	//console.log(geometry.parameters.path.points[1].y)
	


	/* render scene and camera */
	renderer.render(scene,camera);

}
body {
	margin:0;
	overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>

Upvotes: 2

Related Questions