BVB Source Codes

CRYENGINE Show VolumeObjectRenderNode.cpp Source code

Return Download CRYENGINE: download VolumeObjectRenderNode.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4.  
  5. #include "VolumeObjectRenderNode.h"
  6. #include "VolumeObjectDataCreate.h"
  7. #include "MatMan.h"
  8.  
  9. #include <map>
  10.  
  11. //////////////////////////////////////////////////////////////////////////
  12. // volume data cache
  13.  
  14. class CVolumeDataCache
  15. {
  16. public:
  17.         static CVolumeDataCache& Access();
  18.  
  19. public:
  20.         ~CVolumeDataCache();
  21.  
  22.         void             AddItem(const string& name, CVolumeDataItem* pItem);
  23.         void             RemoveItem(const string& name);
  24.         CVolumeDataItem* GetItem(const string& name) const;
  25.         size_t           size() const;
  26.  
  27. private:
  28.         typedef std::map<string, CVolumeDataItem*> VolumeDataItemMap;
  29.  
  30. private:
  31.         CVolumeDataCache();
  32.  
  33. private:
  34.         VolumeDataItemMap m_cache;
  35. };
  36.  
  37. CVolumeDataCache& CVolumeDataCache::Access()
  38. {
  39.         static CVolumeDataCache s_inst;
  40.         return s_inst;
  41. }
  42.  
  43. CVolumeDataCache::CVolumeDataCache()
  44.         : m_cache()
  45. {
  46. }
  47.  
  48. CVolumeDataCache::~CVolumeDataCache()
  49. {
  50.         assert(m_cache.empty());
  51. }
  52.  
  53. void CVolumeDataCache::AddItem(const string& name, CVolumeDataItem* pItem)
  54. {
  55.         VolumeDataItemMap::iterator it(m_cache.find(name));
  56.         assert(it == m_cache.end());
  57.         if (it == m_cache.end())
  58.                 m_cache.insert(VolumeDataItemMap::value_type(name, pItem));
  59. }
  60.  
  61. void CVolumeDataCache::RemoveItem(const string& name)
  62. {
  63.         VolumeDataItemMap::iterator it(m_cache.find(name));
  64.         assert(it != m_cache.end());
  65.         if (it != m_cache.end())
  66.                 m_cache.erase(it);
  67. }
  68.  
  69. CVolumeDataItem* CVolumeDataCache::GetItem(const string& name) const
  70. {
  71.         VolumeDataItemMap::const_iterator it(m_cache.find(name));
  72.         return it != m_cache.end() ? (*it).second : 0;
  73. }
  74.  
  75. size_t CVolumeDataCache::size() const
  76. {
  77.         return m_cache.size();
  78. }
  79.  
  80. //////////////////////////////////////////////////////////////////////////
  81. // volume data item
  82.  
  83. class CVolumeDataItem
  84. {
  85. public:
  86.         static CVolumeDataItem* Create(const char* filePath, const CREVolumeObject* pVolTexFactory);
  87.  
  88. public:
  89.         void                             AddRef();
  90.         void                             Release();
  91.  
  92.         bool                             IsValid() const;
  93.         void                             AddToCache();
  94.  
  95.         const SVolumeDataSrcB*           GetData() const;
  96.         CREVolumeObject::IVolumeTexture* GetVolumeTexture() const;
  97.  
  98.         const AABB&             GetTightBounds() const;
  99.         float                   GetScale() const;
  100.  
  101.         const SVolumeDataHull*  GetHull() const;
  102.         _smart_ptr<IRenderMesh> GetHullMesh();
  103.  
  104. private:
  105.         CVolumeDataItem(const char* filePath, const CREVolumeObject* pVolTexFactory);
  106.         ~CVolumeDataItem();
  107.  
  108. private:
  109.         int                              m_refCount;
  110.         bool                             m_isValid;
  111.         bool                             m_isCached;
  112.         AABB                             m_tightBounds;
  113.         float                            m_scale;
  114.         string                           m_volDataFilePath;
  115.         SVolumeDataSrcB*                 m_pData;
  116.         CREVolumeObject::IVolumeTexture* m_pVolTex;
  117.         SVolumeDataHull*                 m_pHull;
  118.         _smart_ptr<IRenderMesh>          m_pHullMesh;
  119. };
  120.  
  121. CVolumeDataItem* CVolumeDataItem::Create(const char* filePath, const CREVolumeObject* pVolTexFactory)
  122. {
  123.         return new CVolumeDataItem(filePath, pVolTexFactory);
  124. }
  125.  
  126. CVolumeDataItem::CVolumeDataItem(const char* filePath, const CREVolumeObject* pVolTexFactory)
  127.         : m_refCount(1)
  128.         , m_isValid(false)
  129.         , m_isCached(false)
  130.         , m_tightBounds(Vec3(-1, -1, -1), Vec3(1, 1, 1))
  131.         , m_scale(1)
  132.         , m_volDataFilePath(filePath)
  133.         , m_pData(0)
  134.         , m_pVolTex(0)
  135.         , m_pHull(0)
  136.         , m_pHullMesh(0)
  137. {
  138.         if (filePath && pVolTexFactory)
  139.         {
  140.                 SVolumeDataSrcB* pData = new SVolumeDataSrcB(VOLUME_SIZE, VOLUME_SIZE, VOLUME_SIZE);
  141.                 if (pData && pData->m_pData)
  142.                 {
  143.                         if (CreateVolumeObject(m_volDataFilePath, *pData, m_tightBounds, m_scale))
  144.                         {
  145.                                 m_pVolTex = pVolTexFactory->CreateVolumeTexture();
  146.                                 if (m_pVolTex)
  147.                                         m_isValid = m_pVolTex->Create(pData->m_width, pData->m_height, pData->m_depth, pData->m_pData);
  148.  
  149.                                 m_pHull = new SVolumeDataHull();
  150.                                 if (CreateVolumeDataHull(*pData, *m_pHull))
  151.                                 {
  152.                                         m_pHullMesh = gEnv->pRenderer->CreateRenderMeshInitialized(m_pHull->m_pPts, (int) m_pHull->m_numPts, eVF_P3F_C4B_T2F,
  153.                                                                                                    m_pHull->m_pIdx, (int) m_pHull->m_numTris * 3, prtTriangleList, "VolumeObjectHull", "VolumeObjectHull");
  154.                                         m_isValid &= m_pHullMesh != 0;
  155.                                 }
  156.                                 else
  157.                                         m_isValid = false;
  158.  
  159.                                 // delete hull in sys mem if no debug drawing is needed
  160.                                 SAFE_DELETE(m_pHull);
  161.  
  162.                                 m_pData = new SVolumeDataSrcB(VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE);
  163.                                 if (m_pData && m_pData->m_pData)
  164.                                         m_isValid &= CreateDownscaledVolumeObject(*pData, *m_pData);
  165.                                 else
  166.                                         m_isValid = false;
  167.                         }
  168.                 }
  169.                 SAFE_DELETE(pData);
  170.         }
  171. }
  172.  
  173. CVolumeDataItem::~CVolumeDataItem()
  174. {
  175.         if (m_isCached)
  176.         {
  177.                 assert(CVolumeDataCache::Access().GetItem(m_volDataFilePath) == this);
  178.                 CVolumeDataCache::Access().RemoveItem(m_volDataFilePath);
  179.         }
  180.  
  181.         SAFE_DELETE(m_pData);
  182.         SAFE_RELEASE(m_pVolTex);
  183.         SAFE_DELETE(m_pHull);
  184.         m_pHullMesh = NULL;
  185. }
  186.  
  187. void CVolumeDataItem::AddRef()
  188. {
  189.         ++m_refCount;
  190. }
  191.  
  192. void CVolumeDataItem::Release()
  193. {
  194.         --m_refCount;
  195.         if (m_refCount <= 0)
  196.                 delete this;
  197. }
  198.  
  199. bool CVolumeDataItem::IsValid() const
  200. {
  201.         return m_isValid;
  202. }
  203.  
  204. void CVolumeDataItem::AddToCache()
  205. {
  206.         if (m_isValid && !m_isCached)
  207.         {
  208.                 CVolumeDataCache::Access().AddItem(m_volDataFilePath, this);
  209.                 m_isCached = true;
  210.         }
  211. }
  212.  
  213. const SVolumeDataSrcB* CVolumeDataItem::GetData() const
  214. {
  215.         return m_pData;
  216. }
  217.  
  218. CREVolumeObject::IVolumeTexture* CVolumeDataItem::GetVolumeTexture() const
  219. {
  220.         return m_pVolTex;
  221. }
  222.  
  223. const AABB& CVolumeDataItem::GetTightBounds() const
  224. {
  225.         return m_tightBounds;
  226. }
  227.  
  228. float CVolumeDataItem::GetScale() const
  229. {
  230.         return m_scale;
  231. }
  232.  
  233. const SVolumeDataHull* CVolumeDataItem::GetHull() const
  234. {
  235.         return m_pHull;
  236. }
  237.  
  238. _smart_ptr<IRenderMesh> CVolumeDataItem::GetHullMesh()
  239. {
  240.         return m_pHullMesh;
  241. }
  242.  
  243. //////////////////////////////////////////////////////////////////////////
  244. // volume shadow creator
  245.  
  246. class CVolumeShadowCreator
  247. {
  248. public:
  249.         static CVolumeShadowCreator* Create();
  250.  
  251. public:
  252.         int  AddRef();
  253.         int  Release();
  254.  
  255.         void CalculateShadows(const Vec3& newLightDir, float shadowStrength, const CVolumeDataItem* pVolSrc, CREVolumeObject::IVolumeTexture* pShadDst);
  256.  
  257. private:
  258.         CVolumeShadowCreator();
  259.         ~CVolumeShadowCreator();
  260.  
  261. private:
  262.         int              m_refCount;
  263.         SVolumeDataSrcB* m_pShad;
  264. };
  265.  
  266. CVolumeShadowCreator* CVolumeShadowCreator::Create()
  267. {
  268.         return new CVolumeShadowCreator;
  269. }
  270.  
  271. CVolumeShadowCreator::CVolumeShadowCreator()
  272.         : m_refCount(1)
  273.         , m_pShad(0)
  274. {
  275. }
  276.  
  277. CVolumeShadowCreator::~CVolumeShadowCreator()
  278. {
  279. }
  280.  
  281. int CVolumeShadowCreator::AddRef()
  282. {
  283.         ++m_refCount;
  284.         return m_refCount;
  285. }
  286.  
  287. int CVolumeShadowCreator::Release()
  288. {
  289.         --m_refCount;
  290.         int ref(m_refCount);
  291.         if (m_refCount <= 0)
  292.                 delete this;
  293.         return ref;
  294. }
  295.  
  296. void CVolumeShadowCreator::CalculateShadows(const Vec3& newLightDir, float shadowStrength, const CVolumeDataItem* pVolSrc, CREVolumeObject::IVolumeTexture* pShadDst)
  297. {
  298.         const SVolumeDataSrcB* pSrc(pVolSrc->GetData());
  299.         if (!pSrc)
  300.                 return;
  301.  
  302.         if (!m_pShad || m_pShad->m_width != pSrc->m_width || m_pShad->m_height != pSrc->m_height || m_pShad->m_depth != pSrc->m_depth)
  303.         {
  304.                 SAFE_DELETE(m_pShad);
  305.                 m_pShad = new SVolumeDataSrcB(pSrc->m_width, pSrc->m_height, pSrc->m_depth);
  306.         }
  307.  
  308.         if (m_pShad)
  309.         {
  310.                 //float t = gEnv->pTimer->GetAsyncCurTime();
  311.                 CreateVolumeShadow(newLightDir, shadowStrength, *pSrc, *m_pShad);
  312.                 //t = gEnv->pTimer->GetAsyncCurTime() - t;
  313.                 //gEnv->pLog->Log("CreateVolumeShadow(%.3f, %.3f, %.3f) took %.2fms", newLightDir.x, newLightDir.y, newLightDir.z, t * 1000.0f);
  314.                 pShadDst->Update(m_pShad->m_width, m_pShad->m_height, m_pShad->m_depth, m_pShad->m_pData);
  315.         }
  316. }
  317.  
  318. //////////////////////////////////////////////////////////////////////////
  319. // CVolumeObjectRenderNode implementation
  320.  
  321. CVolumeShadowCreator* CVolumeObjectRenderNode::ms_pVolShadowCreator(0);
  322. CVolumeObjectRenderNode::VolumeObjectSet CVolumeObjectRenderNode::ms_volumeObjects;
  323.  
  324. ICVar* CVolumeObjectRenderNode::ms_CV_volobj_stats(0);
  325. int CVolumeObjectRenderNode::e_volobj_stats(0);
  326.  
  327. void CVolumeObjectRenderNode::MoveVolumeObjects()
  328. {
  329.         for (VolumeObjectSet::iterator it(ms_volumeObjects.begin()), itEnd(ms_volumeObjects.end()); it != itEnd; ++it)
  330.                 (*it)->Move();
  331.  
  332.         //////////////////////////////////////////////////////////////////////////
  333.  
  334.         if (e_volobj_stats)
  335.         {
  336.                 CryLogAlways("#VolumeObjects = %" PRISIZE_T, ms_volumeObjects.size());
  337.                 CryLogAlways("#VolumeDataItems = %" PRISIZE_T, CVolumeDataCache::Access().size());
  338.                 e_volobj_stats = 0;
  339.         }
  340. }
  341.  
  342. void CVolumeObjectRenderNode::RegisterVolumeObject(CVolumeObjectRenderNode* p)
  343. {
  344.         VolumeObjectSet::iterator it(ms_volumeObjects.find(p));
  345.         assert(it == ms_volumeObjects.end() && "CVolumeObjectRenderNode::RegisterVolumeObject() -- Object already registered!");
  346.         if (it == ms_volumeObjects.end())
  347.                 ms_volumeObjects.insert(p);
  348. }
  349.  
  350. void CVolumeObjectRenderNode::UnregisterVolumeObject(CVolumeObjectRenderNode* p)
  351. {
  352.         VolumeObjectSet::iterator it(ms_volumeObjects.find(p));
  353.         assert(it != ms_volumeObjects.end() && "CVolumeObjectRenderNode::UnregisterVolumeObject() -- Object not registered or previously removed!");
  354.         if (it != ms_volumeObjects.end())
  355.                 ms_volumeObjects.erase(it);
  356. }
  357.  
  358. CVolumeObjectRenderNode::CVolumeObjectRenderNode()
  359.         : m_WSBBox()
  360.         , m_pos(0, 0, 0)
  361.         , m_origin(0, 0, 0)
  362.         , m_matOrig()
  363.         , m_mat()
  364.         , m_matInv()
  365.         , m_lastCachedLightDir(0, 0, 0)
  366.         , m_tightBoundsOS()
  367.         , m_moveProps()
  368.         , m_alpha(1)
  369.         , m_scale(1)
  370.         , m_shadowStrength(0.4f)
  371.         , m_pMaterial(0)
  372.         , m_pVolDataItem(0)
  373.         , m_pVolShadTex(0)
  374. {
  375.         GetInstCount(GetRenderNodeType())++;
  376.  
  377.         m_matOrig.SetIdentity();
  378.         m_mat.SetIdentity();
  379.         m_matInv.SetIdentity();
  380.  
  381.         m_WSBBox = AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1));
  382.         m_tightBoundsOS = AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1));
  383.  
  384.         m_moveProps.m_autoMove = false;
  385.         m_moveProps.m_speed = Vec3(0, 0, 0);
  386.         m_moveProps.m_spaceLoopBox = Vec3(2000.0f, 2000.0f, 2000.0f);
  387.         m_moveProps.m_fadeDistance = 0;
  388.  
  389.         for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i)
  390.         {
  391.                 m_pRE[i] = (CREVolumeObject*) GetRenderer()->EF_CreateRE(eDATA_VolumeObject);
  392.         }
  393.  
  394.         m_pMaterial = GetMatMan()->LoadMaterial("Materials/VolumeData/Default", false);
  395.  
  396.         if (!ms_pVolShadowCreator)
  397.                 ms_pVolShadowCreator = CVolumeShadowCreator::Create();
  398.         else
  399.                 ms_pVolShadowCreator->AddRef();
  400.  
  401.         RegisterVolumeObject(this);
  402.  
  403.         if (!ms_CV_volobj_stats)
  404.                 ms_CV_volobj_stats = REGISTER_CVAR(e_volobj_stats, 0, VF_NULL, "");
  405. }
  406.  
  407. CVolumeObjectRenderNode::~CVolumeObjectRenderNode()
  408. {
  409.         GetInstCount(GetRenderNodeType())--;
  410.  
  411.         if (ms_pVolShadowCreator->Release() <= 0)
  412.                 ms_pVolShadowCreator = 0;
  413.  
  414.         SAFE_RELEASE(m_pVolShadTex);
  415.         SAFE_RELEASE(m_pVolDataItem);
  416.  
  417.         for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i)
  418.         {
  419.                 if (m_pRE[i])
  420.                 {
  421.                         m_pRE[i]->Release(false);
  422.                         m_pRE[i] = 0;
  423.                 }
  424.         }
  425.  
  426.         Get3DEngine()->FreeRenderNodeState(this);
  427.  
  428.         UnregisterVolumeObject(this);
  429. }
  430.  
  431. void CVolumeObjectRenderNode::LoadVolumeData(const char* filePath)
  432. {
  433.         CREVolumeObject* pVolTextureFactory = m_pRE[0]; // ok to use first instance as function is stateless, ptr is not store in objects created below
  434.  
  435.         CVolumeDataItem* pNewVolDataItem(CVolumeDataCache::Access().GetItem(filePath));
  436.         if (pNewVolDataItem)
  437.         {
  438.                 pNewVolDataItem->AddRef();
  439.                 if (m_pVolDataItem)
  440.                         m_pVolDataItem->Release();
  441.                 m_pVolDataItem = pNewVolDataItem;
  442.                 InvalidateLastCachedLightDir();
  443.         }
  444.         else
  445.         {
  446.                 pNewVolDataItem = CVolumeDataItem::Create(filePath, pVolTextureFactory);
  447.                 if (pNewVolDataItem && pNewVolDataItem->IsValid())
  448.                 {
  449.                         pNewVolDataItem->AddToCache();
  450.                         if (m_pVolDataItem)
  451.                                 m_pVolDataItem->Release();
  452.                         m_pVolDataItem = pNewVolDataItem;
  453.                         InvalidateLastCachedLightDir();
  454.                 }
  455.                 else
  456.                         SAFE_RELEASE(pNewVolDataItem);
  457.         }
  458.  
  459.         SetMatrix(m_matOrig);
  460.  
  461.         if (m_pVolDataItem && pVolTextureFactory && !m_pVolShadTex)
  462.         {
  463.                 m_pVolShadTex = pVolTextureFactory->CreateVolumeTexture();
  464.                 if (!m_pVolShadTex->Create(VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE, 0))
  465.                 {
  466.                         SAFE_RELEASE(m_pVolShadTex);
  467.                 }
  468.         }
  469. }
  470.  
  471. void CVolumeObjectRenderNode::SetProperties(const SVolumeObjectProperties& properties)
  472. {
  473. }
  474.  
  475. void CVolumeObjectRenderNode::SetMovementProperties(const SVolumeObjectMovementProperties& properties)
  476. {
  477.         m_moveProps = properties;
  478. }
  479.  
  480. void CVolumeObjectRenderNode::SetMatrix(const Matrix34& mat)
  481. {
  482.         m_matOrig = mat;
  483.         float initialScale(m_pVolDataItem ? m_pVolDataItem->GetScale() : 1);
  484.         SetMatrixInternal(mat * Matrix33::CreateScale(Vec3(initialScale)), true);
  485. }
  486.  
  487. void CVolumeObjectRenderNode::SetMatrixInternal(const Matrix34& mat, bool updateOrigin)
  488. {
  489.         Get3DEngine()->UnRegisterEntityAsJob(this);
  490.  
  491.         if (updateOrigin)
  492.                 m_origin = mat.GetTranslation();
  493.  
  494.         m_pos = mat.GetTranslation();
  495.         m_mat = mat;
  496.         m_matInv = mat.GetInverted();
  497.  
  498.         m_tightBoundsOS = m_pVolDataItem ? m_pVolDataItem->GetTightBounds() : AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1));
  499.         m_WSBBox.SetTransformedAABB(m_mat, m_tightBoundsOS);
  500.  
  501.         Vec3 scale(m_mat.GetColumn(0).GetLength(), m_mat.GetColumn(1).GetLength(), m_mat.GetColumn(2).GetLength());
  502.         assert(fabsf(scale.x - scale.y) < 1e-4f && fabsf(scale.x - scale.z) < 1e-4f && fabsf(scale.y - scale.z) < 1e-4f);
  503.         m_scale = max(max(scale.x, scale.y), scale.z);
  504.  
  505.         Get3DEngine()->RegisterEntity(this);
  506. }
  507.  
  508. const char* CVolumeObjectRenderNode::GetEntityClassName() const
  509. {
  510.         return "VolumeObject";
  511. }
  512.  
  513. const char* CVolumeObjectRenderNode::GetName() const
  514. {
  515.         return "VolumeObject";
  516. }
  517.  
  518. bool CVolumeObjectRenderNode::IsViewerInsideVolume(const SRenderingPassInfo& passInfo) const
  519. {
  520.         const CCamera& cam(passInfo.GetCamera());
  521.         Vec3 camPosOS(m_matInv.TransformPoint(cam.GetPosition()));
  522.         const Vec3& scale(m_tightBoundsOS.max);
  523.         return fabsf(camPosOS.x) < scale.x && fabsf(camPosOS.y) < scale.y && fabsf(camPosOS.z) < scale.z;
  524. }
  525.  
  526. bool CVolumeObjectRenderNode::NearPlaneIntersectsVolume(const SRenderingPassInfo& passInfo) const
  527. {
  528.         const CCamera& cam = passInfo.GetCamera();
  529.  
  530.         // check if bounding box intersects the near clipping plane
  531.         const Plane* pNearPlane(cam.GetFrustumPlane(FR_PLANE_NEAR));
  532.         Vec3 pntOnNearPlane(cam.GetPosition() - pNearPlane->DistFromPlane(cam.GetPosition()) * pNearPlane->n);
  533.         Vec3 pntOnNearPlaneOS(m_matInv.TransformPoint(pntOnNearPlane));
  534.  
  535.         Vec3 nearPlaneOS_n(m_matInv.TransformVector(pNearPlane->n) /*.GetNormalized()*/);
  536.         f32 nearPlaneOS_d(-nearPlaneOS_n.Dot(pntOnNearPlaneOS));
  537.  
  538.         // get extreme lengths
  539.         float t(fabsf(nearPlaneOS_n.x * m_tightBoundsOS.max.x) + fabsf(nearPlaneOS_n.y * m_tightBoundsOS.max.y) + fabsf(nearPlaneOS_n.z * m_tightBoundsOS.max.z));
  540.         //float t(0.0f);
  541.         //if(nearPlaneOS_n.x >= 0) t += -nearPlaneOS_n.x; else t += nearPlaneOS_n.x;
  542.         //if(nearPlaneOS_n.y >= 0) t += -nearPlaneOS_n.y; else t += nearPlaneOS_n.y;
  543.         //if(nearPlaneOS_n.z >= 0) t += -nearPlaneOS_n.z; else t += nearPlaneOS_n.z;
  544.  
  545.         float t0(t + nearPlaneOS_d);
  546.         float t1(-t + nearPlaneOS_d);
  547.  
  548.         return t0 * t1 < 0.0f;
  549. }
  550.  
  551. void CVolumeObjectRenderNode::InvalidateLastCachedLightDir()
  552. {
  553.         m_lastCachedLightDir = Vec3(0, 0, 0);
  554. }
  555.  
  556. void CVolumeObjectRenderNode::UpdateShadows()
  557. {
  558.         Vec3 newLightDir(m_p3DEngine->GetSunDirNormalized());
  559.  
  560.         float shadowStrength(GetFloatCVar(e_VolObjShadowStrength));
  561.         if (ms_pVolShadowCreator)
  562.         {
  563.                 Vec3 newLightDirLS(m_matInv.TransformVector(newLightDir).GetNormalized()); // 0.999f = 1.56 deg = ??? minutes of TOD update, TODO: make adjustable
  564.                 if (m_shadowStrength != shadowStrength || newLightDirLS.Dot(m_lastCachedLightDir) < 0.999f)
  565.                 {
  566.                         ms_pVolShadowCreator->CalculateShadows(-newLightDirLS, shadowStrength, m_pVolDataItem, m_pVolShadTex);
  567.                         m_lastCachedLightDir = newLightDirLS;
  568.                         m_shadowStrength = shadowStrength;
  569.                 }
  570.         }
  571. }
  572.  
  573. Plane CVolumeObjectRenderNode::GetVolumeTraceStartPlane(bool viewerInsideVolume, const SRenderingPassInfo& passInfo) const
  574. {
  575.         const CCamera& cam(passInfo.GetCamera());
  576.         Vec3 vdir(cam.GetViewdir());
  577.         Vec3 vpos(cam.GetPosition());
  578.  
  579.         if (!viewerInsideVolume)
  580.         {
  581.                 const Vec3 bbp[8] =
  582.                 {
  583.                         Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z),
  584.                         Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z),
  585.                         Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z),
  586.                         Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z),
  587.                         Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z),
  588.                         Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z),
  589.                         Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z),
  590.                         Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z)
  591.                 };
  592.  
  593.                 Plane viewPlane(vdir, -vdir.Dot(vpos));
  594.  
  595.                 Vec3 p(m_mat * bbp[0]);
  596.                 float d(viewPlane.DistFromPlane(p));
  597.  
  598.                 for (int i(1); i < 8; ++i)
  599.                 {
  600.                         Vec3 ptmp(m_mat * bbp[i]);
  601.                         float dtmp(viewPlane.DistFromPlane(ptmp));
  602.  
  603.                         if (dtmp < d)
  604.                         {
  605.                                 p = ptmp;
  606.                                 d = dtmp;
  607.                         }
  608.                 }
  609.  
  610.                 return Plane(vdir, -vdir.Dot(p));
  611.         }
  612.         else
  613.                 return Plane(vdir, -vdir.Dot(vpos));
  614. }
  615.  
  616. float CVolumeObjectRenderNode::GetDistanceToCamera(const SRenderingPassInfo& passInfo) const
  617. {
  618.         const Vec3 bbp[8] =
  619.         {
  620.                 m_mat* Vec3(m_tightBoundsOS.min.x,  m_tightBoundsOS.min.y, m_tightBoundsOS.min.z),
  621.                 m_mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z),
  622.                 m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z),
  623.                 m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z),
  624.                 m_mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z),
  625.                 m_mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z),
  626.                 m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z),
  627.                 m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z)
  628.         };
  629.  
  630.         const CCamera& cam(passInfo.GetCamera());
  631.         const Plane* pNearPlane(cam.GetFrustumPlane(FR_PLANE_NEAR));
  632.         const Vec3 camPos(cam.GetPosition());
  633.  
  634.         f32 distSq(0.0f);
  635.         for (int i(0); i < 8; ++i)
  636.         {
  637.                 float tmpDistSq((bbp[i] - camPos).GetLengthSquared());
  638.                 if (tmpDistSq > distSq && pNearPlane->DistFromPlane(bbp[i]) < 0.0f)
  639.                         distSq = tmpDistSq;
  640.         }
  641.  
  642.         return sqrt_tpl(distSq);
  643. }
  644.  
  645. void CVolumeObjectRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo)
  646. {
  647.         FUNCTION_PROFILER_3DENGINE;
  648.  
  649.         // anything to render?
  650.         if (passInfo.IsRecursivePass() || !m_pMaterial || !m_pVolDataItem || !m_pVolShadTex || !passInfo.RenderClouds())
  651.                 return;
  652.  
  653.         IRenderer* pRenderer(GetRenderer());
  654.  
  655.         const int fillThreadID = passInfo.ThreadID();
  656.  
  657.         // get render objects
  658.         CRenderObject* pRO = pRenderer->EF_GetObject_Temp(fillThreadID);
  659.         if (!pRO || !m_pRE[fillThreadID])
  660.                 return;
  661.  
  662.         // update shadow volume
  663.         UpdateShadows();
  664.  
  665.         // set basic render object properties
  666.         pRO->m_II.m_Matrix = m_mat;
  667.         pRO->m_ObjFlags |= FOB_TRANS_MASK;
  668.         pRO->m_fSort = 0;
  669.         pRO->m_fDistance = GetDistanceToCamera(passInfo);
  670.  
  671.         // transform camera into object space
  672.         const CCamera& cam(passInfo.GetCamera());
  673.         Vec3 viewerPosWS(cam.GetPosition());
  674.         Vec3 viewerPosOS(m_matInv * viewerPosWS);
  675.  
  676.         // set render element attributes
  677.         bool viewerInsideVolume(IsViewerInsideVolume(passInfo));
  678.         bool nearPlaneIntersectsVolume(NearPlaneIntersectsVolume(passInfo));
  679.         m_pRE[fillThreadID]->m_center = m_pos;
  680.         m_pRE[fillThreadID]->m_matInv = m_matInv;
  681.         m_pRE[fillThreadID]->m_eyePosInWS = viewerPosWS;
  682.         m_pRE[fillThreadID]->m_eyePosInOS = viewerPosOS;
  683.         m_pRE[fillThreadID]->m_volumeTraceStartPlane = GetVolumeTraceStartPlane(viewerInsideVolume, passInfo);
  684.         m_pRE[fillThreadID]->m_renderBoundsOS = m_tightBoundsOS;
  685.         m_pRE[fillThreadID]->m_pHullMesh = m_pVolDataItem->GetHullMesh();
  686.         m_pRE[fillThreadID]->m_viewerInsideVolume = viewerInsideVolume;
  687.         m_pRE[fillThreadID]->m_nearPlaneIntersectsVolume = nearPlaneIntersectsVolume;
  688.         m_pRE[fillThreadID]->m_alpha = m_alpha;
  689.         m_pRE[fillThreadID]->m_scale = m_scale;
  690.         m_pRE[fillThreadID]->m_pDensVol = m_pVolDataItem->GetVolumeTexture();
  691.         m_pRE[fillThreadID]->m_pShadVol = m_pVolShadTex;
  692.  
  693.         float mvd(GetMaxViewDist());
  694.         float d((passInfo.GetCamera().GetPosition() - m_mat.GetTranslation()).GetLength());
  695.         if (d > 0.9f * mvd)
  696.         {
  697.                 float s(clamp_tpl(1.0f - (d - 0.9f * mvd) / (0.1f * mvd), 0.0f, 1.0f));
  698.                 m_pRE[fillThreadID]->m_alpha *= s;
  699.         }
  700.  
  701.         // add to renderer
  702.         SShaderItem& shaderItem(m_pMaterial->GetShaderItem(0));
  703.         int afterWater(GetObjManager()->IsAfterWater(m_pos, passInfo.GetCamera().GetPosition(), passInfo, Get3DEngine()->GetWaterLevel()) ? 1 : 0);
  704.         pRenderer->EF_AddEf(m_pRE[fillThreadID], shaderItem, pRO, passInfo, EFSLIST_TRANSP, afterWater);
  705.  
  706. #if 0
  707.         IRenderAuxGeom* p = pRenderer->GetIRenderAuxGeom();
  708.         if (p)
  709.         {
  710.                 const Matrix34& mat = m_mat;
  711.                 Vec3 bpp[8] =
  712.                 {
  713.                         mat* Vec3(m_tightBoundsOS.min.x,  m_tightBoundsOS.min.y, m_tightBoundsOS.min.z),
  714.                         mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z),
  715.                         mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z),
  716.                         mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z),
  717.  
  718.                         mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z),
  719.                         mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z),
  720.                         mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z),
  721.                         mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z)
  722.                 };
  723.  
  724.                 p->SetRenderFlags(e_Def3DPublicRenderflags);
  725.  
  726.                 p->DrawLine(bpp[0], ColorB(255, 0, 0, 255), bpp[1], ColorB(255, 0, 0, 255));
  727.                 p->DrawLine(bpp[1], ColorB(255, 0, 0, 255), bpp[2], ColorB(255, 0, 0, 255));
  728.                 p->DrawLine(bpp[2], ColorB(255, 0, 0, 255), bpp[3], ColorB(255, 0, 0, 255));
  729.                 p->DrawLine(bpp[3], ColorB(255, 0, 0, 255), bpp[0], ColorB(255, 0, 0, 255));
  730.  
  731.                 p->DrawLine(bpp[4], ColorB(255, 0, 0, 255), bpp[5], ColorB(255, 0, 0, 255));
  732.                 p->DrawLine(bpp[5], ColorB(255, 0, 0, 255), bpp[6], ColorB(255, 0, 0, 255));
  733.                 p->DrawLine(bpp[6], ColorB(255, 0, 0, 255), bpp[7], ColorB(255, 0, 0, 255));
  734.                 p->DrawLine(bpp[7], ColorB(255, 0, 0, 255), bpp[4], ColorB(255, 0, 0, 255));
  735.  
  736.                 p->DrawLine(bpp[0], ColorB(255, 0, 0, 255), bpp[4], ColorB(255, 0, 0, 255));
  737.                 p->DrawLine(bpp[1], ColorB(255, 0, 0, 255), bpp[5], ColorB(255, 0, 0, 255));
  738.                 p->DrawLine(bpp[2], ColorB(255, 0, 0, 255), bpp[6], ColorB(255, 0, 0, 255));
  739.                 p->DrawLine(bpp[3], ColorB(255, 0, 0, 255), bpp[7], ColorB(255, 0, 0, 255));
  740.  
  741.                 const SVolumeDataHull* pHull(m_pVolDataItem->GetHull());
  742.                 if (pHull)
  743.                 {
  744.                         for (size_t i = 0; i < pHull->m_numTris; ++i)
  745.                                 p->DrawTriangle(mat * pHull->m_pPts[pHull->m_pIdx[i * 3]].xyz, ColorB(255, 0, 255, 255),
  746.                                                 mat * pHull->m_pPts[pHull->m_pIdx[i * 3 + 1]].xyz, ColorB(255, 0, 255, 255),
  747.                                                 mat * pHull->m_pPts[pHull->m_pIdx[i * 3 + 2]].xyz, ColorB(255, 0, 255, 255));
  748.                 }
  749.         }
  750. #endif
  751. }
  752.  
  753. IPhysicalEntity* CVolumeObjectRenderNode::GetPhysics() const
  754. {
  755.         return 0;
  756. }
  757.  
  758. void CVolumeObjectRenderNode::SetPhysics(IPhysicalEntity*)
  759. {
  760. }
  761.  
  762. void CVolumeObjectRenderNode::SetMaterial(IMaterial* pMat)
  763. {
  764.         m_pMaterial = pMat;
  765. }
  766.  
  767. void CVolumeObjectRenderNode::Precache()
  768. {
  769. }
  770.  
  771. void CVolumeObjectRenderNode::GetMemoryUsage(ICrySizer* pSizer) const
  772. {
  773.         SIZER_COMPONENT_NAME(pSizer, "VolumeObjectRenderNode");
  774.         pSizer->AddObject(this, sizeof(*this));
  775. }
  776.  
  777. void CVolumeObjectRenderNode::Move()
  778. {
  779.         FUNCTION_PROFILER_3DENGINE;
  780.  
  781.         m_alpha = 1;
  782.  
  783.         Vec3 pos(m_mat.GetTranslation());
  784.  
  785.         ITimer* pTimer(gEnv->pTimer);
  786.         if (m_moveProps.m_autoMove)
  787.         {
  788.                 // update position
  789.                 float deltaTime = pTimer->GetFrameTime();
  790.  
  791.                 assert(deltaTime >= 0);
  792.  
  793.                 pos += deltaTime * m_moveProps.m_speed;
  794.  
  795.                 // constrain movement to specified loop box
  796.                 Vec3 loopBoxMin(m_origin - m_moveProps.m_spaceLoopBox);
  797.                 Vec3 loopBoxMax(m_origin + m_moveProps.m_spaceLoopBox);
  798.  
  799.                 if (pos.x < loopBoxMin.x)
  800.                         pos.x = loopBoxMax.x;
  801.                 if (pos.y < loopBoxMin.y)
  802.                         pos.y = loopBoxMax.y;
  803.                 if (pos.z < loopBoxMin.z)
  804.                         pos.z = loopBoxMax.z;
  805.  
  806.                 if (pos.x > loopBoxMax.x)
  807.                         pos.x = loopBoxMin.x;
  808.                 if (pos.y > loopBoxMax.y)
  809.                         pos.y = loopBoxMin.y;
  810.                 if (pos.z > loopBoxMax.z)
  811.                         pos.z = loopBoxMin.z;
  812.  
  813.                 // set new position
  814.                 Matrix34 mat(m_mat);
  815.                 mat.SetTranslation(pos);
  816.                 SetMatrixInternal(mat, false);
  817.  
  818.                 // fade out clouds at the borders of the loop box
  819.                 if (m_moveProps.m_fadeDistance > 0)
  820.                 {
  821.                         Vec3 fade(max(m_moveProps.m_spaceLoopBox.x, m_moveProps.m_fadeDistance),
  822.                                   max(m_moveProps.m_spaceLoopBox.y, m_moveProps.m_fadeDistance),
  823.                                   max(m_moveProps.m_spaceLoopBox.z, m_moveProps.m_fadeDistance));
  824.  
  825.                         fade -= Vec3(fabs(pos.x - m_origin.x), fabs(pos.y - m_origin.y), fabs(pos.z - m_origin.z));
  826.  
  827.                         m_alpha = clamp_tpl(min(min(fade.x, fade.y), fade.z) / m_moveProps.m_fadeDistance, 0.0f, 1.0f);
  828.                 }
  829.         }
  830.         else
  831.         {
  832.                 if ((m_origin - pos).GetLengthSquared() > 1e-4f)
  833.                 {
  834.                         Matrix34 mat(m_mat);
  835.                         mat.SetTranslation(m_origin);
  836.                         SetMatrixInternal(mat, false);
  837.                 }
  838.         }
  839. }
  840.  
  841. void CVolumeObjectRenderNode::OffsetPosition(const Vec3& delta)
  842. {
  843.         if (m_pTempData) m_pTempData->OffsetPosition(delta);
  844.         m_WSBBox.Move(delta);
  845.         m_pos += delta;
  846.         m_origin += delta;
  847.         m_matOrig.SetTranslation(m_matOrig.GetTranslation() + delta);
  848.         m_mat.SetTranslation(m_mat.GetTranslation() + delta);
  849.         m_matInv = m_mat.GetInverted();
  850. }
  851.  
  852. void CVolumeObjectRenderNode::FillBBox(AABB& aabb)
  853. {
  854.         aabb = CVolumeObjectRenderNode::GetBBox();
  855. }
  856.  
  857. EERType CVolumeObjectRenderNode::GetRenderNodeType()
  858. {
  859.         return eERType_VolumeObject;
  860. }
  861.  
  862. float CVolumeObjectRenderNode::GetMaxViewDist()
  863. {
  864.         if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
  865.                 return max(GetCVars()->e_ViewDistMin, CVolumeObjectRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatioDetail * GetViewDistRatioNormilized());
  866.  
  867.         return max(GetCVars()->e_ViewDistMin, CVolumeObjectRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistRatioNormilized());
  868. }
  869.  
  870. Vec3 CVolumeObjectRenderNode::GetPos(bool bWorldOnly) const
  871. {
  872.         return m_pos;
  873. }
  874.  
  875. IMaterial* CVolumeObjectRenderNode::GetMaterial(Vec3* pHitPos) const
  876. {
  877.         return m_pMaterial;
  878. }
  879.  
downloadVolumeObjectRenderNode.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top