model.cpp 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. Copyright (C) 2001-2006, William Joseph.
  3. All Rights Reserved.
  4. This file is part of GtkRadiant.
  5. GtkRadiant is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. GtkRadiant is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GtkRadiant; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #include "model.h"
  18. #include "picomodel.h"
  19. #include "iarchive.h"
  20. #include "idatastream.h"
  21. #include "imodel.h"
  22. #include "modelskin.h"
  23. #include "cullable.h"
  24. #include "renderable.h"
  25. #include "selectable.h"
  26. #include "math/frustum.h"
  27. #include "string/string.h"
  28. #include "generic/static.h"
  29. #include "shaderlib.h"
  30. #include "scenelib.h"
  31. #include "instancelib.h"
  32. #include "transformlib.h"
  33. #include "traverselib.h"
  34. #include "render.h"
  35. class VectorLightList : public LightList
  36. {
  37. typedef std::vector<const RendererLight*> Lights;
  38. Lights m_lights;
  39. public:
  40. void addLight(const RendererLight& light)
  41. {
  42. m_lights.push_back(&light);
  43. }
  44. void clear()
  45. {
  46. m_lights.clear();
  47. }
  48. void evaluateLights() const
  49. {
  50. }
  51. void lightsChanged() const
  52. {
  53. }
  54. void forEachLight(const RendererLightCallback& callback) const
  55. {
  56. for(Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i)
  57. {
  58. callback(*(*i));
  59. }
  60. }
  61. };
  62. class PicoSurface :
  63. public OpenGLRenderable
  64. {
  65. AABB m_aabb_local;
  66. CopiedString m_shader;
  67. Shader* m_state;
  68. Array<ArbitraryMeshVertex> m_vertices;
  69. Array<RenderIndex> m_indices;
  70. public:
  71. PicoSurface()
  72. {
  73. constructNull();
  74. CaptureShader();
  75. }
  76. PicoSurface(picoSurface_t* surface)
  77. {
  78. CopyPicoSurface(surface);
  79. CaptureShader();
  80. }
  81. ~PicoSurface()
  82. {
  83. ReleaseShader();
  84. }
  85. void render(RenderStateFlags state) const
  86. {
  87. if((state & RENDER_BUMP) != 0)
  88. {
  89. if(GlobalShaderCache().useShaderLanguage())
  90. {
  91. glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal);
  92. glVertexAttribPointerARB(c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord);
  93. glVertexAttribPointerARB(c_attr_Tangent, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->tangent);
  94. glVertexAttribPointerARB(c_attr_Binormal, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->bitangent);
  95. }
  96. else
  97. {
  98. glVertexAttribPointerARB(11, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal);
  99. glVertexAttribPointerARB(8, 2, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord);
  100. glVertexAttribPointerARB(9, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->tangent);
  101. glVertexAttribPointerARB(10, 3, GL_FLOAT, 0, sizeof(ArbitraryMeshVertex), &m_vertices.data()->bitangent);
  102. }
  103. }
  104. else
  105. {
  106. glNormalPointer(GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->normal);
  107. glTexCoordPointer(2, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->texcoord);
  108. }
  109. glVertexPointer(3, GL_FLOAT, sizeof(ArbitraryMeshVertex), &m_vertices.data()->vertex);
  110. glDrawElements(GL_TRIANGLES, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data());
  111. #if defined(_DEBUG)
  112. glBegin(GL_LINES);
  113. for(Array<ArbitraryMeshVertex>::const_iterator i = m_vertices.begin(); i != m_vertices.end(); ++i)
  114. {
  115. Vector3 normal = vector3_added(vertex3f_to_vector3((*i).vertex), vector3_scaled(normal3f_to_vector3((*i).normal), 8));
  116. glVertex3fv(vertex3f_to_array((*i).vertex));
  117. glVertex3fv(vector3_to_array(normal));
  118. }
  119. glEnd();
  120. #endif
  121. }
  122. VolumeIntersectionValue intersectVolume(const VolumeTest& test, const Matrix4& localToWorld) const
  123. {
  124. return test.TestAABB(m_aabb_local, localToWorld);
  125. }
  126. const AABB& localAABB() const
  127. {
  128. return m_aabb_local;
  129. }
  130. void render(Renderer& renderer, const Matrix4& localToWorld, Shader* state) const
  131. {
  132. renderer.SetState(state, Renderer::eFullMaterials);
  133. renderer.addRenderable(*this, localToWorld);
  134. }
  135. void render(Renderer& renderer, const Matrix4& localToWorld) const
  136. {
  137. render(renderer, localToWorld, m_state);
  138. }
  139. void testSelect(Selector& selector, SelectionTest& test, const Matrix4& localToWorld)
  140. {
  141. test.BeginMesh(localToWorld);
  142. SelectionIntersection best;
  143. testSelect(test, best);
  144. if(best.valid())
  145. {
  146. selector.addIntersection(best);
  147. }
  148. }
  149. const char* getShader() const
  150. {
  151. return m_shader.c_str();
  152. }
  153. Shader* getState() const
  154. {
  155. return m_state;
  156. }
  157. private:
  158. void CaptureShader()
  159. {
  160. m_state = GlobalShaderCache().capture(m_shader.c_str());
  161. }
  162. void ReleaseShader()
  163. {
  164. GlobalShaderCache().release(m_shader.c_str());
  165. }
  166. void UpdateAABB()
  167. {
  168. m_aabb_local = AABB();
  169. for(std::size_t i = 0; i < m_vertices.size(); ++i )
  170. aabb_extend_by_point_safe(m_aabb_local, reinterpret_cast<const Vector3&>(m_vertices[i].vertex));
  171. for(Array<RenderIndex>::iterator i = m_indices.begin(); i != m_indices.end(); i += 3)
  172. {
  173. ArbitraryMeshVertex& a = m_vertices[*(i + 0)];
  174. ArbitraryMeshVertex& b = m_vertices[*(i + 1)];
  175. ArbitraryMeshVertex& c = m_vertices[*(i + 2)];
  176. ArbitraryMeshTriangle_sumTangents(a, b, c);
  177. }
  178. for(Array<ArbitraryMeshVertex>::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i)
  179. {
  180. vector3_normalise(reinterpret_cast<Vector3&>((*i).tangent));
  181. vector3_normalise(reinterpret_cast<Vector3&>((*i).bitangent));
  182. }
  183. }
  184. void testSelect(SelectionTest& test, SelectionIntersection& best)
  185. {
  186. test.TestTriangles(
  187. VertexPointer(VertexPointer::pointer(&m_vertices.data()->vertex), sizeof(ArbitraryMeshVertex)),
  188. IndexPointer(m_indices.data(), IndexPointer::index_type(m_indices.size())),
  189. best
  190. );
  191. }
  192. void CopyPicoSurface(picoSurface_t* surface)
  193. {
  194. picoShader_t* shader = PicoGetSurfaceShader( surface );
  195. if( shader == 0 )
  196. m_shader = "";
  197. else
  198. m_shader = PicoGetShaderName( shader );
  199. m_vertices.resize( PicoGetSurfaceNumVertexes( surface ) );
  200. m_indices.resize( PicoGetSurfaceNumIndexes( surface ) );
  201. for(std::size_t i = 0; i < m_vertices.size(); ++i )
  202. {
  203. picoVec_t* xyz = PicoGetSurfaceXYZ( surface, int(i) );
  204. m_vertices[i].vertex = vertex3f_from_array(xyz);
  205. picoVec_t* normal = PicoGetSurfaceNormal( surface, int(i) );
  206. m_vertices[i].normal = normal3f_from_array(normal);
  207. picoVec_t* st = PicoGetSurfaceST( surface, 0, int(i) );
  208. m_vertices[i].texcoord = TexCoord2f(st[0], st[1]);
  209. #if 0
  210. picoVec_t* color = PicoGetSurfaceColor( surface, 0, int(i) );
  211. m_vertices[i].colour = Colour4b(color[0], color[1], color[2], color[3]);
  212. #endif
  213. }
  214. picoIndex_t* indexes = PicoGetSurfaceIndexes( surface, 0 );
  215. for(std::size_t j = 0; j < m_indices.size(); ++j )
  216. m_indices[ j ] = indexes[ j ];
  217. UpdateAABB();
  218. }
  219. void constructQuad(std::size_t index, const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d, const Vector3& normal)
  220. {
  221. m_vertices[index * 4 + 0] = ArbitraryMeshVertex(
  222. vertex3f_for_vector3(a),
  223. normal3f_for_vector3(normal),
  224. texcoord2f_from_array(aabb_texcoord_topleft)
  225. );
  226. m_vertices[index * 4 + 1] = ArbitraryMeshVertex(
  227. vertex3f_for_vector3(b),
  228. normal3f_for_vector3(normal),
  229. texcoord2f_from_array(aabb_texcoord_topright)
  230. );
  231. m_vertices[index * 4 + 2] = ArbitraryMeshVertex(
  232. vertex3f_for_vector3(c),
  233. normal3f_for_vector3(normal),
  234. texcoord2f_from_array(aabb_texcoord_botright)
  235. );
  236. m_vertices[index * 4 + 3] = ArbitraryMeshVertex(
  237. vertex3f_for_vector3(d),
  238. normal3f_for_vector3(normal),
  239. texcoord2f_from_array(aabb_texcoord_botleft)
  240. );
  241. }
  242. void constructNull()
  243. {
  244. AABB aabb(Vector3(0, 0, 0), Vector3(8, 8, 8));
  245. Vector3 points[8];
  246. aabb_corners(aabb, points);
  247. m_vertices.resize(24);
  248. constructQuad(0, points[2], points[1], points[5], points[6], aabb_normals[0]);
  249. constructQuad(1, points[1], points[0], points[4], points[5], aabb_normals[1]);
  250. constructQuad(2, points[0], points[1], points[2], points[3], aabb_normals[2]);
  251. constructQuad(3, points[0], points[3], points[7], points[4], aabb_normals[3]);
  252. constructQuad(4, points[3], points[2], points[6], points[7], aabb_normals[4]);
  253. constructQuad(5, points[7], points[6], points[5], points[4], aabb_normals[5]);
  254. m_indices.resize(36);
  255. RenderIndex indices[36] = {
  256. 0, 1, 2, 0, 2, 3,
  257. 4, 5, 6, 4, 6, 7,
  258. 8, 9, 10, 8, 10, 11,
  259. 12, 13, 14, 12, 14, 15,
  260. 16, 17, 18, 16, 18, 19,
  261. 20, 21, 22, 10, 22, 23,
  262. };
  263. Array<RenderIndex>::iterator j = m_indices.begin();
  264. for(RenderIndex* i = indices; i != indices+(sizeof(indices)/sizeof(RenderIndex)); ++i)
  265. {
  266. *j++ = *i;
  267. }
  268. m_shader = "";
  269. UpdateAABB();
  270. }
  271. };
  272. typedef std::pair<CopiedString, int> PicoModelKey;
  273. class PicoModel :
  274. public Cullable,
  275. public Bounded
  276. {
  277. typedef std::vector<PicoSurface*> surfaces_t;
  278. surfaces_t m_surfaces;
  279. AABB m_aabb_local;
  280. public:
  281. Callback m_lightsChanged;
  282. PicoModel()
  283. {
  284. constructNull();
  285. }
  286. PicoModel(picoModel_t* model)
  287. {
  288. CopyPicoModel(model);
  289. }
  290. ~PicoModel()
  291. {
  292. for(surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i)
  293. delete *i;
  294. }
  295. typedef surfaces_t::const_iterator const_iterator;
  296. const_iterator begin() const
  297. {
  298. return m_surfaces.begin();
  299. }
  300. const_iterator end() const
  301. {
  302. return m_surfaces.end();
  303. }
  304. std::size_t size() const
  305. {
  306. return m_surfaces.size();
  307. }
  308. VolumeIntersectionValue intersectVolume(const VolumeTest& test, const Matrix4& localToWorld) const
  309. {
  310. return test.TestAABB(m_aabb_local, localToWorld);
  311. }
  312. virtual const AABB& localAABB() const
  313. {
  314. return m_aabb_local;
  315. }
  316. void render(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, std::vector<Shader*> states) const
  317. {
  318. for(surfaces_t::const_iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i)
  319. {
  320. if((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside)
  321. {
  322. (*i)->render(renderer, localToWorld, states[i - m_surfaces.begin()]);
  323. }
  324. }
  325. }
  326. void testSelect(Selector& selector, SelectionTest& test, const Matrix4& localToWorld)
  327. {
  328. for(surfaces_t::iterator i = m_surfaces.begin(); i != m_surfaces.end(); ++i)
  329. {
  330. if((*i)->intersectVolume(test.getVolume(), localToWorld) != c_volumeOutside)
  331. {
  332. (*i)->testSelect(selector, test, localToWorld);
  333. }
  334. }
  335. }
  336. private:
  337. void CopyPicoModel(picoModel_t* model)
  338. {
  339. m_aabb_local = AABB();
  340. /* each surface on the model will become a new map drawsurface */
  341. int numSurfaces = PicoGetModelNumSurfaces( model );
  342. //% SYs_FPrintf( SYS_VRB, "Model %s has %d surfaces\n", name, numSurfaces );
  343. for(int s = 0; s < numSurfaces; ++s)
  344. {
  345. /* get surface */
  346. picoSurface_t* surface = PicoGetModelSurface( model, s );
  347. if( surface == 0 )
  348. continue;
  349. /* only handle triangle surfaces initially (fixme: support patches) */
  350. if( PicoGetSurfaceType( surface ) != PICO_TRIANGLES )
  351. continue;
  352. /* fix the surface's normals */
  353. PicoFixSurfaceNormals( surface );
  354. PicoSurface* picosurface = new PicoSurface(surface);
  355. aabb_extend_by_aabb_safe(m_aabb_local, picosurface->localAABB());
  356. m_surfaces.push_back(picosurface);
  357. }
  358. }
  359. void constructNull()
  360. {
  361. PicoSurface* picosurface = new PicoSurface();
  362. m_aabb_local = picosurface->localAABB();
  363. m_surfaces.push_back(picosurface);
  364. }
  365. };
  366. inline void Surface_addLight(PicoSurface& surface, VectorLightList& lights, const Matrix4& localToWorld, const RendererLight& light)
  367. {
  368. if(light.testAABB(aabb_for_oriented_aabb(surface.localAABB(), localToWorld)))
  369. {
  370. lights.addLight(light);
  371. }
  372. }
  373. class PicoModelInstance :
  374. public scene::Instance,
  375. public Renderable,
  376. public SelectionTestable,
  377. public LightCullable,
  378. public SkinnedModel
  379. {
  380. class TypeCasts
  381. {
  382. InstanceTypeCastTable m_casts;
  383. public:
  384. TypeCasts()
  385. {
  386. InstanceContainedCast<PicoModelInstance, Bounded>::install(m_casts);
  387. InstanceContainedCast<PicoModelInstance, Cullable>::install(m_casts);
  388. InstanceStaticCast<PicoModelInstance, Renderable>::install(m_casts);
  389. InstanceStaticCast<PicoModelInstance, SelectionTestable>::install(m_casts);
  390. InstanceStaticCast<PicoModelInstance, SkinnedModel>::install(m_casts);
  391. }
  392. InstanceTypeCastTable& get()
  393. {
  394. return m_casts;
  395. }
  396. };
  397. PicoModel& m_picomodel;
  398. const LightList* m_lightList;
  399. typedef Array<VectorLightList> SurfaceLightLists;
  400. SurfaceLightLists m_surfaceLightLists;
  401. class Remap
  402. {
  403. public:
  404. CopiedString first;
  405. Shader* second;
  406. Remap() : second(0)
  407. {
  408. }
  409. };
  410. typedef Array<Remap> SurfaceRemaps;
  411. SurfaceRemaps m_skins;
  412. PicoModelInstance(const PicoModelInstance&);
  413. PicoModelInstance operator=(const PicoModelInstance&);
  414. public:
  415. typedef LazyStatic<TypeCasts> StaticTypeCasts;
  416. void* m_test;
  417. Bounded& get(NullType<Bounded>)
  418. {
  419. return m_picomodel;
  420. }
  421. Cullable& get(NullType<Cullable>)
  422. {
  423. return m_picomodel;
  424. }
  425. void lightsChanged()
  426. {
  427. m_lightList->lightsChanged();
  428. }
  429. typedef MemberCaller<PicoModelInstance, &PicoModelInstance::lightsChanged> LightsChangedCaller;
  430. void constructRemaps()
  431. {
  432. ASSERT_MESSAGE(m_skins.size() == m_picomodel.size(), "ERROR");
  433. ModelSkin* skin = NodeTypeCast<ModelSkin>::cast(path().parent());
  434. if(skin != 0 && skin->realised())
  435. {
  436. SurfaceRemaps::iterator j = m_skins.begin();
  437. for(PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i, ++j)
  438. {
  439. const char* remap = skin->getRemap((*i)->getShader());
  440. if(!string_empty(remap))
  441. {
  442. (*j).first = remap;
  443. (*j).second = GlobalShaderCache().capture(remap);
  444. }
  445. else
  446. {
  447. (*j).second = 0;
  448. }
  449. }
  450. SceneChangeNotify();
  451. }
  452. }
  453. void destroyRemaps()
  454. {
  455. ASSERT_MESSAGE(m_skins.size() == m_picomodel.size(), "ERROR");
  456. for(SurfaceRemaps::iterator i = m_skins.begin(); i != m_skins.end(); ++i)
  457. {
  458. if((*i).second != 0)
  459. {
  460. GlobalShaderCache().release((*i).first.c_str());
  461. (*i).second = 0;
  462. }
  463. }
  464. }
  465. void skinChanged()
  466. {
  467. destroyRemaps();
  468. constructRemaps();
  469. }
  470. PicoModelInstance(const scene::Path& path, scene::Instance* parent, PicoModel& picomodel) :
  471. Instance(path, parent, this, StaticTypeCasts::instance().get()),
  472. m_picomodel(picomodel),
  473. m_surfaceLightLists(m_picomodel.size()),
  474. m_skins(m_picomodel.size())
  475. {
  476. m_lightList = &GlobalShaderCache().attach(*this);
  477. m_picomodel.m_lightsChanged = LightsChangedCaller(*this);
  478. Instance::setTransformChangedCallback(LightsChangedCaller(*this));
  479. constructRemaps();
  480. }
  481. ~PicoModelInstance()
  482. {
  483. destroyRemaps();
  484. Instance::setTransformChangedCallback(Callback());
  485. m_picomodel.m_lightsChanged = Callback();
  486. GlobalShaderCache().detach(*this);
  487. }
  488. void render(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  489. {
  490. SurfaceLightLists::const_iterator j = m_surfaceLightLists.begin();
  491. SurfaceRemaps::const_iterator k = m_skins.begin();
  492. for(PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i, ++j, ++k)
  493. {
  494. if((*i)->intersectVolume(volume, localToWorld) != c_volumeOutside)
  495. {
  496. renderer.setLights(*j);
  497. (*i)->render(renderer, localToWorld, (*k).second != 0 ? (*k).second : (*i)->getState());
  498. }
  499. }
  500. }
  501. void renderSolid(Renderer& renderer, const VolumeTest& volume) const
  502. {
  503. m_lightList->evaluateLights();
  504. render(renderer, volume, Instance::localToWorld());
  505. }
  506. void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
  507. {
  508. renderSolid(renderer, volume);
  509. }
  510. void testSelect(Selector& selector, SelectionTest& test)
  511. {
  512. m_picomodel.testSelect(selector, test, Instance::localToWorld());
  513. }
  514. bool testLight(const RendererLight& light) const
  515. {
  516. return light.testAABB(worldAABB());
  517. }
  518. void insertLight(const RendererLight& light)
  519. {
  520. const Matrix4& localToWorld = Instance::localToWorld();
  521. SurfaceLightLists::iterator j = m_surfaceLightLists.begin();
  522. for(PicoModel::const_iterator i = m_picomodel.begin(); i != m_picomodel.end(); ++i)
  523. {
  524. Surface_addLight(*(*i), *j++, localToWorld, light);
  525. }
  526. }
  527. void clearLights()
  528. {
  529. for(SurfaceLightLists::iterator i = m_surfaceLightLists.begin(); i != m_surfaceLightLists.end(); ++i)
  530. {
  531. (*i).clear();
  532. }
  533. }
  534. };
  535. class PicoModelNode : public scene::Node::Symbiot, public scene::Instantiable
  536. {
  537. class TypeCasts
  538. {
  539. NodeTypeCastTable m_casts;
  540. public:
  541. TypeCasts()
  542. {
  543. NodeStaticCast<PicoModelNode, scene::Instantiable>::install(m_casts);
  544. }
  545. NodeTypeCastTable& get()
  546. {
  547. return m_casts;
  548. }
  549. };
  550. scene::Node m_node;
  551. InstanceSet m_instances;
  552. PicoModel m_picomodel;
  553. public:
  554. typedef LazyStatic<TypeCasts> StaticTypeCasts;
  555. PicoModelNode() : m_node(this, this, StaticTypeCasts::instance().get())
  556. {
  557. }
  558. PicoModelNode(picoModel_t* model) : m_node(this, this, StaticTypeCasts::instance().get()), m_picomodel(model)
  559. {
  560. }
  561. void release()
  562. {
  563. delete this;
  564. }
  565. scene::Node& node()
  566. {
  567. return m_node;
  568. }
  569. scene::Instance* create(const scene::Path& path, scene::Instance* parent)
  570. {
  571. return new PicoModelInstance(path, parent, m_picomodel);
  572. }
  573. void forEachInstance(const scene::Instantiable::Visitor& visitor)
  574. {
  575. m_instances.forEachInstance(visitor);
  576. }
  577. void insert(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance)
  578. {
  579. m_instances.insert(observer, path, instance);
  580. }
  581. scene::Instance* erase(scene::Instantiable::Observer* observer, const scene::Path& path)
  582. {
  583. return m_instances.erase(observer, path);
  584. }
  585. };
  586. #if 0
  587. template<typename Key, typename Type>
  588. class create_new
  589. {
  590. public:
  591. static Type* construct(const Key& key)
  592. {
  593. return new Type(key);
  594. }
  595. static void destroy(Type* value)
  596. {
  597. delete value;
  598. }
  599. };
  600. template<typename Key, typename Type, typename creation_policy = create_new<Key, Type> >
  601. class cache_element : public creation_policy
  602. {
  603. public:
  604. inline cache_element() : m_count(0), m_value(0) {}
  605. inline ~cache_element()
  606. {
  607. ASSERT_MESSAGE(m_count == 0 , "destroyed a reference before it was released\n");
  608. if(m_count > 0)
  609. destroy();
  610. }
  611. inline Type* capture(const Key& key)
  612. {
  613. if(++m_count == 1)
  614. construct(key);
  615. return m_value;
  616. }
  617. inline void release()
  618. {
  619. ASSERT_MESSAGE(!empty(), "failed to release reference - not found in cache\n");
  620. if(--m_count == 0)
  621. destroy();
  622. }
  623. inline bool empty()
  624. {
  625. return m_count == 0;
  626. }
  627. inline void refresh(const Key& key)
  628. {
  629. m_value->refresh(key);
  630. }
  631. private:
  632. inline void construct(const Key& key)
  633. {
  634. m_value = creation_policy::construct(key);
  635. }
  636. inline void destroy()
  637. {
  638. creation_policy::destroy(m_value);
  639. }
  640. std::size_t m_count;
  641. Type* m_value;
  642. };
  643. class create_picomodel
  644. {
  645. typedef PicoModelKey key_type;
  646. typedef PicoModel value_type;
  647. public:
  648. static value_type* construct(const key_type& key)
  649. {
  650. picoModel_t* picomodel = PicoLoadModel(const_cast<char*>(key.first.c_str()), key.second);
  651. value_type* value = new value_type(picomodel);
  652. PicoFreeModel(picomodel);
  653. return value;
  654. }
  655. static void destroy(value_type* value)
  656. {
  657. delete value;
  658. }
  659. };
  660. #include <map>
  661. class ModelCache
  662. {
  663. typedef PicoModel value_type;
  664. public:
  665. typedef PicoModelKey key_type;
  666. typedef cache_element<key_type, value_type, create_picomodel> elem_type;
  667. typedef std::map<key_type, elem_type> cache_type;
  668. value_type* capture(const key_type& key)
  669. {
  670. return m_cache[key].capture(key);
  671. }
  672. void release(const key_type& key)
  673. {
  674. m_cache[key].release();
  675. }
  676. private:
  677. cache_type m_cache;
  678. };
  679. ModelCache g_model_cache;
  680. typedef struct remap_s {
  681. char m_remapbuff[64+1024];
  682. char *original;
  683. char *remap;
  684. } remap_t;
  685. class RemapWrapper :
  686. public Cullable,
  687. public Bounded
  688. {
  689. public:
  690. RemapWrapper(const char* name)
  691. {
  692. parse_namestr(name);
  693. m_model = g_model_cache.capture(ModelCache::key_type(m_name, m_frame));
  694. construct_shaders();
  695. }
  696. virtual ~RemapWrapper()
  697. {
  698. g_model_cache.release(ModelCache::key_type(m_name, m_frame));
  699. for(shaders_t::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i)
  700. {
  701. GlobalShaderCache().release((*i).c_str());
  702. }
  703. for(remaps_t::iterator j = m_remaps.begin(); j != m_remaps.end(); ++j)
  704. {
  705. delete (*j);
  706. }
  707. }
  708. VolumeIntersectionValue intersectVolume(const VolumeTest& test, const Matrix4& localToWorld) const
  709. {
  710. return m_model->intersectVolume(test, localToWorld);
  711. }
  712. virtual const AABB& localAABB() const
  713. {
  714. return m_model->localAABB();
  715. }
  716. void render(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  717. {
  718. m_model->render(renderer, volume, localToWorld, m_states);
  719. }
  720. void testSelect(Selector& selector, SelectionTest& test, const Matrix4& localToWorld)
  721. {
  722. m_model->testSelect(selector, test, localToWorld);
  723. }
  724. private:
  725. void add_remap(const char *remap)
  726. {
  727. const char *ch;
  728. remap_t *pRemap;
  729. ch = remap;
  730. while( *ch && *ch != ';' )
  731. ch++;
  732. if( *ch == '\0' ) {
  733. // bad remap
  734. globalErrorStream() << "WARNING: Shader _remap key found in a model entity without a ; character\n";
  735. } else {
  736. pRemap = new remap_t;
  737. strncpy( pRemap->m_remapbuff, remap, sizeof(pRemap->m_remapbuff) );
  738. pRemap->m_remapbuff[ch - remap] = '\0';
  739. pRemap->original = pRemap->m_remapbuff;
  740. pRemap->remap = pRemap->m_remapbuff + ( ch - remap ) + 1;
  741. m_remaps.push_back( pRemap );
  742. }
  743. }
  744. void parse_namestr(const char *name)
  745. {
  746. const char *ptr, *s;
  747. bool hasName, hasFrame;
  748. hasName = hasFrame = false;
  749. m_frame = 0;
  750. for( s = ptr = name; ; ++ptr )
  751. {
  752. if( !hasName && (*ptr == ':' || *ptr == '\0'))
  753. {
  754. // model name
  755. hasName = true;
  756. m_name = CopiedString(s, ptr);
  757. s = ptr + 1;
  758. }
  759. else if(*ptr == '?' || *ptr == '\0')
  760. {
  761. // model frame
  762. hasFrame = true;
  763. m_frame = atoi(CopiedString(s, ptr).c_str());
  764. s = ptr + 1;
  765. }
  766. else if(*ptr == '&' || *ptr == '\0')
  767. {
  768. // a remap
  769. add_remap(CopiedString(s, ptr).c_str());
  770. s = ptr + 1;
  771. }
  772. if(*ptr == '\0')
  773. break;
  774. }
  775. }
  776. void construct_shaders()
  777. {
  778. const char* global_shader = shader_for_remap("*");
  779. m_shaders.reserve(m_model->size());
  780. m_states.reserve(m_model->size());
  781. for(PicoModel::iterator i = m_model->begin(); i != m_model->end(); ++i)
  782. {
  783. const char* shader = shader_for_remap((*i)->getShader());
  784. m_shaders.push_back(
  785. (shader[0] != '\0')
  786. ? shader
  787. : (global_shader[0] != '\0')
  788. ? global_shader
  789. : (*i)->getShader());
  790. m_states.push_back(GlobalShaderCache().capture(m_shaders.back().c_str()));
  791. }
  792. }
  793. inline const char* shader_for_remap(const char* remap)
  794. {
  795. for(remaps_t::iterator i = m_remaps.begin(); i != m_remaps.end(); ++i)
  796. {
  797. if(shader_equal(remap, (*i)->original))
  798. {
  799. return (*i)->remap;
  800. }
  801. }
  802. return "";
  803. }
  804. CopiedString m_name;
  805. int m_frame;
  806. PicoModel* m_model;
  807. typedef std::vector<remap_t*> remaps_t;
  808. remaps_t m_remaps;
  809. typedef std::vector<CopiedString> shaders_t;
  810. shaders_t m_shaders;
  811. typedef std::vector<Shader*> states_t;
  812. states_t m_states;
  813. };
  814. class RemapWrapperInstance : public scene::Instance, public Renderable, public SelectionTestable
  815. {
  816. RemapWrapper& m_remapwrapper;
  817. public:
  818. RemapWrapperInstance(const scene::Path& path, scene::Instance* parent, RemapWrapper& remapwrapper) : Instance(path, parent), m_remapwrapper(remapwrapper)
  819. {
  820. scene::Instance::m_cullable = &m_remapwrapper;
  821. scene::Instance::m_render = this;
  822. scene::Instance::m_select = this;
  823. }
  824. void renderSolid(Renderer& renderer, const VolumeTest& volume) const
  825. {
  826. m_remapwrapper.render(renderer, volume, Instance::localToWorld());
  827. }
  828. void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
  829. {
  830. renderSolid(renderer, volume);
  831. }
  832. void testSelect(Selector& selector, SelectionTest& test)
  833. {
  834. m_remapwrapper.testSelect(selector, test, Instance::localToWorld());
  835. }
  836. };
  837. class RemapWrapperNode : public scene::Node::Symbiot, public scene::Instantiable
  838. {
  839. scene::Node m_node;
  840. typedef RemapWrapperInstance instance_type;
  841. InstanceSet m_instances;
  842. RemapWrapper m_remapwrapper;
  843. public:
  844. RemapWrapperNode(const char* name) : m_node(this), m_remapwrapper(name)
  845. {
  846. m_node.m_instance = this;
  847. }
  848. void release()
  849. {
  850. delete this;
  851. }
  852. scene::Node& node()
  853. {
  854. return m_node;
  855. }
  856. scene::Instance* create(const scene::Path& path, scene::Instance* parent)
  857. {
  858. return new instance_type(path, parent, m_remapwrapper);
  859. }
  860. void forEachInstance(const scene::Instantiable::Visitor& visitor)
  861. {
  862. m_instances.forEachInstance(visitor);
  863. }
  864. void insert(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance)
  865. {
  866. m_instances.insert(observer, path, instance);
  867. }
  868. scene::Instance* erase(scene::Instantiable::Observer* observer, const scene::Path& path)
  869. {
  870. return m_instances.erase(observer, path);
  871. }
  872. };
  873. scene::Node& LoadRemapModel(const char* name)
  874. {
  875. return (new RemapWrapperNode(name))->node();
  876. }
  877. #endif
  878. size_t picoInputStreamReam(void* inputStream, unsigned char* buffer, size_t length)
  879. {
  880. return reinterpret_cast<InputStream*>(inputStream)->read(buffer, length);
  881. }
  882. scene::Node& loadPicoModel(const picoModule_t* module, ArchiveFile& file)
  883. {
  884. picoModel_t* model = PicoModuleLoadModelStream(module, &file.getInputStream(), picoInputStreamReam, file.size(), 0);
  885. PicoModelNode* modelNode = new PicoModelNode(model);
  886. PicoFreeModel(model);
  887. return modelNode->node();
  888. }