Как анимировать в колебании поверхность N в три. js - PullRequest
1 голос
/ 05 февраля 2020

Я хочу создать NURBS-поверхность, анимированную с помощью Three. js.

Это моя инициализация NURBS:

this.nsControlPoints = [
      [
        new THREE.Vector4 ( -20, -20, 10, 1 ),
        new THREE.Vector4 ( -20, -10, -20, 1 ),
        new THREE.Vector4 ( -20, 10, 25, 1 ),
        new THREE.Vector4 ( -20, 20, -10, 1 )
      ],
      [
        new THREE.Vector4 ( 0, -20, 0, 1 ),
        new THREE.Vector4 ( 0, -10, -10, 5 ),
        new THREE.Vector4 ( 0, 10, 15, 5 ),
        new THREE.Vector4 ( 0, 20, 0, 1 )
      ],
      [
        new THREE.Vector4 ( 20, -20, -10, 1 ),
        new THREE.Vector4 ( 20, -10, 20, 1 ),
        new THREE.Vector4 ( 20, 10, -25, 1 ),
        new THREE.Vector4 ( 20, 20, 10, 1 )
      ]
    ];
    var degree1 = 2;
    var degree2 = 3;
    var knots1 = [0, 0, 0, 1, 1, 1];
    var knots2 = [0, 0, 0, 0, 1, 1, 1, 1];
    this.nurbsSurface = new NURBSSurface(degree1, degree2, knots1, knots2, this.nsControlPoints);

    var map = new THREE.TextureLoader().load( 'assets/img/tile.jpg' );
    map.wrapS = map.wrapT = THREE.RepeatWrapping;
    map.anisotropy = 16;

    let nurbsSurface = this.nurbsSurface;
    let start = this.start;

    function getSurfacePoint(u, v, target) {

      return nurbsSurface.getPoint(u, v, target);

    }

    this.geometry = new THREE.ParametricBufferGeometry( getSurfacePoint, 20, 20 );
    var material = new THREE.MeshBasicMaterial( { wireframe: true, color: 0x666666, opacity: 1.0 } );
    this.objectSurface = new THREE.Mesh( this.geometry, material );
    this.objectSurface.position.set( - 200, -100, 0 );
    this.objectSurface.rotateX(90);
    this.objectSurface.scale.multiplyScalar( 50 );
    this.scene.add( this.objectSurface );

И это то, что я пытался сделать анимацию:

...
var position = this.geometry.attributes.position;
position.setXYZ(1, position.x + ( Date.now() - this.start ), position.y + ( Date.now() - this.start ), position.z + ( Date.now() - this.start ));

if(position instanceof THREE.BufferAttribute) {
    position.needsUpdate = true;
} else {
    position.data.needsUpdate = true;
}
...
this.renderer.render(this.scene, this.camera);

Есть предложения, чтобы сделать это? Я не нашел решения по inte rnet с этой темой.

Заранее спасибо !!!

1 Ответ

2 голосов
/ 05 февраля 2020

Следующий живой фрагмент показывает, что вы можете преобразовать вершины NURBS-поверхности, представленной экземпляром ParametricBufferGeometry. Обратите внимание, как BufferAttribute.setUsage() используется для того, чтобы сообщить WebGL, что вы собираетесь динамически изменять атрибут позиции для каждого кадра.

Анимация очень проста c, но код должен иллюстрировать предполагаемый подход.

var geometry, renderer, scene, camera, controls, clock;

var vertex = new THREE.Vector3();

init();
animate();

function init() {

    // renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setPixelRatio( window.devicePixelRatio );
    document.body.appendChild( renderer.domElement );

    // scene
    scene = new THREE.Scene();
    
    // camera
    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.set( 50, 50, 50 );

    // controls
    controls = new THREE.OrbitControls( camera, renderer.domElement );
		
    clock = new THREE.Clock();
    
    // axes
    scene.add( new THREE.AxesHelper( 20 ) );

    var nsControlPoints = [
      [
        new THREE.Vector4 ( -20, -20, 10, 1 ),
        new THREE.Vector4 ( -20, -10, -20, 1 ),
        new THREE.Vector4 ( -20, 10, 25, 1 ),
        new THREE.Vector4 ( -20, 20, -10, 1 )
      ],
      [
        new THREE.Vector4 ( 0, -20, 0, 1 ),
        new THREE.Vector4 ( 0, -10, -10, 5 ),
        new THREE.Vector4 ( 0, 10, 15, 5 ),
        new THREE.Vector4 ( 0, 20, 0, 1 )
      ],
      [
        new THREE.Vector4 ( 20, -20, -10, 1 ),
        new THREE.Vector4 ( 20, -10, 20, 1 ),
        new THREE.Vector4 ( 20, 10, -25, 1 ),
        new THREE.Vector4 ( 20, 20, 10, 1 )
      ]
    ];
    var degree1 = 2;
    var degree2 = 3;
    var knots1 = [0, 0, 0, 1, 1, 1];
    var knots2 = [0, 0, 0, 0, 1, 1, 1, 1];
    var nurbsSurface = new THREE.NURBSSurface(degree1, degree2, knots1, knots2, nsControlPoints);

    function getSurfacePoint(u, v, target) {

            return nurbsSurface.getPoint(u, v, target);

    }

    geometry = new THREE.ParametricBufferGeometry( getSurfacePoint, 20, 20 );
    var material = new THREE.MeshBasicMaterial( { wireframe: true, color: 0x666666 } );
    var objectSurface = new THREE.Mesh( geometry, material );
    scene.add( objectSurface );
		
    geometry.attributes.position.setUsage( THREE.DynamicDrawUsage );

}

function animate() {

    requestAnimationFrame( animate );
		
    var elapsedTime = clock.getElapsedTime();
	
    var position = geometry.attributes.position;
    
    for ( var i = 0; i < position.count; i ++ ) {
		
	        var z = position.getZ( i );

	        z += Math.sin( elapsedTime ) * 0.1;
			
	        position.setZ( i, z );
		
    }
		
    position.needsUpdate = true;

    renderer.render( scene, camera );

}
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/examples/js/controls/OrbitControls.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/examples/js/curves/NURBSUtils.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/examples/js/curves/NURBSSurface.js"></script>
...