diff --git a/MAKE.bat b/MAKE.bat index 02d9a6e..14b7cc5 100644 --- a/MAKE.bat +++ b/MAKE.bat @@ -75,6 +75,13 @@ if "%1"=="cook" ( exit /b ) +if "%1"=="build_cook" ( + pushd tools + cl cook.c -I..\engine /openmp /Os /Ox /O2 /Oy /MT /DNDEBUG /GL /GF /Gw /arch:AVX2 /link /OPT:ICF /LTCG + popd + + exit /b +) rem generate bindings if "%1"=="bind" ( rem luajit @@ -324,7 +331,7 @@ if "%1"=="fwk_prep" ( xcopy /y "engine\split\3rd_*" "_fwk\engine\split" xcopy /y "engine\art\shaders\*" "_fwk\engine\art\shaders" xcopy /y "demos" "_fwk\demos" - xcopy /y "engine\editor.c" "_fwk\engine\editor.c" + copy /y "engine\editor.c" "_fwk\engine\editor.c" rem xcopy /y/E "tools "_fwk\tools" for %%f in ("engine\split\v4k*") do ( set "filename=%%~nf" @@ -371,6 +378,7 @@ if "%1"=="back" ( xcopy /y "_fwk" "." xcopy /y "_fwk\engine\split\3rd_*" "engine\split" xcopy /y "_fwk\engine\art\shaders\*" "engine\art\shaders" + del "demos\*.c" xcopy /y "_fwk\demos" "demos" xcopy /y "_fwk\engine\editor.c" "engine\editor.c" tools\fwkren.exe "engine\editor.c" to diff --git a/demos/00-hello.c b/demos/00-loop.c similarity index 98% rename from demos/00-hello.c rename to demos/00-loop.c index 7ff2a88..5ae1497 100644 --- a/demos/00-hello.c +++ b/demos/00-loop.c @@ -1,6 +1,8 @@ #include "v4k.h" // Minimal C sample + int main() { window_create(75.0, 0); // 75% size, no extra flags + while( window_swap() && !input(KEY_ESC) ) { // game loop puts("hello V4K from C!"); } diff --git a/demos/00-ui.c b/demos/00-ui.c deleted file mode 100644 index 7035670..0000000 --- a/demos/00-ui.c +++ /dev/null @@ -1,86 +0,0 @@ -// hello ui: config, window, system, ui, video -// - rlyeh, public domain. -// -// Compile with: -// `make demos\01-ui.c` (windows) -// `sh MAKE.bat demos/01-ui.c` (linux, osx) - -#include "v4k.h" - -int main() { - float app_volume = 1.00f; - unsigned app_size = flag("--fullscreen") ? 100 : 75; - unsigned app_flags = flag("--msaa") ? WINDOW_MSAA4 : 0; - unsigned app_target_fps = optioni("--fps", 60); // --fps=30, --fps=45, etc. defaults to 60. - - // window api (fullscreen or 75% sized, optional MSAA flags) - window_create(app_size, app_flags); - window_title(__FILE__); - window_fps_lock(app_target_fps); - - // load video - video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB | VIDEO_LOOP ); - - // app loop - while( window_swap() ) { - // input controls - if( input(KEY_ESC) ) break; - - // profile api - texture_t *textures; - profile( "Video decoder" ) { - // video api: decode frame and get associated textures (audio is sent to audiomixer automatically) - textures = video_decode( v ); - // fullscreen video - // if(video_is_rgb(v)) fullscreen_quad_rgb( textures[0], 1.3f ); - // else fullscreen_quad_ycbcr( textures, 1.3f ); - } - - // create menubar on top - int choice1 = ui_menu("File;Shell;Exit"); - int choice2 = ui_menu("Help;About"); - if( choice1 == 1 ) system(ifdef(win32, "start \"\" cmd", ifdef(osx, "open sh", "xdg-open sh"))); - if( choice1 == 2 ) exit(0); - - // showcase a few ui widgets - ui_demo(0); - - // create ui panel - if( ui_panel("myPanel", PANEL_OPEN) ) { - // Print some numbers - ui_section("Stats"); - ui_label2("FPS", va("%5.2f", window_fps())); - ui_separator(); - - // add some buttons - ui_section("Buttons"); - if( ui_button("Screenshot") ) window_screenshot(__FILE__ ".png"), ui_notify(0,ICON_MD_WARNING "Screenshot"); - if( ui_button("Record Video") ) window_record(__FILE__ ".mp4"), ui_notify(0,ICON_MD_WARNING "Recoding video"); - if( ui_button("Toggle fullscreen") ) window_fullscreen( !window_has_fullscreen() ); - ui_separator(); - - // some more video controls - ui_section("Video"); - if( ui_button("Rewind") ) video_seek(v, video_position(v) - 3); - if( ui_button("Pause") ) video_pause(v, video_is_paused(v) ^ 1); - if( ui_button("Forward") ) video_seek(v, video_position(v) + 3); - if( ui_slider2("Volume", &app_volume, va("%.2f", app_volume))) audio_volume_master(app_volume); - - // end of panel. must be enclosed within same if() branch. - ui_panel_end(); - } - - // create window - static int open = 1; - if( ui_window("myWindow", &open) ) { - // present decoded texture in a widget, without any label (NULL) - ui_texture( NULL, textures[0] ); - // end of window. must be enclosed within same if() branch. - ui_window_end(); - } - } -} - -// this demo supersedes following old sources: -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-hello.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-video.c diff --git a/demos/01-sprite.c b/demos/01-sprite.c deleted file mode 100644 index 4e65c4d..0000000 --- a/demos/01-sprite.c +++ /dev/null @@ -1,218 +0,0 @@ -// sprite routines -// - rlyeh, -// -// credits: original lovely demo by rxi (MIT License). -// see https://github.com/rxi/autobatch/tree/master/demo/cats - -#include "v4k.h" - -texture_t kids, catImage, shadowImage, inputs; -int NUM_SPRITES = 100, NUM_SPRITES_CHANGED = 1; - -typedef struct Cat { - int cat, flip; - double x, y; - double vx, vy; - double animSpeed; - double moveTimer; - double elapsed; -} Cat; - -void demo_cats() { - static array(Cat) cats = 0; - - // init - if( NUM_SPRITES_CHANGED ) { - NUM_SPRITES_CHANGED = 0; - - array_resize(cats, NUM_SPRITES); int i = 0; - for each_array_ptr(cats, Cat, c) { - randset(i++); - c->x = randf() * window_width(); - c->y = randf() * window_height(); - c->vx = c->vy = 0; - c->cat = randi(0, 4); - c->flip = randf() < 0.5; - c->animSpeed = 0.8 + randf() * 0.3; - c->moveTimer = 0; - c->elapsed = 0; - } - } - - // move - const float dt = 1/120.f; - const int appw = window_width(), apph = window_height(); - - enum { yscale = 1 }; - for( int i = 0; i < NUM_SPRITES; ++i ) { - Cat *c = &cats[i]; - // Add velocity to position //and wrap to screen - c->x += yscale * c->vx * dt; // % ; - c->y += yscale * c->vy * dt; // % (int)window_height(); - if( c->x < 0 ) c->x += appw; else if( c->x > appw ) c->x -= appw; - if( c->y < 0 ) c->y += apph; else if( c->y > apph ) c->y -= apph; - // Faster animation if walking - int boost = c->vx == 0 && c->vy == 0 ? 1 : 3; - // Update elapsed time - c->elapsed += dt * boost; - // Update move timer -- if we hit zero then change or zero velocity - c->moveTimer -= dt * boost; - if (c->moveTimer < 0) { - if (randf() < .2) { - c->vx = (randf() * 2 - 1) * 30 * 2; - c->vy = (randf() * 2 - 1) * 15 * 2; - c->flip = c->vx < 0; - } else { - c->vx = c->vy = 0; - } - c->moveTimer = 1 + randf() * 5; - } - } - - // render - uint32_t white = rgba(255,255,255,255); - uint32_t alpha = rgba(255,255,255,255*0.6); - for( int i = 0; i < NUM_SPRITES; ++i ) { - Cat *c = &cats[i]; - // Get current animation frame (8x4 tilesheet) - double e = c->elapsed * c->animSpeed; - double frame_num = c->cat * 8 + floor( ((int)(e * 8)) % 4 ); - frame_num = c->vx != 0 || c->vy != 0 ? frame_num + 4 : frame_num; - // Get x scale based on flip flag - int xscale = yscale * (c->flip ? -1 : 1); - // Draw - float angle = 0; //fmod(window_time()*360/5, 360); - float scale[2] = { 2*xscale, 2*yscale }; - float position[3] = { c->x,c->y,c->y }, no_offset[2] = {0,0}, spritesheet[3] = { frame_num,8,4 }; - sprite_sheet(catImage, - spritesheet, // frame_number in a 8x4 spritesheet - position, angle, // position(x,y,depth: sort by Y), angle - no_offset, scale, // offset(x,y), scale(x,y) - 0,white,0 // is_additive, tint color, resolution independant - ); - float position_neg_sort[3] = { c->x,c->y,-c->y }, offset[2] = {-1,5}, no_spritesheet[3] = {0,0,0}; - sprite_sheet(shadowImage, - no_spritesheet, // no frame_number (0x0 spritesheet) - position_neg_sort, angle, // position(x,y,depth: sort by Y), angle - offset, scale, // offset(x,y), scale(x,y) - 0,alpha,0 // is_additive, tint color, resolution independant - ); - } -} - -void demo_kids() { - static int angle; //++angle; - static int *x, *y, *v; - - // init - if( NUM_SPRITES_CHANGED ) { - NUM_SPRITES_CHANGED = 0; - - y = (int*)REALLOC(y, 0 ); - x = (int*)REALLOC(x, NUM_SPRITES * sizeof(int) ); - y = (int*)REALLOC(y, NUM_SPRITES * sizeof(int) ); - v = (int*)REALLOC(v, NUM_SPRITES * sizeof(int) ); - for( int i = 0; i < NUM_SPRITES; ++i ) { - randset(i); - x[i] = randi(0, window_width()); - y[i] = randi(0, window_height()); - v[i] = randi(1, 3); - } - } - - // config - const int appw = window_width(), apph = window_height(); - - // move & render - for( int i = 0; i < NUM_SPRITES; ++i ) { - y[i] = (y[i] + v[i]) % (apph + 128); - int col = ((x[i] / 10) % 4); // 4x4 tilesheet - int row = ((y[i] / 10) % 4); - int num_frame = col * 4 + row; - float position[3] = {x[i],y[i],y[i]}, offset[2]={0,0}, scale[2]={1,1}, spritesheet[3]={num_frame,4,4}; - sprite_sheet(kids, - spritesheet, // num_frame in a 4x4 spritesheet - position, angle, // position(x,y,depth: sort by Y), angle - offset, scale, // offset(x,y), scale(x,y) - 0, ~0u, 0 // is_additive, tint color, resolution independant - ); - } -} - -int main(int argc, char **argv) { - window_create(75.f, 0); - window_title("V4K - Sprite"); - window_color( SILVER ); - - // options - int do_cats = 1; - NUM_SPRITES = optioni("--num_sprites,-N", NUM_SPRITES); - if(do_cats) NUM_SPRITES/=2; // cat-sprite+cat-shadow == 2 sprites - - // load sprites and sheets - kids = texture( "spriteSheetExample.png", TEXTURE_LINEAR ); - catImage = texture( "cat.png", TEXTURE_LINEAR ); // - shadowImage = texture( "cat-shadow.png", TEXTURE_LINEAR ); - inputs = texture( "prompts_tilemap_34x24_16x16x1.png", TEXTURE_LINEAR ); - - // load all fx files, including subdirs - fx_load("fx**.fs"); - - // init camera (x,y) (z = zoom) - camera_t cam = camera(); - cam.position = vec3(window_width()/2,window_height()/2,1); - camera_enable(&cam); - - while(window_swap()) { - if( input(KEY_F5)) window_reload(); - if( input(KEY_F11)) window_fullscreen( window_has_fullscreen() ^ 1); - if( input(KEY_ESC) ) break; - - // camera panning (x,y) & zooming (z) - if( !ui_hover() && !ui_active() ) { - if( input(MOUSE_L) ) cam.position.x -= input_diff(MOUSE_X); - if( input(MOUSE_L) ) cam.position.y -= input_diff(MOUSE_Y); - cam.position.z += input_diff(MOUSE_W) * 0.1; // cam.p.z += 0.001f; for tests - } - - // apply post-fxs from here - fx_begin(); - - profile("Sprite batching") { - if(do_cats) demo_cats(); else demo_kids(); - } - - // flush retained renderer, so we ensure the fbos are up to date before fx_end() - profile("Sprite flushing") { - sprite_flush(); - } - - // post-fxs end here - fx_end(); - - // draw pixel-art hud, 16x16 ui element, scaled and positioned in resolution-independant way - { - vec3 old_pos = camera_get_active()->position; - - sprite_flush(); - camera_get_active()->position = vec3(window_width()/2,window_height()/2,1); - - float zindex = window_height(); // large number, on top - float spritesheet[3] = {17,34,24}, offset[2] = {0, - 2*absf(sin(window_time()*5))}; // sprite cell and animation - float scale[2] = {3, 3}, tile_w = 16 * scale[0], tile_h = 16 * scale[1]; // scaling - float position[3] = {window_width() - tile_w, window_height() - tile_h, zindex }; // position in screen-coordinates - sprite_sheet(inputs, spritesheet, position, 0/*rotation*/, offset, scale, false/*is_additive*/, WHITE/*color*/, false/*resolution_independant*/); - - sprite_flush(); - camera_get_active()->position = old_pos; - } - - if( ui_panel("Sprite", 0) ) { - const char *labels[] = {"Kids","Cats"}; - if( ui_list("Sprite type", labels, countof(labels), &do_cats) ) NUM_SPRITES_CHANGED = 1; - if( ui_int("Number of Sprites", &NUM_SPRITES) ) NUM_SPRITES_CHANGED = 1; - if( ui_clampf("Zoom", &cam.position.z, 0.1, 10)); - ui_panel_end(); - } - } -} diff --git a/demos/04-lod.c b/demos/04-lod.c deleted file mode 100644 index 99bfe91..0000000 --- a/demos/04-lod.c +++ /dev/null @@ -1,234 +0,0 @@ -// LOD demo, based on Polygon Reduction Demo by Stan Melax (PD) -// - rlyeh, public domain. - -#include "v4k.h" - -vec2 world2screen(vec3 p) { - vec4 clip_pos = transform444(camera_get_active()->proj, transform444(camera_get_active()->view, vec4(p.x,p.y,p.z,1.0))); - vec4 ndc_pos = scale4(clip_pos, 1.0 / (clip_pos.w + !clip_pos.w)); // [-1..1] - vec2 screen_pos = vec2( window_width() * (ndc_pos.x + 1) / 2.0, window_height() * (1 - ndc_pos.y) / 2.0 ); - return screen_pos; -} - -float mesh_area(mesh_t *m) { - // @fixme: return 0 if mesh is out of frustum, or window is minimized - - aabb box = mesh_bounds(m); - ddraw_aabb(box.min, box.max); - - vec2 A = world2screen(vec3(box.min.x,box.min.y,box.min.z)); ddraw_text2d(A, va("A: %5.2f,%5.2f", A.x, A.y)); - vec2 B = world2screen(vec3(box.min.x,box.min.y,box.max.z)); ddraw_text2d(B, va("B: %5.2f,%5.2f", B.x, B.y)); - vec2 C = world2screen(vec3(box.min.x,box.max.y,box.min.z)); ddraw_text2d(C, va("C: %5.2f,%5.2f", C.x, C.y)); - vec2 D = world2screen(vec3(box.min.x,box.max.y,box.max.z)); ddraw_text2d(D, va("D: %5.2f,%5.2f", D.x, D.y)); - vec2 E = world2screen(vec3(box.max.x,box.min.y,box.min.z)); ddraw_text2d(E, va("E: %5.2f,%5.2f", E.x, E.y)); - vec2 F = world2screen(vec3(box.max.x,box.min.y,box.max.z)); ddraw_text2d(F, va("F: %5.2f,%5.2f", F.x, F.y)); - vec2 G = world2screen(vec3(box.max.x,box.max.y,box.min.z)); ddraw_text2d(G, va("G: %5.2f,%5.2f", G.x, G.y)); - vec2 H = world2screen(vec3(box.max.x,box.max.y,box.max.z)); ddraw_text2d(H, va("H: %5.2f,%5.2f", H.x, H.y)); - - vec2 O = min2(min2(min2(min2(min2(min2(min2(A,B),C),D),E),F),G),H); ddraw_text2d(O, "|\\"); - vec2 P = max2(max2(max2(max2(max2(max2(max2(A,B),C),D),E),F),G),H); ddraw_text2d(P, "\\|"); - - float area = (P.x-O.x) * (P.y-O.y); // len2(sub2(P,O)); - float pct = area / (float)(window_height() * window_width()); - - font_print(va(FONT_RIGHT "area: %5.2f%%", pct*100)); - return pct; -} - - -API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation); - -// Map() -// -// Note that the use of the Map() function and the collapse_map Array isn't part of the polygon reduction -// algorithm. We set up the function here so that we could retrieve the model at any desired vertex count. -// -// When the model is rendered using a maximum of mx vertices then it is vertices 0 through mx-1 that are used. -// We are able to do this because the vertex Array gets sorted according to the collapse order. -// The Map() routine takes a vertex number 'n' and the maximum number of vertices 'mx' and returns the -// appropriate vertex in the range 0 to mx-1. When 'n' is greater than 'mx' the Map() routine follows the -// chain of edge collapses until a vertex within the limit is reached. -// An example to make this clear: assume there is a triangle with vertices 1, 3 and 12. But when -// rendering the model we limit ourselves to 10 vertices. In that case we find out how vertex 12 was -// removed by the polygon reduction algorithm. i.e. which edge was collapsed. Lets say that vertex 12 was -// collapsed to vertex number 7. This number would have been stored in the collapse_map array (i.e. -// collapse_map[12]==7). Since vertex 7 is in range (less than max of 10) we will want to render the -// triangle 1,3,7. Pretend now that we want to limit ourselves to 5 vertices. and vertex 7 was collapsed -// to vertex 3 (i.e. collapse_map[7]==3). Then triangle 1,3,12 would now be triangle 1,3,3. i.e. this -// polygon was removed by the progressive mesh polygon reduction algorithm by the time it had gotten down -// to 5 vertices. No need to draw a one dimensional polygon. :-) - -static inline int MapReduce(array(int) collapse_map, int n, int mx) { - while( n >= mx ) n = collapse_map[n]; - return n; -} - -mesh_t *ReduceModel(mesh_t *m, float lo_detail, float hi_detail, float morph) { - int max_verts_to_render = hi_detail * array_count(m->in_vertex3); - int min_verts_to_render = lo_detail * array_count(m->in_vertex3); - - if( max_verts_to_render <= 0 || min_verts_to_render <= 0 ) - return m; - - array_resize(m->out_index3, 0); - array_resize(m->out_vertex3, 0); - - ASSERT(array_count(m->lod_collapse_map)); - for( unsigned int i = 0; i < array_count(m->in_index3); i++ ) { - int p0 = MapReduce(m->lod_collapse_map, m->in_index3[i].x, max_verts_to_render); - int p1 = MapReduce(m->lod_collapse_map, m->in_index3[i].y, max_verts_to_render); - int p2 = MapReduce(m->lod_collapse_map, m->in_index3[i].z, max_verts_to_render); - // @fixme: serious optimization opportunity here, - // by sorting the triangles the following "continue" - // could have been made into a "break" statement. - if(p0==p1 || p0==p2 || p1==p2) continue; - // if we are not currenly morphing between 2 levels of detail - // (i.e. if morph=1.0) then q0,q1, and q2 may not be necessary - int q0 = MapReduce(m->lod_collapse_map, p0, min_verts_to_render); - int q1 = MapReduce(m->lod_collapse_map, p1, min_verts_to_render); - int q2 = MapReduce(m->lod_collapse_map, p2, min_verts_to_render); - vec3 v0, v1, v2; - v0 = mix3(m->in_vertex3[p0], m->in_vertex3[q0], (1-morph)); - v1 = mix3(m->in_vertex3[p1], m->in_vertex3[q1], (1-morph)); - v2 = mix3(m->in_vertex3[p2], m->in_vertex3[q2], (1-morph)); - vec3 normal = norm3(cross3(sub3(v1,v0),sub3(v2,v1))); - array_push(m->out_vertex3, v0); - array_push(m->out_vertex3, normal); - array_push(m->out_vertex3, v1); - array_push(m->out_vertex3, normal); - array_push(m->out_vertex3, v2); - array_push(m->out_vertex3, normal); - - int idx = array_count(m->out_vertex3) / 2; - array_push(m->out_index3, vec3i(idx-3,idx-2,idx-1)); - } - - return m; -} - -void DrawModel(mesh_t *m) { - static mat44 M; do_once id44(M); - static mat44 VP; multiply44x2(VP, camera_get_active()->proj, camera_get_active()->view); - - static const char *vs = - "#version 130\n" - "//" FILELINE "\n" - "uniform mat4 M,VP;\n" - "in vec3 att_position;\n" - "in vec3 att_normal;\n" - "out vec3 v_normal;\n" - "void main() {\n" - " v_normal = normalize(att_normal);\n" - " gl_Position = M * VP * vec4( att_position, 1.0 );\n" - "}\n"; - static const char *fs = - "#version 130\n" - "//" FILELINE "\n" - "in vec3 v_normal;\n" - "out vec4 fragcolor;\n" - "void main() {\n" - "fragcolor = vec4(v_normal, 1.0);\n" // diffuse - "}"; - - static unsigned program; do_once program = shader(vs, fs, "att_position,att_normal", "fragcolor", NULL); - shader_bind(program); - shader_mat44("VP", VP); - shader_mat44("M", M); - - mesh_update(m, "p3 n3", 0,array_count(m->out_vertex3)/2,m->out_vertex3, array_count(m->out_index3)*3,m->out_index3,0); - mesh_render(m); -} - -void InitModel(mesh_t *m) { - static const double verts[]={-0.334392,+0.133007,+0.062259,-0.350189,+0.150354,-0.147769,-0.234201,+0.343811,-0.174307,-0.200259,+0.285207,+0.093749,+0.003520,+0.475208,-0.159365,+0.001856,+0.419203,+0.098582,-0.252802,+0.093666,+0.237538,-0.162901,+0.237984,+0.206905,+0.000865,+0.318141,+0.235370,-0.414624,+0.164083,-0.278254,-0.262213,+0.357334,-0.293246,+0.004628,+0.482694,-0.338626,-0.402162,+0.133528,-0.443247,-0.243781,+0.324275,-0.436763,+0.005293,+0.437592,-0.458332,-0.339884,-0.041150,-0.668211,-0.248382,+0.255825,-0.627493,+0.006261,+0.376103,-0.631506,-0.216201,-0.126776,-0.886936,-0.171075,+0.011544,-0.881386,-0.181074,+0.098223,-0.814779,-0.119891,+0.218786,-0.760153,-0.078895,+0.276780,-0.739281,+0.006801,+0.310959,-0.735661,-0.168842,+0.102387,-0.920381,-0.104072,+0.177278,-0.952530,-0.129704,+0.211848,-0.836678,-0.099875,+0.310931,-0.799381,+0.007237,+0.361687,-0.794439,-0.077913,+0.258753,-0.921640,+0.007957,+0.282241,-0.931680,-0.252222,-0.550401,-0.557810,-0.267633,-0.603419,-0.655209,-0.446838,-0.118517,-0.466159,-0.459488,-0.093017,-0.311341,-0.370645,-0.100108,-0.159454,-0.371984,-0.091991,-0.011044,-0.328945,-0.098269,+0.088659,-0.282452,-0.018862,+0.311501,-0.352403,-0.131341,+0.144902,-0.364126,-0.200299,+0.202388,-0.283965,-0.231869,+0.023668,-0.298943,-0.155218,+0.369716,-0.293787,-0.121856,+0.419097,-0.290163,-0.290797,+0.107824,-0.264165,-0.272849,+0.036347,-0.228567,-0.372573,+0.290309,-0.190431,-0.286997,+0.421917,-0.191039,-0.240973,+0.507118,-0.287272,-0.276431,-0.065444,-0.295675,-0.280818,-0.174200,-0.399537,-0.313131,-0.376167,-0.392666,-0.488581,-0.427494,-0.331669,-0.570185,-0.466054,-0.282290,-0.618140,-0.589220,-0.374238,-0.594882,-0.323298,-0.381071,-0.629723,-0.350777,-0.382112,-0.624060,-0.221577,-0.272701,-0.566522,+0.259157,-0.256702,-0.663406,+0.286079,-0.280948,-0.428359,+0.055790,-0.184974,-0.508894,+0.326265,-0.279971,-0.526918,+0.395319,-0.282599,-0.663393,+0.412411,-0.188329,-0.475093,+0.417954,-0.263384,-0.663396,+0.466604,-0.209063,-0.663393,+0.509344,-0.002044,-0.319624,+0.553078,-0.001266,-0.371260,+0.413296,-0.219753,-0.339762,-0.040921,-0.256986,-0.282511,-0.006349,-0.271706,-0.260881,+0.001764,-0.091191,-0.419184,-0.045912,-0.114944,-0.429752,-0.124739,-0.113970,-0.382987,-0.188540,-0.243012,-0.464942,-0.242850,-0.314815,-0.505402,-0.324768,+0.002774,-0.437526,-0.262766,-0.072625,-0.417748,-0.221440,-0.160112,-0.476932,-0.293450,+0.003859,-0.453425,-0.443916,-0.120363,-0.581567,-0.438689,-0.091499,-0.584191,-0.294511,-0.116469,-0.599861,-0.188308,-0.208032,-0.513640,-0.134649,-0.235749,-0.610017,-0.040939,-0.344916,-0.622487,-0.085380,-0.336401,-0.531864,-0.212298,+0.001961,-0.459550,-0.135547,-0.058296,-0.430536,-0.043440,+0.001378,-0.449511,-0.037762,-0.130135,-0.510222,+0.079144,+0.000142,-0.477549,+0.157064,-0.114284,-0.453206,+0.304397,-0.000592,-0.443558,+0.285401,-0.056215,-0.663402,+0.326073,-0.026248,-0.568010,+0.273318,-0.049261,-0.531064,+0.389854,-0.127096,-0.663398,+0.479316,-0.058384,-0.663401,+0.372891,-0.303961,+0.054199,+0.625921,-0.268594,+0.193403,+0.502766,-0.277159,+0.126123,+0.443289,-0.287605,-0.005722,+0.531844,-0.231396,-0.121289,+0.587387,-0.253475,-0.081797,+0.756541,-0.195164,-0.137969,+0.728011,-0.167673,-0.156573,+0.609388,-0.145917,-0.169029,+0.697600,-0.077776,-0.214247,+0.622586,-0.076873,-0.214971,+0.696301,-0.002341,-0.233135,+0.622859,-0.002730,-0.213526,+0.691267,-0.003136,-0.192628,+0.762731,-0.056136,-0.201222,+0.763806,-0.114589,-0.166192,+0.770723,-0.155145,-0.129632,+0.791738,-0.183611,-0.058705,+0.847012,-0.165562,+0.001980,+0.833386,-0.220084,+0.019914,+0.768935,-0.255730,+0.090306,+0.670782,-0.255594,+0.113833,+0.663389,-0.226380,+0.212655,+0.617740,-0.003367,-0.195342,+0.799680,-0.029743,-0.210508,+0.827180,-0.003818,-0.194783,+0.873636,-0.004116,-0.157907,+0.931268,-0.031280,-0.184555,+0.889476,-0.059885,-0.184448,+0.841330,-0.135333,-0.164332,+0.878200,-0.085574,-0.170948,+0.925547,-0.163833,-0.094170,+0.897114,-0.138444,-0.104250,+0.945975,-0.083497,-0.084934,+0.979607,-0.004433,-0.146642,+0.985872,-0.150715,+0.032650,+0.884111,-0.135892,-0.035520,+0.945455,-0.070612,+0.036849,+0.975733,-0.004458,-0.042526,+1.015670,-0.004249,+0.046042,+1.003240,-0.086969,+0.133224,+0.947633,-0.003873,+0.161605,+0.970499,-0.125544,+0.140012,+0.917678,-0.125651,+0.250246,+0.857602,-0.003127,+0.284070,+0.878870,-0.159174,+0.125726,+0.888878,-0.183807,+0.196970,+0.844480,-0.159890,+0.291736,+0.732480,-0.199495,+0.207230,+0.779864,-0.206182,+0.164608,+0.693257,-0.186315,+0.160689,+0.817193,-0.192827,+0.166706,+0.782271,-0.175112,+0.110008,+0.860621,-0.161022,+0.057420,+0.855111,-0.172319,+0.036155,+0.816189,-0.190318,+0.064083,+0.760605,-0.195072,+0.129179,+0.731104,-0.203126,+0.410287,+0.680536,-0.216677,+0.309274,+0.642272,-0.241515,+0.311485,+0.587832,-0.002209,+0.366663,+0.749413,-0.088230,+0.396265,+0.678635,-0.170147,+0.109517,+0.840784,-0.160521,+0.067766,+0.830650,-0.181546,+0.139805,+0.812146,-0.180495,+0.148568,+0.776087,-0.180255,+0.129125,+0.744192,-0.186298,+0.078308,+0.769352,-0.167622,+0.060539,+0.806675,-0.189876,+0.102760,+0.802582,-0.108340,+0.455446,+0.657174,-0.241585,+0.527592,+0.669296,-0.265676,+0.513366,+0.634594,-0.203073,+0.478550,+0.581526,-0.266772,+0.642330,+0.602061,-0.216961,+0.564846,+0.535435,-0.202210,+0.525495,+0.475944,-0.193888,+0.467925,+0.520606,-0.265837,+0.757267,+0.500933,-0.240306,+0.653440,+0.463215,-0.309239,+0.776868,+0.304726,-0.271009,+0.683094,+0.382018,-0.312111,+0.671099,+0.286687,-0.268791,+0.624342,+0.377231,-0.302457,+0.533996,+0.360289,-0.263656,+0.529310,+0.412564,-0.282311,+0.415167,+0.447666,-0.239201,+0.442096,+0.495604,-0.220043,+0.569026,+0.445877,-0.001263,+0.395631,+0.602029,-0.057345,+0.442535,+0.572224,-0.088927,+0.506333,+0.529106,-0.125738,+0.535076,+0.612913,-0.126251,+0.577170,+0.483159,-0.149594,+0.611520,+0.557731,-0.163188,+0.660791,+0.491080,-0.172482,+0.663387,+0.415416,-0.160464,+0.591710,+0.370659,-0.156445,+0.536396,+0.378302,-0.136496,+0.444358,+0.425226,-0.095564,+0.373768,+0.473659,-0.104146,+0.315912,+0.498104,-0.000496,+0.384194,+0.473817,-0.000183,+0.297770,+0.401486,-0.129042,+0.270145,+0.434495,+0.000100,+0.272963,+0.349138,-0.113060,+0.236984,+0.385554,+0.007260,+0.016311,-0.883396,+0.007865,+0.122104,-0.956137,-0.032842,+0.115282,-0.953252,-0.089115,+0.108449,-0.950317,-0.047440,+0.014729,-0.882756,-0.104458,+0.013137,-0.882070,-0.086439,-0.584866,-0.608343,-0.115026,-0.662605,-0.436732,-0.071683,-0.665372,-0.606385,-0.257884,-0.665381,-0.658052,-0.272542,-0.665381,-0.592063,-0.371322,-0.665382,-0.353620,-0.372362,-0.665381,-0.224420,-0.335166,-0.665380,-0.078623,-0.225999,-0.665375,-0.038981,-0.106719,-0.665374,-0.186351,-0.081749,-0.665372,-0.292554,+0.006943,-0.091505,-0.858354,+0.006117,-0.280985,-0.769967,+0.004495,-0.502360,-0.559799,-0.198638,-0.302135,-0.845816,-0.237395,-0.542544,-0.587188,-0.270001,-0.279489,-0.669861,-0.134547,-0.119852,-0.959004,-0.052088,-0.122463,-0.944549,-0.124463,-0.293508,-0.899566,-0.047616,-0.289643,-0.879292,-0.168595,-0.529132,-0.654931,-0.099793,-0.515719,-0.645873,-0.186168,-0.605282,-0.724690,-0.112970,-0.583097,-0.707469,-0.108152,-0.665375,-0.700408,-0.183019,-0.665378,-0.717630,-0.349529,-0.334459,-0.511985,-0.141182,-0.437705,-0.798194,-0.212670,-0.448725,-0.737447,-0.261111,-0.414945,-0.613835,-0.077364,-0.431480,-0.778113,+0.005174,-0.425277,-0.651592,+0.089236,-0.431732,-0.777093,+0.271006,-0.415749,-0.610577,+0.223981,-0.449384,-0.734774,+0.153275,-0.438150,-0.796391,+0.358414,-0.335529,-0.507649,+0.193434,-0.665946,-0.715325,+0.118363,-0.665717,-0.699021,+0.123515,-0.583454,-0.706020,+0.196851,-0.605860,-0.722345,+0.109788,-0.516035,-0.644590,+0.178656,-0.529656,-0.652804,+0.061157,-0.289807,-0.878626,+0.138234,-0.293905,-0.897958,+0.066933,-0.122643,-0.943820,+0.149571,-0.120281,-0.957264,+0.280989,-0.280321,-0.666487,+0.246581,-0.543275,-0.584224,+0.211720,-0.302754,-0.843303,+0.086966,-0.665627,-0.291520,+0.110634,-0.665702,-0.185021,+0.228099,-0.666061,-0.036201,+0.337743,-0.666396,-0.074503,+0.376722,-0.666513,-0.219833,+0.377265,-0.666513,-0.349036,+0.281411,-0.666217,-0.588670,+0.267564,-0.666174,-0.654834,+0.080745,-0.665602,-0.605452,+0.122016,-0.662963,-0.435280,+0.095767,-0.585141,-0.607228,+0.118944,+0.012799,-0.880702,+0.061944,+0.014564,-0.882086,+0.104725,+0.108156,-0.949130,+0.048513,+0.115159,-0.952753,+0.112696,+0.236643,+0.386937,+0.128177,+0.269757,+0.436071,+0.102643,+0.315600,+0.499370,+0.094535,+0.373481,+0.474824,+0.136270,+0.443946,+0.426895,+0.157071,+0.535923,+0.380222,+0.161350,+0.591224,+0.372630,+0.173035,+0.662865,+0.417531,+0.162808,+0.660299,+0.493077,+0.148250,+0.611070,+0.559555,+0.125719,+0.576790,+0.484702,+0.123489,+0.534699,+0.614440,+0.087621,+0.506066,+0.530188,+0.055321,+0.442365,+0.572915,+0.219936,+0.568361,+0.448571,+0.238099,+0.441375,+0.498528,+0.281711,+0.414315,+0.451121,+0.263833,+0.528513,+0.415794,+0.303284,+0.533081,+0.363998,+0.269687,+0.623528,+0.380528,+0.314255,+0.670153,+0.290524,+0.272023,+0.682273,+0.385343,+0.311480,+0.775931,+0.308527,+0.240239,+0.652714,+0.466159,+0.265619,+0.756464,+0.504187,+0.192562,+0.467341,+0.522972,+0.201605,+0.524885,+0.478417,+0.215743,+0.564193,+0.538084,+0.264969,+0.641527,+0.605317,+0.201031,+0.477940,+0.584002,+0.263086,+0.512567,+0.637832,+0.238615,+0.526867,+0.672237,+0.105309,+0.455123,+0.658482,+0.183993,+0.102195,+0.804872,+0.161563,+0.060042,+0.808692,+0.180748,+0.077754,+0.771600,+0.175168,+0.128588,+0.746368,+0.175075,+0.148030,+0.778264,+0.175658,+0.139265,+0.814333,+0.154191,+0.067291,+0.832578,+0.163818,+0.109013,+0.842830,+0.084760,+0.396004,+0.679695,+0.238888,+0.310760,+0.590775,+0.213380,+0.308625,+0.644905,+0.199666,+0.409678,+0.683003,+0.190143,+0.128597,+0.733463,+0.184833,+0.063516,+0.762902,+0.166070,+0.035644,+0.818261,+0.154361,+0.056943,+0.857042,+0.168542,+0.109489,+0.862725,+0.187387,+0.166131,+0.784599,+0.180428,+0.160135,+0.819438,+0.201823,+0.163991,+0.695756,+0.194206,+0.206635,+0.782275,+0.155438,+0.291260,+0.734412,+0.177696,+0.196424,+0.846693,+0.152305,+0.125256,+0.890786,+0.119546,+0.249876,+0.859104,+0.118369,+0.139643,+0.919173,+0.079410,+0.132973,+0.948652,+0.062419,+0.036648,+0.976547,+0.127847,-0.035919,+0.947070,+0.143624,+0.032206,+0.885913,+0.074888,-0.085173,+0.980577,+0.130184,-0.104656,+0.947620,+0.156201,-0.094653,+0.899074,+0.077366,-0.171194,+0.926545,+0.127722,-0.164729,+0.879810,+0.052670,-0.184618,+0.842019,+0.023477,-0.184638,+0.889811,+0.022626,-0.210587,+0.827500,+0.223089,+0.211976,+0.620493,+0.251444,+0.113067,+0.666494,+0.251419,+0.089540,+0.673887,+0.214360,+0.019258,+0.771595,+0.158999,+0.001490,+0.835374,+0.176696,-0.059249,+0.849218,+0.148696,-0.130091,+0.793599,+0.108290,-0.166528,+0.772088,+0.049820,-0.201382,+0.764454,+0.071341,-0.215195,+0.697209,+0.073148,-0.214475,+0.623510,+0.140502,-0.169461,+0.699354,+0.163374,-0.157073,+0.611416,+0.189466,-0.138550,+0.730366,+0.247593,-0.082554,+0.759610,+0.227468,-0.121982,+0.590197,+0.284702,-0.006586,+0.535347,+0.275741,+0.125287,+0.446676,+0.266650,+0.192594,+0.506044,+0.300086,+0.053287,+0.629620,+0.055450,-0.663935,+0.375065,+0.122854,-0.664138,+0.482323,+0.046520,-0.531571,+0.391918,+0.024824,-0.568450,+0.275106,+0.053855,-0.663931,+0.328224,+0.112829,-0.453549,+0.305788,+0.131265,-0.510617,+0.080746,+0.061174,-0.430716,-0.042710,+0.341019,-0.532887,-0.208150,+0.347705,-0.623533,-0.081139,+0.238040,-0.610732,-0.038037,+0.211764,-0.514274,-0.132078,+0.120605,-0.600219,-0.186856,+0.096985,-0.584476,-0.293357,+0.127621,-0.581941,-0.437170,+0.165902,-0.477425,-0.291453,+0.077720,-0.417975,-0.220519,+0.320892,-0.506363,-0.320874,+0.248214,-0.465684,-0.239842,+0.118764,-0.383338,-0.187114,+0.118816,-0.430106,-0.123307,+0.094131,-0.419464,-0.044777,+0.274526,-0.261706,+0.005110,+0.259842,-0.283292,-0.003185,+0.222861,-0.340431,-0.038210,+0.204445,-0.664380,+0.513353,+0.259286,-0.664547,+0.471281,+0.185402,-0.476020,+0.421718,+0.279163,-0.664604,+0.417328,+0.277157,-0.528122,+0.400208,+0.183069,-0.509812,+0.329995,+0.282599,-0.429210,+0.059242,+0.254816,-0.664541,+0.290687,+0.271436,-0.567707,+0.263966,+0.386561,-0.625221,-0.216870,+0.387086,-0.630883,-0.346073,+0.380021,-0.596021,-0.318679,+0.291269,-0.619007,-0.585707,+0.339280,-0.571198,-0.461946,+0.400045,-0.489778,-0.422640,+0.406817,-0.314349,-0.371230,+0.300588,-0.281718,-0.170549,+0.290866,-0.277304,-0.061905,+0.187735,-0.241545,+0.509437,+0.188032,-0.287569,+0.424234,+0.227520,-0.373262,+0.293102,+0.266526,-0.273650,+0.039597,+0.291592,-0.291676,+0.111386,+0.291914,-0.122741,+0.422683,+0.297574,-0.156119,+0.373368,+0.286603,-0.232731,+0.027162,+0.364663,-0.201399,+0.206850,+0.353855,-0.132408,+0.149228,+0.282208,-0.019715,+0.314960,+0.331187,-0.099266,+0.092701,+0.375463,-0.093120,-0.006467,+0.375917,-0.101236,-0.154882,+0.466635,-0.094416,-0.305669,+0.455805,-0.119881,-0.460632,+0.277465,-0.604242,-0.651871,+0.261022,-0.551176,-0.554667,+0.093627,+0.258494,-0.920589,+0.114248,+0.310608,-0.798070,+0.144232,+0.211434,-0.835001,+0.119916,+0.176940,-0.951159,+0.184061,+0.101854,-0.918220,+0.092431,+0.276521,-0.738231,+0.133504,+0.218403,-0.758602,+0.194987,+0.097655,-0.812476,+0.185542,+0.011005,-0.879202,+0.230315,-0.127450,-0.884202,+0.260471,+0.255056,-0.624378,+0.351567,-0.042194,-0.663976,+0.253742,+0.323524,-0.433716,+0.411612,+0.132299,-0.438264,+0.270513,+0.356530,-0.289984,+0.422146,+0.162819,-0.273130,+0.164724,+0.237490,+0.208912,+0.253806,+0.092900,+0.240640,+0.203608,+0.284597,+0.096223,+0.241006,+0.343093,-0.171396,+0.356076,+0.149288,-0.143443,+0.337656,+0.131992,+0.066374,}; - static const int tris[]={126,134,133,342,138,134,133,134,138,126,342,134,312,316,317,169,163,162,312,317,319,312,319,318,169,162,164,169,168,163,312,314,315,169,164,165,169,167,168,312,315,316,312,313,314,169,165,166,169,166,167,312,318,313,308,304,305,308,305,306,179,181,188,177,173,175,177,175,176,302,293,300,322,294,304,188,176,175,188,175,179,158,177,187,305,293,302,305,302,306,322,304,308,188,181,183,158,173,177,293,298,300,304,294,296,304,296,305,185,176,188,185,188,183,187,177,176,187,176,185,305,296,298,305,298,293,436,432, 28,436, 28, 23,434,278,431, 30,208,209, 30,209, 29, 19, 20, 24,208,207,211,208,211,209, 19,210,212,433,434,431,433,431,432,433,432,436,436,437,433,277,275,276,277,276,278,209,210, 25, 21, 26, 24, 21, 24, 20, 25, 26, 27, 25, 27, 29,435,439,277,439,275,277,432,431, 30,432, 30, 28,433,437,438,433,438,435,434,277,278, 24, 25,210, 24, 26, 25, 29, 27, 28, 29, 28, 30, 19, 24,210,208, 30,431,208,431,278,435,434,433,435,277,434, 25, 29,209, 27, 22, 23, 27, 23, 28, 26, 22, 27, 26, 21, 22,212,210,209,212,209,211,207,208,278,207,278,276,439,435,438, 12, 9, 10, 12, 10, 13, 2, 3, 5, 2, 5, 4, 16, 13, 14, 16, 14, 17, 22, 21, 16, 13, 10, 11, 13, 11, 14, 1, 0, 3, 1, 3, 2, 15, 12, 16, 19, 18, 15, 19, 15, 16, 19, 16, 20, 9, 1, 2, 9, 2, 10, 3, 7, 8, 3, 8, 5, 16, 17, 23, 16, 23, 22, 21, 20, 16, 10, 2, 4, 10, 4, 11, 0, 6, 7, 0, 7, 3, 12, 13, 16,451,446,445,451,445,450,442,440,439,442,439,438,442,438,441,421,420,422,412,411,426,412,426,425,408,405,407,413, 67, 68,413, 68,414,391,390,412, 80,384,386,404,406,378,390,391,377,390,377, 88,400,415,375,398,396,395,398,395,371,398,371,370,112,359,358,112,358,113,351,352,369,125,349,348,345,343,342,342,340,339,341,335,337,328,341,327,331,323,333,331,322,323,327,318,319,327,319,328,315,314,324,302,300,301,302,301,303,320,311,292,285,284,289,310,307,288,310,288,290,321,350,281,321,281,282,423,448,367,272,273,384,272,384,274,264,265,382,264,382,383,440,442,261,440,261,263,252,253,254,252,254,251,262,256,249,262,249,248,228,243,242,228, 31,243,213,215,238,213,238,237, 19,212,230,224,225,233,224,233,231,217,218, 56,217, 56, 54,217,216,239,217,239,238,217,238,215,218,217,215,218,215,214, 6,102,206,186,199,200,197,182,180,170,171,157,201,200,189,170,190,191,170,191,192,175,174,178,175,178,179,168,167,155,122,149,158,122,158,159,135,153,154,135,154,118,143,140,141,143,141,144,132,133,136,130,126,133,124,125,127,122,101,100,122,100,121,110,108,107,110,107,109, 98, 99, 97, 98, 97, 64, 98, 64, 66, 87, 55, 57, 83, 82, 79, 83, 79, 84, 78, 74, 50, 49, 71, 41, 49, 41, 37, 49, 37, 36, 58, 44, 60, 60, 59, 58, 51, 34, 33, 39, 40, 42, 39, 42, 38,243,240, 33,243, 33,229, 39, 38, 6, 44, 46, 40, 55, 56, 57, 64, 62, 65, 64, 65, 66, 41, 71, 45, 75, 50, 51, 81, 79, 82, 77, 88, 73, 93, 92, 94, 68, 47, 46, 96, 97, 99, 96, 99, 95,110,109,111,111,112,110,114,113,123,114,123,124,132,131,129,133,137,136,135,142,145,145,152,135,149,147,157,157,158,149,164,150,151,153,163,168,153,168,154,185,183,182,185,182,184,161,189,190,200,199,191,200,191,190,180,178,195,180,195,196,102,101,204,102,204,206, 43, 48,104, 43,104,103,216,217, 54,216, 54, 32,207,224,231,230,212,211,230,211,231,227,232,241,227,241,242,235,234,241,235,241,244,430,248,247,272,274,253,272,253,252,439,260,275,225,224,259,225,259,257,269,270,407,269,407,405,270,269,273,270,273,272,273,269,268,273,268,267,273,267,266,273,266,265,273,265,264,448,279,367,281,350,368,285,286,301,290,323,310,290,311,323,282,281,189,292,311,290,292,290,291,307,306,302,307,302,303,316,315,324,316,324,329,331,351,350,330,334,335,330,335,328,341,337,338,344,355,354,346,345,348,346,348,347,364,369,352,364,352,353,365,363,361,365,361,362,376,401,402,373,372,397,373,397,400,376, 92,377,381,378,387,381,387,385,386, 77, 80,390,389,412,416,417,401,403,417,415,408,429,430,419,423,418,427,428,444,427,444,446,437,436,441,450,445, 11,450, 11, 4,447,449, 5,447, 5, 8,441,438,437,425,426,451,425,451,452,417,421,415,408,407,429,399,403,400,399,400,397,394,393,416,389,411,412,386,383,385,408,387,378,408,378,406,377,391,376, 94,375,415,372,373,374,372,374,370,359,111,360,359,112,111,113,358,349,113,349,123,346,343,345,343,340,342,338,336,144,338,144,141,327,341,354,327,354,326,331,350,321,331,321,322,314,313,326,314,326,325,300,298,299,300,299,301,288,287,289,189,292,282,287,288,303,284,285,297,368,280,281,448,447,279,274,226,255,267,268,404,267,404,379,429,262,430,439,440,260,257,258,249,257,249,246,430,262,248,234,228,242,234,242,241,237,238,239,237,239,236, 15, 18,227, 15,227,229,222,223, 82,222, 82, 83,214,215,213,214,213, 81, 38,102, 6,122,159,200,122,200,201,174,171,192,174,192,194,197,193,198,190,170,161,181,179,178,181,178,180,166,156,155,163,153,152,163,152,162,120,156,149,120,149,121,152,153,135,140,143,142,135,131,132,135,132,136,130,129,128,130,128,127,100,105,119,100,119,120,106,104,107,106,107,108, 91, 95, 59, 93, 94, 68, 91, 89, 92, 76, 53, 55, 76, 55, 87, 81, 78, 79, 74, 73, 49, 69, 60, 45, 58, 62, 64, 58, 64, 61, 53, 31, 32, 32, 54, 53, 42, 43, 38, 35, 36, 0, 35, 0, 1, 34, 35, 1, 34, 1, 9, 44, 40, 41, 44, 41, 45, 33,240, 51, 63, 62, 58, 63, 58, 59, 45, 71, 70, 76, 75, 51, 76, 51, 52, 86, 85, 84, 86, 84, 87, 89, 72, 73, 89, 73, 88, 91, 92, 96, 91, 96, 95, 72, 91, 60, 72, 60, 69,104,106,105,119,105,117,119,117,118,124,127,128,117,116,129,117,129,131,118,117,131,135,140,142,146,150,152,146,152,145,149,122,121,166,165,151,166,151,156,158,172,173,161,160,189,199,198,193,199,193,191,204,201,202,178,174,194,200,159,186,109, 48, 67, 48,107,104,216, 32,236,216,236,239,223,214, 81,223, 81, 82, 33, 12, 15, 32,228,234, 32,234,236,240, 31, 52,256,255,246,256,246,249,258,263,248,258,248,249,275,260,259,275,259,276,207,276,259,270,271,429,270,429,407,413,418,366,413,366,365,368,367,279,368,279,280,303,301,286,303,286,287,283,282,292,283,292,291,320,292,189,298,296,297,298,297,299,318,327,326,318,326,313,329,330,317,336,333,320,326,354,353,334,332,333,334,333,336,342,339,139,342,139,138,345,342,126,347,357,356,369,368,351,363,356,357,363,357,361,366,367,368,366,368,369,375,373,400, 92, 90,377,409,387,408,386,385,387,386,387,388,412,394,391,396,398,399,408,406,405,415,421,419,415,419,414,425,452,448,425,448,424,444,441,443,448,452,449,448,449,447,446,444,443,446,443,445,250,247,261,250,261,428,421,422,423,421,423,419,427,410,250,417,403,401,403,402,401,420,392,412,420,412,425,420,425,424,386,411,389,383,382,381,383,381,385,378,379,404,372,371,395,372,395,397,371,372,370,361,359,360,361,360,362,368,350,351,349,347,348,356,355,344,356,344,346,344,341,340,344,340,343,338,337,336,328,335,341,324,352,351,324,351,331,320,144,336,314,325,324,322,308,309,310,309,307,287,286,289,203,280,279,203,279,205,297,295,283,297,283,284,447,205,279,274,384, 80,274, 80,226,266,267,379,266,379,380,225,257,246,225,246,245,256,254,253,256,253,255,430,247,250,226,235,244,226,244,245,232,233,244,232,244,241,230, 18, 19, 32, 31,228,219,220, 86,219, 86, 57,226,213,235,206, 7, 6,122,201,101,201,204,101,180,196,197,170,192,171,200,190,189,194,193,195,183,181,180,183,180,182,155,154,168,149,156,151,149,151,148,155,156,120,145,142,143,145,143,146,136,137,140,133,132,130,128,129,116,100,120,121,110,112,113,110,113,114, 66, 65, 63, 66, 63, 99, 66, 99, 98, 96, 46, 61, 89, 88, 90, 86, 87, 57, 80, 78, 81, 72, 69, 49, 67, 48, 47, 67, 47, 68, 56, 55, 53, 50, 49, 36, 50, 36, 35, 40, 39, 41,242,243,229,242,229,227, 6, 37, 39, 42, 47, 48, 42, 48, 43, 61, 46, 44, 45, 70, 69, 69, 70, 71, 69, 71, 49, 74, 78, 77, 83, 84, 85, 73, 74, 77, 93, 96, 92, 68, 46, 93, 95, 99, 63, 95, 63, 59,115,108,110,115,110,114,125,126,127,129,130,132,137,133,138,137,138,139,148,146,143,148,143,147,119,118,154,161,147,143,165,164,151,158,157,171,158,171,172,159,158,187,159,187,186,194,192,191,194,191,193,189,202,201,182,197,184,205, 8, 7, 48,109,107,218,219, 57,218, 57, 56,207,231,211,232,230,231,232,231,233, 53, 52, 31,388,411,386,409,430,250,262,429,254,262,254,256,442,444,428,273,264,383,273,383,384,429,271,251,429,251,254,413,365,362, 67,413,360,282,283,295,285,301,299,202,281,280,284,283,291,284,291,289,320,189,160,308,306,307,307,309,308,319,317,330,319,330,328,353,352,324,332,331,333,340,341,338,354,341,344,349,358,357,349,357,347,364,355,356,364,356,363,364,365,366,364,366,369,374,376,402,375, 92,373, 77,389,390,382,380,381,389, 77,386,393,394,412,393,412,392,401,394,416,415,400,403,411,410,427,411,427,426,422,420,424,247,248,263,247,263,261,445,443, 14,445, 14, 11,449,450, 4,449, 4, 5,443,441, 17,443, 17, 14,436, 23, 17,436, 17,441,424,448,422,448,423,422,414,419,418,414,418,413,406,404,405,399,397,395,399,395,396,420,416,392,388,410,411,386,384,383,390, 88, 77,375, 94, 92,415,414, 68,415, 68, 94,370,374,402,370,402,398,361,357,358,361,358,359,125,348,126,346,344,343,340,338,339,337,335,334,337,334,336,325,353,324,324,331,332,324,332,329,323,322,309,323,309,310,294,295,297,294,297,296,289,286,285,202,280,203,288,307,303,282,295,321, 67,360,111,418,423,367,418,367,366,272,252,251,272,251,271,272,271,270,255,253,274,265,266,380,265,380,382,442,428,261,440,263,258,440,258,260,409,250,410,255,226,245,255,245,246, 31,240,243,236,234,235,236,235,237,233,225,245,233,245,244,220,221, 85,220, 85, 86, 81,213,226, 81,226, 80, 7,206,205,186,184,198,186,198,199,204,203,205,204,205,206,195,193,196,171,174,172,173,174,175,173,172,174,155,167,166,160,161,143,160,143,144,119,154,155,148,151,150,148,150,146,140,137,139,140,139,141,127,126,130,114,124,128,114,128,115,117,105,106,117,106,116,104,105,100,104,100,103, 59, 60, 91, 97, 96, 61, 97, 61, 64, 91, 72, 89, 87, 84, 79, 87, 79, 76, 78, 80, 77, 49, 50, 74, 60, 44, 45, 61, 44, 58, 51, 50, 35, 51, 35, 34, 39, 37, 41, 33, 34, 9, 33, 9, 12, 0, 36, 37, 0, 37, 6, 40, 46, 47, 40, 47, 42, 53, 54, 56, 65, 62, 63, 72, 49, 73, 79, 78, 75, 79, 75, 76, 52, 53, 76, 92, 89, 90, 96, 93, 46,102,103,100,102,100,101,116,106,108,116,108,115,123,125,124,116,115,128,118,131,135,140,135,136,148,147,149,120,119,155,164,162,152,164,152,150,157,147,161,157,161,170,186,187,185,186,185,184,193,197,196,202,203,204,194,195,178,198,184,197, 67,111,109, 38, 43,103, 38,103,102,214,223,222,214,222,221,214,221,220,214,220,219,214,219,218,213,237,235,221,222, 83,221, 83, 85, 15,229, 33,227, 18,230,227,230,232, 52, 51,240, 75, 78, 50,408,430,409,260,258,257,260,257,259,224,207,259,268,269,405,268,405,404,413,362,360,447, 8,205,299,297,285,189,281,202,290,288,289,290,289,291,322,321,295,322,295,294,333,323,311,333,311,320,317,316,329,320,160,144,353,325,326,329,332,334,329,334,330,339,338,141,339,141,139,348,345,126,347,356,346,123,349,125,364,353,354,364,354,355,365,364,363,376,391,394,376,394,401, 92,376,374, 92,374,373,377, 90, 88,380,379,378,380,378,381,388,387,409,388,409,410,416,393,392,399,398,402,399,402,403,250,428,427,421,417,416,421,416,420,426,427,446,426,446,451,444,442,441,452,451,450,452,450,449,}; - enum { NUM_VERTS = countof(verts) / 3, NUM_TRIS = countof(tris) / 3 }; - - // Copy the geometry from the arrays of data into the arrays which we send to the reduction routine - for(int i = 0; i < NUM_VERTS; i++ ) { - const double *vp = &verts[i*3]; - array_push(m->in_vertex3, vec3(vp[0],vp[1],vp[2])); - } - for(int i = 0; i < NUM_TRIS; i++ ) { - const int *td = &tris[i*3]; - array_push(m->in_index3, vec3i(td[0],td[1],td[2])); - } - - int tri_n = array_count(m->in_index3); - int vert_n = array_count(m->in_vertex3); - int vert_stride = sizeof(float) * 3; - array(int) permutation = 0; - array_resize(m->lod_collapse_map, vert_n); - array_resize(permutation, vert_n); - ProgressiveMesh(vert_n, vert_stride, (const float *)m->in_vertex3, tri_n, (const int *)m->in_index3, m->lod_collapse_map, permutation); - // PermuteVertices { - ASSERT(array_count(permutation) == array_count(m->in_vertex3)); - // rearrange the vertex Array - array(vec3) tmp = 0; - for(int i = 0; i < array_count(m->in_vertex3); i++) array_push(tmp, m->in_vertex3[i]); - for(int i = 0; i < array_count(m->in_vertex3); i++) m->in_vertex3[permutation[i]]=tmp[i]; - // update the changes in the entries in the triangle Array - for (int i = 0; i < array_count(m->in_index3); i++) { - m->in_index3[i].x = permutation[m->in_index3[i].x]; - m->in_index3[i].y = permutation[m->in_index3[i].y]; - m->in_index3[i].z = permutation[m->in_index3[i].z]; - } - array_free(tmp); - // } PermuteVertices - array_free(permutation); -} - -int main() { - window_create(0.75, 0); - window_color(PURPLE); - - camera_t cam = camera(); - cam.speed /= 4; - cam.position = vec3(1.667,0.503,2.417); - camera_lookat(&cam, vec3(0,0,0)); - - mesh_t m = mesh(); - InitModel(&m); - - float lo_detail=0.25f; - float hi_detail=1.00f; - float morph=0.75f; - - while( window_swap() && !input(KEY_ESC) ) { - if( input(KEY_LALT) && input_down(KEY_Z) ) window_record(__FILE__ ".mp4"); - - // fps camera - if( input(GAMEPAD_CONNECTED) ) { - vec2 filtered_lpad = input_filter_deadzone(input2(GAMEPAD_LPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 ); - vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 ); - vec2 mouse = scale2(vec2(filtered_rpad.x, filtered_rpad.y), 1.0f); - vec3 wasdec = scale3(vec3(filtered_lpad.x, input(GAMEPAD_LT) - input(GAMEPAD_RT), filtered_lpad.y), 1.0f); - camera_moveby(&cam, wasdec); - camera_fps(&cam, mouse.x,mouse.y); - window_cursor( true ); - } else { - bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); - vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_moveby(&cam, wasdecq); - camera_fps(&cam, mouse.x,mouse.y); - window_cursor( !active ); - } - - profile("LOD generation") { - ReduceModel(&m, lo_detail, hi_detail, morph); - mesh_area(&m); - } - - DrawModel(&m); - - if( ui_panel("LODs", PANEL_OPEN) ) { - ui_label(va("Polys: %d/%d Vertices: %d/%d", array_count(m.out_index3), array_count(m.in_index3), (int)(lo_detail * array_count(m.in_vertex3)), (int)(hi_detail * array_count(m.in_vertex3)))); - if(ui_slider("Lo detail", &lo_detail)) { lo_detail = clampf(lo_detail, 0.01f, 1.0f); if(lo_detail > hi_detail) hi_detail = lo_detail; } - if(ui_slider("Hi detail", &hi_detail)) { hi_detail = clampf(hi_detail, 0.01f, 1.0f); if(hi_detail < lo_detail) lo_detail = hi_detail; } - ui_slider("Morph", &morph); - ui_panel_end(); - } - } -} diff --git a/demos/05-scene.c b/demos/05-scene.c deleted file mode 100644 index fd00e77..0000000 --- a/demos/05-scene.c +++ /dev/null @@ -1,216 +0,0 @@ -// scene demo -// - rlyeh, public domain - -#include "v4k.h" - -int main() { - // options - bool do_twosided = 1; - bool do_wireframe = 0; - bool do_billboard_x = 1, do_billboard_y = 1, do_billboard_z = 1; - - // window (80% sized, MSAA x4 flag) - window_create(80, WINDOW_MSAA4); - window_title(__FILE__); - - // load all postfx files in all subdirs - fx_load("fx**.fs"); - - // scene loading - #define SCENE(...) #__VA_ARGS__ - const char *my_scene = SCENE([ - { - skybox: 'cubemaps/stardust/', - }, - { - position:[-5.0,-2.0,2.0], - rotation: [90.0,0.0,180.0], - scale:0.20, - //anchor/pivot:[], - // vertex:'p3 t2', - mesh:'models/witch/witch.obj', - texture:'models/witch/witch_diffuse.tga.png', -// swapzy:true, - flipuv:false, - }, - { - position:[-5.0,-2.0,2.0], - rotation: [90.0,0.0,180.0], - scale:2.20, - //anchor/pivot:[], - // vertex:'p3 t2', - mesh:'models/witch/witch_object.obj', - texture:'models/witch/witch_object_diffuse.tga.png', -// swapzy:true, - flipuv:false, - }, - ]); - int num_spawned = scene_merge(my_scene); - object_t *obj1 = scene_index(0); - object_t *obj2 = scene_index(1); - - // manual spawn & loading - model_t m1 = model("kgirl/kgirls01.fbx", 0); //MODEL_NO_ANIMS); - texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_RGB); - object_t* obj3 = scene_spawn(); - object_model(obj3, m1); - object_diffuse(obj3, t1); - object_scale(obj3, vec3(3,3,3)); - object_move(obj3, vec3(-10,0,-10)); - object_pivot(obj3, vec3(-90+180,180,0)); - - // camera - camera_t cam = camera(); - - // demo loop - while (window_swap()) - { - // input - if( input_down(KEY_ESC) ) break; - - // fps camera - bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - window_cursor( !active ); - - if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); - vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_moveby(&cam, wasdecq); - camera_fps(&cam, mouse.x,mouse.y); - - // queue model scale bounces - float t = fmod(window_time(), 0.3) / 0.3; - float s = 0.01f * ease_ping_pong(t, EASE_IN|EASE_CUBIC,EASE_OUT|EASE_CUBIC); - object_scale(obj1, vec3(0.20f - s,0.20f + s,0.20f - s)); - object_scale(obj2, vec3(0.20f - s,0.20f + s,0.20f - s)); - - // queue model billboard - object_billboard(obj1, (do_billboard_x << 2)|(do_billboard_y << 1)|(do_billboard_z << 0)); - object_billboard(obj2, (do_billboard_x << 2)|(do_billboard_y << 1)|(do_billboard_z << 0)); - - // queue model rotation - //object_rotate(obj3, vec3(0,1*window_time() * 20,0)); - - // flush render scene (background objects: skybox) - profile("Scene background") { - scene_render(SCENE_BACKGROUND); - } - - // queue debug drawcalls - profile("Debugdraw") { - ddraw_ground(0); - ddraw_color(YELLOW); - ddraw_text(vec3(+1,+1,-1), 0.04f, va("(%f,%f,%f)", cam.position.x,cam.position.y,cam.position.z)); - ddraw_color(YELLOW); - ddraw_flush(); - } - - // apply post-fxs from here - fx_begin(); - - // render scene (foreground objects) with post-effects - profile("Scene foreground") { - int scene_flags = 0; - scene_flags |= do_wireframe ? SCENE_WIREFRAME : 0; - scene_flags |= do_twosided ? 0 : SCENE_CULLFACE; - scene_render(SCENE_FOREGROUND | scene_flags); - } - - profile("Skeletal update") if(!window_has_pause()) { - float delta = window_delta() * 30 ; // 30fps anim - m1.curframe = model_animate(m1, m1.curframe + delta); - - ddraw_text(vec3(-10,5,-10), 0.05, va("Frame: %.1f", m1.curframe)); - } - - // post-fxs end here - fx_end(); - - // queue ui - if( ui_panel("Scene", 0)) { - if(ui_toggle("Billboard X", &do_billboard_x)) {} - if(ui_toggle("Billboard Y", &do_billboard_y)) {} - if(ui_toggle("Billboard Z", &do_billboard_z)) {} - if(ui_separator()) {} - if(ui_bool("Wireframe", &do_wireframe)) {} - if(ui_bool("Two sided", &do_twosided)) {} - ui_panel_end(); - } - } -} - -#if 0 - -// ---------------------------------------------------------------------------- -// material demo -// - rlyeh, public domain -// -// @todo: object_print(obj, ""); - -// create camera -camera_t cam = camera(); -// load video, RGB texture, no audio -video_t *v = video( "pexels-pachon-in-motion-17486489.mp4", VIDEO_RGB | VIDEO_NO_AUDIO | VIDEO_LOOP ); video_seek(v, 30); -// load texture -texture_t t1 = texture("kgirl/g01_texture.png", TEXTURE_RGB); -texture_t t2 = texture("matcaps/material3", 0); -// load model -model_t m1 = model("suzanne.obj", MODEL_NO_ANIMATIONS); -model_t m2 = model("suzanne.obj", MODEL_NO_ANIMATIONS|MODEL_MATCAPS); - -// spawn object1 (diffuse) -object_t* obj1 = scene_spawn(); -object_model(obj1, m1); -object_diffuse(obj1, t1); -object_scale(obj1, vec3(3,3,3)); -object_move(obj1, vec3(-10+5*0,0,-10)); -object_pivot(obj1, vec3(0,90,0)); - -// spawn object2 (matcap) -object_t* obj2 = scene_spawn(); -object_model(obj2, m2); -object_diffuse(obj2, t2); -object_scale(obj2, vec3(3,3,3)); -object_move(obj2, vec3(-10+5*2,0,-10)); -object_pivot(obj2, vec3(0,90,0)); - -// spawn object2 (video) -object_t* obj3 = scene_spawn(); -object_model(obj3, m1); -object_diffuse(obj3, video_textures(v)[0]); -object_scale(obj3, vec3(3,3,3)); -object_move(obj3, vec3(-10+5*1,0,-10)); -object_pivot(obj3, vec3(0,90,0)); - -// @todo: add shadertoy material - static model_t cube; do_once cube = model("cube.obj", 0); - static shadertoy_t s; do_once s = shadertoy("shadertoys/4ttGWM.fs", 256); - model_set_texture(cube, shadertoy_render(&s, window_delta())->tx); - model_render(cube, cam.proj, cam.view, cube.pivot, 0); - -while(window_swap() && !input(KEY_ESC)) { - // draw environment - viewport_color( RGB3(22,22,32) ); - ddraw_grid(0); - ddraw_flush(); - - // update video - video_decode( v ); - - // draw scene - scene_render(SCENE_FOREGROUND); -} - -// load static scene -// model_t sponza = model("sponza.obj", MODEL_MATCAPS); -// model_set_texture(sponza, texture("matcaps/normals", 0)); -// translation44(sponza.pivot, 0,-1,0); -// rotate44(sponza.pivot, -90,1,0,0); -// scale44(sponza.pivot, 10,10,10); - // model_render(sponza, cam.proj, cam.view, sponza.pivot, 0); - -// this demo supersedes following old sources: -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-material.c -// https://github.com/r-lyeh/V4K/blob/45e34d7890b2b8fe1f4994f4b76e496280d83cb6/demos/00-shadertoy.c - -#endif diff --git a/demos/06-controller.c b/demos/06-controller.c deleted file mode 100644 index faf5a98..0000000 --- a/demos/06-controller.c +++ /dev/null @@ -1,280 +0,0 @@ -// full controller demo: anims, input, collide; @todo: gamepad, input opts, easing on hits, notify on gamepad connect -// - rlyeh, public domain. -// -// Compile with: -// `make demos\99-controller.c` (windows) -// `sh MAKE.bat demos/99-controller.c` (linux, osx) - -#include "v4k.h" - -int main() { - // 75% window, MSAAx2 flag - window_create(75, WINDOW_MSAA2); - - // fx: load all post fx files in all subdirs - fx_load("fx**.fs"); - - // create a camera - camera_t cam = camera(); - camera_enable(&cam); - - // config 3d model #1 - model_t witch = model("witch/witch.obj", 0); - model_set_texture(witch, texture("witch/witch_diffuse.tga.png", 0)); - mat44 witch_pivot; vec3 witch_p = {-5,0,-5}, witch_r={-180,180,0}, witch_s={0.1,-0.1,0.1}; - - // config 3d model #2 - model_t girl = model("kgirl/kgirls01.fbx", 0); - mat44 girl_pivot; vec3 girl_p = {0,0,0}, girl_r = {270,0,0}, girl_s = {2,2,2}; - - // skybox - skybox_t sky = skybox("cubemaps/stardust", 0); - - // BGM - audio_play( audio_stream("waterworld-map.fur"), 0 ); - - // editor loop - while( window_swap() ) { - - // game camera - profile("Game.Camera") { - camera_t *cam = camera_get_active(); - - static vec3 source; - do_once source = cam->position; - - vec3 target = add3(girl_p, vec3(0,10,0)); - target = add3(target, scale3(norm3(sub3(source, target)), 10.0)); - source = mix3(source, target, 1-0.99f); - - camera_teleport(cam, source); - camera_lookat(cam, vec3(girl_p.x,0,girl_p.z)); - } - - // render begin (postfx) - fx_begin(); - - // skybox - skybox_render(&sky, cam.proj, cam.view); - - // world - ddraw_grid(0); - ddraw_flush(); - - // models - compose44(girl.pivot, girl_p, eulerq(girl_r), girl_s); - model_render(girl, cam.proj, cam.view, girl.pivot, 0); - - compose44(witch.pivot, witch_p, eulerq(witch_r), witch_s); - model_render(witch, cam.proj, cam.view, witch.pivot, 0); - - // render end (postfx) - fx_end(); - - // input controllers - - double GAME_JUMP_DOWN = input_down(KEY_Z); - double GAME_FIRE_DOWN = input_down(KEY_X); - double GAME_JUMP = input(KEY_Z); - double GAME_FIRE = input(KEY_X); - double GAME_LEFT = input(KEY_J); - double GAME_RIGHT = input(KEY_L); - double GAME_UP = input(KEY_I); - double GAME_DOWN = input(KEY_K); - double GAME_AXISX = input(KEY_L) - input(KEY_J); - double GAME_AXISY = input(KEY_I) - input(KEY_K); - - if( !input_anykey() ) { - if( input(GAMEPAD_CONNECTED) ) { - vec2 filtered_lpad = input_filter_deadzone(input2(GAMEPAD_LPAD), 0.15f /*15% deadzone*/); - GAME_JUMP_DOWN = input_down(GAMEPAD_A); - GAME_FIRE_DOWN = input_down(GAMEPAD_B) || input_down(GAMEPAD_X) || input_down(GAMEPAD_Y); - GAME_JUMP = input(GAMEPAD_A); - GAME_FIRE = input(GAMEPAD_B) || input(GAMEPAD_X) || input(GAMEPAD_Y); - GAME_AXISX = filtered_lpad.x; - GAME_AXISY = filtered_lpad.y; - } - } - - // animation controllers - - profile("Game.Animate scene") if( !window_has_pause() ) { - float delta = window_delta() * 30; // 30fps anim - - // animate girl - girl.curframe = model_animate(girl, girl.curframe + delta); - - // jump controller: jump duration=1.5s, jump height=6 units, anims (expo->circ) - float jump_delta = 1.0; - static double jump_timer = 0, jump_ss = 1.5, jump_h = 6; - if( GAME_JUMP_DOWN ) if( jump_timer == 0 ) jump_timer = time_ss(); - jump_delta = clampf(time_ss() - jump_timer, 0, jump_ss) * (1.0/jump_ss); - if( jump_delta >= 1 ) { jump_timer = 0; } - float y = ease_ping_pong( jump_delta, EASE_OUT|EASE_EXPO, EASE_OUT|EASE_CIRC); - girl_p.y = y * jump_h; - - // punch controller - float punch_delta = 1; - if( jump_delta >= 1 ) { - static vec3 origin; - static double punch_timer = 0, punch_ss = 0.5; - if( GAME_FIRE_DOWN ) if( punch_timer == 0 ) punch_timer = time_ss(), origin = girl_p; - punch_delta = clampf(time_ss() - punch_timer, 0, punch_ss) * (1.0/punch_ss); - if( punch_delta >= 1 ) { punch_timer = 0; } - else { - float x = ease_out_expo( punch_delta ); - vec3 fwd = rotate3q(vec3(0,0,1), eulerq(vec3(girl_r.x - 170,girl_r.y,girl_r.z))); - vec3 mix = mix3(girl_p, add3(origin,scale3(fwd,x*2)), x); - girl_p.x = mix.x, girl_p.z = mix.z; - } - } - - int modern_controller = 1; - int running = 0; - - // girl controller - - // locomotion vars - float speed = 0.2f * delta; - float yaw_boost = GAME_AXISY > 0 ? 1.0 : 1.75; - if(punch_delta < 1) yaw_boost = 0.0; // if firing... - else if(punch_delta <= 0.1) yaw_boost = 4.0; // unless initial punch chaining, extra yaw - - // old fashioned locomotion controller (boat controller) - if(!modern_controller) { - running = GAME_AXISY > 0; - - girl_r.x -= 170; - quat q = eulerq(girl_r); // += custom.pivot - vec3 rgt = rotate3q(vec3(1,0,0), q); - vec3 up = rotate3q(vec3(0,1,0), q); - vec3 fwd = rotate3q(vec3(0,0,1), q); - vec3 dir = scale3(fwd, speed * GAME_AXISY * (GAME_AXISY > 0 ? 2.0 : 0.5)); - girl_r.x += speed * 20.0 * yaw_boost * GAME_AXISX; // yaw - girl_p = add3(girl_p, dir); - girl_r.x += 170; - } - - // modern locomotion controller (mario 3d) - if(modern_controller) { - running = GAME_AXISX != 0 || GAME_AXISY != 0; - - camera_t *cam = camera_get_active(); - vec3 fwd = sub3(girl_p, cam->position); fwd.y = 0; fwd = norm3(fwd); - vec3 rgt = norm3(cross3(fwd, vec3(0,1,0))); - - // target - vec3 dir = add3( - scale3(fwd, GAME_AXISY), - scale3(rgt, GAME_AXISX) - ); dir.y = 0; dir = norm3(dir); - - // smoothing - static vec3 olddir; do_once olddir = dir; - dir = mix3(dir, olddir, 1 - (yaw_boost / 4.0) * 0.85); - olddir = dir; - - // vis - // ddraw_arrow(girl_p, add3(girl_p,scale3(dir,10))); - - // apply direction - girl_p = add3(girl_p, scale3(dir, speed * 2)); - - // apply rotation - { - girl_r.x -= 170; - quat q = eulerq(girl_r); - vec3 fwdg = rotate3q(vec3(0,0,1), q); - girl_r.x += 170; - - //float cosAngle = dot3(dir,fwdg); - //float angle = acos(cosAngle) * TO_DEG; - float angle = TO_DEG * ( atan2(fwdg.z, fwdg.x) - atan2(dir.z, dir.x)); - - if( !isnan(angle) ) { - girl_r.x -= angle; - while(girl_r.x> 180) girl_r.x-=360; - while(girl_r.x<-180) girl_r.x+=360; - } - } - } - - // anim loops - if( jump_delta < 1 ) { // jump/kick anim -#if 0 - girl.curframe = clampf(girl.curframe, 184, 202); - if( girl.curframe > 202-4 && GAME_FIRE_DOWN ) girl.curframe = 184+4; -#else - #define loopf(frame, min, max) (frame < min ? min : frame > max ? min + frame - max : frame) - if(girl.curframe >= 203) - girl.curframe = loopf(girl.curframe, 203, 220); - else - girl.curframe = clampf(girl.curframe, 184, 202); - if( girl.curframe > 202-4 && girl.curframe < 208 && GAME_FIRE_DOWN ) girl.curframe = 203; -#endif - } - else if( punch_delta < 1 ) { // punch anim - girl.curframe = clampf(girl.curframe, 90, 101); - if( girl.curframe > 101-6 && GAME_FIRE_DOWN ) girl.curframe = 101-6; - } - else if( running ) { - // loop running anim - if( girl.curframe < 65 ) girl.curframe = 65; - if( girl.curframe > 85 ) girl.curframe = 65; - } - else { // loop idle anim - if( girl.curframe > 59 ) girl.curframe = 0; - } - } - - // Game collisions - - profile("Game.collisions") { - bool punching = girl.curframe >= 90 && girl.curframe < 101; - bool air_kicking = girl.curframe >= 184 && girl.curframe < 202; - bool jump_kicking = girl.curframe >= 203 && girl.curframe < 220; - bool attacking = punching || air_kicking || jump_kicking; - - if( attacking ) { - aabb boxg = model_aabb(girl, girl_pivot); - aabb boxw = model_aabb(witch, witch_pivot); -#if 0 // halve aabb. ok - { - vec3 diag = sub3(boxg.max, boxg.min); - vec3 halve = scale3(diag, 0.25); - vec3 center = scale3(add3(boxg.min, boxg.max), 0.5); - boxg.min = sub3(center, halve); - boxg.max = add3(center, halve); - } -#endif - hit* h = aabb_hit_aabb(boxg, boxw); - if( h && GAME_FIRE ) { - vec3 dir = norm3(sub3(witch_p, girl_p)); - witch_p = add3(witch_p, mul3(dir,vec3(1,0,1))); - } - } - } - - // ui - if( ui_panel("Input", 0) ) { // @todo: showcase input binding - ui_section("Controllers"); - ui_label("Gamepad #1"); - ui_label("Keys I/J/K/L + Z/X"); - ui_panel_end(); - } - } -} - -// vec2 do_gamepad_polarity = vec2(+1,+1); -// vec2 do_gamepad_sensitivity = vec2(0.1f,0.1f); -// vec2 do_mouse_polarity = vec2(+1,-1); -// vec2 do_mouse_sensitivity = vec2(0.2f,0.2f); -// float do_gamepad_deadzone = 0.15f;// -// -// if(ui_separator()) {} -// if(ui_slider("Gamepad deadzone", &do_gamepad_deadzone)) {} -// if(ui_float2("Gamepad polarity", do_gamepad_polarity.v2)) {} -// if(ui_float2("Gamepad sensitivity", do_gamepad_sensitivity.v2)) {} -// if(ui_separator()) {} -// if(ui_float2("Mouse polarity", do_mouse_polarity.v2)) {} -// if(ui_float2("Mouse sensitivity", do_mouse_sensitivity.v2)) {}// diff --git a/demos/99-nodes.c b/demos/99-nodes.c deleted file mode 100644 index 0e3c094..0000000 --- a/demos/99-nodes.c +++ /dev/null @@ -1,877 +0,0 @@ -#define V4K_IMPLEMENTATION -#include "joint/v4k.h" - -/* -A basic node-based UI built with Nuklear. -Builds on the node editor example included in Nuklear v1.00, with the aim of -being used as a prototype for implementing a functioning node editor. - -Features: -- Nodes of different types. Currently their implementations are #included in - the main file, but they could easily be turned into eg. a plugin system. -- Pins/pins of different types -- currently float values and colors. -- Adding and removing nodes. -- Linking nodes, with validation (one link per input, only link similar pins). -- Detaching and moving links. -- Evaluation of output values of connected nodes. -- Memory management based on fixed size arrays for links and node pointers -- Multiple node types -- Multiple pin types -- Linking between pins of the same type -- Detaching and reattaching links -- Getting value from linked node if pin is connected - -Todo: -- Complete pin types. -- Allow dragging from output to input pin. -- Cut link by CTRL+clicking input pin. -- Cut link by drawing intersect line on a link. -- Group elemnts together with mouse, or LSHIFT+clicking. -- Drag groups. -- DEL elements. -- DEL groups. -- CTRL-C/CTRL-V/CTRL-X elements. -- CTRL-C/CTRL-V/CTRL-X groups. -- CTRL-Z,CTRL-Y. -- CTRL-N. -- CTRL-L,CTRL-S. -- CTRL-F. -- CTRL-Wheel Zooming. -- Allow to extend node types from Lua. - -Extra todo: -- Execution Flow (see: nk_stroke_triangle, nk_fill_triangle) -- Complete missing nodes (see: nk_draw_image, nk_draw_text) -- Right-click could visualize node/board diagram as Lua script. -- Once that done, copy/pasting scripts should work within editor. - -Sources: -- https://github.com/Immediate-Mode-UI/Nuklear/pull/561 -- https://github.com/vurtun/nuklear/blob/master/demo/node_editor.c -*/ - -typedef enum pin_type_t { - type_flow, - type_int,type_float, - type_block,type_texture,type_image, - type_color, - /* - type_bool, - type_char, type_string, - type_int2, type_int3, type_int4, - type_float2, type_float3, type_float4, - type_array, type_map, - */ - - type_total -} pin_type_t; - -struct node_pin { - pin_type_t pin_type; - nk_bool is_connected; - struct node* connected_node; - int connected_pin; -}; - -struct node { - int ID; - char name[32]; - struct nk_rect bounds; - int input_count; - int output_count; - struct node_pin *inputs; - struct node_pin *outputs; - struct { - float in_padding_x; - float in_padding_y; - float in_spacing_y; - float out_padding_x; - float out_padding_y; - float out_spacing_y; - } pin_spacing; /* Maybe this should be called "node_layout" and include the bounds? */ - struct node *next; /* Z ordering only */ - struct node *prev; /* Z ordering only */ - - void* (*eval_func)(struct node*, int oIndex); - void (*display_func)(struct nk_context*, struct node*); -}; - -struct node_link { - struct node* input_node; - int input_pin; - struct node* output_node; - int output_pin; - nk_bool is_active; -}; - -struct node_linking { - int active; - struct node *node; - int input_id; - int input_pin; -}; - -struct node_editor { - int initialized; - struct node *node_buf[32]; - struct node_link links[64]; - struct node *output_node; - struct node *begin; - struct node *end; - int node_count; - int link_count; - struct nk_rect bounds; - struct node *selected; - int show_grid; - struct nk_vec2 scrolling; - struct node_linking linking; -}; - -/* === PROTOTYPES === */ -/* The node implementations need these two functions. */ -/* These could/should go in a header file along with the node and node_pin structs and be #included in the node implementations */ - -struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count); -void* node_editor_eval_connected(struct node *node, int input_pin_number); -/* ================== */ - -/* === NODE TYPE IMPLEMENTATIONS === */ - -#define NODE_DEFAULT_ROW_HEIGHT 25 - - -// ---------------------------------------------------------------------------------------------------- -// #include "node_output.h" - -struct node_type_output { - struct node node; - struct nk_colorf input_val; -}; - -struct nk_colorf *node_output_get(struct node* node) { - struct node_type_output *output_node = (struct node_type_output*)node; - if (!node->inputs[0].is_connected) { - struct nk_colorf black = {0.0f, 0.0f, 0.0f, 0.0f}; - output_node->input_val = black; - } - return &output_node->input_val; -} - -static void node_output_display(struct nk_context *ctx, struct node *node) { - if (node->inputs[0].is_connected) { - struct node_type_output *output_node = (struct node_type_output*)node; - output_node->input_val = *(struct nk_colorf*)node_editor_eval_connected(node, 0); - nk_layout_row_dynamic(ctx, 60, 1); - nk_button_color(ctx, nk_rgba_cf(output_node->input_val)); - } -} - -struct node* node_output_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_output *output_node = (struct node_type_output*)node_editor_add(editor, sizeof(struct node_type_output), "Output", nk_rect(position.x, position.y, 100, 100), 1, 0); - if (output_node){ - output_node->node.inputs[0].pin_type = type_color; - output_node->node.display_func = node_output_display; - } - return (struct node*)output_node; -} - -// ---------------------------------------------------------------------------------------------------- -// #include "node_float.h" - -struct node_type_float { - struct node node; - float output_val; -}; - -static float *node_float_eval(struct node* node, int oIndex) { - struct node_type_float *float_node = (struct node_type_float*)node; - NK_ASSERT(oIndex == 0); - return &float_node->output_val; -} - -static void node_float_draw(struct nk_context *ctx, struct node *node) { - struct node_type_float *float_node = (struct node_type_float*)node; - nk_layout_row_dynamic(ctx, NODE_DEFAULT_ROW_HEIGHT, 1); - float_node->output_val = nk_propertyf(ctx, "#Value:", 0.0f, float_node->output_val, 1.0f, 0.01f, 0.01f); -} - -void node_float_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_float *float_node = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 75), 0, 1); - if (float_node) - { - float_node->output_val = 1.0f; - float_node->node.display_func = node_float_draw; - float_node->node.eval_func = (void*(*)(struct node*, int)) node_float_eval; - } -} - -// ---------------------------------------------------------------------------------------------------- -// #include "node_color.h" - -struct node_type_color { - struct node node; - float input_val[4]; - struct nk_colorf output_val; -}; - -static struct nk_colorf *node_color_eval(struct node* node, int oIndex) -{ - struct node_type_color *color_node = (struct node_type_color*)node; - NK_ASSERT(oIndex == 0); /* only one output connector */ - - return &color_node->output_val; -} - - -static void node_color_draw(struct nk_context *ctx, struct node *node) -{ - struct node_type_color *color_node = (struct node_type_color*)node; - float eval_result; /* Get the values from connected nodes into this so the inputs revert on disconnect */ - const char* labels[4] = {"#R:","#G:","#B:","#A:"}; - float color_val[4]; /* Because we can't just loop through the struct... */ - nk_layout_row_dynamic(ctx, NODE_DEFAULT_ROW_HEIGHT, 1); - nk_button_color(ctx, nk_rgba_cf(color_node->output_val)); - - for (int i = 0; i < 4; i++) - { - if (color_node->node.inputs[i].is_connected) { - eval_result = *(float*)node_editor_eval_connected(node, i); - eval_result = nk_propertyf(ctx, labels[i], eval_result, eval_result, eval_result, 0.01f, 0.01f); - color_val[i] = eval_result; - } - else { - color_node->input_val[i] = nk_propertyf(ctx, labels[i], 0.0f, color_node->input_val[i], 1.0f, 0.01f, 0.01f); - color_val[i] = color_node->input_val[i]; - } - } - - color_node->output_val.r = color_val[0]; - color_node->output_val.g = color_val[1]; - color_node->output_val.b = color_val[2]; - color_node->output_val.a = color_val[3]; -} - -void node_color_create(struct node_editor *editor, struct nk_vec2 position) -{ - struct node_type_color *color_node = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 190), 4, 1); - if (color_node) - { - const struct nk_colorf black = {0.0f, 0.0f, 0.0f, 1.0f}; - - for (int i = 0; i < color_node->node.input_count; i++) - color_node->node.inputs[i].pin_type = type_float; - color_node->node.outputs[0].pin_type = type_color; - - color_node->node.pin_spacing.in_padding_y += NODE_DEFAULT_ROW_HEIGHT; - - color_node->input_val[0] = 0.0f; - color_node->input_val[1] = 0.0f; - color_node->input_val[2] = 0.0f; - color_node->input_val[3] = 1.0f; - - color_node->output_val = black; - - color_node->node.display_func = node_color_draw; - color_node->node.eval_func = (void*(*)(struct node*, int)) node_color_eval; - } -} - -// ---------------------------------------------------------------------------------------------------- -// #include "node_blend.h" - -struct node_type_blend { - struct node node; - struct nk_colorf input_val[2]; - struct nk_colorf output_val; - float blend_val; -}; - -static struct nk_colorf *node_blend_eval(struct node *node, int oIndex) { - struct node_type_blend* blend_node = (struct node_type_blend*)node; - return &blend_node->output_val; -} - -static void node_blend_display(struct nk_context *ctx, struct node *node) { - struct node_type_blend *blend_node = (struct node_type_blend*)node; - const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; - float blend_amnt; - - nk_layout_row_dynamic(ctx, NODE_DEFAULT_ROW_HEIGHT, 1); - for (int i = 0; i < 2; i++){ - if(node->inputs[i].is_connected) { - blend_node->input_val[i] = *(struct nk_colorf*)node_editor_eval_connected(node, i); - } - else { - blend_node->input_val[i] = blank; - } - nk_button_color(ctx, nk_rgba_cf(blend_node->input_val[i])); - } - - if (node->inputs[2].is_connected) { - blend_amnt = *(float*)node_editor_eval_connected(node, 2); - blend_amnt = nk_propertyf(ctx, "#Blend", blend_amnt, blend_amnt, blend_amnt, 0.01f, 0.01f); - } - else { - blend_node->blend_val = nk_propertyf(ctx, "#Blend", 0.0f, blend_node->blend_val, 1.0f, 0.01f, 0.01f); - blend_amnt = blend_node->blend_val; - } - - - if(node->inputs[0].is_connected && node->inputs[1].is_connected) { - blend_node->output_val.r = blend_node->input_val[0].r * (1.0f-blend_amnt) + blend_node->input_val[1].r * blend_amnt; - blend_node->output_val.g = blend_node->input_val[0].g * (1.0f-blend_amnt) + blend_node->input_val[1].g * blend_amnt; - blend_node->output_val.b = blend_node->input_val[0].b * (1.0f-blend_amnt) + blend_node->input_val[1].b * blend_amnt; - blend_node->output_val.a = blend_node->input_val[0].a * (1.0f-blend_amnt) + blend_node->input_val[1].a * blend_amnt; - } - else { - blend_node->output_val = blank; - } -} - -void node_blend_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_blend* blend_node = (struct node_type_blend*)node_editor_add(editor, sizeof(struct node_type_blend), "Blend", nk_rect(position.x, position.y, 180, 130), 3, 1); - if (blend_node) { - const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; - for (int i = 0; i < (int)NK_LEN(blend_node->input_val); i++) - blend_node->node.inputs[i].pin_type = type_color; - blend_node->node.outputs[0].pin_type = type_color; - - // blend_node->node.pin_spacing.in_padding_y = 42.0f; - // blend_node->node.pin_spacing.in_spacing_y = 29.0f; - - for (int i = 0; i < (int)NK_LEN(blend_node->input_val); i++) - blend_node->input_val[i] = blank; - blend_node->output_val = blank; - - blend_node->blend_val = 0.5f; - - blend_node->node.display_func = node_blend_display; - blend_node->node.eval_func = (void*(*)(struct node*, int)) node_blend_eval; - - } -} - -/* ================================= */ - -#define NK_RGB3(r,g,b) {r,g,b,255} -#define BG_COLOR ((struct nk_color){60,60,60,192}) // nk_rgba(0,0,0,192) - -static -struct editor_node_style { - int pin_type; - const char *shape; - struct nk_color color_idle; - struct nk_color color_hover; -} styles[] = { - // order matters: - { type_flow, "triangle_right", NK_RGB3(200,200,200), NK_RGB3(255,255,255) }, // if .num_links == 0 - { type_int, "circle", NK_RGB3(33,227,175), NK_RGB3(135,239,195) }, - { type_float, "circle", NK_RGB3(156,253,65), NK_RGB3(144,225,137) }, - { type_block, "circle", NK_RGB3(6,165,239), NK_RGB3(137,196,247) }, - { type_texture, "circle", NK_RGB3(148,0,0), NK_RGB3(183,137,137) }, - { type_image, "circle", NK_RGB3(200,130,255), NK_RGB3(220,170,255) }, - { type_color, "circle", NK_RGB3(252,200,35), NK_RGB3(255,217,140) }, -}; - -#define COLOR_FLOW_HI styles[type_flow].color_hover -#define COLOR_FLOW_LO styles[type_flow].color_idle - -#define GRID_SIZE 64.0f -#define GRID_COLOR ((struct nk_color)NK_RGB3(80,80,120)) -#define GRID_THICKNESS 1.0f - -// 4 colors: top-left, top-right, bottom-right, bottom-left -#define GRID_BG_COLORS ((struct nk_color){30,30,30,255}), ((struct nk_color){40,20,0,255}), ((struct nk_color){30,30,30,255}), ((struct nk_color){20,30,40,255}) - -#define LINK_THICKNESS 1.0f -#define LINK_DRAW(POINT_A,POINT_B,COLOR) do { \ - vec2 a = (POINT_A); \ - vec2 b = (POINT_B); \ - nk_stroke_line(canvas, a.x, a.y, b.x, b.y, LINK_THICKNESS, COLOR); \ -} while(0) -#undef LINK_DRAW -#define LINK_DRAW(POINT_A,POINT_B,COLOR) do { \ - vec2 a = (POINT_A); \ - vec2 b = (POINT_B); \ - nk_stroke_curve(canvas, a.x, a.y, a.x+50, a.y, b.x-50, b.y, b.x, b.y, LINK_THICKNESS, COLOR); \ -} while(0) -#undef LINK_DRAW -#define LINK_DRAW(POINT_A,POINT_B,COLOR) do { \ - vec2 a = (POINT_A); \ - vec2 b = (POINT_B); \ - float dist2 = len2( sub2( ptr2(&b.x), ptr2(&a.x) ) ); \ - vec2 mid_a = mix2( ptr2(&a.x), ptr2(&b.x), 0.25 ); mid_a.y += dist2/2; \ - vec2 mid_b = mix2( ptr2(&a.x), ptr2(&b.x), 0.75 ); mid_b.y += dist2/3; \ - nk_stroke_curve(canvas, a.x, a.y, mid_a.x, mid_a.y, mid_b.x, mid_b.y, b.x, b.y, LINK_THICKNESS, COLOR); \ -} while(0) - - -#define PIN_RADIUS 12 -#define PIN_THICKNESS 1.0f -#define PIN_DRAW(PIN_ADDR,POINT,RADIUS) do { \ - circle.x = (POINT).x - (RADIUS) / 2; \ - circle.y = (POINT).y - (RADIUS) / 2; \ - circle.w = circle.h = (RADIUS); \ - struct nk_color color = node_get_type_color((PIN_ADDR).pin_type); \ - if((PIN_ADDR).is_connected) \ - nk_fill_circle(canvas, circle, color); \ - else \ - nk_stroke_circle(canvas, circle, PIN_THICKNESS, color); \ -} while(0) - - -static struct nk_color node_get_type_color(unsigned pin_type) { - for( int i = 0; i < type_total; ++i ) - if( styles[i].pin_type == pin_type ) - return styles[i].color_idle; - return ((struct nk_color)NK_RGB3(255,0,255)); -} - -static void node_editor_push(struct node_editor *editor, struct node *node) { - if (!editor->begin) { - node->next = NULL; - node->prev = NULL; - editor->begin = node; - editor->end = node; - } else { - node->prev = editor->end; - if (editor->end) - editor->end->next = node; - node->next = NULL; - editor->end = node; - } -} - -static void node_editor_pop(struct node_editor *editor, struct node *node) { - if (node->next) - node->next->prev = node->prev; - if (node->prev) - node->prev->next = node->next; - if (editor->end == node) - editor->end = node->prev; - if (editor->begin == node) - editor->begin = node->next; - node->next = NULL; - node->prev = NULL; -} - -static struct node* node_editor_find_by_id(struct node_editor *editor, int ID) { - struct node *iter = editor->begin; - while (iter) { - if (iter->ID == ID) - return iter; - iter = iter->next; - } - return NULL; -} - -static struct node_link* node_editor_find_link_by_output(struct node_editor *editor, struct node *output_node, int node_input_connector) { - for( int i = 0; i < editor->link_count; i++ ) { - if (editor->links[i].output_node == output_node && - editor->links[i].output_pin == node_input_connector && - editor->links[i].is_active == nk_true) { - return &editor->links[i]; - } - } - return NULL; -} - -static struct node_link* node_editor_find_link_by_input(struct node_editor *editor, struct node *input_node, int node_output_connector) { - for( int i = 0; i < editor->link_count; i++ ) { - if (editor->links[i].input_node == input_node && - editor->links[i].input_pin == node_output_connector && - editor->links[i].is_active == nk_true) { - return &editor->links[i]; - } - } - return NULL; -} - -static void node_editor_delete_link(struct node_link *link) { - link->is_active = nk_false; - link->input_node->outputs[link->input_pin].is_connected = nk_false; - link->output_node->inputs[link->output_pin].is_connected = nk_false; -} - -struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count) { - static int IDs = 0; - struct node *node = NULL; - - if ((nk_size)editor->node_count < NK_LEN(editor->node_buf)) { - /* node_buf has unused pins */ - node = MALLOC(nodeSize); - editor->node_buf[editor->node_count++] = node; - node->ID = IDs++; - } else { - /* check for freed up pins in node_buf */ - for (int i = 0; i < editor->node_count; i++) { - if (editor->node_buf[i] == NULL) { - node = MALLOC(nodeSize); - editor->node_buf[i] = node; - node->ID = i; - break; - } - } - } - if (node == NULL) { - puts("Node creation failed"); - return NULL; - } - - node->bounds = bounds; - - node->input_count = in_count; - node->output_count = out_count; - - node->inputs = MALLOC(node->input_count * sizeof(struct node_pin)); - node->outputs = MALLOC(node->output_count * sizeof(struct node_pin)); - - for (int i = 0; i < node->input_count; i++) { - node->inputs[i].is_connected = nk_false; - node->inputs[i].pin_type = type_float; /* default pin type */ - } - for (int i = 0; i < node->output_count; i++) { - node->outputs[i].is_connected = nk_false; - node->outputs[i].pin_type = type_float; /* default pin type */ - } - - /* default pin spacing */ - node->pin_spacing.in_padding_x = 2; - node->pin_spacing.in_padding_y = 32 + 25/2 + 6; // titlebar height + next half row + adjust - node->pin_spacing.in_spacing_y = 25; // row height+border - node->pin_spacing.out_padding_x = 3; - node->pin_spacing.out_padding_y = 32 + 25/2 + 6; // titlebar height + next half row + adjust - node->pin_spacing.out_spacing_y = 25; // row height+border - - strcpy(node->name, name); - node_editor_push(editor, node); - - return node; -} - -void *node_editor_eval_connected(struct node* node, int input_pin_number) { - NK_ASSERT(node->inputs[input_pin_number].is_connected); - return node->inputs[input_pin_number].connected_node->eval_func(node->inputs[input_pin_number].connected_node, node->inputs[input_pin_number].connected_pin); -} - -static void node_editor_link(struct node_editor *editor, struct node *in_node, int in_pin, struct node *out_node, int out_pin) { - /* Confusingly, in and out nodes/pins here refer to the inputs and outputs OF THE LINK ITSELF, not the nodes */ - struct node_link *link = NULL; - - if ((nk_size)editor->link_count < NK_LEN(editor->links)) { - link = &editor->links[editor->link_count++]; - } else { - for (int i = 0; i < (int)NK_LEN(editor->links); i++) - { - if (editor->links[i].is_active == nk_false) { - link = &editor->links[i]; - break; - } - } - } - if (link) { - out_node->inputs[out_pin].is_connected = nk_true; - in_node->outputs[in_pin].is_connected = nk_true; - out_node->inputs[out_pin].connected_node = in_node; - out_node->inputs[out_pin].connected_pin = in_pin; - - link->input_node = in_node; - link->input_pin = in_pin; - link->output_node = out_node; - link->output_pin = out_pin; - link->is_active = nk_true; - } else { - puts("Too many links"); - } -} - -static void node_editor_init(struct node_editor *editor) { - if (editor->initialized) return; - - struct nk_rect total_space = nk_window_get_content_region(ui_ctx); - struct nk_vec2 output_node_position = { total_space.w*2/3, total_space.h/3 }; - struct nk_vec2 color_node_position = { total_space.w*1/4, total_space.h/3 }; - - memset(editor, 0, sizeof(*editor)); - - editor->output_node = node_output_create(editor, output_node_position); - node_color_create(editor, color_node_position); - editor->show_grid = nk_true; - - editor->initialized = 1; -} - -static int node_editor(struct node_editor *editor) { - int n = 0; - struct nk_rect total_space; - const struct nk_input *in = &ui_ctx->input; - struct nk_command_buffer *canvas = nk_window_get_canvas(ui_ctx); - struct node *updated = 0; - - node_editor_init(editor); - - { - /* allocate complete window space */ - total_space = nk_window_get_content_region(ui_ctx); - nk_layout_space_begin(ui_ctx, NK_STATIC, total_space.h, editor->node_count); - { - struct node *it = editor->begin; - struct nk_rect size = nk_layout_space_bounds(ui_ctx); - struct nk_panel *nodePanel = 0; - - //nk_fill_rect(canvas, size, 0/*rounding*/, ((struct nk_color){30,30,30,255})); // 20,30,40,255 - nk_fill_rect_multi_color(canvas, size, GRID_BG_COLORS); - - if (editor->show_grid) { - /* display grid */ - for (float x = (float)fmod(size.x - editor->scrolling.x, GRID_SIZE); x < size.w; x += GRID_SIZE) - nk_stroke_line(canvas, x+size.x, size.y, x+size.x, size.y+size.h, GRID_THICKNESS, GRID_COLOR); - for (float y = (float)fmod(size.y - editor->scrolling.y, GRID_SIZE); y < size.h; y += GRID_SIZE) - nk_stroke_line(canvas, size.x, y+size.y, size.x+size.w, y+size.y, GRID_THICKNESS, GRID_COLOR); - } - - /* execute each node as a movable group */ - /* loop through nodes */ - while (it) { - /* Output node window should not have a close button */ - nk_flags nodePanel_flags = NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE; - if (it != editor->output_node) - nodePanel_flags |= NK_WINDOW_CLOSABLE; - - /* calculate scrolled node window position and size */ - nk_layout_space_push(ui_ctx, nk_rect(it->bounds.x - editor->scrolling.x, - it->bounds.y - editor->scrolling.y, it->bounds.w, it->bounds.h)); - - /* execute node window */ - char *name = va(" " ICON_MD_MENU " %s",it->name); //< @r-lyeh added some spacing+icon because of our UI customizations - -struct nk_color bak = ui_ctx->style.window.fixed_background.data.color; -ui_ctx->style.window.fixed_background.data.color = BG_COLOR; - - if (nk_group_begin(ui_ctx, name, nodePanel_flags)) - { - /* always have last selected node on top */ - - nodePanel = nk_window_get_panel(ui_ctx); - if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nodePanel->bounds) && - (!(it->prev && nk_input_mouse_clicked(in, NK_BUTTON_LEFT, - nk_layout_space_rect_to_screen(ui_ctx, nodePanel->bounds)))) && - editor->end != it) - { - updated = it; - } - - if ((nodePanel->flags & NK_WINDOW_HIDDEN)) /* Node close button has been clicked */ - { - /* Delete node */ - struct node_link *link_remove; - node_editor_pop(editor, it); - for (int n = 0; n < it->input_count; n++) { - if ((link_remove = node_editor_find_link_by_output(editor, it, n))) - { - node_editor_delete_link(link_remove); - } - } - for (int n = 0; n < it -> output_count; n++) { - while((link_remove = node_editor_find_link_by_input(editor, it, n))) - { - node_editor_delete_link(link_remove); - } - } - NK_ASSERT(editor->node_buf[it->ID] == it); - editor->node_buf[it->ID] = NULL; - FREE(it->inputs); - FREE(it->outputs); - FREE(it); - } - else { - - /* ================= NODE CONTENT ===================== */ - - it->display_func(ui_ctx, it); - - /* ==================================================== */ - - } - nk_group_end(ui_ctx); - - } - -ui_ctx->style.window.fixed_background.data.color = bak; - - if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) - { - /* node pin and linking */ - struct nk_rect bounds; - bounds = nk_layout_space_rect_to_local(ui_ctx, nodePanel->bounds); - bounds.x += editor->scrolling.x; - bounds.y += editor->scrolling.y; - it->bounds = bounds; - - /* output pins */ - for (int n = 0; n < it->output_count; ++n) { - struct nk_rect circle; - struct nk_vec2 pt = {nodePanel->bounds.x, nodePanel->bounds.y}; - pt.x += nodePanel->bounds.w - PIN_RADIUS / 2 + it->pin_spacing.out_padding_x; - pt.y += it->pin_spacing.out_padding_y + it->pin_spacing.out_spacing_y * (n); - PIN_DRAW(it->outputs[n],pt,PIN_RADIUS); - - /* start linking process */ - /* set linking active */ - if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true)) { - editor->linking.active = nk_true; - editor->linking.node = it; - editor->linking.input_id = it->ID; - editor->linking.input_pin = n; - } - - /* draw link being dragged (from linked pin to mouse position) */ - if (editor->linking.active && editor->linking.node == it && - editor->linking.input_pin == n) { - LINK_DRAW(vec2(circle.x+3,circle.y+3),ptr2(&in->mouse.pos.x),COLOR_FLOW_HI); - } - } - - /* input pins */ - for (int n = 0; n < it->input_count; ++n) { - struct nk_rect circle; - struct nk_vec2 pt = {nodePanel->bounds.x, nodePanel->bounds.y}; - pt.x += it->pin_spacing.in_padding_x; - pt.y += it->pin_spacing.in_padding_y + it->pin_spacing.in_spacing_y * (n); - PIN_DRAW(it->inputs[n],pt,PIN_RADIUS); - - /* Detach link */ - if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true) && - editor->linking.active == nk_false && - it->inputs[n].is_connected == nk_true) { - struct node_link *node_relink = node_editor_find_link_by_output(editor, it, n); - editor->linking.active = nk_true; - editor->linking.node = node_relink->input_node; - editor->linking.input_id = node_relink->input_node->ID; - editor->linking.input_pin = node_relink->input_pin; - node_editor_delete_link(node_relink); - } - - /* Create link */ - if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && - nk_input_is_mouse_hovering_rect(in, circle) && - editor->linking.active && - editor->linking.node != it && - it->inputs[n].pin_type == editor->linking.node->outputs[editor->linking.input_pin].pin_type && - it->inputs[n].is_connected != nk_true) { - editor->linking.active = nk_false; - - node_editor_link(editor, editor->linking.node, - editor->linking.input_pin, it, n); - } - } - } - it = it->next; - } - - /* reset (output) linking connection */ - if (editor->linking.active && (!!input(KEY_LCTRL) || !!input(KEY_RCTRL) || nk_input_is_mouse_released(in, NK_BUTTON_LEFT))) { - editor->linking.active = nk_false; - editor->linking.node = NULL; - } - - /* draw each static link */ - for (int n = 0; n < editor->link_count; ++n) { - struct node_link *link = &editor->links[n]; - if (link->is_active == nk_true){ - struct node *ni = link->input_node; - struct node *no = link->output_node; - struct nk_vec2 l0 = nk_layout_space_to_screen(ui_ctx, nk_vec2(ni->bounds.x + ni->bounds.w + ni->pin_spacing.out_padding_x, 3.0f + ni->bounds.y + ni->pin_spacing.out_padding_y + ni->pin_spacing.out_spacing_y * (link->input_pin))); - struct nk_vec2 l1 = nk_layout_space_to_screen(ui_ctx, nk_vec2(no->bounds.x + no->pin_spacing.in_padding_x, 3.0f + no->bounds.y + no->pin_spacing.in_padding_y + no->pin_spacing.in_spacing_y * (link->output_pin))); - - l0.x -= editor->scrolling.x; - l0.y -= editor->scrolling.y; - l1.x -= editor->scrolling.x; - l1.y -= editor->scrolling.y; - - struct nk_color color = node_get_type_color(no->inputs[link->output_pin].pin_type); - LINK_DRAW(ptr2(&l0.x), ptr2(&l1.x), color); - } - } - - if (updated) { - /* reshuffle nodes to have least recently selected node on top */ - node_editor_pop(editor, updated); - node_editor_push(editor, updated); - } - - /* node selection */ - if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nk_layout_space_bounds(ui_ctx))) { - it = editor->begin; - editor->selected = NULL; - editor->bounds = nk_rect(in->mouse.pos.x, in->mouse.pos.y, 100, 200); - while (it) { - struct nk_rect b = nk_layout_space_rect_to_screen(ui_ctx, it->bounds); - b.x -= editor->scrolling.x; - b.y -= editor->scrolling.y; - if (nk_input_is_mouse_hovering_rect(in, b)) - editor->selected = it; - it = it->next; - } - } - - /* contextual menu */ - if (nk_contextual_begin(ui_ctx, 0, nk_vec2(150, 220), nk_window_get_bounds(ui_ctx))) { - struct nk_vec2 wincoords = { in->mouse.pos.x-total_space.x-50, in->mouse.pos.y-total_space.y-32 }; - -#if 1 - static char *filter = 0; - static int do_filter = 0; - if( input_down(KEY_F) ) if( input(KEY_LCTRL) || input(KEY_RCTRL) ) do_filter ^= 1; - int choice = ui_toolbar(ICON_MD_SEARCH ";"); - if( choice == 1 ) do_filter = 1; - if( do_filter ) { - ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &filter); - if( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 ) { // if clicked on CANCEL icon (1st icon) - do_filter = 0; - } - } else { - if( filter ) filter[0] = '\0'; - } - char *filter_mask = filter && filter[0] ? va("*%s*", filter) : "*"; -#endif - - #define ui_label_filtered(lbl) (strmatchi(lbl,filter_mask) && ui_label(lbl)) - - int close = 0; - if (ui_label_filtered("=Add Color node")) close=1,node_color_create(editor, wincoords); - if (ui_label_filtered("=Add Float node")) close=1,node_float_create(editor, wincoords); - if (ui_label_filtered("=Add Blend Node")) close=1,node_blend_create(editor, wincoords); - if (ui_label_filtered(editor->show_grid ? "=Hide Grid" : "=Show Grid")) - close=1,editor->show_grid = !editor->show_grid; - if(close) do_filter = 0, (filter ? filter[0] = '\0' : '\0'), nk_contextual_close(ui_ctx); - nk_contextual_end(ui_ctx); - } - } - nk_layout_space_end(ui_ctx); - - /* window content scrolling */ - if (nk_input_is_mouse_hovering_rect(in, nk_window_get_bounds(ui_ctx)) && - nk_input_is_mouse_down(in, NK_BUTTON_MIDDLE)) { - editor->scrolling.x += in->mouse.delta.x; - editor->scrolling.y += in->mouse.delta.y; - } - } - - return !nk_window_is_closed(ui_ctx, "NodeEdit"); -} - - - - -int main() { - static int open = 1; - window_create(0.75, 0); - while(window_swap() && open) { - if( ui_window("Node editor",&open) ) { - static struct node_editor nodeEditor = {0}; - node_editor(&nodeEditor); - ui_window_end(); - } - } -} diff --git a/demos/art/sprites/Treasure Hunters/Captain Clown Nose.ase b/demos/art/sprites/Treasure Hunters/Captain Clown Nose.ase new file mode 100644 index 0000000..b4b6335 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Captain Clown Nose.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Crew-Crabby.ase b/demos/art/sprites/Treasure Hunters/Crew-Crabby.ase new file mode 100644 index 0000000..dfd4cf8 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Crew-Crabby.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Crew-Fierce Tooth.ase b/demos/art/sprites/Treasure Hunters/Crew-Fierce Tooth.ase new file mode 100644 index 0000000..7c5f11a Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Crew-Fierce Tooth.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Crew-Pink Start.ase b/demos/art/sprites/Treasure Hunters/Crew-Pink Start.ase new file mode 100644 index 0000000..4f6e1ad Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Crew-Pink Start.ase differ diff --git a/demos/art/sprites/Treasure Hunters/FX1-Dust Particles.ase b/demos/art/sprites/Treasure Hunters/FX1-Dust Particles.ase new file mode 100644 index 0000000..1bf9c3f Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/FX1-Dust Particles.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Chest.ase b/demos/art/sprites/Treasure Hunters/Props-Chest.ase new file mode 100644 index 0000000..4a18738 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Chest.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Decorations.ase b/demos/art/sprites/Treasure Hunters/Props-Decorations.ase new file mode 100644 index 0000000..cc12e94 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Decorations.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Flag.ase b/demos/art/sprites/Treasure Hunters/Props-Flag.ase new file mode 100644 index 0000000..dd29052 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Flag.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Merchant Ship.ase b/demos/art/sprites/Treasure Hunters/Props-Merchant Ship.ase new file mode 100644 index 0000000..2147b67 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Merchant Ship.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Palm Tree.ase b/demos/art/sprites/Treasure Hunters/Props-Palm Tree.ase new file mode 100644 index 0000000..19e4452 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Palm Tree.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Pirate Treasure.ase b/demos/art/sprites/Treasure Hunters/Props-Pirate Treasure.ase new file mode 100644 index 0000000..11b5e74 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Pirate Treasure.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Ship Helm.ase b/demos/art/sprites/Treasure Hunters/Props-Ship Helm.ase new file mode 100644 index 0000000..693699c Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Ship Helm.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Shooter Traps.ase b/demos/art/sprites/Treasure Hunters/Props-Shooter Traps.ase new file mode 100644 index 0000000..e5a22a0 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Shooter Traps.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-TileSets.ase b/demos/art/sprites/Treasure Hunters/Props-TileSets.ase new file mode 100644 index 0000000..8a560d7 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-TileSets.ase differ diff --git a/demos/art/sprites/Treasure Hunters/Props-Water Reflect.ase b/demos/art/sprites/Treasure Hunters/Props-Water Reflect.ase new file mode 100644 index 0000000..537cd5f Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/Props-Water Reflect.ase differ diff --git a/demos/art/sprites/Treasure Hunters/UI-Button Cooldown.ase b/demos/art/sprites/Treasure Hunters/UI-Button Cooldown.ase new file mode 100644 index 0000000..07c1295 Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/UI-Button Cooldown.ase differ diff --git a/demos/art/sprites/Treasure Hunters/UI-Dialogue.ase b/demos/art/sprites/Treasure Hunters/UI-Dialogue.ase new file mode 100644 index 0000000..341aead Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/UI-Dialogue.ase differ diff --git a/demos/art/sprites/Treasure Hunters/UI-Wood and Paper.ase b/demos/art/sprites/Treasure Hunters/UI-Wood and Paper.ase new file mode 100644 index 0000000..81b64db Binary files /dev/null and b/demos/art/sprites/Treasure Hunters/UI-Wood and Paper.ase differ diff --git a/demos/art/sprites/Treasure Hunters/_license b/demos/art/sprites/Treasure Hunters/_license new file mode 100644 index 0000000..66abd7d --- /dev/null +++ b/demos/art/sprites/Treasure Hunters/_license @@ -0,0 +1,123 @@ +https://pixelfrog-assets.itch.io/treasure-hunters + +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. \ No newline at end of file diff --git a/demos/art/sprites/spines/goblins.atlas b/demos/art/sprites/spines/goblins.atlas new file mode 100644 index 0000000..e601faf --- /dev/null +++ b/demos/art/sprites/spines/goblins.atlas @@ -0,0 +1,98 @@ + +goblins.png + size: 1024, 128 + filter: Linear, Linear + pma: true +dagger + bounds: 2, 18, 26, 108 +goblin/eyes-closed + bounds: 2, 4, 34, 12 +goblin/head + bounds: 113, 23, 103, 66 + rotate: 90 +goblin/left-arm + bounds: 937, 89, 37, 35 + rotate: 90 +goblin/left-foot + bounds: 609, 61, 65, 31 + rotate: 90 +goblin/left-hand + bounds: 840, 21, 36, 41 +goblin/left-lower-leg + bounds: 504, 56, 33, 70 +goblin/left-shoulder + bounds: 745, 17, 29, 44 +goblin/left-upper-leg + bounds: 397, 53, 33, 73 +goblin/neck + bounds: 862, 85, 36, 41 +goblin/pelvis + bounds: 776, 18, 62, 43 +goblin/right-arm + bounds: 181, 5, 23, 50 + rotate: 90 +goblin/right-foot + bounds: 747, 63, 63, 33 + rotate: 90 +goblin/right-hand + bounds: 878, 3, 36, 37 +goblin/right-lower-leg + bounds: 321, 50, 36, 76 +goblin/right-shoulder + bounds: 663, 14, 39, 45 +goblin/right-upper-leg + bounds: 675, 63, 34, 63 +goblin/torso + bounds: 181, 30, 68, 96 +goblin/undie-straps + bounds: 38, 2, 55, 19 +goblin/undies + bounds: 974, 97, 36, 29 +goblingirl/eyes-closed + bounds: 397, 30, 37, 21 +goblingirl/head + bounds: 30, 23, 103, 81 + rotate: 90 +goblingirl/left-arm + bounds: 916, 8, 37, 35 + rotate: 90 +goblingirl/left-foot + bounds: 642, 61, 65, 31 + rotate: 90 +goblingirl/left-hand + bounds: 900, 86, 35, 40 +goblingirl/left-lower-leg + bounds: 539, 56, 33, 70 +goblingirl/left-shoulder + bounds: 633, 13, 28, 46 +goblingirl/left-upper-leg + bounds: 574, 56, 33, 70 +goblingirl/neck + bounds: 878, 42, 35, 41 +goblingirl/pelvis + bounds: 817, 64, 62, 43 + rotate: 90 +goblingirl/right-arm + bounds: 603, 4, 28, 50 +goblingirl/right-foot + bounds: 782, 63, 63, 33 + rotate: 90 +goblingirl/right-hand + bounds: 915, 47, 36, 37 +goblingirl/right-lower-leg + bounds: 359, 50, 36, 76 +goblingirl/right-shoulder + bounds: 704, 16, 39, 45 +goblingirl/right-upper-leg + bounds: 711, 63, 34, 63 +goblingirl/torso + bounds: 251, 30, 68, 96 +goblingirl/undie-straps + bounds: 95, 2, 55, 19 +goblingirl/undies + bounds: 974, 66, 36, 29 +shield + bounds: 432, 54, 70, 72 +spear + bounds: 233, 6, 22, 368 + rotate: 90 \ No newline at end of file diff --git a/demos/art/sprites/spines/goblins.json b/demos/art/sprites/spines/goblins.json new file mode 100644 index 0000000..14d356e --- /dev/null +++ b/demos/art/sprites/spines/goblins.json @@ -0,0 +1,627 @@ +{ +"skeleton": { + "hash": "djttFmlR6Co", + "spine": "4.1.17", + "x": -92.53, + "y": -5.3, + "width": 234.03, + "height": 354.91, + "images": "./images/", + "audio": "" +}, +"bones": [ + { "name": "root" }, + { "name": "hip", "parent": "root", "x": 0.65, "y": 114.41, "color": "ffd300ff" }, + { + "name": "torso", + "parent": "hip", + "length": 85.83, + "rotation": 93.93, + "x": -6.42, + "y": 1.98, + "color": "ffd300ff" + }, + { + "name": "neck", + "parent": "torso", + "length": 18.38, + "rotation": -1.52, + "x": 81.68, + "y": -6.35, + "color": "ffd300ff" + }, + { + "name": "head", + "parent": "neck", + "length": 68.29, + "rotation": -13.92, + "x": 20.94, + "y": 11.59, + "color": "ffd300ff" + }, + { + "name": "left-shoulder", + "parent": "torso", + "length": 35.43, + "rotation": -156.96, + "x": 74.05, + "y": -20.39, + "color": "ff0000ff" + }, + { + "name": "left-arm", + "parent": "left-shoulder", + "length": 35.62, + "rotation": 28.17, + "x": 37.86, + "y": -2.35, + "color": "ff0000ff" + }, + { + "name": "left-upper-leg", + "parent": "hip", + "length": 50.4, + "rotation": -89.1, + "x": 14.45, + "y": 2.81, + "color": "ff0000ff" + }, + { + "name": "left-lower-leg", + "parent": "left-upper-leg", + "length": 49.9, + "rotation": -16.66, + "x": 56.34, + "y": 0.99, + "color": "ff0000ff" + }, + { + "name": "left-foot", + "parent": "left-lower-leg", + "length": 46.5, + "rotation": 102.43, + "x": 58.94, + "y": -7.61, + "color": "ff0000ff" + }, + { + "name": "left-hand", + "parent": "left-arm", + "length": 11.52, + "rotation": 2.7, + "x": 35.62, + "y": 0.08, + "color": "ff0000ff" + }, + { "name": "pelvis", "parent": "hip", "x": 1.41, "y": -6.58, "color": "ffd300ff" }, + { + "name": "right-shoulder", + "parent": "torso", + "length": 37.25, + "rotation": 133.89, + "x": 76.02, + "y": 18.15, + "color": "54ff00ff" + }, + { + "name": "right-arm", + "parent": "right-shoulder", + "length": 36.75, + "rotation": 36.33, + "x": 37.61, + "y": 0.31, + "color": "54ff00ff" + }, + { + "name": "right-upper-leg", + "parent": "hip", + "length": 42.46, + "rotation": -97.5, + "x": -20.08, + "y": -6.84, + "color": "54ff00ff" + }, + { + "name": "right-lower-leg", + "parent": "right-upper-leg", + "length": 58.53, + "rotation": -14.34, + "x": 43, + "y": -0.62, + "color": "54ff00ff" + }, + { + "name": "right-foot", + "parent": "right-lower-leg", + "length": 45.46, + "rotation": 110.31, + "x": 64.89, + "y": 0.04, + "color": "54ff00ff" + }, + { + "name": "right-hand", + "parent": "right-arm", + "length": 15.32, + "rotation": 2.36, + "x": 36.9, + "y": 0.35, + "color": "54ff00ff" + } +], +"slots": [ + { "name": "left-shoulder", "bone": "left-shoulder", "attachment": "left-shoulder" }, + { "name": "left-arm", "bone": "left-arm", "attachment": "left-arm" }, + { "name": "left-hand-item", "bone": "left-hand", "attachment": "spear" }, + { "name": "left-hand", "bone": "left-hand", "attachment": "left-hand" }, + { "name": "left-foot", "bone": "left-foot", "attachment": "left-foot" }, + { "name": "left-lower-leg", "bone": "left-lower-leg", "attachment": "left-lower-leg" }, + { "name": "left-upper-leg", "bone": "left-upper-leg", "attachment": "left-upper-leg" }, + { "name": "neck", "bone": "neck", "attachment": "neck" }, + { "name": "torso", "bone": "torso", "attachment": "torso" }, + { "name": "pelvis", "bone": "pelvis", "attachment": "pelvis" }, + { "name": "right-foot", "bone": "right-foot", "attachment": "right-foot" }, + { "name": "right-lower-leg", "bone": "right-lower-leg", "attachment": "right-lower-leg" }, + { "name": "undie-straps", "bone": "pelvis", "attachment": "undie-straps" }, + { "name": "undies", "bone": "pelvis", "attachment": "undies" }, + { "name": "right-upper-leg", "bone": "right-upper-leg", "attachment": "right-upper-leg" }, + { "name": "head", "bone": "head", "attachment": "head" }, + { "name": "eyes", "bone": "head" }, + { "name": "right-shoulder", "bone": "right-shoulder", "attachment": "right-shoulder" }, + { "name": "right-arm", "bone": "right-arm", "attachment": "right-arm" }, + { "name": "right-hand-item", "bone": "right-hand" }, + { "name": "right-hand", "bone": "right-hand", "attachment": "right-hand" }, + { "name": "right-hand-item-top", "bone": "right-hand", "attachment": "shield" } +], +"skins": [ + { + "name": "default", + "attachments": { + "left-hand-item": { + "dagger": { "x": 7.88, "y": -23.46, "rotation": 10.48, "width": 26, "height": 108 }, + "spear": { "x": -4.56, "y": 39.2, "rotation": 13.05, "width": 22, "height": 368 } + }, + "right-hand-item": { + "dagger": { "x": 6.52, "y": -24.16, "rotation": -8.06, "width": 26, "height": 108 } + }, + "right-hand-item-top": { + "shield": { "rotation": 93.5, "width": 70, "height": 72 } + } + } + }, + { + "name": "goblin", + "attachments": { + "eyes": { + "eyes-closed": { "name": "goblin/eyes-closed", "x": 32.22, "y": -21.27, "rotation": -88.93, "width": 34, "height": 12 } + }, + "head": { + "head": { "name": "goblin/head", "x": 25.74, "y": 2.33, "rotation": -92.29, "width": 103, "height": 66 } + }, + "left-arm": { + "left-arm": { + "name": "goblin/left-arm", + "x": 16.7, + "y": -1.69, + "scaleX": 1.0573, + "scaleY": 1.0573, + "rotation": 33.85, + "width": 37, + "height": 35 + } + }, + "left-foot": { + "left-foot": { "name": "goblin/left-foot", "x": 24.85, "y": 8.75, "rotation": 3.32, "width": 65, "height": 31 } + }, + "left-hand": { + "left-hand": { + "name": "goblin/left-hand", + "x": 3.47, + "y": 3.41, + "scaleX": 0.8922, + "scaleY": 0.8922, + "rotation": 31.14, + "width": 36, + "height": 41 + } + }, + "left-lower-leg": { + "left-lower-leg": { "name": "goblin/left-lower-leg", "x": 23.59, "y": -2.07, "rotation": 105.76, "width": 33, "height": 70 } + }, + "left-shoulder": { + "left-shoulder": { "name": "goblin/left-shoulder", "x": 15.56, "y": -2.27, "rotation": 62.01, "width": 29, "height": 44 } + }, + "left-upper-leg": { + "left-upper-leg": { "name": "goblin/left-upper-leg", "x": 29.69, "y": -3.87, "rotation": 89.1, "width": 33, "height": 73 } + }, + "neck": { + "neck": { "name": "goblin/neck", "x": 10.1, "y": 0.42, "rotation": -93.7, "width": 36, "height": 41 } + }, + "pelvis": { + "pelvis": { "name": "goblin/pelvis", "x": -5.62, "y": 0.77, "width": 62, "height": 43 } + }, + "right-arm": { + "right-arm": { "name": "goblin/right-arm", "x": 16.44, "y": -1.04, "rotation": 94.32, "width": 23, "height": 50 } + }, + "right-foot": { + "right-foot": { "name": "goblin/right-foot", "x": 23.57, "y": 9.8, "rotation": 1.53, "width": 63, "height": 33 } + }, + "right-hand": { + "right-hand": { "name": "goblin/right-hand", "x": 7.89, "y": 2.78, "rotation": 91.96, "width": 36, "height": 37 } + }, + "right-lower-leg": { + "right-lower-leg": { "name": "goblin/right-lower-leg", "x": 25.68, "y": -3.16, "rotation": 111.84, "width": 36, "height": 76 } + }, + "right-shoulder": { + "right-shoulder": { "name": "goblin/right-shoulder", "x": 15.68, "y": -1.03, "rotation": 130.65, "width": 39, "height": 45 } + }, + "right-upper-leg": { + "right-upper-leg": { "name": "goblin/right-upper-leg", "x": 20.35, "y": 1.48, "rotation": 97.5, "width": 34, "height": 63 } + }, + "torso": { + "torso": { "name": "goblin/torso", "x": 38.1, "y": -3.87, "rotation": -94.95, "width": 68, "height": 96 } + }, + "undie-straps": { + "undie-straps": { "name": "goblin/undie-straps", "x": -3.88, "y": 13.11, "scaleX": 1.0896, "width": 55, "height": 19 } + }, + "undies": { + "undies": { "name": "goblin/undies", "x": 6.3, "y": 0.13, "rotation": 0.92, "width": 36, "height": 29 } + } + } + }, + { + "name": "goblingirl", + "attachments": { + "eyes": { + "eyes-closed": { "name": "goblingirl/eyes-closed", "x": 28, "y": -25.55, "rotation": -87.05, "width": 37, "height": 21 } + }, + "head": { + "head": { "name": "goblingirl/head", "x": 27.72, "y": -4.32, "rotation": -85.58, "width": 103, "height": 81 } + }, + "left-arm": { + "left-arm": { "name": "goblingirl/left-arm", "x": 19.64, "y": -2.43, "rotation": 33.05, "width": 37, "height": 35 } + }, + "left-foot": { + "left-foot": { "name": "goblingirl/left-foot", "x": 25.18, "y": 7.92, "rotation": 3.32, "width": 65, "height": 31 } + }, + "left-hand": { + "left-hand": { + "name": "goblingirl/left-hand", + "x": 4.34, + "y": 2.39, + "scaleX": 0.8965, + "scaleY": 0.8965, + "rotation": 30.35, + "width": 35, + "height": 40 + } + }, + "left-lower-leg": { + "left-lower-leg": { "name": "goblingirl/left-lower-leg", "x": 25.02, "y": -0.61, "rotation": 105.76, "width": 33, "height": 70 } + }, + "left-shoulder": { + "left-shoulder": { "name": "goblingirl/left-shoulder", "x": 19.81, "y": -0.43, "rotation": 61.22, "width": 28, "height": 46 } + }, + "left-upper-leg": { + "left-upper-leg": { "name": "goblingirl/left-upper-leg", "x": 30.22, "y": -2.95, "rotation": 89.1, "width": 33, "height": 70 } + }, + "neck": { + "neck": { "name": "goblingirl/neck", "x": 6.16, "y": -3.15, "rotation": -98.86, "width": 35, "height": 41 } + }, + "pelvis": { + "pelvis": { "name": "goblingirl/pelvis", "x": -3.88, "y": 3.19, "width": 62, "height": 43 } + }, + "right-arm": { + "right-arm": { "name": "goblingirl/right-arm", "x": 16.85, "y": -0.66, "rotation": 93.53, "width": 28, "height": 50 } + }, + "right-foot": { + "right-foot": { "name": "goblingirl/right-foot", "x": 23.46, "y": 9.66, "rotation": 1.53, "width": 63, "height": 33 } + }, + "right-hand": { + "right-hand": { "name": "goblingirl/right-hand", "x": 7.22, "y": 3.44, "rotation": 91.17, "width": 36, "height": 37 } + }, + "right-lower-leg": { + "right-lower-leg": { "name": "goblingirl/right-lower-leg", "x": 26.15, "y": -3.28, "rotation": 111.84, "width": 36, "height": 76 } + }, + "right-shoulder": { + "right-shoulder": { "name": "goblingirl/right-shoulder", "x": 14.46, "y": 0.46, "rotation": 129.85, "width": 39, "height": 45 } + }, + "right-upper-leg": { + "right-upper-leg": { "name": "goblingirl/right-upper-leg", "x": 19.7, "y": 2.13, "rotation": 97.5, "width": 34, "height": 63 } + }, + "torso": { + "torso": { "name": "goblingirl/torso", "x": 36.28, "y": -5.14, "rotation": -95.75, "width": 68, "height": 96 } + }, + "undie-straps": { + "undie-straps": { "name": "goblingirl/undie-straps", "x": -1.52, "y": 14.19, "width": 55, "height": 19 } + }, + "undies": { + "undies": { "name": "goblingirl/undies", "x": 5.4, "y": 1.71, "width": 36, "height": 29 } + } + } + } +], +"animations": { + "walk": { + "slots": { + "eyes": { + "attachment": [ + { "time": 0.7, "name": "eyes-closed" }, + { "time": 0.8 } + ] + } + }, + "bones": { + "left-upper-leg": { + "rotate": [ + { "value": -26.56 }, + { "time": 0.1333, "value": -8.79 }, + { "time": 0.2333, "value": 9.51 }, + { "time": 0.3667, "value": 30.74 }, + { "time": 0.5, "value": 25.34 }, + { "time": 0.6333, "value": 26.12 }, + { "time": 0.7333, "value": -7.71 }, + { "time": 0.8667, "value": -21.19 }, + { "time": 1, "value": -26.56 } + ], + "translate": [ + { "x": -1.32, "y": 1.71 }, + { "time": 0.3667, "x": -0.06, "y": 2.43 }, + { "time": 1, "x": -1.32, "y": 1.71 } + ] + }, + "right-upper-leg": { + "rotate": [ + { "value": 42.45 }, + { "time": 0.1333, "value": 52.11 }, + { "time": 0.2333, "value": 8.54 }, + { "time": 0.5, "value": -16.94 }, + { "time": 0.6333, "value": 1.9 }, + { + "time": 0.7333, + "value": 28.06, + "curve": [ 0.795, 31.71, 0.867, 58.69 ] + }, + { + "time": 0.8667, + "value": 58.69, + "curve": [ 0.933, 58.35, 1, 42.45 ] + }, + { "time": 1, "value": 42.45 } + ], + "translate": [ + { "x": 6.24 }, + { "time": 0.2333, "x": 2.14, "y": 2.4 }, + { "time": 0.5, "x": 2.44, "y": 4.8 }, + { "time": 1, "x": 6.24 } + ] + }, + "left-lower-leg": { + "rotate": [ + { "value": -22.98 }, + { "time": 0.1333, "value": -63.51 }, + { "time": 0.2333, "value": -73.76 }, + { "time": 0.5, "value": 5.12 }, + { "time": 0.6333, "value": -28.3 }, + { "time": 0.7333, "value": 4.08 }, + { "time": 0.8667, "value": 3.53 }, + { "time": 1, "value": -22.98 } + ], + "translate": [ + {}, + { "time": 0.2333, "x": 2.56, "y": -0.47 }, + { "time": 0.5 } + ] + }, + "left-foot": { + "rotate": [ + { "value": -3.69 }, + { "time": 0.1333, "value": -10.42 }, + { "time": 0.2333, "value": -5.01 }, + { "time": 0.3667, "value": 3.87 }, + { "time": 0.5, "value": -3.88 }, + { "time": 0.6333, "value": 2.78 }, + { "time": 0.7333, "value": 1.68 }, + { "time": 0.8667, "value": -8.54 }, + { "time": 1, "value": -3.69 } + ] + }, + "right-shoulder": { + "rotate": [ + { + "value": 5.29, + "curve": [ 0.167, 5.29, 0.475, 6.65 ] + }, + { "time": 0.6333, "value": 6.65 }, + { "time": 1, "value": 5.29 } + ] + }, + "right-arm": { + "rotate": [ + { + "value": -4.03, + "curve": [ 0.169, -3.91, 0.51, 19.66 ] + }, + { + "time": 0.6333, + "value": 19.79, + "curve": [ 0.746, 19.75, 0.922, -3.91 ] + }, + { "time": 1, "value": -4.03 } + ] + }, + "right-hand": { + "rotate": [ + { "value": 8.99 }, + { "time": 0.6333, "value": 0.51 }, + { "time": 1, "value": 8.99 } + ] + }, + "left-shoulder": { + "rotate": [ + { + "value": 6.26, + "curve": [ 0.17, 6.26, 0.342, -11.79 ] + }, + { + "time": 0.5, + "value": -11.79, + "curve": [ 0.641, -11.79, 0.843, 6.16 ] + }, + { "time": 1, "value": 6.26 } + ], + "translate": [ + { "x": 1.15, "y": 0.24 } + ] + }, + "left-hand": { + "rotate": [ + { + "value": -21.24, + "curve": [ 0.148, -21.24, 0.378, -27.21 ] + }, + { + "time": 0.5, + "value": -27.28, + "curve": [ 0.621, -27.28, 0.875, -21.4 ] + }, + { "time": 1, "value": -21.24 } + ] + }, + "left-arm": { + "rotate": [ + { + "value": 28.38, + "curve": [ 0.17, 28.38, 0.342, 60.09 ] + }, + { + "time": 0.5, + "value": 60.09, + "curve": [ 0.641, 60.09, 0.843, 28.54 ] + }, + { "time": 1, "value": 28.38 } + ] + }, + "torso": { + "rotate": [ + { "value": -10.28 }, + { + "time": 0.1333, + "value": -15.39, + "curve": [ 0.261, -15.36, 0.324, -9.78 ] + }, + { + "time": 0.3667, + "value": -9.78, + "curve": [ 0.521, -10.8, 0.545, -15.72 ] + }, + { + "time": 0.6333, + "value": -15.75, + "curve": [ 0.688, -15.66, 0.819, -7.07 ] + }, + { + "time": 0.8667, + "value": -7.07, + "curve": [ 0.895, -7.07, 0.975, -10.25 ] + }, + { "time": 1, "value": -10.28 } + ], + "translate": [ + { "x": -1.29, "y": 1.69 } + ] + }, + "right-foot": { + "rotate": [ + { "value": -5.25 }, + { "time": 0.2333, "value": -1.91 }, + { "time": 0.3667, "value": -6.45 }, + { "time": 0.5, "value": -5.4 }, + { "time": 0.7333, "value": -11.69 }, + { "time": 0.8667, "value": 0.46 }, + { "time": 1, "value": -5.25 } + ] + }, + "right-lower-leg": { + "rotate": [ + { + "value": -3.39, + "curve": [ 0.042, -4.05, 0.099, -45.1 ] + }, + { + "time": 0.1333, + "value": -45.53, + "curve": [ 0.156, -45.53, 0.207, -5.89 ] + }, + { "time": 0.2333, "value": -4.83 }, + { "time": 0.5, "value": -19.53 }, + { "time": 0.6333, "value": -64.8 }, + { + "time": 0.7333, + "value": -82.56, + "curve": [ 0.882, -68.28, 1, -3.39 ] + }, + { "time": 1, "value": -3.39 } + ], + "translate": [ + { "time": 0.5 }, + { "time": 0.6333, "x": 2.19, "y": 0.21 }, + { "time": 1 } + ] + }, + "hip": { + "translate": [ + { "y": -4.16 }, + { + "time": 0.1333, + "y": -7.06, + "curve": [ 0.217, 0, 0.284, 0, 0.217, -0.53, 0.284, 3.27 ] + }, + { "time": 0.3667, "y": 6.78 }, + { "time": 0.5, "y": -6.14 }, + { + "time": 0.6333, + "y": -7.06, + "curve": [ 0.717, 0, 0.784, 0, 0.717, -0.53, 0.784, 3.27 ] + }, + { "time": 0.8667, "y": 6.78 }, + { "time": 1, "y": -4.16 } + ] + }, + "neck": { + "rotate": [ + { "value": 3.6 }, + { "time": 0.1333, "value": 17.5 }, + { "time": 0.2333, "value": 6.11 }, + { "time": 0.3667, "value": 3.46 }, + { "time": 0.5, "value": 5.18 }, + { "time": 0.6333, "value": 18.36 }, + { "time": 0.7333, "value": 6.09 }, + { "time": 0.8667, "value": 2.29 }, + { "time": 1, "value": 3.6 } + ] + }, + "head": { + "rotate": [ + { + "value": 3.6, + "curve": [ 0, 3.6, 0.094, -0.89 ] + }, + { "time": 0.1333, "value": -0.21 }, + { "time": 0.2333, "value": 6.11 }, + { "time": 0.3667, "value": 3.46 }, + { + "time": 0.5, + "value": 5.18, + "curve": [ 0.5, 5.18, 0.617, -1.4 ] + }, + { "time": 0.6667, "value": 1.11 }, + { "time": 0.7333, "value": 6.09 }, + { "time": 0.8667, "value": 2.29 }, + { "time": 1, "value": 3.6 } + ] + } + } + } +} +} \ No newline at end of file diff --git a/demos/art/sprites/spines/goblins.license b/demos/art/sprites/spines/goblins.license new file mode 100644 index 0000000..cd3e3b4 --- /dev/null +++ b/demos/art/sprites/spines/goblins.license @@ -0,0 +1,8 @@ +Copyright (c) 2013, Esoteric Software + +The images in this project may be redistributed as long as they are accompanied +by this license file. The images may not be used for commercial use of any +kind. + +The project file is released into the public domain. It may be used as the basis +for derivative work. \ No newline at end of file diff --git a/demos/art/sprites/spines/goblins.png b/demos/art/sprites/spines/goblins.png new file mode 100644 index 0000000..4613441 Binary files /dev/null and b/demos/art/sprites/spines/goblins.png differ diff --git a/demos/art/sprites/tiled/castle-tileset-by-RottingPixels-(CC0).png b/demos/art/sprites/tiled/castle-tileset-by-RottingPixels-(CC0).png new file mode 100644 index 0000000..c76c30b Binary files /dev/null and b/demos/art/sprites/tiled/castle-tileset-by-RottingPixels-(CC0).png differ diff --git a/demos/art/sprites/tiled/castle.tmx b/demos/art/sprites/tiled/castle.tmx new file mode 100644 index 0000000..d984584 --- /dev/null +++ b/demos/art/sprites/tiled/castle.tmx @@ -0,0 +1,14 @@ + + + + + + eJztk8sKwjAQRfMb1sderYLPrd/hqnTT//8Ep9DAdXAmkb4o3AOHkpCEQ9qG8M1uJqtgw6blNxXgWtyoucI5v12/hT1x/xD3pBustl+uOlP9fZssU61jfk+5jVM2xa5/3uEUTfq+cu7SOuftNDWdQzel/rfaaGrAdv41kxV06aa9eBBP4hnGR7GEZ5z31uu93thruohX8SE+YXwT7/CM8956vdcbYxPifftjYzURQgghhBBCCMnjAxltRQI= + + + + + eJztlE1Lw0AQhicxoLd605taP489xsb6EZH6hYiKCIKFXvr//4Ez+A4Z102y0oMe5oWHdGd3Ju/OkBKlKwd9KhLOzANmoO/9RfBUZaAAdp2ZM0Xk3LKeTpkzcI66NqbxWCyL5GeRuO71edLeXAdxyXln1phpS33NC/On1MxU9+aIHyV4KnDO6piaOawHtUUT43Nh+DBon4i+z22U4CnHOdGj8aTaxPtWsR4yB8weYosA0RazjbsW8FIHnrokOSVTMW+IXUQ8DbAem72B+a2z0h5n5q6/9ZTjPnlA6GnDeFJfGpuY87bHI2rmW+OZ4klUom5tsN+y1Lqkn9+6xGSWu/Q1S5Htcdnhqc2X1F7Bc4i6Dy2+bjrudMvcMffU9Gls7mD/l1L6JJ4q4+OV4v3aYa6YfeaQOUFccp+YZ+aFmj5p3sx4qhI9/YXcU5r+oyeXy+VyuVwul8vlci2nTwIxM6E= + + + diff --git a/demos/art/sprites/tiled/castle.tsx b/demos/art/sprites/tiled/castle.tsx new file mode 100644 index 0000000..62df76d --- /dev/null +++ b/demos/art/sprites/tiled/castle.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/engine/editor.c b/engine/editor.c index c00a656..aaf7378 100644 --- a/engine/editor.c +++ b/engine/editor.c @@ -56,7 +56,7 @@ TODO("obj: free obj_components()/payload2"); TODO("pack: mp2json, json2mp"); TODO("pack: simplify msgpack API, make it growth similar to va()") -#if 0 // fwk_pack proposal +#if 0 // v4k_pack proposal static __thread char* mpin; static __thread unsigned mpinlen; static __thread char mpinbuf[256]; diff --git a/hello.c b/hello.c index eb4b40a..2c8e04d 100644 --- a/hello.c +++ b/hello.c @@ -1,4 +1,4 @@ -// playground tests for FWK +// playground tests for V4K // - rlyeh, public domain // // # quickstart diff --git a/tools/cook.exe b/tools/cook.exe index dda9c7e..046148c 100644 Binary files a/tools/cook.exe and b/tools/cook.exe differ diff --git a/tools/cook.ini b/tools/cook.ini index 589747c..a599b5d 100644 --- a/tools/cook.ini +++ b/tools/cook.ini @@ -7,7 +7,7 @@ ; syntax: symbols are defined in KEY=value form, as seen below. TOOLS=./ ; folder where our pipeline tools are located -ART=../demos/art/,../engine/art/,../tools/editor/art/ ; comma-separated folder(s) that store all our asset files +ART=../demos/art/,../engine/art/,../editor/art/ ; comma-separated folder(s) that store all our asset files ; lines starting with @windows, @linux or @osx will be processed only where OS matches. ; we are defining here some symbols differently for each platform. @@ -25,9 +25,9 @@ ART=../demos/art/,../engine/art/,../tools/editor/art/ ; comma-separated folder( ; also, once a symbol is found, it is replaced by its value always. ; some predefined symbols: INPUT (input filename), OUTPUT (output filename), PRETTY (clean input filename), PROGRESS (cook progress). -@windows `echo Cooking PROGRESS% PRETTY...` -@linux `echo "Cooking PROGRESS% PRETTY..."` -@osx `echo "Cooking PROGRESS% PRETTY..."` +;@windows `echo Cooking PROGRESS% PRETTY...` +;@linux `echo "Cooking PROGRESS% PRETTY..."` +;@osx `echo "Cooking PROGRESS% PRETTY..."` ; ------------------------------------------------------------------------------ ; groups below are collection of files that we want to cook, and then package. @@ -212,4 +212,4 @@ TOOLS/ase2ini.EXE "INPUT" > OUTPUT [compress] 0|ULZ=texture,image,model,audio,font,text,shader,script -0=video,flac,ogg,wav,mp1,mp3,jpg,png,atlas,tiled +0=video,flac,ogg,wav,mp1,mp3,jpg,png,atlas,tiled \ No newline at end of file