#include "game.h" GameOrbit* getFreeOrbit(GameState* gs) { GameOrbit* orbit = nullptr; // NOTE: first check if we have a freed orbit to use for (u32 i = 0; i < gs->num_orbits; i++) { if (!gs->orbits[i].in_use) orbit = &gs->orbits[i]; } // NOTE: if we can't re-use a freed orbit, initialize a new one if (!orbit) { assert(gs->num_orbits < gs->max_orbits); orbit = &gs->orbits[gs->num_orbits++]; } orbit->in_use = true; return orbit; } void disableGameOrbit(GameState* gs, GameOrbit* orbit) { if (gs->last_selected_orbit == orbit) gs->last_selected_orbit = nullptr; *orbit = {0}; } Ellipse3D ellipse3DInit(EllipseParameters ep, uint vert_count) { assert(ep.a > 0 && ep.b > 0 && ep.a >= ep.b && vert_count > 0); Ellipse3D e3d = { nullptr, vert_count}; // FIXME: should be allocated from GameState->arena e3d.vertices = UTIL_ALLOC(vert_count, vec3); ellipse3DUpdate(ep, e3d); return e3d; } void ellipse3DUpdate(EllipseParameters ep, Ellipse3D& e3d) { double angle = 2 * M_PI / e3d.vert_count; for (uint i = 0; i < e3d.vert_count; i++) { double a = angle * i; // NOTE: solving for distance in polar coordinates relative to focus double r = ep.a * (1 - pow(ep.e, 2)) / (1 + ep.e * cos(a)); 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); } }