Create a curved plane surface which dynamically changes its size

I could use my approach from the
https://discourse.threejs.org/t/addon-produces-almost-infinite-many-time-varying-geometries-with-functions/262 .
https://github.com/hofk/THREEf.js/tree/master/THREEf_90
Totally simplify. An initial approach.

20190217-1806-31310

A motorway with four lanes is also possible.
20190217-1807-16830

Now you only have to generate the matching coordinates. Here is just a primitive example.


<!DOCTYPE html>
<!-- @author hofk -->
<head>
	<title> road </title>
	<meta charset="utf-8" />
</head>
<body> 	

</body>
	<script src="../js/three.min.101.js"></script>
	<script src="../js/OrbitControls.js"></script>
<script>

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.1, 100 );
camera.position.set( 10, 4, 10 );
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xdddddd, 1 );	
var container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement ); 
var controls = new THREE.OrbitControls( camera, renderer.domElement );

var ls = 100; // length segments
var ws = 2; // width segments, tracks

var lss = ls + 1;
var wss = ws + 1;

var faceCount = ls * ws * 2;
var vertexCount = lss * wss;

var g = new THREE.BufferGeometry( );

g.faceIndices = new Uint32Array( faceCount * 3 );
g.vertices = new Float32Array( vertexCount * 3 );  
//g.normals = new Float32Array( vertexCount * 3 ); 
//g.uvs = new Float32Array( vertexCount * 2 );

g.setIndex( new THREE.BufferAttribute( g.faceIndices, 1 ) );	
g.addAttribute( 'position', new THREE.BufferAttribute( g.vertices, 3 ).setDynamic( true ) );
//g.addAttribute( 'normal', new THREE.BufferAttribute( g.normals, 3 ).setDynamic( true ) );
//g.addAttribute( 'uv', new THREE.BufferAttribute( g.uvs, 2 ) );

var idxCount = 0;

for ( var j = 0; j < ls; j ++ ) {
		
	for ( var i = 0; i < ws; i ++ ) {
		
		// 2 faces / segment,  3 vertex indices
		a =  wss * j + i;
		b1 = wss * ( j + 1 ) + i;	// right-bottom
		c1 = wss * ( j + 1 ) + 1 + i;
		b2 = wss * ( j + 1 ) + 1 + i;	// left-top
		c2 = wss * j + 1 + i;
		
		g.faceIndices[ idxCount     ] = a; // right-bottom
		g.faceIndices[ idxCount + 1 ] = b1;
		g.faceIndices[ idxCount + 2 ] = c1; 
		
		g.faceIndices[ idxCount + 3 ] = a; // left-top
		g.faceIndices[ idxCount + 4 ] = b2,
		g.faceIndices[ idxCount + 5 ] = c2; 
		
		idxCount += 6;
		
	}
		
}

// write groups for multi material
/*
//Customize for different colored tracks.
for ( var f = 0, p = 0; f < faceCount; f ++, p += 3 ) {
	
	g.addGroup( p, 3, 1 );
	
}
 
*/

var x, y, z;
var vIdx = 0; 	// vertex index
var posIdx; // position  index

for ( var j = 0; j < lss; j ++ ) {  // length
		
	for ( var i = 0; i < wss; i ++ ) { // width
		
		// calculate here the coordinates according to your wishes
		x = j / 10;
		y = Math.sin(  Math.PI * j / 100 );
		z = i - 1;
		
		xyzSet();
		
		vIdx ++;
		
	}
	
}


g.attributes.position.needsUpdate = true;
//g.attributes.normal.needsUpdate = true;

var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide, wireframe: true } );
var mesh = new THREE.Mesh( g, material );
scene.add( mesh );

animate();

//............................

// set vertex position
function xyzSet() {
	
	posIdx = vIdx * 3;
	
	g.vertices[ posIdx ]  = x;
	g.vertices[ posIdx + 1 ]  = y;
	g.vertices[ posIdx + 2 ]  = z;
	
}

function animate() {

	requestAnimationFrame( animate );	
	renderer.render( scene, camera );
	controls.update();
	
}
</script>

</html>

The sketch shows the scheme of vertices and faces for 3 tracks and a length of 3.
Here you can also see the bottom and top of the Addon.
20190217-1837-39104

1 Like