Skip to content

Commit 862615b

Browse files
authored
Merge pull request #93 from YSCEDC/stupid-fence-culling-fix-maybe-final
Culling fix (again)
2 parents c6aaea1 + 48e0ada commit 862615b

1 file changed

Lines changed: 44 additions & 9 deletions

File tree

src/core/fssimulation.cpp

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7188,28 +7188,63 @@ void FsSimulation::SimDrawAirplane(const ActualViewMode &actualViewMode,const Fs
71887188
//FOV and screen size (pixels) check for draw culling purposes
71897189
bool FsSimulation::IsObjectVisible(FsExistence* obj, const ActualViewMode& actualViewMode, const FsProjection& proj) const
71907190
{
7191+
std::string id = obj->CommonProp().GetIdentifier();
7192+
71917193
//calculate object position in player's view
71927194
YsVec3 objPosInCamSpace = actualViewMode.viewMat * obj->GetPosition();
71937195

7194-
//load visual bounding box
7196+
//load visual bounding box corners
71957197
YsVec3 boxMin, boxMax;
71967198
obj->vis.GetBoundingBox(boxMin, boxMax);
71977199

7198-
//compute obj size on screen
7199-
double boundingBoxDiag = 2.0 * ((boxMin - boxMax).GetLength());
7200+
//calculate span of bounding box
7201+
double boundingBoxDiag = 1.0 * ((boxMin - boxMax).GetLength());
7202+
7203+
//distance from object to camera (magnitude of obj position vector in camera space)
72007204
double objDistToCam = objPosInCamSpace.GetLength();
7205+
7206+
//compute obj size on screen
72017207
double apparentRadInPixels = boundingBoxDiag * proj.prjPlnDist / objDistToCam;
72027208

7209+
//if object is within bounding box span length of cam, draw it regardless of viewport visibility
7210+
//(angular culling method below sometimes fails for extreme angles at close distances to camera)
7211+
if (objDistToCam < boundingBoxDiag)
7212+
{
7213+
return true;
7214+
}
7215+
7216+
//don't perform FOV check if obj too small to see
72037217
if (apparentRadInPixels < 1.0)
72047218
{
7205-
//don't perform FOV check if obj too small to see
72067219
return false;
72077220
}
72087221

7209-
//convert pixels to radians by taking proportion of FOV (alternatively, use angular diam formula: 2.0 * atan(boundingBoxDiag / (2.0 * objDistToCam))
7210-
double objAngularRad = apparentRadInPixels / proj.fovInPixels * proj.fov;
7211-
7212-
//compute view angles
7222+
// compute object's apparent angular radius:
7223+
// (angle between bounding box span and cam axis at object's Z distance)
7224+
// .
7225+
// /|
7226+
// / |
7227+
// / |
7228+
// / | boundingBoxDiag
7229+
// / |
7230+
// /x |
7231+
// cam /------+---> cam axis (+Z)
7232+
// | |
7233+
// objPosInCamSpace.z()
7234+
//
7235+
// angular offset (x): x = atan2(boundingBoxDiag, abs(objPosInCamSpace.z()))
7236+
double objAngularRad = atan2(boundingBoxDiag, abs(objPosInCamSpace.z()));
7237+
7238+
//compute view angles from camera axis
7239+
// +X/+Y . objPosInCamSpace
7240+
// ^ /|
7241+
// | / |
7242+
// | / |
7243+
// | / |
7244+
// | / |
7245+
// |/a | horizontal/vertical view angle (in XZ/YZ plane): a = atan2(objPosInCamSpace.x/y(), objPosInCamSpace.z())
7246+
// cam /------+---> cam axis (+Z)
7247+
//
72137248
double objHorizViewAngle = atan2(objPosInCamSpace.x(), objPosInCamSpace.z());
72147249
double objVertViewAngle = atan2(objPosInCamSpace.y(), objPosInCamSpace.z());
72157250

@@ -9764,7 +9799,7 @@ void FsSimulation::GetProjection(FsProjection &prj,const ActualViewMode &actualV
97649799
{
97659800
prj.fovInPixels = lastProjection.fovInPixels;
97669801
prj.prjMode = lastProjection.prjMode;
9767-
prj.prjPlnDist = (double)hei / (PROJ_PLANE_DIST_SCALE) * (actualViewMode.viewMagFix * viewMagUser / 1.8);
9802+
prj.prjPlnDist = lastProjection.prjPlnDist;
97689803
prj.tanFov = lastProjection.tanFov;
97699804
prj.tanFovSecondary = lastProjection.tanFovSecondary;
97709805
prj.fov = lastProjection.fov;

0 commit comments

Comments
 (0)