// cobbled together from several examples...
Cube = Scene Display List( 1 );
Cube << Begin( QUAD_STRIP );
Cube << Color( 1.0, 0.0, 1.0 );
Cube << Vertex( -0.5, 0.5, 0.5 );
Cube << Color( 1.0, 0.0, 0.0 );
Cube << Vertex( -0.5, -0.5, 0.5 );
Cube << Color( 1.0, 1.0, 1.0 );
Cube << Vertex( 0.5, 0.5, 0.5 );
Cube << Color( 1.0, 1.0, 0.0 );
Cube << Vertex( 0.5, -0.5, 0.5 );
Cube << Color( 0.0, 1.0, 1.0 );
Cube << Vertex( 0.5, 0.5, -0.5 );
Cube << Color( 0.0, 1.0, 0.0 );
Cube << Vertex( 0.5, -0.5, -0.5 );
Cube << Color( 0.0, 0.0, 1.0 );
Cube << Vertex( -0.5, 0.5, -0.5 );
Cube << Color( 0.0, 0.0, 0.0 );
Cube << Vertex( -0.5, -0.5, -0.5 );
Cube << Color( 1.0, 0.0, 1.0 );
Cube << Vertex( -0.5, 0.5, 0.5 );
Cube << Color( 1.0, 0.0, 0.0 );
Cube << Vertex( -0.5, -0.5, 0.5 );
Cube << End();
cube1 = Scene Display List();
cube1 << arcball( cube, .5 ); // don't rebuild the arcballs so
cube2 = Scene Display List();
cube2 << arcball( cube, .5 ); // they remember their positions
WindowHeight = 600;
WindowWidth = 800;
mouseOriginY = WindowHeight / 2;
mouseOriginX = WindowWidth / 2;
mode = "done";
dx = dy = .;
mouseMatrix = Identity( 4 ); // <<<< this accumulates all the angle/size/scale changes
// this function is called with m==1 on mouse down, m==2 on mouse drags, and m=3 on mouse up (k is the shift/control/alt status)
// this function returns 0 or 1, on purpose, to allow arc balls to run or this code to adjust the mouseMatrix.
Click2d = Function( {x, y, m, k},
{xt, xs, xr, yr, zr, degrees, radians, dx, dy},
If(
m == 1,
mouseOriginX = x;
mouseOriginY = y;
If( Is Shift Key(),
mode = "translate"
);
// if(Is Alt Key(), // linux/virtualbox the alt key never makes it to 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 ); // allow the arc ball to get control. 0 means this handler did NOT handle the click.
);//
, /*else if */ m == 2,
dx = x - mouseOriginX;
dy = y - mouseOriginY;
If(
mode == "translate",
xt = Identity( 4 );
xt[1, 4] = dx / WindowWidth;
xt[2, 4] = -dy / WindowWidth;
mouseMatrix = xt * mouseMatrix;//
, /* else if */ mode == "scale",
xs = Identity( 4 );
xs[1, 1] = If( dx >= 0,
(dx + WindowWidth) / WindowWidth//
,
WindowWidth / (WindowWidth - dx)
);
xs[2, 2] = If( dy >= 0,
WindowHeight / (dy + WindowHeight)//
,
(WindowHeight - dy) / WindowHeight
);
mouseMatrix = xs * mouseMatrix;//
, /* else if */ mode == "rotate",
radians = 6 * dy / WindowWidth;
xr = Identity( 4 ); // start out with an identity matrix then plug in the values to rotate about the x axis
xr[2, 2] = Cos( radians );
xr[2, 3] = -Sin( radians );
xr[3, 2] = Sin( radians );
xr[3, 3] = Cos( radians );
yr = Identity( 4 ); // and the y axis
radians = 6 * dx / WindowHeight;
yr[1, 1] = Cos( radians );
yr[1, 3] = Sin( radians );
yr[3, 1] = -Sin( radians );
yr[3, 3] = Cos( radians );
zr = Identity( 4 ); // and the z axis
mouseMatrix = xr * mouseMatrix;
mouseMatrix = yr * mouseMatrix;
);
mouseOriginX = x;
mouseOriginY = y;
rebuild();//
, /*else if */ m == 3,
mode = "done";
0;//
, /* else */
Throw( "unexpected m=" || Char( m ) )
);
//0 // because this function does NOT return 1, JMP will not call it again until the next mouse down. Drags will act like moves and go to the Move2d function.
1; // because it *does* return 1, m=1,2,3 for press,move(s),release
);
Scene = Scene Box( WindowWidth, WindowHeight, Click2d );
Scene << Show ArcBall( "Always" );
New Window( "Matrix rotations", V List Box( Text Box( "shift-drag: pan\!nctrl-drag: zoom\!nctrl-shift-drag: rotate\!nVanilla-drag: rotate cubes" ), Scene ) );
rebuild = Function( {},
degrees = 45;
radians = 3.14159 * degrees / 180; // sin and cos use radians
Scene << clear;
Scene << perspective( 45, 3, 7 );
Scene << Translate( 0.0, 0.0, -4.5 );
// apply the global translation/rotation/scaling
Scene << MultMatrix( mouseMatrix );
Scene << pushmatrix;
xt = Identity( 4 ); // translate this one left by .75
xt[1, 4] = -.75;
Scene << MultMatrix( xt );
Scene << callList( Cube1 );
Scene << popmatrix;
Scene << pushmatrix;
Scene << translate( .75, 0, 0 ); // translate this one right by .75
Scene << calllist( Cube2 );
Scene << popmatrix;
Scene << update;
);
rebuild();
// cobbled together from several examples...
Cube = Scene Display List( 1 );
Cube << Begin( QUAD_STRIP );
Cube << Color( 1.0, 0.0, 1.0 );
Cube << Vertex( -0.5, 0.5, 0.5 );
Cube << Color( 1.0, 0.0, 0.0 );
Cube << Vertex( -0.5, -0.5, 0.5 );
Cube << Color( 1.0, 1.0, 1.0 );
Cube << Vertex( 0.5, 0.5, 0.5 );
Cube << Color( 1.0, 1.0, 0.0 );
Cube << Vertex( 0.5, -0.5, 0.5 );
Cube << Color( 0.0, 1.0, 1.0 );
Cube << Vertex( 0.5, 0.5, -0.5 );
Cube << Color( 0.0, 1.0, 0.0 );
Cube << Vertex( 0.5, -0.5, -0.5 );
Cube << Color( 0.0, 0.0, 1.0 );
Cube << Vertex( -0.5, 0.5, -0.5 );
Cube << Color( 0.0, 0.0, 0.0 );
Cube << Vertex( -0.5, -0.5, -0.5 );
Cube << Color( 1.0, 0.0, 1.0 );
Cube << Vertex( -0.5, 0.5, 0.5 );
Cube << Color( 1.0, 0.0, 0.0 );
Cube << Vertex( -0.5, -0.5, 0.5 );
Cube << End();
cube1 = Scene Display List();
cube1 << arcball( cube, .5 ); // don't rebuild the arcballs so
cube2 = Scene Display List();
cube2 << arcball( cube, .5 ); // they remember their positions
WindowHeight = 600;
WindowWidth = 800;
mouseOriginY = WindowHeight / 2;
mouseOriginX = WindowWidth / 2;
mode = "done";
dx = dy = .;
mouseMatrix = Identity( 4 ); // <<<< this accumulates all the angle/size/scale changes
// this function is called with m==1 on mouse down, m==2 on mouse drags, and m=3 on mouse up (k is the shift/control/alt status)
// this function returns 0 or 1, on purpose, to allow arc balls to run or this code to adjust the mouseMatrix.
Click2d = Function( {x, y, m, k},
{xt, xs, xr, yr, zr, degrees, radians, dx, dy},
If(
m == 1,
mouseOriginX = x;
mouseOriginY = y;
If( Is Shift Key(),
mode = "translate"
);
// if(Is Alt Key(), // linux/virtualbox the alt key never makes it to 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 ); // allow the arc ball to get control. 0 means this handler did NOT handle the click.
);//
, /*else if */ m == 2,
dx = x - mouseOriginX;
dy = y - mouseOriginY;
If(
mode == "translate",
xt = Identity( 4 );
xt[1, 4] = dx / WindowWidth;
xt[2, 4] = -dy / WindowWidth;
mouseMatrix = xt * mouseMatrix;//
, /* else if */ mode == "scale",
xs = Identity( 4 );
xs[1, 1] = If( dx >= 0,
(dx + WindowWidth) / WindowWidth//
,
WindowWidth / (WindowWidth - dx)
);
xs[2, 2] = If( dy >= 0,
WindowHeight / (dy + WindowHeight)//
,
(WindowHeight - dy) / WindowHeight
);
mouseMatrix = xs * mouseMatrix;//
, /* else if */ mode == "rotate",
radians = 6 * dy / WindowWidth;
xr = Identity( 4 ); // start out with an identity matrix then plug in the values to rotate about the x axis
xr[2, 2] = Cos( radians );
xr[2, 3] = -Sin( radians );
xr[3, 2] = Sin( radians );
xr[3, 3] = Cos( radians );
yr = Identity( 4 ); // and the y axis
radians = 6 * dx / WindowHeight;
yr[1, 1] = Cos( radians );
yr[1, 3] = Sin( radians );
yr[3, 1] = -Sin( radians );
yr[3, 3] = Cos( radians );
zr = Identity( 4 ); // and the z axis
mouseMatrix = xr * mouseMatrix;
mouseMatrix = yr * mouseMatrix;
);
mouseOriginX = x;
mouseOriginY = y;
rebuild();//
, /*else if */ m == 3,
mode = "done";
0;//
, /* else */
Throw( "unexpected m=" || Char( m ) )
);
//0 // because this function does NOT return 1, JMP will not call it again until the next mouse down. Drags will act like moves and go to the Move2d function.
1; // because it *does* return 1, m=1,2,3 for press,move(s),release
);
Scene = Scene Box( WindowWidth, WindowHeight, Click2d );
Scene << Show ArcBall( "Always" );
New Window( "Matrix rotations", V List Box( Text Box( "shift-drag: pan\!nctrl-drag: zoom\!nctrl-shift-drag: rotate\!nVanilla-drag: rotate cubes" ), Scene ) );
rebuild = Function( {},
degrees = 45;
radians = 3.14159 * degrees / 180; // sin and cos use radians
Scene << clear;
Scene << perspective( 45, 3, 7 );
Scene << Translate( 0.0, 0.0, -4.5 );
// apply the global translation/rotation/scaling
Scene << MultMatrix( mouseMatrix );
Scene << pushmatrix;
xt = Identity( 4 ); // translate this one left by .75
xt[1, 4] = -.75;
Scene << MultMatrix( xt );
Scene << callList( Cube1 );
Scene << popmatrix;
Scene << pushmatrix;
Scene << translate( .75, 0, 0 ); // translate this one right by .75
Scene << calllist( Cube2 );
Scene << popmatrix;
Scene << update;
);
rebuild();