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 › wrapping around in 3D scene.
Page Index Toggle Pages: 1
wrapping around in 3D scene. (Read 1074 times)
wrapping around in 3D scene.
Jul 21st, 2008, 7:16pm
 
Hi All,

I have a 3D scene - with stationary camera, in which I would like to declare some boundaries but am having problems setting it up. This is the behaviour I would like:

- if an object moves off the left or right of the screen, it reappears on the other side of the screen (wraparound)
- if it hits the top or bottom, it bounces back.

I don't want my boundary checks to be in world coordinates, but in screen coordinates. So it doesnt matter how far from the camera my object is, I want it to be able to go as far left or up or right or down as the edges of my screen, and then I want it to wrap or bounce. And I have a few questions regarding this:

1. For the detection I am using screenX() and screenY() and the detection is working fine. But is this best way to do this? My camera is stationary with no rotation, maybe I could use some optimized method instead?

2. How can I know how much to move my object by to wrap it around? in 2D world I would do if(x<0) x+= width; how much do I offset it by if it is at z=500?

3. This is where it gets a bit more complicated. My objects are long sequences of springs. And when they cross the edges of the screen, they need to wrap around seamlessly. To do this I am doing 2 things:
- when they cross the left or right edge I move all the nodes across by width (as mentioned above - which doesn't work if the object is not at z=0)
- in the object::render() I check to see if the object is near the edge of the screen, if it is I render it twice. once in the original position, once offset by width (or -width). This way if my ribbon goes off the left, but then turns around and comes back, I can see the correct parts on both sides of the screen. However if the ribbon is far back, then the renderWithOffset(width), doesnt work of course, again how do I get this value? (same as before?)

thanks in advance...
Re: wrapping around in 3D scene.
Reply #1 - Jul 22nd, 2008, 11:06am
 
you will have to calculate your camera frustum and test the objects against the planes that make it..
when its out of the frustum on the left side u could pass it to the point on the right side when the object would hit the frustum.
if u're camera is fixed and the object is at z=500 or z=0, you would just need to offset the x value

3. for a FOV of 45 degrees the distance of an object in the leftside from the center would be the same for the right side, so that would be your offset value.

Re: wrapping around in 3D scene.
Reply #2 - Jul 23rd, 2008, 12:02am
 
Hu crmx, yea thats basically what I'm asking info on - how to get the camera frustum. I could do it all from scratch using trigonometry, but I was wondering if there are any methods or tools to simplify the process....
Re: wrapping around in 3D scene.
Reply #3 - Jul 23rd, 2008, 3:43am
 
Hi, well I figured out the first part - detecting the boundaries and moving my objects by the correct amount - if anyone encounters the same situation my code is below (this assumes a basic camera looking down the Z axis with no rotation). But now I have a new problem...

Code:

final static int WIDTH              = 1200;                              // width of render viewport
final static int HEIGHT             = 1800 * 3/4 / 3;                    // height of render viewport
final static float HALF_WIDTH       = WIDTH * 0.5;
final static float HALF_HEIGHT      = HEIGHT * 0.5;
final static float FOV_Y            = PI/3;                              // vertical field of view
final static float CAM_DIST         = HALF_HEIGHT / tan(FOV_Y/2);        // distance from camera to render plane
final static float FOV_X            = 2 * atan(HALF_WIDTH / CAM_DIST);   // horizontal field of view
final static float TAN_HALF_FOV_X   = tan(FOV_X/2);

// gives screen X, Y coordinate for world position x,y,z
Vec3D msaGetScreenXY(float worldX, float worldY, float worldZ) {
   float f = CAM_DIST / (CAM_DIST - worldZ);
   return new Vec3D (HALF_WIDTH + (f * (worldX - HALF_WIDTH)), HALF_HEIGHT - (f * (HALF_HEIGHT - worldY)), 0);
}

void draw() {
   float scrWidth = 2 * TAN_HALF_FOV_X * (CAM_DIST - pos.z);
   scrPos = msaGetScreenXY(pos.x, pos.y, pos.z);
      if (scrPos.x < 0) {
           println(" LESSS ");
           pos.x += scrWidth;
           scrPos.x += width;
           for(int i=0; i<ribbonSegments; i++) {
               particles[i].moveBy(scrWidth, 0, 0);
               particles[i].velocity().clear();
           }
       }
       else if (scrPos.x > width) {
           println(" MORE ");
           pos.x -= scrWidth;
           scrPos.x -= width;
           for(int i=0; i<ribbonSegments; i++) {
               particles[i].moveBy(-scrWidth, 0, 0);
               particles[i].velocity().clear();
           }
       }
}


This seems to take care of the edge detection and wrapping (moving the object) quite nicely. But now my problem is that if the object crosses the edge slowly, as soon as the head passes the edge, the whole object jumps to the other side. To resolve this I was rendering the object twice, but I'm not sure that works. Originally I was just rendering the whole object again shifted by scrWidth. But thats a shift in 3D, and I dont think the perspective matches the far left and far right. Is this even possible to do with a perspective view as I'm going to have problems with the vanishing point probably!?

Re: wrapping around in 3D scene.
Reply #4 - Jul 23rd, 2008, 11:03am
 
your problem is obvious, you are checking visibility for a point.
your idea on rendering same object twice is good, that would work.

u cant do it other way without check for every polygon, and to make it look good ur object would have to be highpoly otherwise u would see polygons jumping, same as the object but in a smaller scale.

u might want to keep to the duplicate object idea. sounds good to me
Re: wrapping around in 3D scene.
Reply #5 - Jul 23rd, 2008, 11:30am
 
You might have a look at this tutorial which is for OPENGL but should be portable to processing. It describes how to do view frustum culling. The tutorial also explains how to do culling for point bounding spheres and bounding boxes so that you can wrap objects without the need to draw them twice.

http://www.lighthouse3d.com/opengl/viewfrustum/
Re: wrapping around in 3D scene.
Reply #6 - Jul 23rd, 2008, 11:45am
 
tex that is what he is doing, still there will be need to duplicate.

imagine a cube half outside the frustum.

for his application that half part would have to go to the other side, while the test against the frustum would still say that the object is not outside the frustum, hence the duplication.

memo, u can also check for the clipspace tut in that site, where u can extract the frustum planes from the concatenated matrix, anyway thats not the point here, but it would save u some instructions.
Re: wrapping around in 3D scene.
Reply #7 - Jul 23rd, 2008, 2:52pm
 
Hi,

Tex that tutorial is pretty much exactly what I was looking for in my first post thanks! I think I've reinvented the wheel though now as I've got the frustum edge detection sorted.
Like crmx says though, I do still need to render the object twice I think for the situations where half the object is on one edge of the screen, and the other half on the other side.

Though i've been thinking about this situation a bit more and I'm beginning to think its impossible with a perspective view. If I just wanted to have my objects wrap around from left to right or right to left then this solution would work. But my viewport will be mapped around a giant cylindrical projection surface. So physically the left edge and right edge will be touching. So when the object wraps around from left edge to right edge, there will be a difference in perspective, and viewers will see a big break in the image. (imagine my object is a cube with no rotation. At the left edge of the screen you will see the right side of the cube, at the right edge you will see the left edge. Someone standing and looking at the cylinder where the left and right edges meet will see a very strange looking cube!.

I'm beginning to think i have to use an orthogonal view with a fake 2D scaling to simulate a kind of perspective that is always perpendicular to the screen...

thanks for the tips...
Page Index Toggle Pages: 1