diff options
Diffstat (limited to 'ent.c')
| -rw-r--r-- | ent.c | 104 |
1 files changed, 95 insertions, 9 deletions
@@ -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 = ©.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); |
