commit c9cfe15a1bb2f8531901768fb943578b104853c9
parent 4059ffe5baaa19c32f0ef6fea644a6cde673affd
Author: William Casarin <jb55@jb55.com>
Date: Wed, 31 Oct 2018 03:16:13 -0700
more work on cameras an entities
Diffstat:
19 files changed, 201 insertions(+), 39 deletions(-)
diff --git a/Makefile b/Makefile
@@ -28,6 +28,7 @@ OBJS += $(SRC)/mat4.o
OBJS += $(SRC)/mat_util.o
OBJS += $(SRC)/model.o
OBJS += $(SRC)/node.o
+OBJS += $(SRC)/orbit.o
OBJS += $(SRC)/perlin.o
OBJS += $(SRC)/ply.o
OBJS += $(SRC)/poisson.o
@@ -40,6 +41,7 @@ OBJS += $(SRC)/uniform.o
OBJS += $(SRC)/update.o
OBJS += $(SRC)/util.o
OBJS += $(SRC)/vec3.o
+OBJS += $(SRC)/hires.o
SRCS=$(OBJS:.o=.c)
diff --git a/etc/shaders/terrain.glsl b/etc/shaders/terrain.glsl
@@ -31,6 +31,7 @@ const vec4 land[nlands] = vec4[](
vec4(1.0, 1.0, 1.0, 380.0) // 5 - snow
);
+
void main()
{
vec3 color = land[0].xyz;
diff --git a/src/common.h b/src/common.h
@@ -10,9 +10,6 @@
#define SLAB(f) "etc/slab/" f
#define RESOURCE(f) "etc/shaders/" f
-#define PI 3.14159265f
-#define TAU 6.2831853f
-
typedef unsigned char u8;
typedef signed char s8;
@@ -22,6 +19,9 @@ typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
+typedef unsigned long long u64;
+typedef signed long long s64;
+
struct point {
double x, y;
};
diff --git a/src/entity.c b/src/entity.c
@@ -2,9 +2,33 @@
#include "entity.h"
#include "node.h"
#include "model.h"
+#include <assert.h>
+#define DEF_NUM_ENTITIES 1024
+
+struct entity_id {
+ u32 index;
+ u32 generation;
+};
void init_entity(struct entity *ent) {
node_init(&ent->node);
ent->casts_shadows = 0;
}
+
+struct entity *get_entity(struct entity_system *system, struct entity_id id) {
+ assert(id.generation <= system->generation);
+ if (id.generation < system->generation)
+ return NULL;
+ return &system->entities[id.index];
+}
+
+void init_entity_system(struct entity_system *system) {
+ system->generation = 0;
+ system->entities = calloc(DEF_NUM_ENTITIES, sizeof(*system->entities));
+
+ system->handles =
+ calloc(DEF_NUM_ENTITIES, sizeof(*system->handles));
+}
+
+
diff --git a/src/entity.h b/src/entity.h
@@ -8,10 +8,23 @@
struct entity {
struct node node;
struct model model;
+ float velocity[3];
+ float accel[3];
int casts_shadows;
};
+struct entity_id;
+
+struct entity_system {
+ struct entity *entities;
+ struct entity_id *handles;
+ int entity_count;
+ u32 generation;
+};
+
void init_entity(struct entity *);
+void init_entity_system(struct entity_system *);
+struct entity *get_entity(struct entity_system *, struct entity_id);
#endif /* ENTITY_H */
diff --git a/src/event.c b/src/event.c
@@ -6,6 +6,10 @@
void process_events(struct game *game, float *camera) {
SDL_Event event;
+ int mdx = 0;
+ int mdy = 0;
+
+ input_reset(&game->input);
while (SDL_PollEvent(&event)) {
switch (event.type) {
@@ -13,6 +17,18 @@ void process_events(struct game *game, float *camera) {
case SDL_KEYUP:
handle_key(&game->input, event.key);
break;
+ case SDL_MOUSEMOTION:
+ if (event.button.button) {
+ if (event.button.button <= MOUSE_BUTTONS)
+ game->input.mbuttons[event.button.button-1] = 1;
+ game->input.is_dragging = 1;
+ mdx += event.motion.xrel;
+ mdy += event.motion.yrel;
+ /* printf("drag... %d %d\n", event.motion.xrel, event.motion.yrel); */
+ game->input.mx = event.motion.x;
+ game->input.my = event.motion.y;
+ }
+ break;
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
@@ -24,5 +40,9 @@ void process_events(struct game *game, float *camera) {
SDL_Quit();
exit(0);
}
+
}
+
+ game->input.mdx = mdx;
+ game->input.mdy = mdy;
}
diff --git a/src/game.c b/src/game.c
@@ -104,6 +104,10 @@ void game_init(struct game *game, int width, int height) {
game->test_resources.fog_on = 1;
game->test_resources.diffuse_on = 0;
+ res->orbit_camera.azimuth = RAD(90.0);
+ res->orbit_camera.inclination = RAD(180.0);
+ res->orbit_camera.radius = RAD(180.0);
+
node_init(root);
node_init(camera);
node_init(sun_camera);
@@ -125,19 +129,13 @@ void game_init(struct game *game, int width, int height) {
node_attach(&player->node, root);
node_attach(camera, &player->node);
- /* node_attach(sun_camera, root); */
quat_axis_angle(V3(1,0,0), -45, camera->orientation);
- /* quat_axis_angle(V3(1,0,0), -90, camera->orientation); */
- /* node_rotate(sun_camera, V3(-7.5, 0, 0)); */
- /* node_translate(sun_camera, V3(width/shadowmap_scale, 2000, 0)); */
node_translate(&player->node, V3(terrain->size/2.,terrain->size/2.,0.0));
- /* vec3_scale(player->node.scale, 10.0, player->node.scale); */
node_rotate(camera, V3(100, 0, 0));
node_translate(camera, V3(0,-40,20));
- /* node_recalc(camera); */
terrain->entity.node.pos[2] = 20.0;
diff --git a/src/game.h b/src/game.h
@@ -11,6 +11,7 @@
#include "terrain.h"
#include "ui.h"
#include "fbo.h"
+#include "orbit.h"
#define PLAYER_HEIGHT 1.73
@@ -55,6 +56,7 @@ struct resources {
struct node root;
struct entity player;
+ struct orbit orbit_camera;
struct node camera;
struct node sun_camera;
@@ -72,6 +74,7 @@ struct resources {
struct game {
int counter;
int seed;
+ float dt;
struct ui ui;
struct resources test_resources;
struct input input;
diff --git a/src/hires.c b/src/hires.c
@@ -0,0 +1,10 @@
+
+#include <time.h>
+#include "common.h"
+#include <SDL2/SDL.h>
+
+double hires_time_in_seconds() {
+ double ticks_per_sec = (double)SDL_GetPerformanceFrequency();
+ double ticks = (double)SDL_GetPerformanceCounter();
+ return ticks / ticks_per_sec;
+}
diff --git a/src/hires.h b/src/hires.h
@@ -0,0 +1,7 @@
+
+#ifndef HIRES_H
+#define HIRES_H
+
+double hires_time_in_seconds();
+
+#endif /* HIRES_H */
diff --git a/src/input.c b/src/input.c
@@ -6,9 +6,20 @@
void input_init(struct input *input) {
/* memset(input->keys, 0, sizeof(input->keys[0]) * ARRAY_SIZE(input->keys)); */
input->keystates = SDL_GetKeyboardState(NULL);
+ input->is_dragging = 0;
+ input->mdx = 0;
+ input->mdy = 0;
assert(input->keystates);
}
void handle_key(struct input *input, SDL_KeyboardEvent key) {
input->modifiers = SDL_GetModState();
}
+
+
+void input_reset(struct input *input) {
+ input->is_dragging = 0;
+
+ for (int i = 0; i < MOUSE_BUTTONS; ++i)
+ input->mbuttons[i] = 0;
+}
diff --git a/src/input.h b/src/input.h
@@ -12,14 +12,22 @@
/* KEY_UP */
/* }; */
+#define MOUSE_BUTTONS 5
+
struct input {
/* enum key_state keys[0x7F-0x1F]; */
- u8 const *keystates;
- SDL_Keymod modifiers;
+ u8 const *keystates;
+ SDL_Keymod modifiers;
+ int mdx, mdy;
+ int mx, my;
+ int is_dragging;
+ int mbuttons[MOUSE_BUTTONS];
};
void input_init(struct input *input);
+void input_reset(struct input *input);
+
void handle_key(struct input *input, SDL_KeyboardEvent ke);
#endif /* POLYADVENT_INPUT_H */
diff --git a/src/main.c b/src/main.c
@@ -18,6 +18,7 @@
#include "uniform.h"
#include "ply.h"
#include "fbo.h"
+#include "hires.h"
int main(void)
@@ -42,7 +43,7 @@ int main(void)
game_init(&game, width, height);
check_gl();
- u32 last = SDL_GetTicks();
+ double last = hires_time_in_seconds();
static float depth_mvp[MAT4_ELEMS];
mat4_id(depth_mvp);
@@ -64,10 +65,17 @@ int main(void)
while (1) {
process_events(&game, game.test_resources.proj_persp);
- u32 ticks = SDL_GetTicks();
- update(&game, ticks-last);
+ double new_time = hires_time_in_seconds();
+ double frame_time = new_time - last;
+ game.dt = frame_time;
+ update(&game);
- last = ticks;
+ /* while (accumulator >= dt) { */
+ /* t += dt; */
+ /* accumulator -= dt; */
+ /* } */
+
+ last = new_time;
GLuint texture = game.test_resources.shadow_buffer.attachments[0];
struct fbo *fbo = &game.test_resources.shadow_buffer;
diff --git a/src/orbit.c b/src/orbit.c
@@ -0,0 +1,25 @@
+
+#include "orbit.h"
+#include "node.h"
+#include <math.h>
+
+void orbit_to_quat(struct orbit *orbit, float *quat)
+{
+ float phi = orbit->azimuth;
+ float theta = orbit->inclination;
+
+ // vector
+ quat[0] = cos(phi/2.0)*cos(theta/2.0); // scalar quaternion components
+ quat[1] = -sin(phi/2.0)*sin(theta/2.0); // x quaternion components
+ quat[2] = cos(phi/2.0)*sin(theta/2.0); // y quaternion components
+ quat[3] = sin(phi/2.0)*cos(theta/2.0); // z quaternion components
+}
+
+/* static void orbit_update_node(struct node *node) { */
+/* } */
+
+void orbit_to_node(struct orbit *orbit, struct node *node) {
+ orbit_to_quat(orbit, node->orientation);
+ node_mark_for_recalc(node);
+}
+
diff --git a/src/orbit.h b/src/orbit.h
@@ -0,0 +1,18 @@
+
+#ifndef ORBIT_H
+#define ORBIT_H
+
+struct node;
+
+struct orbit {
+ float radius;
+ float inclination;
+ float azimuth;
+};
+
+
+void orbit_to_node(struct orbit *orbit, struct node *node);
+void orbit_to_quat(struct orbit *, float *a);
+
+
+#endif /* ORBIT_H */
diff --git a/src/physics.c b/src/physics.c
@@ -0,0 +1,3 @@
+
+void simulate(struct entity_system *entity_system) {
+}
diff --git a/src/update.c b/src/update.c
@@ -136,7 +136,7 @@ void update_terrain(struct game *game) {
/* struct point *samples = */
/* uniform_samples(n_samples, game->terrain.size); */
- static const double pdist = 42.0;
+ static const double pdist = 24.0;
struct point *samples =
poisson_disk_samples(pdist, game->terrain.size, 30, &n_samples);
@@ -153,22 +153,21 @@ void update_terrain(struct game *game) {
terrain_create(&game->terrain);
}
-static void player_terrain_collision(struct game *game) {
- struct node *player = &game->test_resources.player.node;
+static void player_terrain_collision(struct terrain *terrain, struct entity *player) {
// player movement
static vec3 last_pos[3] = {0};
- if (!vec3_eq(player->pos, last_pos, 0.0001)) {
- float player_z = player->pos[2];
+ if (!vec3_eq(player->node.pos, last_pos, 0.0001)) {
+ float player_z = player->node.pos[2];
float terrain_z =
- game->terrain.fn(&game->terrain, player->pos[0], player->pos[1]) + 5.0;
+ terrain->fn(terrain, player->node.pos[0], player->node.pos[1]) + 5.0;
float inset =
min(0.0, player_z - terrain_z);
if (inset <= 0)
- node_translate(player, V3(0.0, 0.0, -inset));
+ node_translate(&player->node, V3(0.0, 0.0, -inset));
}
}
@@ -177,13 +176,12 @@ static void player_movement(struct game *game) {
struct resources *res = &game->test_resources;
movement(game, &res->player.node, 2.0);
- node_recalc(&res->camera);
- vec3 *camera_world = node_world(&res->camera);
- float cam_terrain_z =
- game->terrain.fn(&game->terrain, camera_world[0], camera_world[1]);
+ /* vec3 *camera_world = node_world(&res->camera); */
+ /* float cam_terrain_z = */
+ /* game->terrain.fn(&game->terrain, camera_world[0], camera_world[1]); */
- if (camera_world[2] < cam_terrain_z)
- camera_world[2] = cam_terrain_z + 20.0;
+ /* if (camera_world[2] < cam_terrain_z) */
+ /* camera_world[2] = cam_terrain_z + 20.0; */
}
@@ -241,7 +239,7 @@ void resize_fbos(struct game *game, int width, int height) {
// TODO: match based on some real concept of time
static void day_night_cycle(float time, struct resources *res) {
- float val = time * 50.0;
+ float val = time;
float intensity = vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0));
intensity = clamp(intensity, 0.0, 0.8);
float light_pos[3];
@@ -265,8 +263,8 @@ static void day_night_cycle(float time, struct resources *res) {
/* vec3_normalize(res->light_intensity, res->light_intensity); */
res->light_dir[0] = 0.0;
- res->light_dir[1] = -sin(val);
- res->light_dir[2] = -cos(val);
+ res->light_dir[1] = sin(val);
+ res->light_dir[2] = cos(val) + 1.0;
vec3_normalize(res->light_dir, res->light_dir);
@@ -278,19 +276,26 @@ static void day_night_cycle(float time, struct resources *res) {
look_at(light_pos, res->player.node.pos, V3(0, 0, 1.0), res->sun_camera.mat);
}
-void gravity(struct game *game) {
+static void gravity(struct game *game) {
struct entity *player = &game->test_resources.player;
node_translate(&player->node, V3(0.0, 0.0, -1.0));
}
-void update (struct game *game, u32 dt) {
- static double last_ox, last_oy, last_oz;
+static void player_update(struct game *game, struct entity *player) {
+ struct orbit *orbit_camera = &game->test_resources.orbit_camera;
+ /* orbit_camera->radius += game->dt * 4.0; */
+ /* orbit_camera->inclination += game->dt * 2.0; */
+ /* orbit_camera->azimuth += game->dt * 2.0; */
+ /* orbit_to_node(orbit_camera, &game->test_resources.camera); */
+
+ player_terrain_collision(&game->terrain, player);
+}
+
+void update (struct game *game) {
static int toggle_fog = 0;
- static float n = 1.0;
static int first = 1;
struct resources *res = &game->test_resources;
- struct perlin_settings *ts = &game->terrain.settings;
struct node *tnode = &game->terrain.entity.node;
struct node *root = &game->test_resources.root;
float *time = &res->time;
@@ -303,6 +308,8 @@ void update (struct game *game, u32 dt) {
first = 0;
}
+ player_update(game, &res->player);
+
if (game->input.modifiers & KMOD_LALT) {
movement(game, &res->camera, 1.0);
}
@@ -313,7 +320,6 @@ void update (struct game *game, u32 dt) {
player_movement(game);
}
- player_terrain_collision(game);
#ifdef DEBUG
if (game->input.keystates[SDL_SCANCODE_R])
@@ -333,7 +339,7 @@ void update (struct game *game, u32 dt) {
day_night_cycle(*time, res);
- *time += dt * 0.00001f;
+ *time += game->dt * 0.00001f;
node_recalc(root);
diff --git a/src/update.h b/src/update.h
@@ -4,7 +4,7 @@
#include "game.h"
-void update(struct game * game, u32 dt);
+void update(struct game * game);
void resize_fbos(struct game * game, int width, int height);
#endif /* PA_UPDATE_H */
diff --git a/src/util.h b/src/util.h
@@ -16,6 +16,11 @@
} \
}
+#define PI 3.14159265
+#define TAU 6.2831853
+
+#define RAD(x) ((x)*TAU/360.0)
+
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
void look_at(vec3 *eye, vec3 *target, vec3 *up, mat4 *dest);