Exemplo n.º 1
0
void bsp_select_balanced_divider(const struct BspTree* tree, const struct BspNode* node, size_t num_polygons, const int32_t* polygon_indices, int32_t* selected_divider) {
    *selected_divider = 0;

    float node_width = node->bounds.half_width*2.0f;
    float node_height = node->bounds.half_height*2.0f;
    float node_depth = node->bounds.half_depth*2.0f;

    Vec3f normal_comparison_axis = {0};
    if( node_width <= node_height && node_width <= node_depth ) {
        vec_copy3f((Vec4f)X_AXIS, normal_comparison_axis);
    } else if( node_height <= node_width && node_height <= node_depth ) {
        vec_copy3f((Vec4f)Y_AXIS, normal_comparison_axis);
    } else if( node_depth <= node_width && node_depth <= node_height ) {
        vec_copy3f((Vec4f)Z_AXIS, normal_comparison_axis);
    }

    float min_dot = FLT_MAX;
    Vec3f min_diff_center = {FLT_MAX, FLT_MAX, FLT_MAX};
    int32_t best_i = -1;
    for( size_t polygon_i = 0; polygon_i < num_polygons; polygon_i++ ) {
        int32_t index_i = polygon_indices[polygon_i];
        int32_t start_i = tree->polygons.array[index_i].start;

        float dot = FLT_MAX;
        vec_dot(tree->polygons.array[index_i].normal, normal_comparison_axis, &dot);
        if( fabs(dot) < min_dot ) {
            min_dot = fabs(dot);
            best_i = polygon_i;
        }

        Vec3f average_vertex = {0.0f, 0.0f, 0.0f};
        for( size_t size_i = 0; size_i < tree->polygons.array[index_i].size; size_i++ ) {

        }
    }
}
Exemplo n.º 2
0
int32_t main(int32_t argc, char *argv[]) {
    if( init_sdl2() ) {
        return 1;
    }

    int width = 1280;
    int 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);
    canvas_create("global_static_canvas", &global_static_canvas);

    struct Vbo vbo = {0};
    vbo_create(&vbo);
    vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_STATIC_DRAW);
    vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_NORMAL, 3, GL_FLOAT, GL_STATIC_DRAW);
    vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_STATIC_DRAW);
    vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_NORMAL, NORMAL_SIZE, GL_FLOAT, GL_STATIC_DRAW);

    struct Ibo ibo = {0};
    ibo_create(GL_TRIANGLES, GL_UNSIGNED_INT, GL_STATIC_DRAW, &ibo);

    struct SolidTetrahedron hard_tetrahedron = {0};
    struct SolidBox hard_cube = {0};
    struct SolidSphere16 hard_sphere16 = {0};
    struct SolidSphere32 hard_sphere32 = {0};
    solid_tetrahedron_create(1.0, (Color){255, 0, 0, 255}, &hard_tetrahedron);
    solid_cube_create(0.5, (Color){0, 255, 0, 255}, &hard_cube);
    solid_sphere16_create(16, 8, 0.75, (Color){0, 255, 255, 255}, &hard_sphere16);
    solid_sphere32_create(32, 16, 0.75, (Color){255, 255, 0, 255}, &hard_sphere32);

    solid_optimize((struct Solid*)&hard_tetrahedron);
    solid_optimize((struct Solid*)&hard_cube);
    solid_optimize((struct Solid*)&hard_sphere16);
    solid_optimize((struct Solid*)&hard_sphere32);

    struct VboMesh hard_tetrahedron_mesh, hard_box_mesh, hard_cube_mesh, hard_sphere16_mesh, hard_sphere32_mesh;
    vbo_mesh_create_from_solid((struct Solid*)&hard_tetrahedron, &vbo, &ibo, &hard_tetrahedron_mesh);
    vbo_mesh_create_from_solid((struct Solid*)&hard_cube, &vbo, &ibo, &hard_cube_mesh);
    vbo_mesh_create_from_solid((struct Solid*)&hard_sphere16, &vbo, &ibo, &hard_sphere16_mesh);
    vbo_mesh_create_from_solid((struct Solid*)&hard_sphere32, &vbo, &ibo, &hard_sphere32_mesh);

    struct SolidTetrahedron smooth_tetrahedron = {0};
    struct SolidBox smooth_cube = {0};
    struct SolidSphere16 smooth_sphere16 = {0};
    struct SolidSphere32 smooth_sphere32 = {0};
    solid_tetrahedron_create(1.0, (Color){255, 0, 0, 255}, &smooth_tetrahedron);
    solid_cube_create(0.5, (Color){0, 255, 0, 255}, &smooth_cube);
    solid_sphere16_create(16, 8, 0.75, (Color){0, 255, 255, 255}, &smooth_sphere16);
    solid_sphere32_create(32, 16, 0.75, (Color){255, 255, 0, 255}, &smooth_sphere32);

    solid_optimize((struct Solid*)&smooth_tetrahedron);
    solid_optimize((struct Solid*)&smooth_cube);
    solid_optimize((struct Solid*)&smooth_sphere16);
    solid_optimize((struct Solid*)&smooth_sphere32);
    solid_smooth_normals((struct Solid*)&smooth_tetrahedron, smooth_tetrahedron.normals, smooth_tetrahedron.normals);
    solid_smooth_normals((struct Solid*)&smooth_cube, smooth_cube.normals, smooth_cube.normals);
    solid_smooth_normals((struct Solid*)&smooth_sphere16, smooth_sphere16.normals, smooth_sphere16.normals);
    solid_smooth_normals((struct Solid*)&smooth_sphere32, smooth_sphere32.normals, smooth_sphere32.normals);

    struct VboMesh smooth_tetrahedron_mesh, smooth_box_mesh, smooth_cube_mesh, smooth_sphere16_mesh, smooth_sphere32_mesh;
    vbo_mesh_create_from_solid((struct Solid*)&smooth_tetrahedron, &vbo, &ibo, &smooth_tetrahedron_mesh);
    vbo_mesh_create_from_solid((struct Solid*)&smooth_cube, &vbo, &ibo, &smooth_cube_mesh);
    vbo_mesh_create_from_solid((struct Solid*)&smooth_sphere16, &vbo, &ibo, &smooth_sphere16_mesh);
    vbo_mesh_create_from_solid((struct Solid*)&smooth_sphere32, &vbo, &ibo, &smooth_sphere32_mesh);

    struct Arcball arcball = {0};
    arcball_create(width, height, (Vec4f){2.5,17.0,17.0,1.0}, (Vec4f){2.5,0.0,0.0,1.0}, 0.1, 100.0, &arcball);

    float circular_motion_angle = 0.0f;
    float circular_motion_speed = (2.0f*PI)/30;
    float circular_motion_radius = 12.0f;

    Vec3f light_position = { circular_motion_radius, 10.0, circular_motion_radius };
    Vec3f light_direction = {0};
    vec_sub((Vec3f){0.0f, 0.0f, 0.0f}, light_position, light_direction);
    vec_normalize(light_direction, light_direction);

    Vec3f eye_position = {0};
    vec_copy3f(arcball.camera.pivot.position, eye_position);

    Color ambiance = {50, 25, 150, 255};
    Color specular = {255, 255, 255, 255};
    float material_shininess = 1.0;
    Vec4f material_coefficients = { 0.8, 0.2, 0.0, 0.0 };

    // flat
    struct Shader flat_shader = {0};
    shader_create(&flat_shader);
    shader_attach(&flat_shader, GL_VERTEX_SHADER, "prefix.vert", 1, "flat_shading.vert");
    shader_attach(&flat_shader, GL_FRAGMENT_SHADER, "prefix.frag", 1, "flat_shading.frag");
    shader_make_program(&flat_shader, SHADER_DEFAULT_NAMES, "flat_shader");

    shader_set_uniform_3f(&flat_shader, flat_shader.program, SHADER_UNIFORM_LIGHT_DIRECTION, 3, GL_FLOAT, light_direction);
    shader_set_uniform_4f(&flat_shader, flat_shader.program, SHADER_UNIFORM_AMBIENT_LIGHT, 4, GL_UNSIGNED_BYTE, ambiance);

    // gouraud
    struct Shader gouraud_shader = {0};
    shader_create(&gouraud_shader);
    shader_attach(&gouraud_shader, GL_VERTEX_SHADER, "prefix.vert", 1, "gouraud_shading.vert");
    shader_attach(&gouraud_shader, GL_FRAGMENT_SHADER, "prefix.frag", 1, "gouraud_shading.frag");
    shader_make_program(&gouraud_shader, SHADER_DEFAULT_NAMES, "gouraud_shader");

    shader_set_uniform_3f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_LIGHT_POSITION, 3, GL_FLOAT, light_position);
    shader_set_uniform_3f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_EYE_POSITION, 3, GL_FLOAT, eye_position);
    shader_set_uniform_4f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_AMBIENT_LIGHT, 4, GL_UNSIGNED_BYTE, ambiance);
    shader_set_uniform_4f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_SPECULAR_LIGHT, 4, GL_UNSIGNED_BYTE, specular);
    shader_set_uniform_1f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_MATERIAL_SHININESS, 1, GL_FLOAT, &material_shininess);
    shader_set_uniform_4f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_MATERIAL_COEFFICIENTS, 4, GL_FLOAT, material_coefficients);
    shader_set_uniform_3f(&gouraud_shader, gouraud_shader.program, SHADER_UNIFORM_EYE_POSITION, 3, GL_FLOAT, &arcball.camera.pivot.position);

    Mat identity = IDENTITY_MAT;
    draw_grid(&global_static_canvas, 0, identity, (Color){127, 127, 127, 255}, 0.03f, 12.0f, 12.0f, 12);

    Mat shading_label_transform = IDENTITY_MAT;
    Quat text_rotation = IDENTITY_QUAT;
    quat_from_axis_angle((Vec3f)X_AXIS, -PI/2.0f, text_rotation);
    mat_rotate(shading_label_transform, text_rotation, shading_label_transform);
    mat_translate(shading_label_transform, (float[4]){ 6.5, 0.0, -2.5, 1.0 }, shading_label_transform);
Exemplo n.º 3
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");
}