Exemplo n.º 1
0
static Bool gather_collision_geometry(collision_geometry *cg, int base_x, int base_y, int base_z)
{
   int cx0 = C_MESH_CHUNK_X_FOR_WORLD_X(base_x);
   int cy0 = C_MESH_CHUNK_Y_FOR_WORLD_Y(base_y);
   int cx1 = C_MESH_CHUNK_X_FOR_WORLD_X(base_x+COLLIDE_BLOB_X-1)+1;
   int cy1 = C_MESH_CHUNK_Y_FOR_WORLD_Y(base_y+COLLIDE_BLOB_Y-1)+1;
   int j,i;
   Bool found_bad = False;
   memset(cg, 0, sizeof(*cg));

   cg->x = base_x;
   cg->y = base_y;
   cg->z = base_z;
   for (j=cy0; j < cy1; ++j) {
      for (i=cx0; i < cx1; ++i) {
         int x0 = i << MESH_CHUNK_SIZE_X_LOG2;
         int y0 = j << MESH_CHUNK_SIZE_Y_LOG2;
         mesh_chunk *mc = get_physics_chunk_for_coord(x0,y0);
         if (mc == NULL) {
            found_bad = True;
         } else {
            int a,b;
            int rx1 = x0 + MESH_CHUNK_SIZE_X;
            int ry1 = y0 + MESH_CHUNK_SIZE_Y;
            int rx0 = stb_max(x0, base_x);
            int ry0 = stb_max(y0, base_y);
            rx1 = stb_min(rx1, base_x+COLLIDE_BLOB_X);
            ry1 = stb_min(ry1, base_y+COLLIDE_BLOB_Y);
            for (b=ry0; b < ry1; ++b) {
               for (a=rx0; a < rx1; ++a) {
                  phys_chunk_run *pcr = mc->pc.column[b - y0][a - x0];
                  int z=0;

                  while (z < MAX_Z) {
                     int next_z = z + pcr->length;
                     if (base_z <= next_z && z < base_z + COLLIDE_BLOB_Z) {
                        int z0 = stb_max(base_z, z);
                        int z1 = stb_min(base_z+COLLIDE_BLOB_Z, next_z);
                        int k;
                        for (k=z0; k < z1; ++k)
                           cg->data[b-base_y][a-base_x][k-base_z] = pcr->type;
                     }
                     z = next_z;
                     ++pcr;
                  }
               }
            }
         }
      }
   }
   return !found_bad;
}
Exemplo n.º 2
0
mesh_chunk *get_physics_chunk_for_coord(int x, int y)
{
   int cx = C_MESH_CHUNK_X_FOR_WORLD_X(x);
   int cy = C_MESH_CHUNK_Y_FOR_WORLD_Y(y);
   int rx = cx & (S_PHYSICS_CACHE_X-1);
   int ry = cy & (S_PHYSICS_CACHE_Y-1);
   mesh_chunk *mc = &s_phys_cache[ry][rx];
   if (mc->chunk_x == cx && mc->chunk_y == cy)
      return mc;
   return NULL;
}
Exemplo n.º 3
0
void physics_process_mesh_chunk(mesh_chunk *mc)
{
   int player_cx = C_MESH_CHUNK_X_FOR_WORLD_X(player_x);
   int player_cy = C_MESH_CHUNK_Y_FOR_WORLD_Y(player_y);

   // if it's within the player bounds, update it
   if (mc->chunk_x >= player_cx - S_PHYSICS_CACHE_X/2 && mc->chunk_x < player_cx + S_PHYSICS_CACHE_X/2 &&
       mc->chunk_y >= player_cy - S_PHYSICS_CACHE_Y/2 && mc->chunk_y < player_cy + S_PHYSICS_CACHE_Y/2)
   {
      int phys_cache_x = (mc->chunk_x & (S_PHYSICS_CACHE_X-1));
      int phys_cache_y = (mc->chunk_y & (S_PHYSICS_CACHE_Y-1));
      mesh_chunk *phys_cache_mc = &s_phys_cache[phys_cache_y][phys_cache_x];

      free_mesh_chunk_physics(phys_cache_mc);

      *phys_cache_mc = *mc;
   }

   update_physics_cache_feedback();
}
Exemplo n.º 4
0
int physics_set_player_coord(requested_mesh *rm, int max_req, int px, int py)
{
   int i,j,n=0;

   int player_cx, player_cy;

   player_x = px;
   player_y = py;

   player_cx = C_MESH_CHUNK_X_FOR_WORLD_X(player_x);
   player_cy = C_MESH_CHUNK_Y_FOR_WORLD_Y(player_y);

   for (j=0; j < S_PHYSICS_CACHE_Y; ++j) {
      for (i=0; i < S_PHYSICS_CACHE_X; ++i) {
         int rx = player_cx - S_PHYSICS_CACHE_X/2 + i;
         int ry = player_cy - S_PHYSICS_CACHE_Y/2 + j;
         mesh_chunk *phys_cache_mc = &s_phys_cache[ry & (S_PHYSICS_CACHE_Y-1)][rx & (S_PHYSICS_CACHE_X-1)];
         if (phys_cache_mc->chunk_x != rx || phys_cache_mc->chunk_y != ry) {
            if (n < max_req) {
               rm[n].x = rx << MESH_CHUNK_SIZE_X_LOG2;
               rm[n].y = ry << MESH_CHUNK_SIZE_Y_LOG2;
               rm[n].state = RMS_requested;
               rm[n].needs_triangles = False;
               ++n;
            }
         }
      }
   }

   update_physics_cache_feedback();

   #if 1
   return n;
   #else
   return 0;
   #endif
}
Exemplo n.º 5
0
void render_voxel_world(float campos[3])
{
   int num_build_remaining;
   int distance;
   float x = campos[0], y = campos[1];
   int qchunk_x, qchunk_y;
   int cam_x, cam_y;
   int i,j, rad;

#ifdef SINGLE_THREADED_MESHBUILD
   num_build_remaining = 1;
#else
   num_build_remaining = 0;
#endif

   cam_x = (int) floor(x);
   cam_y = (int) floor(y);

   qchunk_x = C_MESH_CHUNK_X_FOR_WORLD_X(cam_x);
   qchunk_y = C_MESH_CHUNK_Y_FOR_WORLD_Y(cam_y);

   request_mesh_generation(qchunk_x, qchunk_y, cam_x, cam_y);

   glEnable(GL_ALPHA_TEST);
   glAlphaFunc(GL_GREATER, 0.5);

   stbglUseProgram(main_prog);
   setup_uniforms(campos); // set uniforms to default values inefficiently
   glActiveTextureARB(GL_TEXTURE2_ARB);
   stbglEnableVertexAttribArray(0);

   rad = view_distance >> MESH_CHUNK_SIZE_X_LOG2;
   view_dist_for_display = view_distance;

   {
      float lighting[2][3] = { { 0,0,0 }, { 0.75,0.75,0.65f } };
      float bright = 32;
      lighting[0][0] = light_pos[0];
      lighting[0][1] = light_pos[1];
      lighting[0][2] = light_pos[2];
      lighting[1][0] *= bright;
      lighting[1][1] *= bright;
      lighting[1][2] *= bright;
      stbglUniform3fv(stbgl_find_uniform(main_prog, "light_source"), 2, lighting[0]);
   }

   quads_rendered = 0;
   quads_considered = 0;
   chunk_storage_rendered = 0;
   chunk_storage_considered = 0;
   chunk_locations = 0;
   chunks_considered = 0;
   chunks_in_frustum = 0;

   compute_frustum();

   for (distance = 0; distance <= rad; ++distance) {
      for (j=-distance; j <= distance; ++j) {
         for (i=-distance; i <= distance; ++i) {
            int cx = qchunk_x + i;
            int cy = qchunk_y + j;
            int slot_x = cx & (C_MESH_CHUNK_CACHE_X-1);
            int slot_y = cy & (C_MESH_CHUNK_CACHE_Y-1);
            mesh_chunk *mc = c_mesh_cache[slot_y][slot_x];

            if (stb_max(abs(i),abs(j)) != distance)
               continue;

            if (i*i + j*j > rad*rad)
               continue;

            if (mc == NULL || mc->chunk_x != cx || mc->chunk_y != cy || mc->vbuf == 0) {
               float estimated_bounds[2][3];
               if (num_build_remaining == 0)
                  continue;
               estimated_bounds[0][0] = (float) ( cx    << MESH_CHUNK_SIZE_X_LOG2);
               estimated_bounds[0][1] = (float) ( cy    << MESH_CHUNK_SIZE_Y_LOG2);
               estimated_bounds[0][2] = (float) (0);
               estimated_bounds[1][0] = (float) ((cx+1) << MESH_CHUNK_SIZE_X_LOG2);
               estimated_bounds[1][1] = (float) ((cy+1) << MESH_CHUNK_SIZE_Y_LOG2);
               estimated_bounds[1][2] = (float) (255);
               if (!is_box_in_frustum(estimated_bounds[0], estimated_bounds[1]))
                  continue;
               mc = build_mesh_chunk_for_coord(cx * C_MESH_CHUNK_CACHE_X, cy * C_MESH_CHUNK_CACHE_Y);
               --num_build_remaining;
            }

            ++chunk_locations;

            ++chunks_considered;
            quads_considered += mc->num_quads;
            chunk_storage_considered += mc->num_quads * 20;

            if (mc->num_quads) {
               if (is_box_in_frustum(mc->bounds[0], mc->bounds[1])) {
                  // @TODO if in range, frustum cull
                  stbglUniform3fv(stbgl_find_uniform(main_prog, "transform"), 3, mc->transform[0]);
                  glBindBufferARB(GL_ARRAY_BUFFER_ARB, mc->vbuf);
                  glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, 4, (void*) 0);
                  glBindTexture(GL_TEXTURE_BUFFER_ARB, mc->fbuf_tex);

                  glDrawArrays(GL_QUADS, 0, mc->num_quads*4);

                  quads_rendered += mc->num_quads;
                  ++chunks_in_frustum;
                  chunk_storage_rendered += mc->num_quads * 20;
               }
            }
         }
      }
   }

   if (num_build_remaining) {
      for (j=-rad; j <= rad; ++j) {
         for (i=-rad; i <= rad; ++i) {
            int cx = qchunk_x + i;
            int cy = qchunk_y + j;
            int slot_x = cx & (C_MESH_CHUNK_CACHE_X-1);
            int slot_y = cy & (C_MESH_CHUNK_CACHE_Y-1);
            mesh_chunk *mc = c_mesh_cache[slot_y][slot_x];
            if (mc->chunk_x != cx || mc->chunk_y != cy || mc->vbuf == 0) {
               mc = build_mesh_chunk_for_coord(cx * C_MESH_CHUNK_CACHE_X, cy * C_MESH_CHUNK_CACHE_Y);
               --num_build_remaining;
               if (num_build_remaining == 0)
                  goto done;
            }
         }
      }
      done:
      ;
   }

   {
      built_mesh bm;
      while (get_next_built_mesh(&bm)) {
         if (!bm.mc->has_triangles) {
            // server:
            physics_process_mesh_chunk(bm.mc);
            // don't free the physics data below, because the above call copies them
            bm.mc->allocs = NULL;
            free_mesh_chunk(bm.mc);
         } else {
            //s_process_mesh_chunk(bm.mc);
            // client:
            upload_mesh(bm.mc, bm.vertex_build_buffer, bm.face_buffer);
            set_mesh_chunk_for_coord(bm.mc->chunk_x * MESH_CHUNK_SIZE_X, bm.mc->chunk_y * MESH_CHUNK_SIZE_Y, bm.mc);
            free(bm.face_buffer);
            free(bm.vertex_build_buffer);
            bm.mc = NULL;
         }
      }
   }

   chunk_storage_total = 0;
   for (j=0; j < C_MESH_CHUNK_CACHE_Y; ++j)
      for (i=0; i < C_MESH_CHUNK_CACHE_X; ++i)
         if (c_mesh_cache[j][i] != NULL && c_mesh_cache[j][i]->vbuf)
            chunk_storage_total += c_mesh_cache[j][i]->num_quads * 20;

   stbglDisableVertexAttribArray(0);
   glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
   glActiveTextureARB(GL_TEXTURE0_ARB);

   stbglUseProgram(0);
}