javascript coffeescript three.js

javascript - Cómo rotar un objeto 3D en el eje three.js?



coffeescript (9)

Tengo un gran problema con la rotación en three.js. Quiero rotar mi cubo 3D en uno de mis juegos.

//init geometry = new THREE.CubeGeometry grid, grid, grid material = new THREE.MeshLambertMaterial {color:0xFFFFFF * Math.random(), shading:THREE.FlatShading, overdraw:true, transparent: true, opacity:0.8} for i in [[email protected]] othergeo = new THREE.Mesh new THREE.CubeGeometry(grid, grid, grid) othergeo.position.x = grid * @shape[i][0] othergeo.position.y = grid * @shape[i][1] THREE.GeometryUtils.merge geometry, othergeo @mesh = new THREE.Mesh geometry, material //rotate @mesh.rotation.y += y * Math.PI / 180 @mesh.rotation.x += x * Math.PI / 180 @mesh.rotation.z += z * Math.PI / 180

y (x, y, z) puede ser (1, 0, 0)

entonces el cubo puede rotar, pero el problema es que el cubo gira sobre su propio eje, por lo que una vez que ha girado, no puede girar como se espera.

Encuentro la página ¿Cómo rotar un Three.js Vector3 alrededor de un eje? , pero solo deja que un punto Vector3 gire alrededor del eje del mundo?

y he intentado usar matrixRotationWorld como

@mesh.matrixRotationWorld.x += x * Math.PI / 180 @mesh.matrixRotationWorld.y += y * Math.PI / 180 @mesh.matrixRotationWorld.z += z * Math.PI / 180

pero no funciona, no sé si lo usé de manera incorrecta o si hay otras formas ...

Entonces, ¿cómo dejar que el cubo 3D gire alrededor del eje del mundo?


Desde la versión r59, three.js proporciona esas tres funciones para rotar un objeto alrededor del eje del objeto.

object.rotateX(angle); object.rotateY(angle); object.rotateZ(angle);


En Three.js R59, object.rotation.setEulerFromRotationMatrix(object.matrix); ha sido cambiado a object.rotation.setFromRotationMatrix(object.matrix);

3js está cambiando tan rápidamente: D


En Three.js R66, esto es lo que uso (versión CoffeeScript):

THREE.Object3D.prototype.rotateAroundWorldAxis = (axis, radians) -> rotWorldMatrix = new THREE.Matrix4() rotWorldMatrix.makeRotationAxis axis.normalize(), radians rotWorldMatrix.multiply this.matrix this.matrix = rotWorldMatrix this.rotation.setFromRotationMatrix this.matrix


En algún lugar alrededor de r59 esto se vuelve más fácil (rotar alrededor de x):

bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX) { var euler = new THREE.Euler( rotationX, 0, 0, ''XYZ'' ); obj.position.applyEuler(euler); }


Estas son las dos funciones que uso. Se basan en rotaciones de matriz. y puede rotar alrededor de ejes arbitrarios. Para rotar usando los ejes del mundo, querrá usar la segunda función, rotateAroundWorldAxis ().

// Rotate an object around an arbitrary axis in object space var rotObjectMatrix; function rotateAroundObjectAxis(object, axis, radians) { rotObjectMatrix = new THREE.Matrix4(); rotObjectMatrix.makeRotationAxis(axis.normalize(), radians); // old code for Three.JS pre r54: // object.matrix.multiplySelf(rotObjectMatrix); // post-multiply // new code for Three.JS r55+: object.matrix.multiply(rotObjectMatrix); // old code for Three.js pre r49: // object.rotation.getRotationFromMatrix(object.matrix, object.scale); // old code for Three.js r50-r58: // object.rotation.setEulerFromRotationMatrix(object.matrix); // new code for Three.js r59+: object.rotation.setFromRotationMatrix(object.matrix); } var rotWorldMatrix; // Rotate an object around an arbitrary axis in world space function rotateAroundWorldAxis(object, axis, radians) { rotWorldMatrix = new THREE.Matrix4(); rotWorldMatrix.makeRotationAxis(axis.normalize(), radians); // old code for Three.JS pre r54: // rotWorldMatrix.multiply(object.matrix); // new code for Three.JS r55+: rotWorldMatrix.multiply(object.matrix); // pre-multiply object.matrix = rotWorldMatrix; // old code for Three.js pre r49: // object.rotation.getRotationFromMatrix(object.matrix, object.scale); // old code for Three.js pre r59: // object.rotation.setEulerFromRotationMatrix(object.matrix); // code for r59+: object.rotation.setFromRotationMatrix(object.matrix); }

Por lo tanto, debe llamar a estas funciones dentro de su función anim (requestAnimFrame callback), lo que da como resultado una rotación de 90 grados en el eje x:

var xAxis = new THREE.Vector3(1,0,0); rotateAroundWorldAxis(mesh, xAxis, Math.PI / 180);


Necesitaba la función rotateAroundWorldAxis , pero el código anterior no funciona con la versión más reciente (r52). Parece que getRotationFromMatrix() fue reemplazado por setEulerFromRotationMatrix()

function rotateAroundWorldAxis( object, axis, radians ) { var rotationMatrix = new THREE.Matrix4(); rotationMatrix.makeRotationAxis( axis.normalize(), radians ); rotationMatrix.multiplySelf( object.matrix ); // pre-multiply object.matrix = rotationMatrix; object.rotation.setEulerFromRotationMatrix( object.matrix ); }


Por si acaso ... en r52 el método se llama setEulerFromRotationMatrix lugar de getRotationFromMatrix



con r55 tienes que cambiar
rotationMatrix.multiplySelf (object.matrix);
a
rotationMatrix.multiply (object.matrix);