Advertisement
Guest User

Untitled

a guest
Sep 13th, 2013
605
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.82 KB | None | 0 0
  1. #include <limits.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <malloc.h>
  5. #include <math.h>
  6. #include <SDL/SDL.h>
  7.  
  8. #define SECONDARY_SORTING_SPEED 500000
  9. #define width 640
  10. #define height 512
  11.  
  12. typedef unsigned int uint;
  13.  
  14. SDL_Surface *sdl_scr;
  15. uint *scr, *zbf;
  16. float *data, tmp[4];
  17. const uint widthheight = width*height;
  18. const int halfwidth = width/2;
  19. const uint halfheight = height/2;
  20. static uint seed=1000;
  21. float randf() {seed=214013*seed+2531011; return (seed>>16)&32767;}
  22.  
  23. void SWP(uint A, uint B) {
  24.     uint as;
  25.     for(as=0; as<4; as++){
  26.         tmp[as]=data[A+as];
  27.         data[A+as]=data[B+as];
  28.         data[B+as]=tmp[as];
  29.     }
  30. }
  31.  
  32. uint load_points(const char* filename) {
  33.     FILE *f = fopen(filename, "rb");
  34.     fseek(f, 0, SEEK_END);
  35.     const uint count = (ftell(f)/9);
  36.     fseek(f, 0, SEEK_SET);
  37.     data = (float*)calloc(count, 4*4);
  38.     uint i = 0;
  39.     while (!feof(f)) {
  40.         unsigned short xyz[4];
  41.         unsigned char rgb[3];
  42.         fread(&xyz, 3, 2, f);
  43.         fread(&rgb, 3, 1, f);
  44.         data[i+0] = xyz[0]+randf()/32767.0; // small random offset for de-overlapping points
  45.         data[i+1] = xyz[1]+randf()/32767.0; // (undoes 16bit truncation)
  46.         data[i+2] = xyz[2]+randf()/32767.0; // and turns them into floats.
  47.         data[i+3] = (rgb[0]<<16)|(rgb[1]<<8)|rgb[2];
  48.         i+=4;
  49.     }
  50.     fclose(f);
  51.  
  52.     // FIRST SHUFFLING
  53.     for (i = 0; i < count*4; i+=4) {
  54.         uint ri = (int(randf()*randf())%count)*4;
  55.         SWP(i, ri);
  56.     }
  57.     return count;
  58. }
  59.  
  60. __inline void rot2d(float sf, float cf, float *x, float *y) {
  61.     float tx = (*x) * cf - (*y) * sf;
  62.     *y = (*y) * cf + (*x) * sf;
  63.     *x = tx;
  64. }
  65.  
  66. int main(int argc, char **argv) {
  67.     // PREPARATIONS (MEMORY ALLOCATION, POINT CLOUD DATA LOADING):
  68.     if (argc==1) return 0;
  69.     const uint count = load_points(argv[1]);
  70.  
  71.     SDL_Init(SDL_INIT_VIDEO);
  72.     //freopen("CON", "w", stdout); // redirects stdout
  73.     //freopen("CON", "w", stderr); // redirects stderr
  74.  
  75.     sdl_scr = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE);
  76.     scr = (uint*)calloc(width * height, 4);
  77.     zbf = (uint*)calloc(width * height, 4);
  78.     float camx = 512, camy = 512, camz = 512, yaw = 0, pitch = 0;
  79.     float yx = 0, dx = 0, dy = 0, dz = 0, px = 0;
  80.  
  81.     uint stack = 0, lasti = 0, limit = count, f = 0, i4 = 0, i = 0, currentcluster = 0;
  82.  
  83.  
  84.     // MAIN LOOP:
  85.     for(;;) {
  86.         // 1. CAMERA MOTION
  87.         SDL_PumpEvents();
  88.         static uint lt = 0; float d = SDL_GetTicks() - lt; lt += d; float dt = d<1?1:d;
  89.         if (dt<16) { SDL_Delay(16 - dt); dt = 16; }
  90.         unsigned char *key = SDL_GetKeyState(NULL);
  91.         if (key[SDLK_ESCAPE]) return 0;
  92.         yx = -(key[SDLK_LEFT] - key[SDLK_RIGHT]) * dt/600.0;
  93.         px = (key[SDLK_UP] - key[SDLK_DOWN]) * dt/600.0;
  94.         dx = (key[SDLK_d] - key[SDLK_a]) * dt/4.0;
  95.         dy = (key[SDLK_w] - key[SDLK_s]) * dt/4.0;
  96.         dz = (key[SDLK_SPACE] - key[SDLK_LCTRL]) * dt/4.0;
  97.         yaw += yx; pitch += px;
  98.         float sf = sinf(yaw), cf = cosf(yaw), psf = sinf(pitch), pcf = cosf(pitch);
  99.         float tdx = dx, tdy = dy; rot2d(sf, cf, &tdy, &tdx);
  100.         float speed = key[SDLK_LSHIFT] * dt/10.0+1;
  101.         camx += tdx*speed; camy += tdy*speed; camz += dz*speed;
  102.  
  103.         // 2. CLEARING SCREEN AND ZBUFFER
  104.         for (i = 0; i < widthheight; i++) { scr[i] = 0; zbf[i] = INT_MAX; }
  105.  
  106.         // 3. ATOMS DRAWING AND SORTING
  107.         f = 0;
  108.  
  109.         for (i = 0; i < limit; i++) {
  110.             if (i == stack) {
  111.                 i = lasti;
  112.                 limit = i + SECONDARY_SORTING_SPEED;
  113.                 if (limit > count) limit = count;
  114.             }
  115.             i4 = i*4;
  116.             float x = data[i4 + 0] - camx, y = data[i4 + 1] - camy, z = data[i4 + 2] - camz;
  117.             rot2d(sf, cf, &x, &y); rot2d(psf, pcf, &z, &y);
  118.             if (y <= 0) continue;
  119.             const uint sx = halfwidth  + (x*halfwidth) / y;
  120.             if (sx < 0 || sx >= width) continue;
  121.             const uint sy = halfheight - (z*halfwidth) / y;
  122.             if (sy < 0 || sy >= height) continue;
  123.             const uint sind = sx + sy * width;
  124.             if (zbf[sind] < y) continue;
  125.             scr[sind] = data[i4 + 3];
  126.             zbf[sind] = y;
  127.             SWP(i4, f);
  128.             f += 4;
  129.         }
  130.         stack = f*0.275; // Adaptive stack size
  131.         lasti = i;
  132.         if (lasti >= count) { currentcluster = 0; lasti = stack; } else { currentcluster++; }
  133.  
  134.         // 4. FLIPPING SCREEN, SHOWING FPS
  135.         if(SDL_MUSTLOCK(sdl_scr)) if(SDL_LockSurface(sdl_scr)<0) return 0;
  136.         memcpy(sdl_scr->pixels, scr, widthheight*4);
  137.         if(SDL_MUSTLOCK(sdl_scr)) SDL_UnlockSurface(sdl_scr);
  138.         SDL_Flip(sdl_scr);
  139.         char buf[256]; sprintf(buf, "FPS:%.2f Stack:%2d Current zone:%d", 1000/dt, stack, currentcluster ); SDL_WM_SetCaption(buf, NULL);
  140.     }
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement