123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- <body>
- <canvas id="c"></canvas>
- </body>
- <script type="importmap">
- {
- "imports": {
- "three": "../../build/three.module.js",
- "three/addons/": "../../examples/jsm/"
- }
- }
- </script>
- <script type="module">
- import * as THREE from 'three';
- import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
- function main() {
- const canvas = document.querySelector( '#c' );
- const renderer = new THREE.WebGLRenderer( { antialias: true, canvas } );
- const fov = 45;
- const aspect = 2; // the canvas default
- const near = 0.1;
- const far = 10000;
- const camera = new THREE.PerspectiveCamera( fov, aspect, near, far );
- camera.position.set( 0, 1000, 2000 );
- const controls = new OrbitControls( camera, canvas );
- controls.target.set( 0, 5, 0 );
- controls.update();
- const scene = new THREE.Scene();
- scene.background = new THREE.Color( 'black' );
- scene.add( new THREE.GridHelper( 5000, 10 ) );
- let curve;
- let curveObject;
- {
- const controlPoints = [
- [ 1.118281, 5.115846, - 3.681386 ],
- [ 3.948875, 5.115846, - 3.641834 ],
- [ 3.960072, 5.115846, - 0.240352 ],
- [ 3.985447, 5.115846, 4.585005 ],
- [ - 3.793631, 5.115846, 4.585006 ],
- [ - 3.826839, 5.115846, - 14.736200 ],
- [ - 14.542292, 5.115846, - 14.765865 ],
- [ - 14.520929, 5.115846, - 3.627002 ],
- [ - 5.452815, 5.115846, - 3.634418 ],
- [ - 5.467251, 5.115846, 4.549161 ],
- [ - 13.266233, 5.115846, 4.567083 ],
- [ - 13.250067, 5.115846, - 13.499271 ],
- [ 4.081842, 5.115846, - 13.435463 ],
- [ 4.125436, 5.115846, - 5.334928 ],
- [ - 14.521364, 5.115846, - 5.239871 ],
- [ - 14.510466, 5.115846, 5.486727 ],
- [ 5.745666, 5.115846, 5.510492 ],
- [ 5.787942, 5.115846, - 14.728308 ],
- [ - 5.423720, 5.115846, - 14.761919 ],
- [ - 5.373599, 5.115846, - 3.704133 ],
- [ 1.004861, 5.115846, - 3.641834 ],
- ];
- const p0 = new THREE.Vector3();
- const p1 = new THREE.Vector3();
- curve = new THREE.CatmullRomCurve3(
- controlPoints.map( ( p, ndx ) => {
- p0.set( ...p );
- p1.set( ...controlPoints[ ( ndx + 1 ) % controlPoints.length ] );
- return [
- ( new THREE.Vector3() ).copy( p0 ),
- ( new THREE.Vector3() ).lerpVectors( p0, p1, 0.1 ),
- ( new THREE.Vector3() ).lerpVectors( p0, p1, 0.9 ),
- ];
- } ).flat(),
- true,
- );
- {
- const points = curve.getPoints( 250 );
- const geometry = new THREE.BufferGeometry().setFromPoints( points );
- const material = new THREE.LineBasicMaterial( { color: 0xff0000 } );
- curveObject = new THREE.Line( geometry, material );
- curveObject.scale.set( 100, 100, 100 );
- curveObject.position.y = - 621;
- material.depthTest = false;
- curveObject.renderOrder = 1;
- scene.add( curveObject );
- }
- }
- const geometry = new THREE.BoxGeometry( 100, 100, 300 );
- const material = new THREE.MeshBasicMaterial( { color: 'cyan' } );
- const cars = [];
- for ( let i = 0; i < 10; ++ i ) {
- const mesh = new THREE.Mesh( geometry, material );
- scene.add( mesh );
- cars.push( mesh );
- }
- // create 2 Vector3s we can use for path calculations
- const carPosition = new THREE.Vector3();
- const carTarget = new THREE.Vector3();
- function render( time ) {
- time *= 0.001; // convert to seconds
- {
- const pathTime = time * .01;
- const targetOffset = 0.01;
- cars.forEach( ( car, ndx ) => {
- // a number between 0 and 1 to evenly space the cars
- const u = pathTime + ndx / cars.length;
- // get the first point
- curve.getPointAt( u % 1, carPosition );
- carPosition.applyMatrix4( curveObject.matrixWorld );
- // get a second point slightly further down the curve
- curve.getPointAt( ( u + targetOffset ) % 1, carTarget );
- carTarget.applyMatrix4( curveObject.matrixWorld );
- // put the car at the first point (temporarily)
- car.position.copy( carPosition );
- // point the car the second point
- car.lookAt( carTarget );
- // put the car between the 2 points
- car.position.lerpVectors( carPosition, carTarget, 0.5 );
- } );
- }
- renderer.render( scene, camera );
- requestAnimationFrame( render );
- }
- requestAnimationFrame( render );
- }
- main();
- </script>
|