1

I have a javascript object that I am using. I have a verts array that i want to keep as is(The var called verts). Within the object i have a setScalar()method which will take this verts matrix and apply a scalar(jus a simple for loop multipling each value).When I create a new object I apply my scalar but when i create a new object i dont reference the original verts array it seems to apply the scalar to the scaled verts used in the object previous.

here is the verts array:

var verts = [
            // Front face
            -1.0, -1.0,  1.0,
             1.0, -1.0,  1.0,
             1.0,  1.0,  1.0,
            -1.0,  1.0,  1.0,

            // Back face
            -1.0, -1.0, -1.0,
            -1.0,  1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0, -1.0, -1.0,

            // Top face
            -1.0,  1.0, -1.0,
            -1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0, -1.0,

            // Bottom face
            -1.0, -1.0, -1.0,
             1.0, -1.0, -1.0,
             1.0, -1.0,  1.0,
            -1.0, -1.0,  1.0,

            // Right face
             1.0, -1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0,  1.0,  1.0,
             1.0, -1.0,  1.0,

            // Left face
            -1.0, -1.0, -1.0,
            -1.0, -1.0,  1.0,
            -1.0,  1.0,  1.0,
            -1.0,  1.0, -1.0
        ];

and here is how I set it in the object.

//Cube object
    function Cube(name, vertices, cubeVertInd, color, scale, positionX, positionY, positionZ) 
    {
        this.name = name;
        this.vertices = vertices;
        this.cubeVertexIndices = cubeVertInd;
        this.positionX = positionX;
        this.positionY = positionY;
        this.positionZ = positionZ;
        this.setColor(color);
        this.setScale(vertices, scale);
    }

this is the setScale method

Cube.prototype.setScale = function(vertices, scale) 
    {
        var length = vertices.length;
        for( var i = 0; i < length; i++)
        {
            vertices[i] *= scale; 
        }
    }

I know this is what happened because when i use this with webgl I get different sizes depending on what size i make the first object. If i set the object to scale 2 then set the next object to scale 0.1 even though the original verts is all 1's i get 0.2 as the second objects scale. this shows that the scale i set in the first object is being used rather than verts

3 Answers 3

1

You have to clone your vertices array, because otherwise it's always a reference to the original vert array.

Try this:

//Cube object
    function Cube(name, vertices, cubeVertInd, color, scale, positionX, positionY, positionZ) 
    {
        // make a copy of the vertices
        vertices = vertices.slice();

        this.name = name;
        this.vertices = vertices;
        this.cubeVertexIndices = cubeVertInd;
        this.positionX = positionX;
        this.positionY = positionY;
        this.positionZ = positionZ;
        this.setColor(color);
        this.setScale(vertices, scale);
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Sorry I have one more issue. See the this.positionX a similar thing happens when i set the positions is there anyway I can make these unique to each iteration of the object?
0

If you only use setScale() for this purpose, you can use Array.prototype.map() method and remove the function setScale().

In this case another new object is created, scaled and assigned to this.vertices .

function Cube(name, vertices, cubeVertInd, color, scale, positionX, positionY, positionZ) 
    {
        this.name = name;
        this.vertices = vertices.map(function(value){
                             return value*scale;
                        });
        this.cubeVertexIndices = cubeVertInd;
        this.positionX = positionX;
        this.positionY = positionY;
        this.positionZ = positionZ;
        this.setColor(color);
    }

Comments

0

This is answer to a similar thing happens when i set the positions is there anyway I can make these unique to each iteration of the object?

A generic solution to this problem is to have a clone function that can, well, return a clone of an object (not reference). So suppose if you have a base object with {verts: [1,2,3..], positionX: 5, ...} etc what you want to do when creating a new object is newObj = clone(baseObj), then newObj.setScale(-1).

And one implementation of said clone function:

var clone = function(obj,visited){
    if (obj === null || typeof(obj) !== "object"){ // primitives and functions
        return obj;
    }
    visited = visited || [];

    if (visited.indexOf(obj)===-1){ // enable cloning objects with circular references at cost of linear search;
        visited.push(obj);
        if (obj instanceof RegExp){
            return new RegExp(obj);
        } else if (obj instanceof Date){
            return new Date(obj);
        } else if (Array.isArray(obj)){ // the [[Class]] of arrays can only be set by using Array constructor or [];
            var newObj = [];
        } else if (obj.constructor !== undefined){
            newObj = Object.create(obj.constructor.prototype);
        } else {
            throw new TypeError("How to clone object: "+obj+" is undefined.", obj);
        }

    } else { // if object already seen/ circular reference; just return reference to it
        return obj;
    }

    for(var key in obj) { // recursive call itself;
        if(obj.hasOwnProperty(key)) {
            newObj[key] = clone(obj[key],visited);
        }
    }
    return newObj;
};

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.