Showing posts with label controls. Show all posts
Showing posts with label controls. Show all posts

Wednesday, 9 February 2011

Week 20 - User Interaction

Following a short break, it's back to work on the Honours Project. I'm aiming to have the program fully finished by the end of February, the features I'm aiming to improve/add are:

  • More user interaction. This has been partly addressed this week.
  • Improve lighting and shadows. Currently the planets don't have a 'dark side' where the Suns light doesn't hit them. I've no idea why this is as the lights are set up in the centre of the Sun, so I may not be able to solve this.
  • Implement pop up menus. All the user interaction is keyboard and mouse based at the moment, and there's too many functions going on to have them all implemented by a key press - I want to move some stuff over to menus, and also include a pop up with control details for the keyboard functions.
  • Rotate planets as they orbit. Currently the planets aren't rotating as they move, and implementing this has proved more difficult than I first thought it would be.
  • Improve movement controls. This is the least important update, so it may get cast aside if I run out of time, but I would like to improve the way the user moves around the 3D solar system - it's not brilliant but it works, so I wouldn't be too worried about leaving it if need be.

So onto the improvements in the user interaction that have been added this week. The major cosmetic change is the addition of a speed control. I had previously attempted to add this in using a variable called speedFactor which was adjusted everytime the user pressed a key - but could not get it to work. I solved this by moving the code which updates the julian date:


   julDate += (0.1 * speedFactor);

from the updateMercPosition function that it was in, into the main myDrawGLScene method, which fixed the issue of the speedFactor variable not being updated by a user key press. Now whenever the user presses 'm' the speed is increased (to a maximum of 25x), with n decreasing the speed (minimum of 1x). The program launches in 1x speed, and can be increased by the user to 25 times the launch speed. The speed is displayed on screen, beneath the two date displays like so:




The second piece of functionality that has been added is the ability for the user to increase the size of the individual planets. This was something discussed in my last meeting with Rob, and I decided that in order for the user to get a good look at the models (especially the smaller inner four planets) without lots of zooming and panning, this would be a great feature to implement. At the moment, only the planet Earth has this fucntionality coded, and it is controlled by the 'u' (to increase size to a max of 8x the original) and 'i' (to decrease size) keys. This is a feature I intend to move to the menu system, simply for the reason that I will run out of keyboard keys if I use two per planet. In order to code this, I introduced a variable earthSize, which is controlled in a similar way to the speed variable, increasing or decreasing the variable on a key press. I had to move the scaling function for the model from InitGL, where it was located in the display list, into myDrawGLScene, in order for it to update correctly whilst the program is running.


The final piece of functionality that I added this week was scaling the distances from the Sun. There are two options for the user in this case - they can increase/decrease the distance of the inner four planets from the Sun (currently using the 'f' and 'g' keys) or increase/decrease the distance of the outer four planets from the Sun. This gives the user the option to see the planets bunched in much more closely than the correct scale that the program launches in. This is controlled by two variables - innerScale and outerScale, with a default setting of 16 (purely for aesthetic reasons, although this could change). The positions of the planets that are defined in earth Update..Position method are multiplied by these variables, which are increased or decreased by a key press. The increase value for both variables is limited to 20, whilst different limits are applied for the inner and outer decrease values - in the inner case, so Mercury does not disappear into the Sun model, and in the outer case, so Jupiter and Mars' orbits don't collide.
The image below shows the outer planets decreased to their lower limit, Jupiter appearing very close to the inner four planets.


That's all for this week.

Monday, 29 November 2010

Week 8 - Animation

This week I have been working on the DrawSolarSystem class. I've added quite a lot  - some initial keyboard functionality has been added (zoom, pan, rotate and pause), as well as mouse movement. This is in a very early form and I'm not happy with some elements, but it will do for now! The main focus of this weeks work was trying to implement the orbit of one sphere around another. I managed to implement this successfully, and went ahead to program the orbits for all the planets.

Another issue that was raised during my meeting with Rob was the slight difference in accuracy for my figures in the previous blog. I did some more research, and believe this is down to a difference in time. In the Utretch unversity page, they take 1st Jan 2000, 12 noon UTC as their start date. Their current date is 1st Jan 2004, 0:00 UTC. My program only calculates julian dates using day, month and year, where the time of day is as default 12 noon. This means theres a 12 hour difference between their current date and mine, which is I believe the reason for the slight difference in figures.

Firstly, I'd like to list major changes and additions to the classes.


  • the drawOrbit method in OrbitalCalculations has been changed to a type void, and thus doesn't return the planet's vector anymore. I've created a new method to return the vector, so it can be retrieved by the program without doing the whole drawing orbit calculation.
  • The Julian Date is defined as a variable julDate at the top of the DrawSolarSystem class now. This allows the julian date to have numbers added to it in order to increase the time.
  • Planets are created at the top of the DrawSolarSystem class as well, instead of in initGL, outside all methods. This is so different methods can use them.
  • For the same reason, instances of OrbitalCalculations are also created at the top of DrawSolarSystem.
  • Two new methods have been added to DrawSolarSystem for camera manipulation. One called camera, and one called mouseMovement.
  • A new method has been added to DrawSolarSystem to read in each model, so there are 9 methods of this type in total.
  • A new method has also been added to update every planets position, so there are 8 methods of this type.


Now I'm going to run through how the program reads in a model, puts it into a display list, draws that list then updates the planets position.

Firstly the model has to be read in. I use a seperate method for each model, simply to ensure each model is read in correctly. For now I am only using two models - suntest.obj, a yellow sphere, and planettest.obj, a red sphere. Both were created and exported from 3Ds Max. Here's the code to read in the sun model, the rest are much the same:


Next, the models are put into display lists in initGL. Putting the model into a display list means it can be scaled before being called by the drawing method, so it only happens once at the start of the program. As all the models read in are scaled to the same size to fit in the matrix, they have to be scaled again in order to maintain size difference. At the moment my figures are pure estimates, just done to give an impression of the size differences. Lights are also defined in initGL. At the minute, all I have is an ambient light. Here is the code to place the sun model into a display list (note: the scale is so small so that I can zoom greater distances, you'll see why I need to later!):


Now before I call the display list in myDrawGLScene, I need a method to update the position of the planet. Since myDrawGLScene is redrawn all the time, a loop is not required, as the update method will be called each time the scene is redrawn. So all I need to do is increase the julian day every call to the method, draw the orbit and translate the model by the x, y and z coordinates generated. Here is the method for mercury:


Now the display list can be called in myDrawGLScene when the model is drawn. Here is the code for the sun and mercury:


All this resulted in the following screen shots. The first image shows the Sun, Mercury,Venus and the Earth. The second is zoomed out slightly to include Mars. The third is zoomed out a lot to include Jupiter, Saturn, Uranus and Neptune. As you can see, the distances all look to be in proportion, with a lot of zooming out required to see Neptune! At the moment it looks a bit 2D, but thats due to the fixed angle and lack of lighting to give shade. Note that all planets are reading in the same test model, which is why they are all red.






Thats it for this week!