group.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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. ///\file
  18. ///\brief Represents any entity which does not have a fixed size specified in its entity-definition (except misc_model).
  19. ///
  20. /// This entity behaves as a group, i.e. it contains brushes.
  21. #include "cullable.h"
  22. #include "renderable.h"
  23. #include "editable.h"
  24. #include "selectionlib.h"
  25. #include "instancelib.h"
  26. #include "transformlib.h"
  27. #include "traverselib.h"
  28. #include "entitylib.h"
  29. #include "render.h"
  30. #include "eclasslib.h"
  31. #include "targetable.h"
  32. #include "origin.h"
  33. #include "angles.h"
  34. #include "scale.h"
  35. #include "filters.h"
  36. #include "namedentity.h"
  37. #include "keyobservers.h"
  38. #include "namekeys.h"
  39. #include "entity.h"
  40. class Group
  41. {
  42. EntityKeyValues m_entity;
  43. KeyObserverMap m_keyObservers;
  44. MatrixTransform m_transform;
  45. TraversableNodeSet m_traverse;
  46. ClassnameFilter m_filter;
  47. NamedEntity m_named;
  48. NameKeys m_nameKeys;
  49. RenderableNamedEntity m_renderName;
  50. Callback m_transformChanged;
  51. void construct()
  52. {
  53. m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter));
  54. m_keyObservers.insert(Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named));
  55. }
  56. public:
  57. Group(EntityClass* eclass, scene::Node& node, const Callback& transformChanged) :
  58. m_entity(eclass),
  59. m_filter(m_entity, node),
  60. m_named(m_entity),
  61. m_nameKeys(m_entity),
  62. m_renderName(m_named, g_vector3_identity),
  63. m_transformChanged(transformChanged)
  64. {
  65. construct();
  66. }
  67. Group(const Group& other, scene::Node& node, const Callback& transformChanged) :
  68. m_entity(other.m_entity),
  69. m_filter(m_entity, node),
  70. m_named(m_entity),
  71. m_nameKeys(m_entity),
  72. m_renderName(m_named, g_vector3_identity),
  73. m_transformChanged(transformChanged)
  74. {
  75. construct();
  76. }
  77. InstanceCounter m_instanceCounter;
  78. void instanceAttach(const scene::Path& path)
  79. {
  80. if(++m_instanceCounter.m_count == 1)
  81. {
  82. m_filter.instanceAttach();
  83. m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end()));
  84. m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end()));
  85. m_entity.attach(m_keyObservers);
  86. }
  87. }
  88. void instanceDetach(const scene::Path& path)
  89. {
  90. if(--m_instanceCounter.m_count == 0)
  91. {
  92. m_entity.detach(m_keyObservers);
  93. m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end()));
  94. m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end()));
  95. m_filter.instanceDetach();
  96. }
  97. }
  98. EntityKeyValues& getEntity()
  99. {
  100. return m_entity;
  101. }
  102. const EntityKeyValues& getEntity() const
  103. {
  104. return m_entity;
  105. }
  106. scene::Traversable& getTraversable()
  107. {
  108. return m_traverse;
  109. }
  110. Namespaced& getNamespaced()
  111. {
  112. return m_nameKeys;
  113. }
  114. Nameable& getNameable()
  115. {
  116. return m_named;
  117. }
  118. TransformNode& getTransformNode()
  119. {
  120. return m_transform;
  121. }
  122. void attach(scene::Traversable::Observer* observer)
  123. {
  124. m_traverse.attach(observer);
  125. }
  126. void detach(scene::Traversable::Observer* observer)
  127. {
  128. m_traverse.detach(observer);
  129. }
  130. void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  131. {
  132. renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
  133. }
  134. void renderWireframe(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  135. {
  136. renderSolid(renderer, volume, localToWorld);
  137. #if 0
  138. if(g_showNames)
  139. {
  140. renderer.addRenderable(m_renderName, g_matrix4_identity);
  141. }
  142. #endif
  143. }
  144. };
  145. #if 0
  146. class TransformableSetTranslation
  147. {
  148. Translation m_value;
  149. public:
  150. TransformableSetTranslation(const Translation& value) : m_value(value)
  151. {
  152. }
  153. void operator()(Transformable& transformable) const
  154. {
  155. transformable.setTranslation(m_value);
  156. }
  157. };
  158. class TransformableSetRotation
  159. {
  160. Rotation m_value;
  161. public:
  162. TransformableSetRotation(const Rotation& value) : m_value(value)
  163. {
  164. }
  165. void operator()(Transformable& transformable) const
  166. {
  167. transformable.setRotation(m_value);
  168. }
  169. };
  170. class TransformableSetScale
  171. {
  172. Scale m_value;
  173. public:
  174. TransformableSetScale(const Scale& value) : m_value(value)
  175. {
  176. }
  177. void operator()(Transformable& transformable) const
  178. {
  179. transformable.setScale(m_value);
  180. }
  181. };
  182. class TransformableSetType
  183. {
  184. TransformModifierType m_value;
  185. public:
  186. TransformableSetType(const TransformModifierType& value) : m_value(value)
  187. {
  188. }
  189. void operator()(Transformable& transformable) const
  190. {
  191. transformable.setType(m_value);
  192. }
  193. };
  194. class TransformableFreezeTransform
  195. {
  196. TransformModifierType m_value;
  197. public:
  198. void operator()(Transformable& transformable) const
  199. {
  200. transformable.freezeTransform();
  201. }
  202. };
  203. template<typename Functor>
  204. inline void Scene_forEachChildTransformable(const Functor& functor, const scene::Path& path)
  205. {
  206. GlobalSceneGraph().traverse_subgraph(ChildInstanceWalker< InstanceApply<Transformable, Functor> >(functor), path);
  207. }
  208. #endif
  209. class GroupInstance :
  210. public TargetableInstance,
  211. #if 0
  212. public Transformable,
  213. #endif
  214. public Renderable
  215. {
  216. class TypeCasts
  217. {
  218. InstanceTypeCastTable m_casts;
  219. public:
  220. TypeCasts()
  221. {
  222. m_casts = TargetableInstance::StaticTypeCasts::instance().get();
  223. InstanceStaticCast<GroupInstance, Renderable>::install(m_casts);
  224. #if 0
  225. InstanceStaticCast<GroupInstance, Transformable>::install(m_casts);
  226. #endif
  227. }
  228. InstanceTypeCastTable& get()
  229. {
  230. return m_casts;
  231. }
  232. };
  233. Group& m_contained;
  234. public:
  235. typedef LazyStatic<TypeCasts> StaticTypeCasts;
  236. GroupInstance(const scene::Path& path, scene::Instance* parent, Group& group) :
  237. TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), group.getEntity(), *this),
  238. m_contained(group)
  239. {
  240. m_contained.instanceAttach(Instance::path());
  241. StaticRenderableConnectionLines::instance().attach(*this);
  242. }
  243. ~GroupInstance()
  244. {
  245. StaticRenderableConnectionLines::instance().detach(*this);
  246. m_contained.instanceDetach(Instance::path());
  247. }
  248. void renderSolid(Renderer& renderer, const VolumeTest& volume) const
  249. {
  250. m_contained.renderSolid(renderer, volume, Instance::localToWorld());
  251. }
  252. void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
  253. {
  254. m_contained.renderWireframe(renderer, volume, Instance::localToWorld());
  255. }
  256. #if 0
  257. void setType(TransformModifierType type)
  258. {
  259. Scene_forEachChildTransformable(TransformableSetType(type), Instance::path());
  260. }
  261. void setTranslation(const Translation& value)
  262. {
  263. Scene_forEachChildTransformable(TransformableSetTranslation(value), Instance::path());
  264. }
  265. void setRotation(const Rotation& value)
  266. {
  267. Scene_forEachChildTransformable(TransformableSetRotation(value), Instance::path());
  268. }
  269. void setScale(const Scale& value)
  270. {
  271. Scene_forEachChildTransformable(TransformableSetScale(value), Instance::path());
  272. }
  273. void freezeTransform()
  274. {
  275. Scene_forEachChildTransformable(TransformableFreezeTransform(), Instance::path());
  276. }
  277. void evaluateTransform()
  278. {
  279. }
  280. #endif
  281. };
  282. class GroupNode :
  283. public scene::Node::Symbiot,
  284. public scene::Instantiable,
  285. public scene::Cloneable,
  286. public scene::Traversable::Observer
  287. {
  288. class TypeCasts
  289. {
  290. NodeTypeCastTable m_casts;
  291. public:
  292. TypeCasts()
  293. {
  294. NodeStaticCast<GroupNode, scene::Instantiable>::install(m_casts);
  295. NodeStaticCast<GroupNode, scene::Cloneable>::install(m_casts);
  296. NodeContainedCast<GroupNode, scene::Traversable>::install(m_casts);
  297. NodeContainedCast<GroupNode, TransformNode>::install(m_casts);
  298. NodeContainedCast<GroupNode, Entity>::install(m_casts);
  299. NodeContainedCast<GroupNode, Nameable>::install(m_casts);
  300. NodeContainedCast<GroupNode, Namespaced>::install(m_casts);
  301. }
  302. NodeTypeCastTable& get()
  303. {
  304. return m_casts;
  305. }
  306. };
  307. scene::Node m_node;
  308. InstanceSet m_instances;
  309. Group m_contained;
  310. void construct()
  311. {
  312. m_contained.attach(this);
  313. }
  314. void destroy()
  315. {
  316. m_contained.detach(this);
  317. }
  318. public:
  319. typedef LazyStatic<TypeCasts> StaticTypeCasts;
  320. scene::Traversable& get(NullType<scene::Traversable>)
  321. {
  322. return m_contained.getTraversable();
  323. }
  324. TransformNode& get(NullType<TransformNode>)
  325. {
  326. return m_contained.getTransformNode();
  327. }
  328. Entity& get(NullType<Entity>)
  329. {
  330. return m_contained.getEntity();
  331. }
  332. Nameable& get(NullType<Nameable>)
  333. {
  334. return m_contained.getNameable();
  335. }
  336. Namespaced& get(NullType<Namespaced>)
  337. {
  338. return m_contained.getNamespaced();
  339. }
  340. GroupNode(EntityClass* eclass) :
  341. m_node(this, this, StaticTypeCasts::instance().get()),
  342. m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances))
  343. {
  344. construct();
  345. }
  346. GroupNode(const GroupNode& other) :
  347. scene::Node::Symbiot(other),
  348. scene::Instantiable(other),
  349. scene::Cloneable(other),
  350. scene::Traversable::Observer(other),
  351. m_node(this, this, StaticTypeCasts::instance().get()),
  352. m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances))
  353. {
  354. construct();
  355. }
  356. ~GroupNode()
  357. {
  358. destroy();
  359. }
  360. void release()
  361. {
  362. delete this;
  363. }
  364. scene::Node& node()
  365. {
  366. return m_node;
  367. }
  368. scene::Node& clone() const
  369. {
  370. return (new GroupNode(*this))->node();
  371. }
  372. void insert(scene::Node& child)
  373. {
  374. m_instances.insert(child);
  375. }
  376. void erase(scene::Node& child)
  377. {
  378. m_instances.erase(child);
  379. }
  380. scene::Instance* create(const scene::Path& path, scene::Instance* parent)
  381. {
  382. return new GroupInstance(path, parent, m_contained);
  383. }
  384. void forEachInstance(const scene::Instantiable::Visitor& visitor)
  385. {
  386. m_instances.forEachInstance(visitor);
  387. }
  388. void insert(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance)
  389. {
  390. m_instances.insert(observer, path, instance);
  391. }
  392. scene::Instance* erase(scene::Instantiable::Observer* observer, const scene::Path& path)
  393. {
  394. return m_instances.erase(observer, path);
  395. }
  396. };
  397. scene::Node& New_Group(EntityClass* eclass)
  398. {
  399. return (new GroupNode(eclass))->node();
  400. }