BVB Source Codes

CRYENGINE Show WaterWaveRenderNode.cpp Source code

Return Download CRYENGINE: download WaterWaveRenderNode.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // ------------------------------------------------------------------------
  4. //  File name:   WaterWavesRenderNode.cpp
  5. //  Version:     v1.00
  6. //  Created:     20/09/2005 by Tiago Sousa.
  7. //  Compilers:   Visual Studio.NET 2003
  8. //  Description: Draws/Creates waves in the world
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. //  Todo:
  13. //   - physicalization / lod
  14. //
  15. ////////////////////////////////////////////////////////////////////////////
  16.  
  17. #include "StdAfx.h"
  18. #include "WaterWaveRenderNode.h"
  19. #include "VisAreas.h"
  20. #include "MatMan.h"
  21. #include <Cry3DEngine/IIndexedMesh.h>
  22. #include <CryMath/Cry_Geo.h>
  23.  
  24. #define MAX_WAVE_DIST_UPDATE 5000.0f
  25.  
  26. namespace
  27. {
  28. // Some wave utilities
  29.  
  30. Vec3 VecMin(const Vec3& v1, const Vec3& v2)
  31. {
  32.         return Vec3(std::min(v1.x, v2.x), std::min(v1.y, v2.y), std::min(v1.z, v2.z));
  33. }
  34.  
  35. Vec3 VecMax(const Vec3& v1, const Vec3& v2)
  36. {
  37.         return Vec3(std::max(v1.x, v2.x), std::max(v1.y, v2.y), std::max(v1.z, v2.z));
  38. }
  39.  
  40. float sfrand()
  41. {
  42.         return cry_random(-1.0f, 1.0f);
  43. }
  44.  
  45. };
  46.  
  47. //////////////////////////////////////////////////////////////////////////
  48. CWaterWaveRenderNode::CWaterWaveRenderNode() :
  49.         m_nID(~0),
  50.         m_pMaterial(0),
  51.         m_pRenderMesh(0),
  52.         m_pMin(ZERO),
  53.         m_pMax(ZERO),
  54.         m_pSerializeParams(0),
  55.         m_pOrigPos(ZERO),
  56.         m_fWaveKey(-1.0f)
  57. {
  58.         GetInstCount(GetRenderNodeType())++;
  59.  
  60.         memset(m_fRECustomData, 0, sizeof(m_fRECustomData));
  61.         m_fCurrTerrainDepth = 0;
  62.  
  63.         // put default material on
  64.         m_pMaterial = GetMatMan()->LoadMaterial("Materials/Ocean/water_wave", false);
  65. }
  66.  
  67. //////////////////////////////////////////////////////////////////////////
  68. CWaterWaveRenderNode::~CWaterWaveRenderNode()
  69. {
  70.         GetInstCount(GetRenderNodeType())--;
  71.  
  72.         SAFE_DELETE(m_pSerializeParams);
  73.  
  74.         GetWaterWaveManager()->Unregister(this);
  75.  
  76.         Get3DEngine()->FreeRenderNodeState(this);
  77. }
  78.  
  79. //////////////////////////////////////////////////////////////////////////
  80. void CWaterWaveRenderNode::ComputeMinMax(const Vec3* pVertices, unsigned int nVertexCount)
  81. {
  82.  
  83.         m_fWaveKey = 0.0f;
  84.         m_pMin = Vec3(0);
  85.         m_pMax = Vec3(0);
  86.  
  87.         Matrix34 pInvWorldTM(m_pWorldTM);
  88.         pInvWorldTM.Invert();
  89.  
  90.         // Each sector has 4 vertices
  91.         for (uint32 i(0); i < nVertexCount; i += 4)
  92.         {
  93.                 // Set edges (in object space)
  94.                 Vec3 p0(pVertices[i + 0]);
  95.                 p0 = pInvWorldTM.TransformPoint(p0);
  96.  
  97.                 Vec3 p1(pVertices[i + 1]);
  98.                 p1 = pInvWorldTM.TransformPoint(p1);
  99.  
  100.                 Vec3 p2(pVertices[i + 2]);
  101.                 p2 = pInvWorldTM.TransformPoint(p2);
  102.  
  103.                 Vec3 p3(pVertices[i + 3]);
  104.                 p3 = pInvWorldTM.TransformPoint(p3);
  105.  
  106.                 const float fKeyMultiplier = 1000.0f / 3.0f;
  107.  
  108.                 // Compute wave key, for faster instantiation
  109.                 m_fWaveKey += ceilf((p0.x + p0.y + p0.z) * fKeyMultiplier);
  110.                 m_fWaveKey += ceilf((p1.x + p1.y + p1.z) * fKeyMultiplier);
  111.                 m_fWaveKey += ceilf((p2.x + p2.y + p2.z) * fKeyMultiplier);
  112.                 m_fWaveKey += ceilf((p3.x + p3.y + p3.z) * fKeyMultiplier);
  113.  
  114.                 // Store min/max (for faster bounding box computation)
  115.  
  116.                 // Get min/max
  117.                 m_pMin = VecMin(m_pMin, p0);
  118.                 m_pMax = VecMax(m_pMax, p0);
  119.                 m_pMin = VecMin(m_pMin, p1);
  120.                 m_pMax = VecMax(m_pMax, p1);
  121.                 m_pMin = VecMin(m_pMin, p2);
  122.                 m_pMax = VecMax(m_pMax, p2);
  123.                 m_pMin = VecMin(m_pMin, p3);
  124.                 m_pMax = VecMax(m_pMax, p3);
  125.         }
  126.  
  127.         const int nSectors = nVertexCount / 4;
  128.         m_fWaveKey /= (float) nSectors;
  129.  
  130.         // Update bounding info
  131.         UpdateBoundingBox();
  132.  
  133. }
  134.  
  135. //////////////////////////////////////////////////////////////////////////
  136. void CWaterWaveRenderNode::UpdateBoundingBox()
  137. {
  138.  
  139.         m_WSBBox.max = m_pMax;
  140.         m_WSBBox.min = m_pMin;
  141.  
  142.         // Transform back to world space
  143.         m_WSBBox.SetTransformedAABB(m_pWorldTM, m_WSBBox);
  144.  
  145.         m_pParams.m_pPos = m_WSBBox.GetCenter();
  146.  
  147. }
  148.  
  149. //////////////////////////////////////////////////////////////////////////
  150. void CWaterWaveRenderNode::Create(uint64 nID, const Vec3* pVertices, unsigned int nVertexCount, const Vec2& pUVScale, const Matrix34& pWorldTM)
  151. {
  152.  
  153.         if (nVertexCount < 4)
  154.         {
  155.                 return;
  156.         }
  157.  
  158.         // Copy serialization parameters
  159.         CopySerializationParams(nID, pVertices, nVertexCount, pUVScale, pWorldTM);
  160.  
  161.         m_nID = nID;
  162.         m_pWorldTM = pWorldTM;
  163.  
  164.         // Remove form 3d engine
  165.         GetWaterWaveManager()->Unregister(this);
  166.         Get3DEngine()->UnRegisterEntityAsJob(this);
  167.  
  168.         // Get min/max boundings
  169.         ComputeMinMax(pVertices, nVertexCount);
  170.  
  171.         // Store original position
  172.         m_pOrigPos = m_pWorldTM.GetTranslation();
  173.  
  174.         // Add to 3d engine
  175.         GetWaterWaveManager()->Register(this);
  176.         Get3DEngine()->RegisterEntity(this);
  177.  
  178. }
  179.  
  180. //////////////////////////////////////////////////////////////////////////
  181. void CWaterWaveRenderNode::CopySerializationParams(uint64 nID, const Vec3* pVertices, unsigned int nVertexCount, const Vec2& pUVScale, const Matrix34& pWorldTM)
  182. {
  183.  
  184.         SAFE_DELETE(m_pSerializeParams);
  185.  
  186.         m_pSerializeParams = new SWaterWaveSerialize;
  187.  
  188.         m_pSerializeParams->m_nID = nID;
  189.         m_pSerializeParams->m_pMaterial = m_pMaterial;
  190.  
  191.         m_pSerializeParams->m_fUScale = pUVScale.x;
  192.         m_pSerializeParams->m_fVScale = pUVScale.y;
  193.  
  194.         m_pSerializeParams->m_nVertexCount = nVertexCount;
  195.  
  196.         // Copy vertices
  197.         m_pSerializeParams->m_pVertices.resize(nVertexCount);
  198.         for (uint32 v(0); v < nVertexCount; ++v)
  199.         {
  200.                 m_pSerializeParams->m_pVertices[v] = pVertices[v];
  201.         }
  202.  
  203.         m_pSerializeParams->m_pWorldTM = pWorldTM;
  204.  
  205.         m_pSerializeParams->m_pParams = m_pParams;
  206.  
  207. }
  208.  
  209. //////////////////////////////////////////////////////////////////////////
  210. void CWaterWaveRenderNode::SetParams(const SWaterWaveParams& pParams)
  211. {
  212.         m_pParams = pParams;
  213. }
  214.  
  215. //////////////////////////////////////////////////////////////////////////
  216. const SWaterWaveParams& CWaterWaveRenderNode::GetParams() const
  217. {
  218.         return m_pParams;
  219. }
  220.  
  221. //////////////////////////////////////////////////////////////////////////
  222. const char* CWaterWaveRenderNode::GetEntityClassName() const
  223. {
  224.         return "CWaterWaveRenderNode";
  225. }
  226.  
  227. //////////////////////////////////////////////////////////////////////////
  228. const char* CWaterWaveRenderNode::GetName() const
  229. {
  230.         return "WaterWave";
  231. }
  232.  
  233. //////////////////////////////////////////////////////////////////////////
  234. void CWaterWaveRenderNode::Spawn()
  235. {
  236.  
  237.         m_pWorldTM.SetTranslation(m_pOrigPos + Vec3(sfrand(), sfrand(), sfrand()) * m_pParams.m_fPosVar);
  238.         m_pParams.m_fCurrLifetime = max(m_pParams.m_fLifetime + m_pParams.m_fLifetimeVar * sfrand(), 0.5f);
  239.         m_pParams.m_fCurrSpeed = max(m_pParams.m_fSpeed + m_pParams.m_fSpeedVar * sfrand(), 1.0f);
  240.         m_pParams.m_fCurrHeight = max(m_pParams.m_fHeight + m_pParams.m_fHeightVar * sfrand(), 0.0f);
  241.         m_pParams.m_fCurrFrameLifetime = m_pParams.m_fCurrLifetime;
  242.  
  243. }
  244.  
  245. //////////////////////////////////////////////////////////////////////////
  246. void CWaterWaveRenderNode::Update(float fDistanceToCamera)
  247. {
  248.  
  249.         // Check distance to terrain
  250.         Vec3 pCenterPos = m_pParams.m_pPos;
  251.         float fTerrainZ(GetTerrain()->GetZApr(pCenterPos.x, pCenterPos.y, m_nSID));
  252.         m_fCurrTerrainDepth = max(pCenterPos.z - fTerrainZ, 0.0f);
  253.  
  254.         float fDepthAttenuation = clamp_tpl<float>(m_fCurrTerrainDepth * 0.2f, 0.0f, 1.0f);
  255.  
  256.         // Slide wave along transformation orientation
  257.  
  258.         Vec3 pDirection(m_pWorldTM.GetColumn1());
  259.         Vec3 pPos(m_pWorldTM.GetTranslation());
  260.  
  261.         float fDelta(m_pParams.m_fCurrSpeed * GetTimer()->GetFrameTime());
  262.         pPos += pDirection * fDelta * fDepthAttenuation;
  263.  
  264.         // Always set Z to water level
  265.         float fWaterLevel(Get3DEngine()->GetWaterLevel());
  266.         pPos.z = fWaterLevel - 0.5f;
  267.  
  268.         // Update position and bounding box
  269.  
  270.         m_pWorldTM.SetTranslation(pPos);
  271.         UpdateBoundingBox();
  272.  
  273.         // Update lifetime
  274.         m_pParams.m_fCurrFrameLifetime -= GetTimer()->GetFrameTime();
  275.  
  276.         // Spawn new wave
  277.         if (m_pParams.m_fCurrFrameLifetime <= 0.0f || m_fCurrTerrainDepth == 0.0f)
  278.                 Spawn();
  279.  
  280.         //////////////////////////////////////////////////////////////////////////////////////////////////
  281.         // Set custom render data
  282.         m_fRECustomData[8] = clamp_tpl<float>(m_pParams.m_fCurrFrameLifetime, 0.0f, 1.0f);
  283.         m_fRECustomData[8] *= m_fRECustomData[8] * (3.0f - 2.0f * m_fRECustomData[8]);
  284.  
  285.         m_fRECustomData[9] = clamp_tpl<float>(m_pParams.m_fCurrFrameLifetime / m_pParams.m_fCurrLifetime, 0.0f, 1.0f);
  286.  
  287.         m_fRECustomData[10] = min(m_fCurrTerrainDepth, 1.0f);
  288.         m_fRECustomData[11] = min(1.0f, 1.0f - (fDistanceToCamera / GetMaxViewDist()));
  289.         m_fRECustomData[12] = m_pParams.m_fCurrHeight * (fDepthAttenuation);
  290.  
  291. }
  292.  
  293. //////////////////////////////////////////////////////////////////////////
  294. void CWaterWaveRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo)
  295. {
  296.         FUNCTION_PROFILER_3DENGINE;
  297.  
  298.         if (m_pRenderMesh == 0)
  299.                 return; //  false;
  300.  
  301.         if (!m_pMaterial || !passInfo.RenderWaterWaves() || !passInfo.RenderWaterOcean())
  302.                 return; // false;
  303.  
  304.         C3DEngine* p3DEngine(Get3DEngine());
  305.         IRenderer* pRenderer(GetRenderer());
  306.  
  307.         // get render objects
  308.         CRenderObject* pRenderObj(pRenderer->EF_GetObject_Temp(passInfo.ThreadID()));
  309.         if (!pRenderObj)
  310.                 return; // false;
  311.  
  312.         float fWaterLevel(Get3DEngine()->GetWaterLevel());
  313.         Vec3 pCamPos(passInfo.GetCamera().GetPosition());
  314.  
  315.         // don't render if bellow water level
  316.         if (max((pCamPos.z - fWaterLevel) * 100.0f, 0.0f) == 0.0f)
  317.                 return; //false;
  318.  
  319.         // Fill in data for render object
  320.  
  321.         pRenderObj->m_II.m_Matrix = m_pWorldTM;
  322.         pRenderObj->m_fSort = 0;
  323.         pRenderObj->m_ObjFlags |= FOB_TRANS_MASK;
  324.         SRenderObjData* pOD = pRenderObj->GetObjData();
  325.         pOD->m_fTempVars[0] = 1.0f;
  326.  
  327.         m_fRECustomData[0] = p3DEngine->m_oceanWindDirection;
  328.         m_fRECustomData[1] = p3DEngine->m_oceanWindSpeed;
  329.         m_fRECustomData[2] = p3DEngine->m_oceanWavesSpeed;
  330.         m_fRECustomData[3] = p3DEngine->m_oceanWavesAmount;
  331.         m_fRECustomData[4] = p3DEngine->m_oceanWavesSize;
  332.  
  333.         sincos_tpl(p3DEngine->m_oceanWindDirection, &m_fRECustomData[6], &m_fRECustomData[5]);
  334.         m_fRECustomData[7] = fWaterLevel;
  335.  
  336.         //pOD->m_CustomData = &m_fRECustomData;
  337.         m_pRenderMesh->SetREUserData(&m_fRECustomData[0]);
  338.  
  339.         // Submit wave surface
  340.         bool bAboveWaterLevel(max(pCamPos.z - fWaterLevel, 0.0f) > 0.0f);
  341.  
  342.         m_pRenderMesh->AddRenderElements(m_pMaterial, pRenderObj, passInfo, EFSLIST_WATER_VOLUMES, bAboveWaterLevel);
  343.  
  344.         //  return true;
  345. }
  346.  
  347. //////////////////////////////////////////////////////////////////////////
  348. IPhysicalEntity* CWaterWaveRenderNode::GetPhysics() const
  349. {
  350.         return 0;
  351. }
  352.  
  353. //////////////////////////////////////////////////////////////////////////
  354. void CWaterWaveRenderNode::SetPhysics(IPhysicalEntity*)
  355. {
  356.         // make me
  357. }
  358.  
  359. //////////////////////////////////////////////////////////////////////////
  360. void CWaterWaveRenderNode::SetMaterial(IMaterial* pMat)
  361. {
  362.         m_pMaterial = pMat;
  363. }
  364.  
  365. //////////////////////////////////////////////////////////////////////////
  366. void CWaterWaveRenderNode::GetMemoryUsage(ICrySizer* pSizer) const
  367. {
  368.         SIZER_COMPONENT_NAME(pSizer, "WaterWaveNode");
  369.         size_t dynSize(sizeof(*this));
  370.  
  371.         pSizer->AddObject(this, dynSize);
  372. }
  373.  
  374. //////////////////////////////////////////////////////////////////////////
  375. void CWaterWaveRenderNode::Precache()
  376. {
  377.  
  378. }
  379.  
  380. //////////////////////////////////////////////////////////////////////////
  381. void CWaterWaveRenderNode::SetRenderMesh(IRenderMesh* pRenderMesh)
  382. {
  383.         m_pRenderMesh = pRenderMesh;
  384. }
  385.  
  386. void CWaterWaveRenderNode::OffsetPosition(const Vec3& delta)
  387. {
  388.         if (m_pTempData) m_pTempData->OffsetPosition(delta);
  389.         m_pOrigPos += delta;
  390.         m_pWorldTM.SetTranslation(m_pWorldTM.GetTranslation() + delta);
  391.         m_pMin += delta;
  392.         m_pMax += delta;
  393.         m_WSBBox.Move(delta);
  394. }
  395.  
  396. //////////////////////////////////////////////////////////////////////////
  397. CWaterWaveManager::CWaterWaveManager()
  398. {
  399.  
  400. }
  401.  
  402. //////////////////////////////////////////////////////////////////////////
  403. CWaterWaveManager::~CWaterWaveManager()
  404. {
  405.  
  406.         Release();
  407.  
  408. }
  409.  
  410. //////////////////////////////////////////////////////////////////////////
  411. IRenderMesh* CWaterWaveManager::CreateRenderMeshInstance(CWaterWaveRenderNode* pWave)
  412. {
  413.         // todo: put tessellation and indices generation outside
  414.  
  415.         f32 fWaveKey(pWave->GetWaveKey());
  416.         InstancedWavesMap::iterator pItor(m_pInstancedWaves.find(fWaveKey));
  417.  
  418.         if (pItor == m_pInstancedWaves.end())
  419.         {
  420.                 // Create render mesh and store it
  421.                 const SWaterWaveSerialize* pSerParam = pWave->GetSerializationParams();
  422.  
  423.                 Matrix34 pInvWorldTM(pSerParam->m_pWorldTM);
  424.                 pInvWorldTM.Invert();
  425.  
  426.                 int32 nVertexCount(pSerParam->m_nVertexCount);
  427.                 float fUScale(pSerParam->m_fUScale);
  428.                 float fVScale(pSerParam->m_fVScale);
  429.  
  430.                 _smart_ptr<IRenderMesh> pRenderMesh = NULL;
  431.                 std::vector<Vec3> pVertices(pSerParam->m_pVertices);
  432.                 PodArray<SVF_P3F_C4B_T2F> pWaveVertices;
  433.                 PodArray<vtx_idx> pWaveIndices;
  434.  
  435.                 const int nGridRes = GetCVars()->e_WaterWavesTessellationAmount;
  436.                 const float fGridStep = 1.0f / ((float) nGridRes - 1);
  437.  
  438.                 // Generate vertices
  439.                 pWaveVertices.resize(0);
  440.                 pWaveIndices.resize(0);
  441.  
  442.                 pWaveVertices.reserve(nVertexCount);
  443.                 pWaveIndices.reserve(nVertexCount);
  444.  
  445.                 // Tesselate sectors
  446.                 Vec3 pTmpPos;
  447.                 int i = 0;
  448.  
  449.                 const int nSectors = nVertexCount / 4;
  450.                 const int nGridResTotal = nGridRes * nSectors - nSectors;
  451.                 const float fGridResTotalStep = 1.0f / ((float)nGridResTotal);
  452.                 int nCurrVertex = 0;
  453.  
  454.                 // Each sector has 4 vertices
  455.                 for (i = 0; i < nVertexCount; i += 4)
  456.                 {
  457.                         // Set edges (in object space)
  458.                         Vec3 p0(pVertices[i + 0]);
  459.                         p0 = pInvWorldTM.TransformPoint(p0);
  460.  
  461.                         Vec3 p1(pVertices[i + 1]);
  462.                         p1 = pInvWorldTM.TransformPoint(p1);
  463.  
  464.                         Vec3 p2(pVertices[i + 2]);
  465.                         p2 = pInvWorldTM.TransformPoint(p2);
  466.  
  467.                         Vec3 p3(pVertices[i + 3]);
  468.                         p3 = pInvWorldTM.TransformPoint(p3);
  469.  
  470.                         float fBeginTC = 0;
  471.                         float fEndTC = 1;
  472.  
  473.                         for (int x(0); x < nGridRes; ++x)
  474.                         {
  475.                                 // Find min/max edges
  476.                                 float _fCurrStep = (float) x * fGridStep;
  477.                                 Vec3 pMin = p0 + (p2 - p0) * _fCurrStep;
  478.                                 Vec3 pMax = p1 + (p3 - p1) * _fCurrStep;
  479.  
  480.                                 float fTexCoordU = fBeginTC + (fEndTC - fBeginTC) * _fCurrStep;
  481.                                 fTexCoordU *= fUScale;
  482.  
  483.                                 float fXStep = (float) nCurrVertex * fGridResTotalStep;
  484.                                 if (x < nGridRes - 1)
  485.                                 {
  486.                                         nCurrVertex++;
  487.                                 }
  488.  
  489.                                 for (int y(0); y < nGridRes; ++y)
  490.                                 {
  491.                                         // Get final position
  492.                                         float fCurrStep = (float) y * fGridStep;
  493.  
  494.                                         Vec3 pFinal = pMin + (pMax - pMin) * fCurrStep;
  495.  
  496.                                         SVF_P3F_C4B_T2F pCurr;
  497.  
  498.                                         pCurr.xyz = pFinal;
  499.  
  500.                                         float fTexCoordV = fBeginTC + (fEndTC - fBeginTC) * fCurrStep;
  501.                                         fTexCoordV *= fVScale;
  502.  
  503.                                         pCurr.st = Vec2(fTexCoordU, fTexCoordV);
  504.  
  505.                                         // Store some geometry info in vertex colors
  506.                                         float fEdgeX = 1 - abs(fXStep * 2.0f - 1.0f);     // horizontal lerp
  507.                                         float fEdgeY = 1 - abs(fCurrStep * 2.0f - 1.0f);  // vertical lerp
  508.  
  509.                                         float fEdge = fEdgeX * fEdgeY;              // horizontal/vertical merged
  510.                                         uint8 nEdge = (uint8)(fEdge * 255);
  511.  
  512.                                         pCurr.color.bcolor[0] = (uint8) (fXStep * 255.0f);
  513.                                         pCurr.color.bcolor[1] = (uint8) (fCurrStep * 255.0f);
  514.                                         pCurr.color.bcolor[2] = 0;
  515.                                         pCurr.color.bcolor[3] = nEdge;
  516.  
  517.                                         pWaveVertices.push_back(pCurr);
  518.                                 }
  519.                         }
  520.                 }
  521.  
  522.                 // Generate indices
  523.                 int nOffset = 0;
  524.                 for (i = 0; i < nVertexCount; i += 4)
  525.                 {
  526.                         int nIndex(0);
  527.  
  528.                         for (int y(0); y < nGridRes - 1; ++y)
  529.                         {
  530.                                 for (int x(0); x < nGridRes; ++x, ++nIndex)
  531.                                 {
  532.                                         pWaveIndices.push_back(nOffset + nIndex);
  533.                                         pWaveIndices.push_back(nOffset + nIndex + nGridRes);
  534.                                 }
  535.  
  536.                                 if (nGridRes - 2 >= y)
  537.                                 {
  538.                                         // close strip row
  539.                                         pWaveIndices.push_back(nOffset + nIndex + nGridRes - 1);
  540.                                         pWaveIndices.push_back(nOffset + nIndex);
  541.                                 }
  542.                         }
  543.  
  544.                         // close sector strip
  545.                         pWaveIndices.push_back(nOffset + nIndex + nGridRes - 1);
  546.                         pWaveIndices.push_back(nOffset + nIndex);
  547.  
  548.                         // Set new offset
  549.                         nOffset = nOffset + nIndex + nGridRes;
  550.                 }
  551.  
  552.                 // Finally, make render mesh
  553.                 pRenderMesh = GetRenderer()->CreateRenderMeshInitialized(&pWaveVertices[0],
  554.                                                                          pWaveVertices.size(),
  555.                                                                          eVF_P3F_C4B_T2F,
  556.                                                                          &pWaveIndices[0],
  557.                                                                          pWaveIndices.size(),
  558.                                                                          prtTriangleStrip,
  559.                                                                          "WaterWave",
  560.                                                                          "WaterWave",
  561.                                                                          eRMT_Static);
  562.  
  563.                 float texelAreaDensity = 1.0f;
  564.                 {
  565.                         const size_t indexCount = pWaveIndices.size();
  566.                         const size_t vertexCount = pWaveVertices.size();
  567.  
  568.                         if ((indexCount > 0) && (vertexCount > 0))
  569.                         {
  570.                                 float posArea;
  571.                                 float texArea;
  572.                                 const char* errorText = "";
  573.  
  574.                                 const bool ok = CMeshHelpers::ComputeTexMappingAreas(
  575.                                   indexCount, &pWaveIndices[0],
  576.                                   vertexCount,
  577.                                   &pWaveVertices[0].xyz, sizeof(pWaveVertices[0]),
  578.                                   &pWaveVertices[0].st, sizeof(pWaveVertices[0]),
  579.                                   posArea, texArea, errorText);
  580.  
  581.                                 if (ok)
  582.                                 {
  583.                                         texelAreaDensity = texArea / posArea;
  584.                                 }
  585.                                 else
  586.                                 {
  587.                                         gEnv->pLog->LogError("Failed to compute texture mapping density for mesh '%s': %s", "WaterWave", errorText);
  588.                                 }
  589.                         }
  590.                 }
  591.  
  592.                 pRenderMesh->SetChunk(pWave->GetMaterial(0), 0, pWaveVertices.size(), 0, pWaveIndices.size(), texelAreaDensity);
  593.  
  594.                 // And add it to out instanced list
  595.                 m_pInstancedWaves.insert(InstancedWavesMap::value_type(fWaveKey, pRenderMesh));
  596.  
  597.                 return pRenderMesh;
  598.         }
  599.  
  600.         return pItor->second;
  601. }
  602.  
  603. //////////////////////////////////////////////////////////////////////////
  604. void CWaterWaveManager::Register(CWaterWaveRenderNode* pWave)
  605. {
  606.  
  607.         // Check first if exists already
  608.         GlobalWavesMap::iterator pItor(m_pWaves.find(pWave->GetID()));
  609.  
  610.         if (pItor == m_pWaves.end())
  611.         {
  612.                 m_pWaves.insert(GlobalWavesMap::value_type(pWave->GetID(), pWave));
  613.         }
  614.  
  615.         // Make wave geometry instance and set wave render mesh
  616.         _smart_ptr<IRenderMesh> pWaveRenderMesh(CreateRenderMeshInstance(pWave));
  617.         pWave->SetRenderMesh(pWaveRenderMesh);
  618.  
  619. }
  620.  
  621. //////////////////////////////////////////////////////////////////////////
  622. void CWaterWaveManager::Unregister(CWaterWaveRenderNode* pWave)
  623. {
  624.  
  625.         f32 fCurrWaveKey(pWave->GetWaveKey());
  626.  
  627.         {
  628.                 // Remove from map
  629.                 GlobalWavesMapIt pItor(m_pWaves.find(pWave->GetID()));
  630.  
  631.                 if (pItor != m_pWaves.end())
  632.                 {
  633.                         m_pWaves.erase(pItor);
  634.                 }
  635.         }
  636.  
  637.         {
  638.  
  639.                 GlobalWavesMapIt _pItor(m_pWaves.begin());
  640.                 GlobalWavesMapIt pEnd(m_pWaves.end());
  641.                 uint32 nInstances(0);
  642.  
  643.                 // todo: this is unneficient, find better solution
  644.                 for (; _pItor != pEnd; ++_pItor)
  645.                 {
  646.                         f32 fWaveKey = _pItor->second->GetWaveKey();
  647.                         if (fWaveKey == fCurrWaveKey)
  648.                         {
  649.                                 nInstances++;
  650.                                 break;
  651.                         }
  652.                 }
  653.  
  654.                 // If no instances left, remove render mesh
  655.                 if (!nInstances)
  656.                 {
  657.                         InstancedWavesMapIt pItor(m_pInstancedWaves.find(fCurrWaveKey));
  658.                         if (pItor != m_pInstancedWaves.end())
  659.                                 m_pInstancedWaves.erase(pItor);
  660.                 }
  661.  
  662.         }
  663.  
  664. }
  665.  
  666. //////////////////////////////////////////////////////////////////////////
  667. void CWaterWaveManager::Release()
  668. {
  669.         // Free all resources
  670.  
  671.         m_pWaves.clear();
  672.         m_pInstancedWaves.clear();
  673.  
  674. }
  675.  
  676. //////////////////////////////////////////////////////////////////////////
  677. void CWaterWaveManager::Update(const SRenderingPassInfo& passInfo)
  678. {
  679.         FUNCTION_PROFILER_3DENGINE;
  680.  
  681.         // Update each wave
  682.         GlobalWavesMapIt pItor(m_pWaves.begin());
  683.         GlobalWavesMapIt pEnd(m_pWaves.end());
  684.  
  685.         Vec3 pCamPos = passInfo.GetCamera().GetPosition();
  686.  
  687.         for (; pItor != pEnd; ++pItor)
  688.         {
  689.                 // Verify distance to camera and visibility
  690.                 CWaterWaveRenderNode* pCurr(pItor->second);
  691.                 bool IsVisible(abs(pCurr->GetDrawFrame(passInfo.GetRecursiveLevel()) - passInfo.GetFrameID()) <= 2);
  692.                 float fDistanceSqr(pCamPos.GetSquaredDistance(pCurr->GetPos()));
  693.  
  694.                 // if wave is visible, or nearby camera update it
  695.                 if (IsVisible || fDistanceSqr < MAX_WAVE_DIST_UPDATE)
  696.                 {
  697.                         pCurr->Update(sqrt_tpl(fDistanceSqr));
  698.                 }
  699.         }
  700.  
  701. }
  702.  
  703. ///////////////////////////////////////////////////////////////////////////////
  704. void CWaterWaveRenderNode::FillBBox(AABB& aabb)
  705. {
  706.         aabb = CWaterWaveRenderNode::GetBBox();
  707. }
  708.  
  709. ///////////////////////////////////////////////////////////////////////////////
  710. EERType CWaterWaveRenderNode::GetRenderNodeType()
  711. {
  712.         return eERType_WaterWave;
  713. }
  714.  
  715. ///////////////////////////////////////////////////////////////////////////////
  716. float CWaterWaveRenderNode::GetMaxViewDist()
  717. {
  718.         if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
  719.                 return max(GetCVars()->e_ViewDistMin, CWaterWaveRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatioDetail * GetViewDistRatioNormilized());
  720.  
  721.         return max(GetCVars()->e_ViewDistMin, CWaterWaveRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistRatioNormilized());
  722. }
  723.  
  724. ///////////////////////////////////////////////////////////////////////////////
  725. Vec3 CWaterWaveRenderNode::GetPos(bool bWorldOnly) const
  726. {
  727.         return m_pParams.m_pPos;
  728. }
  729.  
  730. ///////////////////////////////////////////////////////////////////////////////
  731. IMaterial* CWaterWaveRenderNode::GetMaterial(Vec3* pHitPos) const
  732. {
  733.         return m_pMaterial;
  734. }
  735.  
downloadWaterWaveRenderNode.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