123
This commit is contained in:
213
Cry3DEngine/ObjManDraw.cpp
Normal file
213
Cry3DEngine/ObjManDraw.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: statobjmandraw.cpp
|
||||
// Version: v1.00
|
||||
// Created: 28/5/2001 by Vladimir Kajalin
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: Draw static objects (vegetations)
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "StatObj.h"
|
||||
#include "objman.h"
|
||||
#include "visareas.h"
|
||||
#include "terrain_sector.h"
|
||||
#include "3dengine.h"
|
||||
#include "cbuffer.h"
|
||||
|
||||
bool CObjManager::IsBoxOccluded( const Vec3d & vBoxMin, const Vec3d & vBoxMax, float fDistance, OcclusionTestClient * pOcclTestVars )
|
||||
{
|
||||
FUNCTION_PROFILER_FAST( GetSystem(),PROFILE_3DENGINE,m_bProfilerEnabled );
|
||||
|
||||
assert(pOcclTestVars);
|
||||
assert(fDistance>=0);
|
||||
|
||||
if(m_nRenderStackLevel)
|
||||
return pOcclTestVars->bLastResult; // return result of base level test
|
||||
|
||||
if(pOcclTestVars->nLastVisibleFrameID < GetFrameID()-1)
|
||||
{ // if was invisible last frames (because of frustum culling)
|
||||
pOcclTestVars->ucOcclusionByObjectsFrames = 0; // force to test this frame
|
||||
|
||||
if(GetCVars()->e_terrain_occlusion_culling!=2)
|
||||
pOcclTestVars->ucOcclusionByTerrainFrames = 0; // force to test this frame
|
||||
}
|
||||
|
||||
{ // test occlusion by objects
|
||||
if(!pOcclTestVars->ucOcclusionByObjectsFrames && fDistance>COVERAGEBUFFER_OCCLUSION_TESTERS_MIN_DISTANCE && GetCVars()->e_cbuffer)
|
||||
{ // less distance do not work because objects are sorted wrong
|
||||
if(!m_pCoverageBuffer->IsBBoxVisible(vBoxMin,vBoxMax))
|
||||
{
|
||||
pOcclTestVars->ucOcclusionByObjectsFrames = 0; // force to test next frame
|
||||
pOcclTestVars->bLastResult = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pOcclTestVars->ucOcclusionByObjectsFrames += 4; // skip testing next frame
|
||||
}
|
||||
/*
|
||||
{ // test occl by antiportals
|
||||
if(GetVisAreaManager()->IsOccludedByOcclVolumes(vBoxMin,vBoxMax))
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
{ // test occlusion by terrain
|
||||
Vec3d vTopMax = vBoxMax;
|
||||
Vec3d vTopMin = vBoxMin; vTopMin.z = vTopMax.z;
|
||||
|
||||
const Vec3d & vCamPos = GetViewCamera().GetPos();
|
||||
|
||||
vTopMax.CheckMin(Vec3d((float)CTerrain::GetTerrainSize(),(float)CTerrain::GetTerrainSize(),1024.f));
|
||||
vTopMin.CheckMax(Vec3d(0,0,-1024.f));
|
||||
|
||||
vTopMin.CheckMin(Vec3d((float)CTerrain::GetTerrainSize(),(float)CTerrain::GetTerrainSize(),1024.f));
|
||||
vTopMax.CheckMax(Vec3d(0,0,-1024.f));
|
||||
|
||||
if( !pOcclTestVars->ucOcclusionByTerrainFrames && GetCVars()->e_terrain_occlusion_culling )
|
||||
{
|
||||
int nMaxTestsToScip = (GetVisAreaManager()->m_pCurPortal) ? 3 : 10000;
|
||||
|
||||
// precision in meters for this object
|
||||
float fMaxStep = fDistance*GetCVars()->e_terrain_occlusion_culling_precision;
|
||||
|
||||
if( (fMaxStep < (vTopMax.x - vTopMin.x)*2.f || fMaxStep < (vTopMax.y - vTopMin.y)*2.f) &&
|
||||
// fDistance<700 &&
|
||||
vBoxMin.x != vBoxMax.x && vBoxMin.y != vBoxMax.y )
|
||||
{
|
||||
bool bOccluded = true;
|
||||
|
||||
// todo: debug this
|
||||
float dx = (vTopMax.x - vTopMin.x)*0.99999f;
|
||||
while(dx>fMaxStep)
|
||||
dx*=0.5f;
|
||||
|
||||
float dy = (vTopMax.y - vTopMin.y)*0.99999f;
|
||||
while(dy>fMaxStep)
|
||||
dy*=0.5f;
|
||||
|
||||
// todo: test only borders
|
||||
for(float x=vTopMin.x; x<=vTopMax.x; x+=dx)
|
||||
for(float y=vTopMin.y; y<=vTopMax.y; y+=dy)
|
||||
{
|
||||
if(!m_pTerrain->IsPointOccludedByTerrain(Vec3d(x, y, vTopMax.z), fDistance, vCamPos, nMaxTestsToScip))
|
||||
{
|
||||
bOccluded = false;
|
||||
x=y=1000000;//break
|
||||
}
|
||||
}
|
||||
|
||||
if(bOccluded)
|
||||
{
|
||||
if(GetCVars()->e_terrain_occlusion_culling!=2)
|
||||
pOcclTestVars->ucOcclusionByTerrainFrames = 0; // force to test next frame
|
||||
|
||||
pOcclTestVars->bLastResult = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3d vTopMid = (vTopMin+vTopMax)*0.5f;
|
||||
if( m_pTerrain->IsPointOccludedByTerrain(vTopMid, fDistance,vCamPos, nMaxTestsToScip))
|
||||
{
|
||||
if(GetCVars()->e_terrain_occlusion_culling!=2)
|
||||
pOcclTestVars->ucOcclusionByTerrainFrames = 0; // force to test next frame
|
||||
|
||||
pOcclTestVars->bLastResult = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pOcclTestVars->ucOcclusionByTerrainFrames == 0) // && GetCVars()->e_terrain_occlusion_culling==3)
|
||||
{ // randomize test time, do this only here otherwice ucOcclusionByTerrainFrames may never become 0 and next test will not happend
|
||||
static int arrRnd[16] =
|
||||
{
|
||||
rand()%4+1, rand()%4+1, rand()%4+1, rand()%4+1,
|
||||
rand()%4+1, rand()%4+1, rand()%4+1, rand()%4+1,
|
||||
rand()%4+1, rand()%4+1, rand()%4+1, rand()%4+1,
|
||||
rand()%4+1, rand()%4+1, rand()%4+1, rand()%4+1
|
||||
};
|
||||
|
||||
static int nRndCounter = 0;
|
||||
nRndCounter++;
|
||||
if(nRndCounter>=16)
|
||||
nRndCounter=0;
|
||||
|
||||
pOcclTestVars->ucOcclusionByTerrainFrames = arrRnd[nRndCounter]*4;
|
||||
}
|
||||
else
|
||||
pOcclTestVars->ucOcclusionByTerrainFrames += 4; // skip testing next 64 frames
|
||||
}
|
||||
|
||||
/* const Vec3d & vCamPos = GetViewCamera().GetPos();
|
||||
|
||||
bool bCameraInBBox =
|
||||
vCamPos.x >= (vBoxMin.x-0.05f) && vCamPos.y >= (vBoxMin.y-0.05f) && vCamPos.z >= (vBoxMin.z-0.05f) &&
|
||||
vCamPos.x <= (vBoxMax.x+0.05f) && vCamPos.y <= (vBoxMax.y+0.05f) && vCamPos.z <= (vBoxMax.z+0.05f);
|
||||
|
||||
// Make test only if camera outside of the box and if feature supported
|
||||
if(fDistance>1 && !bCameraInBBox && GetCVars()->e_hw_occlusion_culling_objects && (GetRenderer()->GetFeatures() & RFT_OCCLUSIONTEST) )
|
||||
{
|
||||
// construct RE if needed
|
||||
for(int i=0; i<2; i++)
|
||||
{
|
||||
if(!pOcclTestVars->arrREOcclusionQuery[i])
|
||||
pOcclTestVars->arrREOcclusionQuery[i] =
|
||||
(CREOcclusionQuery *)GetRenderer()->EF_CreateRE(eDATA_OcclusionQuery);
|
||||
|
||||
pOcclTestVars->arrREOcclusionQuery[i]->m_vBoxMin = vBoxMin;
|
||||
pOcclTestVars->arrREOcclusionQuery[i]->m_vBoxMax = vBoxMax;
|
||||
}
|
||||
|
||||
int nSlotId = GetFrameID()&1;
|
||||
GetRenderer()->EF_AddEf(0, pOcclTestVars->arrREOcclusionQuery[nSlotId], m_pShaderOcclusionQuery, 0);
|
||||
|
||||
if(GetCVars()->e_hw_occlusion_culling_objects>1)
|
||||
{
|
||||
float fVis = (pOcclTestVars->arrREOcclusionQuery[!nSlotId]->m_nVisSamples >= 2);
|
||||
float fCol[] = {fVis,!fVis,1,1};
|
||||
GetRenderer()->DrawLabelEx((vBoxMin + vBoxMax)*0.5f,6, fCol, false, true, "%s",
|
||||
fVis ? "V" : "N");
|
||||
}
|
||||
|
||||
if(
|
||||
pOcclTestVars->arrREOcclusionQuery[0]->m_nVisSamples < 2 &&
|
||||
pOcclTestVars->arrREOcclusionQuery[1]->m_nVisSamples < 2 &&
|
||||
1 >= abs( pOcclTestVars->arrREOcclusionQuery[0]->m_nCheckFrame -
|
||||
pOcclTestVars->arrREOcclusionQuery[1]->m_nCheckFrame ) &&
|
||||
GetFrameID()-2 <= pOcclTestVars->arrREOcclusionQuery[0]->m_nDrawFrame &&
|
||||
GetFrameID()-2 <= pOcclTestVars->arrREOcclusionQuery[1]->m_nDrawFrame )
|
||||
{ // return true only if last test is not older than 1 frame
|
||||
pOcclTestVars->bLastResult = true;
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
pOcclTestVars->bLastResult = false;
|
||||
pOcclTestVars->nLastVisibleFrameID = GetFrameID();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CObjManager::PrefechObjects()
|
||||
{
|
||||
for (ObjectsMap::iterator it = m_lstLoadedObjects.begin(); it != m_lstLoadedObjects.end(); ++it)
|
||||
{
|
||||
CStatObj * pStatObj = (*it);
|
||||
SRendParams params;
|
||||
params.nDLightMask = 1;
|
||||
GetRenderer()->EF_StartEf();
|
||||
for(int i=0; i<3; i++)
|
||||
pStatObj->Render(params,Vec3(zero),i);
|
||||
GetRenderer()->EF_EndEf3D(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user