From f44bdc90fc23c33935d8f278158be79ff1d4c2f5 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Wed, 25 May 2022 12:41:13 -0400 Subject: [PATCH] update ellipse colors when selecting from gooey --- src/game.cpp | 39 ++++++++++++++++++++ src/game.h | 5 +++ src/main.cpp | 102 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 108 insertions(+), 38 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 0406286..9af62a6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -58,3 +58,42 @@ ellipse3DUpdate(EllipseParameters ep, Ellipse3D& e3d) e3d.vertices[i] = vec3(polarToRect(a, r), 0); } } + +void +changeOrbitColor(GameOrbit* orbit, vec3* color_data) +{ + GLBuffer* color_buf; + GLMesh* gl_mesh = &orbit->ellipse_entity->meshes[0]; + + for (u32 i = 0; i < gl_mesh->num_vertex_attrib_buffers; i ++) { + if (utilCStrMatch(gl_mesh->vertex_attrib_buffers[i].name, "color")) + color_buf = &gl_mesh->vertex_attrib_buffers[i]; + } + + assert(color_buf && color_buf->data_size == orbit->e3d.vert_count * 3 * 4); + updateGLBuffer(color_buf, color_data); +} + +void +updateOrbitColors(GameOrbit* last_selected_orbit, GameOrbit* orbit) +{ + assert(orbit && orbit->ellipse_entity); + + // FIXME: need to allocate these somewhere other than stack + static vec3 selected_colors[DEFAULT_ORBIT_VERTICES]; + static vec3 default_colors[DEFAULT_ORBIT_VERTICES]; + + for (u32 i = 0; i < DEFAULT_ORBIT_VERTICES; i++) + selected_colors[i] = SELECTED_ELLIPSE_COLOR; + + changeOrbitColor(orbit, selected_colors); + + // repeat for last orbit + if (last_selected_orbit != nullptr) { + for (u32 i = 0; i < DEFAULT_ORBIT_VERTICES; i++) + default_colors[i] = DEFAULT_ELLIPSE_COLOR; + + changeOrbitColor(last_selected_orbit, default_colors); + } +} + diff --git a/src/game.h b/src/game.h index d473aed..a18a776 100644 --- a/src/game.h +++ b/src/game.h @@ -9,6 +9,9 @@ using glm::vec3; #define DEFAULT_ORBIT_VERTICES 256 +const vec3 DEFAULT_ELLIPSE_COLOR = vec3(0.5, 0.5, 0.5); +const vec3 SELECTED_ELLIPSE_COLOR = vec3(0.7, 0.2, 0.2); + struct Ellipse3D { @@ -40,6 +43,8 @@ struct GameState GameOrbit* orbits; u32 num_orbits; u32 max_orbits; + + GameOrbit* last_selected_orbit; }; GameOrbit* getFreeOrbit(GameState* gs); diff --git a/src/main.cpp b/src/main.cpp index d69e034..6a961a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,10 +59,10 @@ initLights(RenderState* rs) updateGLBuffer(lights_ubo, lb->buffer); } -// FIXME: could pass EllipseParameters and Ellipse3D instead of TwoBodySystem Entity* initEllipseEntity(RenderState* rs, - TwoBodySystem* system, + const EllipseParameters& ep, + Ellipse3D& e3d, u32 num_vertices) { // FIXME: it might be worth using stack memory here, and in @@ -152,52 +152,66 @@ initSatelliteEntity(RenderState* rs, const char* name) 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) { initCamera(rs, vec3(0, -75 / SCALING, 0), vec3(0, 0, 0), vec3(0,0,1)); initLights(rs); gs->running = true; - double a = 26564.5; // semi-major axis in km - double e = 0.7411; // eccentricity double mu = 398601.68; // gravitational parameter double r = 6378; // body radius in km - - GameOrbit* orbit_1 = getFreeOrbit(gs); - systemInit(orbit_1->system, gravBodyInit(mu, r), orbitInit(a, e)); + GravBody body = gravBodyInit(mu, r); + initPlanetEntity(rs, r); // TODO: streamline the boilerplate in init_X_Entity functions ShaderProgram* shader = getShaderByName("colored_vertices", rs->gl_ctx); - initRenderGroup( - getFreeRenderGroup(rs), rs->rg_arena, shader, 256, "manual mesh group"); + RenderGroup* rg = getFreeRenderGroup(rs); + initRenderGroup(rg, rs->rg_arena, shader, 256, "manual mesh group"); - orbit_1->ellipse_entity = initEllipseEntity(rs, &orbit_1->system, 256); - setEntityPosition(orbit_1->ellipse_entity, vec3(0, 0, 0)); - rotateEntity(orbit_1->ellipse_entity, vec3(1, 0, 0), (float) M_PI / 2); + double a = 26564.5; // semi-major axis in km + double e = 0.7411; // eccentricity + 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"); - scaleEntity(orbit_1->satellite_entity, 1 / SCALING); - rotateEntity(orbit_1->satellite_entity, vec3(1, 0, 0), (float) M_PI / 2); - setEntityPosition(orbit_1->satellite_entity, - orbit_1->system.e3d.vertices[0]); + double a_3 = r + 40000; + double e_3 = 0.5; + loadOrbit(gs, rs, body, orbitInit(a_3, e_3), rg, "sat_03"); - // NOTE: testing multiple orbits - 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]); + return true; } void @@ -258,23 +272,31 @@ preFrameCallback(RenderState* rs, void* user_data = nullptr) u64 last_sdl_tick = gs->game_time_ms; gs->game_time_ms = SDL_GetTicks64(); 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 if (gs->running) { u64 last_game_tick = gs->sim_time_ms; gs->sim_time_ms = gs->sim_time_ms + current_tick * gs->sim_speed; 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++) { - GameOrbit& orbit = gs->orbits[i]; + for (u32 i = 0; i < gs->num_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); updateSatelliteEntity(orbit.satellite_entity, orbit.system.sat); // TODO: update EllipseEntity per frame //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.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); gooFree(); freeRenderState(rs);