generic.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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 has a fixed size specified in its entity-definition and does not display a model (e.g. info_player_start).
  19. ///
  20. /// This entity displays an axis-aligned bounding box of the size and colour specified in its entity-definition.
  21. /// The "origin" key directly controls the entity's local-to-parent transform.
  22. /// An arrow is drawn to visualise the "angle" key.
  23. #include "cullable.h"
  24. #include "renderable.h"
  25. #include "editable.h"
  26. #include "math/frustum.h"
  27. #include "selectionlib.h"
  28. #include "instancelib.h"
  29. #include "transformlib.h"
  30. #include "entitylib.h"
  31. #include "render.h"
  32. #include "eclasslib.h"
  33. #include "math/line.h"
  34. #include "targetable.h"
  35. #include "origin.h"
  36. #include "angle.h"
  37. #include "filters.h"
  38. #include "namedentity.h"
  39. #include "keyobservers.h"
  40. #include "namekeys.h"
  41. #include "rotation.h"
  42. #include "entity.h"
  43. class RenderableArrow : public OpenGLRenderable
  44. {
  45. const Ray& m_ray;
  46. public:
  47. RenderableArrow(const Ray& ray)
  48. : m_ray(ray)
  49. {
  50. }
  51. void render(RenderStateFlags state) const
  52. {
  53. arrow_draw(m_ray.origin, m_ray.direction);
  54. }
  55. };
  56. inline void read_aabb(AABB& aabb, const EntityClass& eclass)
  57. {
  58. aabb = aabb_for_minmax(eclass.mins, eclass.maxs);
  59. }
  60. class GenericEntity :
  61. public Cullable,
  62. public Bounded,
  63. public Snappable
  64. {
  65. EntityKeyValues m_entity;
  66. KeyObserverMap m_keyObservers;
  67. MatrixTransform m_transform;
  68. OriginKey m_originKey;
  69. Vector3 m_origin;
  70. AngleKey m_angleKey;
  71. float m_angle;
  72. ClassnameFilter m_filter;
  73. NamedEntity m_named;
  74. NameKeys m_nameKeys;
  75. AABB m_aabb_local;
  76. Ray m_ray;
  77. RenderableArrow m_arrow;
  78. RenderableSolidAABB m_aabb_solid;
  79. RenderableWireframeAABB m_aabb_wire;
  80. RenderableNamedEntity m_renderName;
  81. Callback m_transformChanged;
  82. Callback m_evaluateTransform;
  83. void construct()
  84. {
  85. read_aabb(m_aabb_local, m_entity.getEntityClass());
  86. m_ray.origin = m_aabb_local.origin;
  87. m_ray.direction[0] = 1;
  88. m_ray.direction[1] = 0;
  89. m_ray.direction[2] = 0;
  90. m_keyObservers.insert("classname", ClassnameFilter::ClassnameChangedCaller(m_filter));
  91. m_keyObservers.insert(Static<KeyIsName>::instance().m_nameKey, NamedEntity::IdentifierChangedCaller(m_named));
  92. m_keyObservers.insert("angle", AngleKey::AngleChangedCaller(m_angleKey));
  93. m_keyObservers.insert("origin", OriginKey::OriginChangedCaller(m_originKey));
  94. }
  95. void updateTransform()
  96. {
  97. m_transform.localToParent() = g_matrix4_identity;
  98. matrix4_translate_by_vec3(m_transform.localToParent(), m_origin);
  99. m_ray.direction = matrix4_transformed_direction(matrix4_rotation_for_z(degrees_to_radians(m_angle)), Vector3(1, 0, 0));
  100. m_transformChanged();
  101. }
  102. typedef MemberCaller<GenericEntity, &GenericEntity::updateTransform> UpdateTransformCaller;
  103. void originChanged()
  104. {
  105. m_origin = m_originKey.m_origin;
  106. updateTransform();
  107. }
  108. typedef MemberCaller<GenericEntity, &GenericEntity::originChanged> OriginChangedCaller;
  109. void angleChanged()
  110. {
  111. m_angle = m_angleKey.m_angle;
  112. updateTransform();
  113. }
  114. typedef MemberCaller<GenericEntity, &GenericEntity::angleChanged> AngleChangedCaller;
  115. public:
  116. GenericEntity(EntityClass* eclass, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
  117. m_entity(eclass),
  118. m_originKey(OriginChangedCaller(*this)),
  119. m_origin(ORIGINKEY_IDENTITY),
  120. m_angleKey(AngleChangedCaller(*this)),
  121. m_angle(ANGLEKEY_IDENTITY),
  122. m_filter(m_entity, node),
  123. m_named(m_entity),
  124. m_nameKeys(m_entity),
  125. m_arrow(m_ray),
  126. m_aabb_solid(m_aabb_local),
  127. m_aabb_wire(m_aabb_local),
  128. m_renderName(m_named, g_vector3_identity),
  129. m_transformChanged(transformChanged),
  130. m_evaluateTransform(evaluateTransform)
  131. {
  132. construct();
  133. }
  134. GenericEntity(const GenericEntity& other, scene::Node& node, const Callback& transformChanged, const Callback& evaluateTransform) :
  135. m_entity(other.m_entity),
  136. m_originKey(OriginChangedCaller(*this)),
  137. m_origin(ORIGINKEY_IDENTITY),
  138. m_angleKey(AngleChangedCaller(*this)),
  139. m_angle(ANGLEKEY_IDENTITY),
  140. m_filter(m_entity, node),
  141. m_named(m_entity),
  142. m_nameKeys(m_entity),
  143. m_arrow(m_ray),
  144. m_aabb_solid(m_aabb_local),
  145. m_aabb_wire(m_aabb_local),
  146. m_renderName(m_named, g_vector3_identity),
  147. m_transformChanged(transformChanged),
  148. m_evaluateTransform(evaluateTransform)
  149. {
  150. construct();
  151. }
  152. InstanceCounter m_instanceCounter;
  153. void instanceAttach(const scene::Path& path)
  154. {
  155. if(++m_instanceCounter.m_count == 1)
  156. {
  157. m_filter.instanceAttach();
  158. m_entity.instanceAttach(path_find_mapfile(path.begin(), path.end()));
  159. m_entity.attach(m_keyObservers);
  160. }
  161. }
  162. void instanceDetach(const scene::Path& path)
  163. {
  164. if(--m_instanceCounter.m_count == 0)
  165. {
  166. m_entity.detach(m_keyObservers);
  167. m_entity.instanceDetach(path_find_mapfile(path.begin(), path.end()));
  168. m_filter.instanceDetach();
  169. }
  170. }
  171. EntityKeyValues& getEntity()
  172. {
  173. return m_entity;
  174. }
  175. const EntityKeyValues& getEntity() const
  176. {
  177. return m_entity;
  178. }
  179. Namespaced& getNamespaced()
  180. {
  181. return m_nameKeys;
  182. }
  183. Nameable& getNameable()
  184. {
  185. return m_named;
  186. }
  187. TransformNode& getTransformNode()
  188. {
  189. return m_transform;
  190. }
  191. const AABB& localAABB() const
  192. {
  193. return m_aabb_local;
  194. }
  195. VolumeIntersectionValue intersectVolume(const VolumeTest& volume, const Matrix4& localToWorld) const
  196. {
  197. return volume.TestAABB(localAABB(), localToWorld);
  198. }
  199. void renderArrow(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  200. {
  201. if(g_showAngles)
  202. {
  203. renderer.addRenderable(m_arrow, localToWorld);
  204. }
  205. }
  206. void renderSolid(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  207. {
  208. renderer.SetState(m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials);
  209. renderer.addRenderable(m_aabb_solid, localToWorld);
  210. renderArrow(renderer, volume, localToWorld);
  211. }
  212. void renderWireframe(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
  213. {
  214. renderer.SetState(m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly);
  215. renderer.addRenderable(m_aabb_wire, localToWorld);
  216. renderArrow(renderer, volume, localToWorld);
  217. if(g_showNames)
  218. {
  219. renderer.addRenderable(m_renderName, localToWorld);
  220. }
  221. }
  222. void testSelect(Selector& selector, SelectionTest& test, const Matrix4& localToWorld)
  223. {
  224. test.BeginMesh(localToWorld);
  225. SelectionIntersection best;
  226. aabb_testselect(m_aabb_local, test, best);
  227. if(best.valid())
  228. {
  229. selector.addIntersection(best);
  230. }
  231. }
  232. void translate(const Vector3& translation)
  233. {
  234. m_origin = origin_translated(m_origin, translation);
  235. }
  236. void rotate(const Quaternion& rotation)
  237. {
  238. m_angle = angle_rotated(m_angle, rotation);
  239. }
  240. void snapto(float snap)
  241. {
  242. m_originKey.m_origin = origin_snapped(m_originKey.m_origin, snap);
  243. m_originKey.write(&m_entity);
  244. }
  245. void revertTransform()
  246. {
  247. m_origin = m_originKey.m_origin;
  248. m_angle = m_angleKey.m_angle;
  249. }
  250. void freezeTransform()
  251. {
  252. m_originKey.m_origin = m_origin;
  253. m_originKey.write(&m_entity);
  254. m_angleKey.m_angle = m_angle;
  255. m_angleKey.write(&m_entity);
  256. }
  257. void transformChanged()
  258. {
  259. revertTransform();
  260. m_evaluateTransform();
  261. updateTransform();
  262. }
  263. typedef MemberCaller<GenericEntity, &GenericEntity::transformChanged> TransformChangedCaller;
  264. };
  265. class GenericEntityInstance :
  266. public TargetableInstance,
  267. public TransformModifier,
  268. public Renderable,
  269. public SelectionTestable
  270. {
  271. class TypeCasts
  272. {
  273. InstanceTypeCastTable m_casts;
  274. public:
  275. TypeCasts()
  276. {
  277. m_casts = TargetableInstance::StaticTypeCasts::instance().get();
  278. InstanceContainedCast<GenericEntityInstance, Bounded>::install(m_casts);
  279. InstanceContainedCast<GenericEntityInstance, Cullable>::install(m_casts);
  280. InstanceStaticCast<GenericEntityInstance, Renderable>::install(m_casts);
  281. InstanceStaticCast<GenericEntityInstance, SelectionTestable>::install(m_casts);
  282. InstanceStaticCast<GenericEntityInstance, Transformable>::install(m_casts);
  283. InstanceIdentityCast<GenericEntityInstance>::install(m_casts);
  284. }
  285. InstanceTypeCastTable& get()
  286. {
  287. return m_casts;
  288. }
  289. };
  290. GenericEntity& m_contained;
  291. mutable AABB m_bounds;
  292. public:
  293. typedef LazyStatic<TypeCasts> StaticTypeCasts;
  294. Bounded& get(NullType<Bounded>)
  295. {
  296. return m_contained;
  297. }
  298. Cullable& get(NullType<Cullable>)
  299. {
  300. return m_contained;
  301. }
  302. STRING_CONSTANT(Name, "GenericEntityInstance");
  303. GenericEntityInstance(const scene::Path& path, scene::Instance* parent, GenericEntity& contained) :
  304. TargetableInstance(path, parent, this, StaticTypeCasts::instance().get(), contained.getEntity(), *this),
  305. TransformModifier(GenericEntity::TransformChangedCaller(contained), ApplyTransformCaller(*this)),
  306. m_contained(contained)
  307. {
  308. m_contained.instanceAttach(Instance::path());
  309. StaticRenderableConnectionLines::instance().attach(*this);
  310. }
  311. ~GenericEntityInstance()
  312. {
  313. StaticRenderableConnectionLines::instance().detach(*this);
  314. m_contained.instanceDetach(Instance::path());
  315. }
  316. void renderSolid(Renderer& renderer, const VolumeTest& volume) const
  317. {
  318. m_contained.renderSolid(renderer, volume, Instance::localToWorld());
  319. }
  320. void renderWireframe(Renderer& renderer, const VolumeTest& volume) const
  321. {
  322. m_contained.renderWireframe(renderer, volume, Instance::localToWorld());
  323. }
  324. void testSelect(Selector& selector, SelectionTest& test)
  325. {
  326. m_contained.testSelect(selector, test, Instance::localToWorld());
  327. }
  328. void evaluateTransform()
  329. {
  330. if(getType() == TRANSFORM_PRIMITIVE)
  331. {
  332. m_contained.translate(getTranslation());
  333. m_contained.rotate(getRotation());
  334. }
  335. }
  336. void applyTransform()
  337. {
  338. m_contained.revertTransform();
  339. evaluateTransform();
  340. m_contained.freezeTransform();
  341. }
  342. typedef MemberCaller<GenericEntityInstance, &GenericEntityInstance::applyTransform> ApplyTransformCaller;
  343. };
  344. class GenericEntityNode :
  345. public scene::Node::Symbiot,
  346. public scene::Instantiable,
  347. public scene::Cloneable
  348. {
  349. class TypeCasts
  350. {
  351. NodeTypeCastTable m_casts;
  352. public:
  353. TypeCasts()
  354. {
  355. NodeStaticCast<GenericEntityNode, scene::Instantiable>::install(m_casts);
  356. NodeStaticCast<GenericEntityNode, scene::Cloneable>::install(m_casts);
  357. NodeContainedCast<GenericEntityNode, Snappable>::install(m_casts);
  358. NodeContainedCast<GenericEntityNode, TransformNode>::install(m_casts);
  359. NodeContainedCast<GenericEntityNode, Entity>::install(m_casts);
  360. NodeContainedCast<GenericEntityNode, Nameable>::install(m_casts);
  361. NodeContainedCast<GenericEntityNode, Namespaced>::install(m_casts);
  362. }
  363. NodeTypeCastTable& get()
  364. {
  365. return m_casts;
  366. }
  367. };
  368. InstanceSet m_instances;
  369. scene::Node m_node;
  370. GenericEntity m_contained;
  371. public:
  372. typedef LazyStatic<TypeCasts> StaticTypeCasts;
  373. Snappable& get(NullType<Snappable>)
  374. {
  375. return m_contained;
  376. }
  377. TransformNode& get(NullType<TransformNode>)
  378. {
  379. return m_contained.getTransformNode();
  380. }
  381. Entity& get(NullType<Entity>)
  382. {
  383. return m_contained.getEntity();
  384. }
  385. Nameable& get(NullType<Nameable>)
  386. {
  387. return m_contained.getNameable();
  388. }
  389. Namespaced& get(NullType<Namespaced>)
  390. {
  391. return m_contained.getNamespaced();
  392. }
  393. GenericEntityNode(EntityClass* eclass) :
  394. m_node(this, this, StaticTypeCasts::instance().get()),
  395. m_contained(eclass, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<GenericEntityInstance>::Caller(m_instances))
  396. {
  397. }
  398. GenericEntityNode(const GenericEntityNode& other) :
  399. scene::Node::Symbiot(other),
  400. scene::Instantiable(other),
  401. scene::Cloneable(other),
  402. m_node(this, this, StaticTypeCasts::instance().get()),
  403. m_contained(other.m_contained, m_node, InstanceSet::TransformChangedCaller(m_instances), InstanceSetEvaluateTransform<GenericEntityInstance>::Caller(m_instances))
  404. {
  405. }
  406. void release()
  407. {
  408. delete this;
  409. }
  410. scene::Node& node()
  411. {
  412. return m_node;
  413. }
  414. scene::Node& clone() const
  415. {
  416. return (new GenericEntityNode(*this))->node();
  417. }
  418. scene::Instance* create(const scene::Path& path, scene::Instance* parent)
  419. {
  420. return new GenericEntityInstance(path, parent, m_contained);
  421. }
  422. void forEachInstance(const scene::Instantiable::Visitor& visitor)
  423. {
  424. m_instances.forEachInstance(visitor);
  425. }
  426. void insert(scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance)
  427. {
  428. m_instances.insert(observer, path, instance);
  429. }
  430. scene::Instance* erase(scene::Instantiable::Observer* observer, const scene::Path& path)
  431. {
  432. return m_instances.erase(observer, path);
  433. }
  434. };
  435. scene::Node& New_GenericEntity(EntityClass* eclass)
  436. {
  437. return (new GenericEntityNode(eclass))->node();
  438. }