// compuesto de varios ejemplos... Cubo = Scene Display List( 1 ); Cubo << Begin( QUAD_STRIP ); Cubo << Color( 1.0, 0.0, 1.0 ); Cubo << Vertex( -0.5, 0.5, 0.5 ); Cubo << Color( 1.0, 0.0, 0.0 ); Cubo << Vertex( -0.5, -0.5, 0.5 ); Cubo << Color( 1.0, 1.0, 1.0 ); Cubo << Vertex( 0.5, 0.5, 0.5 ); Cubo << Color( 1.0, 1.0, 0.0 ); Cubo << Vertex( 0.5, -0.5, 0.5 ); Cubo << Color( 0.0, 1.0, 1.0 ); Cubo << Vértice( 0.5, 0.5, -0.5 ); Cubo << Color( 0.0, 1.0, 0.0 ); Cubo << Vértice( 0.5, -0.5, -0.5 ); Cubo << Color( 0.0, 0.0, 1.0 ); Cubo << Vértice( -0.5, 0.5, -0.5 ); Cubo << Color( 0.0, 0.0, 0.0 ); Cubo << Vértice( -0.5, -0.5, -0.5 ); Cubo << Color( 1.0, 0.0, 1.0 ); Cubo << Vértice( -0.5, 0.5, 0.5 ); Cubo << Color( 1.0, 0.0, 0.0 ); Cubo << Vértice( -0.5, -0.5, 0.5 ); Cubo << Fin(); cube1 = Scene Display List(); cube1 << arcball( cube, .5 ); // no reconstruyas las arcballs, por lo que cube2 = Scene Display List(); cube2 << arcball( cube, .5 ); // recuerdan sus posiciones WindowHeight = 600; WindowWidth = 800; mouseOriginY = WindowHeight / 2; mouseOriginX = WindowWidth / 2; mode = "done"; dx = dy = .; mouseMatrix = Identity( 4 ); // <<<< esto acumula todos los cambios de ángulo/tamaño/escala // esta función se llama con m==1 con el mouse presionado, m==2 con el mouse arrastrado y m=3 con el mouse levantado (k es el estado shift/control/alt) // esta función devuelve 0 o 1, a propósito, para permitir que las arcballs se ejecuten o este código para ajustar mouseMatrix. Click2d = Function( {x, y, m, k}, {xt, xs, xr, yr, zr, grados, radianes, dx, dy}, If( m == 1, mouseOriginX = x; mouseOriginY = y; If( Is Shift Key(), mode = "translate" ); // if(Is Alt Key(), // linux/virtualbox la tecla alt nunca llega a JMP // mode = "rotate"; // ); If( Is Control Key(), mode = "scale" ); If( Is Control Key() & Is Shift Key(), mode = "rotate" ); If( !Is Control Key() & !Is Shift Key(), Return( 0 ); // permite que la bola de arco tome el control. 0 significa que este controlador NO manejó el clic. );// , /*else if */ m == 2, dx = x - mouseOriginX; dy = y - mouseOriginY; If( mode == "traducir", xt = Identidad( 4 ); xt[1, 4] = dx / AnchoVentana; xt[2, 4] = -dy / AnchoVentana; matrizDeRatón = xt * MatrizDeRatón;// , /* de lo contrario si */ modo == "escala", xs = Identidad( 4 ); xs[1, 1] = Si( dx >= 0, (dx + AnchoVentana) / AnchoVentana// , AnchoVentana / (AnchoVentana - dx) ); xs[2, 2] = Si( dy >= 0, AltoVentana / (dy + AltoVentana)// , (AltoVentana - dy) / AltoVentana ); matrizDeRatón = xs * MatrizDeRatón;// , /* de lo contrario si */ modo == "rotar", radianes = 6 * dy / AnchoVentana; xr = Identidad( 4 ); // inicio con una matriz identidad, luego reemplaza los valores para rotar sobre el eje x xr[2, 2] = Cos( radianes ); xr[2, 3] = -Sin( radianes ); xr[3, 2] = Sin( radianes ); xr[3, 3] = Cos( radianes ); yr = Identidad( 4 ); // y el eje y radianes = 6 * dx / WindowHeight; yr[1, 1] = Cos( radianes ); yr[1, 3] = Sin( radianes ); yr[3, 1] = -Sin( radianes ); yr[3, 3] = Cos( radianes ); zr = Identidad( 4 ); // y el eje z mouseMatrix = xr * mouseMatrix; mouseMatrix = yr * mouseMatrix; ); mouseOriginX = x; mouseOriginY = y; rebuild();// , /*de lo contrario, si */ m == 3, modo = "listo"; 0;// , /* de lo contrario */ Throw( "m inesperado=" || Char( m ) ) ); //0 // Como esta función no devuelve 1, JMP no la volverá a llamar hasta la siguiente pulsación del ratón. Los arrastres actuarán como movimientos y se aplicarán a la función Move2d. 1; // Porque *sí* devuelve 1, m=1,2,3 para presionar, mover(es), soltar ); Escena = Scene Box( WindowWidth, WindowHeight, Click2d ); Escena << Show ArcBall( "Siempre" ); Nueva ventana( "Rotaciones de matriz", V List Box( Text Box( "Mayús+arrastrar: pan\!nCtrl+arrastrar: zoom\!nCtrl+mayús+arrastrar: rotar\!nVanilla+arrastrar: rotar cubos" ), Escena ) ); reconstruir = Función( {}, grados = 45; radianes = 3.14159 * grados / 180; // seno y coseno usan radianes Escena << borrar; Escena << perspectiva( 45, 3, 7 ); Escena << Traducir( 0.0, 0.0, -4.5 ); // aplicar la traslación/rotación/escalado global Escena << MatrizMult( MatrizMouse); Escena << MatrizPush; xt = Identidad( 4 ); // trasladar este a la izquierda en .75 xt[1, 4] = -.75; Escena << MatrizMult( xt ); Escena << ListaLlamadas( Cubo1 ); Escena << MatrizPop; Escena << MatrizPush; Escena << Traducir( .75, 0, 0 ); // trasladar este a la derecha en .75 Escena << ListaLlamadas( Cubo2 ); Escena << MatrizPop; Escena << Actualizar; ); reconstruir();