test commit dont look

This commit is contained in:
MallocNull 2021-01-21 19:35:39 -06:00
parent 34168ef1d1
commit 678136b970
17 changed files with 473 additions and 95 deletions

88
rbm/rbm.py Normal file
View file

@ -0,0 +1,88 @@
import os
import bpy
import mathutils
import bpy_extras.io_utils
BASE_PATH = "/home/malloc/Documents/link_test/"
def bone_id(name: str):
if(len(name) < 3):
return None
bid = name[0:3]
if(bid[2] != "."):
return None
try:
bid = int(bid[0:2], 16)
except:
bid = None
return bid
def triangulate_mesh(mesh):
import bmesh
bm = bmesh.new()
bm.from_mesh(mesh)
bmesh.ops.triangulate(bm, faces=bm.faces)
bm.to_mesh(mesh)
bm.free()
def write_mesh(object):
vertices = weights = normals = texuvs = faces = bones = []
mesh: bpy.types.Mesh = None
armature: bpy.types.Armature = None
try:
mesh = object.to_mesh(bpy.data.scenes[0], False,
settings='PREVIEW', calc_tessface=False)
except:
print("Could not copy mesh.")
return
if object.parent != None and object.parent.type == 'ARMATURE':
armature = object.parent.data
bones = [(bone_id(group.name), armature.bones[group.name])
for group in object.vertex_groups]
check = [bone for bone in bones if bone[0] == None]
if len(check) > 0:
for bone in check:
print("Bone", bone[1].name, "is not named according to format 'XX.NAME'")
return
triangulate_mesh(mesh)
mesh.transform(object.matrix_world)
if(object.matrix_world.determinant() < 0.0):
mesh.flip_normals()
mesh.calc_normals_split()
vertices = mesh.vertices[:]
if armature:
weights = [list(
(group.group, group.weight)
for group in vertex.groups)
for vertex in vertices]
normals = [vertex.normal for vertex in vertices]
tris = [(i, tri) for i, tri in enumerate(mesh.polygons)]
for i, tri in tris:
bpy.data.meshes.remove(mesh)
def write_armature(object):
pass
#fw(b"\xDE\xAF\xB0\x0B")
os.makedirs(BASE_PATH, exist_ok=True)
for object in bpy.data.objects:
if object.type == 'MESH' :
write_mesh(object)
elif object.type == 'ARMATURE':
write_armature(object)

0
rbm/rbs.py Normal file
View file

View file

@ -0,0 +1,5 @@
#version 100
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

View file

@ -0,0 +1,5 @@
#version 100
void main() {
gl_Position = vec4(vec3(0.0), 1.0);
}

3
src/game/object.c Normal file
View file

@ -0,0 +1,3 @@
#include "object.h"

28
src/game/object.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef SOSC_OBJECT_H
#define SOSC_OBJECT_H
#include <cglm/cglm.h>
#include "okuu/mesh.h"
typedef struct {
mesh_t* mesh;
mat4 translate, scale, rotate;
} object_t;
void object_create(mesh_t*);
void object_reset_matrices(object_t*);
void object_reset_translate(object_t*);
void object_reset_scale(object_t*);
void object_reset_rotate(object_t*);
void object_translate(object_t*, vec3);
void object_scale(object_t*, vec3, float);
void object_scale_uni(object_t*, vec3, float);
void object_rotate(object_t*, vec3, float);
void object_
void object_model_matrix(object_t*, mat4);
void object_destroy(object_t*);
#endif

View file

@ -23,7 +23,6 @@ struct {
int mode, running;
int mouse[3];
vec2 tlocs[10];
font_t* scape;
text_t* text;
mesh_t* monkey;
@ -44,13 +43,6 @@ int init();
void deinit();
void run();
void reset_text_locs() {
for(int i = 0; i < 10; ++i) {
_g.tlocs[i][0] = rand() % (WINDOW_WIDTH / 2);
_g.tlocs[i][1] = rand() % WINDOW_HEIGHT;
}
}
int main(int argc, char* argv[]) {
if(init() < 0)
return -1;
@ -58,23 +50,27 @@ int main(int argc, char* argv[]) {
font_init_subsystem(_g.window);
_g.scape = font_load(
"data/fonts/scape.bmp",
"data/fonts/scape.dat",
"data/fonts/scape2.bmp",
"data/fonts/scape2.dat",
GL_NEAREST
);
font_set_default(_g.scape);
_g.text = text_create(NULL);
text_set(_g.text, "flashwave is cool !!!");
text_set_size(_g.text, 32);
text_set_rgb_hex(_g.text, 0x55007e);
reset_text_locs();
//text_set(_g.text, "Welcome to Rune2006");
text_set_size(_g.text, 16);
text_set_rgb_hex(_g.text, 0xffff00);
_g.monkey = mesh_load("data/models/player.rbm");
color_t path_colors[] = {
{0x60, 0x60, 0x60, 0xFF},
{0x9C, 0x00, 0x0E, 0xFF}
};
_g.map = terrain_load(
"data/terrains/map-heights.bmp",
"data/terrains/map-colors.bmp",
path_colors, sizeof(path_colors) / sizeof(color_t),
10, 10
);
@ -83,8 +79,8 @@ int main(int argc, char* argv[]) {
"vertex", "texuv", "normal", "color"
);
shader_source(_s_def.shader, SHADER_FILE, 2,
"data/shaders/test.vert", GL_VERTEX_SHADER,
"data/shaders/test.frag", GL_FRAGMENT_SHADER
"data/shaders/terrain.vert", GL_VERTEX_SHADER,
"data/shaders/terrain.frag", GL_FRAGMENT_SHADER
);
shader_attribs(_s_def.shader, 3,
"model", "view", "projection"
@ -100,13 +96,18 @@ int main(int argc, char* argv[]) {
}
void run() {
static mat4 model, map, view, projection;
static mat4 model, map, view, projection, mario;
static vec3 center, eye, pick;
static float rot_up = 45, rot_around = 45;
static float x = 0, y = 0;
static char debug[256] = "";
static int init = 1;
if(init) {
//glm_rotate_make(model, glm_rad(90), (vec3){ 0.f, -1.f, 0.f });
//glm_translate_make(mario, (vec3){ 4.f, 4.f, 4.f });
glm_scale_make(mario, (vec3){ 3.f, 3.f, 3.f });
glm_mat4_identity(model);
glm_mat4_identity(map);
@ -133,37 +134,43 @@ void run() {
glClearColor(0.f, 0.f, 0.5f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
center[0] = -x;
center[1] = -(terrain_height(_g.map, x, y) + 2.f);
center[2] = -y;
float radius = 4.f + 4.f * (rot_up / 90.f);
eye[0] = cos(glm_rad(rot_up)) * radius * cos(glm_rad(rot_around));
eye[1] = radius * sin(glm_rad(rot_up));
eye[2] = cos(glm_rad(rot_up)) * radius * sin(glm_rad(rot_around));
glm_lookat(
(vec3){
cos(glm_rad(rot_up)) * radius * cos(glm_rad(rot_around)),
radius * sin(glm_rad(rot_up)),
cos(glm_rad(rot_up)) * radius * sin(glm_rad(rot_around))
},
eye,
(vec3){0.f, 0.f, 0.f},
(vec3){0.f, 1.f, 0.f},
view
);
for(int i = 0; i < 10; ++i) {
text_move(_g.text, _g.tlocs[i]);
text_render(_g.text);
}
glm_translate(view, center);
glm_vec3_inv(center);
text_set_rgb_hex(_g.text, 0xffff00);
text_shadow_xy(_g.text, 1, 1);
shader_start(_s_def.shader); {
glUniformMatrix4fv(_ATTR(DEF_VIEW), 1, GL_FALSE, (float*)view);
glm_translate_make(model, (vec3){-x, -(_g.map->heights[(int)y][(int)x] + 2.f), -y});
glm_mat4_mul(model, map, model);
glUniformMatrix4fv(_ATTR(DEF_MODEL), 1, GL_FALSE, (float*)model);
glUniformMatrix4fv(_ATTR(DEF_MODEL), 1, GL_FALSE, (float*)map);
glBindVertexArray(_g.map->vao);
glDrawArrays(GL_TRIANGLES, 0, _g.map->tri_cnt * 3);
glUniformMatrix4fv(_ATTR(DEF_MODEL), 1, GL_FALSE, (float*)mario);
mesh_bind(_g.monkey);
mesh_render(_g.monkey);
glBindVertexArray(0);
} shader_stop();
SDL_GL_SwapWindow(_g.window);
SDL_PumpEvents();
if(_g.keys[SDL_SCANCODE_ESCAPE])
@ -198,17 +205,65 @@ void run() {
else if(_g.keys[SDL_SCANCODE_A])
y -= .25;
if(_g.keys[SDL_SCANCODE_SPACE]) {
//if(_g.keys[SDL_SCANCODE_SPACE]) {
terrain_move(_g.map, x, y);
glm_translate_make(map, (vec3){__MAX(0, x - CHUNK_SIZE / 2), 0, __MAX(0, y - CHUNK_SIZE / 2)});
}
if(_g.keys[SDL_SCANCODE_P])
reset_text_locs();
glm_translate_make(map, (vec3){_g.map->top_x, 0, _g.map->top_y});
//}
_g.mouse[2] = SDL_GetMouseState(&_g.mouse[0], &_g.mouse[1]);
if(_g.mouse[2] & SDL_BUTTON(SDL_BUTTON_LEFT)) {
float mx = (float)_g.mouse[0] / (float)WINDOW_WIDTH;
float my = (float)_g.mouse[1] / (float)WINDOW_HEIGHT;
vec4 mouse = {mx * 2 - 1, (1 - my) * 2 - 1, -1.f, 1.f};
mat4 imat;
sprintf(debug, "NDC (%f, %f, %f, %f)", mouse[0], mouse[1], mouse[2], mouse[3]);
text_set(_g.text, debug);
text_move_xy(_g.text, 4, 4);
text_render(_g.text);
glm_mat4_inv(projection, imat);
glm_mat4_mulv(imat, mouse, mouse);
mouse[2] = -1.f;
mouse[3] = 0.f;
sprintf(debug, "EYE (%f, %f, %f, %f)", mouse[0], mouse[1], mouse[2], mouse[3]);
text_set(_g.text, debug);
text_move_xy(_g.text, 4, 24);
text_render(_g.text);
glm_mat4_inv(view, imat);
glm_mat4_mulv(imat, mouse, mouse);
glm_vec4_normalize(mouse);
sprintf(debug, "WORLD (%f, %f, %f, %f)", mouse[0], mouse[1], mouse[2], mouse[3]);
text_set(_g.text, debug);
text_move_xy(_g.text, 4, 44);
text_render(_g.text);
vec3 pcam;
glm_vec3_copy(center, pcam);
sprintf(debug, "PL1LOC (%f, %f, %f)", pcam[0], pcam[1], pcam[2]);
text_set(_g.text, debug);
text_move_xy(_g.text, 4, 64);
text_render(_g.text);
glm_vec3_add(eye, pcam, pcam);
sprintf(debug, "CAMLOC (%f, %f, %f)", pcam[0], pcam[1], pcam[2]);
text_set(_g.text, debug);
text_move_xy(_g.text, 4, 84);
text_render(_g.text);
if(_g.mouse[2] & SDL_BUTTON(SDL_BUTTON_LEFT)) {
if(terrain_pick(_g.map, (vec3){ mouse[0], mouse[1], mouse[2] }, pcam, pick)) {
//glm_scale_make(mario, (vec3){ 3.f, 3.f, 3.f });
pick[0] = (int)pick[0] + 0.5f;
pick[1] += 1.f;
pick[2] = (int)pick[2] + 0.5f;
glm_translate_make(mario, pick);
glm_scale(mario, (vec3){2.f, 2.f, 2.f});
}
}
SDL_Event ev;
@ -239,6 +294,8 @@ void run() {
}*/
}
SDL_GL_SwapWindow(_g.window);
}
int init() {

View file

@ -179,6 +179,8 @@ text_t* text_create(font_t* font) {
text->vert_inv =
text->texuv_inv = 1;
glm_vec2_fill(text->shadow, 0.f);
glm_mat4_identity(text->trans_mat);
glGenVertexArrays(1, &text->vao);
glGenBuffers(2, text->buffers);
@ -269,13 +271,14 @@ void text_set_rgba_hex(text_t* text, uint32_t color) {
}
void text_move(text_t* text, vec2 coords) {
vec3 coords3 = { coords[0], coords[1], 0.f };
glm_translate_make(text->trans_mat, coords3);
glm_translate_make(
text->trans_mat,
(vec3){ coords[0], coords[1], 0.f }
);
}
void text_move_xy(text_t* text, float x, float y) {
vec2 coords = { x, y };
text_move(text, coords);
text_move(text, (vec2){ x, y });
}
void text_wrap(text_t* text, uint32_t wrap) {
@ -283,6 +286,14 @@ void text_wrap(text_t* text, uint32_t wrap) {
text->vert_inv = 1;
}
void text_shadow(text_t* text, vec2 offset) {
glm_vec2_copy(offset, text->shadow);
}
void text_shadow_xy(text_t* text, float x, float y) {
text_shadow(text, (vec2){ x, y });
}
void text_redraw(text_t* text) {
if(!text->vert_inv && !text->texuv_inv)
return;
@ -391,9 +402,34 @@ void text_redraw(text_t* text) {
}
void text_render(text_t* text) {
const vec4 shadow = { 0.f, 0.f, 0.f, 1.f };
mat4 trans_shadow;
text_redraw(text);
shader_start(_ss.shader);
glActiveTexture(GL_TEXTURE0);
font_bind(text->font);
glBindVertexArray(text->vao);
if(text->shadow[0] != 0 || text->shadow[1] != 0) {
glm_translate_make(trans_shadow,
(vec3){ text->shadow[0], text->shadow[1], -0.1f });
glm_mat4_mul(trans_shadow, text->trans_mat, trans_shadow);
glUniformMatrix4fv(
_ATTR(FONT_TRANS),
1, GL_FALSE,
(float*)trans_shadow
);
glUniform4fv(
_ATTR(FONT_COLOR), 1,
(float*)shadow
);
glDrawArrays(GL_TRIANGLES, 0, text->tri_cnt * 3);
}
glUniformMatrix4fv(
_ATTR(FONT_TRANS),
1, GL_FALSE,
@ -403,10 +439,7 @@ void text_render(text_t* text) {
_ATTR(FONT_COLOR), 1,
(float*)text->color
);
glActiveTexture(GL_TEXTURE0);
font_bind(text->font);
glBindVertexArray(text->vao);
glDrawArrays(GL_TRIANGLES, 0, text->tri_cnt * 3);
}

View file

@ -35,6 +35,7 @@ typedef struct {
uint32_t
length, size,
wrap, tri_cnt;
vec2 shadow;
mat4 trans_mat;
GLuint vao, buffers[2];
@ -67,6 +68,9 @@ void text_move(text_t*, vec2);
void text_move_xy(text_t*, float, float);
void text_wrap(text_t*, uint32_t);
void text_shadow(text_t*, vec2);
void text_shadow_xy(text_t*, float, float);
void text_redraw(text_t*);
void text_render(text_t*);

View file

@ -9,8 +9,9 @@ typedef struct {
} _tri_t;
int _populate_pts
(_pt_t* data, FILE* fp, uint32_t length, int width)
(_pt_t* data, obb_t* obb, FILE* fp, uint32_t length, int width)
{
obb_clear(obb);
uint8_t buffer[4];
int chk;
@ -22,6 +23,8 @@ int _populate_pts
data[i].data[j] = *(float*)ltoh(buffer, 4);
}
obb_parse_point(obb, data[i].data);
}
return 1;
@ -84,12 +87,13 @@ mesh_t* mesh_load(const char* file) {
_tri_t *faces = malloc(sizeof(_tri_t) * counts[FACE_CNT]);
int chk = 1;
obb_t obb;
chk &= _populate_pts(verts, fp, counts[VERT_CNT], 3);
chk &= _populate_pts(verts, &obb, fp, counts[VERT_CNT], 3);
if(counts[TEX_CNT] > 0)
chk &= _populate_pts(texs, fp, counts[TEX_CNT], 2);
chk &= _populate_pts(texs, NULL, fp, counts[TEX_CNT], 2);
if(counts[NORM_CNT] > 0)
chk &= _populate_pts(norms, fp, counts[NORM_CNT], 3);
chk &= _populate_pts(norms, NULL, fp, counts[NORM_CNT], 3);
int index_length = counts[FACE_CNT] <= 0xFFFF ? 2 : 4;
for(uint32_t i = 0; i < counts[FACE_CNT]; ++i) {
@ -201,6 +205,7 @@ mesh_t* mesh_load(const char* file) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
mesh->tri_cnt = counts[FACE_CNT];
mesh->obb = obb;
return mesh;
}

View file

@ -11,11 +11,13 @@
#include <stdint.h>
#include <string.h>
#include "obb.h"
#include "koa/etc.h"
typedef struct {
GLuint buffers[3], vao;
uint32_t tri_cnt;
obb_t obb;
} mesh_t;
mesh_t* mesh_load(const char*);

56
src/okuu/obb.c Normal file
View file

@ -0,0 +1,56 @@
#include "obb.h"
void obb_from_center(obb_t* obb, vec3 center, vec3 bounds) {
vec3 cbound;
glm_vec3_abs(bounds, cbound);
glm_vec3_scale(cbound, 0.5f, cbound);
glm_vec3_sub(center, cbound, obb->min);
glm_vec3_add(center, cbound, obb->max);
}
void obb_from_min(obb_t* obb, vec3 min, vec3 bounds) {
vec3 cbound;
glm_vec3_abs(bounds, cbound);
glm_vec3_copy(min, obb->min);
glm_vec3_add(min, cbound, obb->max);
}
void obb_from_max(obb_t* obb, vec3 max, vec3 bounds) {
vec3 cbound;
glm_vec3_abs(bounds, cbound);
glm_vec3_copy(max, obb->max);
glm_vec3_sub(max, cbound, obb->min);
}
void obb_clear(obb_t* obb) {
if(obb == NULL)
return;
obb->min[0] =
obb->min[1] =
obb->min[2] =
obb->max[0] =
obb->max[1] =
obb->max[2] = NAN;
}
void obb_parse_point(obb_t* obb, vec3 pt) {
if(obb == NULL)
return;
if(obb->min[0] == NAN) {
glm_vec3_copy(pt, obb->min);
glm_vec3_copy(pt, obb->max);
} else {
obb->min[0] = __MIN(obb->min[0], pt[0]);
obb->min[1] = __MIN(obb->min[1], pt[1]);
obb->min[2] = __MIN(obb->min[2], pt[2]);
obb->max[0] = __MIN(obb->max[0], pt[0]);
obb->max[1] = __MIN(obb->max[1], pt[1]);
obb->max[2] = __MIN(obb->max[2], pt[2]);
}
}

20
src/okuu/obb.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef OKUU_OBB_H
#define OKUU_OBB_H
#include <cglm/cglm.h>
#include "koa/etc.h"
typedef struct {
vec3 min, max;
} obb_t;
void obb_from_center(obb_t*, vec3, vec3);
void obb_from_min(obb_t*, vec3, vec3);
void obb_from_max(obb_t*, vec3, vec3);
void obb_clear(obb_t*);
void obb_parse_point(obb_t*, vec3);
//int obb_pick(obb_t*, ...)
#endif

View file

@ -1,5 +1,7 @@
#include "terrain.h"
#define _TOP(A) (__MAX(0, A - CHUNK_SIZE / 2))
#define _HGT_AT(A, X, Y) (A->bmps[0]->pixels[Y][X][_R_] / 10.f)
#define _RWCOL_AT(A, X, Y) (A->bmps[1]->pixels[Y][X])
#define _RCOL_AT(A, X, Y, C) (_RWCOL_AT(A, X, Y)[C])
@ -16,10 +18,11 @@ float _avg_hgt(terrain_t* map, int x, int y) {
terrain_t* terrain_load
(const char* heights, const char* colors,
const color_t* paths, int path_cnt,
int center_x, int center_y)
{
int top_x = __MAX(0, center_x - CHUNK_SIZE / 2),
top_y = __MAX(0, center_y - CHUNK_SIZE / 2);
int top_x = _TOP(center_x),
top_y = _TOP(center_y);
bmp_t* heights_bmp =
bmp_load_chunk(heights, top_x, top_y, CHUNK_SIZE, CHUNK_SIZE);
@ -36,41 +39,57 @@ terrain_t* terrain_load
terrain_t* terrain = malloc(sizeof(terrain_t));
terrain->bmps[0] = heights_bmp;
terrain->bmps[1] = colors_bmp;
terrain->center_x = terrain->center_y = -1;
terrain->top_x = terrain->top_y = -1;
terrain->pick_dist = 20.f;
terrain->pick_depth = 10;
terrain->paths = NULL;
terrain->path_cnt = 0;
if(paths != NULL && path_cnt > 0) {
terrain->paths = malloc(sizeof(color_t) * path_cnt);
memcpy(terrain->paths, paths, sizeof(color_t) * path_cnt);
terrain->path_cnt = path_cnt;
}
terrain_move(terrain, center_x, center_y);
return terrain;
}
void terrain_move(terrain_t* terrain, int center_x, int center_y) {
int new_terrain = terrain->center_x == -1 || terrain->center_y == -1;
int new_terrain =
terrain->top_x == -1
|| terrain->top_y == -1;
terrain->top_x = _TOP(center_x);
terrain->top_y = _TOP(center_y);
if(new_terrain) {
glGenVertexArrays(1, &terrain->vao);
glGenBuffers(TERR_BUFFS, terrain->buffers);
} else {
int top_x = __MAX(0, center_x - CHUNK_SIZE / 2),
top_y = __MAX(0, center_y - CHUNK_SIZE / 2);
bmp_reload_chunk
(terrain->bmps[0], top_x, top_y, CHUNK_SIZE, CHUNK_SIZE);
(terrain->bmps[0], terrain->top_x, terrain->top_y,
CHUNK_SIZE, CHUNK_SIZE);
bmp_reload_chunk
(terrain->bmps[1], top_x, top_y, CHUNK_SIZE, CHUNK_SIZE);
(terrain->bmps[1], terrain->top_x, terrain->top_y,
CHUNK_SIZE, CHUNK_SIZE);
}
terrain->center_x = center_x;
terrain->center_y = center_y;
terrain->width = terrain->bmps[0]->width;
terrain->height = terrain->bmps[0]->height;
const int data_length = 12 * 3 * (CHUNK_SIZE - 1) * (CHUNK_SIZE - 1);
terrain->tri_cnt = data_length / 3;
terrain->tri_cnt = 4 * (terrain->width - 1) * (terrain->height - 1);
float data[data_length];
vec3 dir1, dir2, norm1, norm2, norm3;
vec3 dir1, dir2, norm;
for(int i = 0; i < TERR_BUFFS; ++i) {
int cnt = i == 1 ? 2 : 3;
for(int y = 0; y < CHUNK_SIZE - 1; ++y) {
for(int x = 0; x < CHUNK_SIZE - 1; ++x) {
int at = (y * (CHUNK_SIZE - 1) * 12 * cnt) + (x * 12 * cnt);
for(int y = 0; y < terrain->height - 1; ++y) {
for(int x = 0; x < terrain->width - 1; ++x) {
int at = (y * (terrain->width - 1) * 12 * cnt) + (x * 12 * cnt);
switch(i) {
case 0:
@ -177,11 +196,11 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
(vec3){ x + 1, _HGT_AT(terrain, x + 1, y), y },
dir2
);
glm_vec3_cross(dir1, dir2, norm1);
glm_vec3_normalize(norm1);
memcpy(&data[at], norm1, 3 * sizeof(float));
memcpy(&data[at + 3], norm1, 3 * sizeof(float));
memcpy(&data[at + 6], norm1, 3 * sizeof(float));
glm_vec3_cross(dir1, dir2, norm);
glm_vec3_normalize(norm);
memcpy(&data[at], norm, 3 * sizeof(float));
memcpy(&data[at + 3], norm, 3 * sizeof(float));
memcpy(&data[at + 6], norm, 3 * sizeof(float));
glm_vec3_sub(
(vec3){ x + 1, _HGT_AT(terrain, x + 1, y), y },
@ -193,11 +212,11 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
(vec3){ x + 1, _HGT_AT(terrain, x + 1, y + 1), y + 1 },
dir2
);
glm_vec3_cross(dir1, dir2, norm1);
glm_vec3_normalize(norm1);
memcpy(&data[at + 9], norm1, 3 * sizeof(float));
memcpy(&data[at + 12], norm1, 3 * sizeof(float));
memcpy(&data[at + 15], norm1, 3 * sizeof(float));
glm_vec3_cross(dir1, dir2, norm);
glm_vec3_normalize(norm);
memcpy(&data[at + 9], norm, 3 * sizeof(float));
memcpy(&data[at + 12], norm, 3 * sizeof(float));
memcpy(&data[at + 15], norm, 3 * sizeof(float));
glm_vec3_sub(
(vec3){ x + 1, _HGT_AT(terrain, x + 1, y + 1), y + 1 },
@ -209,11 +228,11 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
(vec3){ x, _HGT_AT(terrain, x, y + 1), y + 1 },
dir2
);
glm_vec3_cross(dir1, dir2, norm1);
glm_vec3_normalize(norm1);
memcpy(&data[at + 18], norm1, 3 * sizeof(float));
memcpy(&data[at + 21], norm1, 3 * sizeof(float));
memcpy(&data[at + 24], norm1, 3 * sizeof(float));
glm_vec3_cross(dir1, dir2, norm);
glm_vec3_normalize(norm);
memcpy(&data[at + 18], norm, 3 * sizeof(float));
memcpy(&data[at + 21], norm, 3 * sizeof(float));
memcpy(&data[at + 24], norm, 3 * sizeof(float));
glm_vec3_sub(
(vec3){ x, _HGT_AT(terrain, x, y), y },
@ -225,11 +244,11 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
(vec3){ x, _HGT_AT(terrain, x, y + 1), y + 1 },
dir2
);
glm_vec3_cross(dir2, dir1, norm1);
glm_vec3_normalize(norm1);
memcpy(&data[at + 27], norm1, 3 * sizeof(float));
memcpy(&data[at + 30], norm1, 3 * sizeof(float));
memcpy(&data[at + 33], norm1, 3 * sizeof(float));
glm_vec3_cross(dir2, dir1, norm);
glm_vec3_normalize(norm);
memcpy(&data[at + 27], norm, 3 * sizeof(float));
memcpy(&data[at + 30], norm, 3 * sizeof(float));
memcpy(&data[at + 33], norm, 3 * sizeof(float));
glm_vec3_add(
data + at + 3,
@ -258,14 +277,14 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
data[at + j * 3 + 2] = _COL_AT(terrain, x, y, _B_);
}
const color_t path_colors[] = {
{0x60, 0x60, 0x60, 0xFF},
{0x9C, 0x00, 0x0E, 0xFF}
};
if(terrain->paths == NULL)
continue;
int found = 0;
for(int j = 0; j < sizeof(path_colors) / sizeof(color_t); ++j) {
if(color_eqp(path_colors[j], _RWCOL_AT(terrain, x, y))) {
for(int j = 0; j < terrain->path_cnt; ++j) {
if(color_eqp(terrain->paths[j],
_RWCOL_AT(terrain, x, y)))
{
found = 1;
break;
}
@ -339,7 +358,7 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
} else {
glBufferSubData(
GL_ARRAY_BUFFER, 0,
data_length * sizeof(float),
terrain->tri_cnt * 3 * 3 * sizeof(float),
data
);
}
@ -348,6 +367,50 @@ void terrain_move(terrain_t* terrain, int center_x, int center_y) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
float terrain_height(terrain_t* terrain, int x, int y) {
x -= terrain->top_x;
y -= terrain->top_y;
if(x < 0 || y < 0 || x >= terrain->width || y >= terrain->height)
return NAN;
return terrain->heights[y][x];
}
void terrain_pick_params(terrain_t* terrain, float distance, int depth) {
terrain->pick_dist = distance;
terrain->pick_depth = depth;
}
int terrain_pick
(terrain_t* terrain, vec3 ray, vec3 camera, vec3 out)
{
int intersect = 0;
float t = terrain->pick_dist / 2.f, delta = t;
for(int i = 0; i < terrain->pick_depth; ++i) {
delta /= 2;
glm_vec3_scale(ray, t, out);
glm_vec3_add(out, camera, out);
float height = terrain_height(terrain, out[0], out[2]);
if(height == NAN)
t = t - delta;
else {
if(height < out[1])
t = t + delta;
else {
intersect = 1;
t = t - delta;
}
out[1] = height;
}
}
return intersect;
}
void terrain_unload(terrain_t* terrain) {
bmp_unload(terrain->bmps[0]);
bmp_unload(terrain->bmps[1]);

View file

@ -14,18 +14,27 @@
#include "koa/file.h"
#define CHUNK_SIZE 100
#define CHUNK_SIZE 20
#define TERR_BUFFS 4
typedef struct {
bmp_t* bmps[2];
int center_x, center_y, tri_cnt;
color_t* paths;
int top_x, top_y, width, height,
tri_cnt, path_cnt;
float heights[CHUNK_SIZE][CHUNK_SIZE];
GLuint buffers[TERR_BUFFS], vao;
float pick_dist;
int pick_depth;
} terrain_t;
terrain_t* terrain_load(const char*, const char*, int, int);
terrain_t* terrain_load
(const char*, const char*, const color_t*, int, int, int);
void terrain_move(terrain_t*, int, int);
float terrain_height(terrain_t*, int, int);
void terrain_pick_params(terrain_t*, float, int);
int terrain_pick(terrain_t*, vec3, vec3, vec3);
void terrain_unload(terrain_t*);
#endif