2012-06-20 8 views
10

Можно ли делать вращения с осью мира, а не с объектом?Как повернуть объект на оси мира three.js?

Мне нужно сделать некоторые вращения объекта, но после первого поворота я не могу выполнять другие вращения, как я хочу.

Если поворот на оси невозможен, вторым вариантом является сброс оси после первого поворота. Есть ли какая-то функция для этого?

Я не могу использовать object.eulerOrder, потому что он меняет ориентацию моего объекта, когда я устанавливаю object.eulerOrder="YZX" после некоторых поворотов.

+0

@RamyAlZuhouri Попробуйте эти новые методы: http://stackoverflow.com/a/17712076 – user2301179

ответ

12

Да, вы можете сделать это с помощью функции, которая подавалась по three.js вопросам 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); 
} 

Тогда

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

Смотрите мой пример - http://jsfiddle.net/SCXNQ/156/

+0

getRotationFromMatrix не признаваемых в качестве функции, также multiplySelf. Нужно ли использовать конкретную версию three.js? –

+1

@RamyAlZuhouri взгляните на три github, посмотрите, что они теперь изменили. Я хотел бы использовать последние три .js – Neil

+8

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

2

Вот небольшое изменение , Протестировано с 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); 
} 

три последние строки только для повторной синхронизации Params (position,rotation) из матрицы ... Интересно, если есть более эффективный способ сделать это ...

1

Где-то около R59 это получает много проще (вращение вокруг х):

bb.GraphicsEngine.prototype.calcRotation = function (obj, rotationX) 
{ 
    var euler = new THREE.Euler(rotationX, 0, 0, 'XYZ'); 
    obj.position.applyEuler(euler); 
} 
Смежные вопросы