techkaczynski.dev / code

summaryrefslogtreecommitdiff
path: root/ent.c
diff options
context:
space:
mode:
Diffstat (limited to 'ent.c')
-rw-r--r--ent.c104
1 files changed, 95 insertions, 9 deletions
diff --git a/ent.c b/ent.c
index 2b23f0f..055239e 100644
--- a/ent.c
+++ b/ent.c
@@ -250,22 +250,68 @@ entity_system_clear(void) {
static void
entity_draw_mdl(u64 id) {
Entity *ent = entity_get(id);
- if (!ent->mdl.mdl) {
- Asset *asset = asset_get(ent->mdl.key);
+ ModelCmp *model = &ent->mdl;
+
+ if (!model->mdl) {
+ Asset *asset = asset_get(model->key);
if (!asset) {
return;
}
- ent->mdl.mdl = &asset->mdl;
+ model->mdl = &asset->mdl;
}
- Model mdl = *ent->mdl.mdl;
+ Model mdl = *model->mdl;
mdl.transform = entity_world_matrix(id);
Color tint = ent->ed.selected && ed.mode == ED_MODE_SCENE ?
- (Color){ 100, 100, 100, 255 } :
- BLACK;
+ (Color){100, 100, 100, 255} : BLACK;
+
+ u32 count = MIN(model->mat_cnt, (u32)mdl.materialCount);
+
+ if (!count) {
+ DrawModel(mdl, (Vec3){0}, 1, tint);
+ return;
+ }
+
+ struct {
+ MaterialMap albedo;
+ Shader shader;
+ } saved[count];
+
+ for (u32 i = 0; i < count; ++i) {
+ Material *material = &mdl.materials[i];
+ MaterialMap *albedo;
+ albedo = &material->maps[MATERIAL_MAP_ALBEDO];
+
+ saved[i].albedo = *albedo;
+ saved[i].shader = material->shader;
+
+ MaterialOverride *override = &model->materials[i];
+
+ if (override->tex_key) {
+ Asset *asset = asset_get(override->tex_key);
+ if (asset) {
+ albedo->texture = asset->tex;
+ }
+ }
+
+ if (override->shader_key) {
+ FunShader *shader;
+ shader = shader_get(override->shader_key);
+
+ if (shader) {
+ material->shader = shader->sdr;
+ }
+ }
+ }
- DrawModel(mdl, (Vec3) {0}, 1, tint);
+ DrawModel(mdl, (Vec3){0}, 1, tint);
+
+ for (u32 i = 0; i < count; ++i) {
+ Material *material = &mdl.materials[i];
+ material->maps[MATERIAL_MAP_ALBEDO] = saved[i].albedo;
+ material->shader = saved[i].shader;
+ }
}
void
@@ -388,6 +434,46 @@ entity_delete(u64 id) {
en.delete_queue_cnt += 1;
}
+ModelCmp
+entity_model_copy(const ModelCmp *src) {
+ ModelCmp copy = *src;
+ copy.key = src->key ? strdup(src->key) : NULL;
+ copy.materials = NULL;
+
+ if (src->mat_cnt) {
+ copy.materials = calloc(src->mat_cnt,
+ sizeof(*copy.materials));
+ if (!copy.materials) {
+ perror("entity_model_copy: alloc failed.");
+ exit(1);
+ }
+
+ for (u32 i = 0; i < src->mat_cnt; ++i) {
+ const MaterialOverride *from = &src->materials[i];
+ MaterialOverride *to = &copy.materials[i];
+
+ to->tex_key = from->tex_key ?
+ strdup(from->tex_key) : NULL;
+ to->shader_key = from->shader_key ?
+ strdup(from->shader_key) : NULL;
+ }
+ }
+
+ return copy;
+}
+
+void
+entity_model_free(ModelCmp *model) {
+ for (u32 i = 0; i < model->mat_cnt; ++i) {
+ free(model->materials[i].tex_key);
+ free(model->materials[i].shader_key);
+ }
+
+ free(model->materials);
+ free(model->key);
+ *model = (ModelCmp){0};
+}
+
static void *
physics_copy_data(const void *src, size_t size) {
if (!size) {
@@ -396,7 +482,7 @@ physics_copy_data(const void *src, size_t size) {
void *copy = malloc(size);
if (!copy) {
- perror("physics_copy_data");
+ perror("physics_copy_data: alloc failed");
exit(1);
}
@@ -872,7 +958,7 @@ entity_clean(Entity *ent) {
free(ent->name);
/* model component data */
- free(ent->mdl.key);
+ entity_model_free(&ent->mdl);
/* physics component data */
entity_physics_free(&ent->phys);