2012-06-20 40 views
10

¿Es posible hacer rotaciones teniendo ejes del mundo y no del objeto?Cómo rotar un objeto en axis world three.js?

Necesito hacer algunas rotaciones de un objeto, pero después de la primera rotación, no puedo hacer otras rotaciones como quiera.

Si no es posible hacer la rotación en el eje del mundo, mi segunda opción es restablecer el eje después de la primera rotación. ¿Hay alguna función para esto?

No puedo usar object.eulerOrder porque cambia la orientación de mi objeto cuando configuro object.eulerOrder="YZX" después de algunas rotaciones.

+0

@RamyAlZuhouri probar estos métodos más nuevos: http://stackoverflow.com/a/17712076 – user2301179

Respuesta

12

Sí, puede hacerlo con una función que se proporciona en Three.js cuestiones de GitHub:

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); 
    rotWorldMatrix.multiplySelf(object.matrix);  // pre-multiply 
    object.matrix = rotWorldMatrix; 
    object.rotation.getRotationFromMatrix(object.matrix, object.scale); 
} 

Entonces

//rotate 30 degrees on world X 
rotateAroundWorldAxis(cube, new THREE.Vector3(1,0,0), 30 * Math.PI/180); 

Ver mi ejemplo - http://jsfiddle.net/SCXNQ/156/

+0

getRotationFromMatrix no se reconoce como una función, también multiplySelf. ¿Debo usar una versión específica de three.js? –

+1

@RamyAlZuhouri echa un vistazo a los tres github, mira a qué han cambiado las funciones ahora. Me gustaría utilizar el último Three.js – Neil

+8

'getRotationFromMatrix (object.matrix, object.scale)' -> 'setFromRotationMatrix (object.matrix)' y 'multiplySelf' ->' multiply'. r71 – PierreDuc

2

Aquí hay una pequeña variación . Probado con r56.

THREE.Object3D._matrixAux = new THREE.Matrix4(); // global auxiliar variable 
// Warnings: 1) axis is assumed to be normalized. 
// 2) matrix must be updated. If not, call object.updateMatrix() first 
// 3) this assumes we are not using quaternions 
THREE.Object3D.prototype.rotateAroundWorldAxis = function(axis, radians) { 
    THREE.Object3D._matrixAux.makeRotationAxis(axis, radians); 
    this.matrix.multiplyMatrices(THREE.Object3D._matrixAux,this.matrix); // r56 
    THREE.Object3D._matrixAux.extractRotation(this.matrix); 
    this.rotation.setEulerFromRotationMatrix(THREE.Object3D._matrixAux, this.eulerOrder); 
    this.position.getPositionFromMatrix(this.matrix); 
} 
THREE.Object3D.prototype.rotateAroundWorldAxisX = function(radians) { 
    this._vector.set(1,0,0); 
    this.rotateAroundWorldAxis(this._vector,radians); 
} 
THREE.Object3D.prototype.rotateAroundWorldAxisY = function(radians) { 
    this._vector.set(0,1,0); 
    this.rotateAroundWorldAxis(this._vector,radians); 
} 
THREE.Object3D.prototype. rotateAroundWorldAxisZ = function(degrees){ 
    this._vector.set(0,0,1); 
    this.rotateAroundWorldAxis(this._vector,degrees); 
} 

Las tres últimas líneas son sólo para volver a sincronizar los parametros (position,rotation) de la matriz ... Me pregunto si hay una manera más eficiente de hacer eso ...

1

En algún momento alrededor r59 esto se pone mucho más fácil (girar alrededor de x):

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