简体   繁体   中英

Mesh position invalid after changing the vertice positions dynamically

I try to create a mesh with PlaneGeometry. After I change the geometry's vertices dynamically the mesh.position and mesh.rotation is not correct afterwards. Is it possible to recompute these accordingly with the new vertices?

I try to do this:

var geometry = new THREE.PlaneGeometry(500, 500);
geometry.dynamic = true;
var material = new THREE.MeshBasicMaterial({
            side: THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry, material);
scene.add(plane);

geometry.vertices[0].x += 15;
geometry.vertices[1].x += 15;
geometry.vertices[2].x += 10;
geometry.vertices[3].x += 10;
geometry.verticesNeedUpdate = true;

Here plane.position is still Vector3(0, 0, 0). How can I update this to correct position?

The position of the plane is not based on the position of the vertices, it is the position of the vertices that are relative to the position of the plane geometry. That is, the world-position of vertex n is calculated as mesh.position + geometry.vertices[n] (if there is no rotation or scale).

What you should do is move the center of the plane first:

plane.translateX(12.5);
//You may have to update the matrix to see the result:
plane.updateMatrix();

And then update the vertex positions:

//The plane has moved 12.5 units, so the vertices that should move 15 have 2.5 left to move:
geometry.vertices[0].x += 2.5;
geometry.vertices[1].x += 2.5;
//The vertices that should move 10 units have moved 2.5 too many, so we subtract that value from their position:
geometry.vertices[2].x -= 2.5;
geometry.vertices[3].x -= 2.5;
geometry.verticesNeedUpdate = true;

The reason for moving the plane 12.5 units is to keep everything centered. If this was not a requirement, you could move the plane 10 units and just add 5 to vertex 0 and vertex 1.

Position and vertices are independent things. It's possible to have a mesh located at (0, 0, 0) but drawn in a completely different place because its vertices are all large numbers. Vertex position is thus a position relative to the objects position. For your plane new THREE.PlaneGeometry(500, 500) :

(-250, 250, 0)            (250, 250, 0)
*--------------------------*
|                          |
|                          |
|                          |
|        (0, 0, 0)         |
|            O             |
|                          |
|                          |
|                          |
*--------------------------*
(-250, 250, 0)             (250, -250, 0) 

O is the origin in this case. And after your transformation:

(-235, 250, 0)            (265, 250, 0)
   *--------------------------*
   |                          |
  |                          |
  |                          |
  |       (0, 0, 0)          |
 |            O             |
 |                          |
 |                          |
|                          |
*--------------------------*
(-240, 250, 0)             (260, -250, 0) 

You get a slightly shifted parallelogram, but the origin has not moved, because you never asked the origin to move. It's possible to have a shape that looks like this:

                                      (500, 250, 0)            (750, 250, 0)
                                      *--------------------------*
                                      |                          |
                                      |                          |
                                      |                          |
(0, 0, 0)                             |                          |
    O                                 |                          |
                                      |                          |
                                      |                          |
                                      |                          |
                                      *--------------------------*
                                      (500, 250, 0)             (750, -250, 0) 

And it's still perfectly valid. What are you trying to do? It is definitely not good practice to move a mesh by moving vertex positions, but it appears as though you are also trying to deform the mesh as well. If, for whatever reason you needed to move the mesh vertices independently, but always wanted the mesh's position to be at its center:

var boundingBox = new THREE.Box3().setFromObject(mesh);
var centerDisplacement = boundingBox.getCenter().sub(mesh.position); // Difference between your mesh's position and its center
geometry.vertices[0].add(centerDisplacement);
geometry.vertices[1].add(centerDisplacement);
geometry.vertices[2].add(centerDisplacement);
geometry.vertices[3].add(centerDisplacement);
geometry.verticesNeedUpdate = true;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM