How do you build a custom plane geometry in three.js?

14,709

Solution 1

Becare about PlaneGeometry, it is deprecated (so it will be removed in a next revision). Use PlaneBufferGeometry instead.

@pailhead's answer is correct if you want the 'normal' plane division.

If you want the vertices to have other positions you would have to build the geometry vertex per vertex that is something else*.

Also and that answers your need to move/animate the vertices later, you can change each vertex'position after the geometry creation by writing :

planeMesh.geometry.vertices[i].set(x,y,z);// this way you can move each vertex coordinates
planeMesh.geometry.verticesNeedUpdate=true;

* : example for a plane with 4 vertices (=2 triangles) :

var geo=new THREE.Geometry();
geometry.vertices.push(
    new THREE.Vector3(x1,y1,z1),//vertex0
    new THREE.Vector3(x2,y2,z2),//1
    new THREE.Vector3(x3,y3,z3),//2
    new THREE.Vector3(x4,y4,z4)//3
    );
geometry.faces.push(
    new THREE.Face3(2,1,0),//use vertices of rank 2,1,0
    new THREE.Face3(3,1,2)//vertices[3],1,2...
    );

of course what makes this geometry a plane is that the 4 vertices are coplonar.

When you create a geometry with many faces, you understand you need a pen + paper to draw your faces :) Depending on your geometry you can also use an algorithm.

Solution 2

I created my customized plane, using:

        // Plane
            var size = 500, step = 100;
            var geometry = new THREE.Geometry();
            for ( var i = - size; i <= size; i += step ) {

                geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
                geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );

                geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
                geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );

            }

            var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.5 } );

            var line = new THREE.Line( geometry, material, THREE.LinePieces );
            scene.add( line );
Share:
14,709

Related videos on Youtube

blazerix
Author by

blazerix

Updated on September 16, 2022

Comments

  • blazerix
    blazerix over 1 year

    I want to create a plane in three.js, but with more points than default (so I don't want to use PlaneGeometry, as I don't think it will let me define custom points). The reason being is that I want to be able to animate or move any given point in time.

    This is what I have so far:

    var camera;
    var scene;
    var renderer;
    var mesh;
    
    init();
    animate();
    
    function init() {
    
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);
    
        var light = new THREE.DirectionalLight( 0xffffff );
        light.position.set( 0, 1, 1 ).normalize();
        scene.add(light);
    
    
        var geometry = new THREE.PlaneGeometry( 50, 50);  
    
        var texture = THREE.ImageUtils.loadTexture('images/03032122.png', {}, function() {
        renderer.render(scene, camera);
        })
        var material = new THREE.MeshBasicMaterial({map: texture, transparent: true })
    
    
        mesh = new THREE.Mesh(geometry, material );
        mesh.position.z = -50;
        scene.add( mesh );
    
        renderer = new THREE.WebGLRenderer({ alpha: true });
        renderer.setSize( window.innerWidth, window.innerHeight );
    
        renderer.setClearColor( 0xffffff, 1);
        document.body.appendChild( renderer.domElement );
    
        window.addEventListener( 'resize', onWindowResize, false );
    
        render();
    }
    
    function animate() {
        //mesh.scale.x+= 0.0003;
    
    
        render();
        requestAnimationFrame( animate );
    
    }
    
    function render() {
        renderer.render( scene, camera );
    }
    
    
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
        render();
    }
    

    What I'm looking to do, is create something like this:

    http://www.math.ubc.ca/~cass/courses/m308-02b/projects/schweber/square%20tiles.gif

  • blazerix
    blazerix almost 9 years
    How would you go about building it vertex by vertex?
  • blazerix
    blazerix almost 9 years
    Sorry, ignore the above post (I'm still getting used to stackoverflow). So, I try the following: geometry.vertices.push( new THREE.Vector3(0,1,10),//vertex0 new THREE.Vector3(1,0,10),//1 new THREE.Vector3(1,1,10),//2 new THREE.Vector3(0,0,10)//3 ); geometry.faces.push( new THREE.Face3(2,1,0),//use vertices of rank 2,1,0 new THREE.Face3(1,1,2)//vertices[3],1,2... ); but I get the an error: glDrawElements: attempt to access out of range vertices in attribute 1
  • Mouloud85
    Mouloud85 almost 9 years
    you can delete your previous comment. You are asking me to debug code, please link a jsfiddle. You can upvote the answers you like by the way, and validate the one that brings most to you.
  • Mouloud85
    Mouloud85 almost 9 years
    I updated the fiddle with the last version of threejs and corrected the Face3(1,1,2) to (3,1,2). That was the cause of the error (you need 3 points for a face3...). However you still have work to do. I cannot do it for you, but you may will have to check those questions stackoverflow.com/questions/17640089/face-is-not-drawn, stackoverflow.com/questions/19085369/…
  • blazerix
    blazerix almost 9 years
    Hi there, the problem is with the texture not displaying right?
  • blazerix
    blazerix almost 9 years
    Hi Victor, Would it be possible to add a texture to your custom plane?
  • Víctor Romário Paz de Jesus
    Víctor Romário Paz de Jesus almost 9 years
    Yes. My customization was for a "ground" in my plan and it worked. here: var ground = new THREE.Mesh( new THREE.PlaneGeometry(1000, 1000, 50, 50), new THREE.MeshLambertMaterial({color:0xFFFFFF}) ); ground.receiveShadow = true; ground.position.set(0, -25, 0); ground.rotation.x = -Math.PI / 2; scene.add(ground);
  • Mouloud85
    Mouloud85 almost 9 years
    Please don't make a conversation of commenting :) Just follow your way. You may encounter a problem that those links can answer
  • blazerix
    blazerix almost 9 years
    Hi Victor, if it is okay with you, could you take a look at my JS Fiddle? All I see is a line across the screen. jsfiddle.net/z9z28ume
  • pailhead
    pailhead almost 9 years
    Errm, look at other examples in three.js (boxgeometry, cylindergeometry, spheregeometry) etc to get an idea on different primitives, topologies etc. The original question actually makes a call to the PlaneGeometry, and that class has only the UV subdivision available. Sure you can look into all sorts of algorithms to generate triangles or ngons in between, but i think you complicated things a bit.