void moving (void) { struct groundtri *gt; if ((gt = detect_plane (&player.p)) == NULL) { printf ("Can't find ground, moving player to start position " "to avoid seg fault\n"); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; gt = detect_plane (&player.p); } player.loc = gt; if (gt->theta < DTOR (50)) player.lastflat = gt; switch (player.movtype) { case GROUNDED: grounded_moving (); break; case FALLING: falling_moving (); break; case FLYING: flying_moving (); break; } }
double ground_height (struct pt *p) { struct groundtri *gt; if ((gt = detect_plane (p)) == NULL) { printf ("Can't find ground, moving player to start position " "to avoid seg fault\n"); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; gt = detect_plane (&player.p); } return (z_at_pt_on_plane (p, >->pl)); }
void FarMesh::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) return;*/ if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) return; /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SKY_BOX) return;*/ driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); //const s16 grid_radius_i = 12; //const float grid_size = BS*50; const s16 grid_radius_i = m_render_range/MAP_BLOCKSIZE; const float grid_size = BS*MAP_BLOCKSIZE; const v2f grid_speed(-BS*0, 0); // Position of grid noise origin in world coordinates v2f world_grid_origin_pos_f(0,0); // Position of grid noise origin from the camera v2f grid_origin_from_camera_f = world_grid_origin_pos_f - m_camera_pos; // The center point of drawing in the noise v2f center_of_drawing_in_noise_f = -grid_origin_from_camera_f; // The integer center point of drawing in the noise v2s16 center_of_drawing_in_noise_i( MYROUND(center_of_drawing_in_noise_f.X / grid_size), MYROUND(center_of_drawing_in_noise_f.Y / grid_size) ); // The world position of the integer center point of drawing in the noise v2f world_center_of_drawing_in_noise_f = v2f( center_of_drawing_in_noise_i.X * grid_size, center_of_drawing_in_noise_i.Y * grid_size ) + world_grid_origin_pos_f; for(s16 zi=-grid_radius_i; zi<grid_radius_i; zi++) for(s16 xi=-grid_radius_i; xi<grid_radius_i; xi++) { /*// Don't draw very close to player s16 dd = 3; if(zi > -dd && zi < dd && xi > -dd && xi < dd) continue;*/ v2s16 p_in_noise_i( xi+center_of_drawing_in_noise_i.X, zi+center_of_drawing_in_noise_i.Y ); // If sector was drawn, don't draw it this way if(m_client->m_env.getClientMap().sectorWasDrawn(p_in_noise_i)) continue; /*if((p_in_noise_i.X + p_in_noise_i.Y)%2==0) continue;*/ /*if((p_in_noise_i.X/2 + p_in_noise_i.Y/2)%2==0) continue;*/ v2f p0 = v2f(xi,zi)*grid_size + world_center_of_drawing_in_noise_f; /*double noise[4]; double d = 100*BS; noise[0] = d*noise2d_perlin( (float)(p_in_noise_i.X+0)*grid_size/BS/100, (float)(p_in_noise_i.Y+0)*grid_size/BS/100, m_seed, 3, 0.5); noise[1] = d*noise2d_perlin( (float)(p_in_noise_i.X+0)*grid_size/BS/100, (float)(p_in_noise_i.Y+1)*grid_size/BS/100, m_seed, 3, 0.5); noise[2] = d*noise2d_perlin( (float)(p_in_noise_i.X+1)*grid_size/BS/100, (float)(p_in_noise_i.Y+1)*grid_size/BS/100, m_seed, 3, 0.5); noise[3] = d*noise2d_perlin( (float)(p_in_noise_i.X+1)*grid_size/BS/100, (float)(p_in_noise_i.Y+0)*grid_size/BS/100, m_seed, 3, 0.5);*/ HeightPoint hps[5]; hps[0] = ground_height(m_seed, v2s16( (p_in_noise_i.X+0)*grid_size/BS, (p_in_noise_i.Y+0)*grid_size/BS)); hps[1] = ground_height(m_seed, v2s16( (p_in_noise_i.X+0)*grid_size/BS, (p_in_noise_i.Y+1)*grid_size/BS)); hps[2] = ground_height(m_seed, v2s16( (p_in_noise_i.X+1)*grid_size/BS, (p_in_noise_i.Y+1)*grid_size/BS)); hps[3] = ground_height(m_seed, v2s16( (p_in_noise_i.X+1)*grid_size/BS, (p_in_noise_i.Y+0)*grid_size/BS)); v2s16 centerpoint( (p_in_noise_i.X+0)*grid_size/BS+MAP_BLOCKSIZE/2, (p_in_noise_i.Y+0)*grid_size/BS+MAP_BLOCKSIZE/2); hps[4] = ground_height(m_seed, centerpoint); float noise[5]; float h_min = BS*65535; float h_max = -BS*65536; float ma_avg = 0; float h_avg = 0; u32 have_sand_count = 0; float tree_amount_avg = 0; for(u32 i=0; i<5; i++) { noise[i] = hps[i].gh + hps[i].ma; if(noise[i] < h_min) h_min = noise[i]; if(noise[i] > h_max) h_max = noise[i]; ma_avg += hps[i].ma; h_avg += noise[i]; if(hps[i].have_sand) have_sand_count++; tree_amount_avg += hps[i].tree_amount; } ma_avg /= 5.0; h_avg /= 5.0; tree_amount_avg /= 5.0; float steepness = (h_max - h_min)/grid_size; float light_f = noise[0]+noise[1]-noise[2]-noise[3]; light_f /= 100; if(light_f < -1.0) light_f = -1.0; if(light_f > 1.0) light_f = 1.0; //light_f += 1.0; //light_f /= 2.0; v2f p1 = p0 + v2f(1,1)*grid_size; bool ground_is_sand = false; bool ground_is_rock = false; bool ground_is_mud = false; video::SColor c; // Detect water if(h_avg < WATER_LEVEL*BS && h_max < (WATER_LEVEL+5)*BS) { //c = video::SColor(255,59,86,146); //c = video::SColor(255,82,120,204); c = video::SColor(255,74,105,170); /*// Set to water level for(u32 i=0; i<4; i++) { if(noise[i] < BS*WATER_LEVEL) noise[i] = BS*WATER_LEVEL; }*/ light_f = 0; } // Steep cliffs else if(steepness > 2.0) { c = video::SColor(255,128,128,128); ground_is_rock = true; } // Basic ground else { if(ma_avg < 2.0*BS) { c = video::SColor(255,128,128,128); ground_is_rock = true; } else { if(h_avg <= 2.5*BS && have_sand_count >= 2) { c = video::SColor(255,210,194,156); ground_is_sand = true; } else { /*// Trees if there are over 0.01 trees per MapNode if(tree_amount_avg > 0.01) c = video::SColor(255,50,128,50); else c = video::SColor(255,107,134,51);*/ c = video::SColor(255,107,134,51); ground_is_mud = true; } } } // Set to water level for(u32 i=0; i<4; i++) { if(noise[i] < BS*WATER_LEVEL) noise[i] = BS*WATER_LEVEL; } float b = m_brightness + light_f*0.1*m_brightness; if(b < 0) b = 0; if(b > 2) b = 2; c = video::SColor(255, b*c.getRed(), b*c.getGreen(), b*c.getBlue()); driver->setMaterial(m_materials[0]); video::S3DVertex vertices[4] = { video::S3DVertex(p0.X,noise[0],p0.Y, 0,0,0, c, 0,1), video::S3DVertex(p0.X,noise[1],p1.Y, 0,0,0, c, 1,1), video::S3DVertex(p1.X,noise[2],p1.Y, 0,0,0, c, 1,0), video::S3DVertex(p1.X,noise[3],p0.Y, 0,0,0, c, 0,0), }; u16 indices[] = {0,1,2,2,3,0}; driver->drawVertexPrimitiveList(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); // Add some trees if appropriate if(tree_amount_avg >= 0.0065 && steepness < 1.4 && ground_is_mud == true) { driver->setMaterial(m_materials[1]); float b = m_brightness; c = video::SColor(255, b*255, b*255, b*255); { video::S3DVertex vertices[4] = { video::S3DVertex(p0.X,noise[0],p0.Y, 0,0,0, c, 0,1), video::S3DVertex(p0.X,noise[0]+BS*MAP_BLOCKSIZE,p0.Y, 0,0,0, c, 0,0), video::S3DVertex(p1.X,noise[2]+BS*MAP_BLOCKSIZE,p1.Y, 0,0,0, c, 1,0), video::S3DVertex(p1.X,noise[2],p1.Y, 0,0,0, c, 1,1), }; u16 indices[] = {0,1,2,2,3,0}; driver->drawVertexPrimitiveList(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); } { video::S3DVertex vertices[4] = { video::S3DVertex(p1.X,noise[3],p0.Y, 0,0,0, c, 0,1), video::S3DVertex(p1.X,noise[3]+BS*MAP_BLOCKSIZE,p0.Y, 0,0,0, c, 0,0), video::S3DVertex(p0.X,noise[1]+BS*MAP_BLOCKSIZE,p1.Y, 0,0,0, c, 1,0), video::S3DVertex(p0.X,noise[1],p1.Y, 0,0,0, c, 1,1), }; u16 indices[] = {0,1,2,2,3,0}; driver->drawVertexPrimitiveList(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); } } } //driver->clearZBuffer(); }
void old_grounded_moving (void) { double now, dt; struct pt newpos; struct groundtri *gt; struct vect v1, v2, ctrl_vel; now = get_secs (); dt = now - player.lasttime; ctrl_vel.x = 0; ctrl_vel.y = 0; ctrl_vel.z = 0; if (player.p.z <= ground_height (&player.p)) { switch (player.moving) { case BACK: ctrl_vel.x = -.3 * player.speed * cos (player.theta); ctrl_vel.y = -.3 * player.speed * sin (player.theta); break; case FORW: ctrl_vel.x = player.speed * cos (player.theta); ctrl_vel.y = player.speed * sin (player.theta); break; case SIDE_Q: ctrl_vel.x = player.speed * cos (player.theta + DTOR (90)); ctrl_vel.y = player.speed * sin (player.theta + DTOR (90)); break; case SIDE_E: ctrl_vel.x = player.speed * cos (player.theta - DTOR (90)); ctrl_vel.y = player.speed * sin (player.theta - DTOR (90)); break; case FORW_Q: ctrl_vel.x = player.speed * cos (player.theta + DTOR (45)); ctrl_vel.y = player.speed * sin (player.theta + DTOR (45)); break; case FORW_E: ctrl_vel.x = player.speed * cos (player.theta - DTOR (45)); ctrl_vel.y = player.speed * sin (player.theta - DTOR (45)); break; case BACK_Q: ctrl_vel.x = -.3 * player.speed * cos (player.theta - DTOR (45)); ctrl_vel.y = -.3 * player.speed * sin (player.theta - DTOR (45)); break; case BACK_E: ctrl_vel.x = -.3 * player.speed * cos (player.theta + DTOR (45)); ctrl_vel.y = -.3 * player.speed * sin (player.theta + DTOR (45)); break; } } newpos.x = player.p.x + ctrl_vel.x * dt; newpos.y = player.p.y + ctrl_vel.y * dt; newpos.z = player.p.z + ctrl_vel.z * dt; psub (&player.vel, &newpos, &player.p); vscal (&player.vel, &player.vel, 1 / dt); if ((gt = detect_plane (&newpos)) == NULL) { printf ("Can't find ground, moving player to start position " "to avoid seg fault\n"); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; player.loc = detect_plane (&player.p); return; } if (gt->theta < DTOR (50)) { newpos.z = ground_height (&newpos); psub (&player.vel, &newpos, &player.p); vscal (&player.vel, &player.vel, 1 / dt); player.p = newpos; } else if (newpos.z > gt->pl.middle.z) { player.p = newpos; player.movtype = FALLING; printf ("switching to falling\n"); } else if (newpos.z <= gt->pl.middle.z) { if (gt == player.loc) { printf ("line %d: some sort of bug caused" " player to be in grounded mode while" " on steep plane\n", __LINE__); pt_on_z_plane (&newpos, &newpos, &player.loc->pl); player.p = newpos; printf ("shifting player to nearest point on" " plane with same z\n"); vset (&player.vel, 0, 0, 0); printf ("killing player velocity\n"); player.movtype = FALLING; printf ("switching to falling\n"); paused = YES; printf ("paused game\n"); return; } vnorm (&v2, &ctrl_vel); vcross (&v1, &player.loc->normv, >->normv); vnorm (&v1, &v1); if (vdot (&v1, &v2) < 0) vscal (&v1, &v1, -1); vscal (&ctrl_vel, &v1, vdot (&ctrl_vel, &v1)); newpos.x = player.p.x + ctrl_vel.x * dt; newpos.y = player.p.y + ctrl_vel.y * dt; newpos.z = player.p.z + ctrl_vel.z * dt; if ((gt = detect_plane (&newpos)) == NULL) { printf ("can't detect plane, exiting\n"); exit (1); } if (gt->theta < DTOR (50)) { newpos.z = ground_height (&newpos); psub (&player.vel, &newpos, &player.p); vscal (&player.vel, &player.vel, 1 / dt); printf ("bar\n"); player.p = newpos; } else { // struct groundtri *first_col, *last_col, *gt2; // int i; //PLAYER STARTS MOVING INTO GROUND BEFORE THIS EVER //HAPPENS printf ("pausing\n"); paused = YES; /* i = 0; */ /* first_col = NULL; */ /* last_col = NULL; */ /* for (gt2 = first_groundtri; gt2; gt2 = gt2->next) { */ /* if (detect_collision (&player.p, */ /* &newpos, gt2)) { */ /* if (first_col == NULL) { */ /* first_col = gt2; */ /* } else { */ /* last_col->next = gt2; */ /* } */ /* last_col = gt2; */ /* i++; */ /* } */ /* } */ /* if (first_col == NULL) { */ /* printf ("%s: %s: %d: something weird\n", */ /* __FILE__, __FUNCTION__, __LINE__); */ /* } */ /* printf ("number of collisions: %d\n", i); */ //TRY PROJECTING PLAYER TO LINE OF INTERSECTION //BETWEEN OLD & NEW PLANES. IF PLAYER IS STILL //INSIDE ANY PLANES, GRAB THREE PLANES AND GO //TO INTERSECTION POINT OF THOSE. MIGHT WANT //TO CHECK FOR OVER THREE PLANES JUST IN CASE /* printf ("player.z: %g\n", player.p.z); */ /* newpos = player.p; */ /* rnd_escape (&newpos, gt); */ /* printf ("ran rnd_escape\n"); */ /* gt = detect_plane (&newpos); */ /* double b2; */ /* b2 = newpos.y - (gt->pl.b / gt->pl.a) * newpos.x; */ /* newpos.x = -(b2 * gt->pl.a * gt->pl.b */ /* + gt->pl.c * newpos.z * gt->pl.a */ /* + gt->pl.d * gt->pl.a) */ /* / (square (gt->pl.a) + square (gt->pl.b)); */ /* newpos.y = (gt->pl.b / gt->pl.a) * newpos.x + b2; */ /* player.p = newpos; */ /* printf ("shifting player to nearest point on" */ /* " plane with same z\n"); */ /* gt = detect_plane (&player.p); */ /* printf ("re detected plane\n"); */ /* if (gt->theta >= DTOR (50)) { */ /* printf ("rnd_escape put player on slope," */ /* " changing player to falling\n"); */ /* player.movtype = FALLING; */ /* printf ("killing velocity\n"); */ /* vset (&player.vel, 0, 0, 0); */ /* } */ /* printf ("player.z: %g\n", player.p.z); */ } } else { printf ("this should never be printed\n"); } }
void grounded_moving (void) { double now, dt; struct pt newpos; struct groundtri *gt; struct vect ctrl_vel; now = get_secs (); dt = now - player.lasttime; ctrl_vel.x = 0; ctrl_vel.y = 0; ctrl_vel.z = 0; if (fabs (player.p.z - ground_height (&player.p)) <= 1e6) { switch (player.moving) { case BACK: ctrl_vel.x = -.3 * player.speed * cos (player.theta); ctrl_vel.y = -.3 * player.speed * sin (player.theta); break; case FORW: ctrl_vel.x = player.speed * cos (player.theta); ctrl_vel.y = player.speed * sin (player.theta); break; case SIDE_Q: ctrl_vel.x = player.speed * cos (player.theta + DTOR (90)); ctrl_vel.y = player.speed * sin (player.theta + DTOR (90)); break; case SIDE_E: ctrl_vel.x = player.speed * cos (player.theta - DTOR (90)); ctrl_vel.y = player.speed * sin (player.theta - DTOR (90)); break; case FORW_Q: ctrl_vel.x = player.speed * cos (player.theta + DTOR (45)); ctrl_vel.y = player.speed * sin (player.theta + DTOR (45)); break; case FORW_E: ctrl_vel.x = player.speed * cos (player.theta - DTOR (45)); ctrl_vel.y = player.speed * sin (player.theta - DTOR (45)); break; case BACK_Q: ctrl_vel.x = -.3 * player.speed * cos (player.theta - DTOR (45)); ctrl_vel.y = -.3 * player.speed * sin (player.theta - DTOR (45)); break; case BACK_E: ctrl_vel.x = -.3 * player.speed * cos (player.theta + DTOR (45)); ctrl_vel.y = -.3 * player.speed * sin (player.theta + DTOR (45)); break; } } newpos.x = player.p.x + ctrl_vel.x * dt; newpos.y = player.p.y + ctrl_vel.y * dt; newpos.z = player.p.z + ctrl_vel.z * dt; psub (&player.vel, &newpos, &player.p); vscal (&player.vel, &player.vel, 1 / dt); if ((gt = detect_plane (&newpos)) == NULL) { printf ("Can't find ground, moving player to start position " "to avoid seg fault\n"); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; player.loc = detect_plane (&player.p); return; } if (gt->theta < DTOR (50)) { newpos.z = ground_height (&newpos); psub (&player.vel, &newpos, &player.p); vscal (&player.vel, &player.vel, 1 / dt); player.p = newpos; } else if (newpos.z > gt->pl.middle.z) { //imperfect detection of cliffs but tolerable for now player.p = newpos; player.movtype = FALLING; printf ("switching to falling\n"); } else { if (gt == player.loc) { printf ("line %d: HORRIBLE MESSINESS\n", __LINE__); paused = YES; printf ("paused game\n"); return; } struct vect v1, v2; vnorm (&v2, &ctrl_vel); vcross (&v1, &player.loc->normv, >->normv); vnorm (&v1, &v1); if (vdot (&v1, &v2) < 0) vscal (&v1, &v1, -1); vscal (&ctrl_vel, &v1, vdot (&ctrl_vel, &v1)); newpos.x = player.p.x + ctrl_vel.x * dt; newpos.y = player.p.y + ctrl_vel.y * dt; newpos.z = player.p.z + ctrl_vel.z * dt; newpos.z = ground_height (&newpos); psub (&player.vel, &newpos, &player.p); vscal (&player.vel, &player.vel, 1 / dt); player.p = newpos; } }
void process_input (void) { SDL_Event event; int key; while (SDL_PollEvent (&event)) { key = event.key.keysym.sym; switch (event.type) { case SDL_QUIT: exit (0); case SDL_KEYDOWN: switch (key) { case SDLK_UP: case 'w': arrowkey[UP] = 1; break; case SDLK_DOWN: case 's': arrowkey[DOWN] = 1; break; case SDLK_LEFT: case 'a': arrowkey[LEFT] = 1; if (mousebutton[3] == 1 || mousebutton[2] == 1) arrowkey[FAKE_Q] = 1; break; case SDLK_RIGHT: case 'd': arrowkey[RIGHT] = 1; if (mousebutton[3] == 1 || mousebutton[2] == 1) arrowkey[FAKE_E] = 1; break; case 'q': arrowkey[Q] = 1; break; case 'e': arrowkey[E] = 1; break; case ' ': if (0) { if (player.p.z <= ground_height (&player.p) && player.movtype == GROUNDED) { player.p.z += 1e-6; player.vel.z = 25; player.movtype = FALLING; } } break; case 'r': player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); break; case 'u': player.p.z = ground_height (&player.p) + 50; player.movtype = FALLING; break; case 'm': printf ("%8.3f %8.3f %8.3f, %8.3f, %8.3f\n", player.p.x, player.p.y, player.p.z, player.theta, playercamera.theta); break; case 'p': if (paused == NO) { paused = YES; } else { paused = NO; } break; case 't': player.p.x = 42.010; player.p.y = 60.977; player.p.z = 0.203; player.theta = 1.441; playercamera.theta = 4.583; break; case 'y': player.p.x = 63.293; player.p.y = 78.532; player.p.z = .203; break; case 'n': vset (&player.vel, 0, 0, 0); break; } break; case SDL_KEYUP: switch (key) { case SDLK_ESCAPE: exit (0); case SDLK_UP: case 'w': arrowkey[UP] = 0; break; case SDLK_DOWN: case 's': arrowkey[DOWN] = 0; break; case SDLK_LEFT: case 'a': arrowkey[LEFT] = 0; if (arrowkey[FAKE_Q]) arrowkey[FAKE_Q] = 0; break; case SDLK_RIGHT: case 'd': arrowkey[RIGHT] = 0; if (arrowkey[FAKE_E]) arrowkey[FAKE_E] = 0; break; case 'q': arrowkey[Q] = 0; break; case 'e': arrowkey[E] = 0; break; } case SDL_MOUSEBUTTONDOWN: mousebutton[event.button.button] = 1; switch (event.button.button) { case 1: leftclickdown (); break; case 2: middleclickdown (); break; case 3: rightclickdown (); break; case 4: zoomin (); break; case 5: zoomout (); break; } break; case SDL_MOUSEBUTTONUP: mousebutton[event.button.button] = 0; switch (event.button.button) { case 1: leftclickup (); break; case 2: middleclickup (); break; case 3: rightclickup (); break; case 4: zoomin (); break; case 5: zoomout (); break; } break; case SDL_MOUSEMOTION: mouse_x = event.button.x; mouse_y = event.button.y; break; } } }
int main (int argc, char **argv) { int i; double now; feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); init_sdl_gl_flags (WIDTH, HEIGHT, 0); srandom (time (NULL)); init_gl (&argc, argv); glEnable (GL_LIGHTING); glEnable (GL_DEPTH_TEST); glEnable (GL_AUTO_NORMAL); glEnable (GL_NORMALIZE); glClearDepth (1); glViewport (0, 0, WIDTH, HEIGHT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (60, (GLfloat) WIDTH/(GLfloat) HEIGHT, .1, 1000); glClearColor (0, 0, 0, 0); glMatrixMode (GL_MODELVIEW); SDL_ShowCursor (1); makeImages (); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glGenTextures (1, texName); makeTexture (texName[0], groundtexture.texturesize, (GLubyte ***) groundtexture.tex); glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glBlendFunc (GL_SRC_ALPHA, GL_ONE); gndcounter = 1; read_terrain (); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.loc = detect_plane (&player.p); player.movtype = GROUNDED; player.speed = 100; player.mass = 1; vset (&player.vel, 0, 0, 0); player.turnspeed = DTOR (180); player.theta = DTOR (0); player.camdist = 15; player.lasttime = get_secs (); player.moving = NO; playercamera.phi = DTOR (0); playercamera.theta_difference = 0; while (1) { process_input (); if (mousebutton[1] == 0 && mousebutton[2] == 0 && mousebutton[3] == 0) { SDL_ShowCursor (1); } else { SDL_ShowCursor (0); } movement (); if (paused == NO) { for (i = 0; i < 1; i++) { moving (); now = get_secs (); player.lasttime = now; } } process_mouse (); draw (); now = get_secs (); player.lasttime = now; SDL_Delay (10); } return (0); }
void falling_moving (void) { double now, dt; struct vect grav, grav_acc; struct groundtri *gt; struct pt newpos, p1; now = get_secs (); dt = now - player.lasttime; if ((gt = detect_plane (&player.p)) == NULL) { printf ("Can't find ground, moving player to start position " "to avoid seg fault\n"); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; player.loc = detect_plane (&player.p); return; } if (player.p.z <= ground_height (&player.p) && gt->theta < DTOR (50)) { player.movtype = GROUNDED; player.p.z = ground_height (&player.p); return; } grav.x = 0; grav.y = 0; grav.z = GRAVITY; vscal (&grav_acc, &grav, 1 / player.mass); player.vel.x += grav_acc.x; player.vel.y += grav_acc.y; player.vel.z += grav_acc.z; newpos.x = player.p.x + player.vel.x * dt; newpos.y = player.p.y + player.vel.y * dt; newpos.z = player.p.z + player.vel.z * dt; if (newpos.z <= ground_height (&newpos)) { if ((gt = detect_plane (&newpos)) == NULL) { printf ("Can't find ground at newpos, moving player to " "start position to avoid seg fault\n"); player.p.x = 0; player.p.y = 0; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; player.loc = detect_plane (&player.p); return; } if (gt->theta < DTOR (50)) { player.p = newpos; player.p.z = ground_height (&player.p); player.movtype = GROUNDED; player.loc = gt; return; } else { p1.x = vdot (&player.vel, >->normv) * gt->normv.x; p1.y = vdot (&player.vel, >->normv) * gt->normv.y; p1.z = vdot (&player.vel, >->normv) * gt->normv.z; player.vel.x -= p1.x; player.vel.y -= p1.y; player.vel.z -= p1.z; player.p.x += player.vel.x * dt; player.p.y += player.vel.y * dt; player.p.z += player.vel.z * dt; } } else { player.p.x = newpos.x; player.p.y = newpos.y; player.p.z = newpos.z; player.loc = gt; } }