I am trying to understand Scene::IsVisibleInCamera() :
Code:
//=================================================
//Update.
//=================================================
bool Scene::IsVisibleInCamera( D3DXVECTOR3 *pCnt, float radius ) {
//tilemanger, cloudmanager:
float z = camera_z.x*pCnt->x + camera_z.y*pCnt->y + camera_z.z*pCnt->z;
if( z < (-radius) ) return false;
if( z < 0) z=-z;
float y = camera_y.x*pCnt->x + camera_y.y*pCnt->y + camera_y.z*pCnt->z;
if( y < 0) y=-y;
if( y - (radius*vhf) > (vh*z) ) return false;
float x = camera_x.x*pCnt->x + camera_x.y*pCnt->y + camera_x.z*pCnt->z;
if( x < 0 ) x=-x;
if( x - (radius*vwf) > (vw*z) ) return false;
return true;
}
I understand that this function will check if a point is within the camera view frustum and return true if it is. Anything outside the radius returns false. This radius can be different for different calls to this function, so its a parameter.
pCnt is the location of the point in the Orbiter global frame ?
What does vhf stand for - view height at the far plane ? This is initialized in :
Code:
void Scene::Update() {
DWORD j;
View = View_new;
Proj = Proj_new;
ViewProj = ViewProj_new;//VP matrix for exterior views
ViewProj_VC = ViewProj_VC_new;//VP matrix for VC
CamPos = CamPos_new;
CamAperture = CamAperture_new;
vh = (float)tan(CamAperture);
vw = vh*cfg->Aspect;
vhf = (float)(1.0f/cos(CamAperture));
vwf = vhf*cfg->Aspect;
camera_x = D3DXVECTOR3(View._11, View._21, View._31);
camera_y = D3DXVECTOR3(View._12, View._22, View._32);
camera_z = D3DXVECTOR3(View._13, View._23, View._33);
Proxy = Proxy_new;
UpdateSkyColor();//updates cBackground and skybrt using atm params of the nearest planet
for( j = 0; j < VesselCount; j++ )
Vessel[j]->Update();
if( bPause ) {
for( j = 0; j < nstream; j++ )
PStream[j]->Update();
}
bPause = bPause_new;
}
But if CamAperture is half the FoV then vh is actually the aspect ratio of the view as far as I can see. vw or 'view width' would then be = vh*cfg->Aspect which is correct.
What does vhf stand for ? 'view height at far plane' ?
I made a diagram from what I understood so far :
https://docs.google.com/drawings/d/1W1Mfg1S_g9J8CveCzVfrZE28Arck2STWCZyBTH5x21A/edit?usp=sharing
I am assuming the camera view space is right handed, so the camera is looking down the -ve z axis. So say there is a point P within the view frustum as shown in the dig.
float z = camera_z.x*pCnt->x + camera_z.y*pCnt->y + camera_z.z*pCnt->z;
will calculate the projection of the point's position vector in the Orbiter global frame, on the z axis. so
if( z < (-radius) ) return false;
is valid.
float y = camera_y.x*pCnt->x + camera_y.y*pCnt->y + camera_y.z*pCnt->z;
calculates the projection on the +ve y axis. Now I am not sure how this check is working after that line:
if( y - (radius*vhf) > (vh*z) ) return false;
Since vhf = 1/cos(CamAperture)
radius*vhf = ED (in the diagram)
Why would ED be subtracted from y (they do not appear to be in the same direction - ED is not along Y).
vhf*z = HQ
What I understand is that you are trying to check if P'Q < HQ i.e. whether the Y projection of a point P'(i.e. it ht) is less than the frustum height at the point's z projection(EQ in the dig.) Then the point could be inside the view frustum.
So the check should be :
if( y > (vh*z) ) return false;
vh*z makes sense as vh = tan(CamAperture) and z is the projection of P' on the Z-axis.
---------------
Ok I think I got it. You are testing a sphere and not just a single point in the function.
http://www.lighthouse3d.com/tutorials/view-frustum-culling/radar-approach-implementation-ii/
I'll recheck my calculations.