From 4a14ab2fdead5b47a4dfb0f347398746d5225c05 Mon Sep 17 00:00:00 2001 From: T1ti <40864460+T1ti@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:31:42 +0200 Subject: [PATCH] finish drag selection --- src/math/bounding_box.cpp | 16 +-- src/math/bounding_box.hpp | 1 + src/math/ray.cpp | 45 +++--- src/math/ray.hpp | 23 +-- src/noggit/Misc.cpp | 4 +- src/noggit/Misc.h | 6 + src/noggit/ModelInstance.cpp | 54 ++++--- src/noggit/ModelInstance.h | 2 +- src/noggit/WMOInstance.cpp | 25 ++-- src/noggit/World.cpp | 204 ++++++++++++++++----------- src/noggit/rendering/WorldRender.hpp | 1 + 11 files changed, 218 insertions(+), 163 deletions(-) diff --git a/src/math/bounding_box.cpp b/src/math/bounding_box.cpp index b1122d15..9e8ef46f 100755 --- a/src/math/bounding_box.cpp +++ b/src/math/bounding_box.cpp @@ -58,14 +58,14 @@ namespace math std::array box_points(glm::vec3 const& box_min, glm::vec3 const& box_max) { return std::array { - glm::vec3(box_max.x, box_max.y, box_max.z), - glm::vec3(box_max.x, box_max.y, box_min.z), - glm::vec3(box_max.x, box_min.y, box_max.z), - glm::vec3(box_max.x, box_min.y, box_min.z), - glm::vec3(box_min.x, box_max.y, box_max.z), - glm::vec3(box_min.x, box_max.y, box_min.z), - glm::vec3(box_min.x, box_min.y, box_max.z), - glm::vec3(box_min.x, box_min.y, box_min.z) + glm::vec3(box_max.x, box_max.y, box_max.z), // 0: Top-right-front + glm::vec3(box_max.x, box_max.y, box_min.z), // 1: Top-right-back + glm::vec3(box_max.x, box_min.y, box_max.z), // 2: Bottom-right-front + glm::vec3(box_max.x, box_min.y, box_min.z), // 3: Bottom-right-back + glm::vec3(box_min.x, box_max.y, box_max.z), // 4: Top-left-front + glm::vec3(box_min.x, box_max.y, box_min.z), // 5: Top-left-back + glm::vec3(box_min.x, box_min.y, box_max.z), // 6: Bottom-left-front + glm::vec3(box_min.x, box_min.y, box_min.z) // 7: Bottom-left-back }; } diff --git a/src/math/bounding_box.hpp b/src/math/bounding_box.hpp index aa465c78..c3da2f96 100755 --- a/src/math/bounding_box.hpp +++ b/src/math/bounding_box.hpp @@ -15,6 +15,7 @@ namespace math aabb(std::vector const& points); std::array all_corners() const; + inline glm::vec3 center() const { return (min + max) * 0.5f; }; glm::vec3 min; glm::vec3 max; diff --git a/src/math/ray.cpp b/src/math/ray.cpp index 04e71313..dbd6199d 100755 --- a/src/math/ray.cpp +++ b/src/math/ray.cpp @@ -8,37 +8,23 @@ namespace math { std::optional ray::intersect_bounds - (glm::vec3 const& min, glm::vec3 const& max) const + (glm::vec3 const& min, glm::vec3 const& max) const noexcept { float tmin (std::numeric_limits::lowest()); float tmax (std::numeric_limits::max()); - if (_direction.x != 0.0f) - { - float const tx1 ((min.x - _origin.x) / _direction.x); - float const tx2 ((max.x - _origin.x) / _direction.x); + auto calculate_tmin_tmax = [](float origin, float direction, float min, float max, float& tmin, float& tmax) { + if (direction != 0.0f) { + float t1 = (min - origin) / direction; + float t2 = (max - origin) / direction; + tmin = std::max(tmin, std::min(t1, t2)); + tmax = std::min(tmax, std::max(t1, t2)); + } + }; - tmin = std::max (tmin, std::min (tx1, tx2)); - tmax = std::min (tmax, std::max (tx1, tx2)); - } - - if (_direction.y != 0.0f) - { - float const ty1 ((min.y - _origin.y) / _direction.y); - float const ty2 ((max.y - _origin.y) / _direction.y); - - tmin = std::max (tmin, std::min (ty1, ty2)); - tmax = std::min (tmax, std::max (ty1, ty2)); - } - - if (_direction.z != 0.0f) - { - float const tz1 ((min.z - _origin.z) / _direction.z); - float const tz2 ((max.z - _origin.z) / _direction.z); - - tmin = std::max (tmin, std::min (tz1, tz2)); - tmax = std::min (tmax, std::max (tz1, tz2)); - } + calculate_tmin_tmax(_origin.x, _direction.x, min.x, max.x, tmin, tmax); + calculate_tmin_tmax(_origin.y, _direction.y, min.y, max.y, tmin, tmax); + calculate_tmin_tmax(_origin.z, _direction.z, min.z, max.z, tmin, tmax); if (tmax >= tmin) { @@ -49,7 +35,7 @@ namespace math } std::optional ray::intersect_triangle - (glm::vec3 const& v0, glm::vec3 const& v1, glm::vec3 const& v2) const + (glm::vec3 const& v0, glm::vec3 const& v1, glm::vec3 const& v2) const noexcept { glm::vec3 e1 (v1 - v0); glm::vec3 e2 (v2 - v0); @@ -58,7 +44,8 @@ namespace math float const det = glm::dot(e1, P); - if (det == 0.0f) + constexpr float epsilon = std::numeric_limits::epsilon(); + if (std::fabs(det) < epsilon) // if (det == 0.0f) { return std::nullopt; } @@ -81,7 +68,7 @@ namespace math float const dott = glm::dot(e2 , Q) / det; - if (dott > std::numeric_limits::min()) + if (dott > epsilon) // if (dott > std::numeric_limits::min()) { return dott; } diff --git a/src/math/ray.hpp b/src/math/ray.hpp index af9c366c..36c14328 100755 --- a/src/math/ray.hpp +++ b/src/math/ray.hpp @@ -2,25 +2,32 @@ #pragma once #include #include +#include namespace math { struct ray { - ray (glm::vec3 origin, glm::vec3 const& direction): _origin (std::move (origin)), _direction (glm::normalize(direction)) - {} + ray (glm::vec3 origin, glm::vec3 const& direction) + : _origin (std::move (origin)), _direction (glm::normalize(direction)) + { + if (std::isnan(_direction.x) || std::isnan(_direction.y) || std::isnan(_direction.z)) + { + std::cout << "Vector contains NaN values!" << std::endl; + } + } - ray (glm::mat4x4 const& transform, ray const& other): ray ( - glm::vec3( - (transform * glm::vec4(other._origin.x, other._origin.y, other._origin.z, 1.0))), - glm::vec3((transform * glm::vec4(other._direction.x, other._direction.y, other._direction.z, 0.0))) + ray (glm::mat4x4 const& transform, ray const& other) + : ray ( + glm::vec3(transform * glm::vec4(other._origin, 1.0f)), + glm::vec3((glm::mat3(transform) * other._direction)) ) {} std::optional intersect_bounds - (glm::vec3 const& _min, glm::vec3 const& _max) const; + (glm::vec3 const& _min, glm::vec3 const& _max) const noexcept; std::optional intersect_triangle - (glm::vec3 const& _v0, glm::vec3 const& _v1, glm::vec3 const& _v2) const; + (glm::vec3 const& _v0, glm::vec3 const& _v1, glm::vec3 const& _v2) const noexcept; glm::vec3 position (float distance) const { diff --git a/src/noggit/Misc.cpp b/src/noggit/Misc.cpp index 48c9c178..f9772a42 100755 --- a/src/noggit/Misc.cpp +++ b/src/noggit/Misc.cpp @@ -43,7 +43,7 @@ namespace misc // Perspective division to move to normalized device coordinates (NDC) float ndcX = clipSpacePos.x / clipSpacePos.w; float ndcY = clipSpacePos.y / clipSpacePos.w; - float ndcZ = clipSpacePos.z / clipSpacePos.w; + // float ndcZ = clipSpacePos.z / clipSpacePos.w; // unnecessary but could be used for extra checks // If the point is out of the normalized device coordinates range, it's off-screen if (ndcX < -1.0f || ndcX > 1.0f || ndcY < -1.0f || ndcY > 1.0f) @@ -55,6 +55,8 @@ namespace misc // Convert NDC to screen space coordinates clipSpacePos.x = (ndcX + 1.0f) * 0.5f * viewport_width; clipSpacePos.y = (1.0f - (ndcY + 1.0f) * 0.5f) * viewport_height; + // test inverting the MapView::normalized_device_coords formula. + // clipSpacePos.y = (1.0f - ndcY) * 0.5f * viewport_height; // from MapView::normalized_device_coords // x 2.0f * x / viewport_width - 1.0f diff --git a/src/noggit/Misc.h b/src/noggit/Misc.h index a491a28d..401872a4 100755 --- a/src/noggit/Misc.h +++ b/src/noggit/Misc.h @@ -68,6 +68,12 @@ namespace misc bool pointInside(glm::vec3 point, std::array const& extents); bool pointInside(glm::vec2 point, std::array const& extents); + + inline glm::vec4 normalized_device_coords(int x, int y, int screen_width, int screen_height) + { + return { 2.0f * x / screen_width - 1.0f, 1.0f - 2.0f * y / screen_height, 0.0f, 1.0f }; + } + void minmax(glm::vec3* a, glm::vec3* b); inline int rounded_int_div(int value, int div) diff --git a/src/noggit/ModelInstance.cpp b/src/noggit/ModelInstance.cpp index 99ccbc73..a3b4c477 100755 --- a/src/noggit/ModelInstance.cpp +++ b/src/noggit/ModelInstance.cpp @@ -1,19 +1,21 @@ // This file is part of Noggit3, licensed under GNU General Public License (version 3). +#include +#include +#include // checkinside +#include // Model, etc. +#include +#include +#include +#include +#include + #include #include #include #include #include -#include -#include // checkinside -#include // Model, etc. -#include -#include -#include -#include -#include -#include +#include #include @@ -88,12 +90,17 @@ void ModelInstance::draw_box (glm::mat4x4 const& model_view } } -std::vector> ModelInstance::intersect (glm::mat4x4 const& model_view +void ModelInstance::intersect (glm::mat4x4 const& model_view , math::ray const& ray , selection_result* results , int animtime ) { + if (!finishedLoading() || model->loading_failed()) + return; + + ensureExtents(); + std::vector> triangle_indices; math::ray subray (_transform_mat_inverted, ray); @@ -102,7 +109,7 @@ std::vector> ModelInstance::intersect (glm::mat4x4 con ) ) { - return triangle_indices; + return; } for (auto&& result : model->intersect (model_view, subray, animtime)) @@ -112,7 +119,7 @@ std::vector> ModelInstance::intersect (glm::mat4x4 con results->emplace_back (result.first * scale, this); triangle_indices.emplace_back(result.second); } - return triangle_indices; + return; } @@ -189,23 +196,26 @@ void ModelInstance::recalcExtents() //! the model is bad itself. We *could* detect that case and explicitly //! assume {-1, 1} then, to be nice to fuckported models. - auto corners_in_world = std::vector(); + std::array corners_in_world; auto transform = misc::transform_model_box_coords; - auto points = relative_to_model.all_corners(); - for (auto& point : points) + std::array points = relative_to_model.all_corners(); + + for (int i = 0; i < 8; ++i) + // for (auto& point : points) { - point = transform(point); - corners_in_world.push_back(point); + // points[i] = transform(points[i]); + corners_in_world[i] = transform(points[i]); } - auto rotated_corners_in_world = std::vector(); - auto transposedMat = _transform_mat; - for (auto const& point : corners_in_world) + std::array rotated_corners_in_world; + // for (auto const& point : corners_in_world) + for (int i = 0; i < 8; ++i) { - rotated_corners_in_world.emplace_back(transposedMat * glm::vec4(point, 1.f)); + rotated_corners_in_world[i] = _transform_mat * glm::vec4(corners_in_world[i], 1.f); } - math::aabb const bounding_of_rotated_points (rotated_corners_in_world); + math::aabb const bounding_of_rotated_points (std::vector(rotated_corners_in_world.begin() + , rotated_corners_in_world.end())); extents[0] = bounding_of_rotated_points.min; extents[1] = bounding_of_rotated_points.max; diff --git a/src/noggit/ModelInstance.h b/src/noggit/ModelInstance.h index 6e2482f2..cbac3d9b 100755 --- a/src/noggit/ModelInstance.h +++ b/src/noggit/ModelInstance.h @@ -81,7 +81,7 @@ public: ); - std::vector> intersect(glm::mat4x4 const& model_view + void intersect(glm::mat4x4 const& model_view , math::ray const& , selection_result* , int animtime diff --git a/src/noggit/WMOInstance.cpp b/src/noggit/WMOInstance.cpp index 7b6df352..31ea4494 100755 --- a/src/noggit/WMOInstance.cpp +++ b/src/noggit/WMOInstance.cpp @@ -136,6 +136,9 @@ void WMOInstance::draw ( OpenGL::Scoped::use_program& wmo_shader void WMOInstance::intersect (math::ray const& ray, selection_result* results, bool do_exterior) { + if (!finishedLoading() || wmo->loading_failed()) + return; + ensureExtents(); if (!ray.intersect_bounds (extents[0], extents[1])) @@ -160,7 +163,7 @@ std::array const& WMOInstance::getExtents() void WMOInstance::ensureExtents() { - if (_need_recalc_extents && wmo->finishedLoading()) + if ( (_need_recalc_extents || _update_group_extents) && wmo->finishedLoading()) { recalcExtents(); } @@ -234,11 +237,11 @@ void WMOInstance::recalcExtents() glm::vec3 wmo_max(misc::transform_model_box_coords(wmo->extents[1])); auto&& root_points = math::aabb(wmo_min, wmo_max).all_corners(); - auto adjustedPoints = std::vector(); + std::array adjustedPoints; - for (auto const& point : root_points) + for (int i = 0; i < 8; ++i) { - adjustedPoints.push_back(_transform_mat * glm::vec4(point, 1.f)); + adjustedPoints[i] = _transform_mat * glm::vec4(root_points[i], 1.f); } points.insert(points.end(), adjustedPoints.begin(), adjustedPoints.end()); @@ -248,24 +251,24 @@ void WMOInstance::recalcExtents() auto const& group = wmo->groups[i]; auto&& group_points = math::aabb(group.BoundingBoxMin, group.BoundingBoxMax).all_corners(); - auto adjustedGroupPoints = std::vector(); + std::array adjustedGroupPoints; - for (auto const& point : group_points) + for (int i = 0; i < 8; ++i) { - adjustedGroupPoints.push_back(_transform_mat * glm::vec4(point, 1.f)); + adjustedGroupPoints[i] = _transform_mat * glm::vec4(group_points[i], 1.f); } - points.insert(points.end(), adjustedGroupPoints.begin(), adjustedGroupPoints.end()); - if (group.has_skybox() /* || _update_group_extents*/) + if (group.has_skybox() || _update_group_extents) { - math::aabb const group_aabb(adjustedGroupPoints); + math::aabb const group_aabb(std::vector(adjustedGroupPoints.begin() + , adjustedGroupPoints.end())); group_extents[i] = {group_aabb.min, group_aabb.max}; + _update_group_extents = false; } } - _update_group_extents = false; math::aabb const wmo_aabb(points); diff --git a/src/noggit/World.cpp b/src/noggit/World.cpp index 7c857f71..78856e7e 100755 --- a/src/noggit/World.cpp +++ b/src/noggit/World.cpp @@ -1767,7 +1767,7 @@ void World::loadAllTiles() if (mTile) { - mTile->wait_until_loaded(); + // mTile->wait_until_loaded(); } } } @@ -3626,13 +3626,14 @@ void World::select_objects_in_area( } glm::mat4 VPmatrix = projection * view; + glm::mat4x4 const invertedViewMatrix = glm::inverse(VPmatrix); constexpr int max_position_raycast_processing = 10000; constexpr int max_bounds_raycast_processing = 5000; // when selecting large amount of objects, avoid doing complex ray calculations to not freeze constexpr float bounds_check_scale = 0.8f; // size of the bounding box to use when interesecting withs election rectangle constexpr float obj_raycast_min_size = 30.0f; // screen size rectangle lenght in pixels - int processed_obj_count = 0; + int processed_obj_count = 0; // num objects that had a raycast test at least once // int debug_count_obj_min_size = 0; // int debug_count_obj_min_size_not = 0; @@ -3674,105 +3675,161 @@ void World::select_objects_in_area( for (auto& pair : tile->getObjectInstances()) { [[unlikely]] - if (!pair.first->finishedLoading()) + if (!pair.first->finishedLoading() || pair.first->loading_failed()) continue; - auto objectType = pair.second[0]->which(); - [[unlikely]] - if (!(objectType == eMODEL || objectType == eWMO)) + if (pair.second.empty()) continue; + SceneObjectTypes objectType = pair.second[0]->which(); + + // check if object is hidden + if (objectType == eWMO) + { + WMOInstance* model_instance = static_cast(pair.second[0]); + + if (model_instance->wmo->is_hidden()) + continue; + } + else if (objectType == eMODEL) + { + ModelInstance* model_instance = static_cast(pair.second[0]); + + if (model_instance->model->is_hidden()) + continue; + } + else + [[unlikely]] + { + continue; + } + for (auto& instance : pair.second) { // problem : M2s have additional sized based culling with >isInRenderDist() // if (!instance->_rendered_last_frame) // continue; - bool do_selection = false; + const float distance = glm::distance(camera_position, instance->pos); + if (distance > user_depth || distance > renderer()->cullDistance()) + continue; - // Old code to check position point instead of bound box + math::aabb obj_aabb(instance->getExtents()[0], instance->getExtents()[1]); + auto aabb_center = obj_aabb.center(); + + bool point_valid = false; + auto origin_screen_pos = misc::projectPointToScreen(aabb_center, VPmatrix, viewport_width, viewport_height, point_valid); + // if screenPos.w < 0.0f, object is behind camera + // check object bounding radius instead to compare the object's size, if it clips with the camera. + if (!origin_screen_pos.w < -instance->getBoundingRadius()) { - glm::vec4 screenPos = VPmatrix * glm::vec4(instance->pos, 1.0f); - - // if screenPos.w < 0.0f, object is behind camera - // check object bounding radius instead to compare the object's size, if it clips with the camera. - if (screenPos.w < -instance->getBoundingRadius()) - continue; - - screenPos.x /= screenPos.w; - screenPos.y /= screenPos.w; - - // Convert normalized device coordinates (NDC) to screen coordinates - screenPos.x = (screenPos.x + 1.0f) * 0.5f * viewport_width; - screenPos.y = (1.0f - (screenPos.y + 1.0f) * 0.5f) * viewport_height; - - - float distance = glm::distance(camera_position, instance->pos); - if (distance > user_depth) - continue; - - // check if position(origin) point is within rectangle first because it is much cheaper - { - const glm::vec2 screenPos2D = glm::vec2(screenPos); - if (misc::pointInside(screenPos2D, selection_box)) - { - processed_obj_count++; - - // check if point is occluded by terrain - if (processed_obj_count < max_position_raycast_processing - && !is_point_occluded_by_terrain(instance->pos, view, VPmatrix, viewport_width, viewport_height, camera_position)) - { - do_selection = true; - } - // else - // bool debug_breakpoint = true; - } - } + continue; } - // if it's not, check again if bounding box is within selection - // we check _rendered_last_frame because m2s that are too small on screen already don't render - if (!do_selection && instance->_rendered_last_frame && (processed_obj_count < max_bounds_raycast_processing) ) + bool do_selection = false; + // check if position point is within rectangle first because it is much cheaper + { + const glm::vec2 screenPos2D = glm::vec2(origin_screen_pos); + if (misc::pointInside(screenPos2D, selection_box)) + { + // processed_obj_count++; + // check if center point is occluded by terrain + if (processed_obj_count < max_position_raycast_processing && + !is_point_occluded_by_terrain(aabb_center, view, VPmatrix, viewport_width, viewport_height, camera_position)) + { + // if not occluded, select it and skip other checks + do_selection = true; + } + // else + // bool debug_breakpoint = true; + } + } + + // if center point raycast didn't succeed, check again if bounding box is within selection in 2D screen space to test other points + std::array aabb_screnbounds; + if (!do_selection) { bool valid = false; - auto screenBounds = misc::getAABBScreenBounds(instance->getExtents(), VPmatrix + aabb_screnbounds = misc::getAABBScreenBounds(instance->getExtents(), VPmatrix , viewport_width, viewport_height, valid, 0.75f); - if (valid && math::boxIntersects(screenBounds[0], screenBounds[1] + if (valid && math::boxIntersects(aabb_screnbounds[0], aabb_screnbounds[1] , selection_box[0], selection_box[1])) { // do_selection = true; } else + { + // if rectangles don't intersect, just skip continue; + } + // Optimization : Only do raycast bounds checks for object that take enough screen space + // if object is too small checking other points is useless if (!do_selection) { - if (glm::distance(screenBounds[0], screenBounds[1]) < obj_raycast_min_size) - { - // debug_count_obj_min_size++; - continue; - } - else + + float bounds_size = glm::distance(aabb_screnbounds[0], aabb_screnbounds[1]); + if ( bounds_size < obj_raycast_min_size || !instance->_rendered_last_frame) { // debug_count_obj_min_size_not++; + continue; + } + else if (processed_obj_count > max_bounds_raycast_processing) + { + // select it anyways + do_selection = true; + // debug_count_obj_min_size++; } } } // Occlusion test on object's corners (that are in selection box) // uses ray casting, very expensive - if (!do_selection) + // // we check _rendered_last_frame because m2s that are too small on screen already don't render + if (!do_selection /* && instance->_rendered_last_frame && (processed_obj_count < max_bounds_raycast_processing)*/) { - math::aabb obj_aabb(instance->getExtents()[0], instance->getExtents()[1]); + processed_obj_count++; + + // get the center of the intersectino rectangle + // 1 : get the intersection rectangle of screen space and bounding box + glm::vec2 intersectionMin = glm::max(aabb_screnbounds[0], selection_box[0]); + glm::vec2 intersectionMax = glm::min(aabb_screnbounds[1], selection_box[1]); + // Check for Valid Intersection: + if (intersectionMin.x < intersectionMax.x && intersectionMin.y < intersectionMax.y) { + // Valid intersection + } + else { + // No intersection, shouldn't happen + continue; + } + // 2 : get center + glm::vec2 intersectionCenter = (intersectionMin + intersectionMax) * 0.5f; + // 3 : convert 2D screenspace point back to 3d + glm::vec4 normalisedView = invertedViewMatrix * misc::normalized_device_coords(intersectionCenter.x, intersectionCenter.y, + viewport_width, viewport_height); + glm::vec3 intersectionCenter_pos = glm::vec3(normalisedView.x / normalisedView.w, normalisedView.y / normalisedView.w, normalisedView.z / normalisedView.w); + + auto obj_aabb_corners = obj_aabb.all_corners(); - // int required_num_unoccluded_corers = 6; // require 6 of 8 corners to not be occluded + // Iterate key points instead of all 8 corners + std::vector key_points = { + // intersectionCenter_pos, + // (obj_aabb_corners[0] + obj_aabb_corners[6]) * 0.5f, // Center between top corners + obj_aabb_corners[0], // Top-right-front + obj_aabb_corners[5], // Top-left-back + obj_aabb_corners[4], // Top-left-front + obj_aabb_corners[1] // Top-right-back + }; + + // int required_num_unoccluded_corners = 2; bool object_occluded = true; - for (const auto& corner : obj_aabb_corners) + // check if points are occluded by terrain + for (const auto& corner : key_points /*obj_aabb_corners*/) { // TODO : only need to do max top left and max top right in 2d instead of all corners? @@ -3789,6 +3846,7 @@ void World::select_objects_in_area( if (!corner_occluded) { + // if just one point isn't occluded is enough, select object object_occluded = false; break; } @@ -3801,31 +3859,12 @@ void World::select_objects_in_area( if (!do_selection) continue; - auto& obj = instance; - auto which = obj->which(); - if (which == eWMO) - { - auto model_instance = static_cast(obj); - - if (!model_instance->wmo->is_hidden()) - { - this->add_to_selection(obj, false, false); - } - } - else if (which == eMODEL) - { - auto model_instance = static_cast(obj); - - if (!model_instance->model->is_hidden()) - { - this->add_to_selection(obj, false, false); - } - } + add_to_selection(instance, false, false); } } } - this->update_selection_pivot(); + this->update_selection_pivot(); } @@ -3868,14 +3907,13 @@ bool World::is_point_occluded_by_terrain(const glm::vec3& point, for (const auto& terrain_hit : terrain_intersect_results) { // if terrain hit is further, skip - if (terrain_hit.first + 10.0f > distance) // add some leeway, skip hits that are too close, especially for the terrain at object's origin + if (terrain_hit.first + 5.0f > distance) // add some leeway, skip hits that are too close, especially for the terrain at object's origin continue; return true; - + /* auto const& hitChunkInfo = std::get(terrain_hit.second); - /* // check if terrain hit is higher than the object's corner in 2D screen space bool point_valid = false; auto terrain_hit_screen_pos = misc::projectPointToScreen(hitChunkInfo.position, VPmatrix, viewport_width, viewport_height, point_valid); diff --git a/src/noggit/rendering/WorldRender.hpp b/src/noggit/rendering/WorldRender.hpp index 8438ebe2..a81fe7b3 100755 --- a/src/noggit/rendering/WorldRender.hpp +++ b/src/noggit/rendering/WorldRender.hpp @@ -87,6 +87,7 @@ namespace Noggit::Rendering [[nodiscard]] std::unique_ptr& skies() { return _skies; }; float _view_distance; + inline float cullDistance() const { return _cull_distance; } private: