BsReflectionProbe.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsReflectionProbe.h"
  4. #include "BsReflectionProbeRTTI.h"
  5. #include "BsSceneObject.h"
  6. #include "BsFrameAlloc.h"
  7. #include "BsTexture.h"
  8. #include "BsRenderer.h"
  9. #include "BsUUID.h"
  10. namespace bs
  11. {
  12. ReflectionProbeBase::ReflectionProbeBase()
  13. : mPosition(BsZero), mRotation(BsIdentity), mScale(1.0f, 1.0f, 1.0f), mType(ReflectionProbeType::Box), mRadius(1.0f)
  14. , mExtents(1.0f, 1.0f, 1.0f), mTransitionDistance(1.0f), mIsActive(true), mBounds(Vector3::ZERO, 1.0f)
  15. { }
  16. ReflectionProbeBase::ReflectionProbeBase(ReflectionProbeType type, float radius, const Vector3& extents)
  17. : mPosition(BsZero), mRotation(BsIdentity), mScale(1.0f, 1.0f, 1.0f), mType(type), mRadius(radius)
  18. , mExtents(extents), mTransitionDistance(1.0f), mIsActive(true), mBounds(Vector3::ZERO, 1.0f)
  19. { }
  20. void ReflectionProbeBase::updateBounds()
  21. {
  22. switch (mType)
  23. {
  24. case ReflectionProbeType::Sphere:
  25. mBounds = Sphere(mPosition, mRadius * std::max(std::max(mScale.x, mScale.y), mScale.z));
  26. break;
  27. case ReflectionProbeType::Box:
  28. mBounds = Sphere(mPosition, (mExtents * mScale).length());
  29. break;
  30. }
  31. }
  32. template <bool Core>
  33. TReflectionProbe<Core>::TReflectionProbe()
  34. :ReflectionProbeBase()
  35. { }
  36. template <bool Core>
  37. TReflectionProbe<Core>::TReflectionProbe(ReflectionProbeType type, float radius, const Vector3& extents)
  38. : ReflectionProbeBase(type, radius, extents)
  39. { }
  40. template <bool Core>
  41. void TReflectionProbe<Core>::generate()
  42. {
  43. if (mCustomTexture != nullptr)
  44. _markCoreDirty();
  45. }
  46. template class TReflectionProbe<true>;
  47. template class TReflectionProbe<false>;
  48. ReflectionProbe::ReflectionProbe()
  49. :mLastUpdateHash(0)
  50. {
  51. }
  52. ReflectionProbe::ReflectionProbe(ReflectionProbeType type, float radius, const Vector3& extents)
  53. : TReflectionProbe(type, radius, extents), mLastUpdateHash(0)
  54. {
  55. // Calling virtual method is okay here because this is the most derived type
  56. updateBounds();
  57. }
  58. SPtr<ct::ReflectionProbe> ReflectionProbe::getCore() const
  59. {
  60. return std::static_pointer_cast<ct::ReflectionProbe>(mCoreSpecific);
  61. }
  62. SPtr<ReflectionProbe> ReflectionProbe::createSphere(float radius)
  63. {
  64. ReflectionProbe* probe = new (bs_alloc<ReflectionProbe>()) ReflectionProbe(ReflectionProbeType::Sphere, radius, Vector3::ZERO);
  65. SPtr<ReflectionProbe> probePtr = bs_core_ptr<ReflectionProbe>(probe);
  66. probePtr->_setThisPtr(probePtr);
  67. probePtr->mUUID = UUIDGenerator::generateRandom();
  68. probePtr->initialize();
  69. return probePtr;
  70. }
  71. SPtr<ReflectionProbe> ReflectionProbe::createBox(const Vector3& extents)
  72. {
  73. ReflectionProbe* probe = new (bs_alloc<ReflectionProbe>()) ReflectionProbe(ReflectionProbeType::Box, 0.0f, extents);
  74. SPtr<ReflectionProbe> probePtr = bs_core_ptr<ReflectionProbe>(probe);
  75. probePtr->_setThisPtr(probePtr);
  76. probePtr->mUUID = UUIDGenerator::generateRandom();
  77. probePtr->initialize();
  78. return probePtr;
  79. }
  80. SPtr<ReflectionProbe> ReflectionProbe::createEmpty()
  81. {
  82. ReflectionProbe* probe = new (bs_alloc<ReflectionProbe>()) ReflectionProbe();
  83. SPtr<ReflectionProbe> probePtr = bs_core_ptr<ReflectionProbe>(probe);
  84. probePtr->_setThisPtr(probePtr);
  85. return probePtr;
  86. }
  87. SPtr<ct::CoreObject> ReflectionProbe::createCore() const
  88. {
  89. ct::ReflectionProbe* probe = new (bs_alloc<ct::ReflectionProbe>()) ct::ReflectionProbe(mType, mRadius, mExtents);
  90. SPtr<ct::ReflectionProbe> probePtr = bs_shared_ptr<ct::ReflectionProbe>(probe);
  91. probePtr->mUUID = mUUID;
  92. probePtr->_setThisPtr(probePtr);
  93. return probePtr;
  94. }
  95. CoreSyncData ReflectionProbe::syncToCore(FrameAlloc* allocator)
  96. {
  97. UINT32 size = 0;
  98. size += rttiGetElemSize(mPosition);
  99. size += rttiGetElemSize(mRotation);
  100. size += rttiGetElemSize(mScale);
  101. size += rttiGetElemSize(mType);
  102. size += rttiGetElemSize(mRadius);
  103. size += rttiGetElemSize(mExtents);
  104. size += rttiGetElemSize(mTransitionDistance);
  105. size += rttiGetElemSize(mIsActive);
  106. size += rttiGetElemSize(getCoreDirtyFlags());
  107. size += rttiGetElemSize(mBounds);
  108. size += sizeof(SPtr<ct::Texture>);
  109. size += rttiGetElemSize(mUUID);
  110. UINT8* buffer = allocator->alloc(size);
  111. char* dataPtr = (char*)buffer;
  112. dataPtr = rttiWriteElem(mPosition, dataPtr);
  113. dataPtr = rttiWriteElem(mRotation, dataPtr);
  114. dataPtr = rttiWriteElem(mScale, dataPtr);
  115. dataPtr = rttiWriteElem(mType, dataPtr);
  116. dataPtr = rttiWriteElem(mRadius, dataPtr);
  117. dataPtr = rttiWriteElem(mExtents, dataPtr);
  118. dataPtr = rttiWriteElem(mTransitionDistance, dataPtr);
  119. dataPtr = rttiWriteElem(mIsActive, dataPtr);
  120. dataPtr = rttiWriteElem(getCoreDirtyFlags(), dataPtr);
  121. dataPtr = rttiWriteElem(mBounds, dataPtr);
  122. dataPtr = rttiWriteElem(mUUID, dataPtr);
  123. SPtr<ct::Texture>* customTexture = new (dataPtr)SPtr<ct::Texture>();
  124. if (mCustomTexture.isLoaded(false))
  125. *customTexture = mCustomTexture->getCore();
  126. else
  127. *customTexture = nullptr;
  128. dataPtr += sizeof(SPtr<ct::Texture>);
  129. return CoreSyncData(buffer, size);
  130. }
  131. void ReflectionProbe::_updateTransform(const HSceneObject& parent)
  132. {
  133. UINT32 curHash = parent->getTransformHash();
  134. if (curHash != _getLastModifiedHash())
  135. {
  136. setPosition(parent->getWorldPosition());
  137. setRotation(parent->getWorldRotation());
  138. setScale(parent->getWorldScale());
  139. _setLastModifiedHash(curHash);
  140. }
  141. }
  142. void ReflectionProbe::_markCoreDirty(ReflectionProbeDirtyFlag flags)
  143. {
  144. markCoreDirty((UINT32)flags);
  145. }
  146. RTTITypeBase* ReflectionProbe::getRTTIStatic()
  147. {
  148. return ReflectionProbeRTTI::instance();
  149. }
  150. RTTITypeBase* ReflectionProbe::getRTTI() const
  151. {
  152. return ReflectionProbe::getRTTIStatic();
  153. }
  154. namespace ct
  155. {
  156. ReflectionProbe::ReflectionProbe(ReflectionProbeType type, float radius, const Vector3& extents)
  157. : TReflectionProbe(type, radius, extents), mRendererId(0)
  158. {
  159. }
  160. ReflectionProbe::~ReflectionProbe()
  161. {
  162. gRenderer()->notifyReflectionProbeRemoved(this);
  163. }
  164. void ReflectionProbe::initialize()
  165. {
  166. updateBounds();
  167. gRenderer()->notifyReflectionProbeAdded(this);
  168. CoreObject::initialize();
  169. }
  170. void ReflectionProbe::syncToCore(const CoreSyncData& data)
  171. {
  172. char* dataPtr = (char*)data.getBuffer();
  173. UINT32 dirtyFlags = 0;
  174. bool oldIsActive = mIsActive;
  175. ReflectionProbeType oldType = mType;
  176. dataPtr = rttiReadElem(mPosition, dataPtr);
  177. dataPtr = rttiReadElem(mRotation, dataPtr);
  178. dataPtr = rttiReadElem(mScale, dataPtr);
  179. dataPtr = rttiReadElem(mType, dataPtr);
  180. dataPtr = rttiReadElem(mRadius, dataPtr);
  181. dataPtr = rttiReadElem(mExtents, dataPtr);
  182. dataPtr = rttiReadElem(mTransitionDistance, dataPtr);
  183. dataPtr = rttiReadElem(mIsActive, dataPtr);
  184. dataPtr = rttiReadElem(dirtyFlags, dataPtr);
  185. dataPtr = rttiReadElem(mBounds, dataPtr);
  186. dataPtr = rttiReadElem(mUUID, dataPtr);
  187. SPtr<Texture>* texture = (SPtr<Texture>*)dataPtr;
  188. mCustomTexture = *texture;
  189. texture->~SPtr<Texture>();
  190. dataPtr += sizeof(SPtr<Texture>);
  191. updateBounds();
  192. if (dirtyFlags == (UINT32)ReflectionProbeDirtyFlag::Transform)
  193. {
  194. if (mIsActive)
  195. gRenderer()->notifyReflectionProbeUpdated(this);
  196. }
  197. else
  198. {
  199. if (oldIsActive != mIsActive)
  200. {
  201. if (mIsActive)
  202. gRenderer()->notifyReflectionProbeAdded(this);
  203. else
  204. {
  205. ReflectionProbeType newType = mType;
  206. mType = oldType;
  207. gRenderer()->notifyReflectionProbeRemoved(this);
  208. mType = newType;
  209. }
  210. }
  211. else
  212. {
  213. ReflectionProbeType newType = mType;
  214. mType = oldType;
  215. gRenderer()->notifyReflectionProbeRemoved(this);
  216. mType = newType;
  217. gRenderer()->notifyReflectionProbeAdded(this);
  218. }
  219. }
  220. }
  221. }}