2011-01-14 15 views
6

Creé este Cubo de Rubiks con Papervison3D. Con algunos recursos, creé un cubo con 27 minicubos dentro (3 * 3 * 3 = 27). Al girar el Cubo Rubiks en el movimiento del mouse ya está hecho. (No giro la cámara.)Animación de rotación de cubos de Quaternion

Todo el comportamiento de un cubo Rubiks ya está allí. Pero estoy un poco atrapado en la fase final.

Cuando juego con él como lo haría con un Cubo de Rubiks normal, funciona bien, además de que sé que los valores de rotación de Euler predeterminados ya no son confiables después de un tiempo. Lo que necesito es girar el Cubo de Rubik hacia el lado seleccionado y luego girar el Cubo de Rubik sobre el eje z para que la cara del minicubo quede hacia arriba. Prefiero animarlo con TweenMax pero estoy realmente atascado ya que necesito rotaciones de cuaternión.

Conozco la cara seleccionada del Cubo Rubiks. Sé que la rotación de Euler Rubiks Cube usando Matrix3D.matrix2euler(_rubiksCube.transform); Lo que necesito es girarlo a la cara seleccionada por ejemplo cuando la rotación actual es x: -20, y: 35, z: 10 y selecciono la cara posterior del rubiksCube debe rotar a x:0, y: 180, z: 0.

Lo que necesito es cambiar esto a los valores de Quaternion y rotar el cubo de Rubiks al nuevo valor de Quaternion. Después de eso, debe rotar el Cubo Rubiks sobre su eje z para hacer frente al minicubo seleccionado boca arriba.

Este es el código que uso cuando se arrastra/girar el cubo de Rubik

private function onMouseMove(e : MouseEvent) : void { 
    var m : Matrix3D; 
    m = Matrix3D.rotationY((mouseX - _mouseDownPoint.x)/120); 
    m = Matrix3D.multiply(m, Matrix3D.rotationX(-(mouseY - _mouseDownPoint.y)/120)); 
    _rubiksCube.transform = Matrix3D.multiply(m, _rubiksCube.transform); 
    _mouseDownPoint.x = mouseX; 
    _mouseDownPoint.y = mouseY; 
} 
+2

me trató de seguir su pregunta, pero es difícil. ¿Podrías tratar de ser más claro sobre lo que necesitas? PD No soy un programador de flash. ¿A qué te refieres con "valores de rotación de Euler predeterminados no son confiables después de un tiempo"? Sospecho que desea mantener una representación interna * lógica * del cubo de rubic en lugar de sus ubicaciones físicas. –

Respuesta

4

cuaterniones son definitivamente el camino a seguir. Ha pasado un tiempo desde que usé PV3D, pero es algo como esto:

  1. Almacene los ángulos de euler en variables separadas (por ejemplo, u, v, w). Acumula estas variables en el cálculo.
  2. Cree un cuaternión utilizando Quaternion.createFromEuler();
  3. Transformación mediante quaternion.matrix

Ej:

var yRotation:Number = 0; 
var xRotation:Number = 0; 

function mouseHandler(e:MouseEvent):void { 
    yRotation += (mouseX - _mouseDownPoint.x)/120; 
    xRotation += -(mouseY - _mouseDownPoint.y)/120); 

    var q:Quaternion = Quaternion.createFromEuler(xRotation, yRotation, zRotation, true); 
    _rubiksCube.transform = q.matrix; 
    _mouseDownPoint.x = mouseX; 
    _mouseDownPoint.y = mouseY; 
} 

Actualización: Ah, he leído tu pregunta de nuevo. Parece que quiere interpolar sin problemas desde la orientación actual a la nueva orientación. Lo que funcionó para mí antes es la siguiente:

  1. obtener su ubicación actual Euler y convertir a un cuaternión usando Quaternion.createFromEuler().
  2. Obtén el quaternion de destino.
  3. Interpolar en el tiempo desde el quaternion fuente al destino utilizando quaternion.slerp().

Ej:

function clickHandler(e:MouseEvent):void { 
    qSource = qCurrent; 
    qTarget = quaternion.createFromEuler(....); 
    t = getTimer(); 
} 

function frameHandler(e:Event):void { 
    if (isAnimating) { 
     tDelta = (getTimer() - t)/10000; // 10000 = 10 seconds 
     qCurrent = slerp(qSource, qTarget, tDelta); 
     _rubiksCube.transform = qCurrent.matrix; 
    } 
} 
Cuestiones relacionadas