Exemple #1
0
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");
}
Exemple #2
0
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);
    }