所以,这很尴尬,似乎我所有的高中数学技能都消失了。
我费力地整理了一些似乎可行的代码,但是看着它,我觉得我要么是在绕行,要么是不了解其背后的数学。
glm::vec3 cameraDirection = glm::normalize(camera->lookat - camera->position);
glm::vec3 cameraViewAxis = camera->position + (cameraDirection * (camera->farPlaneDistance) );
for(const auto & obj : scene->objects){
glm::vec3 point = obj.position;
glm::vec3 objDirection = glm::normalize(point - camera->position);
float cosAlpha = glm::dot(objDirection, cameraDirection);
float distance = glm::distance(camera->position, point);
float distanceOnViewAxis = distance * cosAlpha;
glm::vec3 pointOnViewAxis = camera->position + (cameraDirection * distanceOnViewAxis);
float distanceFromViewAxis = glm::distance(pointOnViewAxis, point);
float viewRadius = getViewRadius(distanceOnViewAxis); // based on FOV/aspect ratio
if(distanceFromViewAxis < viewRadius){
// might be visible
}
}
我有点the,有更好的方法,我只需要distanceOnViewAxis
和distanceFromViewAxis
,就三角学而言,它们是 adjacent 和对角线
我看过一些类似的问题,但是它们并没有真正帮助我。
答案 0 :(得分:1)
这是使用点乘和叉乘的更简洁的解决方案。
bool is_in_cone(const glm::vec3& camera_pos, const glm::vec3& camera_direction, const glm::vec3& object_pos) {
auto normalized_dir = glm::normalize(camera_direction);
auto obj_vector = object_pos - camera_pos;
auto dis_on_view_axis = glm::dot(obj_vector, normalized_dir);
if (dis_on_view_axis < 0.0f) return false;
return glm::length(glm::cross(obj_vector, normalized_dir)) <= getViewRadius(dis_on_view_axis);
}