Reputation: 346
I want to change the position of an object by a specific vertex of that object in three.js. I have this .OBJ glasses model which has 8,856 vertices. Here is my code:
Note: OBJLoader.js is necessary.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vertices Positioning</title>
</head>
<body>
<canvas
id="modelCanvas"
width="600px"
height="400px"
></canvas>
</body>
<!-- JavaScript -->
<script src="js/three.js"></script>
<script src="js/OBJLoader.js"></script>
<script src="script.js"></script>
</html>
script.js:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, 600 / 400, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
canvas: modelCanvas,
});
renderer.setSize(600, 400);
renderer.setClearColor(0x000000, 0);
document.body.appendChild(renderer.domElement);
const loader = new THREE.OBJLoader();
let obj3D = new THREE.Object3D();
loader.load(
"./model.obj",
function (obj) {
obj3D = obj;
console.log(obj3D);
scene.add(obj3D);
}
);
camera.position.z = 5;
const render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
What I mean is that let's say, the object is in its default location of 0, 0 (Red dot: default position, Cyan dot: Vertex position). Now if I want to get the position of a specific vertex (top left corner) and change the vertex's position, the object's position also changes (Cyan Dot: Object position, Blue Dot: New Vertex position). That's what I want to achieve in Three.js.
Bonus:
I did some research and found out that the vertices are located in Object3D > Children > (Index of the Mesh) > geometry > attributes, check this image. This contains normal, position and uv. And each one of them contains an array of vertices. But this array only contains one position number, so I don't know if it is X-axis, Y-Axis or Z-Axis.
Thanks for the help!
Upvotes: 2
Views: 1771
Reputation: 8896
The position attribute holds triplets like this: [ x1, y1, z1, x2, y2, z2, ... ]
.
So to make a Vector3
of the first vertex, you can do:
let v = new THREE.Vector3(
mesh.geometry.attributes.position.array[ 0 ],
mesh.geometry.attributes.position.array[ 1 ],
mesh.geometry.attributes.position.array[ 2 ]
);
You can also use Vector3.fromBufferAttribute
like this:
let v = new THREE.Vector3().fromBufferAttribute( mesh.geometry.attributes.position, i );
Optimally, you don't have to create a new Vector3
.
Mesh.position
is already a Vector3
, so you can use the Vector3.set
method with the individually referenced indices, or use Vector3.fromBufferAttribute
directly on position like this:
mesh.position.fromBufferAttribute( mesh.geometry.attributes.position, i );
Upvotes: 1