0

I actually made an easy workaround, but I'm just curious. I don't exactly understand what .clone() does under the hood.

I created this class to normalize vectors

class Vector {
  constructor(x,y){
    this.x = x
    this.y = y
  }
  normalize() {
    let length = Math.sqrt(this.x * this.x + this.y * this.y)
      this.x = this.x / length
      this.y = this.y / length
  }
}

I then import a GLTF model (simplified code):

const loader = new GLTFLoader();
loader.load( './assets/models/ROCKS.glb', function ( glb ) {

glb.scene.userData.mouseDirVector = new Vector(0,0)

obj = glb.scene
obj2 = obj.clone()
}

But later in code, when I try to use the Vector object's .normalize() method, I get an error (only on the cloned object):

Uncaught TypeError: obj2.userData.mouseDirVector.normalize is not a function

Why is it happening?

AlexM
  • 161
  • 5
  • 3
    The documentation states that your use case is not supported: https://threejs.org/docs/index.html#api/en/core/Object3D.userData – Mugen87 Jul 26 '22 at 08:30

2 Answers2

2

As stated in the docs, .clone() doesn't preserve the function references while cloning the object.

Note: as stated by DonMcCurdy the following method won't work because the object hasn't a prototype

You can try adding the method in the UserData prototype itself:

UserData.prototype.mouseDirVector = new Vector(0, 0);

In this way, the method will be available in all the following UserData that will be instantiated and you won't need to write it. In this case, this refers to your object, not the Tree object.

Otherwise, you can re-assign the property:

obj2 = obj.clone();
obj2.userData.mouseDirVector = new Vector(0,0);
  • 1
    The [`.userData` object](https://github.com/mrdoob/three.js/blob/7ad7827df5110f5ff1082e5f84106e04a52286f6/src/core/Object3D.js#L114) is not an instance of a class, so I don't think the first option will work. The `.userData` object is meant for JSON-serializable metadata, things like functions or instances won't survive .clone(). – Don McCurdy Jul 26 '22 at 17:42
1

AFAIK there is no ONE clone() (see: MDN clone()) method to clone objects. You should rather use structuredClone() JSON.parse/stringify approach or any libary. Check out deep clone object in JavaScript.

Coming back to the clone() method, I suspect that you are using Response.clone() or Request.clone(). You should try to find out what method exactly you are using and then check the docs for it, alternatively you can come back here once you know what method we are talking about.

JMB
  • 51
  • 2
  • It seems OP is asking about THREE.js's `Object3D.clone()` specifically, so not really a question about the JavaScript language. – Berthur Jul 26 '22 at 13:17