|
|
|
@ -59,10 +59,10 @@ initLights(RenderState* rs) |
|
|
|
updateGLBuffer(lights_ubo, lb->buffer); |
|
|
|
updateGLBuffer(lights_ubo, lb->buffer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// FIXME: could pass EllipseParameters and Ellipse3D instead of TwoBodySystem
|
|
|
|
|
|
|
|
Entity* |
|
|
|
Entity* |
|
|
|
initEllipseEntity(RenderState* rs, |
|
|
|
initEllipseEntity(RenderState* rs, |
|
|
|
TwoBodySystem* system, |
|
|
|
const EllipseParameters& ep, |
|
|
|
|
|
|
|
Ellipse3D& e3d, |
|
|
|
u32 num_vertices) |
|
|
|
u32 num_vertices) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// FIXME: it might be worth using stack memory here, and in
|
|
|
|
// FIXME: it might be worth using stack memory here, and in
|
|
|
|
@ -152,52 +152,66 @@ initSatelliteEntity(RenderState* rs, const char* name) |
|
|
|
return e; |
|
|
|
return e; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
GameOrbit* |
|
|
|
|
|
|
|
loadOrbit(GameState* gs, |
|
|
|
|
|
|
|
RenderState* rs, |
|
|
|
|
|
|
|
const GravBody& body, |
|
|
|
|
|
|
|
const OrbitalElements& elements, |
|
|
|
|
|
|
|
RenderGroup* rg, |
|
|
|
|
|
|
|
const char* sat_name) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
GameOrbit* orbit = getFreeOrbit(gs); |
|
|
|
|
|
|
|
systemInit(orbit->system, body, elements); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
orbit->ellipse_entity = initEllipseEntity(rs, |
|
|
|
|
|
|
|
orbit->system.ep, |
|
|
|
|
|
|
|
orbit->e3d, |
|
|
|
|
|
|
|
DEFAULT_ORBIT_VERTICES); |
|
|
|
|
|
|
|
setEntityPosition(orbit->ellipse_entity, vec3(0, 0, 0)); |
|
|
|
|
|
|
|
rotateEntity(orbit->ellipse_entity, vec3(1, 0, 0), (float) M_PI / 2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
orbit->satellite_entity = initSatelliteEntity(rs, sat_name); |
|
|
|
|
|
|
|
scaleEntity(orbit->satellite_entity, 1 / SCALING); |
|
|
|
|
|
|
|
rotateEntity(orbit->satellite_entity, vec3(1, 0, 0), (float) M_PI / 2); |
|
|
|
|
|
|
|
setEntityPosition(orbit->satellite_entity, |
|
|
|
|
|
|
|
orbit->e3d.vertices[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return orbit; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
loadScene(GameState* gs, RenderState* rs) |
|
|
|
loadScene(GameState* gs, RenderState* rs) |
|
|
|
{ |
|
|
|
{ |
|
|
|
initCamera(rs, vec3(0, -75 / SCALING, 0), vec3(0, 0, 0), vec3(0,0,1)); |
|
|
|
initCamera(rs, vec3(0, -75 / SCALING, 0), vec3(0, 0, 0), vec3(0,0,1)); |
|
|
|
initLights(rs); |
|
|
|
initLights(rs); |
|
|
|
gs->running = true; |
|
|
|
gs->running = true; |
|
|
|
|
|
|
|
|
|
|
|
double a = 26564.5; // semi-major axis in km
|
|
|
|
|
|
|
|
double e = 0.7411; // eccentricity
|
|
|
|
|
|
|
|
double mu = 398601.68; // gravitational parameter
|
|
|
|
double mu = 398601.68; // gravitational parameter
|
|
|
|
double r = 6378; // body radius in km
|
|
|
|
double r = 6378; // body radius in km
|
|
|
|
|
|
|
|
GravBody body = gravBodyInit(mu, r); |
|
|
|
GameOrbit* orbit_1 = getFreeOrbit(gs); |
|
|
|
initPlanetEntity(rs, r); |
|
|
|
systemInit(orbit_1->system, gravBodyInit(mu, r), orbitInit(a, e)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: streamline the boilerplate in init_X_Entity functions
|
|
|
|
// TODO: streamline the boilerplate in init_X_Entity functions
|
|
|
|
ShaderProgram* shader = getShaderByName("colored_vertices", rs->gl_ctx); |
|
|
|
ShaderProgram* shader = getShaderByName("colored_vertices", rs->gl_ctx); |
|
|
|
initRenderGroup( |
|
|
|
RenderGroup* rg = getFreeRenderGroup(rs); |
|
|
|
getFreeRenderGroup(rs), rs->rg_arena, shader, 256, "manual mesh group"); |
|
|
|
initRenderGroup(rg, rs->rg_arena, shader, 256, "manual mesh group"); |
|
|
|
|
|
|
|
|
|
|
|
orbit_1->ellipse_entity = initEllipseEntity(rs, &orbit_1->system, 256); |
|
|
|
double a = 26564.5; // semi-major axis in km
|
|
|
|
setEntityPosition(orbit_1->ellipse_entity, vec3(0, 0, 0)); |
|
|
|
double e = 0.7411; // eccentricity
|
|
|
|
rotateEntity(orbit_1->ellipse_entity, vec3(1, 0, 0), (float) M_PI / 2); |
|
|
|
GameOrbit* orbit_1 = loadOrbit(gs, rs, body, orbitInit(a, e), rg, "sat_01"); |
|
|
|
|
|
|
|
// NOTE: set as selected orbit
|
|
|
|
|
|
|
|
updateOrbitColors(nullptr, orbit_1); |
|
|
|
|
|
|
|
gs->last_selected_orbit = orbit_1; |
|
|
|
|
|
|
|
|
|
|
|
initPlanetEntity(rs, r); |
|
|
|
double a_2 = r + 10000; |
|
|
|
|
|
|
|
double e_2 = 0; |
|
|
|
|
|
|
|
loadOrbit(gs, rs, body, orbitInit(a_2, e_2), rg, "sat_02"); |
|
|
|
|
|
|
|
|
|
|
|
orbit_1->satellite_entity = initSatelliteEntity(rs, "ship 01"); |
|
|
|
double a_3 = r + 40000; |
|
|
|
scaleEntity(orbit_1->satellite_entity, 1 / SCALING); |
|
|
|
double e_3 = 0.5; |
|
|
|
rotateEntity(orbit_1->satellite_entity, vec3(1, 0, 0), (float) M_PI / 2); |
|
|
|
loadOrbit(gs, rs, body, orbitInit(a_3, e_3), rg, "sat_03"); |
|
|
|
setEntityPosition(orbit_1->satellite_entity, |
|
|
|
|
|
|
|
orbit_1->system.e3d.vertices[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOTE: testing multiple orbits
|
|
|
|
return true; |
|
|
|
double a_2 = r + 10000; // km
|
|
|
|
|
|
|
|
double e_2 = 0; |
|
|
|
|
|
|
|
GameOrbit* orbit_2 = getFreeOrbit(gs); |
|
|
|
|
|
|
|
systemInit(orbit_2->system, gravBodyInit(mu, r), orbitInit(a_2, e_2)); |
|
|
|
|
|
|
|
orbit_2->ellipse_entity = initEllipseEntity(rs, &orbit_2->system, 256); |
|
|
|
|
|
|
|
setEntityPosition(orbit_2->ellipse_entity, vec3(0, 0, 0)); |
|
|
|
|
|
|
|
rotateEntity(orbit_2->ellipse_entity, vec3(1, 0, 0), (float) M_PI / 2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
orbit_2->satellite_entity = initSatelliteEntity(rs, "ship 02"); |
|
|
|
|
|
|
|
scaleEntity(orbit_2->satellite_entity, 1 / SCALING); |
|
|
|
|
|
|
|
rotateEntity(orbit_2->satellite_entity, vec3(1, 0, 0), (float) M_PI / 2); |
|
|
|
|
|
|
|
setEntityPosition(orbit_2->satellite_entity, |
|
|
|
|
|
|
|
orbit_2->system.e3d.vertices[0]); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
void |
|
|
|
@ -258,23 +272,31 @@ preFrameCallback(RenderState* rs, void* user_data = nullptr) |
|
|
|
u64 last_sdl_tick = gs->game_time_ms; |
|
|
|
u64 last_sdl_tick = gs->game_time_ms; |
|
|
|
gs->game_time_ms = SDL_GetTicks64(); |
|
|
|
gs->game_time_ms = SDL_GetTicks64(); |
|
|
|
u64 current_tick = gs->game_time_ms - last_sdl_tick; |
|
|
|
u64 current_tick = gs->game_time_ms - last_sdl_tick; |
|
|
|
|
|
|
|
double time_step = 0; |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: update sim time base on time since last frame * sim_speed
|
|
|
|
// NOTE: update sim time base on time since last frame * sim_speed
|
|
|
|
if (gs->running) { |
|
|
|
if (gs->running) { |
|
|
|
u64 last_game_tick = gs->sim_time_ms; |
|
|
|
u64 last_game_tick = gs->sim_time_ms; |
|
|
|
gs->sim_time_ms = gs->sim_time_ms + current_tick * gs->sim_speed; |
|
|
|
gs->sim_time_ms = gs->sim_time_ms + current_tick * gs->sim_speed; |
|
|
|
u32 diff_ms = gs->sim_time_ms - last_game_tick; |
|
|
|
u32 diff_ms = gs->sim_time_ms - last_game_tick; |
|
|
|
double time_step = double(diff_ms) / 1000; |
|
|
|
time_step = double(diff_ms) / 1000; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < gs->num_orbits; i++) { |
|
|
|
for (u32 i = 0; i < gs->num_orbits; i++) { |
|
|
|
GameOrbit& orbit = gs->orbits[i]; |
|
|
|
GameOrbit& orbit = gs->orbits[i]; |
|
|
|
|
|
|
|
|
|
|
|
if (orbit.in_use && orbit.satellite_entity) { |
|
|
|
if (orbit.in_use && orbit.satellite_entity) { |
|
|
|
|
|
|
|
if (gs->running) { |
|
|
|
updateSatelliteModel(orbit.system, time_step); |
|
|
|
updateSatelliteModel(orbit.system, time_step); |
|
|
|
updateSatelliteEntity(orbit.satellite_entity, orbit.system.sat); |
|
|
|
updateSatelliteEntity(orbit.satellite_entity, orbit.system.sat); |
|
|
|
// TODO: update EllipseEntity per frame
|
|
|
|
// TODO: update EllipseEntity per frame
|
|
|
|
//updateOrbit(gs->system, ellipse_entity);
|
|
|
|
//updateOrbit(gs->system, ellipse_entity);
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (orbit.selected && &orbit != gs->last_selected_orbit) { |
|
|
|
|
|
|
|
updateOrbitColors(gs->last_selected_orbit, &orbit); |
|
|
|
|
|
|
|
gs->last_selected_orbit = &orbit; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -312,7 +334,11 @@ main() |
|
|
|
gs.max_orbits = DEFAULT_MAX_ORBITS; |
|
|
|
gs.max_orbits = DEFAULT_MAX_ORBITS; |
|
|
|
gs.orbits = ARENA_ALLOC(gs.arena, GameOrbit, DEFAULT_MAX_ORBITS); |
|
|
|
gs.orbits = ARENA_ALLOC(gs.arena, GameOrbit, DEFAULT_MAX_ORBITS); |
|
|
|
|
|
|
|
|
|
|
|
loadScene(&gs, rs); |
|
|
|
if (!loadScene(&gs, rs)) { |
|
|
|
|
|
|
|
LOGF(Error, "Error loading scene\n"); |
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
doRenderLoop(rs, 60, preFrameCallback, postFrameCallback, &gs); |
|
|
|
doRenderLoop(rs, 60, preFrameCallback, postFrameCallback, &gs); |
|
|
|
gooFree(); |
|
|
|
gooFree(); |
|
|
|
freeRenderState(rs); |
|
|
|
freeRenderState(rs); |
|
|
|
|