2012-09-19 18 views
6

Estoy creando algún tipo de aplicación de arrastrar y soltar en javascript/jquery (basado en DOM, no en lienzo).Traducir las coordenadas del mouse a un plan 3D

La idea es ser capaz de arrastrar divs en una escena en 3D (un div rotado en 3D).

Se trabaja en un plano 2D, el problema es cuando puedo rotar la escena en 3D, la posición de los objetos no refleja la posición actual del ratón, pero las coordenadas traduce en 3D

exemple Ilustrado: exemple

EXEMPLE ON JSFIDDLE

quiero que los objetos en movimiento con respecto a la posición absoluta del ratón.

I calcular la posición del ratón como esto:

document.addEventListener(gestureMove, function (event) { 
    if (mouseDown == true) { 
    event.preventDefault(); 
    moveX = (event.pageX - $('#scene').offset().left); 
    moveY = (event.pageY - $('#scene').offset().top); 
} 

#scene { 
    width: 1000px; 
    height: 1000px; 
    -webkit-transform-style: preserve-3d; 
    -webkit-transform: rotateX(35deg); 
} 

Una solución temprana era para calcular la diferencia entre la posición del ratón y el objeto en base a la posición inicial, y de añadir a la posición del objeto durante el arrastre . Funcionó, pero la animación fue realmente entrecortada y nada suave.

Estoy seguro de que hay una manera más simple de obtener las coordenadas del mouse relativas al plan 3D, pero no fue posible encontrar una solución real en este punto.

La mayoría de los resultados de búsqueda en esta materia apuntan a lenguajes orientados a juegos, o preguntas canvas/webgl.

¿Alguna idea?

Gracias

+0

Creo que Google Sketch-up hizo un buen trabajo al respecto. –

+0

Probablemente termines haciendo lo contrario de la proyección en perspectiva: http://en.wikipedia.org/wiki/3D_projection#Perspective_projection – Blender

+0

¿Puedes destilar tu código lo suficiente como para caber en jsfiddle? – Shmiddty

Respuesta

2

Suponiendo que la posición del ratón es una posición de la pantalla absoluta, y quiere agarrar y deslizar un objeto alrededor de un plano en 3D basado directamente en la posición del ratón:

Puede representar a su 3D plano objetivo como:

  • un origen 3D de punto O
  • dos vectores 3D U y V, que representan la dirección de las direcciones U y V ejes

Entonces, dado un punto 3D correspondiente al plano de coordenadas [u,v] es:

point3d P = O + u*U + v*V 

A continuación, se pueden combinar las operaciones que se asignan a este punto en particular en 3D a la pantalla ; esto generalmente se describe con las matrices de transformación 3D ModelMatrix, ViewMatrix y ProjectionMatrix, y una transformación de ventana determinada por un punto de origen de pantalla 2D origin_2d y un vector de escala 2D scale_2d. Para resolver el problema de una manera fácilmente invertible, promocione todo a coordenadas homogéneas, agregando un .w -coordinación a cada uno de ellos.Este extra de coordinar actúa como un factor de escala - para obtener las coordenadas cartesianas de vuelta, es necesario dividir los homogéneas .x y .y valores por el valor .w:

P_hom = [u, v, 1] * [U.x, U.y, U.z, 0] = [u, v, 1] * TexMatrix 
        [V.x, V.y, V.z, 0] 
        [O.x, O.y, O.z, 1] 

P_clip_hom = P_hom * ModelMatrix * ViewMatrix * ProjectionMatrix 
      = P_hom * ModelViewProjectionMatrix 

screenpos_hom = P_clip_hom * [scale_2d.x  0  0] = P_clip_hom * PortMatrix 
          [ 0  scale_2d.y 0] 
          [ 0   0  0] 
          [origin_2d.x origin_2d.y 1] 

So, screenpos_hom = [u, v, 1] * TexMatrix * ModelViewProjectionMatrix * PortMatrix 
        = [u, v, 1] * TexToScreenMatrix 

-> [screenpos.x, screenpos.y] = [screenpos_hom.x, screenpos_hom.y]/screenpos_hom.w 

Tenga en cuenta que TexToScreenMatrix es una matriz 3x3; usted debería ser capaz de invertirla:

UV_2d_hom = [screenpos.x, screenpos.y, 1] * (TexToScreenMatrix)^-1 

-> [u, v] = [UV_2d_hom.x, UV_2d_hom.y]/UV_2d_hom.w 

Por último, puede utilizar el [u,v] coordina directamente, o puede usarlos para recrear el punto P 3D como se describió anteriormente.

+0

gracias! pero no estoy seguro de ver cómo usar matrices de transformación 3D en JavaScript. Además, ¿qué es "w" en mi ejemplo? – Julian

+0

Me temo que no sé cómo están vinculados en la plataforma javascript/webkit. Si no puede acceder directamente a las matrices de transformación de webkit, puede que tenga que hacer coincidir las matemáticas 3D en javascript; por ejemplo, si usa 'rotateX (35deg)', desafortunadamente necesitará configurar su propia rotación 3D en X. matriz de 35 grados y multiplíquelo en su propia 'ViewMatrix' ... – comingstorm

+0

En cuanto a la" w ", traté de explicarlo brevemente en mi respuesta; La división por "w" es lo que te permite hacer una perspectiva 3D en primer lugar. Si quiere entenderlo mejor que eso, necesita una presentación más larga y mejor sobre matemática 3D básica; prueba wikipedia en [proyección 3D] (http://en.wikipedia.org/wiki/3D_projection). – comingstorm

Cuestiones relacionadas