#include "examples.h" #include "example1.h" #include "example2.h" #include "example3.h" #include "example4.h" #include "example5.h" #include "example6.h" #include "example7.h" #include "framerate.h" #include using namespace std; PFNWGLSWAPINTERVALEXTPROC pwglSwapIntervalEXT; vector examples; rat_glyph_font *glyphfont; rat_texture_font *outfont=NULL; const unsigned int num_examples=7; char keys[SDLK_LAST]; char numkeys[10]; int numkeypress=-1; int curex=0; bool arbshowdown=false; bool aabbshowdown=false; bool qdtshowdown=false; bool linesmoothdown=false; bool mousedown=false; bool show_arbiters=false; bool show_aabbs=false; bool show_quadtree=false; bool linesmoothing=true; bool alt_down=false; bool enter_down=false; bool fullscreen=false; bool run=true; rat_body *grabbed_body; rat_spring *grabbed_spring; bool has_grabbed=false; vector2 world_cursor; rat_real fontsizey; static void toggle_fullscreen() { fullscreen=!fullscreen; SDL_QuitSubSystem(SDL_INIT_VIDEO); if (SDL_InitSubSystem(SDL_INIT_VIDEO)!=0) { printf("VIDEO SUBSYSTEM EPIC FAIL! ... \"%s\"\n",SDL_GetError()); fflush(stdout); exit(1); } } static void create_video() { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,16); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,16); SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT,16,SDL_OPENGL|(fullscreen?SDL_FULLSCREEN:0)); SDL_WM_SetCaption("Rat Physics Examples v2.0",NULL); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL/2); if (outfont) rat_texture_font_destroy(outfont); assert(glyphfont); outfont=rat_texture_font_from_glyph_font(glyphfont); #ifdef RAT_PHYSICS_WINDOWS if (!pwglSwapIntervalEXT) pwglSwapIntervalEXT=(PFNWGLSWAPINTERVALEXTPROC)load_extension("wglSwapIntervalEXT"); if (pwglSwapIntervalEXT) pwglSwapIntervalEXT(0); #endif glClearColor(0.8f,0.8f,0.8f,1); } static void handle_events() { SDL_Event event; numkeypress=-1; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: run=false; break; case SDL_KEYDOWN: if (event.key.keysym.sym>=SDLK_0&&event.key.keysym.sym<=SDLK_9) numkeys[event.key.keysym.sym-SDLK_0]=(char)true; switch (event.key.keysym.sym) { case SDLK_ESCAPE: run=false; break; case SDLK_LALT: case SDLK_RALT: alt_down=true; break; case SDLK_RETURN: enter_down=true; break; default: keys[event.key.keysym.sym]=(char)true; break; }; break; case SDL_KEYUP: if (event.key.keysym.sym>=SDLK_0&&event.key.keysym.sym<=SDLK_9) { numkeys[event.key.keysym.sym-SDLK_0]=(char)false; numkeypress=event.key.keysym.sym-SDLK_0; } switch (event.key.keysym.sym) { case SDLK_LALT: case SDLK_RALT: alt_down=false; if (enter_down) { enter_down=false; toggle_fullscreen(); create_video(); } break; case SDLK_RETURN: enter_down=false; if (alt_down) { alt_down=false; toggle_fullscreen(); create_video(); } default: keys[event.key.keysym.sym]=(char)false; break; }; break; case SDL_MOUSEBUTTONDOWN: mousedown=true; break; case SDL_MOUSEBUTTONUP: mousedown=false; break; case SDL_MOUSEMOTION: world_cursor.x=((rat_real)event.motion.x/(rat_real)WINDOW_WIDTH)*SCENE_WIDTH; world_cursor.y=((rat_real)event.motion.y/(rat_real)WINDOW_HEIGHT)*SCENE_HEIGHT; break; default: break; }; }; } static void populate_list() { examples.push_back(new RatPhysicsExample1("Pinchinco Pegs")); examples.push_back(new RatPhysicsExample2("Pyramid Stress Test")); examples.push_back(new RatPhysicsExample3("Varying Restitution")); examples.push_back(new RatPhysicsExample4("Varying Friction")); examples.push_back(new RatPhysicsExample5("Collision Filters")); examples.push_back(new RatPhysicsExample6("Pivot/Link Chains")); examples.push_back(new RatPhysicsExample7("Newtons Cradle")); } static void destroy_list() { vector::iterator it; for (it=examples.begin(); it!=examples.end(); it++) delete *it; } static void draw_text_bg(rat_real x,rat_real y,char *text) { rat_real sizex=rat_texture_font_text_length(outfont,text); float rgba[4]={0,0,0,1}; glColor4f(1,1,1,0.6); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(x,y,0); glScalef(sizex,fontsizey,0); glBegin(GL_QUADS); glVertex2f(0,0); glVertex2f(0,1); glVertex2f(1,1); glVertex2f(1,0); glEnd(); glPopMatrix(); rat_set_text_color(rgba); rat_texture_font_render_text(outfont,x,y,text); } #ifdef WIN32SUBSYS int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { #else int main(int argc,char *argv[]) { #endif char tempbuf[256]; char *infotext="Press the number keys across the top row for different demos."; rat_real deltatime=1.0; cout.sync_with_stdio(true); memset(keys,0,SDLK_LAST); atexit(SDL_Quit); if (SDL_Init(SDL_INIT_VIDEO)!=0) { printf("VIDEO SUBSYSTEM EPIC FAIL! ... \"%s\"\n",SDL_GetError()); fflush(stdout); return 1; } rat_start_font_system(); if (!(glyphfont=rat_glyph_font_load("small.ttf",12))) { cout<<"failed to load font!"<InitWorld()) { cout<<"init world fail!"<world); solvacc=(--solvacc)<1?1:solvacc; rat_world_set_solver_iterations(examples[curex]->world,solvacc); } if (keys[SDLK_PAGEUP]) { unsigned int solvacc=rat_world_get_solver_iterations(examples[curex]->world); solvacc++; rat_world_set_solver_iterations(examples[curex]->world,solvacc); } if (mousedown) { if (has_grabbed) rat_spring_update_global_anchor(grabbed_spring,vector2_add(world_cursor,examples[curex]->pickoffset)); else { vector2 global_anchor; vector2 local_anchor; rat_body *picked_body; if (examples[curex]->WorldPointPick(vector2_add(world_cursor,examples[curex]->pickoffset),&picked_body,&local_anchor)) { // we grab this puppy has_grabbed=true; grabbed_body=picked_body; grabbed_spring=rat_spring_create(grabbed_body,NULL, local_anchor,world_cursor,92.0,0.0,46.0); rat_world_add_spring(examples[curex]->world,grabbed_spring); } } } else if (has_grabbed) { has_grabbed=false; rat_world_remove_and_destroy_spring(examples[curex]->world,grabbed_spring); } // switch demos based on number pressed if (numkeypress>-1) { if (numkeypress<1) numkeypress=9; else numkeypress--; if (numkeypressFreeWorld()) { cout<<"free world on example change fail!"<InitWorld()) { cout<<"init world on example change fail!"<delta_time)/25.0; if (!keys[SDLK_p]) { if (!examples[curex]->UpdateWorld(deltatime)) { cout<<"update world fail!"<UpdateVisuals()) { cout<<"update visual fail!"<fps); string title_str=examples[curex]->title+tempbuf; draw_text_bg(0,0,(char *)title_str.c_str()); rat_mem_alloced_string(tempbuf+128); sprintf(tempbuf,"solver islands %03u memory usage %s",examples[curex]->world->numislands,tempbuf+128); draw_text_bg(0,fontsizey,tempbuf); sprintf(tempbuf,"solver iterations %04u (pgup/pgdn to change)", rat_world_get_solver_iterations(examples[curex]->world)); draw_text_bg(0,fontsizey*2.0,tempbuf); draw_text_bg(infotextx,infotexty,infotext); glPopAttrib(); rat_ortho_pop(); SDL_GL_SwapBuffers(); rat_frame_counter_update(framectr,1); rat_frame_counter_update(frameratetracker,1); } rat_frame_counter_destroy(framectr); rat_frame_counter_destroy(frameratetracker); if (!fail) { if (!examples[curex]->FreeWorld()) { cout<<"free world fail!"<body_manager); for (; rat_iterator_finished(iter); rat_iterator_next(iter)) { thisbody=(rat_body *)rat_iterator_value(iter); if (rat_hull_point_query(thisbody->hull,point)) { rat_iterator_destroy(iter); *bodypicked=thisbody; *local_picked=vector2_world_to_local( point,rat_hull_get_pos(thisbody->hull), rat_hull_get_angle(thisbody->hull)); return true; } } rat_iterator_destroy(iter); return false; } void rat_examples_create_walls(rat_world *world) { static vector2 tmpvec,tmpvec2; rat_hull **wallhulls=(rat_hull **)rat_stack_alloc(world->sal,4*sizeof(rat_hull *)); vector2_set(&tmpvec2,20,SCENE_HEIGHT/2.0); vector2_set(&tmpvec,0,SCENE_HEIGHT/2.0); wallhulls[0]=rat_hull_polygon_create_box(tmpvec,tmpvec2); vector2_set(&tmpvec,SCENE_WIDTH,SCENE_HEIGHT/2.0); wallhulls[1]=rat_hull_polygon_create_box(tmpvec,tmpvec2); vector2_set(&tmpvec2,SCENE_WIDTH/2.0,20); vector2_set(&tmpvec,SCENE_WIDTH/2.0,0); wallhulls[2]=rat_hull_polygon_create_box(tmpvec,tmpvec2); vector2_set(&tmpvec,SCENE_WIDTH/2.0,SCENE_HEIGHT); wallhulls[3]=rat_hull_polygon_create_box(tmpvec,tmpvec2); rat_world_add_body(world,rat_body_create(wallhulls[0],1.0,1.0,0.0,0.0)); rat_world_add_body(world,rat_body_create(wallhulls[1],1.0,1.0,0.0,0.0)); rat_world_add_body(world,rat_body_create(wallhulls[2],1.0,1.0,0.0,0.0)); rat_world_add_body(world,rat_body_create(wallhulls[3],1.0,1.0,0.0,0.0)); rat_stack_dealloc(world->sal,(void *)wallhulls); } void rat_examples_create_circle_row(rat_world *world,rat_real diameter,rat_real padx,rat_real y,rat_real xcenter,unsigned int numcircs,int tag) { register unsigned int i; register rat_real halfwidth=((diameter+padx)/2.0)*numcircs; rat_real radius=diameter*0.5; for (i=0; ifiltertag=tag; last_body=anchor; rat_world_add_body(world,anchor); vector2 boxverts[6]= { {halfsize.x*0.75,-halfsize.y}, {-halfsize.x*0.75,-halfsize.y}, {-halfsize.x*1.2,0.0}, {-halfsize.x*0.75,halfsize.y}, {halfsize.x*0.75,halfsize.y}, {halfsize.x*1.2,0.0} }; for (i=0; i