From: hgn Date: Sat, 10 Feb 2024 20:10:03 +0000 (+0000) Subject: rigidbody view X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=commitdiff_plain;h=1c305409e8eca9cf8449d681df73208956ce14df rigidbody view --- diff --git a/labs/build.c b/labs/build.c new file mode 100644 index 0000000..bb0b343 --- /dev/null +++ b/labs/build.c @@ -0,0 +1,34 @@ +#include "vg/vg_build.h" +#include "vg/vg_build_utils_shader.h" + +void s_lab_physics(void){ + vg_info( "running script: s_lab_physics(void)\n" ); + vg_build.fresh = 0; + vg_build.platform = k_platform_linux; + vg_build.arch = k_architecture_x86_64; + vg_build.compiler = k_compiler_clang; + vg_build.libc = k_libc_version_native; + + vg_build_new( "physics" ); + vg_add_source( "physics.c" ); + vg_add_graphics(); + vg_add_game_stuff(); + vg_compile( "physics" ); + vg_success( "Completed 1/1\n" ); +} + +int main( int argc, char *argv[] ){ + char *arg; + while( vg_argp( argc, argv ) ){ + if( vg_long_opt( "physics" ) ) + s_lab_physics(); + + if( vg_opt('r') ) + vg_build.optimization = 3; + } + + if( vg_build.warnings ) + vg_warn( "Finished with %u warnings\n", vg_build.warnings ); + else + vg_success( "All scripts ran successfully\n" ); +} diff --git a/labs/build.sh b/labs/build.sh new file mode 100755 index 0000000..d807648 --- /dev/null +++ b/labs/build.sh @@ -0,0 +1 @@ +clang -fsanitize=address -O0 -I./vg build.c -o /tmp/tmpsr && /tmp/tmpsr $@ diff --git a/labs/physics.c b/labs/physics.c new file mode 100644 index 0000000..e741f12 --- /dev/null +++ b/labs/physics.c @@ -0,0 +1,105 @@ +#define VG_GAME +#define VG_AUDIO_FORCE_COMPRESSED +#define VG_3D +#define VG_LOG_SOURCE_INFO +#define VG_TIMESTEP_FIXED (1.0/60.0) + +#ifndef VG_RELEASE + #define VG_DEVWINDOW +#endif + +#define SDL_MAIN_HANDLED + +#include "vg/vg.h" +#include "vg/vg_camera.h" + +int main( int argc, char *argv[] ){ + vg_mem.use_libc_malloc = 0; + vg_set_mem_quota( 80*1024*1024 ); + vg_enter( argc, argv, "Voyager Game Engine" ); + return 0; +} + +static void vg_launch_opt(void){ + const char *arg; +} + +static void vg_preload(void){ + vg_audio.dsp_enabled = 0; +} + +static void vg_load(void){ + vg_bake_shaders(); +} + +static void vg_pre_update(void){ +} + +static void vg_fixed_update(void){ +} + +static void vg_post_update(void){ +} + +static void vg_framebuffer_resize( int w, int h ){ +} + +static void draw_origin_axis(void){ + vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 ); + vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 ); + vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff ); +} + +static void vg_render(void){ + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + glViewport( 0,0, vg.window_x, vg.window_y ); + glEnable( GL_DEPTH_TEST ); + glDisable( GL_BLEND ); + + glClearColor( 0.05f, 0.05f, 0.05f, 1.0f ); + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + + f32 x = -((f32)vg.mouse_pos[0] / (f32)vg.window_x) * VG_TAUf, + y = (((f32)vg.mouse_pos[1] / (f32)vg.window_y) - 0.5f)*VG_PIf; + + f32 t = vg.time * 0.1f * VG_TAUf; + + vg_camera cam = { + .angles = { -x, y, 0 }, + .nearz = 0.01f, + .farz = 500.0f, + .fov = 90.0f, + .pos = { sinf(x)*10.0f*cosf(y), + sinf(y)*10.0f, + cosf(x)*10.0f*cosf(y) }, + }; + + vg_camera_update_transform( &cam ); + vg_camera_update_view( &cam ); + vg_camera_update_projection( &cam ); + vg_camera_finalize( &cam ); + m4x4_copy( cam.mtx.pv, vg.pv ); + + m4x3f mdl; + m4x3_identity( mdl ); + + vg_rb_view_bind(); + vg_rb_view_capsule( mdl, (sinf(t*0.2f)*0.5f+0.55f)*2.0f, + (sinf(t*0.33f)*0.5f+0.55f)*1.0f, + (v4f){1,0,0,1} ); + vg_rb_view_box( mdl, (boxf){{-4.999,-2.001,-4.999},{4.999,-0.999,4.999}}, + (v4f){0.8f,0.8f,0.8f,1} ); + + mdl[3][0] = sinf(t)*2.0f; + mdl[3][2] = cosf(t)*2.0f; + vg_rb_view_sphere( mdl, 1, (v4f){0,1,0,1} ); + + draw_origin_axis(); + vg_lines_drawall(); + + glDisable(GL_DEPTH_TEST); +} + +static void vg_gui(void){ + vg_ui.wants_mouse = 1; +} diff --git a/labs/vg b/labs/vg new file mode 120000 index 0000000..a96aa0e --- /dev/null +++ b/labs/vg @@ -0,0 +1 @@ +.. \ No newline at end of file diff --git a/projects/encode.c b/projects/encode.c deleted file mode 100644 index 8298bc8..0000000 --- a/projects/encode.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "../vg_platform.h" - - -struct yo -{ - float a, b, c, d; -}; - -int main( int argc, const char *argv[] ) -{ - struct yo yo = { 300.324, 2023.334, -324.1232, 30.494 }; - printf( "{%f %f %f %f}\n", yo.a, yo.b, yo.c, yo.d ); - - char text[ sizeof(yo)*2 ]; - vg_bin_str( &yo, text, sizeof(yo) ); - - printf( "encoded: %.*s\n", (int)(sizeof(yo)*2), text ); - - vg_str_bin( text, &yo, sizeof(yo)*2 ); - - printf( "{%f %f %f %f}\n", yo.a, yo.b, yo.c, yo.d ); -} diff --git a/projects/struct b/projects/struct deleted file mode 100755 index 34d1298..0000000 Binary files a/projects/struct and /dev/null differ diff --git a/vg.h b/vg.h index 987ed73..5237792 100644 --- a/vg.h +++ b/vg.h @@ -258,6 +258,7 @@ static void vg_checkgl( const char *src_info ); #include "vg_input.h" #include "vg_imgui.h" #include "vg_lines.h" +#include "vg_rigidbody_view.h" #include "vg_loader.h" #include "vg_opt.h" #include "vg_settings_menu.h" @@ -316,6 +317,7 @@ static void _vg_load_full( void *data ){ /* internal */ vg_loader_step( vg_input_init, vg_input_free ); vg_loader_step( vg_lines_init, NULL ); + vg_loader_step( vg_rb_view_init, NULL ); #ifndef VG_NO_AUDIO vg_loader_step( vg_audio_init, vg_audio_free ); #endif @@ -427,12 +429,12 @@ static void _vg_gameloop_update(void) vg.engine_stage = k_engine_stage_update_fixed; vg.fixed_iterations = 0; - vg_lines.allow_input = 1; + vg_lines.enabled = vg_lines.render; vg.time_fixed_accumulator += vg.time_delta; while( vg.time_fixed_accumulator >= VG_TIMESTEP_FIXED ){ vg_fixed_update(); - vg_lines.allow_input = 0; + vg_lines.enabled = 0; vg.time_fixed_accumulator -= VG_TIMESTEP_FIXED; vg.fixed_iterations ++; @@ -440,7 +442,7 @@ static void _vg_gameloop_update(void) break; } } - vg_lines.allow_input = 1; + vg_lines.enabled = vg_lines.render; vg.time_fixed_extrapolate = vg.time_fixed_accumulator / VG_TIMESTEP_FIXED; vg.engine_stage = k_engine_stage_update; diff --git a/vg_build.h b/vg_build.h index 965f14c..a30fe17 100644 --- a/vg_build.h +++ b/vg_build.h @@ -5,6 +5,8 @@ #include #include +#include "vg.h" +#include "vg_opt.h" #include "vg_log.h" /* we dont free dynamic vg_strs in this program. so, we dont care.. */ @@ -21,7 +23,8 @@ struct { u32 optimization, warnings; bool fresh, - debug_asan; + debug_asan, + build_times; enum platform { k_platform_anyplatform, diff --git a/vg_camera.h b/vg_camera.h new file mode 100644 index 0000000..9fd660b --- /dev/null +++ b/vg_camera.h @@ -0,0 +1,91 @@ +#pragma once +#include "vg_m.h" + +typedef struct vg_camera vg_camera; +struct vg_camera{ + /* Input */ + v3f angles; + v3f pos; + f32 fov, nearz, farz; + + /* Output */ + m4x3f transform, + transform_inverse; + + struct vg_camera_mtx{ + m4x4f p, + v, + pv; + } + mtx, + mtx_prev; +}; + +static void vg_camera_lerp_angles( v3f a, v3f b, f32 t, v3f d ){ + d[0] = vg_alerpf( a[0], b[0], t ); + d[1] = vg_lerpf( a[1], b[1], t ); + d[2] = vg_lerpf( a[2], b[2], t ); +} + +/* lerp position, fov, and angles */ +static void vg_camera_lerp( vg_camera *a, vg_camera *b, f32 t, vg_camera *d ){ + v3_lerp( a->pos, b->pos, t, d->pos ); + vg_camera_lerp_angles( a->angles, b->angles, t, d->angles ); + d->fov = vg_lerpf( a->fov, b->fov, t ); +} + +static void vg_camera_copy( vg_camera *a, vg_camera *d ){ + v3_copy( a->pos, d->pos ); + v3_copy( a->angles, d->angles ); + d->fov = a->fov; +} + +static void vg_m4x3_transform_camera( m4x3f m, vg_camera *cam ){ + m4x3_mulv( m, cam->pos, cam->pos ); + + v3f v0; + v3_angles_vector( cam->angles, v0 ); + m3x3_mulv( m, v0, v0 ); + v3_normalize( v0 ); + v3_angles( v0, cam->angles ); +} + +/* + * 1) [angles, pos] -> transform + */ +static void vg_camera_update_transform( vg_camera *cam ){ + v4f qyaw, qpitch, qcam; + q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -cam->angles[0] ); + q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -cam->angles[1] ); + + q_mul( qyaw, qpitch, qcam ); + q_m3x3( qcam, cam->transform ); + v3_copy( cam->pos, cam->transform[3] ); +} + +/* + * 2) [transform] -> transform_inverse, view matrix + */ +static void vg_camera_update_view( vg_camera *cam ){ + m4x4_copy( cam->mtx.v, cam->mtx_prev.v ); + m4x3_invert_affine( cam->transform, cam->transform_inverse ); + m4x3_expand( cam->transform_inverse, cam->mtx.v ); +} + +/* + * 3) [fov,nearz,farz] -> projection matrix + */ +static void vg_camera_update_projection( vg_camera *cam ){ + m4x4_copy( cam->mtx.p, cam->mtx_prev.p ); + m4x4_projection( cam->mtx.p, cam->fov, + (float)vg.window_x / (float)vg.window_y, + cam->nearz, cam->farz ); +} + +/* + * 4) [projection matrix, view matrix] -> previous pv, new pv + */ +static void vg_camera_finalize( vg_camera *cam ){ + m4x4_copy( cam->mtx.pv, cam->mtx_prev.pv ); + m4x4_mul( cam->mtx.p, cam->mtx.v, cam->mtx.pv ); +} diff --git a/vg_lines.h b/vg_lines.h index 5511875..8fff226 100644 --- a/vg_lines.h +++ b/vg_lines.h @@ -59,8 +59,8 @@ static struct vg_shader _shader_lines = { }; struct{ - u32 draw, - allow_input; + u32 enabled, + render; struct vg_lines_vert{ v3f co; @@ -106,7 +106,6 @@ static void async_vg_lines_init( void *payload, u32 payload_size ){ glEnableVertexAttribArray( 1 ); VG_CHECK_GL_ERR(); - vg_lines.allow_input = 1; } static void vg_lines_init(void){ @@ -116,7 +115,7 @@ static void vg_lines_init(void){ vg_async_call( async_vg_lines_init, NULL, 0 ); - vg_console_reg_var( "vg_lines", &vg_lines.draw, k_var_dtype_i32, + vg_console_reg_var( "vg_lines", &vg_lines.render, k_var_dtype_i32, VG_VAR_CHEAT ); vg_shader_register( &_shader_lines ); } @@ -131,14 +130,13 @@ static void vg_lines_drawall( void ){ glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo ); u32 bufusage = vg_linear_get_cur(vg_lines.vertex_buffer); - glBufferSubData( GL_ARRAY_BUFFER, 0, bufusage, vg_lines.vertex_buffer ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBlendEquation( GL_FUNC_ADD ); - if( vg_lines.draw ) + if( vg_lines.render ) glDrawArrays( GL_LINES, 0, bufusage / sizeof(struct vg_lines_vert) ); glDisable( GL_BLEND ); @@ -146,8 +144,7 @@ static void vg_lines_drawall( void ){ } static void vg_line2( line_co from, line_co to, u32 fc, u32 tc ){ - if( !vg_lines.allow_input ) return; - if( !vg_lines.draw ) return; + if( !vg_lines.enabled ) return; u32 size = 2 * sizeof(struct vg_lines_vert); struct vg_lines_vert *v = vg_linear_alloc( vg_lines.vertex_buffer, size ); @@ -160,10 +157,14 @@ static void vg_line2( line_co from, line_co to, u32 fc, u32 tc ){ } static void vg_line( line_co from, line_co to, u32 colour ){ + if( !vg_lines.enabled ) return; + vg_line2( from, to, colour, colour ); } static void vg_line_arrow( line_co co, line_co dir, float size, u32 colour ){ + if( !vg_lines.enabled ) return; + v3f p1, tx, ty, p2, p3; v3_muladds( co, dir, size, p1 ); v3_tangent_basis( dir, tx, ty ); @@ -178,6 +179,8 @@ static void vg_line_arrow( line_co co, line_co dir, float size, u32 colour ){ } static void vg_line_box_verts( boxf box, v3f verts[8] ){ + if( !vg_lines.enabled ) return; + for( u32 i=0; i<8; i++ ){ for( u32 j=0; j<3; j++ ){ verts[i][j] = i&(0x1<verts_size, inf->verts, GL_STATIC_DRAW ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_rb_view.ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, + inf->tris_size, inf->tris, GL_STATIC_DRAW ); + + /* 0: coordinates */ + size_t stride = sizeof(rb_view_vert); + glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, (void*)0 ); + glEnableVertexAttribArray( 0 ); + + /* 1: normal */ + glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, + stride, (void *)offsetof(rb_view_vert, n) ); + glEnableVertexAttribArray( 1 ); + + VG_CHECK_GL_ERR(); +} + +static void vg_rb_view_init(void){ + vg_shader_register( &_shader_rigidbody ); + + u32 H = 20, + V = 16, + verts_count = 0, + tris_count = 0; + + /* box */ + verts_count += 4*6; + tris_count += 2*6; + vg_rb_view.box_count = 2*6; + vg_rb_view.box_start = 0; + + /* sphere */ + verts_count += H*(V-2) + 2; + tris_count += H*2 + (V-2)*(H*2); + vg_rb_view.sphere_count = H*2 + (V-2)*(H*2); + + u32 hdr_size = vg_align8( sizeof(struct vg_rb_mesh_init) ), + vert_size = vg_align8( verts_count * sizeof(rb_view_vert) ), + tris_size = vg_align8( tris_count * 3 * sizeof(u16) ); + + vg_async_item *call = vg_async_alloc( hdr_size + vert_size + tris_size ); + + struct vg_rb_mesh_init *inf = call->payload; + rb_view_vert *verts = ((void *)inf) + hdr_size; + u16 *tris = ((void *)inf) + hdr_size + vert_size; + + inf->verts = verts; + inf->tris = tris; + inf->verts_size = vert_size; + inf->tris_size = tris_size; + + u32 tri_index = 0, + vert_index = 0; + + /* box + * ----------------------------------------------------------- */ + for( u32 i=0; i<6; i ++ ){ + v3f n = {i%3==0,i%3==1,i%3==2}; + if( i >= 3 ) v3_negate( n, n ); + v3f v0, v1; + v3_tangent_basis( n, v0, v1 ); + + rb_view_vert *vs = &verts[vert_index]; + vert_index += 4; + + for( u32 j=0; j<4; j ++ ){ + v3_copy( n, vs[j].n ); + v3_muladds( n, v0, j&0x1?1.0f:-1.0f, vs[j].co ); + v3_muladds( vs[j].co, v1, j&0x2?1.0f:-1.0f, vs[j].co ); + vs[j].co[3] = 0.0f; + } + + tris[tri_index*3+0] = i*4+0; + tris[tri_index*3+1] = i*4+1; + tris[tri_index*3+2] = i*4+3; + tris[tri_index*3+3] = i*4+0; + tris[tri_index*3+4] = i*4+3; + tris[tri_index*3+5] = i*4+2; + tri_index += 2; + } + + /* sphere / capsule + * ----------------------------------------------------------- */ + u32 base = vert_index; + vg_rb_view.sphere_start = tri_index; + v4_copy( (v4f){0,-1,0,0}, verts[vert_index].co ); + v3_copy( (v3f){0,-1,0}, verts[vert_index ++].n ); + + for( u32 x=0; x=(V/2) }; + v4_copy( co, verts[vert_index].co ); + v4_copy( co, verts[vert_index ++].n ); + + if( y < V-2 ){ + tris[tri_index*3+0] = base+1 + ybase*H + x; + tris[tri_index*3+1] = base+1 + (ybase+1)*H + ((x+1)%H); + tris[tri_index*3+2] = base+1 + ybase*H + ((x+1)%H); + tris[tri_index*3+3] = base+1 + ybase*H + x; + tris[tri_index*3+4] = base+1 + (ybase+1)*H + x; + tris[tri_index*3+5] = base+1 + (ybase+1)*H + ((x+1)%H); + tri_index += 2; + } + } + } + + v4_copy( (v4f){0, 1,0,1}, verts[vert_index].co ); + v3_copy( (v3f){0, 1,0}, verts[vert_index ++].n ); + + for( u32 x=0; x