I am very new with three.js and I wanted to do something that looked simple.
I wanted to generate a tube that follows some data points (a sinewave for now) and shift this to the left with a certain speed ( x seconds) . That seems to work but then I want a box, sphere or whatever mesh to not move to the left (x-axis) but only follow the y values (height) of the moving tube. Like if you would shine a spotlight on it. Because I have no clue what the y value is on the path at a certain x value I want to use the raycaster, I looked it up from a few samples etc but I cannot get it to work. Can someone help with this raycaster (see attached code) or has another idea of calculating the y value at a certain x inside the path of a tubegeomerty ? I also tried path.getPointAt(x); but that probably only gives a point at a certain length of the path between 0…1
index.html (2.3 KB)
class CustomSinCurve extends THREE.Curve {
constructor( scale = 1 ) {
super();
this.scale = scale;
}
getPoint( t, optionalTarget = new THREE.Vector3() ) {
const tx = t * 3 - 1.5;
const ty = Math.sin( 2 * Math.PI * t );
const tz = 0;
return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale );
}
}
// Our Javascript will go here.
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
const path = new CustomSinCurve( 10 );
const geometryPipe = new THREE.TubeGeometry( path, 70, 2, 16, false );
const materialPipe = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const meshPipe = new THREE.Mesh( geometryPipe, materialPipe );
scene.add( meshPipe );
// Add some lighting to the scene
var light = new THREE.PointLight( 0xffffff, 1, 100 );
light.position.set( 5, 5, 5 );
scene.add( light );
camera.position.z = 50;
function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
meshPipe.position.x -= 0.1;
// Create a new raycaster
var raycaster = new THREE.Raycaster();
// Set the origin of the ray to the x value you're looking for
var x = 0;
raycaster.set(new THREE.Vector3(x, 0, 0), new THREE.Vector3(0, 1, 0));
// Check if the ray intersects with the tube
var intersects = raycaster.intersectObject(meshPipe);
if (intersects.length > 0) {
var y = intersects[0].point.y;
console.log(y);
}
renderer.render( scene, camera );
}
animate();
</script>
</body>