summaryrefslogtreecommitdiff
path: root/gfx/src/asset/asset_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/src/asset/asset_cache.c')
-rw-r--r--gfx/src/asset/asset_cache.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/gfx/src/asset/asset_cache.c b/gfx/src/asset/asset_cache.c
index 0320954..e17de9d 100644
--- a/gfx/src/asset/asset_cache.c
+++ b/gfx/src/asset/asset_cache.c
@@ -1,9 +1,15 @@
1#include "asset_cache.h" 1#include "asset_cache.h"
2 2
3#include "scene.h" 3#include "scene.h"
4#include "scene/animation_impl.h"
5#include "scene/model_impl.h"
6#include "scene/node_impl.h"
7#include "scene/scene_memory.h"
4#include "texture.h" 8#include "texture.h"
9
5#include <gfx/asset.h> 10#include <gfx/asset.h>
6#include <gfx/gfx.h> 11#include <gfx/gfx.h>
12#include <gfx/scene/node.h>
7#include <gfx_assert.h> 13#include <gfx_assert.h>
8 14
9#include <cstring.h> 15#include <cstring.h>
@@ -97,6 +103,31 @@ static void log_model_loaded(const LoadModelCmd* cmd) {
97 } 103 }
98} 104}
99 105
106static Model* clone_model(const Model* model) {
107 assert(model);
108
109 // Only the Anima needs to be (shallow) cloned since everything else in the
110 // model is static. Also note that only the Anima's joints and animation state
111 // need to be cloned; all other members can be shared. So a shallow clone of
112 // the anima is sufficient.
113 const SceneNode* root = mem_get_node(model->root);
114 if (gfx_get_node_type(root) == AnimaNode) {
115 const Anima* anima = gfx_get_node_anima(root);
116 Anima* anima_copy = mem_alloc_anima();
117 *anima_copy = *anima; // Shallow copy.
118
119 SceneNode* root_copy = gfx_clone_scene_shallow(root);
120 root_copy->anima = mem_get_anima_index(anima_copy);
121 anima_copy->parent = mem_get_node_index(root_copy);
122
123 Model* copy = mem_alloc_model();
124 copy->root = mem_get_node_index(root_copy);
125 return copy;
126 } else {
127 return (Model*)model; // Static model, can't be mutated.
128 }
129}
130
100void gfx_init_asset_cache(AssetCache* cache) { 131void gfx_init_asset_cache(AssetCache* cache) {
101 assert(cache); 132 assert(cache);
102 mempool_make(&cache->assets); 133 mempool_make(&cache->assets);
@@ -122,7 +153,7 @@ Model* gfx_load_model(Gfx* gfx, const LoadModelCmd* cmd) {
122 Asset* asset = lookup_cache(cache, hash); 153 Asset* asset = lookup_cache(cache, hash);
123 if (asset) { 154 if (asset) {
124 log_model_cache_hit(cmd, hash); 155 log_model_cache_hit(cmd, hash);
125 return asset->model; 156 return clone_model(asset->model);
126 } 157 }
127 158
128 // Asset not found in the cache. 159 // Asset not found in the cache.
@@ -136,7 +167,7 @@ Model* gfx_load_model(Gfx* gfx, const LoadModelCmd* cmd) {
136 }; 167 };
137 log_model_loaded(cmd); 168 log_model_loaded(cmd);
138 } 169 }
139 return model; 170 return clone_model(model);
140} 171}
141 172
142const Texture* gfx_load_texture(Gfx* gfx, const LoadTextureCmd* cmd) { 173const Texture* gfx_load_texture(Gfx* gfx, const LoadTextureCmd* cmd) {