public
Authored by avatar Emeka T. Nkurumeh

simple ground

Edited
demo.c 2.23 KiB
#include "color.h"
#include "forces.h"
#include "polygon.h"
#include "scene.h"
#include "sdl_wrapper.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <stdlib.h>

const size_t WINDOW_X = 200, WINDOW_Y = 100;
const double RADIUS = 30, MASS = 100;

#define G 6.67E-11          // N m^2 / kg^2
#define M 6E25              // kg
#define g 9.8               // m / s^2
#define R (sqrt(G * M / g)) // m

typedef struct state {
  scene_t *scene;
} state_t;

static list_t *create_rectangle(vector_t half, vector_t origin) {
  const vector_t verts[] = {{-half.x, half.y}, {half.x, half.y}, {half.x, -half.y}, {-half.x, -half.y},};
  list_t *result = list_init(4, free);
  for (size_t i = 0; i < 4; i++) {
    vector_t *v = malloc(sizeof(vector_t));
    *v = verts[i];
    list_add(result, v);
  }
  polygon_translate(result, origin);
  return result;
}

body_t *particle_init(double radius, double mass, vector_t pos) {
  list_t *poly = list_init(20 * 2, free);
  for (size_t i = 0; i < 20 * 2; i++) {
    vector_t *point = malloc(sizeof(vector_t));
    double theta = (double)i * M_PI / 20;
    point->x = radius * cos(theta);
    point->y = radius * sin(theta);
    list_add(poly, point);
  }
  polygon_translate(poly, pos);
  return body_init(poly, mass, (rgb_color_t){0, 0, 1});
}

state_t *emscripten_init() {
  vector_t min = {.x = -WINDOW_X, .y = -WINDOW_Y};
  vector_t max = {.x = WINDOW_X, .y = WINDOW_Y};
  sdl_init(min, max);

  state_t *state = malloc(sizeof(state_t));
  state->scene = scene_init();
  body_t *body = particle_init(RADIUS, MASS, VEC_ZERO);
  body_t *floor = body_init(create_rectangle((vector_t){WINDOW_X, 20}, (vector_t){0, -100}), INFINITY, (rgb_color_t){1, 0, 0});
  body_t *gravity = body_init(create_rectangle((vector_t){1, 1}, (vector_t){0, -R}), M,(rgb_color_t){0});
  create_newtonian_gravity(state->scene, G, body, gravity);
  create_physics_collision(state->scene, 0, body, floor);
  scene_add_body(state->scene, body);
  scene_add_body(state->scene, floor);
  scene_add_body(state->scene, gravity);
  return state;
}

void emscripten_main(state_t *state) {
  double dt = time_since_last_tick();
  scene_tick(state->scene, dt);
  sdl_render_scene(state->scene);
}

void emscripten_free(state_t *state) {
  scene_free(state->scene);
  free(state);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment