BsLightProbeVolumeRTTI.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsRTTIType.h"
  6. #include "BsLightProbeVolume.h"
  7. #include "BsRenderer.h"
  8. #include "BsCoreThread.h"
  9. #include "BsTextureRTTI.h"
  10. namespace bs
  11. {
  12. /** @cond RTTI */
  13. /** @addtogroup RTTI-Impl-Engine
  14. * @{
  15. */
  16. BS_ALLOW_MEMCPY_SERIALIZATION(LightProbeSHCoefficients)
  17. /** Serializable information about a single light probe. */
  18. struct SavedLightProbeInfo
  19. {
  20. Vector<Vector3> positions;
  21. Vector<LightProbeSHCoefficients> coefficients;
  22. };
  23. template<> struct RTTIPlainType<SavedLightProbeInfo>
  24. {
  25. enum { id = TID_SavedLightProbeInfo }; enum { hasDynamicSize = 1 };
  26. static void toMemory(const SavedLightProbeInfo& data, char* memory)
  27. {
  28. UINT32 size = getDynamicSize(data);
  29. UINT32 curSize = sizeof(UINT32);
  30. memcpy(memory, &size, curSize);
  31. memory += curSize;
  32. UINT32 version = 0;
  33. memory = rttiWriteElem(version, memory);
  34. memory = rttiWriteElem(data.positions, memory);
  35. memory = rttiWriteElem(data.coefficients, memory);
  36. }
  37. static UINT32 fromMemory(SavedLightProbeInfo& data, char* memory)
  38. {
  39. UINT32 size;
  40. memcpy(&size, memory, sizeof(UINT32));
  41. memory += sizeof(UINT32);
  42. UINT32 version;
  43. memory = rttiReadElem(version, memory);
  44. switch(version)
  45. {
  46. case 0:
  47. rttiReadElem(data.positions, memory);
  48. rttiReadElem(data.coefficients, memory);
  49. break;
  50. default:
  51. LOGERR("Unknown version of SavedLightProbeInfo data. Unable to deserialize.");
  52. break;
  53. }
  54. return size;
  55. }
  56. static UINT32 getDynamicSize(const SavedLightProbeInfo& data)
  57. {
  58. UINT64 dataSize = rttiGetElemSize(data.positions) + rttiGetElemSize(data.coefficients) + sizeof(UINT32) * 2;
  59. #if BS_DEBUG_MODE
  60. if(dataSize > std::numeric_limits<UINT32>::max())
  61. {
  62. BS_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
  63. }
  64. #endif
  65. return (UINT32)dataSize;
  66. }
  67. };
  68. class BS_CORE_EXPORT LightProbeVolumeRTTI : public RTTIType <LightProbeVolume, IReflectable, LightProbeVolumeRTTI>
  69. {
  70. private:
  71. BS_BEGIN_RTTI_MEMBERS
  72. BS_RTTI_MEMBER_PLAIN(mPosition, 0)
  73. BS_RTTI_MEMBER_PLAIN(mRotation, 1)
  74. BS_RTTI_MEMBER_PLAIN(mVolume, 3)
  75. BS_RTTI_MEMBER_PLAIN(mCellCount, 4)
  76. BS_END_RTTI_MEMBERS
  77. SavedLightProbeInfo& getProbeInfo(LightProbeVolume* obj)
  78. {
  79. obj->updateCoefficients();
  80. UINT32 numProbes = (UINT32)obj->mProbes.size();
  81. SavedLightProbeInfo savedLightProbeInfo;
  82. savedLightProbeInfo.coefficients.resize(numProbes);
  83. savedLightProbeInfo.positions.resize(numProbes);
  84. UINT32 idx = 0;
  85. for(auto& entry : obj->mProbes)
  86. {
  87. savedLightProbeInfo.positions[idx] = entry.second.position;
  88. savedLightProbeInfo.coefficients[idx] = entry.second.coefficients;
  89. idx++;
  90. }
  91. obj->mRTTIData = savedLightProbeInfo;
  92. return any_cast_ref<SavedLightProbeInfo>(obj->mRTTIData);
  93. }
  94. void setProbeInfo(LightProbeVolume* obj, SavedLightProbeInfo& data)
  95. {
  96. obj->mProbes.clear();
  97. UINT32 numProbes = (UINT32)data.positions.size();
  98. for(UINT32 i = 0; i < numProbes; ++i)
  99. {
  100. UINT32 handle = obj->mNextProbeId++;
  101. LightProbeVolume::ProbeInfo probeInfo;
  102. probeInfo.flags = LightProbeFlags::Clean;
  103. probeInfo.position = data.positions[i];
  104. probeInfo.coefficients = data.coefficients[i];
  105. obj->mProbes[handle] = probeInfo;
  106. }
  107. }
  108. public:
  109. LightProbeVolumeRTTI()
  110. :mInitMembers(this)
  111. {
  112. addPlainField("mProbeInfo", 2, &LightProbeVolumeRTTI::getProbeInfo, &LightProbeVolumeRTTI::setProbeInfo,
  113. RTTI_Flag_SkipInReferenceSearch);
  114. }
  115. void onSerializationEnded(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
  116. {
  117. // Clear temporary data
  118. LightProbeVolume* volume = static_cast<LightProbeVolume*>(obj);
  119. volume->mRTTIData = nullptr;
  120. }
  121. void onDeserializationEnded(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
  122. {
  123. // Note: Since this is a CoreObject I should call initialize() right after deserialization,
  124. // but since this specific type is used in Components we delay initialization until Component
  125. // itself does it. Keep this is mind in case this ever needs to be deserialized for non-Component
  126. // purposes (you'll need to call initialize manually).
  127. }
  128. const String& getRTTIName() override
  129. {
  130. static String name = "LightProbeVolume";
  131. return name;
  132. }
  133. UINT32 getRTTIId() override
  134. {
  135. return TID_LightProbeVolume;
  136. }
  137. SPtr<IReflectable> newRTTIObject() override
  138. {
  139. return LightProbeVolume::createEmpty();
  140. }
  141. };
  142. /** @} */
  143. /** @endcond */
  144. }