BVB Source Codes

CRYENGINE Show Vegetation.cpp Source code

Return Download CRYENGINE: download Vegetation.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:   Vegetation.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: Loading trees, buildings, register/unregister entities for rendering
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15.  
  16. #include "StatObj.h"
  17. #include "terrain.h"
  18. #include "StatObj.h"
  19. #include "ObjMan.h"
  20. #include "PolygonClipContext.h"
  21. #include "3dEngine.h"
  22. #include "Vegetation.h"
  23. #include "DeformableNode.h"
  24.  
  25. #define BYTE2RAD(x) ((x) * float(g_PI2) / 255.0f)
  26.  
  27. float CRY_ALIGN(128) CVegetation::g_scBoxDecomprTable[256];
  28.  
  29. // g_scBoxDecomprTable heps on consoles (no difference on PC)
  30. void CVegetation::InitVegDecomprTable()
  31. {
  32.         const float cDecompFactor = (VEGETATION_CONV_FACTOR / 255.f);
  33.         for (int i = 0; i < 256; ++i)
  34.                 g_scBoxDecomprTable[i] = (float)i * cDecompFactor;
  35. }
  36.  
  37. CVegetation::CVegetation()
  38. {
  39.         Init();
  40.  
  41.         GetInstCount(eERType_Vegetation)++;
  42. }
  43.  
  44. void CVegetation::Init()
  45. {
  46.         m_pInstancingInfo = 0;
  47.         m_nObjectTypeIndex = 0;
  48.         m_vPos.Set(0, 0, 0);
  49.         m_ucScale = 0;
  50.         m_pPhysEnt = 0;
  51.         m_ucAngle = 0;
  52.         m_ucAngleX = 0;
  53.         m_ucAngleY = 0;
  54.         m_pTempData = NULL;
  55.         m_pSpriteInfo = NULL;
  56.         m_pDeformable = NULL;
  57.         m_bApplyPhys = false;
  58. #ifdef SEG_WORLD
  59.         m_nStaticTypeSlot = 0;
  60. #endif
  61. }
  62.  
  63. //////////////////////////////////////////////////////////////////////////
  64. void CVegetation::CalcMatrix(Matrix34A& tm, int* pFObjFlags)
  65. {
  66.         FUNCTION_PROFILER_3DENGINE;
  67.  
  68.         Matrix34A matTmp;
  69.         int orFlags = 0;
  70.  
  71.         matTmp.SetIdentity();
  72.  
  73.         if (float fAngle = GetZAngle())
  74.         {
  75.                 matTmp.SetRotationZ(fAngle);
  76.                 orFlags |= FOB_TRANS_ROTATE;
  77.         }
  78.  
  79.         StatInstGroup& vegetGroup = GetStatObjGroup();
  80.  
  81.         if (vegetGroup.GetAlignToTerrainAmount() != 0.f)
  82.         {
  83.                 Matrix33 m33;
  84.                 GetTerrain()->GetTerrainAlignmentMatrix(m_vPos, vegetGroup.GetAlignToTerrainAmount(), m33);
  85.                 matTmp = m33 * matTmp;
  86.  
  87.                 orFlags |= FOB_TRANS_ROTATE;
  88.         }
  89.         else
  90.         {
  91.                 matTmp = Matrix34::CreateRotationXYZ(Ang3(BYTE2RAD(m_ucAngleX), BYTE2RAD(m_ucAngleY), GetZAngle()));
  92.  
  93.                 orFlags |= FOB_TRANS_ROTATE;
  94.         }
  95.  
  96.         float fScale = GetScale();
  97.         if (fScale != 1.0f)
  98.         {
  99.                 Matrix33 m33;
  100.                 m33.SetIdentity();
  101.                 m33.SetScale(Vec3(fScale, fScale, fScale));
  102.                 matTmp = m33 * matTmp;
  103.                 //orFlags |= FOB_TRANS_SCALE;
  104.         }
  105.  
  106.         matTmp.SetTranslation(m_vPos);
  107.  
  108.         if (pFObjFlags)
  109.         {
  110.                 *pFObjFlags |= (FOB_TRANS_TRANSLATE | orFlags);
  111.         }
  112.  
  113.         tm = matTmp;
  114. }
  115.  
  116. //////////////////////////////////////////////////////////////////////////
  117. AABB CVegetation::CalcBBox()
  118. {
  119.         AABB WSBBox = GetStatObj()->GetAABB();
  120.         //WSBBox.min.z = 0;
  121.  
  122.         if (m_ucAngle || m_ucAngleX || m_ucAngleY)
  123.         {
  124.                 Matrix34A tm;
  125.                 CalcMatrix(tm);
  126.                 WSBBox.SetTransformedAABB(tm, WSBBox);
  127.         }
  128.         else
  129.         {
  130.                 float fScale = GetScale();
  131.                 WSBBox.min = m_vPos + WSBBox.min * fScale;
  132.                 WSBBox.max = m_vPos + WSBBox.max * fScale;
  133.         }
  134.  
  135.         SetBBox(WSBBox);
  136.  
  137.         return WSBBox;
  138. }
  139.  
  140. CLodValue CVegetation::ComputeLod(int wantedLod, const SRenderingPassInfo& passInfo)
  141. {
  142.         uint8 nDissolveRefA = 0;
  143.         int nLodA = -1;
  144.         int nLodB = -1;
  145.  
  146.         StatInstGroup& vegetGroup = GetStatObjGroup();
  147.         if (CStatObj* pStatObj = vegetGroup.GetStatObj())
  148.         {
  149.                 const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  150.  
  151.                 // update LOD faster in zoom mode
  152.                 if (passInfo.IsGeneralPass() && passInfo.IsZoomActive())
  153.                 {
  154.                         const float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, GetBBox())) * passInfo.GetZoomFactor();
  155.                         wantedLod = CObjManager::GetObjectLOD(this, fEntDistance);
  156.                 }
  157.  
  158.                 int minUsableLod = pStatObj->GetMinUsableLod();
  159.                 int maxUsableLod = (int)pStatObj->m_nMaxUsableLod;
  160.                 nLodA = CLAMP(wantedLod, minUsableLod, maxUsableLod);
  161.                 if (!(pStatObj->m_nFlags & STATIC_OBJECT_COMPOUND))
  162.                         nLodA = pStatObj->FindNearesLoadedLOD(nLodA);
  163.  
  164.                 if (passInfo.IsGeneralPass())
  165.                 {
  166.                         const float fSpriteSwitchDist = GetSpriteSwitchDist();
  167.  
  168.                         if (m_pSpriteInfo)
  169.                         {
  170.                                 m_pSpriteInfo->ucDissolveOut = 255;
  171.  
  172.                                 if (nLodA == -1 && nLodB != -1)
  173.                                 {
  174.                                         m_pSpriteInfo->ucAlphaTestRef = nDissolveRefA;
  175.                                 }
  176.                                 else if (nLodB == -1 && nLodA != -1)
  177.                                 {
  178.                                         m_pSpriteInfo->ucAlphaTestRef = nDissolveRefA;
  179.                                         m_pSpriteInfo->ucDissolveOut = 0;
  180.                                 }
  181.                                 else if (nLodA == -1 && nLodB == -1)
  182.                                 {
  183.                                         m_pSpriteInfo->ucAlphaTestRef = 0;
  184.                                 }
  185.                                 else
  186.                                 {
  187.                                         m_pSpriteInfo->ucAlphaTestRef = 255;
  188.                                 }
  189.                         }
  190.                 }              
  191.         }
  192.  
  193.         return CLodValue(nLodA, nDissolveRefA, nLodB);
  194. }
  195.  
  196. //////////////////////////////////////////////////////////////////////////
  197. void CVegetation::FillBendingData(CRenderObject* pObj) const
  198. {
  199.         const StatInstGroup& vegetGroup = GetStatObjGroup();
  200.  
  201.         if (GetCVars()->e_VegetationBending && vegetGroup.fBending)
  202.         {
  203.                 pObj->m_vegetationBendingData.scale = 0.1f * vegetGroup.fBending;
  204.                 pObj->m_vegetationBendingData.verticalRadius = vegetGroup.GetStatObj() ? vegetGroup.GetStatObj()->GetRadiusVert() : 1.0f;
  205.                 pObj->m_ObjFlags |= FOB_BENDED | FOB_DYNAMIC_OBJECT;
  206.         }
  207.         else
  208.         {
  209.                 pObj->m_vegetationBendingData.scale = 0.0f;
  210.                 pObj->m_vegetationBendingData.verticalRadius = 0.0f;
  211.         }
  212. }
  213.  
  214. //////////////////////////////////////////////////////////////////////////
  215. void CVegetation::Render(const SRenderingPassInfo& passInfo, const CLodValue& lodValue, SSectorTextureSet* pTerrainTexInfo) const
  216. {
  217.         FUNCTION_PROFILER_3DENGINE;
  218.  
  219.         CRenderObject* pRenderObject = 0;
  220.  
  221.         if (GetObjManager()->AddOrCreatePersistentRenderObject(m_pTempData, pRenderObject, &lodValue, passInfo))
  222.         {
  223.                 if (GetCVars()->e_StaticInstancing == 3 && m_pInstancingInfo)
  224.                         DrawBBox(GetBBox());
  225.  
  226.                 return;
  227.         }
  228.  
  229.         assert(m_pTempData);
  230.  
  231.         if (pRenderObject->m_bPermanent && m_pOcNode && GetCVars()->e_StaticInstancing && m_pInstancingInfo)
  232.         {
  233.                 WriteLock lock(((COctreeNode*)m_pOcNode)->m_updateStaticInstancingLock);
  234.  
  235.                 // Copy instancing data to the render object
  236.                 if (GetCVars()->e_StaticInstancing && m_pInstancingInfo)
  237.                 {
  238.                         // Copy vegetation static instancing data to the permanent render object.
  239.                         pRenderObject->m_Instances.resize(m_pInstancingInfo->Count());
  240.                         memcpy(&pRenderObject->m_Instances[0], m_pInstancingInfo->GetElements(), m_pInstancingInfo->Count() * sizeof(CRenderObject::SInstanceInfo));
  241.                 }
  242.         }
  243.  
  244.         StatInstGroup& vegetGroup = GetStatObjGroup();
  245.  
  246.         CStatObj* pStatObj = vegetGroup.GetStatObj();
  247.  
  248.         if (!pStatObj)
  249.                 return;
  250.  
  251.         FillBendingData(pRenderObject);
  252.  
  253.         const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  254.         const Vec3 vObjCenter = GetBBox().GetCenter();
  255.         const Vec3 vObjPos = GetPos();
  256.  
  257.         float fEntDistance = pRenderObject->m_bPermanent ? 0 : sqrt_tpl(Distance::Point_AABBSq(vCamPos, GetBBox())) * passInfo.GetZoomFactor();
  258.         float fEntDistance2D = pRenderObject->m_bPermanent ? 0 : sqrt_tpl(vCamPos.GetSquaredDistance2D(m_vPos)) * passInfo.GetZoomFactor();
  259.         bool bUseTerrainColor((vegetGroup.bUseTerrainColor && GetCVars()->e_VegetationUseTerrainColor) || GetCVars()->e_VegetationUseTerrainColor == 2);
  260.  
  261.         SRenderNodeTempData::SUserData& userData = m_pTempData->userData;
  262.  
  263.         pRenderObject->m_pRenderNode = const_cast<IRenderNode*>(static_cast<const IRenderNode*>(this));
  264.         pRenderObject->m_II.m_Matrix = userData.objMat;
  265.         pRenderObject->m_fAlpha = 1.f;
  266.         pRenderObject->m_ObjFlags |= FOB_INSHADOW | FOB_TRANS_MASK | FOB_DYNAMIC_OBJECT;
  267.         pRenderObject->m_editorSelectionID = m_nEditorSelectionID;
  268.  
  269.         if (!userData.objMat.m01 && !userData.objMat.m02 && !userData.objMat.m10 && !userData.objMat.m12 && !userData.objMat.m20 && !userData.objMat.m21)
  270.                 pRenderObject->m_ObjFlags &= ~FOB_TRANS_ROTATE;
  271.         else
  272.                 pRenderObject->m_ObjFlags |= FOB_TRANS_ROTATE;
  273.  
  274.         if (bUseTerrainColor)
  275.         {
  276.                 m_pTempData->userData.bTerrainColorWasUsed = true;
  277.                 pRenderObject->m_ObjFlags |= FOB_BLEND_WITH_TERRAIN_COLOR;
  278.         }
  279.         else
  280.                 pRenderObject->m_ObjFlags &= ~FOB_BLEND_WITH_TERRAIN_COLOR;
  281.  
  282.         pRenderObject->m_fDistance = fEntDistance;
  283.         pRenderObject->m_nSort = fastround_positive(fEntDistance * 2.0f);
  284.  
  285.         if (uint8 nMaterialLayers = GetMaterialLayers())
  286.         {
  287.                 uint8 nFrozenLayer = (nMaterialLayers & MTL_LAYER_FROZEN) ? MTL_LAYER_FROZEN_MASK : 0;
  288.                 uint8 nWetLayer = (nMaterialLayers & MTL_LAYER_WET) ? MTL_LAYER_WET_MASK : 0;
  289.                 pRenderObject->m_nMaterialLayers = (uint32) (nFrozenLayer << 24) | (nWetLayer << 16);
  290.         }
  291.         else
  292.                 pRenderObject->m_nMaterialLayers = 0;
  293.  
  294.         if (vegetGroup.pMaterial)
  295.                 pRenderObject->m_pCurrMaterial = vegetGroup.pMaterial;
  296.         else if (vegetGroup.GetStatObj())
  297.                 pRenderObject->m_pCurrMaterial = vegetGroup.GetStatObj()->GetMaterial();
  298.  
  299.         pRenderObject->m_II.m_AmbColor.a = vegetGroup.fBrightness;
  300.  
  301.         if (pRenderObject->m_II.m_AmbColor.a > 1.f)
  302.                 pRenderObject->m_II.m_AmbColor.a = 1.f;
  303.  
  304.         float fRenderQuality = vegetGroup.bUseSprites ?
  305.                                min(1.f, max(1.f - fEntDistance2D / GetSpriteSwitchDist(), 0.f)) :
  306.                                min(1.f, max(1.f - fEntDistance2D / (m_fWSMaxViewDist * 0.3333f), 0.f));
  307.  
  308.         pRenderObject->m_nRenderQuality = (uint16)(fRenderQuality * 65535.0f);
  309.  
  310.         pRenderObject->m_data.m_fMaxViewDistance = m_fWSMaxViewDist;
  311.  
  312.         if (!pTerrainTexInfo && (pRenderObject->m_ObjFlags & FOB_BLEND_WITH_TERRAIN_COLOR) && passInfo.IsShadowPass() && pRenderObject->m_bPermanent && GetCVars()->e_VegetationUseTerrainColor)
  313.         {
  314.                 GetObjManager()->FillTerrainTexInfo(m_pOcNode, fEntDistance, pTerrainTexInfo, GetBBox());
  315.         }
  316.  
  317.         if (pTerrainTexInfo)
  318.                 if (pRenderObject->m_ObjFlags & (FOB_BLEND_WITH_TERRAIN_COLOR))
  319.                 {
  320.                         pRenderObject->m_data.m_pTerrainSectorTextureInfo = pTerrainTexInfo;
  321.                         pRenderObject->m_nTextureID = -(int)pTerrainTexInfo->nSlot0 - 1; // nTextureID is set only for proper batching, actual texture id is same for all terrain sectors
  322.  
  323.                         {
  324.                                 float fBlendDistance = GetCVars()->e_VegetationUseTerrainColorDistance;
  325.  
  326.                                 if (!fBlendDistance && m_dwRndFlags & ERF_PROCEDURAL)
  327.                                         fBlendDistance = -1.f;
  328.  
  329.                                 if (fBlendDistance == 0)
  330.                                 {
  331.                                         pRenderObject->m_data.m_fMaxViewDistance = m_fWSMaxViewDist;
  332.                                 }
  333.                                 else if (fBlendDistance > 0)
  334.                                 {
  335.                                         pRenderObject->m_data.m_fMaxViewDistance = fBlendDistance;
  336.                                 }
  337.                                 else // if(fBlendDistance < 0)
  338.                                 {
  339.                                         pRenderObject->m_data.m_fMaxViewDistance = abs(fBlendDistance) * vegetGroup.fVegRadius * vegetGroup.fMaxViewDistRatio * GetCVars()->e_ViewDistRatioVegetation;
  340.                                 }
  341.                         }
  342.                 }
  343.  
  344.         IFoliage* pFoliage = const_cast<CVegetation*>(this)->GetFoliage();
  345.         if (pFoliage && ((CStatObjFoliage*)pFoliage)->m_pVegInst == this)
  346.         {
  347.                 SRenderObjData* pOD = pRenderObject->GetObjData();
  348.                 if (pOD)
  349.                 {
  350.                         pOD->m_pSkinningData = pFoliage->GetSkinningData(pRenderObject->m_II.m_Matrix, passInfo);
  351.                         pRenderObject->m_ObjFlags |= FOB_SKINNED | FOB_DYNAMIC_OBJECT;
  352.                         pFoliage->SetFlags(pFoliage->GetFlags() & ~IFoliage::FLAG_FROZEN | -(int)(pRenderObject->m_nMaterialLayers & MTL_LAYER_FROZEN) & IFoliage::FLAG_FROZEN);
  353.                 }
  354.         }
  355.  
  356.         // Physicalized foliage might have not found the correct stencil ref during onrendernodebecomevisible
  357.         // because it can be called from the physics callback.
  358.         // A query for the visareastencilref is therefore issued every time it is rendered.
  359.         pRenderObject->m_nClipVolumeStencilRef = 0;
  360.         if (m_pOcNode && m_pOcNode->m_pVisArea)
  361.                 pRenderObject->m_nClipVolumeStencilRef = ((IVisArea*)m_pOcNode->m_pVisArea)->GetStencilRef();
  362.         else if (userData.m_pClipVolume)
  363.                 pRenderObject->m_nClipVolumeStencilRef = userData.m_pClipVolume->GetStencilRef();
  364.  
  365.         if (m_pSpriteInfo && m_pSpriteInfo->ucAlphaTestRef < 255 && GetCVars()->e_VegetationSprites && !passInfo.IsShadowPass())
  366.         {
  367.                 CThreadSafeRendererContainer<SVegetationSpriteInfo>& arrSpriteInfo = GetObjManager()->m_arrVegetationSprites[passInfo.GetRecursiveLevel()][passInfo.ThreadID()];
  368.                 arrSpriteInfo.push_back(*m_pSpriteInfo);
  369.         }
  370.  
  371.         if (m_bEditor) // editor can modify material anytime
  372.         {
  373.                 if (vegetGroup.pMaterial)
  374.                         pRenderObject->m_pCurrMaterial = vegetGroup.pMaterial;
  375.                 else
  376.                         pRenderObject->m_pCurrMaterial = pStatObj->GetMaterial();
  377.         }
  378.  
  379.         // check the object against the water level
  380.         if (CObjManager::IsAfterWater(vObjCenter, vCamPos, passInfo, Get3DEngine()->GetWaterLevel()))
  381.                 pRenderObject->m_ObjFlags |= FOB_AFTER_WATER;
  382.         else
  383.                 pRenderObject->m_ObjFlags &= ~FOB_AFTER_WATER;
  384.  
  385.         CRenderObject* pRenderObjectFin = pRenderObject;
  386.  
  387.         bool duplicated = false;
  388.         if (userData.m_pFoliage) // fix for vegetation flicker when switching back from foliage mode
  389.         {
  390.                 pRenderObjectFin = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo);
  391.                 if (SRenderObjData* objData = pRenderObjectFin->GetObjData())
  392.                 {
  393.                         if (!objData->m_pSkinningData)
  394.                         {
  395.                                 pRenderObjectFin->m_ObjFlags &= ~FOB_SKINNED;
  396.                         }
  397.                         else
  398.                         {
  399.                                 pRenderObjectFin->m_ObjFlags |= FOB_SKINNED;
  400.                         }
  401.                 }
  402.                 duplicated = true;
  403.         }
  404.  
  405.         if (Get3DEngine()->IsTessellationAllowed(pRenderObject, passInfo))
  406.         {
  407.                 // Allow this RO to be tessellated, however actual tessellation will be applied if enabled in material
  408.                 pRenderObject->m_ObjFlags |= FOB_ALLOW_TESSELLATION;
  409.         }
  410.         else
  411.                 pRenderObject->m_ObjFlags &= ~FOB_ALLOW_TESSELLATION;
  412.         pStatObj->RenderInternal(pRenderObject, 0, lodValue, passInfo);
  413.  
  414.         if (m_pDeformable) m_pDeformable->RenderInternalDeform(pRenderObject, lodValue.LodA(), GetBBox(), passInfo);
  415.  
  416.         if (GetCVars()->e_BBoxes)
  417.                 GetObjManager()->RenderObjectDebugInfo((IRenderNode*)this, pRenderObject->m_fDistance, passInfo);
  418. }
  419.  
  420. //////////////////////////////////////////////////////////////////////////
  421. float CVegetation::GetSpriteSwitchDist() const
  422. {
  423.         StatInstGroup& vegetGroup = GetStatObjGroup();
  424.  
  425.         return vegetGroup.m_fSpriteSwitchDist * LERP(1.0f, CVegetation::GetScale(), GetFloatCVar(e_VegetationSpritesScaleFactor));
  426. }
  427.  
  428. //////////////////////////////////////////////////////////////////////////
  429. bool CVegetation::IsBending() const
  430. {
  431.         return GetStatObjGroup().fBending != 0.0f;
  432. }
  433.  
  434. void CVegetation::Physicalize(bool bInstant)
  435. {
  436.         FUNCTION_PROFILER_3DENGINE;
  437.  
  438.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Physics, 0, "Vegetation physicalization");
  439.  
  440.         StatInstGroup& vegetGroup = GetStatObjGroup();
  441.  
  442.         CStatObj* pBody = vegetGroup.GetStatObj();
  443.         if (!pBody)
  444.                 return;
  445.  
  446.         bool bHideability = vegetGroup.bHideability;
  447.         bool bHideabilitySecondary = vegetGroup.bHideabilitySecondary;
  448.  
  449.         //////////////////////////////////////////////////////////////////////////
  450.         // Not create instance if no physical geometry.
  451.         if (!pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_DEFAULT] && !(pBody->GetFlags() & STATIC_OBJECT_COMPOUND))
  452.                 //no bHidability check for the E3 demo - make all the bushes with MAT_OBSTRUCT things soft cover
  453.                 //if(!(pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT] && (bHideability || pBody->m_nSpines)))
  454.                 if (!(pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT]))
  455.                         if (!(pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE]))
  456.                                 return;
  457.         //////////////////////////////////////////////////////////////////////////
  458.         m_bApplyPhys = true;
  459.  
  460.         AABB WSBBox = GetBBox();
  461.  
  462.         int bNoOnDemand =
  463.           !(GetCVars()->e_OnDemandPhysics & 0x1) || max(WSBBox.max.x - WSBBox.min.x, WSBBox.max.y - WSBBox.min.y) > Get3DEngine()->GetCVars()->e_OnDemandMaxSize;
  464.         if (bNoOnDemand)
  465.                 bInstant = true;
  466.  
  467.         if (!bInstant)
  468.         {
  469.                 gEnv->pPhysicalWorld->RegisterBBoxInPODGrid(&WSBBox.min);
  470.                 return;
  471.         }
  472.  
  473.         // create new
  474.         pe_params_pos pp;
  475.         Matrix34A mtx;
  476.         CalcMatrix(mtx);
  477.         Matrix34 mtxNA = mtx;
  478.         pp.pMtx3x4 = &mtxNA;
  479.         float fScale = GetScale();
  480.         //pp.pos = m_vPos;
  481.         //pp.q.SetRotationXYZ( Ang3(0,0,GetZAngle()) );
  482.         //pp.scale = fScale;
  483.         if (m_pPhysEnt)
  484.                 Dephysicalize();
  485.  
  486.         m_pPhysEnt = GetSystem()->GetIPhysicalWorld()->CreatePhysicalEntity(PE_STATIC, (1 - bNoOnDemand) * 5.0f, &pp,
  487.                                                                             (IRenderNode*)this, PHYS_FOREIGN_ID_STATIC);
  488.         if (!m_pPhysEnt)
  489.                 return;
  490.  
  491.         pe_geomparams params;
  492.         params.density = 800;
  493.         params.flags |= geom_break_approximation;
  494.         params.scale = fScale;
  495.  
  496.         if (pBody->GetFlags() & STATIC_OBJECT_COMPOUND)
  497.         {
  498.                 Matrix34 scaleMat;
  499.                 scaleMat.Set(Vec3(fScale), Quat(IDENTITY), Vec3(ZERO));
  500.                 params.pMtx3x4 = &scaleMat;
  501.                 pBody->Physicalize(m_pPhysEnt, &params);
  502.         }
  503.  
  504.         // collidable
  505.         if (pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_DEFAULT])
  506.         {
  507.                 pe_params_ground_plane pgp;
  508.                 Vec3 bbox[2] = { pBody->GetBoxMin(), pBody->GetBoxMax() };
  509.                 pgp.iPlane = 0;
  510.                 pgp.ground.n.Set(0, 0, 1);
  511.                 (pgp.ground.origin = (bbox[0] + bbox[1]) * 0.5f).z -= (bbox[1].z - bbox[0].z) * 0.49f;
  512.                 pgp.ground.origin *= fScale;
  513.  
  514.                 m_pPhysEnt->SetParams(&pgp, 1);
  515.  
  516.                 if (pBody->GetFlags() & STATIC_OBJECT_NO_PLAYER_COLLIDE)
  517.                         params.flags &= ~geom_colltype_player;
  518.  
  519.                 if (!(m_dwRndFlags & ERF_PROCEDURAL))
  520.                 {
  521.                         params.idmatBreakable = pBody->m_idmatBreakable;
  522.                         if (pBody->m_bBreakableByGame)
  523.                                 params.flags |= geom_manually_breakable;
  524.                 }
  525.                 else
  526.                         params.idmatBreakable = -1;
  527.                 m_pPhysEnt->AddGeometry(pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_DEFAULT], &params, -1, 1);
  528.         }
  529.  
  530.         phys_geometry* pgeom;
  531.         params.density = 2;
  532.         params.idmatBreakable = -1;
  533.         if (pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE] && pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT])
  534.         {
  535.                 params.minContactDist = GetFloatCVar(e_FoliageStiffness);
  536.                 params.flags = geom_squashy | geom_colltype_obstruct;
  537.                 m_pPhysEnt->AddGeometry(pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT], &params, 1024, 1);
  538.  
  539.                 if (!gEnv->IsDedicated() && GetCVars()->e_PhysFoliage >= 2)
  540.                 {
  541.                         params.density = 0;
  542.                         params.flags = geom_log_interactions;
  543.                         params.flagsCollider = 0;
  544.                         if (pBody->m_nSpines)
  545.                                 params.flags |= geom_colltype_foliage_proxy;
  546.                         m_pPhysEnt->AddGeometry(pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE], &params, 2048, 1);
  547.                 }
  548.         }
  549.         else if ((pgeom = pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE]) || (pgeom = pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT]))
  550.         {
  551.                 params.minContactDist = GetFloatCVar(e_FoliageStiffness);
  552.                 params.flags = geom_log_interactions | geom_squashy;
  553.                 if (pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT])
  554.                         params.flags |= geom_colltype_obstruct;
  555.                 if (pBody->m_nSpines)
  556.                         params.flags |= geom_colltype_foliage_proxy;
  557.                 m_pPhysEnt->AddGeometry(pgeom, &params, 1024, 1);
  558.         }
  559.  
  560.         if (bHideability)
  561.         {
  562.                 pe_params_foreign_data foreignData;
  563.                 m_pPhysEnt->GetParams(&foreignData);
  564.                 foreignData.iForeignFlags |= PFF_HIDABLE;
  565.                 m_pPhysEnt->SetParams(&foreignData, 1);
  566.         }
  567.  
  568.         if (bHideabilitySecondary)
  569.         {
  570.                 pe_params_foreign_data foreignData;
  571.                 m_pPhysEnt->GetParams(&foreignData);
  572.                 foreignData.iForeignFlags |= PFF_HIDABLE_SECONDARY;
  573.                 m_pPhysEnt->SetParams(&foreignData, 1);
  574.         }
  575.  
  576.         //PhysicalizeFoliage();
  577. }
  578.  
  579. bool CVegetation::PhysicalizeFoliage(bool bPhysicalize, int iSource, int nSlot)
  580. {
  581.         CStatObj* pBody = GetStatObj();
  582.         if (!pBody || !pBody->m_pSpines)
  583.                 return false;
  584.  
  585.         if (bPhysicalize)
  586.         {
  587.                 if (m_pTempData) // Temporary data should exist for visible objects (will not physicalize invisible objects)
  588.                 {
  589.                         Matrix34A mtx;
  590.                         CalcMatrix(mtx);
  591.                         if (pBody->PhysicalizeFoliage(m_pPhysEnt, mtx, m_pTempData->userData.m_pFoliage, GetCVars()->e_FoliageBranchesTimeout, iSource))//&& !pBody->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_DEFAULT])
  592.                         {
  593.                                 ((CStatObjFoliage*)m_pTempData->userData.m_pFoliage)->m_pVegInst = this;
  594.                         }
  595.                 }
  596.         }
  597.         else if (m_pTempData && m_pTempData->userData.m_pFoliage)
  598.         {
  599.                 m_pTempData->userData.m_pFoliage->Release();
  600.                 m_pTempData->userData.m_pFoliage = NULL;
  601.         }
  602.  
  603.         return m_pTempData && m_pTempData->userData.m_pFoliage;
  604. }
  605.  
  606. IRenderNode* CVegetation::Clone() const
  607. {
  608.         CVegetation* pDestVeg = new CVegetation();
  609.  
  610.         //CVegetation member vars
  611.         pDestVeg->m_vPos = m_vPos;
  612.         pDestVeg->m_nObjectTypeIndex = m_nObjectTypeIndex;
  613.         pDestVeg->m_ucAngle = m_ucAngle;
  614.         pDestVeg->m_ucAngleX = m_ucAngleX;
  615.         pDestVeg->m_ucAngleY = m_ucAngleY;
  616.         pDestVeg->m_ucScale = m_ucScale;
  617.         pDestVeg->m_boxExtends[0] = m_boxExtends[0];
  618.         pDestVeg->m_boxExtends[1] = m_boxExtends[1];
  619.         pDestVeg->m_boxExtends[2] = m_boxExtends[2];
  620.         pDestVeg->m_boxExtends[3] = m_boxExtends[3];
  621.         pDestVeg->m_boxExtends[4] = m_boxExtends[4];
  622.         pDestVeg->m_boxExtends[5] = m_boxExtends[5];
  623.         pDestVeg->m_ucRadius = m_ucRadius;
  624.  
  625.         //IRenderNode member vars
  626.         //      We cannot just copy over due to issues with the linked list of IRenderNode objects
  627.         pDestVeg->m_fWSMaxViewDist = m_fWSMaxViewDist;
  628.         pDestVeg->m_dwRndFlags = m_dwRndFlags;
  629.         pDestVeg->m_pOcNode = m_pOcNode;
  630.         pDestVeg->m_ucViewDistRatio = m_ucViewDistRatio;
  631.         pDestVeg->m_ucLodRatio = m_ucLodRatio;
  632.         pDestVeg->m_cShadowLodBias = m_cShadowLodBias;
  633.         pDestVeg->m_nInternalFlags = m_nInternalFlags;
  634.         pDestVeg->m_nMaterialLayers = m_nMaterialLayers;
  635.  
  636.         return pDestVeg;
  637. }
  638.  
  639. void CVegetation::ShutDown()
  640. {
  641.         Get3DEngine()->FreeRenderNodeState(this); // Also does unregister entity.
  642.         assert(!m_pTempData);
  643.  
  644.         // TODO: Investigate thread-safety wrt tempdata here.
  645.         Dephysicalize();
  646.  
  647.         SAFE_DELETE(m_pSpriteInfo);
  648.         SAFE_DELETE(m_pDeformable);
  649. }
  650.  
  651. CVegetation::~CVegetation()
  652. {
  653.         ShutDown();
  654.  
  655.         GetInstCount(GetRenderNodeType())--;
  656.  
  657.         Get3DEngine()->m_lstKilledVegetations.Delete(this);
  658. }
  659.  
  660. void CVegetation::Dematerialize()
  661. {
  662. }
  663.  
  664. void CVegetation::Dephysicalize(bool bKeepIfReferenced)
  665. {
  666.         // delete old physics
  667.         if (m_pPhysEnt && GetSystem()->GetIPhysicalWorld()->DestroyPhysicalEntity(m_pPhysEnt, 4 * (int)bKeepIfReferenced))
  668.         {
  669.                 m_pPhysEnt = 0;
  670.                 if (m_pTempData && m_pTempData->userData.m_pFoliage)
  671.                 {
  672.                         m_pTempData->userData.m_pFoliage->Release();
  673.                         m_pTempData->userData.m_pFoliage = NULL;
  674.                         InvalidatePermanentRenderObject();
  675.                 }
  676.         }
  677. }
  678.  
  679. void CVegetation::GetMemoryUsage(ICrySizer* pSizer) const
  680. {
  681.         SIZER_COMPONENT_NAME(pSizer, "Vegetation");
  682.         pSizer->AddObject(this, sizeof(*this));
  683.         if (m_pSpriteInfo)
  684.                 pSizer->Add(*m_pSpriteInfo);
  685. }
  686.  
  687. const char* CVegetation::GetName() const
  688. {
  689.         return (GetStatObjGroupSize() && GetStatObj()) ?
  690.                GetStatObj()->GetFilePath() : "StatObjNotSet";
  691. }
  692. //////////////////////////////////////////////////////////////////////////
  693. IRenderMesh* CVegetation::GetRenderMesh(int nLod)
  694. {
  695.         CStatObj* pStatObj(GetStatObj());
  696.  
  697.         if (!pStatObj)
  698.         {
  699.                 return NULL;
  700.         }
  701.  
  702.         pStatObj = (CStatObj*)pStatObj->GetLodObject(nLod);
  703.  
  704.         if (!pStatObj)
  705.         {
  706.                 return NULL;
  707.         }
  708.  
  709.         return pStatObj->GetRenderMesh();
  710. }
  711. //////////////////////////////////////////////////////////////////////////
  712. IMaterial* CVegetation::GetMaterialOverride()
  713. {
  714.         StatInstGroup& vegetGroup = GetStatObjGroup();
  715.  
  716.         if (vegetGroup.pMaterial)
  717.                 return vegetGroup.pMaterial;
  718.  
  719.         return NULL;
  720. }
  721.  
  722. float CVegetation::GetZAngle() const
  723. {
  724.         return BYTE2RAD(m_ucAngle);
  725. }
  726.  
  727. void CVegetation::OnRenderNodeBecomeVisible(const SRenderingPassInfo& passInfo)
  728. {
  729.         assert(m_pTempData);
  730.         SRenderNodeTempData::SUserData& userData = m_pTempData->userData;
  731.  
  732.         Matrix34A mtx;
  733.         CalcMatrix(mtx);
  734.         userData.objMat = mtx;
  735.  
  736.         const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  737.         StatInstGroup& vegetGroup = GetStatObjGroup();
  738.         float fEntDistance2D = sqrt_tpl(vCamPos.GetSquaredDistance2D(m_vPos)) * passInfo.GetZoomFactor();
  739.         float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, GetBBox())) * passInfo.GetZoomFactor();
  740.  
  741.         userData.nWantedLod = CObjManager::GetObjectLOD(this, fEntDistance);
  742. }
  743.  
  744. const float CVegetation::GetRadius() const
  745. {
  746.         const float* const __restrict cpDecompTable = g_scBoxDecomprTable;
  747.         return cpDecompTable[m_ucRadius];
  748. }
  749.  
  750. void CVegetation::SetBBox(const AABB& WSBBox)
  751. {
  752.         SetBoxExtends(m_boxExtends, &m_ucRadius, WSBBox, m_vPos);
  753. }
  754.  
  755. void CVegetation::UpdateSpriteInfo(SVegetationSpriteInfo& si, float fSpriteAmount, SSectorTextureSet* pTerrainTexInfo, const SRenderingPassInfo& passInfo) const
  756. {
  757.         const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  758.         StatInstGroup& vegetGroup = GetStatObjGroup();
  759.  
  760.         const float nMin = 1;
  761.         const float nMax = 255;
  762.  
  763.         si.ucAlphaTestRef = (byte)nMin;
  764.  
  765.         si.pTerrainTexInfo = vegetGroup.bUseTerrainColor ? pTerrainTexInfo : NULL;
  766.         si.pVegetation = this;
  767.  
  768.         Matrix34A matRotZ;
  769.  
  770.         float fZAngle = GetZAngle();
  771.         if (fZAngle != 0.0f)
  772.         {
  773.                 matRotZ.SetRotationZ(fZAngle);
  774.         }
  775.         else
  776.         {
  777.                 matRotZ.SetIdentity();
  778.         }
  779.  
  780.         Vec3 vCenter = GetStatObj()->GetVegCenter() * GetScale();
  781.         vCenter = matRotZ * vCenter;
  782.         Vec3 vD1 = m_vPos + vCenter - vCamPos;
  783.  
  784.         float fAngle = atan2_tpl(vD1.x, vD1.y) + fZAngle;
  785.         int dwAngle = ((int)(fAngle * (255.0f / (2.0f * gf_PI)))) & 0xff;
  786.         si.ucSlotId = (((dwAngle + FAR_TEX_HAL_ANGLE) * FAR_TEX_COUNT) / 256) % FAR_TEX_COUNT;
  787.         assert(si.ucSlotId < FAR_TEX_COUNT);
  788.  
  789.         si.sp = Sphere(GetPos() + vCenter, GetScale() * vegetGroup.fVegRadius);
  790.  
  791.         si.pLightInfo = &vegetGroup.m_arrSSpriteLightInfo[si.ucSlotId];
  792.  
  793.         si.pStatInstGroup = &vegetGroup;
  794.         si.fScaleV = GetScale() * si.pStatInstGroup->fVegRadiusVert;
  795.         si.fScaleH = GetScale() * si.pStatInstGroup->fVegRadiusHor;
  796. };
  797.  
  798. IFoliage* CVegetation::GetFoliage(int nSlot)
  799. {
  800.         if (m_pTempData)
  801.                 return m_pTempData->userData.m_pFoliage;
  802.  
  803.         return 0;
  804. }
  805.  
  806. IPhysicalEntity* CVegetation::GetBranchPhys(int idx, int nSlot)
  807. {
  808.         IFoliage* pFoliage = GetFoliage();
  809.         return pFoliage && (unsigned int)idx < (unsigned int)((CStatObjFoliage*)pFoliage)->m_nRopes ? ((CStatObjFoliage*)pFoliage)->m_pRopes[idx] : 0;
  810. }
  811.  
  812. void CVegetation::SetStatObjGroupIndex(int nVegetationGroupIndex)
  813. {
  814.         m_nObjectTypeIndex = nVegetationGroupIndex;
  815.         CheckCreateDeformable();
  816.         InvalidatePermanentRenderObject();
  817. }
  818.  
  819. void CVegetation::SetMatrix(const Matrix34& mat)
  820. {
  821.         m_vPos = mat.GetTranslation();
  822.         if (m_pDeformable)
  823.                 m_pDeformable->BakeDeform(mat);
  824. }
  825.  
  826. void CVegetation::CheckCreateDeformable()
  827. {
  828.         if (CStatObj* pStatObj = GetStatObj())
  829.         {
  830.                 if (pStatObj->IsDeformable())
  831.                 {
  832.                         Matrix34A tm;
  833.                         CalcMatrix(tm);
  834.                         SAFE_DELETE(m_pDeformable);
  835. #ifdef SEG_WORLD
  836.                         m_pDeformable = new CDeformableNode(m_nStaticTypeSlot);
  837. #else
  838.                         m_pDeformable = new CDeformableNode(0);
  839. #endif
  840.                         m_pDeformable->SetStatObj(pStatObj);
  841.                         m_pDeformable->CreateDeformableSubObject(true, tm, NULL);
  842.                 }
  843.                 else
  844.                         SAFE_DELETE(m_pDeformable);
  845.         }
  846. }
  847.  
  848. void CVegetation::OffsetPosition(const Vec3& delta)
  849. {
  850.         if (m_pTempData) m_pTempData->OffsetPosition(delta);
  851.         // GetBBox before moving position
  852.         AABB aabb = GetBBox();
  853.         if (m_bApplyPhys)
  854.                 gEnv->pPhysicalWorld->UnregisterBBoxInPODGrid(&aabb.min);
  855.  
  856.         m_vPos += delta;
  857.         aabb.Move(delta);
  858.  
  859.         // SetBBox after new position is applied
  860.         SetBBox(aabb);
  861.         if (m_bApplyPhys)
  862.                 gEnv->pPhysicalWorld->RegisterBBoxInPODGrid(&aabb.min);
  863.  
  864.         if (m_pPhysEnt)
  865.         {
  866.                 pe_params_pos par_pos;
  867.                 m_pPhysEnt->GetParams(&par_pos);
  868.                 par_pos.pos = m_vPos;
  869.                 m_pPhysEnt->SetParams(&par_pos);
  870.         }
  871. }
  872.  
  873. bool CVegetation::GetLodDistances(const SFrameLodInfo& frameLodInfo, float* distances) const
  874. {
  875.         StatInstGroup& vegetGroup = GetStatObjGroup();
  876.         CStatObj* pStatObj = vegetGroup.GetStatObj();
  877.  
  878.         const float fEntityLodRatio = GetLodRatioNormalized();
  879.         if (pStatObj && fEntityLodRatio > 0.0f)
  880.         {
  881.                 const float fDistMultiplier = 1.0f / (fEntityLodRatio * frameLodInfo.fTargetSize);
  882.                 const float lodDistance = pStatObj->GetLodDistance();
  883.  
  884.                 for (uint i = 0; i < SMeshLodInfo::s_nMaxLodCount; ++i)
  885.                 {
  886.                         distances[i] = lodDistance * (i + 1) * fDistMultiplier;
  887.                 }
  888.         }
  889.         else
  890.         {
  891.                 for (uint i = 0; i < SMeshLodInfo::s_nMaxLodCount; ++i)
  892.                 {
  893.                         distances[i] = FLT_MAX;
  894.                 }
  895.         }
  896.  
  897.         return true;
  898. }
  899.  
  900. const AABB CVegetation::GetBBox() const
  901. {
  902.         AABB aabb;
  903.         FillBBoxFromExtends(aabb, m_boxExtends, m_vPos);
  904.         return aabb;
  905. }
  906.  
  907. void CVegetation::UpdateRndFlags()
  908. {
  909.         StatInstGroup& vegetGroup = GetStatObjGroup();
  910.  
  911.         const auto dwFlagsToUpdate =
  912.                 ERF_CASTSHADOWMAPS | ERF_DYNAMIC_DISTANCESHADOWS | ERF_HIDABLE | ERF_PICKABLE
  913.                 | ERF_SPEC_BITS_MASK | ERF_OUTDOORONLY | ERF_ACTIVE_LAYER | ERF_GI_MODE_BITS_MASK;
  914.  
  915.         m_dwRndFlags &= ~dwFlagsToUpdate;
  916.         m_dwRndFlags |= vegetGroup.m_dwRndFlags & (dwFlagsToUpdate | ERF_HAS_CASTSHADOWMAPS);
  917.  
  918.         IRenderNode::SetLodRatio((int)(vegetGroup.fLodDistRatio * 100.f));
  919.         IRenderNode::SetViewDistRatio((int)(vegetGroup.fMaxViewDistRatio * 100.f));
  920. }
  921.  
  922. void CVegetation::FillBBox(AABB& aabb)
  923. {
  924.         FillBBoxFromExtends(aabb, m_boxExtends, m_vPos);
  925. }
  926.  
  927. EERType CVegetation::GetRenderNodeType()
  928. {
  929.         return eERType_Vegetation;
  930. }
  931.  
  932. float CVegetation::GetMaxViewDist()
  933. {
  934.         StatInstGroup& group = GetStatObjGroup();
  935.         CStatObj* pStatObj = (CStatObj*)(IStatObj*)group.pStatObj;
  936.         if (pStatObj)
  937.         {
  938.                 if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
  939.                         return max(GetCVars()->e_ViewDistMin, group.fVegRadius * CVegetation::GetScale() * GetCVars()->e_ViewDistRatioDetail * GetViewDistRatioNormilized());
  940.  
  941.                 return max(GetCVars()->e_ViewDistMin, group.fVegRadius * CVegetation::GetScale() * GetCVars()->e_ViewDistRatioVegetation * GetViewDistRatioNormilized());
  942.         }
  943.  
  944.         return 0;
  945. }
  946.  
  947. IStatObj* CVegetation::GetEntityStatObj(unsigned int nPartId, unsigned int nSubPartId, Matrix34A* pMatrix, bool bReturnOnlyVisible)
  948. {
  949.         if (nPartId != 0)
  950.                 return 0;
  951.  
  952.         if (pMatrix)
  953.         {
  954.                 if (m_pTempData)
  955.                 {
  956.                         *pMatrix = m_pTempData->userData.objMat;
  957.                 }
  958.                 else
  959.                 {
  960.                         Matrix34A tm;
  961.                         CalcMatrix(tm);
  962.                         *pMatrix = tm;
  963.                 }
  964.         }
  965.  
  966.         return GetStatObj();
  967. }
  968.  
  969. Vec3 CVegetation::GetPos(bool bWorldOnly) const
  970. {
  971.         assert(bWorldOnly);
  972.         return m_vPos;
  973. }
  974.  
  975. IMaterial* CVegetation::GetMaterial(Vec3* pHitPos) const
  976. {
  977.         StatInstGroup& vegetGroup = GetStatObjGroup();
  978.  
  979.         if (vegetGroup.pMaterial)
  980.                 return vegetGroup.pMaterial;
  981.  
  982.         if (CStatObj* pBody = vegetGroup.GetStatObj())
  983.                 return pBody->GetMaterial();
  984.  
  985.         return NULL;
  986. }
  987.  
downloadVegetation.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