The SpaceSimSharp project
The "SpaceSimSharp" is a simple application for Windows that simulates a space environment.
This project was born with a learning purpose, so it is in a constant work-in-progress state. Download latest version
The idea behind the project was to develop a simple physics simulator, complex enough to create a "working" space environment with orbiting planets; the target was learning some OOP (Object Oriented Programming), learning how to work with Visual C# (Visual Studio 2010), learning some of the basics of a physics engine and understand the idea behind a "pilot in the loop" simulator.
The project includes some objects from various sources: the graphic engine, TrueVision3D, which is a wrapper for the DirectX; a 3d model from scifi3d.com; some textures from various sources (google image search); some code snippets found around the web; a great help came from the TrueVision3D irc channel, http://chat.truevision3d.com/ .
The project is divided into a form and three classes:
main.cs form:
This form is housing the rendering picturebox and all the option panes. The startup code and the main cycle are in the code associated to the form, as we'll see later.
fisica.cs class:
This is the class of the physics engine, it's made of the main physics class, with all the functions related to simulation, and of the "oggetto" class, which is the class for the physic body.
config.cs class:
This class is a small wrapper for the .NET XML parser, it saves and loads options for the program.
camera.cs class:
This class holds some functions used for the 3d engine camera.
A simple guide to the SpaceSimSharp
Note: the program is compiled with .NET framework 4.0, so you'll have to download it here
When the program is done with loading, you can notice is has a main rendering box and two panes for options and settings: the lower one is for physics and graphics options, the upper one is used for interaction with the simulator.
The simulation is now paused: to enable the main simulation cycle, press the play (">") button in the lower right corner.
The simulator is now working: you can control the spaceship using the keyboard as follows:
W for forward thrust, S for reverse thrust, A and D for lateral thrust, Q and E for upward and downward thrust;
The arrows for pitch and roll rotation, right CTRL and NumPad0 for yaw rotation.
The yellow line is the forecast of the trajectory; the cobalt line is the currently applied force; the blue line is the X axis, the red line is the Y axis, the green line is the Z axis.
Notice that you can rotate the camera by holding the right mouse button and moving it around the ship; you can also scroll the mouse wheel to zoom in/out; you can move around the XY plane by holding both mouse buttons; you can select an object by clicking on it with the left mouse button, you can select an object as the center of the camera by clicking on it with the mouse wheel; if you want to make your controls more effective try holding down the left SHIFT key.
The ship can now move around as you wish; if you'd like to "feel" the speed of the ship as it moves try to enable the space dust in the "Graphic options" pane. You can also enable/disable a trail for the ship, the exhaust effect and the bounding box (bounding box option not working in this version).
As you can see, in the upper pane there are two tabs that can show you some informations about the simulation: the "Charts" tab , that shows the speed and the acceleration (acceleration not working in this version) of the spaceship; the "Selected object" tab, that shows you some basic info about the currently selected object.
The speed components by color are: red for X, green for Y, blue for Z, yellow for 3d vector module.
Whenever you're ready, you can add a planet to your simulation: go to the "Planets" tab in the upper pane and setup a new planet: insert the position, the speed, the radius, the mass, the name and select a texture. Recommended values for standard simulation settings are: position not exceeding 100k; speed not exceeding 1; radius not exceeding 10k; mass not exceeding 100k. When everything is ready, click on the "Add Planet" button.
As you can see, if the gravitational force is strong enough, the forecasted trajectory of the ship is no more a straight line, but it is curved as the ship follows its orbital path.
You can add as many planets as you wish, and can also load/save the system you create using the "Open file" and "Save file" buttons.
Understanding the inner workings
The basic principles of this simulator are newton's laws, used with the laws of kinetics, solved with a simple Eulerian integrator. (other integrators are in the ToDo list; I'm working on midpoint and RK4 integrators)
The physical body class "oggetto" has a set of various properties used for graphics and interface, a set of inertial properties and a struct that holds both kinematic and dynamic properties.
The body has also some internal functions that can be used to move and rotate it, and to apply forces and torques to it.
Whenever the constructor is called, the newly generated object is put into a dynamic list so that it can be taken into account in the simulation when a function is called.
An important thing to understand about the engine is that there is more than one physical status, so that you don't have to move the graphical object (the Mesh) associated to the object if you wish to simulate something withouth showing it; so whenever you call a function it will need the physical status in which the body is or which you wish to update.
The main class functions are:
gravity (given two objects and their status, it returns a vector representing the gravitational force generated between the two objects)
collision (given two objects and their status, returns true if they have collided; it is based on the bounding sphere)
Apply_Gravity (applies to all the objects the gravity they apply on each other)
interpolate_state (computes a linear interpolation between two physical states; for instance it can be used to avoid time aliasing)
apply_state (updates the graphical Meshes with a certain physical status)
Simulation_Step (calls the integrator for a given status and a given time step)
Simulate_Eulerian (solves the equations of motion)
The function behind the movements of the camera is a simple conversion between plane coordinates (mouse XY) and Spherical coordinates, where the radius is regulated via the mouse wheel. So it is a simple transformation as described here.
To avoid gimbal lock the rotations are computed via quaternions; to simplify the problem some DirectX functions wrapped into the TV3D Math lib were used to compute the quaternion from the rotation matrix and viceversa.
Some interesting particle effects are used in SpaceSimSharp: the glow of the engines, the trail the ship leaves behind and the space dust giving the feeling of motion. This last one is centered on the camera so that only a small amount of particles has got to be created to render a realistic effect.
The rendering cycle is not synchronized with the physics, so the FPS rate doesn't affect the speed of the simulation (unless the framerate drops below the frequency given by the physics integration timestep); this is realized via an accumulator, which reads the time elapsed between the rendering of two frames; this accumulator is divided by a multiple of the timestep; then the physics are calculated as many times as was the result of the division, plus one step that is interpolated in proportion of the remainder of the division. This is to avoid temporal aliasing.
Remember that this project is not complete and that is an exercise for me, so do not expect it to be totally correct or without bugs!!!
Feel free to send me opinions & comments.




