Cosmonium: A 3D astronomy and space exploration program

ok I understand, thank you for your answers to my questions

Hello, your project is very impressive
But he seems very greedy resource, i have GTX 2060 and i have only 35fps,

have you planned any improvements/update like best performance, planetary atmosphere, 3d planet field (with mountain, water…) ?
I couldn’t test the example with ralph from the source code, how can we launch it ?
in advance thank you for your answers

Thank you for the feedback!

It is indeed quite greedy in resources, I took the approach develop the features first and optimize later :slight_smile: Right now I started working on fixing the most outstanding bugs then I will switch to the optimization before adding new features.

Actually the bottleneck is not in the GPU but in the app code, the octree traversal is not fast enough and, above 10000 objects, the slowdown is visible, even with a fast machine. Also, the code to update the position from the orbit equation does not scale well. I have to find a way to be able to quickly know which objects must be updated, which can be ignored for a given time, but it’s not trivial

Once the core of the engine is optimized enough, I will go back to procedural generation. There is already basic support for that (O’Neil atmospheric scattering, perlin height map generation, …) but it’s still limited and not user friendly.

Btw, Ralph should work from the source (it doesn’t when run from there binaries), what is the error you have ?

hello, I have a question, why is the demo on the procedural field with ralph happening on a flat map and not on a spherical planet in space ?
I don’t know if it’s a bug, but we can cross rocks/trees.

The Ralph demo is mainly a development and debug tool for me, it’s much easier to debug a quadtree and terrain generator with only 5 levels than a full scale planet with 25 levels. Also I don’t have the complexity added due to the spherical coordinates and no precision issue.

The absence of collision is not a bug it’s a missing feature :stuck_out_tongue: the object populator will in the future also instantiate collision solids, but to be honest it’s a low priority feature.

I was asking the question because I wonder if you planned to make planets with relief and water.
I haven’t found in panda a way to create a spherical terrain with relief and collision management.
I found a solution for water that is to have 2 half sphere but terrain is more complex.
and I’m not talking about making caves, I think that need to implement a new field management libraries.

I don’t know what the purpose of your project ?
is it to create 3D procedural worlds with spacecraft or to make astronomy software like celestia or a simulator like kerbal/orbiter

Yes, that’s the purpose of the application, a crossover between astronomy software, like Celestia and others, and space exploration. So an open-source SpaceEngine (well, after a few more years of development :blush: )

I already have the base to generate full scale procedural planet either with procedurally generated heightmap or procedurally generated textures.

Here is a crappy gif I just took, the camera starts from 2 meters above grounds and raises until being at 500,000km with tiles generated on the fly.

com-optimize

Water is not yet in but it’s on my short term todo list.

Spherical terrain is much more harder to implement than “flat” terrain and much less useful, unless you really want full scale planet. Usually you use flat terrain with a horizon cut off, some fog and a bit of distortion added in the shader to simulate the curvature.
Depending on how it is implemented you could use 6 Panda ShaderHeightmapTerrain to create a cube and apply the spherical distortion in the shader, but you will have to create the bounding volume yourself and I fear the LOD algorithm will no longer work as you displace the vertices in the shader (unless the lod is calculated in the shader, in that case it’s not a problem)

Caves are even harder to implement, usually you need voxels or sdf raymarching to implement them, but I haven’t even considered if I will ever implement them :slight_smile:

1 Like

Okay, thank you for those clarifications.
is your "crappy gif " included in your project on github? I’d like to test it and see how it was done.
Can you manage collisions with a physical engine such as bullet or ODE ?

I have a little criticism with your atmosphere (there is the same problem with the earth), when I have the camera sticking against the ground the sky is not blue enough, we can see the stars when it’s noon.

Yes, you can fly to that planet by pressing Enter,then type Planet Demo and press d to go to the planet.

Alternatively you can just load the procedural demo and start in front of the planet :

 ./main.py --main data/cosmonium-proc.yaml  --default 'Planet Demo'

The zoom out effect is simply done using the change altitude Home or End and using the function “center camera on selected object” c when high enough to automatically rotate the camera

I would say out of the box no, the generated heightmap is distorted according to the spherical coordinates used (UV, normalization, …) but the displacement is done following the sphere normal. Unless bullet or ODE have a spherical heightmap mode it won’t work. One workaround would be to generate another heightmap which include the projection on the sphere and that would work, I think, with the physic engine as a plain heightmap.

It’s a known problem :slight_smile: I’m using O’Neil atmospheric scattering and it has many limitations (one of them being the sky not blue enough when looking up, the atmosphere too saturated when the sun is in your back, …), in a future version I’ll switch to Bruneton scattering which is one of the best real-time atmospheric scattering. (To be honest, I spent so much time fine tuning the O’Neil scattering that I could have integrated Bruneton instead…)

The still visible stars is also a known problem :slight_smile: I need to implement brightness culling to ignore object not luminous enough and also apply the atmospheric scattering on far objects when looking through the atmosphere. But for that I need first a physically realistic scattering.

At last version 0.1.1 of Cosmonium is available :slight_smile:

Lots of bugfixes in this releases, though many are not directly visible, and a few new features, most notably :

  • Analytic shadows
  • Full menubar
  • Proper seam and crack removal algorithm for procedural planets
  • New noise functions
  • Improved performances
  • Fixed many procedural planet bugs
  • Better OpenGL capabilities detection
  • cel:// url support
  • Improved rendering
  • and so on :slight_smile:

See the changelog for the complete list.

Saturn with proper ring shadows :

An eclipse on the Earth :

The improved terrain :

And the Ralph demo with even more infinite terrain :slight_smile:

It’s still a long way to the final version of Cosmonium, but it’s great to (slowly) progress towards it! I must thanks all the people that tried and send me their comments and criticisms. Also, I must thank a lot rdb and Moguri for their work on Panda and their support :slight_smile:

3 Likes

do you think you can add 3d relief to the planets, with real satelite heightmap ?

It’s already possible with procedural heightmap, so I feel silly not having added support for data based heightmap :slight_smile: I have done the modifications and now (in the develop branch) you can have planet with real relief, if you have the right elevation map :stuck_out_tongue:

Here is Mars with the elevation map generated by the Mars Orbiter, it has a resolution of 563m and an uncertainty of ±3m (Well much worse here as I’m using a simple oblate spheroid and not the correct mars geodetic system). For fun, I used an exaggeration factor of 10x :slight_smile:

You can admire Olympus Mons (on the left), the Tharsis Montes (the three mons at the left of the center) and the impressive Valles Marineris :

And the same in 3D :

You can also add more precise elevation map for some place of interest, but for now on you need to convert the longitude, latitude to the patch coordinates (x, y and lod level) manually, which is cumbersome.

There is still a bug, I think, with the generated normals which shows artifacts when you get too close to the planet. Even with the b-spline interpolator they do not vanish, so probably I’m doing the calculation wrong. I hope to find it and fix it before the next release though :slight_smile:

1 Like

the rendering is really good!
I have friends who teach high school and he was interested in visiting planets for her students
Would you know how to add an object to a planet ? for example apollo 11 lunar module at real coordonate ?
I’m not asking you to add it, just tell me how to add a bam/egg object has a precise coordinate ?

Other question, Is there a basic physics/collision of planets field? For example, to roll a rover to Mars on the field like your ralph example (but in mars and with a rover instead of a ralph)

I’m not asking you to add it, just tell me how to add a bam/egg object has a precise coordinate ?

I added this week-end a more user friendly frame to place object at the surface of a body, here is for the curiosity rover :

spacecraft:
    name: Curiosity
    parent: Mars
    radius: 0.0015
    surfaces:
      - shape:
          type: mesh
          model: models/vtad-curiosity.glb
          rotation: [0, -90, 0]
        lighting-model: pbr
        attribution: nasa-vtad
    frame:
      type: surface
      long: 137.4417
      lat: -4.5895
    orbit:
        type: fixed
        position: [0, 0, 0]
        global: false
    rotation:
        type: fixed

And here is the result in app :

But as you see, the resolution of the global elevation map is to coarse and the terrain is almost flat except for a few mountains in the background… There are high resolution DEM available, but they’re huge (the raw DEM for the curiosity landing point is about 23GB) I will write a tool to extract part of them and align it on the low resolution map.

Other question, Is there a basic physics/collision of planets field? For example, to roll a rover to Mars on the field like your ralph example (but in mars and with a rover instead of a ralph)

Ah, well for that it’s not possible yet on a planet, but the building blocks are there : there is a nav mode to “walk” on a planet and follow the terrain, I need to modify it to move not only the camera but also a mesh.

I have friends who teach high school and he was interested in visiting planets for her students
Would you know how to add an object to a planet ? for example apollo 11 lunar module at real coordonate ?

With the latest develop version, it’s now possible :slight_smile: However, Cosmonium is still in heavy development and perhaps more mature tools would be better for your friend (Though I would be happy to learn from their usage and improve it :smiley: )

I looked at the example with Ralph, it looks like he’s not on a spherical planet but a rectangular map, am I wrong?

the interest I see with cosmonium is to be able to easily develop a small scene, like a rocket landing on mars for example.
you instantiate the object in a yaml file (vtad-curiosity.glb) but I would like to be able to manipulate it in python code, is that possible?
if I can manipulate it, I can move it forward or something, right? like any panda3d model?

Cosmonium benefits from the power of python, I have a lot of nice ideas, like developing a small artificial intelligence with genetic algorithm to move the martian rover, or do spaceship combat with tensorflow.

in which file did you add the code for the rover?
edit: I think I get it, we need to edit the mars.yaml file.
how do you add the heightmap?

Yes, The Ralph example uses flat geometry and equirectangular heightmap, it’s much easier to test and validate the terrain engine :slight_smile: The planets on the other hand are using heightmap with projection (either lambertian or spherical)

Well, currently the position of an object is defined by three things, its orbit its rotation and its reference frame. So to control an object you need to modify those. For example, the curiosity rover above has a fixed orbit and a fixed rotation with regard to its reference frame. To move it on the surface of the planet, you only need to change the centre of the surface reference frame. In this case, the orbit and rotation are like the position and orientation of a panda node wrt its parent.

So I need to reuse the code of the “walk” mode and modify it to update the reference frame of an object and you would be able to control any object as if it was on the surface.

That’s the great thing with Python and Panda3D, it’s very easy to program new thing or extend existing thing. Though, as Cosmonium is still in heavy development there is no stable API yet. But looking at new use case helps me to see what is useful from a user point of view and what can be kept internal.

Using the develop branch, you can simply add the file above in the extra directory, it will automatically add the body to the mars system.
Same for the heightmap, you can add an additional surface for any existing bodies, so you don’t need to modify the original file. Except that I just discovered that there is a limitation, the surface texture is not found as it resides in another directory.

Here is how to add a heightmap :

    heightmap:
       type: texture
       max-height: 65535
       interpolator: bspline
       data:
         type: ctx
         root: textures/Mars_MGS_MOLA_DEM_mosaic_global_463m
         ext: png
         size: 1024

isn’t there a way to control an object as we would normally do with panda3d?
i want to call for example this code in cosmonium (after load rover object into json)

def move_rover(self, task):
    if self.keyMap["forward"]:
        myrover_objet.setY(myrover_objet.getY + 1)
        myrover_objet.loop("run")
    return task.cont

Moving an object is a bit more complicated than that, especially if you want to keep it on the surface of the planet. To help, I created helper classes to move bodies taking into account their reference frame and position with regard to their parent. I also added a controller class which can be used to add behavior to objects in the engine.Finally I added basic plugin support, so in the yaml file you can link a controller to a body.

Here as an example the Curiosity rover making a loop on the procedural planet demo :

Imgur

The controller code is quite simple :

from cosmonium.controllers import BodyController
from cosmonium.astro import units

from math import pi

class TurnBody(BodyController):

    def update(self, time, dt):
        self.mover.turn_relative(pi / 100 / units.Sec * dt)
        self.mover.step_relative(0.001 / units.Sec * dt)

ControllerClass = TurnBody

And in the curiosity yaml file I added the reference to the controller :

    controller:
      name: turn
      file: modules/turn.py

(To be honest this is a bad example, the position is modified by delta so the errors will accumulate over time, especially if the simulation speed is increased. Instead one should keep a reference position and do updates relatives to it)

The new code is mostly there : https://github.com/cosmonium/cosmonium/blob/develop/cosmonium/controllers.py

There is also now a hidden feature, select the object, type ‘Control-T’ and a debug nav mode will be created to control the displacement of the body using the keyboard (The camera will be stuck in place, I still need to add proper follow camera mode and so on)

1 Like

I don’t understand where I have to put the code.
I add a curiosity.yaml file in the data folder and I add the models and modules folder ?
but after this how can I go see my object on mars?

I looked at your last few commits, is cockpit class for the camera?

Exactly like that, you put the code in the modules directory and you put a reference in the yaml file, like the model actually. Here is a zip with everything included, you can extract it in the extra directory and it should be loaded when you start the app :

Note that you need the latest snapshot of the development branch.

That’s like any other objects, you can select them by pressing the Tab key then enter their name, then press G to go to them, or use the wheel to navigate to it. You can go to the help menu, you have the list of all the navigation shortcuts you can use.
Beware that you could end up upside down or under the surface (I still have to work on that), but you can orbit the camera around the object easily.

Yes, I’m working on adding spacecrafts and ships. The cockpit is used to attach elements to the node holding the camera when you’re inside the spacecraft (But there is still lots of work to do :slight_smile: )