GraphicsObject.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. #pragma once
  2. #include "Containers.h"
  3. #include "GraphicsDataSets.h"
  4. #include "LightComponent.h"
  5. #include "Loaders.h"
  6. #include "Math.h"
  7. #include "NullSystemObjects.h"
  8. #include "System.h"
  9. enum GraphicsComponentType : std::size_t
  10. {
  11. GraphicsComponentType_Model = 0,
  12. GraphicsComponentType_Shader,
  13. GraphicsComponentType_Light,
  14. GraphicsComponentType_NumOfComponents
  15. };
  16. class GraphicsObject : public SystemObject
  17. {
  18. public:
  19. GraphicsObject(SystemScene *p_systemScene, const std::string &p_name)
  20. : SystemObject(p_systemScene, p_name, Properties::Graphics)
  21. {
  22. m_modelComponent = nullptr;
  23. m_shaderComponent = nullptr;
  24. m_lightComponent = nullptr;
  25. m_updateQuaternion = false;
  26. }
  27. virtual ~GraphicsObject()
  28. {
  29. // Iterate over all component types and delete components if they have been created
  30. for(std::size_t i = 0; i < GraphicsComponentType::GraphicsComponentType_NumOfComponents; i++)
  31. removeComponent(static_cast<GraphicsComponentType>(i));
  32. }
  33. // System type is Graphics
  34. BitMask getSystemType() { return Systems::Graphics; }
  35. void update(const float p_deltaTime)
  36. {
  37. if(isUpdateNeeded())
  38. {
  39. if(m_updateQuaternion)
  40. {
  41. //TODO: calculate rotation quaternion
  42. m_updateQuaternion = false;
  43. }
  44. // Calculate model matrix
  45. m_worldSpace.m_transformMat = Math::createTransformMat(m_worldSpace.m_spatialData.m_position, m_worldSpace.m_spatialData.m_rotationEuler, m_worldSpace.m_spatialData.m_scale);
  46. // Mark as updated
  47. updatePerformed();
  48. }
  49. }
  50. virtual BitMask getDesiredSystemChanges() { return Systems::Changes::Spatial::AllWorld | Systems::Changes::Graphics::All; }
  51. virtual BitMask getPotentialSystemChanges() { return Systems::Changes::Spatial::WorldTransform; }
  52. virtual void changeOccurred(ObservedSubject *p_subject, BitMask p_changeType)
  53. {
  54. // Track what data has been modified
  55. BitMask newChanges = Systems::Changes::None;
  56. // Get all of the world spatial data, include the transform matrix; add up the bit-mask of changed data;
  57. if(p_changeType & Systems::Changes::Spatial::AllWorld)
  58. {
  59. m_worldSpace.m_spatialData = p_subject->getSpatialData(this, Systems::Changes::Spatial::AllWorldNoTransform);
  60. m_worldSpace.m_transformMat = p_subject->getMat4(this, Systems::Changes::Spatial::WorldTransform);
  61. newChanges = newChanges | Systems::Changes::Spatial::AllWorld;
  62. }
  63. else
  64. {
  65. // Get world spatial data without transform matrix; add up the bit-mask of changed data; flag object to need updating
  66. if(p_changeType & Systems::Changes::Spatial::AllWorldNoTransform)
  67. {
  68. m_worldSpace.m_spatialData = p_subject->getSpatialData(this, Systems::Changes::Spatial::AllWorldNoTransform);
  69. newChanges = newChanges | Systems::Changes::Spatial::AllWorldNoTransform;
  70. setUpdateNeeded(true);
  71. }
  72. else
  73. {
  74. // Get world position vector; add up the bit-mask of changed data; flag object to need updating
  75. if(p_changeType & Systems::Changes::Spatial::WorldPosition)
  76. {
  77. m_worldSpace.m_spatialData.m_position = p_subject->getVec3(this, Systems::Changes::Spatial::WorldPosition);
  78. newChanges = newChanges | Systems::Changes::Spatial::WorldPosition;
  79. setUpdateNeeded(true);
  80. }
  81. // Get world rotation vector; add up the bit-mask of changed data; flag object to need updating; flag rotation quaternion to need updating
  82. if(p_changeType & Systems::Changes::Spatial::WorldRotation)
  83. {
  84. m_worldSpace.m_spatialData.m_rotationEuler = p_subject->getVec3(this, Systems::Changes::Spatial::WorldRotation);
  85. newChanges = newChanges | Systems::Changes::Spatial::WorldRotation;
  86. setUpdateNeeded(true);
  87. m_updateQuaternion = true;
  88. }
  89. // Get world scale vector; add up the bit-mask of changed data; flag object to need updating
  90. if(p_changeType & Systems::Changes::Spatial::WorldScale)
  91. {
  92. m_worldSpace.m_spatialData.m_scale = p_subject->getVec3(this, Systems::Changes::Spatial::WorldScale);
  93. newChanges = newChanges | Systems::Changes::Spatial::WorldScale;
  94. setUpdateNeeded(true);
  95. }
  96. }
  97. }
  98. // If any new data has been left, pass it to the components
  99. if(newChanges != Systems::Changes::None)
  100. {
  101. }
  102. //postChanges(newChanges);
  103. }
  104. const Math::Mat4f &getMat4(const Observer *p_observer, BitMask p_changedBits) const
  105. {
  106. switch(p_changedBits)
  107. {
  108. case Systems::Changes::Spatial::WorldTransform:
  109. return m_worldSpace.m_transformMat;
  110. break;
  111. }
  112. return ObservedSubject::getMat4(p_observer, p_changedBits);
  113. }
  114. const SpatialData &getSpatialData(const Observer *p_observer, BitMask p_changedBits) const
  115. {
  116. switch(p_changedBits)
  117. {
  118. case Systems::Changes::Spatial::AllWorld:
  119. return m_worldSpace.m_spatialData;
  120. break;
  121. }
  122. return ObservedSubject::getSpatialData(p_observer, p_changedBits);
  123. }
  124. // Get the world spatial data (without transform matrix)
  125. const inline SpatialData &getWorldSpatialData() const { return m_worldSpace.m_spatialData; }
  126. // Get the world spatial transform data
  127. const inline SpatialTransformData &getWorldSpatialTransformData() const { return m_worldSpace; }
  128. // Get the world position
  129. const inline Math::Vec3f &getWorldPosition() const { return m_worldSpace.m_spatialData.m_position; }
  130. // Get the world rotation in Euler
  131. const inline Math::Vec3f getWorldRotationEuler() const { return m_worldSpace.m_spatialData.m_rotationEuler; }
  132. // Get the world rotation as a quaternion
  133. const inline Math::Quaternion getWorldRotationQuat() const { return m_worldSpace.m_spatialData.m_rotationQuat; }
  134. // Get the world scale
  135. const inline Math::Vec3f &getWorldScale() const { return m_worldSpace.m_spatialData.m_scale; }
  136. // Set the world spatial data (without transform matrix)
  137. inline void setWorldSpatialData(const SpatialData &p_spatialData) { setUpdateNeeded(true); m_worldSpace.m_spatialData = p_spatialData; }
  138. // Set the world spatial transform data
  139. inline void setWorldSpatialTransformData(const SpatialTransformData &p_spatialData) { m_worldSpace = p_spatialData; }
  140. // Set the world position
  141. inline void setWorldPosition(const Math::Vec3f &p_position) { setUpdateNeeded(true); m_worldSpace.m_spatialData.m_position = p_position; }
  142. // Set the world rotation in Euler
  143. inline void setWorldRotation(const Math::Vec3f &p_rotationEuler) { setUpdateNeeded(true); m_updateQuaternion - true; m_worldSpace.m_spatialData.m_rotationEuler = p_rotationEuler; }
  144. // Set the world rotation as a quaternion
  145. inline void setWorldRotation(const Math::Quaternion &p_rotationQuat) { setUpdateNeeded(true); m_worldSpace.m_spatialData.m_rotationQuat = p_rotationQuat; }
  146. // Set the world scale
  147. inline void setWorldScale(const Math::Vec3f &p_scale) { setUpdateNeeded(true); m_worldSpace.m_spatialData.m_scale = p_scale; }
  148. // Component functions
  149. /*void addComponent(DirectionalLightDataSet &p_lightDataSet)
  150. {
  151. // Make sure that this component isn't assigned already
  152. removeComponent(GraphicsComponentType::GraphicsComponentType_Light);
  153. //m_lightComponent = new LightComponent(p_lightDataSet);
  154. }
  155. void addComponent(PointLightDataSet &p_lightDataSet)
  156. {
  157. // Make sure that this component isn't assigned already
  158. removeComponent(GraphicsComponentType::GraphicsComponentType_Light);
  159. //m_lightComponent = new LightComponent(p_lightDataSet);
  160. }
  161. void addComponent(SpotLightDataSet &p_lightDataSet)
  162. {
  163. // Make sure that this component isn't assigned already
  164. removeComponent(GraphicsComponentType::GraphicsComponentType_Light);
  165. //m_lightComponent = new LightComponent(p_lightDataSet);
  166. }*/
  167. void addComponent(LightComponent *p_component)
  168. {
  169. // Make sure that this component isn't assigned already
  170. removeComponent(GraphicsComponentType::GraphicsComponentType_Light);
  171. m_lightComponent = p_component;
  172. }
  173. void addComponent(ModelComponentData *p_component)
  174. {
  175. // Make sure that this component isn't assigned already
  176. removeComponent(GraphicsComponentType::GraphicsComponentType_Model);
  177. m_modelComponent = p_component;
  178. }
  179. void addComponent(ShaderData *p_component)
  180. {
  181. // Make sure that this component isn't assigned already
  182. removeComponent(GraphicsComponentType::GraphicsComponentType_Shader);
  183. m_shaderComponent = p_component;
  184. }
  185. void removeComponent(const GraphicsComponentType p_compType)
  186. {
  187. switch(p_compType)
  188. {
  189. case GraphicsComponentType_Light:
  190. {
  191. if(m_lightComponent != nullptr)
  192. delete m_lightComponent;
  193. break;
  194. }
  195. case GraphicsComponentType_Model:
  196. {
  197. if(m_modelComponent != nullptr)
  198. delete m_modelComponent;
  199. break;
  200. }
  201. case GraphicsComponentType_Shader:
  202. {
  203. if(m_shaderComponent != nullptr)
  204. delete m_shaderComponent;
  205. break;
  206. }
  207. }
  208. }
  209. private:
  210. //enum
  211. /*struct
  212. {
  213. union
  214. {
  215. } m_component;
  216. } m_graphicsComponents;*/
  217. /*struct
  218. {
  219. enum LightComponentType
  220. {
  221. };
  222. union
  223. {
  224. } m_light;
  225. } m_lightComponent;*/
  226. // Pointers to multiple variables, intended as a way to modify component values directly (like a simplified observer pattern).
  227. // If a pointer to a value is not nullptr, then that variable is acting as a listener its value should be updated
  228. struct ProxyValues
  229. {
  230. ProxyValues()
  231. {
  232. m_color = nullptr;
  233. }
  234. Math::Vec3f *m_color;
  235. };
  236. ProxyValues m_proxyValues;
  237. //std::vector<BaseGraphicsComponent&> m_components;
  238. std::vector<MeshData> m_meshData;
  239. SpatialTransformData m_worldSpace;
  240. // Components
  241. ModelComponentData *m_modelComponent;
  242. ShaderData *m_shaderComponent;
  243. LightComponent *m_lightComponent;
  244. // Flag data that needs to be updated
  245. bool m_updateQuaternion;
  246. };
  247. /*class GraphicsObject : public SystemObject
  248. {
  249. public:
  250. GraphicsObject(SystemScene *p_systemScene, const std::string &p_name)
  251. : SystemObject(p_systemScene, p_name, Properties::Graphics), m_needsUpdate(true), m_affectedByLighting(true) { }
  252. virtual ~GraphicsObject() { }
  253. BitMask getSystemType() { return Systems::Graphics; }
  254. virtual BitMask getDesiredSystemChanges() { return Systems::Changes::Spatial::All; }
  255. virtual BitMask getPotentialSystemChanges() { return Systems::Changes::None; }
  256. // Processes any spacial changes
  257. virtual void changeOccurred(ObservedSubject *p_subject, BitMask p_changeType)
  258. {
  259. if(p_changeType & Systems::Changes::Spatial::Position)
  260. {
  261. m_baseObjectData.m_position =
  262. p_subject->getVec3(this, Systems::Changes::Spatial::Position) + m_baseObjectData.m_offsetPosition;
  263. m_needsUpdate = true;
  264. }
  265. if(p_changeType & Systems::Changes::Spatial::Rotation)
  266. {
  267. m_baseObjectData.m_rotation =
  268. p_subject->getVec3(this, Systems::Changes::Spatial::Rotation) + m_baseObjectData.m_offsetRotation;
  269. m_needsUpdate = true;
  270. }
  271. if(p_changeType & Systems::Changes::Spatial::Scale)
  272. {
  273. m_baseObjectData.m_scale = p_subject->getVec3(this, Systems::Changes::Spatial::Scale);
  274. m_needsUpdate = true;
  275. }
  276. if(p_changeType & Systems::Changes::Spatial::ModelMatrix)
  277. {
  278. m_baseObjectData.m_modelMat = p_subject->getMat4(this, Systems::Changes::Spatial::ModelMatrix);
  279. m_needsUpdate = true;
  280. }
  281. if(p_changeType & Systems::Changes::Graphics::Lighting)
  282. {
  283. m_affectedByLighting = p_subject->getBool(this, Systems::Changes::Graphics::Lighting);
  284. }
  285. }
  286. // Has the object been already loaded to memory (RAM)?
  287. const inline bool isLoadedToMemory() const { return m_loadedToMemory; }
  288. // Has the object been already loaded to video memory (GPU VRAM)
  289. const inline bool isLoadedToVideoMemory() const { return m_loadedToVideoMemory; }
  290. // Getters
  291. const virtual Math::Vec3f &getVec3(const Observer *p_observer, BitMask p_changedBits) const
  292. {
  293. switch(p_changedBits)
  294. {
  295. case Systems::Changes::Spatial::Position:
  296. return m_baseObjectData.m_position;
  297. break;
  298. case Systems::Changes::Spatial::Rotation:
  299. return m_baseObjectData.m_rotation;
  300. break;
  301. case Systems::Changes::Spatial::Scale:
  302. return m_baseObjectData.m_scale;
  303. break;
  304. }
  305. return ObservedSubject::getVec3(p_observer, p_changedBits);
  306. }
  307. const virtual bool getBool(const Observer *p_observer, BitMask p_changedBits) const
  308. {
  309. switch(p_changedBits)
  310. {
  311. case Systems::Changes::Graphics::Lighting:
  312. return m_affectedByLighting;
  313. break;
  314. }
  315. return ObservedSubject::getBool(p_observer, p_changedBits);
  316. }
  317. const inline GraphicsData &getBaseObjectData() const { return m_baseObjectData; }
  318. // Setters for spacial data
  319. inline void setScale(const Math::Vec3f &p_scale) { m_baseObjectData.m_scale = p_scale; }
  320. inline void setPosition(const Math::Vec3f &p_position) { m_baseObjectData.m_position = p_position; }
  321. inline void setRotation(const Math::Vec3f &p_rotation) { m_baseObjectData.m_rotation = p_rotation; }
  322. inline void setOffsetPosition(const Math::Vec3f &p_position) { m_baseObjectData.m_offsetPosition = p_position; }
  323. inline void setOffsetRotation(const Math::Vec3f &p_rotation) { m_baseObjectData.m_offsetRotation = p_rotation; }
  324. // Setters for misc data
  325. inline void setAffectedByLighting(const bool p_flag) { m_affectedByLighting = p_flag; }
  326. inline void setAlphaThreshold(const float p_value) { m_baseObjectData.m_alphaThreshold = p_value; }
  327. inline void setEmissiveThreshold(const float p_value) { m_baseObjectData.m_emissiveThreshold = p_value; }
  328. inline void setHeightScale(const float p_value) { m_baseObjectData.m_heightScale = p_value; }
  329. inline void setTextureTilingFactor(const float p_value) { m_baseObjectData.m_textureTilingFactor = p_value; }
  330. protected:
  331. // A flag telling if this object should be rendered during geometry pass or as a post-process (i.e. after lighting)
  332. bool m_affectedByLighting;
  333. // Does the object need to be updated after any of its data has been changed
  334. bool m_needsUpdate;
  335. // Spatial and misc data of an object
  336. GraphicsData m_baseObjectData;
  337. };*/