BVB Source Codes

CRYENGINE Show Brush.cpp Source code

Return Download CRYENGINE: download Brush.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:   brush.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description:
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include "StatObj.h"
  16. #include "ObjMan.h"
  17. #include "VisAreas.h"
  18. #include "terrain_sector.h"
  19. #include "PolygonClipContext.h"
  20. #include "3dEngine.h"
  21. #include "IndexedMesh.h"
  22. #include "Brush.h"
  23. #include "terrain.h"
  24.  
  25. #include <CryEntitySystem/IEntity.h>
  26.  
  27. CBrush::CBrush()
  28.         : m_bVehicleOnlyPhysics(0)
  29.         , m_bDrawLast(0)
  30.         , m_bNoPhysicalize(0)
  31. {
  32.         m_WSBBox.min = m_WSBBox.max = Vec3(ZERO);
  33.         m_dwRndFlags = 0;
  34.         m_Matrix.SetIdentity();
  35.         m_pPhysEnt = 0;
  36.         m_pMaterial = 0;
  37.         m_nLayerId = 0;
  38.         m_pStatObj = NULL;
  39.         m_pMaterial = NULL;
  40.         m_collisionClassIdx = 0;
  41.         m_pDeform = NULL;
  42.  
  43.         GetInstCount(GetRenderNodeType())++;
  44. }
  45.  
  46. CBrush::~CBrush()
  47. {
  48.         INDENT_LOG_DURING_SCOPE(true, "Destroying brush \"%s\"", this->GetName());
  49.  
  50.         if (m_pFoliage)
  51.         {
  52.                 static IFoliage* g_pFoliage0 = nullptr;
  53.                 ((CStatObjFoliage*)m_pFoliage)->m_ppThis = &g_pFoliage0;
  54.                 m_pFoliage->Release();
  55.         }
  56.         Dephysicalize();
  57.         Get3DEngine()->FreeRenderNodeState(this);
  58.  
  59.         m_pStatObj = NULL;
  60.         if (m_pDeform)
  61.                 delete m_pDeform;
  62.  
  63.         if (m_pCameraSpacePos)
  64.         {
  65.                 delete m_pCameraSpacePos;
  66.                 m_pCameraSpacePos = nullptr;
  67.         }
  68.  
  69.         if (m_pTempData)
  70.         {
  71.                 m_pTempData->MarkForDelete();
  72.                 m_pTempData = nullptr;
  73.         }
  74.  
  75.         GetInstCount(GetRenderNodeType())--;
  76. }
  77.  
  78. const char* CBrush::GetEntityClassName() const
  79. {
  80.         return "Brush";
  81. }
  82.  
  83. const char* CBrush::GetName() const
  84. {
  85.         if (m_pStatObj)
  86.                 return m_pStatObj->GetFilePath();
  87.         return "StatObjNotSet";
  88. }
  89.  
  90. bool CBrush::HasChanged()
  91. {
  92.         return false;
  93. }
  94.  
  95. #if CRY_PLATFORM_WINDOWS && CRY_PLATFORM_64BIT
  96.         #pragma warning( push )               //AMD Port
  97.         #pragma warning( disable : 4311 )
  98. #endif
  99.  
  100. CLodValue CBrush::ComputeLod(int wantedLod, const SRenderingPassInfo& passInfo)
  101. {
  102.         int nLodA = -1;
  103.  
  104.         if (CStatObj* pStatObj = m_pStatObj)
  105.         {
  106.                 const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  107.                 const float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, CBrush::GetBBox())) * passInfo.GetZoomFactor();
  108.  
  109.                 // update LOD faster in zoom mode
  110.                 if (passInfo.IsGeneralPass() && passInfo.IsZoomActive())
  111.                 {
  112.                         wantedLod = CObjManager::GetObjectLOD(this, fEntDistance);
  113.                 }
  114.  
  115.                 nLodA = CLAMP(wantedLod, pStatObj->GetMinUsableLod(), (int)pStatObj->m_nMaxUsableLod);
  116.  
  117.                 if (!(pStatObj->m_nFlags & STATIC_OBJECT_COMPOUND))
  118.                         nLodA = pStatObj->FindNearesLoadedLOD(nLodA, true);
  119.         }
  120.  
  121.         return CLodValue(nLodA, 0, -1);
  122. }
  123.  
  124. void CBrush::Render(const struct SRendParams& _EntDrawParams, const SRenderingPassInfo& passInfo)
  125. {
  126.         FUNCTION_PROFILER_3DENGINE;
  127.  
  128.         if (!m_pStatObj || m_dwRndFlags & ERF_HIDDEN)
  129.                 return; //false;
  130.  
  131.         if (m_dwRndFlags & ERF_COLLISION_PROXY || m_dwRndFlags & ERF_RAYCAST_PROXY)
  132.         {
  133.                 // Collision proxy is visible in Editor while in editing mode.
  134.                 if (!gEnv->IsEditor() || !gEnv->IsEditing())
  135.                 {
  136.                         if (GetCVars()->e_DebugDraw == 0)
  137.                                 return; //true;
  138.                 }
  139.         }
  140.  
  141.         // some parameters will be modified
  142.         SRendParams rParms = _EntDrawParams;
  143.  
  144.         if (m_nMaterialLayers)
  145.                 rParms.nMaterialLayers = m_nMaterialLayers;
  146.  
  147.         rParms.pMatrix = &m_Matrix;
  148.         rParms.pMaterial = m_pMaterial;
  149.         rParms.nEditorSelectionID = m_nEditorSelectionID;
  150.  
  151.         rParms.dwFObjFlags |= (m_dwRndFlags & ERF_FOB_RENDER_AFTER_POSTPROCESSING) ? FOB_RENDER_AFTER_POSTPROCESSING : 0;
  152.         //rParms.dwFObjFlags |= (m_dwRndFlags & ERF_FOB_NEAREST) ? FOB_NEAREST : 0;
  153.         rParms.dwFObjFlags |= FOB_TRANS_MASK;
  154.  
  155.         m_pStatObj->Render(rParms, passInfo);
  156. }
  157.  
  158. #if CRY_PLATFORM_WINDOWS && CRY_PLATFORM_64BIT
  159.         #pragma warning( pop )                //AMD Port
  160. #endif
  161.  
  162. void CBrush::SetMatrix(const Matrix34& mat)
  163. {
  164.         Get3DEngine()->UnRegisterEntityAsJob(this);
  165.  
  166.         bool replacePhys = false;
  167.  
  168.         if (!IsMatrixValid(mat))
  169.         {
  170.                 Warning("Error: IRenderNode::SetMatrix: Invalid matrix passed from the editor - ignored, reset to identity: %s", GetName());
  171.                 replacePhys = true;
  172.                 m_Matrix.SetIdentity();
  173.         }
  174.         else
  175.         {
  176.                 replacePhys = fabs(mat.GetColumn(0).len() - m_Matrix.GetColumn(0).len())
  177.                               + fabs(mat.GetColumn(1).len() - m_Matrix.GetColumn(1).len())
  178.                               + fabs(mat.GetColumn(2).len() - m_Matrix.GetColumn(2).len()) > FLT_EPSILON;
  179.                 m_Matrix = mat;
  180.         }
  181.         InvalidatePermanentRenderObjectMatrix();
  182.  
  183.         pe_params_foreign_data foreignData;
  184.         foreignData.iForeignFlags = 0;
  185.         if (!replacePhys && m_pPhysEnt)
  186.         {
  187.                 m_pPhysEnt->GetParams(&foreignData);
  188.                 replacePhys = !(foreignData.iForeignFlags & PFF_OUTDOOR_AREA) != !(m_dwRndFlags & ERF_NODYNWATER);
  189.         }
  190.  
  191.         CalcBBox();
  192.  
  193.         Get3DEngine()->RegisterEntity(this);
  194.         if (replacePhys)
  195.                 Dephysicalize();
  196.         if (!m_pPhysEnt)
  197.         {
  198.                 if (!m_bNoPhysicalize)
  199.                 {
  200.                         Physicalize();
  201.                 }
  202.         }
  203.         else
  204.         {
  205.                 // Just move physics.
  206.                 pe_status_placeholder spc;
  207.                 if (m_pPhysEnt->GetStatus(&spc) && !spc.pFullEntity)
  208.                 {
  209.                         pe_params_bbox pbb;
  210.                         pbb.BBox[0] = m_WSBBox.min;
  211.                         pbb.BBox[1] = m_WSBBox.max;
  212.                         m_pPhysEnt->SetParams(&pbb);
  213.                 }
  214.                 else
  215.                 {
  216.                         pe_params_pos par_pos;
  217.                         par_pos.pos = m_Matrix.GetTranslation();
  218.                         par_pos.q = Quat(Matrix33(m_Matrix) * Diag33(m_Matrix.GetColumn(0).len(), m_Matrix.GetColumn(1).len(), m_Matrix.GetColumn(2).len()).invert());
  219.                         m_pPhysEnt->SetParams(&par_pos);
  220.                 }
  221.  
  222.                 //////////////////////////////////////////////////////////////////////////
  223.                 // Update physical flags.
  224.                 //////////////////////////////////////////////////////////////////////////
  225.                 if (m_dwRndFlags & ERF_HIDABLE)
  226.                         foreignData.iForeignFlags |= PFF_HIDABLE;
  227.                 else
  228.                         foreignData.iForeignFlags &= ~PFF_HIDABLE;
  229.                 if (m_dwRndFlags & ERF_HIDABLE_SECONDARY)
  230.                         foreignData.iForeignFlags |= PFF_HIDABLE_SECONDARY;
  231.                 else
  232.                         foreignData.iForeignFlags &= ~PFF_HIDABLE_SECONDARY;
  233.                 // flag to exclude from AI triangulation
  234.                 if (m_dwRndFlags & ERF_EXCLUDE_FROM_TRIANGULATION)
  235.                         foreignData.iForeignFlags |= PFF_EXCLUDE_FROM_STATIC;
  236.                 else
  237.                         foreignData.iForeignFlags &= ~PFF_EXCLUDE_FROM_STATIC;
  238.                 m_pPhysEnt->SetParams(&foreignData);
  239.         }
  240.  
  241.         if (m_pDeform)
  242.                 m_pDeform->BakeDeform(m_Matrix);
  243.  
  244.         m_lastMoveFrameId = gEnv->nMainFrameID;
  245. }
  246.  
  247. void CBrush::CalcBBox()
  248. {
  249.         m_WSBBox.min = SetMaxBB();
  250.         m_WSBBox.max = SetMinBB();
  251.  
  252.         if (!m_pStatObj)
  253.                 return;
  254.  
  255.         m_WSBBox.min = m_pStatObj->GetBoxMin();
  256.         m_WSBBox.max = m_pStatObj->GetBoxMax();
  257.         m_WSBBox.SetTransformedAABB(m_Matrix, m_WSBBox);
  258. }
  259.  
  260. void CBrush::Physicalize(bool bInstant)
  261. {
  262.         m_bNoPhysicalize = false;
  263.         PhysicalizeOnHeap(NULL, bInstant);
  264. }
  265.  
  266. void CBrush::PhysicalizeOnHeap(IGeneralMemoryHeap* pHeap, bool bInstant)
  267. {
  268.         MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Physics, 0, "Brush: %s", m_pStatObj ? m_pStatObj->GetFilePath() : "(unknown)");
  269.  
  270.         if (m_pStatObj && (m_pStatObj->GetBreakableByGame() || m_pStatObj->GetIDMatBreakable() != -1))
  271.         {
  272.                 pHeap = m_p3DEngine->GetBreakableBrushHeap();
  273.         }
  274.  
  275.         float fScaleX = m_Matrix.GetColumn(0).len();
  276.         float fScaleY = m_Matrix.GetColumn(1).len();
  277.         float fScaleZ = m_Matrix.GetColumn(2).len();
  278.  
  279.         if (!m_pStatObj || !m_pStatObj->IsPhysicsExist())
  280.         {
  281.                 // skip non uniform scaled object or objects without physics
  282.  
  283.                 // Check if we are acompound object.
  284.                 if (m_pStatObj && !m_pStatObj->IsPhysicsExist() && (m_pStatObj->GetFlags() & STATIC_OBJECT_COMPOUND))
  285.                 {
  286.                         // Try to physicalize compound object.
  287.                 }
  288.                 else
  289.                 {
  290.                         Dephysicalize();
  291.                         return;
  292.                 }
  293.         }
  294.  
  295.         AABB WSBBox = GetBBox();
  296.         bool notPodable = max(WSBBox.max.x - WSBBox.min.x, WSBBox.max.y - WSBBox.min.y) > Get3DEngine()->GetCVars()->e_OnDemandMaxSize;
  297.         if (!(GetCVars()->e_OnDemandPhysics & 0x2)
  298.             || notPodable
  299.             || (m_pStatObj->GetFlags() & STATIC_OBJECT_COMPOUND))
  300.                 bInstant = true;
  301.  
  302.         if (m_pDeform)
  303.         {
  304.                 m_pDeform->CreateDeformableSubObject(true, GetMatrix(), pHeap);
  305.         }
  306.  
  307.         if (!bInstant)
  308.         {
  309.                 gEnv->pPhysicalWorld->RegisterBBoxInPODGrid(&WSBBox.min);
  310.                 return;
  311.         }
  312.  
  313.         // create new
  314.         if (!m_pPhysEnt)
  315.         {
  316.                 m_pPhysEnt = GetSystem()->GetIPhysicalWorld()->CreatePhysicalEntity(PE_STATIC, NULL, (IRenderNode*)this, PHYS_FOREIGN_ID_STATIC, -1, pHeap);
  317.                 if (!m_pPhysEnt)
  318.                         return;
  319.         }
  320.  
  321.         pe_action_remove_all_parts remove_all;
  322.         m_pPhysEnt->Action(&remove_all);
  323.  
  324.         pe_geomparams params;
  325.         if (m_pStatObj->GetPhysGeom(PHYS_GEOM_TYPE_DEFAULT))
  326.         {
  327.                 if (GetRndFlags() & ERF_COLLISION_PROXY)
  328.                 {
  329.                         // Collision proxy only collides with players and vehicles.
  330.                         params.flags = geom_colltype_player | geom_colltype_vehicle;
  331.                 }
  332.                 if (GetRndFlags() & ERF_RAYCAST_PROXY)
  333.                 {
  334.                         // Collision proxy only collides with players and vehicles.
  335.                         params.flags = geom_colltype_ray;
  336.                 }
  337.                 /*if (m_pStatObj->m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE])
  338.                    params.flags &= ~geom_colltype_ray;*/
  339.                 if (m_bVehicleOnlyPhysics || (m_pStatObj->GetVehicleOnlyPhysics() != 0))
  340.                         params.flags = geom_colltype_vehicle;
  341.                 if (GetCVars()->e_ObjQuality != CONFIG_LOW_SPEC)
  342.                 {
  343.                         params.idmatBreakable = m_pStatObj->GetIDMatBreakable();
  344.                         if (m_pStatObj->GetBreakableByGame())
  345.                                 params.flags |= geom_manually_breakable;
  346.                 }
  347.                 else
  348.                         params.idmatBreakable = -1;
  349.         }
  350.  
  351.         Matrix34 mtxScale;
  352.         mtxScale.SetScale(Vec3(fScaleX, fScaleY, fScaleZ));
  353.         params.pMtx3x4 = &mtxScale;
  354.         m_pStatObj->Physicalize(m_pPhysEnt, &params);
  355.  
  356.         if (m_dwRndFlags & (ERF_HIDABLE | ERF_HIDABLE_SECONDARY | ERF_EXCLUDE_FROM_TRIANGULATION | ERF_NODYNWATER))
  357.         {
  358.                 pe_params_foreign_data foreignData;
  359.                 m_pPhysEnt->GetParams(&foreignData);
  360.                 if (m_dwRndFlags & ERF_HIDABLE)
  361.                         foreignData.iForeignFlags |= PFF_HIDABLE;
  362.                 if (m_dwRndFlags & ERF_HIDABLE_SECONDARY)
  363.                         foreignData.iForeignFlags |= PFF_HIDABLE_SECONDARY;
  364.                 //[PETAR] new flag to exclude from triangulation
  365.                 if (m_dwRndFlags & ERF_EXCLUDE_FROM_TRIANGULATION)
  366.                         foreignData.iForeignFlags |= PFF_EXCLUDE_FROM_STATIC;
  367.                 if (m_dwRndFlags & ERF_NODYNWATER)
  368.                         foreignData.iForeignFlags |= PFF_OUTDOOR_AREA;
  369.                 m_pPhysEnt->SetParams(&foreignData);
  370.         }
  371.  
  372.         pe_params_flags par_flags;
  373.         par_flags.flagsOR = pef_never_affect_triggers | pef_log_state_changes;
  374.         m_pPhysEnt->SetParams(&par_flags);
  375.  
  376.         pe_params_pos par_pos;
  377.         par_pos.pos = m_Matrix.GetTranslation();
  378.         par_pos.q = Quat(Matrix33(m_Matrix) * Diag33(fScaleX, fScaleY, fScaleZ).invert());
  379.         par_pos.bEntGridUseOBB = 1;
  380.         m_pPhysEnt->SetParams(&par_pos);
  381.  
  382.         pe_params_collision_class pcc;
  383.         Get3DEngine()->GetCollisionClass(pcc.collisionClassOR, m_collisionClassIdx);
  384.         m_pPhysEnt->SetParams(&pcc);
  385.  
  386.         if (m_pMaterial)
  387.                 UpdatePhysicalMaterials();
  388.  
  389.         if (GetRndFlags() & ERF_NODYNWATER)
  390.         {
  391.                 pe_params_part ppart;
  392.                 ppart.flagsAND = ~geom_floats;
  393.                 m_pPhysEnt->SetParams(&ppart);
  394.         }
  395. }
  396.  
  397. bool CBrush::PhysicalizeFoliage(bool bPhysicalize, int iSource, int nSlot)
  398. {
  399.         if (nSlot < 0 || !m_pStatObj->GetSubObjectCount())
  400.         {
  401.                 bool res = false;
  402.                 for (int i = 0; i < m_pStatObj->GetSubObjectCount(); i++)
  403.                         res = res || PhysicalizeFoliage(bPhysicalize, iSource, i);
  404.                 if (!res)
  405.                 {
  406.                         if (bPhysicalize)
  407.                         {
  408.                                 res = m_pStatObj->PhysicalizeFoliage(m_pPhysEnt, m_Matrix, m_pFoliage) != 0;
  409.                         }
  410.                         else if (m_pFoliage)
  411.                         {
  412.                                 m_pFoliage->Release();
  413.                                 m_pFoliage = nullptr;
  414.                         }
  415.                 }
  416.                 return res;
  417.         }
  418.  
  419.         if (IStatObj::SSubObject* pSubObj = m_pStatObj->GetSubObject(nSlot))
  420.                 if (bPhysicalize)
  421.                 {
  422.                         if (!pSubObj->pStatObj || !((CStatObj*)pSubObj->pStatObj)->m_nSpines)
  423.                                 return false;
  424.                         if (!(m_pStatObj->GetFlags() & STATIC_OBJECT_CLONE))
  425.                         {
  426.                                 m_pStatObj = (CStatObj*)m_pStatObj->Clone(false, false, false);
  427.                                 pSubObj = m_pStatObj->GetSubObject(nSlot);
  428.                         }
  429.                         Matrix34 mtx = m_Matrix * pSubObj->localTM;
  430.                         pSubObj->pStatObj->PhysicalizeFoliage(m_pPhysEnt, mtx, pSubObj->pFoliage, GetCVars()->e_FoliageBranchesTimeout, iSource);
  431.                         return pSubObj->pFoliage != 0;
  432.                 }
  433.                 else if (pSubObj->pFoliage)
  434.                 {
  435.                         pSubObj->pFoliage->Release();
  436.                         return true;
  437.                 }
  438.         return false;
  439. }
  440.  
  441. IFoliage* CBrush::GetFoliage(int nSlot)
  442. {
  443.         if (!m_pStatObj)
  444.                 return nullptr;
  445.         IStatObj::SSubObject* pSubObj = m_pStatObj->GetSubObject(nSlot);
  446.         if (pSubObj)
  447.                 return pSubObj->pFoliage;
  448.         return m_pFoliage;
  449. }
  450.  
  451. //////////////////////////////////////////////////////////////////////////
  452. void CBrush::UpdatePhysicalMaterials(int bThreadSafe)
  453. {
  454.         if (!m_pPhysEnt)
  455.                 return;
  456.  
  457.         if ((GetRndFlags() & ERF_COLLISION_PROXY) && m_pPhysEnt)
  458.         {
  459.                 pe_params_part ppart;
  460.                 ppart.flagsAND = 0;
  461.                 ppart.flagsOR = geom_colltype_player | geom_colltype_vehicle;
  462.                 m_pPhysEnt->SetParams(&ppart);
  463.         }
  464.  
  465.         if ((GetRndFlags() & ERF_RAYCAST_PROXY) && m_pPhysEnt)
  466.         {
  467.                 pe_params_part ppart;
  468.                 ppart.flagsAND = 0;
  469.                 ppart.flagsOR = geom_colltype_ray;
  470.                 m_pPhysEnt->SetParams(&ppart);
  471.         }
  472.  
  473.         if (m_pMaterial)
  474.         {
  475.                 // Assign custom material to physics.
  476.                 int surfaceTypesId[MAX_SUB_MATERIALS];
  477.                 memset(surfaceTypesId, 0, sizeof(surfaceTypesId));
  478.                 int i, numIds = m_pMaterial->FillSurfaceTypeIds(surfaceTypesId);
  479.                 ISurfaceTypeManager* pSurfaceTypeManager = Get3DEngine()->GetMaterialManager()->GetSurfaceTypeManager();
  480.                 ISurfaceType* pMat;
  481.                 bool bBreakable = false;
  482.  
  483.                 for (i = 0, m_bVehicleOnlyPhysics = false; i < numIds; i++)
  484.                         if (pMat = pSurfaceTypeManager->GetSurfaceType(surfaceTypesId[i]))
  485.                         {
  486.                                 if (pMat->GetFlags() & SURFACE_TYPE_VEHICLE_ONLY_COLLISION)
  487.                                         m_bVehicleOnlyPhysics = true;
  488.                                 if (pMat->GetBreakability())
  489.                                         bBreakable = true;
  490.                         }
  491.  
  492.                 if (bBreakable && m_pStatObj)
  493.                 {
  494.                         // mark the rendermesh as KepSysMesh so that it is kept in system memory
  495.                         if (m_pStatObj->GetRenderMesh())
  496.                                 m_pStatObj->GetRenderMesh()->KeepSysMesh(true);
  497.  
  498.                         m_pStatObj->SetFlags(m_pStatObj->GetFlags() | STATIC_OBJECT_DYNAMIC);
  499.                 }
  500.                 pe_params_part ppart;
  501.                 ppart.nMats = numIds;
  502.                 ppart.pMatMapping = surfaceTypesId;
  503.                 if (m_bVehicleOnlyPhysics)
  504.                         ppart.flagsAND = geom_colltype_vehicle;
  505.                 if ((pMat = m_pMaterial->GetSurfaceType()) && pMat->GetPhyscalParams().collType >= 0)
  506.                         ppart.flagsAND = ~(geom_collides | geom_floats), ppart.flagsOR = pMat->GetPhyscalParams().collType;
  507.                 m_pPhysEnt->SetParams(&ppart, bThreadSafe);
  508.         }
  509.         else if (m_bVehicleOnlyPhysics)
  510.         {
  511.                 m_bVehicleOnlyPhysics = false;
  512.                 if (!m_pStatObj->GetVehicleOnlyPhysics())
  513.                 {
  514.                         pe_params_part ppart;
  515.                         ppart.flagsOR = geom_colltype_solid | geom_colltype_ray | geom_floats | geom_colltype_explosion;
  516.                         m_pPhysEnt->SetParams(&ppart, bThreadSafe);
  517.                 }
  518.         }
  519. }
  520.  
  521. void CBrush::Dephysicalize(bool bKeepIfReferenced)
  522. {
  523.         AABB WSBBox = GetBBox();
  524.  
  525.         // delete old physics
  526.         if (m_pPhysEnt && 0 != GetSystem()->GetIPhysicalWorld()->DestroyPhysicalEntity(m_pPhysEnt, ((int)bKeepIfReferenced) * 4))
  527.                 m_pPhysEnt = 0;
  528.  
  529.         if (!bKeepIfReferenced)
  530.         {
  531.                 if (m_pDeform)
  532.                 {
  533.                         m_pDeform->CreateDeformableSubObject(false, GetMatrix(), NULL);
  534.                 }
  535.         }
  536. }
  537.  
  538. void CBrush::Dematerialize()
  539. {
  540.         if (m_pMaterial)
  541.                 m_pMaterial = 0;
  542. }
  543.  
  544. IPhysicalEntity* CBrush::GetPhysics() const
  545. {
  546.         return m_pPhysEnt;
  547. }
  548.  
  549. //////////////////////////////////////////////////////////////////////////
  550. void CBrush::SetPhysics(IPhysicalEntity* pPhys)
  551. {
  552.         m_pPhysEnt = pPhys;
  553. }
  554.  
  555. //////////////////////////////////////////////////////////////////////////
  556. bool CBrush::IsMatrixValid(const Matrix34& mat)
  557. {
  558.         Vec3 vScaleTest = mat.TransformVector(Vec3(0, 0, 1));
  559.         float fDist = mat.GetTranslation().GetDistance(Vec3(0, 0, 0));
  560.  
  561.         if (vScaleTest.GetLength() > 1000.f || vScaleTest.GetLength() < 0.01f || fDist > 256000 ||
  562.             !_finite(vScaleTest.x) || !_finite(vScaleTest.y) || !_finite(vScaleTest.z))
  563.                 return false;
  564.  
  565.         return true;
  566. }
  567.  
  568. //////////////////////////////////////////////////////////////////////////
  569. void CBrush::SetMaterial(IMaterial* pMat)
  570. {
  571.         m_pMaterial = pMat;
  572.  
  573.         bool bCollisionProxy = false;
  574.         bool bRaycastProxy = false;
  575.  
  576.         if (pMat)
  577.         {
  578.                 if (pMat->GetFlags() & MTL_FLAG_COLLISION_PROXY)
  579.                         bCollisionProxy = true;
  580.  
  581.                 if (pMat->GetFlags() & MTL_FLAG_RAYCAST_PROXY)
  582.                 {
  583.                         bRaycastProxy = true;
  584.                 }
  585.         }
  586.         SetRndFlags(ERF_COLLISION_PROXY, bCollisionProxy);
  587.         SetRndFlags(ERF_RAYCAST_PROXY, bRaycastProxy);
  588.  
  589.         UpdatePhysicalMaterials();
  590.  
  591.         // register and get brush material id
  592.         m_pMaterial = pMat;
  593.  
  594.         InvalidatePermanentRenderObject();
  595. }
  596.  
  597. void CBrush::CheckPhysicalized()
  598. {
  599.         if (!m_pPhysEnt && !m_bNoPhysicalize)
  600.         {
  601.                 Physicalize();
  602.         }
  603. }
  604.  
  605. void CBrush::GetMemoryUsage(ICrySizer* pSizer) const
  606. {
  607.         SIZER_COMPONENT_NAME(pSizer, "Brush");
  608.         pSizer->AddObject(this, sizeof(*this));
  609. }
  610.  
  611. void CBrush::SetEntityStatObj(unsigned int nSlot, IStatObj* pStatObj, const Matrix34A* pMatrix)
  612. {
  613.         //assert(pStatObj);
  614.  
  615.         IStatObj* pPrevStatObj = m_pStatObj;
  616.  
  617.         SetStatObj(pStatObj);
  618.  
  619.         if (pMatrix)
  620.         {
  621.                 SetMatrix(*pMatrix);
  622.         }
  623.  
  624.         // If object differ we must re-physicalize.
  625.         bool bRePhysicalize = (pStatObj != pPrevStatObj) && (!pPrevStatObj || !pStatObj || (pStatObj->GetCloneSourceObject() != pPrevStatObj));
  626.  
  627.         if (bRePhysicalize && !m_bNoPhysicalize)
  628.         {
  629.                 Physicalize();
  630.         }
  631.         InvalidatePermanentRenderObject();
  632. }
  633.  
  634. //////////////////////////////////////////////////////////////////////////
  635. void CBrush::SetStatObj(IStatObj* pStatObj)
  636. {
  637.         if (pStatObj == m_pStatObj)
  638.                 return;
  639.  
  640.         if (m_pTempData)
  641.         {
  642.                 m_pTempData->MarkForDelete();
  643.                 m_pTempData = nullptr;
  644.         }
  645.  
  646.         m_pStatObj = (CStatObj*)pStatObj;
  647.         if (m_pStatObj && m_pStatObj->IsDeformable())
  648.         {
  649.                 if (!m_pDeform)
  650.                         m_pDeform = new CDeformableNode(m_nSID);
  651.                 m_pDeform->SetStatObj(static_cast<CStatObj*>(m_pStatObj.get()));
  652.                 m_pDeform->BakeDeform(GetMatrix());
  653.         }
  654.         else
  655.                 SAFE_DELETE(m_pDeform);
  656.  
  657.         if (m_pTempData)
  658.         {
  659.                 m_pTempData->MarkForDelete();
  660.                 m_pTempData = nullptr;
  661.         }
  662.  
  663.         m_nInternalFlags |= UPDATE_DECALS;
  664.  
  665.         InvalidatePermanentRenderObject();
  666. }
  667.  
  668. IRenderNode* CBrush::Clone() const
  669. {
  670.         CBrush* pDestBrush = new CBrush();
  671.  
  672.         pDestBrush->m_Matrix = m_Matrix;
  673.         //pDestBrush->m_pPhysEnt                //Don't want to copy the phys ent pointer
  674.         pDestBrush->m_pMaterial = m_pMaterial;
  675.         pDestBrush->m_pStatObj = m_pStatObj;
  676.  
  677.         pDestBrush->m_bVehicleOnlyPhysics = m_bVehicleOnlyPhysics;
  678.         pDestBrush->m_bDrawLast = m_bDrawLast;
  679.         pDestBrush->m_WSBBox = m_WSBBox;
  680.  
  681.         pDestBrush->m_collisionClassIdx = m_collisionClassIdx;
  682.         pDestBrush->m_nLayerId = m_nLayerId;
  683.  
  684.         //IRenderNode member vars
  685.         //      We cannot just copy over due to issues with the linked list of IRenderNode objects
  686.         CopyIRenderNodeData(pDestBrush);
  687.  
  688.         return pDestBrush;
  689. }
  690.  
  691. void CBrush::SetLayerId(uint16 nLayerId)
  692. {
  693.         bool bChanged = m_nLayerId != nLayerId;
  694.         m_nLayerId = nLayerId;
  695.  
  696.         if (bChanged)
  697.         {
  698.                 Get3DEngine()->C3DEngine::UpdateObjectsLayerAABB(this);
  699.         }
  700.         InvalidatePermanentRenderObject();
  701. }
  702.  
  703. IRenderMesh* CBrush::GetRenderMesh(int nLod)
  704. {
  705.         IStatObj* pStatObj = m_pStatObj ? m_pStatObj->GetLodObject(nLod) : NULL;
  706.         return pStatObj ? pStatObj->GetRenderMesh() : NULL;
  707. }
  708.  
  709. void CBrush::OffsetPosition(const Vec3& delta)
  710. {
  711.         if (m_pTempData) m_pTempData->OffsetPosition(delta);
  712.         m_Matrix.SetTranslation(m_Matrix.GetTranslation() + delta);
  713.         InvalidatePermanentRenderObjectMatrix();
  714.         m_WSBBox.Move(delta);
  715.  
  716.         if (m_pPhysEnt)
  717.         {
  718.                 pe_params_pos par_pos;
  719.                 par_pos.pos = m_Matrix.GetTranslation();
  720.                 m_pPhysEnt->SetParams(&par_pos);
  721.         }
  722. }
  723.  
  724. //////////////////////////////////////////////////////////////////////////
  725. void CBrush::SetCameraSpacePos(Vec3* pCameraSpacePos)
  726. {
  727.         if (pCameraSpacePos)
  728.         {
  729.                 if (!m_pCameraSpacePos)
  730.                         m_pCameraSpacePos = new Vec3;
  731.                 *m_pCameraSpacePos = *pCameraSpacePos;
  732.         }
  733.         else
  734.         {
  735.                 delete m_pCameraSpacePos;
  736.                 m_pCameraSpacePos = nullptr;
  737.         }
  738. }
  739.  
  740. void CBrush::SetSubObjectHideMask(hidemask subObjHideMask)
  741. {
  742.         m_nSubObjHideMask = subObjHideMask;
  743.         InvalidatePermanentRenderObject();
  744. }
  745.  
  746. bool CBrush::GetLodDistances(const SFrameLodInfo& frameLodInfo, float* distances) const
  747. {
  748.         const float fEntityLodRatio = GetLodRatioNormalized();
  749.         if (fEntityLodRatio > 0.0f)
  750.         {
  751.                 const float fDistMultiplier = 1.0f / (fEntityLodRatio * frameLodInfo.fTargetSize);
  752.                 const float lodDistance = m_pStatObj ? m_pStatObj->GetLodDistance() : FLT_MAX;
  753.  
  754.                 for (uint i = 0; i < SMeshLodInfo::s_nMaxLodCount; ++i)
  755.                 {
  756.                         distances[i] = lodDistance * (i + 1) * fDistMultiplier;
  757.                 }
  758.         }
  759.         else
  760.         {
  761.                 for (uint i = 0; i < SMeshLodInfo::s_nMaxLodCount; ++i)
  762.                 {
  763.                         distances[i] = FLT_MAX;
  764.                 }
  765.         }
  766.  
  767.         return true;
  768. }
  769.  
  770. ///////////////////////////////////////////////////////////////////////////////
  771. void CBrush::Render(const CLodValue& lodValue, const SRenderingPassInfo& passInfo, SSectorTextureSet* pTerrainTexInfo, PodArray<CDLight*>* pAffectingLights)
  772. {
  773.         FUNCTION_PROFILER_3DENGINE;
  774.  
  775.         // Collision proxy is visible in Editor while in editing mode.
  776.         if (m_dwRndFlags & (ERF_COLLISION_PROXY | ERF_RAYCAST_PROXY))
  777.         {
  778.                 if (!gEnv->IsEditor() || !gEnv->IsEditing())
  779.                         if (GetCVars()->e_DebugDraw == 0)
  780.                                 return;
  781.         }
  782.  
  783.         if (!m_pStatObj || m_dwRndFlags & ERF_HIDDEN)
  784.                 return;
  785.  
  786.         /*
  787.            if (!passInfo.IsShadowPass())
  788.            {
  789.            if (pFoliage)
  790.            {
  791.             pFoliage->SetFlags(pFoliage->GetFlags() & ~IFoliage::FLAG_FROZEN | -(int)(rParams.nMaterialLayers&MTL_LAYER_FROZEN) & IFoliage::FLAG_FROZEN);
  792.             float maxdist = GetCVars()->e_FoliageWindActivationDist;
  793.             Vec3 pos = m_worldTM.GetTranslation();
  794.             if (pStatObj && (gEnv->pSystem->GetViewCamera().GetPosition() - pos).len2() < sqr(maxdist) && gEnv->p3DEngine->GetWind(AABB(pos), false).len2() > 101.0f)
  795.               pStatObj->PhysicalizeFoliage(pEntity->GetPhysics(), m_worldTM, pFoliage, 0, 4);
  796.            }
  797.            }
  798.          */
  799.  
  800.         Matrix34 transformMatrix = m_Matrix;
  801.  
  802.         if (GetRndFlags() & ERF_FOB_NEAREST)
  803.         {
  804.                 if (passInfo.IsRecursivePass()) // Nearest objects are not rendered in the recursive passes.
  805.                         return;
  806.  
  807.                 // Nearest objects recalculate instance matrix every frame
  808.                 CalcNearestTransform(transformMatrix, passInfo);
  809.         }
  810.  
  811.         CRenderObject* pObj = 0;
  812.  
  813.         if (m_pFoliage || m_pDeform)
  814.         {
  815.                 // Foliage and deform do not support permanent render objects
  816.                 pObj = gEnv->pRenderer->EF_GetObject_Temp(passInfo.ThreadID());
  817.         }
  818.  
  819.         if (!pObj)
  820.         {
  821.                 if (GetObjManager()->AddOrCreatePersistentRenderObject(m_pTempData, pObj, &lodValue, passInfo))
  822.                 {
  823.                         if (pObj && pObj->m_bInstanceDataDirty)
  824.                         {
  825.                                 pObj->m_II.m_Matrix = transformMatrix;
  826.                         }
  827.                         return;
  828.                 }
  829.         }
  830.  
  831.         SRenderNodeTempData::SUserData& userData = m_pTempData->userData;
  832.  
  833.         const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  834.         const Vec3 vObjCenter = CBrush::GetBBox().GetCenter();
  835.         const Vec3 vObjPos = CBrush::GetPos();
  836.  
  837.         pObj->m_fDistance = pObj->m_bPermanent ? 0 : sqrt_tpl(Distance::Point_AABBSq(vCamPos, CBrush::GetBBox())) * passInfo.GetZoomFactor();
  838.  
  839.         pObj->m_pRenderNode = this;
  840.         pObj->m_II.m_Matrix = transformMatrix;
  841.         pObj->m_fAlpha = 1.f;
  842.         IF (!m_bDrawLast, 1)
  843.                 pObj->m_nSort = fastround_positive(pObj->m_fDistance * 2.0f);
  844.         else
  845.                 pObj->m_fSort = 10000.0f;
  846.  
  847.         IMaterial* pMat = pObj->m_pCurrMaterial = CBrush::GetMaterial();
  848.         pObj->m_ObjFlags |= FOB_INSHADOW | FOB_TRANS_MASK;
  849.  
  850.         pObj->m_ObjFlags |= (m_dwRndFlags & ERF_FOB_RENDER_AFTER_POSTPROCESSING) ? FOB_RENDER_AFTER_POSTPROCESSING : 0;
  851.         pObj->m_ObjFlags |= (m_dwRndFlags & ERF_FOB_NEAREST) ? FOB_NEAREST : 0;
  852.  
  853.         if (m_dwRndFlags & ERF_NO_DECALNODE_DECALS && !(gEnv->nMainFrameID - m_lastMoveFrameId < 3))
  854.         {
  855.                 pObj->m_ObjFlags |= FOB_DYNAMIC_OBJECT;
  856.         }
  857.  
  858.         if (uint8 nMaterialLayers = IRenderNode::GetMaterialLayers())
  859.         {
  860.                 uint8 nFrozenLayer = (nMaterialLayers & MTL_LAYER_FROZEN) ? MTL_LAYER_FROZEN_MASK : 0;
  861.                 uint8 nWetLayer = (nMaterialLayers & MTL_LAYER_WET) ? MTL_LAYER_WET_MASK : 0;
  862.                 pObj->m_nMaterialLayers = (uint32)(nFrozenLayer << 24) | (nWetLayer << 16);
  863.         }
  864.         else
  865.                 pObj->m_nMaterialLayers = 0;
  866.  
  867.         if (!passInfo.IsShadowPass() && m_nInternalFlags & IRenderNode::REQUIRES_NEAREST_CUBEMAP)
  868.         {
  869.                 if (!(pObj->m_nTextureID = GetObjManager()->CheckCachedNearestCubeProbe(this)) || !GetCVars()->e_CacheNearestCubePicking)
  870.                         pObj->m_nTextureID = GetObjManager()->GetNearestCubeProbe(pAffectingLights, m_pOcNode->m_pVisArea, CBrush::GetBBox());
  871.  
  872.                 m_pTempData->userData.nCubeMapId = pObj->m_nTextureID;
  873.         }
  874.  
  875.         //////////////////////////////////////////////////////////////////////////
  876.         // temp fix to update ambient color (Vlad please review!)
  877.         pObj->m_nClipVolumeStencilRef = userData.m_pClipVolume ? userData.m_pClipVolume->GetStencilRef() : 0;
  878.         if (m_pOcNode && m_pOcNode->m_pVisArea)
  879.                 pObj->m_II.m_AmbColor = m_pOcNode->m_pVisArea->GetFinalAmbientColor();
  880.         else
  881.                 pObj->m_II.m_AmbColor = Get3DEngine()->GetSkyColor();
  882.         //////////////////////////////////////////////////////////////////////////
  883.         pObj->m_editorSelectionID = m_nEditorSelectionID;
  884.  
  885.         if (pTerrainTexInfo)
  886.         {
  887.                 bool bUseTerrainColor = (GetCVars()->e_BrushUseTerrainColor == 2);
  888.                 if (pMat && GetCVars()->e_BrushUseTerrainColor == 1)
  889.                 {
  890.                         if (pMat->GetSafeSubMtl(0)->GetFlags() & MTL_FLAG_BLEND_TERRAIN)
  891.                                 bUseTerrainColor = true;
  892.                 }
  893.  
  894.                 if (bUseTerrainColor)
  895.                 {
  896.                         m_pTempData->userData.bTerrainColorWasUsed = true;
  897.                         pObj->m_ObjFlags |= FOB_BLEND_WITH_TERRAIN_COLOR;
  898.  
  899.                         pObj->m_data.m_pTerrainSectorTextureInfo = pTerrainTexInfo;
  900.                         pObj->m_nTextureID = -(int)pTerrainTexInfo->nSlot0 - 1; // nTextureID is set only for proper batching, actual texture id is same for all terrain sectors
  901.  
  902.                         {
  903.                                 float fBlendDistance = GetCVars()->e_VegetationUseTerrainColorDistance;
  904.  
  905.                                 if (fBlendDistance == 0)
  906.                                 {
  907.                                         pObj->m_data.m_fMaxViewDistance = m_fWSMaxViewDist;
  908.                                 }
  909.                                 else if (fBlendDistance > 0)
  910.                                 {
  911.                                         pObj->m_data.m_fMaxViewDistance = fBlendDistance;
  912.                                 }
  913.                                 else // if(fBlendDistance < 0)
  914.                                 {
  915.                                         pObj->m_data.m_fMaxViewDistance = abs(fBlendDistance) * GetCVars()->e_ViewDistRatio;
  916.                                 }
  917.                         }
  918.                 }
  919.                 else
  920.                         pObj->m_ObjFlags &= ~FOB_BLEND_WITH_TERRAIN_COLOR;
  921.         }
  922.  
  923.         // check the object against the water level
  924.         if (CObjManager::IsAfterWater(vObjCenter, vCamPos, passInfo, Get3DEngine()->GetWaterLevel()))
  925.                 pObj->m_ObjFlags |= FOB_AFTER_WATER;
  926.         else
  927.                 pObj->m_ObjFlags &= ~FOB_AFTER_WATER;
  928.  
  929.         //IFoliage* pFoliage = GetFoliage(-1);
  930.         if (m_pFoliage)
  931.         {
  932.                 if (SRenderObjData* pOD = pObj->GetObjData())
  933.                 {
  934.                         pOD->m_pSkinningData = m_pFoliage->GetSkinningData(m_Matrix, passInfo);
  935.                         pObj->m_ObjFlags |= FOB_SKINNED | FOB_DYNAMIC_OBJECT;
  936.                         //m_pFoliage->SetFlags(m_pFoliage->GetFlags() & ~IFoliage::FLAG_FROZEN | -(int)(pObj->m_nMaterialLayers & MTL_LAYER_FROZEN) & IFoliage::FLAG_FROZEN);
  937.                 }
  938.         }
  939.  
  940.         {
  941.                 // temporary fix for autoreload from max export, Vladimir needs to properly fix it!
  942.                 if (pObj->m_pCurrMaterial != GetMaterial())
  943.                         pObj->m_pCurrMaterial = GetMaterial();
  944.  
  945.                 if (Get3DEngine()->IsTessellationAllowed(pObj, passInfo, true))
  946.                 {
  947.                         // Allow this RO to be tessellated, however actual tessellation will be applied if enabled in material
  948.                         pObj->m_ObjFlags |= FOB_ALLOW_TESSELLATION;
  949.                 }
  950.                 else
  951.                         pObj->m_ObjFlags &= ~FOB_ALLOW_TESSELLATION;
  952.  
  953.                 if (GetCVars()->e_BBoxes)
  954.                         GetObjManager()->RenderObjectDebugInfo((IRenderNode*)this, pObj->m_fDistance, passInfo);
  955.  
  956.                 if (lodValue.LodA() <= 0 && Cry3DEngineBase::GetCVars()->e_MergedMeshes != 0 && m_pDeform && m_pDeform->HasDeformableData())
  957.                 {
  958.                         if (GetCVars()->e_StatObjBufferRenderTasks == 1 && passInfo.IsGeneralPass() && JobManager::InvokeAsJob("CheckOcclusion"))
  959.                         {
  960.                                 GetObjManager()->PushIntoCullOutputQueue(SCheckOcclusionOutput::CreateDeformableBrushOutput(this, gEnv->pRenderer->EF_DuplicateRO(pObj, passInfo), lodValue.LodA(), passInfo));
  961.                         }
  962.                         else
  963.                         {
  964.                                 m_pDeform->RenderInternalDeform(gEnv->pRenderer->EF_DuplicateRO(pObj, passInfo), lodValue.LodA(), CBrush::GetBBox(), passInfo);
  965.                         }
  966.                 }
  967.  
  968.                 m_pStatObj->RenderInternal(pObj, m_nSubObjHideMask, lodValue, passInfo);
  969.         }
  970. }
  971.  
  972. ///////////////////////////////////////////////////////////////////////////////
  973. IStatObj* CBrush::GetEntityStatObj(unsigned int nPartId, unsigned int nSubPartId, Matrix34A* pMatrix, bool bReturnOnlyVisible)
  974. {
  975.         if (nPartId != 0)
  976.                 return 0;
  977.  
  978.         if (pMatrix)
  979.                 *pMatrix = m_Matrix;
  980.  
  981.         return m_pStatObj;
  982. }
  983.  
  984. ///////////////////////////////////////////////////////////////////////////////
  985. void CBrush::OnRenderNodeBecomeVisible(const SRenderingPassInfo& passInfo)
  986. {
  987.         assert(m_pTempData);
  988.         SRenderNodeTempData::SUserData& userData = m_pTempData->userData;
  989.  
  990.         userData.objMat = m_Matrix;
  991.         const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  992.         float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, CBrush::GetBBox())) * passInfo.GetZoomFactor();
  993.  
  994.         userData.nWantedLod = CObjManager::GetObjectLOD(this, fEntDistance);
  995.  
  996.         if (GetOwnerEntity() && (GetRndFlags() & ERF_ENABLE_ENTITY_RENDER_CALLBACK))
  997.         {
  998.                 // When render node becomes visible notify our owner render node that it is now visible.
  999.                 GetOwnerEntity()->OnRenderNodeVisibilityChange(true);
  1000.         }
  1001. }
  1002.  
  1003. void CBrush::OnRenderNodeBecomeInvisible()
  1004. {
  1005.         if (GetOwnerEntity() && (GetRndFlags() & ERF_ENABLE_ENTITY_RENDER_CALLBACK))
  1006.         {
  1007.                 // When render node becomes invisible notify our owner render node that it is now invisible.
  1008.                 GetOwnerEntity()->OnRenderNodeVisibilityChange(false);
  1009.         }
  1010. }
  1011.  
  1012. //////////////////////////////////////////////////////////////////////////
  1013. void CBrush::CalcNearestTransform(Matrix34& transformMatrix, const SRenderingPassInfo& passInfo)
  1014. {
  1015.         // Camera space
  1016.         if (m_pCameraSpacePos)
  1017.         {
  1018.                 // Use camera space relative position
  1019.                 transformMatrix.SetTranslation(*m_pCameraSpacePos);
  1020.         }
  1021.         else
  1022.         {
  1023.                 // We don't have camera space relative position, so calculate it out from world space
  1024.                 // (This will not have the precision advantages of camera space rendering)
  1025.                 transformMatrix.AddTranslation(-passInfo.GetCamera().GetPosition());
  1026.         }
  1027.         InvalidatePermanentRenderObjectMatrix();
  1028. }
  1029.  
  1030. void CBrush::InvalidatePermanentRenderObjectMatrix()
  1031. {
  1032.         if (m_pStatObj && m_pStatObj->GetFlags() & STATIC_OBJECT_COMPOUND)
  1033.         {
  1034.                 // Compound unmerged stat objects create duplicate sub render objects and do not support fast matrix only instance update for PermanentRenderObject
  1035.                 InvalidatePermanentRenderObject();
  1036.         }
  1037.         else if (m_pTempData)
  1038.         {
  1039.                 // Special optimization when only matrix change, we invalidate render object instance data flag
  1040.                 m_pTempData->InvalidateRenderObjectsInstanceData();
  1041.         }
  1042. }
  1043.  
  1044. ///////////////////////////////////////////////////////////////////////////////
  1045. bool CBrush::CanExecuteRenderAsJob()
  1046. {
  1047.         return false;
  1048. }
  1049.  
  1050. //////////////////////////////////////////////////////////////////////////
  1051. void CBrush::DisablePhysicalization(bool bDisable)
  1052. {
  1053.         m_bNoPhysicalize = bDisable;
  1054. }
  1055.  
  1056. ///////////////////////////////////////////////////////////////////////////////
  1057. void CBrush::FillBBox(AABB& aabb)
  1058. {
  1059.         aabb = CBrush::GetBBox();
  1060. }
  1061.  
  1062. ///////////////////////////////////////////////////////////////////////////////
  1063. EERType CBrush::GetRenderNodeType()
  1064. {
  1065.         return eERType_Brush;
  1066. }
  1067.  
  1068. ///////////////////////////////////////////////////////////////////////////////
  1069. float CBrush::GetMaxViewDist()
  1070. {
  1071.         if (GetRndFlags() & ERF_FORCE_POST_3D_RENDER)
  1072.         {
  1073.                 // Always want to render models in post 3d render (menus), whatever distance they are
  1074.                 return FLT_MAX;
  1075.         }
  1076.  
  1077.         if (GetRndFlags() & ERF_CUSTOM_VIEW_DIST_RATIO)
  1078.         {
  1079.                 float s = max(max((m_WSBBox.max.x - m_WSBBox.min.x), (m_WSBBox.max.y - m_WSBBox.min.y)), (m_WSBBox.max.z - m_WSBBox.min.z));
  1080.                 return max(GetCVars()->e_ViewDistMin, s * GetCVars()->e_ViewDistRatioCustom * GetViewDistRatioNormilized());
  1081.         }
  1082.  
  1083.         if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
  1084.                 return max(GetCVars()->e_ViewDistMin, min(GetFloatCVar(e_ViewDistCompMaxSize), CBrush::GetBBox().GetRadius()) * GetCVars()->e_ViewDistRatioDetail * GetViewDistRatioNormilized());
  1085.  
  1086.         return max(GetCVars()->e_ViewDistMin, min(GetFloatCVar(e_ViewDistCompMaxSize), CBrush::GetBBox().GetRadius()) * GetCVars()->e_ViewDistRatio * GetViewDistRatioNormilized());
  1087. }
  1088.  
  1089. ///////////////////////////////////////////////////////////////////////////////
  1090. Vec3 CBrush::GetPos(bool bWorldOnly) const
  1091. {
  1092.         assert(bWorldOnly);
  1093.         return m_Matrix.GetTranslation();
  1094. }
  1095.  
  1096. //////////////////////////////////////////////////////////////////////////
  1097. float CBrush::GetScale() const
  1098. {
  1099.         return m_Matrix.GetColumn0().GetLength();
  1100. }
  1101.  
  1102. ///////////////////////////////////////////////////////////////////////////////
  1103. IMaterial* CBrush::GetMaterial(Vec3* pHitPos) const
  1104. {
  1105.         if (m_pMaterial)
  1106.                 return m_pMaterial;
  1107.  
  1108.         if (m_pStatObj)
  1109.                 return m_pStatObj->GetMaterial();
  1110.  
  1111.         return NULL;
  1112. }
  1113.  
downloadBrush.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