Progress Update #12

 Early Spring Cleaning + New Small Features


    This past week I have taken care of some TODO's and changed a few small features.


From Commit 986d999: "Fixes"

    This commit had to to mainly with structure. I have recently been reading "Design Patterns: Elements of Reusable Object-Oriented Design" (available as a pdf here) all about the importance of intentional design and design patterns in object-oriented programming. The reading got me thinking about how haphazard I have been recently with adding new features and how I should probably plan out as much of a system as I can in UML before diving head-first into development. This is where the "Fixes" come in.
    The biggest change here was the creation of a GaseousColorGenerator class. This is to keep the structure of gas giants more in line with that of the terrestrial planets; that is to have a color generator object that handles creating textures, changing material properties, etc.  This change also resolved a TODO I had in the RingSystemComponent that made the ring systems tied to the gas giant class. Now ring systems can be added to terrestrial planets without erroring out.
    This commit also fixed some #includes by giving those classes forward declarations in the header file thereby reducing the complexity of the header files.


From Commit 2b5ccc3: "Orbit Calculations"

    This commit revolved around two TODO's on Planet.cpp:
  1. Calculate what portion of the necessary orbit velocity should be applied to each section of initialVelocity vector
  2. Fix orbit velocity calculation
    Full disclosure; this commit only fully resolved number 1, I found out that number 2 turned out to be way more involved than I had originally thought. So here's what I did for TODO 1:


    So SetToOrbit() is supposed to take orbitVelocity (which is the velocity needed for this actor to orbit OrbitingBody) and calculate how to split that velocity between the X, Y, Z components of initialVelocity. To do this we need a unit vector that is tangent to the path it will take. Lines 3, 4, and 5 work together to find this vector.
    Line 3 gets a vector pointing directly at OrbitingBody and line 4 gets the up vector of the mesh. Both if these vectors will be perpendicular and to get the last perpendicular vector (aka the tangent to the path) we just have to get the cross of those two vectors on line 5. This process is very similar to that of the initialization of TerrainFace
    Now that we have the unit vector, we need to figure out how much of orbitVelocity goes to each component of initialVelocity. Because tangent is a unit vector we can just multiply it by orbitVelocity  to accomplish exactly that. Negating orbitVelocity makes the orbits counter-clockwise which is how I had the test solar system set up at the time of making this. The last thing to do is to add the velocity of  the OrbitingBody so that this planet can keep up. 
    Line 13 will then draw the orbits to show that it worked. When lines 18-20 are uncommented calling SetToOrbit() will draw some nice arrows showing the three vectors.

Now for TODO 2. 
    The equation used to move the planets at runtime is the formula for that of real life gravitational force, Newton's law of universal gravitation:
    So when I go to calculate the necessary orbital velocity, I think back to physics 201 and remember the formula:
    Simple right? Only, I forgot about this one caveat to using that formula: "This is an approximation that only holds true when the orbiting body is of considerably lesser mass than the central one" (Wikipedia). In my case this is not true. I have a moon whose mass is 1/150th that of it's parent planet and a planet whose mass is only 1/33rd that of it's parent star. When considering that in real life the Earth is 1/333,000th the mass of the Sun, the scale of my game is laughable.
     I spent the entire rest of the day trying to find a solution. I tried every formula I could think of and even tried improvising a few but nothing was working. Eventually, I created a test level that was completely empty except for two planets. To try to find a correlation between mass and orbiting velocity, I would adjust the mass of one planet, adjust the velocity of the smaller planet until it showed a 99% stable orbit and write it down. I did three masses for the larger planet (50, 100, 200) and for each of those I did 5 masses for the smaller planet (1, 5, 10, 20, 50) resulting in 15 velocities for orbit. 
    I took this data into Excel and tried to extrapolate the data into a general formula. Using a linear regression line I got the formula:

V = .5M1 + 50.5 + (M2/2)

    I plugged that into C++ and it worked! I went back to the main level to try on the Earth-like planet and moon and it worked there too with a little moon wobble from the influence of the sun. I then tried it on the Mars planet and it gave me a number that was way too big and just shot Mars into a different system. 
    So this formula only really works for M1 = 50-100 and M2 = 1-50. It doesn't take into account the gravitational constant (G) or the distance between the masses which are the two pieces I am missing right now. To fix this in the future I will look into the gravitational two-body problem which deals with orbital mechanics of bodies that are of similar mass.


From Commit 5b85a04: "More Fixes"

    Super simple commit. Mostly fixing compiler warnings that I had ignored. I rebuilt the entire project, noted all the warnings (most of which explained that I was using a deprecated function and told me the function to use instead which was very helpful) and fixed everything that was wrong. I also took more care about certain variables that didn't need to be exposed in the editor and privated them. Lastly I made the orbit debug redraw orbits if a planet moved through use of virtual void PostEditMove(bool bFinished) override;


From Commit 0e421fb: "Optimizations to voronoi generation and orbit splines"

    The optimization to voronoi generation was precalculating the storm radii as I said I would do in a previous post. Here's what that code looks like:


    Not much going on here. Only things of note are the use of a map variable type and an iterator which is a design pattern I will learn more about as I read that book.

    The optimization to orbit splines had to do with the way they were created. Before, every time the orbits were redrawn each spline would be cleared of points then each point would be re-added. I changed it so that if the number of steps we are drawing is more than previously we just add points and if NumSteps is less then vice versa:


    I also realized that I could optimize this more by only updating splines of bodyIndex that have changed so we don't have to recalculate all objects paths when we don't need to. The biggest thing yet to optimize here though is drawing splines to the screen which is way more intensive than debug lines.


From Multiple Commits: "Starting skybox", "Skybox Rev.1", and "Skybox Rev.2"

    I got bored of staring into the entirely black void that used to be the background and decided to do something about it. I also decided that the previous "distant stars" approach just didn't cut it anymore and would be too resource demanding as time goes on. 
    My new approach would be to procedurally generate a texture then wave some noise over it to make it look like the stars are twinkling. I then did exactly that and I'm quite happy with the results.



From Commit e775c3f: "Asteroids Rev.1, Skybox collision fix, Asset organization"

    Skybox collision fix: Turned off collision on the skybox sphere b/c during play the camera would be kicked out of the sphere

    Asset Organization: Cleaned up MaterialStuff folder with subfolders b/c it was getting a little crowded in there. This move also broke some asset string references… oops

    Asteroids: A new addition to the solar system and something to fill up empty space. Eventually these will be created with a similar formula to the terrestrial planets but for now they are cubes as a placeholder. To achieve an asteroid field type feel while still remaining performant they will use instanced static meshes. More to come in the future.

Comments

Popular posts from this blog

Polishing the Foundation

Progress Update #13

A New Chapter