在运行时创建网格并推送新的三角形

时间:2014-05-26 22:20:46

标签: three.js

我正在尝试创建一个网格,其中包含通过实时跟踪路径生成的所有三角形。我认为问题是几何体没有正确更新,因为它没有任何可视化。使用绿色立方体的位置创建三角形,随着时间的推移,文本样条线为动画。

我是如何创作的:

    var geometryHandFont = new THREE.Geometry();
    geometryHandFont.dynamic = true;

    var materialHandFont = new THREE.MeshBasicMaterial({
        color: 0xffffff, wireframe:true, side: THREE.DoubleSide
    });

    this.handFont = new THREE.Mesh(geometryHandFont, materialHandFont);
    this.handFont.geometry.dynamic = true;

我如何更新每一帧:

        this.handFont.geometry.vertices.push(tl);
        this.handFont.geometry.vertices.push(tr);
        this.handFont.geometry.vertices.push(br);
        // triangle 2
        this.handFont.geometry.vertices.push(tr);
        this.handFont.geometry.vertices.push(br);
        this.handFont.geometry.vertices.push(bl);

        this.handFont.geometry.faces.push(new THREE.Face3(this.f++,this.f++,this.f++));
        this.handFont.geometry.faces.push(new THREE.Face3(this.f++,this.f++,this.f++));
        this.handFont.geometry.verticesNeedUpdate = true;
        this.handFont.geometry.elementsNeedUpdate = true;
        this.handFont.geometry.computeBoundingBox();
        this.handFont.geometry.computeFaceNormals();
        this.handFont.geometry.computeVertexNormals();

代码: http://jsfiddle.net/mcanet/6cr6R/3/

还有一些截图:https://www.flickr.com/photos/mcanet/14094429489/

我正在使用Three.js版本67.如果有人可以帮助我,我将不胜感激:)

2 个答案:

答案 0 :(得分:1)

好的,这花了我一段时间,但我想我明白了!基本上,在将网格物体添加到场景后,您无法添加顶点,因为无法调整缓冲区的大小。

  

您只能更新缓冲区的内容,无法调整缓冲区大小(这非常昂贵,基本上等同于创建新几何体)。

     

https://github.com/mrdoob/three.js/wiki/Updates

这意味着您必须创建一个几何图形,其中包含您需要的所有顶点和面,使它们不可见并在绘图过程中更新它们。代码如下所示:

...

this.newWish = function(){

    ...     
    // create 9999 vertices that are not visible (maybe you can calculate the number before)    
    for(var i = 0; i < 9999; i++){
        geometryHandFont.vertices.push(new THREE.Vector3());
        geometryHandFont.vertices[geometryHandFont.vertices.length-1].visible = false;
        if(i % 3 === 0 && i + 3 < 10000)
            geometryHandFont.faces.push(new THREE.Face3(this.f++,this.f++,this.f++));
    }

    this.lastVerticeIndex = -1;

    ...
};

...

this.addGeometry = function(tr, br){    
    if(this.previusTR != null){

        ...

        this.handFont.geometry.vertices[this.lastVerticeIndex++] = tl;
        this.handFont.geometry.vertices[this.lastVerticeIndex++] = tr;
        this.handFont.geometry.vertices[this.lastVerticeIndex++] = br;
        // triangle 2
        this.handFont.geometry.vertices[this.lastVerticeIndex++] = tr;
        this.handFont.geometry.vertices[this.lastVerticeIndex++] = br;
        this.handFont.geometry.vertices[this.lastVerticeIndex++] = bl;

        ...

        this.handFont.geometry.verticesNeedUpdate = true;
        this.handFont.geometry.elementsNeedUpdate = true;
        this.handFont.geometry.morphTargetsNeedUpdate = true;
        this.handFont.geometry.uvsNeedUpdate = true;
        this.handFont.geometry.normalsNeedUpdate = true;
        this.handFont.geometry.colorsNeedUpdate = true;
        this.handFont.geometry.tangentsNeedUpdate = true;

        this.handFont.needsUpdate = true;
        this.handFont.verticesNeedUpdate = true;

    }

    ...

};

希望这能帮到你!

答案 1 :(得分:0)

是的,拉斐尔是对的。但是,如果您的目标是实时,请务必使用BufferGeometry类。这是唯一的官方示例,截至目前,与r67:http://mrdoob.github.io/three.js/examples/#webgl_buffergeometry_rawshader一致。基本上,您只需要创建部分(分配比您需要的更大的缓冲区)。我把一个小例子放在一起:

var maxFaces = 1000000,
    geometry = new THREE.BufferGeometry(),
    material = new THREE.MeshBasicMaterial({
        color: 0xffffff, wireframe: true, side: THREE.DoubleSide
    });

geometry.addAttribute('position', new THREE.Float32Attribute( maxFaces * 3, 3 ));
var mesh = new THREE.Mesh( geometry, material );

var positions = geometry.attributes.position.array, // a Float32Array of coords
    counter = 0; // no vertices yet

然后,在更新循环中你会做(确实是低级别):

...for each new vertex, wherever you get them from... {
    positions[counter] = vertex[0];
    positions[counter + 1] = vertex[1];
    positions[counter + 2] = vertex[2];
    counter += 3;
}
// and here or there, to draw the changes:
geometry.attributes.position.needsUpdate = true;

默认情况下,应在r67中启用geometry.dynamic属性。 祝你好运!