Jumping lines during rotation

Hi again Guys,

Here is today’s issue, I am sure you know the reason.

First scenario:

2D drawing of lines only the, bounding rect (0,0, 400, 800) I can zoom / rotate without problems.

Second scenario:

Same 2D drawing of lines only, far from origin: bounding rect (490000, 500000, 400, 800). When I zoom / rotate I see the line ends jumping 2-3 pixel right/left/top/bottom at every frame.

Why?!? How can I improve this?

Thanks so much in advance.

Alberto

It’s a matter of precision.
If it were me, (a 100% guessing noob) and I really needed a half million units to be represented, I’d have like a Level Of Detail switch, but for scale.
Say it’s a solar system, have a scaled down version whenever you reference that big a number, so the solar system model gets tiny but the bounding universe stays around 0,0,400,800

ie: scale down the solar system model instead of scaling up the universe?

500000 Does not seem big enough to bring serious precision problems.
Can you post your code ?

Just for your info. I experienced this, with my 42Hz Interlaced CRT monitor during animation.

ZbuffeR,

I don’t know what to copy & paste, the relevant code is here and there. Please tell me what it is intersting to you, for example gluPerspective settings, near and far planes or what?

fldz,

Customers don’t want scaled models, we were forced to switch to real scale coords.

Thanks,

Alberto

Whats the biggest and smallest number in the model coordinate? As far as I know, there are no scaled/real scale stuff in CG. I think it will be automatically adjusted. But, it will affect the object data size (higher precision, higher data - eg: a huge tower, and an ant), the coordinate precision will still be adjusted automatically.

I think codes within the OpenGL loop will help.

zbuffer, please correct me if I am wrong.

Yes, my answer was a bit rushed, should have mentioned that it is not the absolute values that matters, but the relations between numbers. Unless you have flower to mountain ratios, it should be ok.
Interesting code will be the projection and modelview matrix manipulations, glviewport, how is translated and scaled geometry according to user input (or scripted sequences if done in a non-interactive way).

Hi, I believe I’m having the exact same problem in my scene…I’m using JOGL so the code is slightly different but the concepts are all the same.

Let me setup what I have…basically I have an Earth based system with a vehicle orbiting the Earth. I have made both the vehicles and the Earth the correct relative scale which means the vehicle itself is tiny and requires a very small near clipping plane so that I could zoom in to it. That said, I don’t believe the clipping plane distance is the root of this problem as I’ll explain later.

My problem is that when I zoom in close to the vehicle, around which I’ve drawn various lines and some shapes, I notice that I get very bad jitter (objects and shapes move relative to each other, etc) when I rotate my view - I’m not rotating or changing any coordinates, simply rotating my view around it…yes, effectively I am rotating the objects because I apply the glRotated() rotations but I think you know what I mean. To clarify, I’m rotating about the vehicle which is not at the center of the OPENGL scene, because the Earth is at the center - the vehicle is offset about 6000 kilometers/units away and I employ a centering technique so that I move to the vehicle and rotate around it as if it was in the center. The jitter happens when I do rotate about the vehicle but if I move the vehicle closer to the center of the opengl world - ie to 0,0,0 (inside the Earth) then the rotations are perfectly smooth and I don’t see jitter.

What I do is basically the following (JOGL code snip):
I chose the body to focus on and translate that body to
the origin I then apply these rotations based on mouse
inputs:
gl.glRotated(rotX, 1.0, 0.0, 0.0);
gl.glRotated(rotZ, 0.0, 0.0, 1.0);
Then I translate the body back to its position

I did notice one thing…when I only rotate about one axis and keep the other axis at 0 degrees then I don’t see jitter…but as soon as the other rotation is non-zero (ie rotZ is 1.0 degree for example) and I move my mouse to rotate rotX then I see jitter…and again, only if the object is not at the center. SO, it makes me think that there is more than just order of rotations that could be at fault, it seems like the distance of the object and the need to perform multiple translates is causing issues too.

Also, I do have a very near clipping plane because the object I have is a vehicle who I want to be able to zoom close too and yet I want to see the Earth background below it and so the far clipping plane is far as well and I wonder if the combination of these two and the other factors are combining for the jitter. Just as a test I reduced the far clipping plane significantly to see if maybe the ratio of the distances of far clipping plane to close clipping plane is a factor and it is not…the jitter still exists even though I have a low ratio.

ZbuffeR,

Here are some values from our program. Do you see something wrong?

glViewport(0, 0, 344, 383);

gluPerspective(26.99, 0.89, 0.05, 287.96);

gluLookAt(
{491663, 475896, 14.4254},
{491658, 475907, -0.350002},
{-0.623493, 0.50244, 0.599008});

Z-Knight,

Yes we are doing the same thing: rotating around a center very far from the scene origin. Why don’t you post the data I’ve just posted so we can compare them?

Thanks,

Alberto

I’m trying to put together a little JOGL online demo for you to load and see my exact problem and I hope to have that working sometime today…my demo consists of a 3D earth scaled to the correct size in kilometers and a teapot representing the International Space Station (or some other vehicle) that is scaled to the correct size (so it means it is quite tiny in comparison - 50 meter radius (0.050 km) and I notice that my horrible jitter happens when the vehicle is away from the center of the scene and I’ve minimized the number push/pops and translations/rotations/etc so as to eliminate any possible cummulative errors in calculations - though there still could be some.

Anyway, here is what I have for my settings:

glViewport(0, 0, 640, 480);

// I can vary the far plane distance from 100 to 100000000.0
// and I get the same jitter
gluPerspective(65.0, 1.333, 0.005, 100000000.0);

gluLookAt(
{10000.029588568046, 10000.004951428176, 10000.014084146884},
{10000.0, 10000.0, 10000.0},
{0, 1, 0));

The reason my gluLookAt eye point is so close to the lookat point is because I have a very small object so I want to be close to it to view it.

I have to believe that being so close is the cause of my problem but it also confuses me that I can be this close at 0,0,0 and not see the same jitter…for example my gluLookAt is this:

gluLookAt(
{0.029588568046, 0.004951428176, 0.014084146884},
{0.0, 0.0, 0.0},
{0, 1, 0));

I’ve created a quick demo of my problem and you can run it from here:

  [TestRotations.jnlp](http://www.zaczek.com/jogl/TestRotations.jnlp)  

I implemented some rudimentary keyboard and mouse rotations but nothing real so don’t be surprised if the rotations are not acting as you expect - just quick and dirty:

Mouse Inputs - use left mouse button to rotate around

Keyboard Inputs:
1 - Focus on “Earth” (Earth Size: 6000 unit radius)
2 - Focus on Teapot located at 0, 0, 0
3 - Focus on Teapot located at 1000, 1000, 1000
4 - Focus on Teapot located at 10000, 10000, 10000
5 - Focus on Teapot located at 30000, 30000, 30000
6 - Focus on Teapot located at 60000, 60000, 60000
7 - Focus on Teapot located at 100000, 100000, 100000

Q - Far Clipping Plane: 100
W - Far Clipping Plane: 1000
E - Far Clipping Plane: 10000
R - Far Clipping Plane: 100000
T - Far Clipping Plane: 1000000
Y - Far Clipping Plane: 10000000
U - Far Clipping Plane: 100000000

A - Near Clipping Plane: 5.0
S - Near Clipping Plane: 0.5
D - Near Clipping Plane: 0.05
F - Near Clipping Plane: 0.005
G - Near Clipping Plane: 0.0005
H - Near Clipping Plane: 0.00005
J - Near Clipping Plane: 0.000005

Note that when viewing at 10,000 away from the earth (key 4) changing the clipping plane distance has no effect on the jitter…I can have a small far to near clipping ratio and still have horrible jitter.

Here is my display() method…note, this code is in JOGL but it would be almost exactly the same in OPENGL:


public void display(GLAutoDrawable drawable) {
    GL gl = drawable.getGL();

    if (reset) {
      int width = getWidth();
      int height = getHeight();
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL.GL_PROJECTION);
      gl.glLoadIdentity();
      // Set the Field-of-View, Aspect Ratio, Near & Far clipping planes
      glu.gluPerspective(65.0, (double) width / (double) height, nearPlane, farPlane);
      gl.glMatrixMode(GL.GL_MODELVIEW);
      reset = false;
    }

    // Clear Screen And Depth Buffer
    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    
    // Reset/Clear matrix
    gl.glLoadIdentity();

    // Update light position
    // 0 in the last component causes jagged terminator on planets, 1 results
    // in a smooth terminator but the location of the sunlight is no longer
    // correct...not sure why.  Old code used a 0 (zero) very successfully,
    // what changed?!
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0);

    gl.glPushMatrix();         
      double posX = Math.cos(rotY * Math.PI / 180.0) * radiusOffset;
      double posY = Math.sin(rotY * Math.PI / 180.0) * radiusOffset;

      double zX = Math.cos(rotX * Math.PI / 180.0) * radiusOffset;
      double zY = Math.sin(rotX * Math.PI / 180.0) * radiusOffset;

      
      double eyeX = systemX + posX;
      double eyeY = systemY + posY;
      double eyeZ = systemZ + zY;
      
      glu.gluLookAt(eyeX,    eyeY,    eyeZ,
                    systemX, systemY, systemZ,
                    0,       1,       0);
      
      System.out.println("Eye:  " + eyeX + ", " + eyeY + ", " + eyeZ);
      System.out.println("View: " + systemX + ", " + systemY + ", " + systemZ);
      
      // Draw stars
      displayStars(gl);
      
      // Draw Teapot
      gl.glPushMatrix();
        gl.glEnable(GL.GL_LIGHTING);
        gl.glEnable(GL.GL_COLOR_MATERIAL);
        gl.glDisable(GL.GL_CULL_FACE);
        gl.glTranslated(teapotX, teapotY, teapotZ);
        GLUT glut = new GLUT();
        gl.glColor3f(1f, 1f, 0f);
        glut.glutSolidTeapot(0.01);
        gl.glDisable(GL.GL_LIGHTING);
        gl.glColor3f(1f, 1f, 1f);
        glut.glutWireTeapot(0.0101);
        
        gl.glScaled(0.02, 0.02, 0.02);
        displayAxes(gl);        
      gl.glPopMatrix();

      // Draw Earth
      displayEarth(gl);      
      
    gl.glPopMatrix();

    // Flush The GL Rendering Pipeline
    gl.glFlush();
  }

Here are the links to the source codes:
KeyHandler.java
MouseHandler.java
Renderer.java
ResourceRetriever.java
TestRotations.java
TextureReader.java
BitmapLoader.java
stars.jpg
earth.jpg

Z-Knight,

I tested your program and the ‘jumping’ is very similar to what I see in our app.

Somebody should help us to spot where the problem is.

Thanks,

Alberto

gosh I hope so…I’m worried that for me is has to do with the small size and the fact that at large distances from center a rotation of 1.0 degree (for example) translates to a large translation while at near center the same angle rotation is only a small translation.

I should probably figure out with simple geometry how much a one degree rotation translates into a distance at 10000 units and see if the size of my object would be too small and fall outside the bounds of the double precision capabilities…I can’t believe that my object size of 0.01 units compared to a distance of 10000 units away can be outside of the double precision limits - can it?

I figured that in your case, devdept, that might be the issue since you had such large eye and lookat position (ie 490000, etc) so you might be far out there but I have much smaller distance and I have this issue too.

sigh…I hope I’m stupid and I did something supremely stupid so I can easily fix this.

edit: correction, had said teapot was 0.05 but is 0.01 size.

I’m not sure, but Java’s gluSphere maybe doesn’t generate normals? As you rotate the view, the light seems to rotate, too - but in your code lightPosition[] is constant. This makes me think that generated normals are incorrect, or missing altogether.

the normals are ok, I just didn’t put the light position in the display() method within the glPushMatrix() so it doesn’t rotate with the view but the objects rotate - the normals are OK.

The Earth doesn’t actually have anything to do with the issue of the jitter though…I could take out the earth and the jitter remains…I simply included the Earth for a reference so one could see something moving in the view.

Looks like a precision issue to me. Here’s some test code:


float  tmpf = 10000.029588568046;
double tmpd = 10000.029588568046;
fprintf(stderr,"%5.12f
%5.12f
",tmpf,tmpd);

The output is

10000.029296875000 for float
10000.029588568046 for double

Nice test, thanks…I was afraid this would be a precision error. sigh.

I repeated this test in Java and have some similar disappointment:


    float  tmpf = 10000.029588568046f;
    double tmpd = 10000.029588568046;
            
    System.out.println(" float: " + tmpf + "
"
                     + "(cast): " + (double)tmpf + "
"
                     + "double: " + tmpd);

Resulted in:


 float: 10000.029
(cast): 10000.029296875
double: 10000.029588568046

I updated my code and the demo and I think I figured out something…

here is the demo link: TestRotations.jnlp

This time it defaults to the “non jitter” code…press ‘L’ to toggle between jitter and non-jitter code.

In the jitter code (original code) I created an Earth and a teapot and I set the gluLookAt() to move the view to the teapot location and to rotate around the teapot…because of the precision of floats I believe this caused the jitter as you moved the teapot farther from 0,0,0. To fix this I tried to apply a global glTranslated() and translate the entire system by the distance of the teapot…ie move everything back by this distance so that the teapot was at 0,0,0 and my view would be looking at 0,0,0 and I figured in this case the precision would not be a problem because I was using gluLookAt() around the 0,0,0 point instead of some far distance such as 10000, 10000, 10000. Well…this still caused jitter because (I believe) the glTranslated() would apply the 10000 distance translation which effectively is a matrix multiplication which still cause the precision problem.

SO…I did the following to change the display method to make the system not-jitter. I still translate the objects by the distance to the teapot…so the earth gets moved down and the teapot is moved to 0,0,0, etc…but the difference is that instead of a global glTranlated() I apply the differencing in position directly on each object and so now the jitter is not present.

Note, that updated the demo and the codes that are linked above…I also added a couple of things. I draw a white line from the Earth to the teapot (just because) and I have a wireframe blue/cyan sphere that is a fixed size and I use it see that when I press the various scale keys I could see things scale relative to something…you can turn of the wireframe sphere using the ‘P’ key.

To scale the system (earth, teapot scale) press the Z, X, C, V, B, N keys to scale from 1, 10, 100, 1000, 10000, 100000, respectively.

Z-Knight,

Are you trying to say that:

gluLookAt(10000,10000,10000, 9999,9999,9999, 0,1,0);

behaves differently from:

gluLookAt(1,1,1, 0,0,0, 0,1,0);

Thanks,

Alberto

Given that single precision float can only accurately represent 7 significant decimal digits I think that is hardly surprising. At 10000 the resolution of single precision floats is just 1/1024.