void bsp_tree_create_from_solid(struct BspTree* tree, struct Solid* solid) { size_t alloc_attributes_result = bsp_tree_alloc_attributes(tree, solid->attributes_size); log_assert( alloc_attributes_result >= solid->attributes_size ); size_t num_polygons = solid->indices_size/3; size_t alloc_polygons_result = bsp_tree_alloc_polygons(tree, num_polygons); log_assert( alloc_polygons_result >= num_polygons ); size_t alloc_nodes_result = bsp_tree_alloc_nodes(tree, num_polygons); log_assert( alloc_nodes_result >= num_polygons ); int32_t* workset_polygons_front = malloc(alloc_polygons_result * sizeof(int32_t)); log_assert( workset_polygons_front != NULL ); int32_t* workset_polygons_back = malloc(alloc_polygons_result * sizeof(int32_t)); log_assert( workset_polygons_back != NULL ); float min_x = FLT_MAX; float min_y = FLT_MAX; float min_z = FLT_MAX; float max_x = -FLT_MAX; float max_y = -FLT_MAX; float max_z = -FLT_MAX; for( size_t indices_i = 0; indices_i < solid->indices_size+1; indices_i++ ) { uint32_t src_i = solid->indices[indices_i]; if( indices_i < solid->indices_size ) { VecP* src = &solid->vertices[src_i*VERTEX_SIZE]; VecP* dst = &tree->attributes.vertices[indices_i*VERTEX_SIZE]; vec_copy3f(src, dst); tree->attributes.occupied += 1; if( src[0] < min_x ) { min_x = src[0]; } if( src[1] < min_y ) { min_y = src[1]; } if( src[2] < min_z ) { min_z = src[2]; } if( src[0] > max_x ) { max_x = src[0]; } if( src[1] > max_y ) { max_y = src[1]; } if( src[2] > max_z ) { max_z = src[2]; } } if( indices_i > 0 && indices_i % 3 == 0 ) { size_t poly_i = indices_i / 3 - 1; tree->polygons.array[poly_i].start = poly_i*3*VERTEX_SIZE; tree->polygons.array[poly_i].size = 3; polygon_normal(3, VERTEX_SIZE, &tree->attributes.vertices[poly_i*3*VERTEX_SIZE], tree->polygons.array[poly_i].normal); tree->polygons.occupied += 1; workset_polygons_front[poly_i] = poly_i; } } struct BspNode* root = &tree->nodes.array[0]; bsp_node_create(root); tree->nodes.occupied = 1; root->bounds.half_width = (max_x - min_x)/2.0f; root->bounds.half_height = (max_y - min_y)/2.0f; root->bounds.half_depth = (max_z - min_z)/2.0f; root->bounds.center[0] = min_x + root->bounds.half_width; root->bounds.center[1] = min_y + root->bounds.half_height; root->bounds.center[2] = min_z + root->bounds.half_depth; root->divider = 0; bsp_select_balanced_divider(tree, root, num_polygons, workset_polygons_front, &root->divider); struct BspPoly* root_divider = &tree->polygons.array[root->divider]; const float* root_divider_polygon = &tree->attributes.vertices[root_divider->start]; draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 0, 0, 255}, 0.01f, root_divider->size, root_divider_polygon, root_divider->normal); draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 0, 0, 255}, 0.01f, root_divider->normal, &root_divider_polygon[3], 1.0f, 0.1f); /* draw_plane(&global_static_canvas, MAX_CANVAS_LAYERS-1, (Mat)IDENTITY_MAT, (Color){120, 120, 150, 127}, root_divider->normal, &root_divider_polygon[3], 10.0f); */ for( size_t polygon_i = 0; polygon_i < num_polygons; polygon_i++ ) { size_t cuts_polygon_size = 3; const float* cuts_polygon = &tree->attributes.vertices[polygon_i*cuts_polygon_size*VERTEX_SIZE]; size_t result_size = cuts_polygon_size; struct PolygonCutPoints result_points[cuts_polygon_size]; enum PolygonCutType result_type = polygon_cut(cuts_polygon_size, VERTEX_SIZE, cuts_polygon, root_divider->normal, root_divider_polygon, result_size, result_points); Vec3f cuts_polygon_normal = {0}; polygon_normal(3, VERTEX_SIZE, cuts_polygon, cuts_polygon_normal); switch(result_type) { case POLYGON_COPLANNAR: //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 255, 255, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal); break; case POLYGON_FRONT: //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 0, 255, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal); break; case POLYGON_BACK: //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){0, 0, 255, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal); break; case POLYGON_SPANNING: //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 255, 0, 255}, 0.01f, result_size, cuts_polygon, cuts_polygon_normal); if( result_points[0].num_cuts > 0 ) { size_t new_poly_size = cuts_polygon_size+result_points[0].num_cuts+10; size_t front_occupied = 0; float front_vertices[new_poly_size*VERTEX_SIZE]; size_t back_occupied = 0; float back_vertices[new_poly_size*VERTEX_SIZE]; for( size_t result_i = 0; result_i < result_size; result_i++ ) { if( result_points[result_i].type == POLYGON_BACK ) { vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &back_vertices[back_occupied*VERTEX_SIZE]); back_occupied += 1; } else if( result_points[result_i].type == POLYGON_FRONT ) { vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &front_vertices[front_occupied*VERTEX_SIZE]); front_occupied += 1; } else if( result_points[result_i].type == POLYGON_COPLANNAR ) { vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &back_vertices[back_occupied*VERTEX_SIZE]); back_occupied += 1; vec_copy3f(&cuts_polygon[result_i*VERTEX_SIZE], &front_vertices[front_occupied*VERTEX_SIZE]); front_occupied += 1; } if( result_points[result_i].interpolation_index > -1 ) { const VecP* a = &cuts_polygon[result_i*VERTEX_SIZE]; const VecP* b = &cuts_polygon[result_points[result_i].interpolation_index*VERTEX_SIZE]; Vec3f r = {0}; vec_lerp(b, a, result_points[result_i].interpolation_value, r); vec_copy3f(r, &back_vertices[back_occupied*VERTEX_SIZE]); back_occupied += 1; vec_copy3f(r, &front_vertices[front_occupied*VERTEX_SIZE]); front_occupied += 1; } } //printf("front_occupied: %lu\n", front_occupied); //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, red, 0.01f, front_occupied, front_vertices, cuts_polygon_normal); //draw_polygon_wire(&global_static_canvas, 0, (Mat)IDENTITY_MAT, white, 0.01f, back_occupied, back_vertices, cuts_polygon_normal); } break; } } log_fail(__FILE__, __LINE__, "BUILT BSP TREE... OR NOT?\n"); }
int32_t main(int32_t argc, char *argv[]) { printf("<<watchlist//>>\n"); if( init_sdl2() ) { return 1; } int32_t width = 1280; int32_t height = 720; SDL_Window* window; sdl2_window("cute3d: " __FILE__, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, &window); SDL_GLContext* context; sdl2_glcontext(3, 2, window, &context); if( init_shader() ) { return 1; } if( init_canvas(width, height) ) { return 1; } canvas_create("global_dynamic_canvas", &global_dynamic_canvas); struct Arcball arcball = {0}; arcball_create(width, height, (Vec4f){0.0,6.0,10.0,1.0}, (Vec4f){0.0,0.0,0.0,1.0}, 0.001f, 100.0, &arcball); struct GameTime time = {0}; gametime_create(1.0f / 60.0f, &time); Vec4f a = {0.0f, 0.0f, 1.0f}; Vec4f b = {1.0f, 0.0f, 1.0f}; draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){25, 255, 25, 255}, 0.01f, a, (Vec3f){0.0f, 0.0f, 0.0f}, 1.0f, 1.0f); draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 25, 25, 255}, 0.01f, b, (Vec3f){0.0f, 0.0f, 0.0f}, 1.0f, 1.0f); Quat axis_angle_rot = {0}; quat_from_axis_angle((Vec4f)Y_AXIS, PI/4, axis_angle_rot); draw_quaternion(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 255, 255, 255}, (Color){255, 0, 255, 255}, 0.01f, axis_angle_rot, 2.0f); vec_print("axis_angle_rot: ", axis_angle_rot); Vec4f axis_angle_result = {0}; vec_rotate(a, axis_angle_rot, axis_angle_result); draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 255, 25, 255}, 0.01f, axis_angle_result, (Vec3f){0.0f, 0.0f, 0.0f}, 1.0f, 2.0f); Vec4f axis = {0}; float angle = 0.0f; quat_to_axis_angle(axis_angle_rot, axis, &angle); Quat axis_angle_rot2 = {0}; quat_from_axis_angle(axis, angle, axis_angle_rot2); vec_print("axis_angle_rot2: ", axis_angle_rot2); Quat euler_angles_rot = {0}; quat_from_euler_angles(0.0f, PI/4, 0.0f, euler_angles_rot); vec_print("euler_angles_rot: ", euler_angles_rot); Vec4f euler_angles_result = {0}; vec_rotate(a, euler_angles_rot, euler_angles_result); draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){25, 255, 255, 255}, 0.01f, euler_angles_result, (Vec3f){0.0f, 0.0f, 0.0f}, 1.0f, 3.0f); Quat vec_pair_rot = {0}; quat_from_vec_pair(a, b, vec_pair_rot); vec_print("vec_pair_rot: ", vec_pair_rot); Vec4f vec_pair_result = {0}; vec_rotate(a, vec_pair_rot, vec_pair_result); draw_vec(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){255, 25, 255, 255}, 0.01f, vec_pair_result, (Vec3f){0.0f, 0.0f, 0.0f}, 1.0f, 4.0f); Mat xaxis_control = {0}; xaxis_control[0] = 1; xaxis_control[4] = 0; xaxis_control[8] = 0; xaxis_control[12] = 0; xaxis_control[1] = 0; xaxis_control[5] = cosf(PI/4); xaxis_control[9] = -sinf(PI/4); xaxis_control[13] = 0; xaxis_control[2] = 0; xaxis_control[6] = sinf(PI/4); xaxis_control[10] = cosf(PI/4); xaxis_control[14] = 0; xaxis_control[3] = 0; xaxis_control[7] = 0; xaxis_control[11] = 0; xaxis_control[15] = 1; mat_print("xaxis_control: ", xaxis_control); Quat xaxis_rot = {0}; quat_from_axis_angle((Vec4f)X_AXIS, PI/4, xaxis_rot); Mat xaxis_mat = {0}; quat_to_mat(xaxis_rot, xaxis_mat); mat_print("xaxis_mat: ", xaxis_mat); Mat yaxis_control = {0}; yaxis_control[0] = cosf(PI/4); yaxis_control[4] = 0; yaxis_control[8] = sinf(PI/4); yaxis_control[12] = 0; yaxis_control[1] = 0; yaxis_control[5] = 1; yaxis_control[9] = 0; yaxis_control[13] = 0; yaxis_control[2] = -sinf(PI/4); yaxis_control[6] = 0; yaxis_control[10] = cosf(PI/4); yaxis_control[14] = 0; yaxis_control[3] = 0; yaxis_control[7] = 0; yaxis_control[11] = 0; yaxis_control[15] = 1; mat_print("yaxis_control: ", yaxis_control); Quat yaxis_rot = {0}; quat_from_axis_angle((Vec4f)Y_AXIS, PI/4, yaxis_rot); Mat yaxis_mat = {0}; quat_to_mat(yaxis_rot, yaxis_mat); mat_print("yaxis_mat: ", yaxis_mat); Mat zaxis_control = {0}; zaxis_control[0] = cosf(PI/4); zaxis_control[4] = -sinf(PI/4); zaxis_control[8] = 0; zaxis_control[12] = 0; zaxis_control[1] = sinf(PI/4); zaxis_control[5] = cosf(PI/4); zaxis_control[9] = 0; zaxis_control[13] = 0; zaxis_control[2] = 0; zaxis_control[6] = 0; zaxis_control[10] = 1; zaxis_control[14] = 0; zaxis_control[3] = 0; zaxis_control[7] = 0; zaxis_control[11] = 0; zaxis_control[15] = 1; mat_print("zaxis_control: ", zaxis_control); Quat zaxis_rot = {0}; quat_from_axis_angle((Vec4f)Z_AXIS, PI/4, zaxis_rot); Mat zaxis_mat = {0}; quat_to_mat(zaxis_rot, zaxis_mat); mat_print("zaxis_mat: ", zaxis_mat); draw_grid(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){120, 120, 120, 255}, 0.01f, 12.0f, 12.0f, 12); while(true) { SDL_Event event; while( sdl2_poll_event(&event) ) { if( sdl2_handle_quit(event) ) { goto done; } sdl2_handle_resize(event); arcball_handle_resize(&arcball, event); arcball_handle_mouse(&arcball, event); } sdl2_gl_set_swap_interval(0); ogl_debug( glClearDepth(1.0f); glClearColor(.0f, .0f, .0f, 1.0f); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); ); gametime_advance(&time, sdl2_time_delta()); gametime_integrate(&time); canvas_render_layers(&global_static_canvas, 0, MAX_CANVAS_LAYERS, &arcball.camera, (Mat)IDENTITY_MAT); sdl2_gl_swap_window(window); }