ابن آدم
ابن آدم

Reputation: 346

Changing position of an object by a specific vertex in Three.js

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

Answers (1)

TheJim01
TheJim01

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

Related Questions