Tuesday, March 9, 2010

Matter of scale

Yesterday I was thinking more closely about numbers to understand the scales of the star system(s), and ways to deal with them.

I started from understanding how far is the distance from our Sun to the last planet. According to Wikipedia, the Neptune is about 30 AU (astronomical units. 1AU = 149’597’871 kilometers, or 92’960’000 miles). Objects of Kuiper belt, or so called trans-Neptunian objects, may be placed at the distance not far from 55 AU in their average radius, and it consists mostly from small objects, like asteroid belt. The biggest body of Kuiper belt is Eris, which has 97 AU in aphelion and 37 AU in perihelion. Beyond Kuiper belt lies The Oort cloud - a hypothesized spherical cloud of comets which may lie roughly 50’000 AU, or nearly a light-year, from the Sun. Oort cloud consists from asteroids, space dust and comets.

So, for the star like our Sun (G2 star), which has a mass of 1.9+E30kg. the distance from its center to the farthest object could be around 1’000 AU, or about 1.49+E11km. A thousand AU came from the idea that if I want to make project close to reality, I may close my eyes on every and very far object in the star system, but, never the less, make enough space to model some really far objects. My guess is that this number can easily be divided even 10 times, and it will be more than enough, and later I will use the number of 100 AU for the stars like our Sun.

But! According to this nice article, O-class stars may have mass from 15 to 90 times more, than the mass of the Sun. Taking in account the dependency of gravity force from objects mass by Newton’s law, such big stars will have the same about of gravitational force at the distance of square root of mass. So, if the mass is 90 times bigger, then the distance will be a bit more less than 10 times.

With all that in mind, I need to be able to operate with the distances of 1’000 AU for a single star.

According to Wikipedia, almost half of the stars in our galaxy are systems of two stars, or binary star systems, where 2 stars floats around their center of mass. It is written there that some binary systems may have more suitable conditions for planet formation, rather than single stars may have.

But let’s fantasize a bit and assume that even star systems with 3 or 4 stars may have a condition to form planets (stable or not), and to be able to make and fly around such star system I will need, let’s say the double space I have calculated.

So, 2’000 AU will be enough for any condition and any star in my virtual galaxy. And it is equal to 299’195’742’000 km, in every direction from the star system center. That is a HUGE space. By the way, if I move with the speed of light (which is equal to 299’792 km/sec.) I will need about 693 days, or almost 2 years to travel from the center of star system to its boundaries. But why should I worry? I have a hyperspace drive, haven’t I? :)

If I want to have a precision of 1 meter in my project, I will need to be able to operate with the numbers from -2.99+E14 to +2.99+E14, which can perfectly be held by double precision floating points. But dealing with doubles every time with every object may significally decrease the performance.

I came up with idea of so called local space and global space to, probably, solve performance issues I might have, if I use doubles everywhere. The idea is to render/calculate everything using global scale units when player’s cam isn’t near any global object of star system (global units have a precision of, let’s say 10000 km), and switch to local (coordinates), when player’s cam enters some certain region near any global space object, for example planet. If we assume that each space body has its global coordinates, then local space would be bounded and centered to the current position of the body.

Switching back and forth from global to local coordinates should probably spare some CPU power and give me necessary precision.

I should post some more thoughts on this idea later.

Monday, March 8, 2010

Core object scheme and hierarchy

Today I was thinking more closely to the overall object hierarchy of the entire project. As well as the bodies in our solar system “attached” to theirs “parent” bodies (like the moon is a “child” of our Earth, it goes around the Earth, and Earth goes around the Sun), and all the space bodies goes around the Sun, my structure tries to stay closer the same hierarchy.

The scheme of object hierarchy can be seen below. Of course, I believe I will modify it in time due to some new ideas, but the core idea should look that way.



Basically almost every entity on this scheme has a name of “factory”, and it’s pretty self-explanatory. Each this entity handles the generation of the named object in the space, stores it’s parameters and handles some object routines.

For example, PlanetFactory is responsible for generating the planet body with all the stuff, that planet consists of, like surface (that’s been generated by PlanetSurfaceFactory), water (PlanetWaterFactory) or whatever liquid the planet may have, sky (PlanetSkyFactory), and maybe some more later (RiverFactory, CityFactory, etc.). Therefore PlanetFactory is a child to PlanetarySystemFactory – class, that is responsible for processing all the bodies, including the planet itself, that orbits around, let’s say, the center of mass of the planet – Planet itself, planet moons, celestial bodies like Saturn rings, asteroids, debris… If we go higher, there is a SolarSystemFactory, and, as you can guess already, stores and processes all space bodies of the star system, including the star itself, planets, asteroids and asteroid belts, comets and all others.

The scheme looks good and logical for me, and I will definitely try to follow it. Next step will be to define common variables and procedures for each node of the scheme.

Long-awaited update

It’s been a while since I have posted the last message. A lot of thing have changed and a lot of has been redone. It’s a pity that it is now 4th rework on the simple node tree flow, but because I find it essential to the whole project, I think it’s best to find the right solution first, and then continue to make other things.

I have now switched back to Java Monkey Engine due to simplicity of coding from all my platforms that I work on every day. The experience with Ogre3d engine in that area wasn’t very good from the perspective of switching the development platform each day due to the fact that in my work time, I like to put the work away and return to the project, if I have some ideas I want to try. And in that time I work under windows. And at home I have my beautiful iMac with MacOS X in it, of course. Switching back to jME took away the problem of reconfiguring the project settings for each platform each time I put the code written form windows to mac, and vice versa. I know that it’s solvable and my lack of knowledge in that area gives me pain, but for now, it’s better for me to stay with jME to avoid them. Anyway, if you understand the problem completely (and for now, understanding the routines to handle trees for planet surface rendering is the problem), it isn’t very hard to switch to another engine in future.

At the moment I have completely decided what scheme is better for my needs of creating and handling the planet surface, and it’s ROAM. I do not remember whether I posted the link to the ROAM PDF paper or not, but I will do it now anyway. So, here’s the link.

Why ROAM is good? Well, the best way to see it is to define how I want the planet surface to be born and handled. I have found the following scheme the best:

1. Using complex procedural algorithms generate a planetary map (the vision of what the planet will look like with all the coasts, mountains, valleys, etc.) that later can be modified to add crates, rivers, cliffs, and many more.
2. Using the same algorithm make a height map.
3. Make a spherical planet body and apply map to it.
4. Using altitude as the parameter, adjust the height of the planet mesh, and add extra geometry when we approach closer to surface. This means that form space you will see a bump mapped sphere, and as you get closer to surface, the surface will slowly and smoothly change to reveal all the “heights”.

For that scheme I find ROAM is a perfect choice. Later on I will post some updates on the node and tree routines.

Thursday, October 8, 2009

Completely new node class

During my last days I've been working on implementing new class for my nodes. I took the conception to make each node not 1 by 1 quad, by n by n quads. This means that each my node will consist of n by n nodes (16x16 for example). After the node is being created, it's transformed into a single mesh and then attacked to the scene. The reason for this was bad frame-per-second rate with previous ways, because each frame each my quad was send to GPU for rendering. And because of huge amount of quads, each sending slowed down the performance. GPU can handle complex meshes very fast if sent to GPU as a single mesh.

So, by rewriting the Node class to this new approach, the fps increased more than 100 times! Now that's what I call HUGE :)

Also, the node's constructor allows now to set the desired amount of quads on each side. The example below shows the cube with 128x128 quads on each cube's face.

SimpleGameScreenShot.png


And with this one it's still over 150 frames per second.

Monday, October 5, 2009

Performance issues and ideas

It seems that performance issues are caused by too many nodes attached to the rootNode manager (the one that handles all the geometry in the scene). I have asked the question on the forum (here) and there were some solutions gives, as well as some ideas made up in my mind.

Well, one way is to somehow lower the amount of custom nodes while saving the same amount of triangles in the scene. This can be done if I make a constant mesh from many nodes and only then add it to the rootNode manager. So I have to write a procedure that reads all my quad tree, finds all nodes that have to be rendered (i.e. are leafs) that are on the same level in my quad tree, and makes a constant mesh (TriMesh to be exact by java terminology) and then pass it to the scene manager. And that for all tree levels.

Another thought that I had was related with splitting. In my previous posts I mentioned that according to my splitting procedure the quad splits on 4 smaller. In future the idea was to split the quad if camera is close o it so to add more detail. But splitting only one segment each time won't add much of a nice picture, imho. I think I need to "split" quads for some segment bigger than one parent quad. That way adding more detail won't be so.. mmm... so rude, maybe. Somehow like this.

So, I believe I will focus on this.

Thursday, October 1, 2009

Cube to Sphere mapping

Whooah...

Finaly I have managed to solve all bugs in my way to map coordinates for each vertex from primary cube so to form a sphere. Planet should look like a sphere, because nobody likes cubic planets :)

The main equations for transforming coordinates of cube to spherical are the following:

9C401787-51AE-4B7D-BDD8-0D5BD4B522FE.jpg


For that reasons I have made a "final" class called c_MyMath for keeping all the future equation functions there.

HelloWorld.png


After a bit of testing I found that it was a bad idea to store spherical coordinates of each vertex multiplied by planetary scale factor (the radius of the planet) because while doing scaling in the node's constructor, I needed to take care of scaling during quad splitting also. I thought it's whatever if I do the scaling for each vertex in the constructor and in splitting procedure, and doing it just before the prerender function, which finds all the quads that should be rendered and then apply the scaling. I understand that it's better to handle everything from the start (not just before th rendering) but for now I have decided to leave things as they were.

HelloWorld-1.png


Now the protoplanet looks finally like a sphere!

Dealing with quadtrees 3: The cube

I have managed to draw a single quad on the window, and make split algorithm work properly. It uses parent quad's vertex coordinates and makes new 4 quads and calculates it's vertex coordinates.

I have realized, that basically I need to store in some king of list all my new quads, and later on I also need to make a procedure (at the moment just a simple one) that looks through this lists and makes another one, containing only leafs - quads that have to be rendered.

To store it I used LinkedList class. Very useful.

I needed to make a cube that consist of 6 quads (6 sides) at the moment of creation. The problem was that by defining a tree (as it should be defined) it should have only one root (quad, or whatever). By making 6 sides, I basically create 6 roots, and I was afraid that I will have problems later when I will have to make some kind of procedure, that will need to find all quads that have to be rendered, because that way I will need to call it for each 6 primary quads. The solution with lists I found quite resultive.

HelloWorld.png


This is the result of primary cube. At the moment I have decided to draw cube so that it's center is in the (0;0;0) and vertexes have by default +1 or -1 in all direction, multiplied by scale factor. Later on I will have to add algorithm that could place the cube in any coordinates so that all formulas stay consistant and correct. But that will be later.

HelloWorld-1.png


This is the result of splitting the primary cube 3 times (6 sides times 4^3 gives 384 quads).

By now it works, by the framerate results doesn't make me happy, because by dividing the prime cube 5 times gives only 20 fps and that's odd.

Next step will be finding out why the hell fps are so small :) and second make a sphere out of cube - it should be spherical planet, not cube like :)