1
votes

I'm making a simple solar system simulation using OpenTK for OpenGL and monodevelop for a C# ide. It's been going well, and I had planets orbiting the sun, lit properly. The problem started when I wanted to tilt the axis of planets; wherever I put the new rotation in my method it doesn't visibly rotate. Once it made the lit faces of my spheres rotate around it somehow. If I put the rotation before or after the rotation that makes the planet rotate around its axis, the top of the planet gets lit strangely, as if the normals are broken.

public void Display (float time)
{
    GL.Rotate (axialTilt, tiltAxis);  // This rotation causes the issues, no matter
                                      // where I put it
    GL.PushMatrix ();                 // This push/pop was added later, but it 
                                      // doesn't help
    rotationalPosition += rotationSpeed * time;
    GL.Rotate (rotationalPosition, Vector3.UnitZ);

    planet.Draw ();

    GL.PopMatrix ();

    if (ring != null) {
        ring.Draw ();
    }
    if (moons != null) {
        foreach (Orbit o in moons) {
            o.Draw (time);
        }
    }
}

This is called by:

public void Draw (float time)
{
    GL.PushMatrix ();

    GL.Rotate (angle, orientation);            // This will allow an angled axis for
                                               // moons and other planetary orbits.
    orbitPosition += orbitSpeed * time;
    GL.Rotate (orbitPosition, Vector3.UnitZ);

    GL.Translate (orbitDistance, 0, 0);

    GL.Rotate (-orbitPosition, Vector3.UnitZ); // Rotate backward, so rotating around
                                               // the orbit axis doesn't rotate the
                                               // planet.
    orbitingBody.Display (time);

    GL.PopMatrix ();
}

It's therefore rather strange. Nothing here should be causing issues with normals, and the tilt seems to be in the right place.

1
Where you call GL.Rotate (rotationalPosition, Vector3.UnitZ); is where you want to rotate your planet around its axis right? If it has a tilted axis, you shouldn't be rotating around the z-axis, you should be rotating it around the z-axis rotated by the planets axial tilt.kappamaki
Your planet drawing code does seem needlessly complicated however. You could just convert the planet's polar coordinates to cartesian coordinates and translate it by that. x = orbitDistance*cos(orbitPosition); y=orbitDistance*sin(orbitPosition); Simplifying your code might help you spot your problem.kappamaki

1 Answers

1
votes

It looks like you are tilting the planet around the sun first, then rotating it. This is making the light come from a different direction than you expect.

I'm not sure what planet.Draw() does, but this is what your code should be doing conceptually.

Start with an identity matrix (if you don't start with an identity matrix, you are rotating around the center of the scene, instead of the planet's axis)

Rotate the planet around its tilt axis.enter image description here

Add the planets current position relative to the sun to the transformation so that the sun is now at the origin of the scene. (GL.translate)

Rotate the planet around the sun. enter image description here