Skip to content

Commit

Permalink
renderer: Fix object position fetching.
Browse files Browse the repository at this point in the history
Needed the current `time` for getting the correct position.
  • Loading branch information
heinezen committed Jul 14, 2024
1 parent d3c347e commit 2b9c173
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 49 deletions.
44 changes: 22 additions & 22 deletions libopenage/renderer/camera/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ Camera::Camera(const std::shared_ptr<Renderer> &renderer,

// Make the frustum slightly bigger than the camera's view to ensure objects on the boundary get rendered
float real_zoom = 0.7f * this->default_zoom_ratio * this->zoom;
frustum.Recalculate(this->viewport_size,
near_distance,
far_distance,
this->scene_pos,
cam_direction,
Eigen::Vector3f(0.0f, 1.0f, 0.0f),
real_zoom);
frustum.update(this->viewport_size,
near_distance,
far_distance,
this->scene_pos,
cam_direction,
Eigen::Vector3f(0.0f, 1.0f, 0.0f),
real_zoom);

log::log(INFO << "Created new camera at position "
<< "(" << this->scene_pos[0]
Expand Down Expand Up @@ -66,13 +66,13 @@ Camera::Camera(const std::shared_ptr<Renderer> &renderer,

// Make the frustum slightly bigger than the camera's view to ensure objects on the boundary get rendered
float real_zoom = 0.7f * this->default_zoom_ratio * this->zoom;
frustum.Recalculate(this->viewport_size,
near_distance,
far_distance,
this->scene_pos,
cam_direction,
Eigen::Vector3f(0.0f, 1.0f, 0.0f),
real_zoom);
frustum.update(this->viewport_size,
near_distance,
far_distance,
this->scene_pos,
cam_direction,
Eigen::Vector3f(0.0f, 1.0f, 0.0f),
real_zoom);

log::log(INFO << "Created new camera at position "
<< "(" << this->scene_pos[0]
Expand Down Expand Up @@ -129,14 +129,14 @@ void Camera::move_to(Eigen::Vector3f scene_pos) {
this->moved = true;

// Make the frustum slightly bigger than the camera's view to ensure objects on the boundary get rendered
float real_zoom = 0.7f * this->default_zoom_ratio * this->zoom;
frustum.Recalculate(viewport_size,
near_distance,
far_distance,
scene_pos,
cam_direction,
Eigen::Vector3f(0.0f, 1.0f, 0.0f),
real_zoom);
float real_zoom = 0.5f * this->default_zoom_ratio * this->zoom;
frustum.update(viewport_size,
near_distance,
far_distance,
scene_pos,
cam_direction,
Eigen::Vector3f(0.0f, 1.0f, 0.0f),
real_zoom);
}

void Camera::move_rel(Eigen::Vector3f direction, float delta) {
Expand Down
28 changes: 14 additions & 14 deletions libopenage/renderer/camera/frustum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ Frustum::Frustum() :
near_face_normal{Eigen::Vector3f(0.0f, 0.0f, 0.0f)} {
}

void Frustum::Recalculate(util::Vector2s &viewport_size,
float near_distance,
float far_distance,
Eigen::Vector3f &scene_pos,
Eigen::Vector3f cam_direction,
Eigen::Vector3f up_direction,
float real_zoom) {
void Frustum::update(util::Vector2s &viewport_size,
float near_distance,
float far_distance,
Eigen::Vector3f &scene_pos,
Eigen::Vector3f cam_direction,
Eigen::Vector3f up_direction,
float real_zoom) {
// offsets are adjusted by zoom
// this is the same calculation as for the projection matrix
float halfscreenwidth = viewport_size[0] / 2;
Expand All @@ -57,10 +57,10 @@ void Frustum::Recalculate(util::Vector2s &viewport_size,
Eigen::Vector3f u = s.cross(f);
u.normalize();

Eigen::Vector3f near_position = scene_pos - direction * near_distance;
Eigen::Vector3f near_position = scene_pos + direction * near_distance;
Eigen::Vector3f far_position = scene_pos + direction * far_distance;

// The frustum is a box with 8 points defining it (4 on the near plane, 4 on the far plane)
// The frustum is a cuboid box with 8 points defining it (4 on the near plane, 4 on the far plane)
Eigen::Vector3f near_top_left = near_position - s * halfwidth + u * halfheight;
Eigen::Vector3f near_top_right = near_position + s * halfwidth + u * halfheight;
Eigen::Vector3f near_bottom_left = near_position - s * halfwidth - u * halfheight;
Expand All @@ -72,11 +72,11 @@ void Frustum::Recalculate(util::Vector2s &viewport_size,
Eigen::Vector3f far_bottom_right = far_position + s * halfwidth - u * halfheight;

// The near and far planes are easiest to compute, as they should be in the direction of the camera
this->near_face_normal = -1.0f * cam_direction.normalized();
this->far_face_normal = cam_direction.normalized();
this->near_face_normal = cam_direction.normalized();
this->far_face_normal = -1.0f * cam_direction.normalized();

this->near_face_distance = this->near_face_normal.dot(near_position) * -1.0f;
this->far_face_distance = this->far_face_normal.dot(far_position) * -1.0f;
this->near_face_distance = this->near_face_normal.dot(near_position);
this->far_face_distance = this->far_face_normal.dot(far_position);

// Each left, right, top, and bottom plane are defined by three points on the plane
this->left_face_normal = (near_bottom_left - near_top_left).cross(far_bottom_left - near_bottom_left);
Expand All @@ -95,7 +95,7 @@ void Frustum::Recalculate(util::Vector2s &viewport_size,
this->bottom_face_distance = this->bottom_face_normal.dot(near_bottom_left);
}

bool Frustum::is_in_frustum(Eigen::Vector3f &pos) const {
bool Frustum::in_frustum(Eigen::Vector3f &pos) const {
// For each plane, if a point is behind one of the frustum planes, it is not within the frustum
float distance;

Expand Down
43 changes: 35 additions & 8 deletions libopenage/renderer/camera/frustum.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,46 @@

namespace openage::renderer::camera {

/**
* Frustum for a camera.
*
* Used for frustum culling (https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling)
* in the renderer.
*/
class Frustum {
public:
/**
* Create a new frustum.
*/
Frustum();

void Recalculate(util::Vector2s &viewport_size,
float near_distance,
float far_distance,
Eigen::Vector3f &scene_pos,
Eigen::Vector3f cam_direction,
Eigen::Vector3f up_direction,
float real_zoom);
/**
* Update this frustum with the new camera parameters.
*
* @param viewport_size Size of the viewport (width x height).
* @param near_distance Near distance of the frustum.
* @param far_distance Far distance of the frustum.
* @param scene_pos Scene position of the camera.
* @param cam_direction Direction the camera is looking at.
* @param up_direction Up direction of the camera.
* @param real_zoom Zoom factor of the camera.
*/
void update(util::Vector2s &viewport_size,
float near_distance,
float far_distance,
Eigen::Vector3f &scene_pos,
Eigen::Vector3f cam_direction,
Eigen::Vector3f up_direction,
float real_zoom);

bool is_in_frustum(Eigen::Vector3f &pos) const;
/**
* Check whether a point in the scene is inside the frustum.
*
* @param scene_pos 3D scene coordinates.
*
* @return true if the point is inside the frustum, else false.
*/
bool in_frustum(Eigen::Vector3f &scene_pos) const;

private:
Eigen::Vector3f top_face_normal;
Expand Down
7 changes: 4 additions & 3 deletions libopenage/renderer/stages/world/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,11 @@ void WorldObject::set_uniforms(std::vector<std::shared_ptr<renderer::UniformInpu
this->layer_uniforms = std::move(uniforms);
}

bool WorldObject::within_camera_frustum(const std::shared_ptr<camera::Camera> &camera) {
Eigen::Vector3f current_pos = this->position.get(this->last_update).to_world_space();
bool WorldObject::within_camera_frustum(const std::shared_ptr<camera::Camera> &camera,
const time::time_t &time) {
Eigen::Vector3f current_pos = this->position.get(time).to_world_space();
auto frustum = camera->get_frustum();
return frustum.is_in_frustum(current_pos);
return frustum.in_frustum(current_pos);
}

} // namespace openage::renderer::world
3 changes: 2 additions & 1 deletion libopenage/renderer/stages/world/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ class WorldObject {
*/
void set_uniforms(std::vector<std::shared_ptr<renderer::UniformInput>> &&uniforms);

bool within_camera_frustum(const std::shared_ptr<camera::Camera> &camera);
bool within_camera_frustum(const std::shared_ptr<camera::Camera> &camera,
const time::time_t &time);

/**
* Shader uniform IDs for setting uniform values.
Expand Down
2 changes: 1 addition & 1 deletion libopenage/renderer/stages/world/render_stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void WorldRenderStage::update() {
std::unique_lock lock{this->mutex};
auto current_time = this->clock->get_real_time();
for (auto &obj : this->render_objects) {
if (not obj->within_camera_frustum(this->camera)) {
if (not obj->within_camera_frustum(this->camera, current_time)) {
continue;
}

Expand Down

0 comments on commit 2b9c173

Please sign in to comment.