We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpOpenGL and 3D Libraries › panning (sounds easier than it is )
Page Index Toggle Pages: 1
panning (sounds easier than it is? ) (Read 361 times)
panning (sounds easier than it is? )
Sep 13th, 2008, 12:24am
 
hey!


i'm trying to pan through a 3d scene without "ruining" the perspective. you can achive the effect i'm thinking of by rendering the 3d scene to 2d, and then doing a pan over the result.

the easiest code (that doesn't work) is this:

void setup(){
 size( 320, 240, P3D );
}

void draw(){
 background( 255 );
 translate( mouseX, mouseY );

 fill( 150 );
 stroke( 0 );
 box( 50, 50, 50 );
}


of course that doesn't work, because the perspective of the cube will change as you move your mouse.
i have no idea how to fix this... :(

hansi.
Re: panning (sounds easier than it is? )
Reply #1 - Sep 13th, 2008, 2:45am
 
okay, after a lot of matrix action i found a way to solve this with a "frustum hacksy".
i guess the code that came out could be done a thousands times prettier, however, this works. so if anyone ever wants to do some panning without modifying the perspective use this:

import processing.opengl.*;

void setup(){
 size( 400, 400, OPENGL );
}

void draw(){
 background( 255 );
 pan( mouseX, mouseY );
 stroke( 0 );
 fill( 150 );
 box( 100, 100, 100 );
}


void pan( float dx, float dy ){
 PMatrix p = g.projection;
 float near, far, left, top, right, bottom;
 
 right = p.m23/((-1+p.m22)*p.m00);
 left = -p.m23/(p.m00*(-1+p.m22));
 top = p.m23/((-1+p.m22)*p.m11);
 bottom = -p.m23/(p.m11*(p.m22-1));
 far = p.m23/(1+p.m22);
 near = p.m23/(-1+p.m22);
 
 float scaleX = abs(left-right)/width;
 float scaleY = abs(top-bottom)/height;
 frustum( left-dx*scaleX, right-dx*scaleX, bottom+dy*scaleY, top+dy*scaleY, near, far );
}

this is highly nastly, i know...
i'm pretty proud of myself anyways :-P

p.s. the way this is implemented the current scale factor is not taken into account. this can be good or bad depending on what you're doing.
Re: panning (sounds easier than it is? )
Reply #2 - Sep 14th, 2008, 11:03pm
 
just for completion: above approach won't work in many cases.
this here works perfectly and all the time:

import processing.opengl.*;
import javax.media.opengl.*;



void setup(){
 size( 800, 400, OPENGL );
 frameRate( 100 );
}

void draw(){
 background( 255 );
 pan( (PGraphicsOpenGL) g , mouseX, mouseY );
 stroke( 0 );
 fill( 150 );
 box( 100 );
 box( .5 );
}

float panProjectionFloats[] = new float[16];
void pan( PGraphicsOpenGL g, float dx, float dy ){
 GL gl = (GL) g.gl;
 panProjectionFloats[ 0] = g.projection.m00; panProjectionFloats[ 1] = g.projection.m10; panProjectionFloats[ 2] = g.projection.m20; panProjectionFloats[ 3] = g.projection.m30;
 panProjectionFloats[ 4] = g.projection.m01; panProjectionFloats[ 5] = g.projection.m11; panProjectionFloats[ 6] = g.projection.m21; panProjectionFloats[ 7] = g.projection.m31;
 panProjectionFloats[ 8] = g.projection.m02; panProjectionFloats[ 9] = g.projection.m12; panProjectionFloats[10] = g.projection.m22; panProjectionFloats[11] = g.projection.m32;
 panProjectionFloats[12] = g.projection.m03; panProjectionFloats[13] = g.projection.m13; panProjectionFloats[14] = g.projection.m23; panProjectionFloats[15] = g.projection.m33;
 
 gl.glMatrixMode( GL.GL_PROJECTION );
 gl.glLoadIdentity();
 gl.glTranslatef( 2*dx/g.width, -2*dy/g.height, 0 );
 gl.glMultMatrixf( panProjectionFloats, 0);
 gl.glMatrixMode( GL.GL_MODELVIEW );
}


first of all thanks to _3b_ from the freenode #opengl channel.
the idea of this is to add a 2d-translation before the perspective matrix is loaded. that way you can have "undistorted" panning.

you should call this very soon inside draw(), definitely before you perform any other drawing commands.  
also note that this kind of panning is absolute ( pan(10,0) and then pan(20,0) will result in a pan of 20!).
it also breaks any other translations and rotations you've used. another reason to call it before drawing anything!


ok, hope this proves helpful to someone at some point...
(for reference: code adapted from >>image tiling<< http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node30.html)
Page Index Toggle Pages: 1