Applying a matrix in Three.js does not what I expe

2019-08-13 18:18发布

For a project I am working on I am trying to get get a 3D-model of a building visible in a browser. Of all the elements of the building I have vertices, indices and a matrix3d. This information comes from an application that uses OpenGL to show the elements in a offline program.

Now I am trying to add these elements to my Three.js scene.

I am at the point that I can add elements to the scene defined by the vertices and indices an I can see them by using materials and lights, but I can not rotate and translate them into the right place. For example I add an element like this:

var m242242255255 = new THREE.MeshPhongMaterial({color:0xf2f2ff, transparent:true, opacity:1, side:THREE.DoubleSide});
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array([821,-15,2825.1,-821,-15,2825.1,-821,-39,2825.1,821,-39,2825.1,-821,-39,54,-821,-15,54,821,-15,54,821,-39,54,-875,-54,0,-821,-54,54,-821,-54,2825.1,821,-54,54,-875,-54,2879.1,821,-54,2825.1,875,-54,0,875,-54,2879.1,875,0,0,821,0,54,821,0,2825.1,-821,0,54,875,0,2879.1,-821,0,2825.1,-875,0,0,-875,0,2879.1]), 3));
geometry.setIndex(new THREE.BufferAttribute(new Uint16Array([8,9,10,9,8,11,12,10,13,10,12,8,11,14,13,14,11,8,13,15,12,15,13,14,16,17,18,17,16,19,20,18,21,18,20,16,19,22,21,22,19,16,21,23,20,23,21,22,8,22,16,16,14,8,14,16,20,20,15,14,15,20,23,23,12,15,12,23,22,22,8,12,13,18,17,17,11,13,11,17,19,19,9,11,9,19,21,21,10,9,10,21,18,18,13,10]), 1));

var mesh = new THREE.Mesh(geometry, m242242255255);
mesh.matrixAutoUpdate = false;
mesh.applyMatrix(new THREE.Matrix4().set(0,0,-1,0,  -0.42262,-0.90631,0,0,  -0.90631,0.42262,0,0,  64754.68,15569.13,-4647.5,1));
mesh.updateMatrix();
scene.add(mesh);

The element shows up in my scene and it looks like is rotated but it is not translated to its correct position.

I can add the translation before the adding of the mesh to the scene, but it feels like it should not be necessary.

mesh.applyMatrix(new THREE.Matrix4().makeTranslation(-64754.68, -15569.13, -4647.5));
mesh.updateMatrix();

It also looks like the element is rotated along the wrong axis. It is rotated along the x-axis instead of the z-axis. Can someone tell me what it is I am doing wrong? Should I changed the matrix first to be able to use it in Three.js?

Edit:

I just found out that I had to invert my matrix to correct the rotation-problem. So I now have:

var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array([821,-15,2825.1,-821,-15,2825.1,-821,-39,2825.1,821,-39,2825.1,-821,-39,54,-821,-15,54,821,-15,54,821,-39,54,-875,-54,0,-821,-54,54,-821,-54,2825.1,821,-54,54,-875,-54,2879.1,821,-54,2825.1,875,-54,0,875,-54,2879.1,875,0,0,821,0,54,821,0,2825.1,-821,0,54,875,0,2879.1,-821,0,2825.1,-875,0,0,-875,0,2879.1]), 3));
geometry.setIndex(new THREE.BufferAttribute(new Uint16Array([8,9,10,9,8,11,12,10,13,10,12,8,11,14,13,14,11,8,13,15,12,15,13,14,16,17,18,17,16,19,20,18,21,18,20,16,19,22,21,22,19,16,21,23,20,23,21,22,8,22,16,16,14,8,14,16,20,20,15,14,15,20,23,23,12,15,12,23,22,22,8,12,13,18,17,17,11,13,11,17,19,19,9,11,9,19,21,21,10,9,10,21,18,18,13,10]), 1));

var mesh = new THREE.Mesh(geometry, m242242255255);
mesh.matrixAutoUpdate = false;
var matrix = new THREE.Matrix4();
matrix.set(0,0,-1,0,-0.42262,-0.90631,0,0,-0.90631,0.42262,0,0,64754.68,15569.13,-4647.5,1);
matrix.getInverse(matrix);
mesh.applyMatrix( matrix );
mesh.updateMatrix();
mesh.applyMatrix( new THREE.Matrix4().makeTranslation( 64754.68, 15569.13, -4647.5 ) );
mesh.updateMatrix();
scene.add(mesh);

But I still have a problem with translating using the matrix. How can I avoid updating the mesh twice?

3条回答
唯我独甜
2楼-- · 2019-08-13 18:49

From the documentation for modifying the object's matrix directly

Note that matrixAutoUpdate must be set to false in this case, and you should make sure not to call updateMatrix. Calling updateMatrix will clobber the manual changes made to the matrix, recalculating the matrix from position, scale, and so on.

You'll find that after you call mesh.updateMatrix(), the mesh transformation matrix will be different than the one you set. You verify this by comparing matrix.elements to mesh.matrixWorld.elements, which will be the same after you remove updateMatrix.

查看更多
聊天终结者
3楼-- · 2019-08-13 18:52

You need to specify your matrix elements by rows, like so:

matrix.set( n11, n12, n13, n14,
            n21, n22, n23, n24,
            n31, n32, n33, n34,
            n41, n42, n43, n44 );

It is done this way so it is human-readable.

three.js r.76

查看更多
冷血范
4楼-- · 2019-08-13 19:05

suppost you ratate in the x, y, z sequence.

    rotationMatrix = new THREE.Matrix4().multiplyMatrices(new THREE.Matrix4().makeRotationY(rV.y), new THREE.Matrix4().makeRotationX(rV.x));
    rotationMatrix.premultiply(new THREE.Matrix4().makeRotationZ(rV.z));
    matrix.copy(rM).setPosition(vector3);
查看更多
登录 后发表回答