BsLightProbeVolume.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsLightProbeVolume.h"
  4. #include "BsLightProbeVolumeRTTI.h"
  5. #include "BsFrameAlloc.h"
  6. #include "BsRenderer.h"
  7. #include "BsLight.h"
  8. namespace bs
  9. {
  10. LightProbeVolumeBase::LightProbeVolumeBase()
  11. : mPosition(BsZero), mRotation(BsIdentity), mIsActive(true)
  12. { }
  13. LightProbeVolume::LightProbeVolume()
  14. { }
  15. LightProbeVolume::LightProbeVolume(const AABox& volume, const Vector3& density)
  16. {
  17. // TODO - Generates probes in the grid volume
  18. }
  19. UINT32 LightProbeVolume::addProbe(const Vector3& position)
  20. {
  21. UINT32 handle = mNextProbeId++;
  22. mProbes[handle] = ProbeInfo(LightProbeFlags::Dirty, position);
  23. _markCoreDirty();
  24. return handle;
  25. }
  26. void LightProbeVolume::removeProbe(UINT32 handle)
  27. {
  28. auto iterFind = mProbes.find(handle);
  29. if (iterFind != mProbes.end())
  30. {
  31. iterFind->second.flags = LightProbeFlags::Removed;
  32. _markCoreDirty();
  33. }
  34. }
  35. void LightProbeVolume::setProbePosition(UINT32 handle, const Vector3& position)
  36. {
  37. auto iterFind = mProbes.find(handle);
  38. if (iterFind != mProbes.end())
  39. {
  40. iterFind->second.flags = LightProbeFlags::Dirty;
  41. iterFind->second.position = position;
  42. _markCoreDirty();
  43. }
  44. }
  45. Vector3 LightProbeVolume::getProbePosition(UINT32 handle) const
  46. {
  47. auto iterFind = mProbes.find(handle);
  48. if (iterFind != mProbes.end())
  49. return iterFind->second.position;
  50. return Vector3::ZERO;
  51. }
  52. SPtr<ct::LightProbeVolume> LightProbeVolume::getCore() const
  53. {
  54. return std::static_pointer_cast<ct::LightProbeVolume>(mCoreSpecific);
  55. }
  56. SPtr<LightProbeVolume> LightProbeVolume::create(const AABox& volume, const Vector3& density)
  57. {
  58. LightProbeVolume* probeVolume = new (bs_alloc<LightProbeVolume>()) LightProbeVolume(volume, density);
  59. SPtr<LightProbeVolume> probeVolumePtr = bs_core_ptr<LightProbeVolume>(probeVolume);
  60. probeVolumePtr->_setThisPtr(probeVolumePtr);
  61. probeVolumePtr->initialize();
  62. return probeVolumePtr;
  63. }
  64. SPtr<LightProbeVolume> LightProbeVolume::createEmpty()
  65. {
  66. LightProbeVolume* probeVolume = new (bs_alloc<LightProbeVolume>()) LightProbeVolume();
  67. SPtr<LightProbeVolume> probleVolumePtr = bs_core_ptr<LightProbeVolume>(probeVolume);
  68. probleVolumePtr->_setThisPtr(probleVolumePtr);
  69. return probleVolumePtr;
  70. }
  71. SPtr<ct::CoreObject> LightProbeVolume::createCore() const
  72. {
  73. ct::LightProbeVolume* handler = new (bs_alloc<ct::LightProbeVolume>()) ct::LightProbeVolume(mProbes);
  74. SPtr<ct::LightProbeVolume> handlerPtr = bs_shared_ptr<ct::LightProbeVolume>(handler);
  75. handlerPtr->_setThisPtr(handlerPtr);
  76. return handlerPtr;
  77. }
  78. CoreSyncData LightProbeVolume::syncToCore(FrameAlloc* allocator)
  79. {
  80. UINT32 size = 0;
  81. UINT8* buffer = nullptr;
  82. bs_frame_mark();
  83. {
  84. FrameVector<std::pair<UINT32, ProbeInfo>> dirtyProbes;
  85. FrameVector<UINT32> removedProbes;
  86. for (auto& probe : mProbes)
  87. {
  88. if (probe.second.flags == LightProbeFlags::Dirty)
  89. {
  90. dirtyProbes.push_back(std::make_pair(probe.first, probe.second));
  91. probe.second.flags = LightProbeFlags::Clean;
  92. }
  93. else if (probe.second.flags == LightProbeFlags::Removed)
  94. {
  95. removedProbes.push_back(probe.first);
  96. probe.second.flags = LightProbeFlags::Empty;
  97. }
  98. }
  99. UINT32 numDirtyProbes = (UINT32)dirtyProbes.size();
  100. UINT32 numRemovedProbes = (UINT32)removedProbes.size();
  101. size += rttiGetElemSize(mPosition);
  102. size += rttiGetElemSize(mRotation);
  103. size += rttiGetElemSize(mIsActive);
  104. size += rttiGetElemSize(numDirtyProbes);
  105. size += rttiGetElemSize(numRemovedProbes);
  106. size += (sizeof(UINT32) + sizeof(Vector3) + sizeof(LightProbeFlags)) * numDirtyProbes;
  107. size += sizeof(UINT32) * numRemovedProbes;
  108. buffer = allocator->alloc(size);
  109. char* dataPtr = (char*)buffer;
  110. dataPtr = rttiWriteElem(mPosition, dataPtr);
  111. dataPtr = rttiWriteElem(mRotation, dataPtr);
  112. dataPtr = rttiWriteElem(mIsActive, dataPtr);
  113. dataPtr = rttiWriteElem(numDirtyProbes, dataPtr);
  114. dataPtr = rttiWriteElem(numRemovedProbes, dataPtr);
  115. for (auto& entry : dirtyProbes)
  116. {
  117. dataPtr = rttiWriteElem(entry.first, dataPtr);
  118. dataPtr = rttiWriteElem(entry.second.position, dataPtr);
  119. dataPtr = rttiWriteElem(entry.second.flags, dataPtr);
  120. }
  121. for(auto& entry : removedProbes)
  122. dataPtr = rttiWriteElem(entry, dataPtr);
  123. }
  124. bs_frame_clear();
  125. return CoreSyncData(buffer, size);
  126. }
  127. void LightProbeVolume::_markCoreDirty()
  128. {
  129. markCoreDirty();
  130. }
  131. RTTITypeBase* LightProbeVolume::getRTTIStatic()
  132. {
  133. return LightProbeVolumeRTTI::instance();
  134. }
  135. RTTITypeBase* LightProbeVolume::getRTTI() const
  136. {
  137. return LightProbeVolume::getRTTIStatic();
  138. }
  139. namespace ct
  140. {
  141. LightProbeVolume::LightProbeVolume(const UnorderedMap<UINT32, bs::LightProbeVolume::ProbeInfo>& probes)
  142. {
  143. UINT32 probeIdx = 0;
  144. for(auto& entry : probes)
  145. {
  146. mProbeMap[entry.first] = probeIdx;
  147. mProbePositions[probeIdx] = entry.second.position;
  148. LightProbeInfo probeInfo;
  149. probeInfo.flags = LightProbeFlags::Dirty;
  150. probeInfo.bufferIdx = -1;
  151. mProbeInfos[probeIdx] = probeInfo;
  152. probeIdx++;
  153. }
  154. }
  155. LightProbeVolume::~LightProbeVolume()
  156. {
  157. gRenderer()->notifyLightProbeVolumeRemoved(this);
  158. }
  159. void LightProbeVolume::initialize()
  160. {
  161. gRenderer()->notifyLightProbeVolumeAdded(this);
  162. CoreObject::initialize();
  163. }
  164. void LightProbeVolume::syncToCore(const CoreSyncData& data)
  165. {
  166. char* dataPtr = (char*)data.getBuffer();
  167. bool oldIsActive = mIsActive;
  168. dataPtr = rttiReadElem(mPosition, dataPtr);
  169. dataPtr = rttiReadElem(mRotation, dataPtr);
  170. dataPtr = rttiReadElem(mIsActive, dataPtr);
  171. UINT32 numDirtyProbes, numRemovedProbes;
  172. dataPtr = rttiReadElem(numDirtyProbes, dataPtr);
  173. dataPtr = rttiReadElem(numRemovedProbes, dataPtr);
  174. for (UINT32 i = 0; i < numDirtyProbes; ++i)
  175. {
  176. UINT32 idx;
  177. dataPtr = rttiReadElem(idx, dataPtr);
  178. Vector3 position;
  179. dataPtr = rttiReadElem(position, dataPtr);
  180. LightProbeFlags flags;
  181. dataPtr = rttiReadElem(flags, dataPtr);
  182. auto iterFind = mProbeMap.find(idx);
  183. if(iterFind != mProbeMap.end())
  184. {
  185. UINT32 compactIdx = iterFind->second;
  186. mProbeInfos[compactIdx].flags = LightProbeFlags::Dirty;
  187. mProbePositions[compactIdx] = position;
  188. }
  189. else
  190. {
  191. UINT32 compactIdx = (UINT32)mProbeInfos.size();
  192. LightProbeInfo info;
  193. info.flags = LightProbeFlags::Dirty;
  194. info.bufferIdx = -1;
  195. mProbeInfos.push_back(info);
  196. mProbePositions.push_back(position);
  197. mProbeMap[idx] = compactIdx;
  198. }
  199. }
  200. for (UINT32 i = 0; i < numRemovedProbes; ++i)
  201. {
  202. UINT32 idx;
  203. dataPtr = rttiReadElem(idx, dataPtr);
  204. auto iterFind = mProbeMap.find(idx);
  205. if(iterFind != mProbeMap.end())
  206. {
  207. UINT32 compactIdx = iterFind->second;
  208. LightProbeInfo& info = mProbeInfos[compactIdx];
  209. info.flags = LightProbeFlags::Removed;
  210. info.nextEmptyIdx = mNextFreeIdx;
  211. mProbeMap.erase(iterFind);
  212. mNextFreeIdx = compactIdx;
  213. }
  214. }
  215. if (oldIsActive != mIsActive)
  216. {
  217. if (mIsActive)
  218. gRenderer()->notifyLightProbeVolumeAdded(this);
  219. else
  220. gRenderer()->notifyLightProbeVolumeRemoved(this);
  221. }
  222. else
  223. {
  224. if(mIsActive)
  225. gRenderer()->notifyLightProbeVolumeUpdated(this);
  226. }
  227. }
  228. }}