2 #include "cpicomodel.h"
8 #define RADIANT_ASSERT(condition, message) if(!(condition)) { Sys_Printf("ASSERTION FAILURE: " message "\n"); } else
10 template<class key_type, class value_type>
14 inline cache_element() : m_count(0), m_value(NULL) {}
15 inline ~cache_element()
17 RADIANT_ASSERT(m_count == 0 , "destroyed a reference before it was released\n");
21 inline value_type* capture(const key_type& key)
29 RADIANT_ASSERT(!empty(), "failed to release reference - not found in cache\n");
37 inline void refresh(const key_type& key)
39 m_value->refresh(key);
42 inline void construct(const key_type& key)
44 m_value = new value_type(key);
57 typedef CPicoModel value_type;
60 typedef PicoModelKey key_type;
61 typedef cache_element<key_type, value_type> elem_type;
62 typedef map<key_type, elem_type> cache_type;
64 value_type* capture(const key_type& key)
66 return m_cache[key].capture(key);
68 void release(const key_type& key)
70 m_cache[key].release();
77 ModelCache g_model_cache;
81 typedef struct remap_s {
82 char m_remapbuff[64+1024];
87 class RemapWrapper : public IRender, public ISelect
89 unsigned int m_refcount;
91 RemapWrapper(entity_interfaces_t* model, const char* name)
96 m_model = g_model_cache.capture(ModelCache::key_type(m_name.GetBuffer(), m_frame));
98 model->pRender = this;
99 model->pRender->IncRef();
101 model->pSelect = this;
102 model->pSelect->IncRef();
106 virtual ~RemapWrapper()
108 g_model_cache.release(ModelCache::key_type(m_name.GetBuffer(), m_frame));
110 for(shaders_t::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i) {
114 for(remaps_t::iterator j = m_remaps.begin(); j != m_remaps.end(); ++j)
116 remap_t *pRemap = (*j);
121 virtual void IncRef()
125 virtual void DecRef()
127 if(--m_refcount == 0)
130 virtual void Draw(int state, int rflags) const
132 m_model->Draw(state, m_shaders, rflags);
134 virtual const aabb_t *GetAABB() const
136 return m_model->GetAABB();
138 virtual bool TestRay(const ray_t *ray, vec_t *dist) const
140 return m_model->TestRay(ray, dist);
143 void add_remap(const char *remap)
150 while( *ch && *ch != ';' )
155 Sys_FPrintf( SYS_WRN, "WARNING: Shader _remap key found in a model entity without a ; character\n" );
157 pRemap = new remap_t;
159 strncpy( pRemap->m_remapbuff, remap, sizeof(pRemap->m_remapbuff) );
161 pRemap->m_remapbuff[ch - remap] = '\0';
163 pRemap->original = pRemap->m_remapbuff;
164 pRemap->remap = pRemap->m_remapbuff + ( ch - remap ) + 1;
166 m_remaps.push_back( pRemap );
170 void parse_namestr(const char *name)
174 bool hasName, hasFrame;
176 hasName = hasFrame = false;
178 for( s = ptr = name; *ptr; ptr++ ) {
179 if( !hasName && *ptr == ':' ) {
182 strncpy( buf, s, ptr - s );
186 } else if( *ptr == '?' ) {
189 strncpy( buf, s, ptr - s );
193 } else if( *ptr == '&' ) {
195 strncpy( buf, s, ptr - s );
204 strncpy( buf, s, ptr - s );
209 strncpy( buf, s, ptr - s );
215 void construct_shaders()
217 IShader* global_shader = shader_for_remap("*");
219 unsigned int numSurfaces = m_model->GetNumSurfaces();
220 m_shaders.reserve(numSurfaces);
221 // now go through our surface and find our shaders, remap if needed
222 for(unsigned int j = 0; j < numSurfaces; j++ )
224 const char* surfShaderName = m_model->GetShaderNameForSurface(j);
225 IShader* shader = shader_for_remap(surfShaderName);
226 // m_shaders.push_back((shader) ? shader : (global_shader) ? global_shader : QERApp_Shader_ForName(surfShaderName));
227 // Determine which shader it is going to be
229 if( global_shader ) {
230 shader = global_shader;
232 shader = QERApp_Shader_ForName(surfShaderName);
238 m_shaders.push_back( shader );
242 inline IShader* shader_for_remap(const char* remap)
245 remaps_t::iterator i;
246 for(i = m_remaps.begin(); i != m_remaps.end(); ++i)
249 if( stricmp( remap, pRemap->original ) == 0 )
252 return (i != m_remaps.end()) ? QERApp_Shader_ForName(pRemap->remap) : NULL;
259 typedef vector<remap_t *> remaps_t;
261 typedef vector<IShader*> shaders_t;
265 class ModelWrapper : public IRender, public ISelect
267 unsigned int m_refcount;
269 ModelWrapper(entity_interfaces_t* model, const char* name)
270 : m_refcount(1), m_name(name)
272 m_model = g_model_cache.capture(ModelCache::key_type(m_name.GetBuffer(), 0));
274 model->pRender = this;
275 model->pRender->IncRef();
277 model->pSelect = this;
278 model->pSelect->IncRef();
280 virtual ~ModelWrapper()
282 g_model_cache.release(ModelCache::key_type(m_name.GetBuffer(), 0));
285 virtual void IncRef()
289 virtual void DecRef()
291 if(--m_refcount == 0)
294 virtual void Draw(int state, int rflags) const
296 m_model->Draw(state, rflags);
298 virtual const aabb_t *GetAABB() const
300 return m_model->GetAABB();
302 virtual bool TestRay(const ray_t *ray, vec_t *dist) const
304 return m_model->TestRay(ray, dist);
311 void LoadModel(entity_interfaces_t* model, const char* name)
313 if(strchr(name, ':') != NULL || strchr(name, '?') != NULL || strchr(name, '&') != NULL)
315 RemapWrapper* wrapper = new RemapWrapper(model, name);
320 ModelWrapper* wrapper = new ModelWrapper(model, name);