bool Renderer::checkVisibility(const Mat4 &transform, const Size &size)
{
// 获取当前运行的场景
auto scene = Director::getInstance()->getRunningScene();
// 只有在默认相机的情况下,才使用此剔除算法。
if (!scene || (scene && scene->_defaultCamera != Camera::getVisitingCamera()))
return true;
// 获取 Director 实例
auto director = Director::getInstance();
// 创建一个矩形,表示屏幕上可见区域的矩形
Rect visiableRect(director->getVisibleOrigin(), director->getVisibleSize());
// 将对象的尺寸大小的一半作为中心点
float hSizeX = size.width / 2; // 对象宽度的一半
float hSizeY = size.height / 2; // 对象高度的一半
Vec3 v3p(hSizeX, hSizeY, 0); // 创建一个三维点,初始位置在对象的中心
transform.transformPoint(&v3p); // 将对象的中心点从局部坐标转换到世界坐标
Vec2 v2p = Camera::getVisitingCamera()->projectGL(v3p); // 将世界坐标的中心点转换到屏幕坐标
// 计算对象在世界坐标系下的宽度和高度
// 计算对象在世界坐标系下的宽度(wshw)和高度(wshh),考虑了对象的缩放和旋转
float wshw = std::max(fabsf(hSizeX * transform.m[0] + hSizeY * transform.m[4]),
fabsf(hSizeX * transform.m[0] - hSizeY * transform.m[4]));
float wshh = std::max(fabsf(hSizeX * transform.m[1] + hSizeY * transform.m[5]),
fabsf(hSizeX * transform.m[1] - hSizeY * transform.m[5]));
// 根据对象的宽度和高度调整可见区域的大小
// 扩大可见区域的大小以确保即使在物体变换后仍能正确判断是否可见
visiableRect.origin.x -= wshw; // 向左扩展
visiableRect.origin.y -= wshh; // 向下扩展
visiableRect.size.width += wshw * 2; // 增加宽度
visiableRect.size.height += wshh * 2; // 增加高度
// 检查计算出的对象中心点是否在扩展后的可见区域内
bool ret = visiableRect.containsPoint(v2p);
return ret; // 返回对象是否可见
}
核心思想:如果物体的中心点在扩大后的可见区域内,我们可以认为物体在可视区域内;如果物体的中心点在扩大后的可见区域外,我们可以认为物体在可视区域外。