javascript3dthree.jsphysijs

After setting vertices on THREE.Geometry objects, THREE.Shape.Utils.triangulateShape fails with TypeError


I've created a game made from THREE.JS and Physijs. I made a function called addBlock2 that adds a triangular pyramid to the scene. It sets the appropriate vertices, but when it comes to triangulateShape it fails with the following error:

Uncaught TypeError: Cannot read property 'x' of undefined

THREE.Shape.Utils.triangulateShape  @   three.min.js:680
Game.addBlock2          @   game.js:210
Game.update             @   game.js:271
(anonymous function)    @   game.js:284
onAnimationFrame        @   VM3973:49
(anonymous function)    @   VM3973:18

game.js:210 is the "triangulateShape" line.

Here is the code:

Game.prototype.addBlock2 = function(x,y,z) {
    var geometry = new THREE.Geometry();
    geometry.vertices = [
        THREE.Vector3(0,0,0),
        THREE.Vector3(0,200,-100),
        THREE.Vector3(100,200,100),
        THREE.Vector3(-100,200,100)
    ]
    var triangles = THREE.Shape.Utils.triangulateShape(geometry.vertices, []);
    for (i in triangles){
        geometry.faces[geometry.faces.length] = new THREE.Face3(triangles[i][0], triangles[i][1], triangles[i][2])
    }
    geometry.computeFaceNormals();
    geometry.computeVertexNormals();
    var material = Physijs.createMaterial(new THREE.MeshPhongMaterial({color: 0xFFFF00}),0.3,0.8);
    try {
        var mesh = new Physijs.ConvexMesh(geometry,material);
    }
    catch (e) {
        console.log(e,geometry,material)
        return
    }
    mesh.position.x = x || 0
    mesh.position.y = y || 0
    mesh.position.z = z || 0
    mesh.__dirtyPosition = true
    mesh.name = "block."+(x||0)+","+(y||0)+","+(z||0)
    mesh.receiveShadow = true
    this.scene.add(mesh);
    this.blocks[this.blocks.length] = mesh
}

Solution

  • I fixed it. I was supposed to use new THREE.Vector3 instead of THREE.Vector3. I couldn't get triangulateShape to get what I wanted so I set the faces manually. Here is the new code:

    Game.prototype.addBlock2 = function(x,y,z) {
        var geometry = new THREE.Geometry();
        geometry.vertices = [
            new THREE.Vector3(0,0,0),
            new THREE.Vector3(0,200,-100),
            new THREE.Vector3(100,200,100),
            new THREE.Vector3(-100,200,100)
        ]
        geometry.faces = [
            new THREE.Face3(0,1,2),
            new THREE.Face3(0,2,3),
            new THREE.Face3(0,3,1),
            new THREE.Face3(1,2,3)
        ]
        geometry.computeFaceNormals();
        geometry.computeVertexNormals();
        var material = Physijs.createMaterial(new THREE.MeshPhongMaterial({color: 0xFFFF00, side: THREE.DoubleSide}),0.3,0.8);
        try {
            var mesh = new Physijs.ConvexMesh(geometry,material);
        }
        catch (e) {
            console.log(e,geometry,material)
            return
        }
        mesh.position.x = x || 0
        mesh.position.y = y || 0
        mesh.position.z = z || 0
        mesh.__dirtyPosition = true
        mesh.name = "block."+(x||0)+","+(y||0)+","+(z||0)
        mesh.receiveShadow = true
        this.scene.add(mesh);
        this.blocks[this.blocks.length] = mesh
    }