Kody Puebla
Kody Puebla

Reputation: 227

Javascript - Defined Variable throws Error for being Undefined?

My Javascript code is throwing this error: "Uncaught TypeError: Cannot read property '0' of undefined". I've been searching this error and it always seems to lead back to an undefined variable, but this doesn't seem to be the case with my code. When I run it through Chrome's debugger, it shows that all of my variables are defined on the line that throws the error. The constructor of my class is called first with parameters (64, -0.5, 0.5, -0.5, 0.5). Within constructor, generateTriangles() is called, which populates this.vBuffer by pushing 12675 floating point values onto it. Then constructor calls diamond_square() which calls getVertex(). The error is thrown on the second line of getVertex(). When the error is thrown, the debugger shows vBuffer is populated with values and vid is 0. It specifically underlines [vid] in red and links it to the error. This code works perfectly without the call to diamond_square() in constructor. Here is the relevant code:

/** Class implementing 3D terrain. */
class Terrain{   
/**
 * Initialize members of a Terrain object
 * @param {number} div Number of triangles along x axis and y axis
 * @param {number} minX Minimum X coordinate value
 * @param {number} maxX Maximum X coordinate value
 * @param {number} minY Minimum Y coordinate value
 * @param {number} maxY Maximum Y coordinate value
 */
    constructor(div,minX,maxX,minY,maxY){
        this.div = div;
        this.minX=minX;
        this.minY=minY;
        this.maxX=maxX;
        this.maxY=maxY;

        // Allocate vertex array
        this.vBuffer = [];
        // Allocate triangle array
        this.fBuffer = [];
        // Allocate normal array
        this.nBuffer = [];
        // Allocate array for edges so we can draw wireframe
        this.eBuffer = [];
        console.log("Terrain: Allocated buffers");

        this.generateTriangles();
        console.log("Terrain: Generated triangles");

        this.diamond_square();
        console.log("Terrain: Performed Diamond-Square");

        this.generateLines();
        console.log("Terrain: Generated lines");

        // Get extension for 4 byte integer indices for drwElements
        var ext = gl.getExtension('OES_element_index_uint');
        if (ext ==null){
            alert("OES_element_index_uint is unsupported by your browser and terrain generation cannot proceed.");
        }
    }

    /**
    * Set the x,y,z coords of a vertex at location(i,j)
    * @param {Object} v an an array of length 3 holding x,y,z coordinates
    * @param {number} i the ith row of vertices
    * @param {number} j the jth column of vertices
    */
    setVertex(v,i,j)
    {
        var vid = 3*(i*(this.div+1) + j);
        this.vbuffer[vid] = v[0];
        this.vbuffer[vid+1] = v[1];
        this.vbuffer[vid+2] = v[2];
    }

    /**
    * Return the x,y,z coordinates of a vertex at location (i,j)
    * @param {Object} v an an array of length 3 holding x,y,z coordinates
    * @param {number} i the ith row of vertices
    * @param {number} j the jth column of vertices
    */
    getVertex(v,i,j)
    {
        var vid = 3*(i*(this.div+1) + j);
        v[0] = this.vbuffer[vid];
        v[1] = this.vbuffer[vid+1];
        v[2] = this.vbuffer[vid+2];
    }

    /**
     * Fill the vertex and buffer arrays 
     */    
    generateTriangles()
    {
        var x_amount = (this.maxX - this.minX) / this.div;
        var y_amount = (this.maxY - this.minY) / this.div;

        for (var i = 0; i <= this.div; i++) {
            for (var j = 0; j <= this.div; j++) {
                this.vBuffer.push(j*x_amount + this.minX);
                this.vBuffer.push(this.minY + i*y_amount);
                this.vBuffer.push(0);

                this.nBuffer.push(0);
                this.nBuffer.push(0);
                this.nBuffer.push(1);
            }
        }

        for (var i = 0; i < this.div; i++) {
            for (var j = 0; j < this.div; j++) {

                var vid = i*(this.div+1) + j;

                this.fBuffer.push(vid);
                this.fBuffer.push(vid + this.div+1);
                this.fBuffer.push(vid + this.div+2);

                this.fBuffer.push(vid);
                this.fBuffer.push(vid+1);
                this.fBuffer.push(vid + this.div+2);
            }
        }

        this.numVertices = this.vBuffer.length/3;
        this.numFaces = this.fBuffer.length/3;
    }

    diamond_square()
    {
        // initialize corners to 0
        var init_value = 0;
        var max = this.div;
        var v = [0.0, 0.0, 0.0];
        // top-left corner
        this.getVertex(v, 0, 0);
        v[2] = init_value;
        this.setVertex(v, 0, 0);
        // bottom-left corner
        this.getVertex(v, 0, max);
        v[2] = init_value;
        this.setVertex(v, 0, max);
        // top-right corner
        this.getVertex(v, max, 0);
        v[2] = init_value;
        this.setVertex(v, max, 0);
        // bottom-right corner
        this.getVertex(v, max, max);
        v[2] = init_value;
        this.setVertex(v, max, max);
        // perform diamond-square recursively on the rest of the vertices
        this.subsection(max);
    }
}

Upvotes: 0

Views: 132

Answers (1)

Karim
Karim

Reputation: 8632

In both the getVertex and setVertex functions you mispelled this.vBuffer, you instead used this.vbuffer that is actually undefined, that is throwing the exception

getVertex(v,i,j) {
  var vid = 3*(i*(this.div+1) + j);
  v[0] = this.vbuffer[vid];  //should be this.vBuffer
  v[1] = this.vbuffer[vid+1]; //should be this.vBuffer
  v[2] = this.vbuffer[vid+2]; //should be this.vBuffer
}

setVertex(v,i,j) {
  var vid = 3*(i*(this.div+1) + j);
  this.vbuffer[vid] = v[0]; //should be this.vBuffer
  this.vbuffer[vid+1] = v[1]; //should be this.vBuffer
  this.vbuffer[vid+2] = v[2]; //should be this.vBuffer
}

Upvotes: 1

Related Questions