增量显示three.js TubeGeometry [英] Incrementally display three.js TubeGeometry

查看:286
本文介绍了增量显示three.js TubeGeometry的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够显示如下的THREE.TubeGeometry图

I am able to display a THREE.TubeGeometry figure as follows

以下代码,链接到 jsbin

<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r75/three.js"></script>

<script>
    // global variables
    var renderer;
    var scene;
    var camera;
    var geometry;

    var control;

    var count = 0;
    var animationTracker;

    init();
    drawSpline();

    function init()
    {
        // create a scene, that will hold all our elements such as objects, cameras and lights.
        scene = new THREE.Scene();

        // create a camera, which defines where we're looking at.
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

        // create a render, sets the background color and the size
        renderer = new THREE.WebGLRenderer();
        renderer.setClearColor('lightgray', 1.0);
        renderer.setSize(window.innerWidth, window.innerHeight);

        // position and point the camera to the center of the scene
        camera.position.x = 0;
        camera.position.y = 40;
        camera.position.z = 40;
        camera.lookAt(scene.position);

        // add the output of the renderer to the html element
        document.body.appendChild(renderer.domElement);
    }

    function drawSpline(numPoints)
    {
        var numPoints = 100;
//        var start = new THREE.Vector3(-5, 0, 20);
        var start = new THREE.Vector3(-5, 0, 20);
        var middle = new THREE.Vector3(0, 35, 0);
        var end = new THREE.Vector3(5, 0, -20);

        var curveQuad = new THREE.QuadraticBezierCurve3(start, middle, end);

        var tube = new THREE.TubeGeometry(curveQuad, numPoints, 0.5, 20, false);
        var mesh = new THREE.Mesh(tube, new THREE.MeshNormalMaterial({
            opacity: 0.9,
            transparent: true
        }));

        scene.add(mesh);
        renderer.render(scene, camera);
    }
</script>
</body>
</html>

但是,我想逐步显示,就像在正在加载的弧,使得它以起始点开始,逐渐绘制,最后在完成后查看下面的弧。

However, I would like to display incrementally, as in, like an arc that is loading, such that it starts as the start point, draws incrementally and finally looks the below arc upon completion.

我一直在付出一些努力,能够通过存储弧所覆盖的所有点/坐标,以及在连续坐标之间绘制线来实现这一点,这样我就可以获得弧加载的感觉。但是,有没有更好的方法来实现这一目标?这是指向 jsbin 的链接

I have been putting in some effort, and was able to do this by storing all the points/coordinates covered by the arc, and drawing lines between the consecutive coordinates, such that I get the 'arc loading incrementally' feel. However, is there a better way to achieve this? This is the link to jsbin

此处也添加代码

<!DOCTYPE html>
<html>
<head>
    <title>Incremental Spline Curve</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r75/three.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<script>

    // global variables
    var renderer;
    var scene;
    var camera;
    var splineGeometry;

    var control;

    var count = 0;
    var animationTracker;

//    var sphereCamera;
    var sphere;
    var light;

    function init() {

        // create a scene, that will hold all our elements such as objects, cameras and lights.
        scene = new THREE.Scene();

        // create a camera, which defines where we're looking at.
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

        // create a render, sets the background color and the size
        renderer = new THREE.WebGLRenderer();
//        renderer.setClearColor(0x000000, 1.0);
        renderer.setClearColor( 0xffffff, 1 );
        renderer.setSize(window.innerWidth, window.innerHeight);

        // position and point the camera to the center of the scene
        camera.position.x = 0;
        camera.position.y = 40;
        camera.position.z = 40;
        camera.lookAt(scene.position);

        // add the output of the renderer to the html element
        document.body.appendChild(renderer.domElement);

//        //init for sphere
//        sphereCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
//        sphereCamera.position.y = -400;
//        sphereCamera.position.z = 400;
//        sphereCamera.rotation.x = .70;

        sphere = new THREE.Mesh(new THREE.SphereGeometry(0.8,31,31), new THREE.MeshLambertMaterial({
            color: 'yellow',
        }));

        light = new THREE.DirectionalLight('white', 1);
//        light.position.set(0,-400,400).normalize();
        light.position.set(0,10,10).normalize();

        //get points covered by Spline
        getSplineData();
    }

    //save points in geometry.vertices
    function getSplineData() {
        var curve = new THREE.CubicBezierCurve3(
                new THREE.Vector3( -5, 0, 10 ),
                new THREE.Vector3(0, 20, 0 ),
                new THREE.Vector3(0, 20, 0 ),
                new THREE.Vector3( 2, 0, -25 )
        );

        splineGeometry = new THREE.Geometry();
        splineGeometry.vertices = curve.getPoints( 50 );

        animate();
    }

    //scheduler loop
    function animate() {
        if(count == 50)
        {
            cancelAnimationFrame(animationTracker);
            return;
        }

        //add line to the scene
        drawLine();

        renderer.render(scene, camera);
  //      renderer.render(scene, sphereCamera);

        count += 1;
//        camera.position.z -= 0.25;
//        camera.position.y -= 0.25;
        animationTracker = requestAnimationFrame(animate);
    }

    function drawLine() {
        var lineGeometry = new THREE.Geometry();
        var lineMaterial = new THREE.LineBasicMaterial({
            color: 0x0000ff
        });
        console.log(splineGeometry.vertices[count]);
        console.log(splineGeometry.vertices[count+1]);
        lineGeometry.vertices.push(
                splineGeometry.vertices[count],
                splineGeometry.vertices[count+1]
        );

        var line = new THREE.Line( lineGeometry, lineMaterial );
        scene.add( line );
    }

    // calls the init function when the window is done loading.
    window.onload = init;

</script>
<body>
</body>
</html>

缺点:以上述方式做到这一点的缺点是,当天结束时,我是在连续点之间画一条线,所以我在TubeGeometry中失去了许多可能的效果,例如厚度,透明度等。

Drawback : The drawback of doing it the above way is that, end of the day, I'm drawing a line between consecutive points, and so I lose out on a lot of the effects possible in TubeGeometry such as, thickness, transparency etc.

请建议我另一种方法为TubeGeometry获得平滑的增量加载。

Please suggest me an alternative way to get a smooth incremental load for the TubeGeometry.

推荐答案

THREE.TubeGeometry 返回 THREE.Geometry 。通过将几何转换为

THREE.TubeGeometry returns a THREE.Geometry. By converting the geometry to

THREE.BufferGeometry ,您可以访问属性 drawRange 你可以设置为网格绘图设置动画:

THREE.BufferGeometry, you have access to a property drawRange that you can set to animate the drawing of the mesh:

var nEnd = 0, nMax, nStep = 90; // 30 faces * 3 vertices/face

...

// geometry
var geometry = new THREE.TubeGeometry( path, pathSegments, tubeRadius, radiusSegments, closed );

// to buffer goemetry
geometry = new THREE.BufferGeometry().fromGeometry( geometry );
nMax = geometry.attributes.position.count;

...

function animate() {

    requestAnimationFrame( animate );

    nEnd = ( nEnd + nStep ) % nMax;

    mesh.geometry.setDrawRange( 0, nEnd );

    renderer.render( scene, camera );

}

小提琴: http://jsfiddle.net/k73pxyL2/

编辑:有关其他方法,请参阅这个SO答案

For another approach, see this SO answer.

three.js r.75

three.js r.75

这篇关于增量显示three.js TubeGeometry的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆