summaryrefslogtreecommitdiff
path: root/src/transform_hierarchy.c
blob: a5f4d97784c9dac769c145ec32004cea8ba1e7e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

/**
 * @file transform_hierarchy.h
 */
#pragma once
#include "transform_hierarchy.h"
#include <stdlib.h>
#include <string.h>

#include "core.h"
#include "log.h"
#include "maths.h"
#include "maths_types.h"
#include "render_types.h"

// struct transform_hierarchy {
//   transform_node root;
// };

// transform_hierarchy* transform_hierarchy_create() {
//   transform_hierarchy* tfh = malloc(sizeof(struct transform_hierarchy));

//   tfh->root = (transform_node){ .model = { ABSENT_MODEL_HANDLE },
//                                 .tf = TRANSFORM_DEFAULT,
//                                 .local_matrix_tf = mat4_ident(),
//                                 .world_matrix_tf = mat4_ident(),
//                                 .parent = NULL,
//                                 .children = { 0 },
//                                 .n_children = 0,
//                                 .tfh = tfh };
//   return tfh;
// }

// bool free_node(transform_node* node, void* _ctx_data) {
//   if (!node) return true;  // leaf node
//   if (node == &node->tfh->root) {
//     WARN("You can't free the root node!");
//     return false;
//   }

//   printf("Freed node\n");
//   free(node);
//   return true;
// }

// void transform_hierarchy_free(transform_hierarchy* tfh) {
//   transform_hierarchy_dfs(&tfh->root, free_node, false, NULL);
//   free(tfh);
// }

// transform_node* transform_hierarchy_root_node(transform_hierarchy* tfh) { return &tfh->root; }

// transform_node* transform_hierarchy_add_node(transform_node* parent, ModelHandle model,
//                                              Transform tf) {
//   if (!parent) {
//     WARN("You tried to add a node to a bad parent (NULL?)");
//     return NULL;
//   }
//   transform_node* node = malloc(sizeof(transform_node));
//   node->model = model;
//   node->tf = tf;
//   node->local_matrix_tf = mat4_ident();
//   node->world_matrix_tf = mat4_ident();
//   node->parent = parent;
//   memset(node->children, 0, sizeof(node->children));
//   node->n_children = 0;
//   node->tfh = parent->tfh;

//   // push into parent's children array
//   u32 next_index = parent->n_children;
//   if (next_index == MAX_TF_NODE_CHILDREN) {
//     ERROR("This transform hierarchy node already has MAX children. Dropping.");
//     free(node);
//   } else {
//     parent->children[next_index] = node;
//     parent->n_children++;
//   }

//   return node;
// }

// void transform_hierarchy_delete_node(transform_node* node) {
//   // delete all children
//   for (u32 i = 0; i < node->n_children; i++) {
//     transform_node* child = node->children[i];
//     transform_hierarchy_dfs(child, free_node, false, NULL);
//   }

//   if (node->parent) {
//     for (u32 i = 0; i < node->parent->n_children; i++) {
//       transform_node* child = node->parent->children[i];
//       if (child == node) {
//         node->parent->children[i] = NULL;  // HACK: this will leave behind empty slots in the
//                                            // children array of the parent. oh well.
//       }
//     }
//   }

//   free(node);
// }

// void transform_hierarchy_dfs(transform_node* start_node,
//                              bool (*visit_node)(transform_node* node, void* ctx_data),
//                              bool is_pre_order, void* ctx_data) {
//   if (!start_node) return;

//   bool continue_traversal = true;
//   if (is_pre_order) {
//     continue_traversal = visit_node(start_node, ctx_data);
//   }

//   if (continue_traversal) {
//     for (u32 i = 0; i < start_node->n_children; i++) {
//       transform_node* child = start_node->children[i];
//       transform_hierarchy_dfs(child, visit_node, is_pre_order, ctx_data);
//     }
//   }

//   if (!is_pre_order) {
//     // post-order
//     visit_node(start_node, ctx_data);
//   }
// }

// // Update matrix for the current node
// bool update_matrix(transform_node* node, void* _ctx_data) {
//   if (!node) return true;  // leaf node

//   if (node->parent && node->parent->tf.is_dirty) {
//     node->tf.is_dirty = true;
//   }

//   if (node->tf.is_dirty) {
//     // invalidates children
//     Mat4 updated_local_transform = transform_to_mat(&node->tf);
//     node->local_matrix_tf = updated_local_transform;
//     if (node->parent) {
//       Mat4 updated_world_transform =
//           mat4_mult(node->parent->world_matrix_tf, updated_local_transform);
//       node->world_matrix_tf = updated_world_transform;
//     }
//   }

//   return true;
// }

// void transform_hierarchy_propagate_transforms(transform_hierarchy* tfh) {
//   // kickoff traversal
//   transform_hierarchy_dfs(&tfh->root, update_matrix, false, NULL);
// }

// struct print_ctx {
//   Core* core;
//   u32 indentation_lvl;
// };

// bool print_node(transform_node* node, void* ctx_data) {
//   struct print_ctx* ctx = (struct print_ctx*)ctx_data;

//   if (!node) return true;
//   if (!node->parent) {
//     printf("Root Node\n");
//     ctx->indentation_lvl++;
//     return true;
//   }

//   // Grab the model
//   // FIXME
//   // model m = ctx->core->models->data[node->model.raw];
//   for (int i = 0; i < ctx->indentation_lvl; i++) {
//     printf("  ");
//   }
//   // printf("Node %s\n", m.name.buf);
//   ctx->indentation_lvl++;

//   return true;
// }

// void transform_hierarchy_debug_print(transform_node* start_node, Core* core) {
//   struct print_ctx* ctx = malloc(sizeof(struct print_ctx));
//   ctx->core = core;
//   ctx->indentation_lvl = 0;
//   transform_hierarchy_dfs(start_node, print_node, true, (void*)ctx);
//   free(ctx);
// }