Skip to content

Commit

Permalink
debbuging bsp worikin until split lines
Browse files Browse the repository at this point in the history
  • Loading branch information
SirAlabar committed Feb 7, 2025
1 parent 7ddcda8 commit b88df3b
Show file tree
Hide file tree
Showing 15 changed files with 1,601 additions and 257 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@ fclean: clean
leak: ${NAME}
ifeq ($(UNAME_S),Linux)
@echo "$(YELLOW)Running Valgrind for leak check...$(RESET)"
@$(VALGRIND) ./${NAME} maps/test.cub
@$(VALGRIND) ./${NAME} maps/demo_map.cub
else ifeq ($(UNAME_S),Darwin)
@echo "$(YELLOW)Running leak check for macOS...$(RESET)"
@leaks --atExit -- ./${NAME} maps/valid/valid1.cub
@leaks --atExit -- ./${NAME} maps/demo_map.cub
endif

test: all
@./$(NAME) maps/valid/valid1.cub
@./$(NAME) maps/demo_map.cub

# Rebuild rule
re: fclean all
Expand Down
31 changes: 28 additions & 3 deletions includes/bsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
# include <stddef.h>
# include <libft.h>

/* BSP Configuration */
# define BSP_WEIGHT_FACTOR 3
# define BSP_MIN_SEED 0
# define BSP_MAX_SEED 1000
# define BSP_MAX_DEPTH 16
# define BSP_MIN_NODE_SIZE 4096

/* Fixed point value for collision detection (1/16) */
# define COLLISION_THRESHOLD 4096
/* Penalty factor for each line split during partition */
Expand Down Expand Up @@ -49,6 +56,7 @@ typedef struct s_bsp_node
struct s_bsp_node *back;
t_bsp_line **lines;
int num_lines;
int depth;
} t_bsp_node;

/*
Expand All @@ -59,6 +67,9 @@ typedef struct s_bsp_node
typedef struct s_bsp_tree
{
t_bsp_node *root;
t_fixed32 best_score;
unsigned int best_seed;
int max_depth;
} t_bsp_tree;

/*
Expand Down Expand Up @@ -87,6 +98,9 @@ typedef struct s_count_data
int front;
int back;
int split;
int total_splits;
int tree_depth;
int max_depth;
} t_count_data;

/*
Expand All @@ -110,10 +124,13 @@ typedef enum e_bsp_side
*/

/* bsp_build.c */
t_bsp_node *build_bsp_tree(t_bsp_line **lines, int num_lines);
t_bsp_node *build_bsp_tree(t_bsp_line **lines, int num_lines, int depth);
t_bsp_node *build_subtrees(t_bsp_node *node, t_bsp_data *data);
t_bsp_line *choose_partition(t_bsp_line **lines, int num_lines);
t_fixed32 eval_partition(t_bsp_line *partition,
t_bsp_line **lines, int num_lines);
t_fixed32 eval_partition(t_bsp_line *partition, t_bsp_line **lines,
int num_lines, int depth);
void count_line_sides(t_bsp_line *line, t_bsp_line *partition,
t_count_data *count);

/* bsp_classify.c */
t_bsp_side bsp_classify_line(t_bsp_line *line,
Expand Down Expand Up @@ -167,4 +184,12 @@ void count_line_sides(t_bsp_line *line, t_bsp_line *partition,
t_count_data *count);
t_bsp_node *build_subtrees(t_bsp_node *node, t_bsp_data *data);


unsigned int generate_random_seed(void);
void shuffle_lines(t_bsp_line **lines, int count, unsigned int seed);
t_fixed32 evaluate_seed_quality(t_bsp_line **lines, int count,
unsigned int seed, int depth);
unsigned int find_best_seed(t_bsp_line **lines, int count, int depth);
void init_count_data(t_count_data *count);

#endif
2 changes: 2 additions & 0 deletions includes/fixed_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ t_fixed32 fixed32_sub(t_fixed32 a, t_fixed32 b);
t_fixed32 fixed32_mul(t_fixed32 a, t_fixed32 b);
t_fixed32 fixed32_div(t_fixed32 a, t_fixed32 b);
t_fixed32 fixed32_abs(t_fixed32 value);
t_fixed32 fix_max(t_fixed32 a, t_fixed32 b);
t_fixed32 fix_min(t_fixed32 a, t_fixed32 b);

/*
** Advanced operations (fixed32_vec_adv_operations.c)
Expand Down
17 changes: 17 additions & 0 deletions srcs/engine/bsp/bsp_balance.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@

#include <bsp.h>


/*
** Initializes count data structure with zero values
*/
void init_count_data(t_count_data *count)
{
count->front = 0;
count->back = 0;
count->split = 0;
count->total_splits = 0;
count->tree_depth = 0;
count->max_depth = 0;
}

/*
** Calculate balance score for a partition line
** Based on distribution of lines and potential splits
Expand All @@ -25,6 +39,9 @@ static t_fixed32 calculate_balance_score(t_bsp_node *node, t_bsp_line *line)
count.front = 0;
count.back = 0;
count.split = 0;
count.total_splits = 0;
count.tree_depth = 0;
count.max_depth = 0;
i = 0;
while (i < node->num_lines)
{
Expand Down
116 changes: 72 additions & 44 deletions srcs/engine/bsp/bsp_build.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

#include <bsp.h>

/*
** Counts how lines are distributed relative to partition
** Updates front/back counters and tracks splits
** Updates total splits and depth metrics in count data
*/
void count_line_sides(t_bsp_line *line, t_bsp_line *partition,
t_count_data *count)
{
Expand All @@ -23,92 +28,115 @@ void count_line_sides(t_bsp_line *line, t_bsp_line *partition,
else if (side == BSP_BACK)
count->back++;
else if (side == BSP_SPANNING)
{
count->split++;
count->total_splits++;
}
if (count->tree_depth > count->max_depth)
count->max_depth = count->tree_depth;
}

/*
** Evaluates the quality of a potential partition line
** Calculates a score based on balance and splits
** Higher score for balanced tree, lower score for more split lines
** Returns a score value, higher is better
** Evaluate partition quality using count data and depth
** Returns weighted score based on balance and splits
** Lower score indicates better partition
*/
t_fixed32 eval_partition(t_bsp_line *partition, t_bsp_line **lines,
int num_lines)
int num_lines, int depth)
{
t_count_data count;
int i;
t_fixed32 balance_score;
t_fixed32 split_score;
t_fixed32 depth_penalty;

count.front = 0;
count.back = 0;
count.split = 0;
i = 0;
while (i < num_lines)
init_count_data(&count);
count.tree_depth = depth;
while (num_lines--)
{
if (lines[i] != partition)
count_line_sides(lines[i], partition, &count);
i++;
if (lines[num_lines] != partition)
count_line_sides(lines[num_lines], partition, &count);
}
return (int_to_fixed32(abs(count.front - count.back))
- int_to_fixed32(count.split * 8));
balance_score = int_to_fixed32(abs(count.front - count.back));
split_score = int_to_fixed32(count.split * BSP_WEIGHT_FACTOR);
depth_penalty = int_to_fixed32((depth * depth) / BSP_MAX_DEPTH);

return (fixed32_add(fixed32_add(balance_score, split_score), depth_penalty));
}

/*
** Chooses the best partition line from a set of lines
** Uses evaluate_partition to score each potential partition
** Returns the line that creates the most balanced tree with fewest splits
** Finds best partition line using multiple random seeds
** Tests different configurations for optimal balance
** Returns line that creates most balanced tree
*/
t_bsp_line *choose_partition(t_bsp_line **lines, int num_lines)
{
t_bsp_line *best_partition;
t_bsp_line *best_line;
t_fixed32 best_score;
t_fixed32 score;
int i;
t_fixed32 curr_score;
int i;
int attempt;

best_partition = NULL;
best_score = INT32_MIN;
i = 0;
while (i < num_lines)
best_line = NULL;
best_score = INT32_MAX;
attempt = 0;
while (attempt++ < BSP_MAX_SEED)
{
score = eval_partition(lines[i], lines, num_lines);
if (score > best_score)
shuffle_lines(lines, num_lines, generate_random_seed());
i = 0;
while (i < num_lines)
{
best_score = score;
best_partition = lines[i];
curr_score = eval_partition(lines[i], lines, num_lines, 0);
if (curr_score < best_score)
{
best_score = curr_score;
best_line = lines[i];
}
i++;
}
i++;
}
return (best_partition);
return (best_line);
}

/*
** Handles recursive build of BSP subtrees
** Handles recursive build of BSP subtrees with depth tracking
** Creates front and back child nodes maintaining tree balance
** Returns pointer to parent node or NULL on failure
*/
t_bsp_node *build_subtrees(t_bsp_node *node, t_bsp_data *data)
{
node->front = build_bsp_tree(data->front_lines, data->num_front);
node->back = build_bsp_tree(data->back_lines, data->num_back);
if (!node || !data)
return (NULL);
node->front = build_bsp_tree(data->front_lines, data->num_front,
node->depth + 1);
node->back = build_bsp_tree(data->back_lines, data->num_back,
node->depth + 1);
free(data->front_lines);
free(data->back_lines);
return (node);
}

/*
** Main recursive function to build the BSP tree
** Builds BSP tree recursively with depth tracking
** Uses balanced partition selection at each level
** Returns NULL if max depth reached or build fails
*/
t_bsp_node *build_bsp_tree(t_bsp_line **lines, int num_lines)
t_bsp_node *build_bsp_tree(t_bsp_line **lines, int num_lines, int depth)
{
t_bsp_node *node;
t_bsp_data data;
t_bsp_data split_data;
t_bsp_line *partition;

if (num_lines == 0)
if (!lines || !num_lines || depth >= BSP_MAX_DEPTH)
return (NULL);
node = create_bsp_node();
if (!node)
return (NULL);
node->partition = choose_partition(lines, num_lines);
if (!node->partition)
node->depth = depth;
partition = choose_partition(lines, num_lines);
if (!partition)
return (free_and_return(node, NULL));
if (!split_lines(node->partition, lines, num_lines, &data))
if (!split_lines(partition, lines, num_lines, &split_data))
return (free_and_return(node, NULL));
return (build_subtrees(node, &data));
}
node->partition = partition;
return (build_subtrees(node, &split_data));
}
65 changes: 47 additions & 18 deletions srcs/engine/bsp/bsp_classify.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,56 @@
** - BSP_ON if point lies on the line
** Uses cross product in fixed-point for efficient classification
*/
t_bsp_side bsp_classify_point(t_fixed_vec32 point, t_bsp_line *partition)
t_bsp_side bsp_classify_point(t_fixed_vec32 point, t_bsp_line *partition)
{
t_fixed_vec32 vec_to_point;
t_fixed_vec32 line_vec;
t_fixed32 cross_product;
t_fixed32 epsilon;
if (!partition)
return BSP_COLINEAR;

vec_to_point.x = fixed32_sub(point.x, partition->start.x);
vec_to_point.y = fixed32_sub(point.y, partition->start.y);
line_vec.x = fixed32_sub(partition->end.x, partition->start.x);
line_vec.y = fixed32_sub(partition->end.y, partition->start.y);
cross_product = fixed32_sub(fixed32_mul(vec_to_point.x, line_vec.y),
fixed32_mul(vec_to_point.y, line_vec.x));
epsilon = int_to_fixed32(1) >> 8;
if (cross_product > epsilon)
return (BSP_FRONT);
if (cross_product < -epsilon)
return (BSP_BACK);
return (BSP_COLINEAR);
}
// Vetores
t_fixed_vec32 vec_to_point = {
fixed32_sub(point.x, partition->start.x),
fixed32_sub(point.y, partition->start.y)
};

t_fixed_vec32 line_vec = {
fixed32_sub(partition->end.x, partition->start.x),
fixed32_sub(partition->end.y, partition->start.y)
};

// Cálculo do produto cruz (determinante)
// Corrigido: Invertemos a ordem para corrigir a orientação
t_fixed32 cross_product = fixed32_sub(
fixed32_mul(line_vec.x, vec_to_point.y),
fixed32_mul(line_vec.y, vec_to_point.x)
);

// Epsilon adaptativo baseado no comprimento da linha
t_fixed32 line_length_sq = fixed32_add(
fixed32_mul(line_vec.x, line_vec.x),
fixed32_mul(line_vec.y, line_vec.y)
);
t_fixed32 epsilon = fixed32_mul(
fixed32_sqrt(line_length_sq),
int_to_fixed32(1) >> 6
);

// Classificação com epsilon adaptativo
if (cross_product > epsilon)
return BSP_FRONT;
if (cross_product < -epsilon)
return BSP_BACK;

// Verificação para pontos além dos endpoints
t_fixed32 dot_product = fixed32_add(
fixed32_mul(vec_to_point.x, line_vec.x),
fixed32_mul(vec_to_point.y, line_vec.y)
);

if (dot_product < 0 || dot_product > line_length_sq)
return BSP_COLINEAR;

return BSP_COLINEAR;
}
/*
** Classifies a line segment relative to a partition line
** Returns:
Expand Down
Loading

0 comments on commit b88df3b

Please # to comment.