mesh_chunk *build_mesh_chunk_for_coord(int x, int y) { int cx = MESH_CHUNK_X_FOR_WORLD_X(x); int slot_x = cx & (MESH_CHUNK_CACHE_X-1); int cy = MESH_CHUNK_Y_FOR_WORLD_Y(y); int slot_y = cy & (MESH_CHUNK_CACHE_Y-1); mesh_chunk *mc = &mesh_cache[slot_y][slot_x]; if (mc->vbuf) { assert(mc->chunk_x != cx || mc->chunk_y != cy); free_mesh_chunk(mc); } { stbvox_mesh_maker mm; chunk_set cs; int i,j; vec3i wc = { x,y,0 }; for (j=0; j < 4; ++j) for (i=0; i < 4; ++i) cs.chunk[j][i] = get_gen_chunk_for_coord(x + (i-1)*GEN_CHUNK_SIZE_X, y + (j-1)*GEN_CHUNK_SIZE_Y); stbvox_init_mesh_maker(&mm); generate_mesh_for_chunk_set(&mm, mc, wc, &cs, vertex_build_buffer, sizeof(vertex_build_buffer), face_buffer); upload_mesh(mc, vertex_build_buffer, face_buffer); } return mc; }
int mesh_worker_handler(void *data) { for(;;) { task t; if (get_pending_task(&t)) { switch (t.task_type) { case JOB_build_mesh: { stbvox_mesh_maker mm; mesh_chunk *mc = malloc(sizeof(*mc)); built_mesh out_mesh; vec3i wc = { t.world_x, t.world_y, 0 }; stbvox_init_mesh_maker(&mm); mc->chunk_x = t.world_x >> MESH_CHUNK_CACHE_X_LOG2; mc->chunk_y = t.world_y >> MESH_CHUNK_CACHE_Y_LOG2; generate_mesh_for_chunk_set(&mm, mc, wc, &t.cs, vertex_build_buffer, sizeof(vertex_build_buffer), face_buffer); out_mesh.vertex_build_buffer = malloc(mc->num_quads * 16); out_mesh.face_buffer = malloc(mc->num_quads * 4); memcpy(out_mesh.vertex_build_buffer, vertex_build_buffer, mc->num_quads * 16); memcpy(out_mesh.face_buffer, face_buffer, mc->num_quads * 4); { int i; for (i=0; i < 16; ++i) release_gen_chunk(t.cs.chunk[0][i]); } out_mesh.mc = mc; if (!add_to_queue(&built_meshes, &out_mesh)) { free(out_mesh.vertex_build_buffer); free(out_mesh.face_buffer); } else waiter_wake(&manager_monitor); break; } case JOB_generate_terrain: { finished_gen_chunk fgc; fgc.world_x = t.world_x; fgc.world_y = t.world_y; fgc.gc = generate_chunk(t.world_x, t.world_y); if (!add_to_queue(&finished_gen, &fgc)) release_gen_chunk(fgc.gc); else { ++fgc.gc->ref_count; waiter_wake(&manager_monitor); } break; } } } } }
int mesh_worker_handler(void *data) { for(;;) { task t; if (get_pending_task(&t)) { switch (t.task_type) { case JOB_build_mesh: { stbvox_mesh_maker mm; mesh_chunk *mc = malloc(sizeof(*mc)); built_mesh out_mesh; vec3i wc = { t.world_x, t.world_y, 0 }; stbvox_init_mesh_maker(&mm); mc->chunk_x = t.world_x >> MESH_CHUNK_CACHE_X_LOG2; mc->chunk_y = t.world_y >> MESH_CHUNK_CACHE_Y_LOG2; generate_mesh_for_chunk_set(&mm, mc, wc, &t.cs, vertex_build_buffer, sizeof(vertex_build_buffer), face_buffer); out_mesh.vertex_build_buffer = malloc(mc->num_quads * 16); out_mesh.face_buffer = malloc(mc->num_quads * 4); memcpy(out_mesh.vertex_build_buffer, vertex_build_buffer, mc->num_quads * 16); memcpy(out_mesh.face_buffer, face_buffer, mc->num_quads * 4); out_mesh.mc = mc; if (!add_built_mesh(&out_mesh)) { free(out_mesh.vertex_build_buffer); free(out_mesh.face_buffer); } break; } case JOB_generate_terrain: { finished_gen_chunk fgc; fgc.world_x = t.world_x; fgc.world_y = t.world_y; fgc.gc = generate_chunk(t.world_x, t.world_y); if (!add_gen(fgc)) free(fgc.gc); break; } } } } }