For instance i have scaled the model to (2, 1, 1) and now i want the model scale to be reset to (1,1,1) without changing the model. (just like how we apply scale in blender)
how can i do that, is that even possible.
Thanks in advance.
For instance i have scaled the model to (2, 1, 1) and now i want the model scale to be reset to (1,1,1) without changing the model. (just like how we apply scale in blender)
how can i do that, is that even possible.
Thanks in advance.
Hi @yodha …
Have You tried
mesh.scale.set(0.5,1,1);
mesh.updateMatrix(); //make sure matrix is up to date with position/rotation/scale
mesh.geometry.applyMatrix4(mesh.matrix); //Transform the geometry itself by that matrix...
mesh.matrix.identity(); //Reset the matrix to identity now...
mesh.matrix.decompose(mesh.position,mesh.quaternion,mesh.scale) //synchronise the position/quat/scale of the object.
hey @jrlazz unfortunately that is not what i am looking for.
Thanks @manthrax the code you provided works perfectly for my requirements. While researching the solution, I came across Matrix4
and makeScale
, and I ended up writing something like this:
function setScale(object) {
const scaleMatrix = new THREE.Matrix4().makeScale(
object.scale.x,
object.scale.y,
object.scale.z
);
object.geometry.applyMatrix4(scaleMatrix);
object.updateWorldMatrix(true, false);
object.scale.set(1, 1, 1);
}
Could you explain which approach is better and why? I’m currently learning Three.js, and understanding the reasoning behind these concepts would really help me improve.
Thanks in advance!
Both approaches are fine. The one I showed just applies the entire transform, not just scaling.
Yet another approach would be just looping through the vertices and scaling them.
let p = mesh.geometry.attributes.position.array;
let {x,y,z}=mesh.scale;
for(let i=0;i<p.length;){
p[i++]*=x
p[i++]*=y
p[i++]*=z
}
mesh.geometry.attributes.position.needsUpdate=true;
mesh.scale.set(1,1,1);
(however… this might fail with some kinds of geometries depending on how the vertex buffer is structured…) but just showing you another way to interact w geometry.
I myself usually prefer the solution that is a balance between the most performant, and the least amount of code.
looping through the geometry and scaling the vertices is the fastest.
Our approaches via geometry.applyMatrix4() are slower, but more robust/flexible, and perhaps less code to read.
If you’re doing it once at init time… then I would prefer the .applyMatrix4 approach… but if it was being done each frame, I might use the other approach or something different entirely.
Thanks fro the explanation @manthrax, i will be using it only once so ig applyMatrix4
works well for me.