0

I am trying to create a mesh that contain all triangles generate by following a path in realtime. I think problem is that geometry is not properly updated and because it not visualize nothing. Triangles are created with positions of the green cubes that follow animated over time the text Spline lines.

how I create:

    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;

How I update each frame:

        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();

Code: http://jsfiddle.net/mcanet/6cr6R/3/

And some screenshot: https://www.flickr.com/photos/mcanet/14094429489/

I am using Three.js version 67. If someone can help me with that it would be much appreciated :)

2 Answers 2

1

Ok this took me a while but I think i got it! Basically you can not add vertices after adding the mesh to the scene because you can not resize the buffer.

You can only update content of buffers, you cannot resize buffers (this is very costly, basically equivalent to creating new geometry).

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

This means you have to create a geometry that contains all the vertices and faces you will need, make them invisible and update them in the drawing process. The code would look like this:

...

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;

    }

    ...

};

Hope this helps you!

Sign up to request clarification or add additional context in comments.

2 Comments

I follow your advice and fixed code: jsfiddle.net/mcanet/6cr6R/4 . Still some aesthetics errors to fix but vertex problem is totally solved.
Now you could center the text so the camera does not feel that weird. You can achieve this by getting the center point of the geometries bounding box and set its negative values as position.
0

Yup, Raphael is right. However, if you aim for the real realtime, be sure to use the BufferGeometry class. Here's the only official example that is, as of now, consistent with the r67: http://mrdoob.github.io/three.js/examples/#webgl_buffergeometry_rawshader. Basically, you would only need the creation part (allocate a buffer of bigger size than you should need). I've put together a little example:

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

Then, in an update loop you would do (low-level indeed):

...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;

The geometry.dynamic property should be enabled by default in r67. Good luck!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.