@@ -7188,28 +7188,63 @@ void FsSimulation::SimDrawAirplane(const ActualViewMode &actualViewMode,const Fs
71887188// FOV and screen size (pixels) check for draw culling purposes
71897189bool 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