diff --git a/EvoEngine_Plugins/LogGrading/include/LogGrader.hpp b/EvoEngine_Plugins/LogGrading/include/LogGrader.hpp index 66386e5..8d1aa97 100644 --- a/EvoEngine_Plugins/LogGrading/include/LogGrader.hpp +++ b/EvoEngine_Plugins/LogGrading/include/LogGrader.hpp @@ -7,22 +7,22 @@ using namespace evo_engine; using namespace eco_sys_lab_plugin; namespace log_grading_plugin { struct LogWoodMeshGenerationSettings { - float m_ySubdivision = 0.02f; + float m_y_subdivision = 0.02f; }; class ProceduralLogParameters { public: bool m_bottom = true; - bool m_soundDefect = false; - float m_lengthWithoutTrimInFeet = 16.0f; - float m_lengthStepInInches = 1.f; - float m_largeEndDiameterInInches = 25.f; - float m_smallEndDiameterInInches = 20.f; + bool m_sound_defect = false; + float m_length_without_trim_in_feet = 16.0f; + float m_length_step_in_inches = 1.f; + float m_large_end_diameter_in_inches = 25.f; + float m_small_end_diameter_in_inches = 20.f; unsigned m_mode = 0; - float m_spanInInches = 0.0f; + float m_span_in_inches = 0.0f; float m_angle = 180.0f; - float m_crookRatio = 0.7f; + float m_crook_ratio = 0.7f; bool OnInspect(); }; @@ -39,26 +39,26 @@ class LogGrader : public IPrivateComponent { std::shared_ptr m_tempFlatMesh2{}; std::shared_ptr m_tempFlatMesh3{}; std::shared_ptr m_tempFlatMesh4{}; - void RefreshMesh(const LogGrading& logGrading) const; + void RefreshMesh(const LogGrading& log_grading) const; public: - int m_bestGradingIndex = 0; - std::vector m_availableBestGrading{}; - ProceduralLogParameters m_proceduralLogParameters; - AssetRef m_branchShape{}; - bool OnInspect(const std::shared_ptr& editorLayer) override; - void InitializeLogRandomly(const ProceduralLogParameters& proceduralLogParameters, - const std::shared_ptr& branchShape); - LogWoodMeshGenerationSettings m_logWoodMeshGenerationSettings{}; - LogWood m_logWood{}; + int m_best_grading_index = 0; + std::vector m_available_best_grading{}; + ProceduralLogParameters m_procedural_log_parameters; + AssetRef m_branch_shape{}; + bool OnInspect(const std::shared_ptr& editor_layer) override; + void InitializeLogRandomly(const ProceduralLogParameters& procedural_log_parameters, + const std::shared_ptr& branch_shape); + LogWoodMeshGenerationSettings m_log_wood_mesh_generation_settings{}; + LogWood m_log_wood{}; void GenerateCylinderMesh(const std::shared_ptr& mesh, - const LogWoodMeshGenerationSettings& meshGeneratorSettings) const; - void GenerateFlatMesh(const std::shared_ptr& mesh, const LogWoodMeshGenerationSettings& meshGeneratorSettings, - int startX, int endX) const; + const LogWoodMeshGenerationSettings& mesh_generator_settings) const; + void GenerateFlatMesh(const std::shared_ptr& mesh, const LogWoodMeshGenerationSettings& mesh_generator_settings, + int start_x, int end_x) const; void GenerateSurface(const std::shared_ptr& surface, - const LogWoodMeshGenerationSettings& meshGeneratorSettings, int startX, int endX) const; + const LogWoodMeshGenerationSettings& mesh_generator_settings, int start_x, int end_x) const; void OnCreate() override; - void InitializeMeshRenderer(const LogWoodMeshGenerationSettings& meshGeneratorSettings) const; + void InitializeMeshRenderer(const LogWoodMeshGenerationSettings& mesh_generator_settings) const; void ClearMeshRenderer() const; }; } // namespace eco_sys_lab_plugin \ No newline at end of file diff --git a/EvoEngine_Plugins/LogGrading/include/LogWood.hpp b/EvoEngine_Plugins/LogGrading/include/LogWood.hpp index 093a47c..bf92337 100644 --- a/EvoEngine_Plugins/LogGrading/include/LogWood.hpp +++ b/EvoEngine_Plugins/LogGrading/include/LogWood.hpp @@ -1,53 +1,88 @@ #pragma once using namespace evo_engine; namespace log_grading_plugin { +struct Vec4 { + float v0 = 0; + float v1 = 0; + float v2 = 0; + float v3 = 0; + Vec4 Multiply(float other) const; + + Vec4 Add(const Vec4& other) const; +}; +struct Vec3 { + float v0 = 0; + float v1 = 0; + float v2 = 0; + + Vec3 Add(const Vec3& other) const; + + Vec3 Subtract(const Vec3& other) const; + + Vec3 Div(float other) const; + + Vec3 Multiply(float other) const; + + float Distance(const Vec3& other) const; + + float Dot(const Vec3& other) const; +}; +struct Vec2 { + float v0 = 0; + float v1 = 0; + + Vec2 Multiply(float rhs) const; + + Vec2 Add(const Vec2& rhs) const; +}; + struct LogWoodIntersectionBoundaryPoint { - float m_centerDistance = 0.0f; - float m_defectStatus = 0.0f; - glm::vec4 m_color = glm::vec4(1.0f); + float m_center_distance = 0.0f; + float m_defect_status = 0.0f; + Vec4 m_color = Vec4{1.0f, 1.0f, 1.0f, 1.0f}; }; class LogWoodIntersection { public: - glm::vec2 m_center = glm::vec2(0.0f); + Vec2 m_center = Vec2{0.0f, 0.0f}; std::vector m_boundary{}; - [[nodiscard]] float GetCenterDistance(float angle) const; - [[nodiscard]] glm::vec2 GetBoundaryPoint(float angle) const; - [[nodiscard]] float GetDefectStatus(float angle) const; - [[nodiscard]] glm::vec4 GetColor(float angle) const; - [[nodiscard]] float GetAverageDistance() const; - [[nodiscard]] float GetMaxDistance() const; - [[nodiscard]] float GetMinDistance() const; + float GetCenterDistance(float angle) const; + Vec2 GetBoundaryPoint(float angle) const; + float GetDefectStatus(float angle) const; + Vec4 GetColor(float angle) const; + float GetAverageDistance() const; + float GetMaxDistance() const; + float GetMinDistance() const; }; struct LogGradeFaceCutting { - float m_startInMeters = 0; - float m_endInMeters = 0; + float m_start_in_meters = 0; + float m_end_in_meters = 0; }; struct LogGradingFace { - int m_faceIndex = 0; - int m_startAngle = 0; - int m_endAngle = 0; - int m_faceGrade = 0; - std::vector m_clearCuttings{}; - float m_clearCuttingMinLengthInMeters = 0; - float m_clearCuttingMinProportion = 0; + int m_face_index = 0; + int m_start_angle = 0; + int m_end_angle = 0; + int m_face_grade = 0; + std::vector m_clear_cuttings{}; + float m_clear_cutting_min_length_in_meters = 0; + float m_clear_cutting_min_proportion = 0; }; struct LogGrading { - float m_doyleRuleScale = 0.0f; - float m_scribnerRuleScale = 0.0f; - float m_internationalRuleScale = 0.0f; - - float m_crookDeduction = 0.0f; - float m_sweepDeduction = 0.0f; - int m_angleOffset = 0; - float m_lengthWithoutTrimInMeters = 0.0f; - float m_scalingDiameterInMeters = 0; - int m_gradeDetermineFaceIndex = 0; + float m_doyle_rule_scale = 0.0f; + float m_scribner_rule_scale = 0.0f; + float m_international_rule_scale = 0.0f; + + float m_crook_deduction = 0.0f; + float m_sweep_deduction = 0.0f; + int m_angle_offset = 0; + float m_length_without_trim_in_meters = 0.0f; + float m_scaling_diameter_in_meters = 0; + int m_grade_determine_face_index = 0; int m_grade = 0; - int m_startIntersectionIndex = 0; - float m_startHeightInMeters = 0.0f; + int m_start_intersection_index = 0; + float m_start_height_in_meters = 0.0f; LogGradingFace m_faces[4]{}; }; @@ -57,33 +92,43 @@ class LogWood { static float FeetToMeter(float feet); static float MetersToInches(float meters); static float MetersToFeet(float meters); + static Vec3 ClosestPointOnLine(const Vec3& point, const Vec3& a, const Vec3& b) { + const float line_length = a.Distance(b); + const Vec3 vector = point.Subtract(a); + const Vec3 line_direction = b.Subtract(a).Div(line_length); + + // Project Vector to LineDirection to get the distance of point from a + const float distance = vector.Dot(line_direction); + return a.Add(line_direction.Multiply(distance)); + } + bool m_butt = true; float m_length = 0.0f; - float m_sweepInInches = 0.0f; - float m_crookCInInches = 0.0f; - float m_crookCLInFeet = 0.0f; - bool m_soundDefect = false; + float m_sweep_in_inches = 0.0f; + float m_crook_cl_in_inches = 0.0f; + float m_crook_cl_in_feet = 0.0f; + bool m_sound_defect = false; std::vector m_intersections; - [[nodiscard]] glm::vec2 GetSurfacePoint(float height, float angle) const; - [[nodiscard]] float GetCenterDistance(float height, float angle) const; - [[nodiscard]] float GetDefectStatus(float height, float angle) const; - [[nodiscard]] glm::vec4 GetColor(float height, float angle) const; + Vec2 GetSurfacePoint(float height, float angle) const; + float GetCenterDistance(float height, float angle) const; + float GetDefectStatus(float height, float angle) const; + Vec4 GetColor(float height, float angle) const; - [[nodiscard]] LogWoodIntersectionBoundaryPoint& GetBoundaryPoint(float height, float angle); + LogWoodIntersectionBoundaryPoint& GetBoundaryPoint(float height, float angle); void Rotate(int degrees); - [[nodiscard]] float GetAverageDistance(float height) const; - [[nodiscard]] float GetAverageDistance() const; - [[nodiscard]] float GetMaxAverageDistance() const; - [[nodiscard]] float GetMinAverageDistance() const; - [[nodiscard]] float GetMaxDistance() const; - [[nodiscard]] float GetMinDistance() const; - void MarkDefectRegion(float height, float angle, float heightRange, float angleRange); - void EraseDefectRegion(float height, float angle, float heightRange, float angleRange); + float GetAverageDistance(float height) const; + float GetAverageDistance() const; + float GetMaxAverageDistance() const; + float GetMinAverageDistance() const; + float GetMaxDistance() const; + float GetMinDistance() const; + void MarkDefectRegion(float height, float angle, float height_range, float angle_range); + void EraseDefectRegion(float height, float angle, float height_range, float angle_range); void ClearDefects(); - [[nodiscard]] bool RayCastSelection(const glm::mat4& transform, float pointDistanceThreshold, const Ray& ray, - float& height, float& angle) const; + bool RayCastSelection(const glm::mat4& transform, float point_distance_threshold, const Ray& ray, float& height, + float& angle) const; - void CalculateGradingData(std::vector& logGrading) const; - void ColorBasedOnGrading(const LogGrading& logGradingData); + void CalculateGradingData(std::vector& log_grading) const; + void ColorBasedOnGrading(const LogGrading& log_grading_data); }; -} // namespace eco_sys_lab_plugin \ No newline at end of file +} // namespace log_grading_plugin \ No newline at end of file diff --git a/EvoEngine_Plugins/LogGrading/src/LogGrader.cpp b/EvoEngine_Plugins/LogGrading/src/LogGrader.cpp index e0d8190..f07dc06 100644 --- a/EvoEngine_Plugins/LogGrading/src/LogGrader.cpp +++ b/EvoEngine_Plugins/LogGrading/src/LogGrader.cpp @@ -7,42 +7,42 @@ bool ProceduralLogParameters::OnInspect() { if (ImGui::TreeNodeEx("Log Parameters", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::Checkbox("Butt only", &m_bottom)) changed = true; - if (ImGui::DragFloat("Height (Feet)", &m_lengthWithoutTrimInFeet)) + if (ImGui::DragFloat("Height (Feet)", &m_length_without_trim_in_feet)) changed = true; - if (ImGui::DragFloat("Large End Diameter (Inch)", &m_largeEndDiameterInInches)) + if (ImGui::DragFloat("Large End Diameter (Inch)", &m_large_end_diameter_in_inches)) changed = true; - if (ImGui::DragFloat("Small End Diameter (Inch)", &m_smallEndDiameterInInches)) + if (ImGui::DragFloat("Small End Diameter (Inch)", &m_small_end_diameter_in_inches)) changed = true; - if (ImGui::Checkbox("Less than 1/4 sound defects", &m_soundDefect)) + if (ImGui::Checkbox("Less than 1/4 sound defects", &m_sound_defect)) changed = true; if (ImGui::Combo("Mode", {"Sweep", "Crook"}, m_mode)) changed = true; if (m_mode == 0) { - if (ImGui::DragFloat("Sweep (Inch)", &m_spanInInches, 0.1f, .0f, 100.f)) + if (ImGui::DragFloat("Sweep (Inch)", &m_span_in_inches, 0.1f, .0f, 100.f)) changed = true; if (ImGui::DragFloat("Sweep Angle", &m_angle, 1.f, .0f, 360.f)) changed = true; } else { - if (ImGui::DragFloat("Crook (Inch)", &m_spanInInches, 0.1f, .0f, 100.f)) + if (ImGui::DragFloat("Crook (Inch)", &m_span_in_inches, 0.1f, .0f, 100.f)) changed = true; if (ImGui::DragFloat("Crook Angle", &m_angle, 1.f, .0f, 360.f)) changed = true; - if (ImGui::SliderFloat("Crook Ratio", &m_crookRatio, 0.f, 1.f)) + if (ImGui::SliderFloat("Crook Ratio", &m_crook_ratio, 0.f, 1.f)) changed = true; - ImGui::Text(("CL: " + std::to_string(m_lengthWithoutTrimInFeet * (1.f - m_crookRatio)) + " feet.").c_str()); + ImGui::Text(("CL: " + std::to_string(m_length_without_trim_in_feet * (1.f - m_crook_ratio)) + " feet.").c_str()); } if (ImGui::Button("Reset")) { m_bottom = true; - m_soundDefect = false; - m_lengthWithoutTrimInFeet = 16.0f; - m_lengthStepInInches = 1.f; - m_largeEndDiameterInInches = 25.f; - m_smallEndDiameterInInches = 20.f; + m_sound_defect = false; + m_length_without_trim_in_feet = 16.0f; + m_length_step_in_inches = 1.f; + m_large_end_diameter_in_inches = 25.f; + m_small_end_diameter_in_inches = 20.f; m_mode = 0; - m_spanInInches = 0.0f; + m_span_in_inches = 0.0f; m_angle = 180.0f; - m_crookRatio = 0.7f; + m_crook_ratio = 0.7f; changed = true; } ImGui::TreePop(); @@ -50,17 +50,17 @@ bool ProceduralLogParameters::OnInspect() { return changed; } -void LogGrader::RefreshMesh(const LogGrading& logGrading) const { - GenerateCylinderMesh(m_tempCylinderMesh, m_logWoodMeshGenerationSettings); - - GenerateSurface(m_surface4, m_logWoodMeshGenerationSettings, 270 + logGrading.m_angleOffset, - 360 + logGrading.m_angleOffset); - GenerateSurface(m_surface3, m_logWoodMeshGenerationSettings, 0 + logGrading.m_angleOffset, - 90 + logGrading.m_angleOffset); - GenerateSurface(m_surface2, m_logWoodMeshGenerationSettings, 180 + logGrading.m_angleOffset, - 270 + logGrading.m_angleOffset); - GenerateSurface(m_surface1, m_logWoodMeshGenerationSettings, 90 + logGrading.m_angleOffset, - 180 + logGrading.m_angleOffset); +void LogGrader::RefreshMesh(const LogGrading& log_grading) const { + GenerateCylinderMesh(m_tempCylinderMesh, m_log_wood_mesh_generation_settings); + + GenerateSurface(m_surface4, m_log_wood_mesh_generation_settings, 270 + log_grading.m_angle_offset, + 360 + log_grading.m_angle_offset); + GenerateSurface(m_surface3, m_log_wood_mesh_generation_settings, 0 + log_grading.m_angle_offset, + 90 + log_grading.m_angle_offset); + GenerateSurface(m_surface2, m_log_wood_mesh_generation_settings, 180 + log_grading.m_angle_offset, + 270 + log_grading.m_angle_offset); + GenerateSurface(m_surface1, m_log_wood_mesh_generation_settings, 90 + log_grading.m_angle_offset, + 180 + log_grading.m_angle_offset); // GenerateFlatMesh(m_tempFlatMesh1, m_logWoodMeshGenerationSettings, 90 + logGrading.m_angleOffset, 180 + // logGrading.m_angleOffset); GenerateFlatMesh(m_tempFlatMesh2, m_logWoodMeshGenerationSettings, 0 + // logGrading.m_angleOffset, 90 + logGrading.m_angleOffset); GenerateFlatMesh(m_tempFlatMesh3, @@ -69,110 +69,110 @@ void LogGrader::RefreshMesh(const LogGrading& logGrading) const { // logGrading.m_angleOffset); } -bool LogGrader::OnInspect(const std::shared_ptr& editorLayer) { +bool LogGrader::OnInspect(const std::shared_ptr& editor_layer) { bool changed = false; - m_proceduralLogParameters.OnInspect(); + m_procedural_log_parameters.OnInspect(); if (ImGui::Button("Initialize Log")) { - auto branchShape = m_branchShape.Get(); - if (!branchShape) { - branchShape = ProjectManager::CreateTemporaryAsset(); - m_branchShape = branchShape; - branchShape->bark_depth = branchShape->base_depth = 0.1f; + auto branch_shape = m_branch_shape.Get(); + if (!branch_shape) { + branch_shape = ProjectManager::CreateTemporaryAsset(); + m_branch_shape = branch_shape; + branch_shape->bark_depth = branch_shape->base_depth = 0.1f; } - InitializeLogRandomly(m_proceduralLogParameters, branchShape); - m_bestGradingIndex = 0; - m_logWood.CalculateGradingData(m_availableBestGrading); - m_logWood.ColorBasedOnGrading(m_availableBestGrading[m_bestGradingIndex]); - RefreshMesh(m_availableBestGrading[m_bestGradingIndex]); + InitializeLogRandomly(m_procedural_log_parameters, branch_shape); + m_best_grading_index = 0; + m_log_wood.CalculateGradingData(m_available_best_grading); + m_log_wood.ColorBasedOnGrading(m_available_best_grading[m_best_grading_index]); + RefreshMesh(m_available_best_grading[m_best_grading_index]); } if (ImGui::TreeNode("Log Mesh Generation")) { // editorLayer->DragAndDropButton(m_branchShape, "Branch Shape", true); - ImGui::DragFloat("Y Subdivision", &m_logWoodMeshGenerationSettings.m_ySubdivision, 0.01f, 0.01f, 0.5f); - static int rotateDegrees = 10; - ImGui::DragInt("Degrees", &rotateDegrees, 1, 1, 360); - if (ImGui::Button(("Rotate " + std::to_string(rotateDegrees) + " degrees").c_str())) { - m_logWood.Rotate(rotateDegrees); - m_bestGradingIndex = 0; - m_logWood.CalculateGradingData(m_availableBestGrading); - m_logWood.ColorBasedOnGrading(m_availableBestGrading[m_bestGradingIndex]); - RefreshMesh(m_availableBestGrading[m_bestGradingIndex]); + ImGui::DragFloat("Y Subdivision", &m_log_wood_mesh_generation_settings.m_y_subdivision, 0.01f, 0.01f, 0.5f); + static int rotate_degrees = 10; + ImGui::DragInt("Degrees", &rotate_degrees, 1, 1, 360); + if (ImGui::Button(("Rotate " + std::to_string(rotate_degrees) + " degrees").c_str())) { + m_log_wood.Rotate(rotate_degrees); + m_best_grading_index = 0; + m_log_wood.CalculateGradingData(m_available_best_grading); + m_log_wood.ColorBasedOnGrading(m_available_best_grading[m_best_grading_index]); + RefreshMesh(m_available_best_grading[m_best_grading_index]); } if (ImGui::Button("Initialize Mesh Renderer")) - InitializeMeshRenderer(m_logWoodMeshGenerationSettings); + InitializeMeshRenderer(m_log_wood_mesh_generation_settings); ImGui::TreePop(); } if (ImGui::Button("Clear Defects")) { - m_bestGradingIndex = 0; - m_logWood.ClearDefects(); - m_logWood.CalculateGradingData(m_availableBestGrading); - m_logWood.ColorBasedOnGrading(m_availableBestGrading[m_bestGradingIndex]); - RefreshMesh(m_availableBestGrading[m_bestGradingIndex]); + m_best_grading_index = 0; + m_log_wood.ClearDefects(); + m_log_wood.CalculateGradingData(m_available_best_grading); + m_log_wood.ColorBasedOnGrading(m_available_best_grading[m_best_grading_index]); + RefreshMesh(m_available_best_grading[m_best_grading_index]); } - static bool debugVisualization = true; + static bool debug_visualization = true; - static int rotationAngle = 0; + static int rotation_angle = 0; - if (!m_availableBestGrading.empty()) { + if (!m_available_best_grading.empty()) { std::string grading = "Current grading: "; - if (m_availableBestGrading.front().m_grade <= 3) { + if (m_available_best_grading.front().m_grade <= 3) { grading.append("F1"); - } else if (m_availableBestGrading.front().m_grade <= 7) { + } else if (m_available_best_grading.front().m_grade <= 7) { grading.append("F2"); - } else if (m_availableBestGrading.front().m_grade <= 8) { + } else if (m_available_best_grading.front().m_grade <= 8) { grading.append("F3"); } else { grading.append("N/A"); } ImGui::Text(grading.c_str()); - const auto& currentBestGrading = m_availableBestGrading[m_bestGradingIndex]; + const auto& current_best_grading = m_available_best_grading[m_best_grading_index]; ImGui::Text(("Scaling diameter (Inch): " + - std::to_string(LogWood::MetersToInches(currentBestGrading.m_scalingDiameterInMeters))) + std::to_string(LogWood::MetersToInches(current_best_grading.m_scaling_diameter_in_meters))) .c_str()); ImGui::Text(("Length without trim (Feet): " + - std::to_string(LogWood::MetersToFeet(currentBestGrading.m_lengthWithoutTrimInMeters))) + std::to_string(LogWood::MetersToFeet(current_best_grading.m_length_without_trim_in_meters))) .c_str()); ImGui::Separator(); - ImGui::Text(("Crook Deduction: " + std::to_string(currentBestGrading.m_crookDeduction)).c_str()); - ImGui::Text(("Sweep Deduction: " + std::to_string(currentBestGrading.m_sweepDeduction)).c_str()); + ImGui::Text(("Crook Deduction: " + std::to_string(current_best_grading.m_crook_deduction)).c_str()); + ImGui::Text(("Sweep Deduction: " + std::to_string(current_best_grading.m_sweep_deduction)).c_str()); ImGui::Separator(); - ImGui::Text(("Doyle Rule: " + std::to_string(currentBestGrading.m_doyleRuleScale)).c_str()); - ImGui::Text(("Scribner Rule: " + std::to_string(currentBestGrading.m_scribnerRuleScale)).c_str()); - ImGui::Text(("International Rule: " + std::to_string(currentBestGrading.m_internationalRuleScale)).c_str()); + ImGui::Text(("Doyle Rule: " + std::to_string(current_best_grading.m_doyle_rule_scale)).c_str()); + ImGui::Text(("Scribner Rule: " + std::to_string(current_best_grading.m_scribner_rule_scale)).c_str()); + ImGui::Text(("International Rule: " + std::to_string(current_best_grading.m_international_rule_scale)).c_str()); if (ImGui::TreeNode("Grading details")) { - if (ImGui::SliderInt("Grading index", &m_bestGradingIndex, 0, m_availableBestGrading.size())) { - m_bestGradingIndex = glm::clamp(m_bestGradingIndex, 0, static_cast(m_availableBestGrading.size())); - m_logWood.ColorBasedOnGrading(m_availableBestGrading[m_bestGradingIndex]); - RefreshMesh(m_availableBestGrading[m_bestGradingIndex]); + if (ImGui::SliderInt("Grading index", &m_best_grading_index, 0, m_available_best_grading.size())) { + m_best_grading_index = glm::clamp(m_best_grading_index, 0, static_cast(m_available_best_grading.size())); + m_log_wood.ColorBasedOnGrading(m_available_best_grading[m_best_grading_index]); + RefreshMesh(m_available_best_grading[m_best_grading_index]); } ImGui::Text( - ("Grade determine face index: " + std::to_string(currentBestGrading.m_gradeDetermineFaceIndex)).c_str()); - ImGui::Text(("Angle offset: " + std::to_string(currentBestGrading.m_angleOffset)).c_str()); - for (int gradingFaceIndex = 0; gradingFaceIndex < 4; gradingFaceIndex++) { - const auto& face = currentBestGrading.m_faces[gradingFaceIndex]; - if (ImGui::TreeNodeEx(("Face " + std::to_string(gradingFaceIndex)).c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::Text(("Start angle: " + std::to_string(face.m_startAngle)).c_str()); - ImGui::Text(("End angle: " + std::to_string(face.m_endAngle)).c_str()); - ImGui::Text(("Face Grade Index: " + std::to_string(face.m_faceGrade)).c_str()); - std::string faceGrading = "Face grading: "; - if (face.m_faceGrade <= 3) { + ("Grade determine face index: " + std::to_string(current_best_grading.m_grade_determine_face_index)).c_str()); + ImGui::Text(("Angle offset: " + std::to_string(current_best_grading.m_angle_offset)).c_str()); + for (int grading_face_index = 0; grading_face_index < 4; grading_face_index++) { + const auto& face = current_best_grading.m_faces[grading_face_index]; + if (ImGui::TreeNodeEx(("Face " + std::to_string(grading_face_index)).c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::Text(("Start angle: " + std::to_string(face.m_start_angle)).c_str()); + ImGui::Text(("End angle: " + std::to_string(face.m_end_angle)).c_str()); + ImGui::Text(("Face Grade Index: " + std::to_string(face.m_face_grade)).c_str()); + std::string face_grading = "Face grading: "; + if (face.m_face_grade <= 3) { grading.append("F1"); - } else if (face.m_faceGrade <= 7) { + } else if (face.m_face_grade <= 7) { grading.append("F2"); - } else if (face.m_faceGrade <= 8) { + } else if (face.m_face_grade <= 8) { grading.append("F3"); } else { grading.append("N/A"); } - ImGui::Text(faceGrading.c_str()); - ImGui::Text(("Clear Cuttings Count: " + std::to_string(face.m_clearCuttings.size())).c_str()); - ImGui::Text(("Clear Cuttings Min Length: " + std::to_string(face.m_clearCuttingMinLengthInMeters)).c_str()); - ImGui::Text(("Clear Cuttings Min Proportion: " + std::to_string(face.m_clearCuttingMinProportion)).c_str()); + ImGui::Text(face_grading.c_str()); + ImGui::Text(("Clear Cuttings Count: " + std::to_string(face.m_clear_cuttings.size())).c_str()); + ImGui::Text(("Clear Cuttings Min Length: " + std::to_string(face.m_clear_cutting_min_length_in_meters)).c_str()); + ImGui::Text(("Clear Cuttings Min Proportion: " + std::to_string(face.m_clear_cutting_min_proportion)).c_str()); ImGui::TreePop(); } } @@ -180,207 +180,213 @@ bool LogGrader::OnInspect(const std::shared_ptr& editorLayer) { } } - ImGui::Checkbox("Visualization", &debugVisualization); - if (debugVisualization) { - static bool enableDefectSelection = true; - static bool eraseMode = false; - ImGui::Checkbox("Defect Marker", &enableDefectSelection); - static float defectHeightRange = 0.1f; - static int defectAngleRange = 10.0f; + ImGui::Checkbox("Visualization", &debug_visualization); + if (debug_visualization) { + static bool enable_defect_selection = true; + static bool erase_mode = false; + ImGui::Checkbox("Defect Marker", &enable_defect_selection); + static float defect_height_range = 0.1f; + static int defect_angle_range = 10.0f; if (ImGui::TreeNode("Marker Settings")) { - ImGui::Checkbox("Erase mode", &eraseMode); - ImGui::DragFloat("Defect Marker Y", &defectHeightRange, 0.01f, 0.03f, 1.0f); - ImGui::DragInt("Defect Marker X", &defectAngleRange, 1, 3, 30); + ImGui::Checkbox("Erase mode", &erase_mode); + ImGui::DragFloat("Defect Marker Y", &defect_height_range, 0.01f, 0.03f, 1.0f); + ImGui::DragInt("Defect Marker X", &defect_angle_range, 1, 3, 30); } ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 0, 0, 1)); - if (!editorLayer->SceneCameraWindowFocused() && editorLayer->GetKey(GLFW_KEY_F) == Input::KeyActionType::Press) { + if (!editor_layer->SceneCameraWindowFocused() && editor_layer->GetKey(GLFW_KEY_F) == Input::KeyActionType::Press) { EVOENGINE_WARNING("Select Scene Window FIRST!"); } ImGui::Text("Press F for marking"); ImGui::PopStyleColor(); Transform transform{}; - transform.SetEulerRotation(glm::radians(glm::vec3(0, rotationAngle, 0))); - if (enableDefectSelection) { - static std::vector mousePositions{}; - if (editorLayer->SceneCameraWindowFocused() && editorLayer->GetLockEntitySelection() && - editorLayer->GetSelectedEntity() == GetOwner()) { - if (editorLayer->GetKey(GLFW_MOUSE_BUTTON_RIGHT) == Input::KeyActionType::Press) { - mousePositions.clear(); - } else if (editorLayer->GetKey(GLFW_KEY_F) == Input::KeyActionType::Hold) { - mousePositions.emplace_back(editorLayer->GetMouseSceneCameraPosition()); - } else if (editorLayer->GetKey(GLFW_KEY_F) == Input::KeyActionType::Release && !mousePositions.empty()) { + transform.SetEulerRotation(glm::radians(glm::vec3(0, rotation_angle, 0))); + if (enable_defect_selection) { + static std::vector mouse_positions{}; + if (editor_layer->SceneCameraWindowFocused() && editor_layer->GetLockEntitySelection() && + editor_layer->GetSelectedEntity() == GetOwner()) { + if (editor_layer->GetKey(GLFW_MOUSE_BUTTON_RIGHT) == Input::KeyActionType::Press) { + mouse_positions.clear(); + } else if (editor_layer->GetKey(GLFW_KEY_F) == Input::KeyActionType::Hold) { + mouse_positions.emplace_back(editor_layer->GetMouseSceneCameraPosition()); + } else if (editor_layer->GetKey(GLFW_KEY_F) == Input::KeyActionType::Release && !mouse_positions.empty()) { const auto scene = GetScene(); - GlobalTransform cameraLtw; - cameraLtw.value = glm::translate(editorLayer->GetSceneCameraPosition()) * - glm::mat4_cast(editorLayer->GetSceneCameraRotation()); - for (const auto& position : mousePositions) { - const Ray cameraRay = editorLayer->GetSceneCamera()->ScreenPointToRay(cameraLtw, position); + GlobalTransform camera_ltw; + camera_ltw.value = glm::translate(editor_layer->GetSceneCameraPosition()) * + glm::mat4_cast(editor_layer->GetSceneCameraRotation()); + for (const auto& position : mouse_positions) { + const Ray camera_ray = editor_layer->GetSceneCamera()->ScreenPointToRay(camera_ltw, position); float height, angle; - if (m_logWood.RayCastSelection(transform.value, 0.02f, cameraRay, height, angle)) { - if (!eraseMode) - m_logWood.MarkDefectRegion(height, angle, defectHeightRange, defectAngleRange); + if (m_log_wood.RayCastSelection(transform.value, 0.02f, camera_ray, height, angle)) { + if (!erase_mode) + m_log_wood.MarkDefectRegion(height, angle, defect_height_range, defect_angle_range); else - m_logWood.EraseDefectRegion(height, angle, defectHeightRange, defectAngleRange); + m_log_wood.EraseDefectRegion(height, angle, defect_height_range, defect_angle_range); } } - mousePositions.clear(); - m_bestGradingIndex = 0; - m_logWood.CalculateGradingData(m_availableBestGrading); - m_logWood.ColorBasedOnGrading(m_availableBestGrading[m_bestGradingIndex]); - RefreshMesh(m_availableBestGrading[m_bestGradingIndex]); + mouse_positions.clear(); + m_best_grading_index = 0; + m_log_wood.CalculateGradingData(m_available_best_grading); + m_log_wood.ColorBasedOnGrading(m_available_best_grading[m_best_grading_index]); + RefreshMesh(m_available_best_grading[m_best_grading_index]); } } else { - mousePositions.clear(); + mouse_positions.clear(); } } - ImGui::SliderInt("Rotation angle", &rotationAngle, 0, 360); - GizmoSettings gizmoSettings{}; - gizmoSettings.color_mode = GizmoSettings::ColorMode::VertexColor; - const float avgDistance = m_logWood.GetMaxAverageDistance(); - const float circleLength = 2.0f * glm::pi() * avgDistance; + ImGui::SliderInt("Rotation angle", &rotation_angle, 0, 360); + GizmoSettings gizmo_settings{}; + gizmo_settings.depth_test = true; + gizmo_settings.depth_write = true; + gizmo_settings.color_mode = GizmoSettings::ColorMode::VertexColor; + const float avg_distance = m_log_wood.GetMaxAverageDistance(); + const float circle_length = 2.0f * glm::pi() * avg_distance; if (m_tempCylinderMesh) - editorLayer->DrawGizmoMesh(m_tempCylinderMesh, glm::vec4(1.0f), transform.value, 1.f, gizmoSettings); + editor_layer->DrawGizmoMesh(m_tempCylinderMesh, glm::vec4(1.0f), transform.value, 1.f, gizmo_settings); - float xLeftOffset = -avgDistance * 3.f - circleLength / 4.0f; - transform.SetPosition({xLeftOffset, 0, 0}); + float x_left_offset = -avg_distance * 3.f - circle_length / 4.0f; + transform.SetPosition({x_left_offset, 0, 0}); transform.SetEulerRotation(glm::radians(glm::vec3(0, 180, 0))); // if (m_tempFlatMesh1) editorLayer->DrawGizmoMesh(m_tempFlatMesh1, glm::vec4(1.0f), transform.value, 1.f, // gizmoSettings); if (m_surface1) - editorLayer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface1, - transform.value, 1, gizmoSettings); - xLeftOffset -= circleLength / 4.0f + 0.2f; - transform.SetPosition({xLeftOffset, 0, 0}); + editor_layer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface1, + transform.value, 1, gizmo_settings); + x_left_offset -= circle_length / 4.0f + 0.2f; + transform.SetPosition({x_left_offset, 0, 0}); // if (m_tempFlatMesh2) editorLayer->DrawGizmoMesh(m_tempFlatMesh2, glm::vec4(1.0f), transform.value, 1.f, // gizmoSettings); if (m_surface2) - editorLayer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface2, - transform.value, 1.f, gizmoSettings); + editor_layer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface2, + transform.value, 1.f, gizmo_settings); - float xRightOffset = avgDistance * 3.f; - transform.SetPosition({xRightOffset, 0, 0}); + float x_right_offset = avg_distance * 3.f; + transform.SetPosition({x_right_offset, 0, 0}); // if (m_tempFlatMesh3) editorLayer->DrawGizmoMesh(m_tempFlatMesh3, glm::vec4(1.0f), transform.value, 1.f, // gizmoSettings); if (m_surface3) - editorLayer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface3, - transform.value, 1.f, gizmoSettings); + editor_layer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface3, + transform.value, 1.f, gizmo_settings); - xRightOffset += circleLength / 4.0f + 0.2f; - transform.SetPosition({xRightOffset, 0, 0}); + x_right_offset += circle_length / 4.0f + 0.2f; + transform.SetPosition({x_right_offset, 0, 0}); // if (m_tempFlatMesh4) editorLayer->DrawGizmoMesh(m_tempFlatMesh4, glm::vec4(1.0f), transform.value, 1.f, // gizmoSettings); if (m_surface4) - editorLayer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface4, - transform.value, 1.f, gizmoSettings); + editor_layer->DrawGizmoMeshInstancedColored(Resources::GetResource("PRIMITIVE_QUAD"), m_surface4, + transform.value, 1.f, gizmo_settings); } return changed; } -void LogGrader::InitializeLogRandomly(const ProceduralLogParameters& proceduralLogParameters, - const std::shared_ptr& branchShape) { - m_logWood.m_intersections.clear(); - m_logWood.m_length = LogWood::FeetToMeter(proceduralLogParameters.m_lengthWithoutTrimInFeet); - const auto lengthStepInMeters = LogWood::InchesToMeters(proceduralLogParameters.m_lengthStepInInches); - m_logWood.m_intersections.resize(glm::max(1.0f, m_logWood.m_length / lengthStepInMeters)); +void LogGrader::InitializeLogRandomly(const ProceduralLogParameters& procedural_log_parameters, + const std::shared_ptr& branch_shape) { + m_log_wood.m_intersections.clear(); + m_log_wood.m_length = LogWood::FeetToMeter(procedural_log_parameters.m_length_without_trim_in_feet); + const auto length_step_in_meters = LogWood::InchesToMeters(procedural_log_parameters.m_length_step_in_inches); + m_log_wood.m_intersections.resize(glm::max(1.0f, m_log_wood.m_length / length_step_in_meters)); - m_logWood.m_sweepInInches = 0.0f; - m_logWood.m_crookCInInches = 0.0f; - m_logWood.m_crookCLInFeet = 0.0f; + m_log_wood.m_sweep_in_inches = 0.0f; + m_log_wood.m_crook_cl_in_inches = 0.0f; + m_log_wood.m_crook_cl_in_feet = 0.0f; - m_logWood.m_soundDefect = proceduralLogParameters.m_soundDefect; + m_log_wood.m_sound_defect = procedural_log_parameters.m_sound_defect; - if (proceduralLogParameters.m_mode == 0) { - m_logWood.m_sweepInInches = proceduralLogParameters.m_spanInInches; + if (procedural_log_parameters.m_mode == 0) { + m_log_wood.m_sweep_in_inches = procedural_log_parameters.m_span_in_inches; } else { - m_logWood.m_crookCInInches = proceduralLogParameters.m_spanInInches; - m_logWood.m_crookCLInFeet = - proceduralLogParameters.m_lengthWithoutTrimInFeet * (1.f - proceduralLogParameters.m_crookRatio); + m_log_wood.m_crook_cl_in_inches = procedural_log_parameters.m_span_in_inches; + m_log_wood.m_crook_cl_in_feet = + procedural_log_parameters.m_length_without_trim_in_feet * (1.f - procedural_log_parameters.m_crook_ratio); } float theta = 0.0f; float r = 0.0f; - if (proceduralLogParameters.m_mode == 0) { + if (procedural_log_parameters.m_mode == 0) { theta = - 2.f * glm::atan(LogWood::InchesToMeters(proceduralLogParameters.m_spanInInches) / (m_logWood.m_length / 2.0f)); - r = m_logWood.m_length / 2.0f / glm::sin(theta); + 2.f * glm::atan(LogWood::InchesToMeters(procedural_log_parameters.m_span_in_inches) / (m_log_wood.m_length / 2.0f)); + r = m_log_wood.m_length / 2.0f / glm::sin(theta); } - for (int intersectionIndex = 0; intersectionIndex < m_logWood.m_intersections.size(); intersectionIndex++) { - const float a = static_cast(intersectionIndex) / (m_logWood.m_intersections.size() - 1); + for (int intersection_index = 0; intersection_index < m_log_wood.m_intersections.size(); intersection_index++) { + const float a = static_cast(intersection_index) / (m_log_wood.m_intersections.size() - 1); const float radius = - glm::mix(LogWood::InchesToMeters(proceduralLogParameters.m_largeEndDiameterInInches) * 0.5f, - LogWood::InchesToMeters(proceduralLogParameters.m_smallEndDiameterInInches) * 0.5f, a); - auto& intersection = m_logWood.m_intersections[intersectionIndex]; - if (proceduralLogParameters.m_spanInInches != 0.f) { - if (proceduralLogParameters.m_mode == 0) { - const glm::vec2 sweepDirection = glm::vec2(glm::cos(glm::radians(proceduralLogParameters.m_angle)), - glm::sin(glm::radians(proceduralLogParameters.m_angle))); - const float height = glm::abs(0.5f - a) * m_logWood.m_length; - const float actualSpan = glm::sqrt(r * r - height * height) - glm::cos(theta) * r; - intersection.m_center = sweepDirection * actualSpan; - } else if (a > proceduralLogParameters.m_crookRatio) { - const glm::vec2 crookDirection = glm::vec2(glm::cos(glm::radians(proceduralLogParameters.m_angle)), - glm::sin(glm::radians(proceduralLogParameters.m_angle))); - const float actualA = (a - proceduralLogParameters.m_crookRatio) / (1.f - proceduralLogParameters.m_crookRatio); - intersection.m_center = - crookDirection * actualA * LogWood::InchesToMeters(proceduralLogParameters.m_spanInInches); + glm::mix(LogWood::InchesToMeters(procedural_log_parameters.m_large_end_diameter_in_inches) * 0.5f, + LogWood::InchesToMeters(procedural_log_parameters.m_small_end_diameter_in_inches) * 0.5f, a); + auto& intersection = m_log_wood.m_intersections[intersection_index]; + if (procedural_log_parameters.m_span_in_inches != 0.f) { + if (procedural_log_parameters.m_mode == 0) { + const glm::vec2 sweep_direction = glm::vec2(glm::cos(glm::radians(procedural_log_parameters.m_angle)), + glm::sin(glm::radians(procedural_log_parameters.m_angle))); + const float height = glm::abs(0.5f - a) * m_log_wood.m_length; + const float actual_span = glm::sqrt(r * r - height * height) - glm::cos(theta) * r; + const auto center = sweep_direction * actual_span; + intersection.m_center = {center.x, center.y}; + } else if (a > procedural_log_parameters.m_crook_ratio) { + const glm::vec2 crook_direction = glm::vec2(glm::cos(glm::radians(procedural_log_parameters.m_angle)), + glm::sin(glm::radians(procedural_log_parameters.m_angle))); + const float actual_a = (a - procedural_log_parameters.m_crook_ratio) / (1.f - procedural_log_parameters.m_crook_ratio); + const auto center = + crook_direction * actual_a * LogWood::InchesToMeters(procedural_log_parameters.m_span_in_inches); + intersection.m_center = {center.x, center.y}; + ; } } intersection.m_boundary.resize(360); - for (int boundaryPointIndex = 0; boundaryPointIndex < 360; boundaryPointIndex++) { - auto& boundaryPoint = intersection.m_boundary.at(boundaryPointIndex); - boundaryPoint.m_centerDistance = + for (int boundary_point_index = 0; boundary_point_index < 360; boundary_point_index++) { + auto& boundary_point = intersection.m_boundary.at(boundary_point_index); + boundary_point.m_center_distance = radius; // *branchShape->GetValue(static_cast(boundaryPointIndex) / 360.0f, intersectionIndex * // proceduralLogParameters.m_lengthStepInInches); - boundaryPoint.m_defectStatus = 0.0f; + boundary_point.m_defect_status = 0.0f; } } } void LogGrader::GenerateCylinderMesh(const std::shared_ptr& mesh, - const LogWoodMeshGenerationSettings& meshGeneratorSettings) const { + const LogWoodMeshGenerationSettings& mesh_generator_settings) const { if (!mesh) return; - if (m_logWood.m_intersections.size() < 2) + if (m_log_wood.m_intersections.size() < 2) return; - const float logLength = m_logWood.m_length; - const int yStepSize = logLength / meshGeneratorSettings.m_ySubdivision; - const float yStep = logLength / yStepSize; + const float log_length = m_log_wood.m_length; + const int y_step_size = log_length / mesh_generator_settings.m_y_subdivision; + const float y_step = log_length / y_step_size; std::vector vertices{}; std::vector indices{}; - vertices.resize((yStepSize + 1) * 360); - indices.resize(yStepSize * 360 * 6); + vertices.resize((y_step_size + 1) * 360); + indices.resize(y_step_size * 360 * 6); - Jobs::RunParallelFor(yStepSize + 1, [&](const unsigned yIndex) { + Jobs::RunParallelFor(y_step_size + 1, [&](const unsigned y_index) { Vertex archetype{}; - const float y = yStep * static_cast(yIndex); - for (int xIndex = 0; xIndex < 360; xIndex++) { - const float x = static_cast(xIndex); - const glm::vec2 boundaryPoint = m_logWood.GetSurfacePoint(y, x); - archetype.position = glm::vec3(boundaryPoint.x, y, boundaryPoint.y); - archetype.color = m_logWood.GetColor(y, x); + const float y = y_step * static_cast(y_index); + for (int x_index = 0; x_index < 360; x_index++) { + const float x = static_cast(x_index); + const auto boundary_point = m_log_wood.GetSurfacePoint(y, x); + archetype.position = glm::vec3(boundary_point.v0, y, boundary_point.v1); + const auto color = m_log_wood.GetColor(y, x); + archetype.color = {color.v0, color.v1, color.v2, color.v3}; archetype.tex_coord = {x, y}; - vertices[yIndex * 360 + xIndex] = archetype; + vertices[y_index * 360 + x_index] = archetype; } }); - Jobs::RunParallelFor(yStepSize, [&](const unsigned yIndex) { - const auto vertexStartIndex = yIndex * 360; - for (int xIndex = 0; xIndex < 360; xIndex++) { - auto a = vertexStartIndex + xIndex; - auto b = vertexStartIndex + (xIndex == 360 - 1 ? 0 : xIndex + 1); - auto c = vertexStartIndex + 360 + xIndex; - indices.at((yIndex * 360 + xIndex) * 6) = a; - indices.at((yIndex * 360 + xIndex) * 6 + 1) = b; - indices.at((yIndex * 360 + xIndex) * 6 + 2) = c; - a = vertexStartIndex + 360 + (xIndex == 360 - 1 ? 0 : xIndex + 1); - b = vertexStartIndex + 360 + xIndex; - c = vertexStartIndex + (xIndex == 360 - 1 ? 0 : xIndex + 1); - indices.at((yIndex * 360 + xIndex) * 6 + 3) = a; - indices.at((yIndex * 360 + xIndex) * 6 + 4) = b; - indices.at((yIndex * 360 + xIndex) * 6 + 5) = c; + Jobs::RunParallelFor(y_step_size, [&](const unsigned y_index) { + const auto vertex_start_index = y_index * 360; + for (int x_index = 0; x_index < 360; x_index++) { + auto a = vertex_start_index + x_index; + auto b = vertex_start_index + (x_index == 360 - 1 ? 0 : x_index + 1); + auto c = vertex_start_index + 360 + x_index; + indices.at((y_index * 360 + x_index) * 6) = a; + indices.at((y_index * 360 + x_index) * 6 + 1) = b; + indices.at((y_index * 360 + x_index) * 6 + 2) = c; + a = vertex_start_index + 360 + (x_index == 360 - 1 ? 0 : x_index + 1); + b = vertex_start_index + 360 + x_index; + c = vertex_start_index + (x_index == 360 - 1 ? 0 : x_index + 1); + indices.at((y_index * 360 + x_index) * 6 + 3) = a; + indices.at((y_index * 360 + x_index) * 6 + 4) = b; + indices.at((y_index * 360 + x_index) * 6 + 5) = c; } }); @@ -390,57 +396,58 @@ void LogGrader::GenerateCylinderMesh(const std::shared_ptr& mesh, } void LogGrader::GenerateFlatMesh(const std::shared_ptr& mesh, - const LogWoodMeshGenerationSettings& meshGeneratorSettings, const int startX, - const int endX) const { + const LogWoodMeshGenerationSettings& mesh_generator_settings, const int start_x, + const int end_x) const { if (!mesh) return; - if (m_logWood.m_intersections.size() < 2) + if (m_log_wood.m_intersections.size() < 2) return; - const float avgDistance = m_logWood.GetAverageDistance(); - const float circleLength = 2.0f * glm::pi() * avgDistance; - const float flatXStep = circleLength / 360; - const float logLength = m_logWood.m_length; - const int yStepSize = logLength / meshGeneratorSettings.m_ySubdivision; - const float yStep = logLength / yStepSize; + const float avg_distance = m_log_wood.GetAverageDistance(); + const float circle_length = 2.0f * glm::pi() * avg_distance; + const float flat_x_step = circle_length / 360; + const float log_length = m_log_wood.m_length; + const int y_step_size = log_length / mesh_generator_settings.m_y_subdivision; + const float y_step = log_length / y_step_size; std::vector vertices{}; std::vector indices{}; - const int span = endX - startX; + const int span = end_x - start_x; - vertices.resize((yStepSize + 1) * (span + 1)); - indices.resize(yStepSize * span * 6); + vertices.resize((y_step_size + 1) * (span + 1)); + indices.resize(y_step_size * span * 6); - Jobs::RunParallelFor(yStepSize + 1, [&](const unsigned yIndex) { + Jobs::RunParallelFor(y_step_size + 1, [&](const unsigned y_index) { Vertex archetype{}; - const float y = yStep * static_cast(yIndex); - const float intersectionAvgDistance = m_logWood.GetAverageDistance(y); - for (int xIndex = 0; xIndex <= span; xIndex++) { - const float x = static_cast(xIndex); - const float centerDistance = m_logWood.GetCenterDistance(y, x); + const float y = y_step * static_cast(y_index); + const float intersection_avg_distance = m_log_wood.GetAverageDistance(y); + for (int x_index = 0; x_index <= span; x_index++) { + const float x = static_cast(x_index); + const float center_distance = m_log_wood.GetCenterDistance(y, x); archetype.position = - glm::vec3(flatXStep * static_cast(xIndex - span), y, centerDistance - intersectionAvgDistance); - archetype.color = m_logWood.GetColor(y, x + startX); + glm::vec3(flat_x_step * static_cast(x_index - span), y, center_distance - intersection_avg_distance); + const auto color = m_log_wood.GetColor(y, x + start_x); + archetype.color = {color.v0, color.v1, color.v2, color.v3}; archetype.tex_coord = {x, y}; - vertices[yIndex * (span + 1) + xIndex] = archetype; + vertices[y_index * (span + 1) + x_index] = archetype; } }); - Jobs::RunParallelFor(yStepSize, [&](const unsigned yIndex) { - const auto vertexStartIndex = yIndex * (span + 1); - for (int xIndex = 0; xIndex < span; xIndex++) { - auto a = vertexStartIndex + xIndex; - auto b = vertexStartIndex + xIndex + 1; - auto c = vertexStartIndex + (span + 1) + xIndex; - indices.at((yIndex * span + xIndex) * 6) = a; - indices.at((yIndex * span + xIndex) * 6 + 1) = b; - indices.at((yIndex * span + xIndex) * 6 + 2) = c; - a = vertexStartIndex + (span + 1) + xIndex + 1; - b = vertexStartIndex + (span + 1) + xIndex; - c = vertexStartIndex + xIndex + 1; - indices.at((yIndex * span + xIndex) * 6 + 3) = a; - indices.at((yIndex * span + xIndex) * 6 + 4) = b; - indices.at((yIndex * span + xIndex) * 6 + 5) = c; + Jobs::RunParallelFor(y_step_size, [&](const unsigned y_index) { + const auto vertex_start_index = y_index * (span + 1); + for (int x_index = 0; x_index < span; x_index++) { + auto a = vertex_start_index + x_index; + auto b = vertex_start_index + x_index + 1; + auto c = vertex_start_index + (span + 1) + x_index; + indices.at((y_index * span + x_index) * 6) = a; + indices.at((y_index * span + x_index) * 6 + 1) = b; + indices.at((y_index * span + x_index) * 6 + 2) = c; + a = vertex_start_index + (span + 1) + x_index + 1; + b = vertex_start_index + (span + 1) + x_index; + c = vertex_start_index + x_index + 1; + indices.at((y_index * span + x_index) * 6 + 3) = a; + indices.at((y_index * span + x_index) * 6 + 4) = b; + indices.at((y_index * span + x_index) * 6 + 5) = c; } }); @@ -450,41 +457,42 @@ void LogGrader::GenerateFlatMesh(const std::shared_ptr& mesh, } void LogGrader::GenerateSurface(const std::shared_ptr& surface, - const LogWoodMeshGenerationSettings& meshGeneratorSettings, const int startX, - const int endX) const { + const LogWoodMeshGenerationSettings& mesh_generator_settings, const int start_x, + const int end_x) const { if (!surface) return; - if (m_logWood.m_intersections.size() < 2) + if (m_log_wood.m_intersections.size() < 2) return; - const float avgDistance = m_logWood.GetAverageDistance(); - const float circleLength = 2.0f * glm::pi() * avgDistance; - const float flatXStep = circleLength / 360; - const float logLength = m_logWood.m_length; - const int yStepSize = logLength / meshGeneratorSettings.m_ySubdivision; - const float yStep = logLength / yStepSize; + const float avg_distance = m_log_wood.GetAverageDistance(); + const float circle_length = 2.0f * glm::pi() * avg_distance; + const float flat_x_step = circle_length / 360; + const float log_length = m_log_wood.m_length; + const int y_step_size = log_length / mesh_generator_settings.m_y_subdivision; + const float y_step = log_length / y_step_size; - const int span = endX - startX; - std::vector particleInfos; + const int span = end_x - start_x; + std::vector particle_infos; - particleInfos.resize(yStepSize * (span + 1)); + particle_infos.resize(y_step_size * (span + 1)); - Jobs::RunParallelFor(yStepSize + 1, [&](const unsigned yIndex) { - const float y = yStep * static_cast(yIndex); - const float intersectionAvgDistance = m_logWood.GetAverageDistance(y); - for (int xIndex = 0; xIndex <= span; xIndex++) { - const float x = static_cast(xIndex); - const float centerDistance = m_logWood.GetCenterDistance(y, x); + Jobs::RunParallelFor(y_step_size + 1, [&](const unsigned y_index) { + const float y = y_step * static_cast(y_index); + const float intersection_avg_distance = m_log_wood.GetAverageDistance(y); + for (int x_index = 0; x_index <= span; x_index++) { + const float x = static_cast(x_index); + const float center_distance = m_log_wood.GetCenterDistance(y, x); const auto position = - glm::vec3(flatXStep * static_cast(xIndex - span), y, centerDistance - intersectionAvgDistance); - const auto size = glm::vec3(flatXStep, 0.f, yStep); + glm::vec3(flat_x_step * static_cast(x_index - span), y, center_distance - intersection_avg_distance); + const auto size = glm::vec3(flat_x_step, 0.f, y_step); const auto rotation = glm::quat(glm::radians(glm::vec3(-90, 0, 0))); - auto& particleInfo = particleInfos.at(yIndex * span + xIndex); - particleInfo.instance_matrix.value = glm::translate(position) * glm::mat4_cast(rotation) * glm::scale(size); - particleInfo.instance_color = m_logWood.GetColor(y, x + startX); + auto& particle_info = particle_infos.at(y_index * span + x_index); + particle_info.instance_matrix.value = glm::translate(position) * glm::mat4_cast(rotation) * glm::scale(size); + const auto color = m_log_wood.GetColor(y, x + start_x); + particle_info.instance_color = {color.v0, color.v1, color.v2, color.v3}; } }); - surface->SetParticleInfos(particleInfos); + surface->SetParticleInfos(particle_infos); } void LogGrader::OnCreate() { @@ -498,110 +506,105 @@ void LogGrader::OnCreate() { m_surface3 = ProjectManager::CreateTemporaryAsset(); m_surface4 = ProjectManager::CreateTemporaryAsset(); - auto branchShape = m_branchShape.Get(); - if (!branchShape) { - branchShape = ProjectManager::CreateTemporaryAsset(); - m_branchShape = branchShape; - branchShape->bark_depth = branchShape->base_depth = 0.1f; + auto branch_shape = m_branch_shape.Get(); + if (!branch_shape) { + branch_shape = ProjectManager::CreateTemporaryAsset(); + m_branch_shape = branch_shape; + branch_shape->bark_depth = branch_shape->base_depth = 0.1f; } - InitializeLogRandomly(m_proceduralLogParameters, branchShape); - m_bestGradingIndex = 0; - m_logWood.CalculateGradingData(m_availableBestGrading); - m_logWood.ColorBasedOnGrading(m_availableBestGrading[m_bestGradingIndex]); - RefreshMesh(m_availableBestGrading[m_bestGradingIndex]); + InitializeLogRandomly(m_procedural_log_parameters, branch_shape); + m_best_grading_index = 0; + m_log_wood.CalculateGradingData(m_available_best_grading); + m_log_wood.ColorBasedOnGrading(m_available_best_grading[m_best_grading_index]); + RefreshMesh(m_available_best_grading[m_best_grading_index]); } -void LogGrader::InitializeMeshRenderer(const LogWoodMeshGenerationSettings& meshGeneratorSettings) const { +void LogGrader::InitializeMeshRenderer(const LogWoodMeshGenerationSettings& mesh_generator_settings) const { ClearMeshRenderer(); const auto scene = GetScene(); const auto self = GetOwner(); - const auto cylinderEntity = scene->CreateEntity("Log Wood Cylinder Mesh"); - if (scene->IsEntityValid(cylinderEntity)) { - scene->SetParent(cylinderEntity, self); + if (const auto cylinder_entity = scene->CreateEntity("Log Wood Cylinder Mesh"); scene->IsEntityValid(cylinder_entity)) { + scene->SetParent(cylinder_entity, self); const auto mesh = ProjectManager::CreateTemporaryAsset(); - GenerateCylinderMesh(mesh, meshGeneratorSettings); + GenerateCylinderMesh(mesh, mesh_generator_settings); const auto material = ProjectManager::CreateTemporaryAsset(); - const auto meshRenderer = scene->GetOrSetPrivateComponent(cylinderEntity).lock(); + const auto mesh_renderer = scene->GetOrSetPrivateComponent(cylinder_entity).lock(); material->material_properties.roughness = 1.0f; material->material_properties.metallic = 0.0f; material->vertex_color_only = true; - meshRenderer->mesh = mesh; - meshRenderer->material = material; + mesh_renderer->mesh = mesh; + mesh_renderer->material = material; } - const float avgDistance = m_logWood.GetMaxAverageDistance(); - const float circleLength = 2.0f * glm::pi() * avgDistance; - float xOffset = avgDistance * 1.5f; - const auto flatEntity1 = scene->CreateEntity("Log Wood Flat Mesh 1"); - if (scene->IsEntityValid(flatEntity1)) { - scene->SetParent(flatEntity1, self); + const float avg_distance = m_log_wood.GetMaxAverageDistance(); + const float circle_length = 2.0f * glm::pi() * avg_distance; + float x_offset = avg_distance * 1.5f; + if (const auto flat_entity1 = scene->CreateEntity("Log Wood Flat Mesh 1"); scene->IsEntityValid(flat_entity1)) { + scene->SetParent(flat_entity1, self); Transform transform{}; - transform.SetPosition({xOffset, 0, 0}); + transform.SetPosition({x_offset, 0, 0}); transform.SetEulerRotation(glm::radians(glm::vec3(0, 180, 0))); - scene->SetDataComponent(flatEntity1, transform); + scene->SetDataComponent(flat_entity1, transform); const auto mesh = ProjectManager::CreateTemporaryAsset(); - GenerateFlatMesh(mesh, meshGeneratorSettings, 90, 180); + GenerateFlatMesh(mesh, mesh_generator_settings, 90, 180); const auto material = ProjectManager::CreateTemporaryAsset(); - const auto meshRenderer = scene->GetOrSetPrivateComponent(flatEntity1).lock(); + const auto mesh_renderer = scene->GetOrSetPrivateComponent(flat_entity1).lock(); material->material_properties.roughness = 1.0f; material->material_properties.metallic = 0.0f; material->vertex_color_only = true; - meshRenderer->mesh = mesh; - meshRenderer->material = material; + mesh_renderer->mesh = mesh; + mesh_renderer->material = material; } - xOffset += circleLength / 4.0f + 0.2f; - const auto flatEntity2 = scene->CreateEntity("Log Wood Flat Mesh 2"); - if (scene->IsEntityValid(flatEntity2)) { - scene->SetParent(flatEntity2, self); + x_offset += circle_length / 4.0f + 0.2f; + if (const auto flat_entity2 = scene->CreateEntity("Log Wood Flat Mesh 2"); scene->IsEntityValid(flat_entity2)) { + scene->SetParent(flat_entity2, self); Transform transform{}; - transform.SetPosition({xOffset, 0, 0}); + transform.SetPosition({x_offset, 0, 0}); transform.SetEulerRotation(glm::radians(glm::vec3(0, 180, 0))); - scene->SetDataComponent(flatEntity2, transform); + scene->SetDataComponent(flat_entity2, transform); const auto mesh = ProjectManager::CreateTemporaryAsset(); - GenerateFlatMesh(mesh, meshGeneratorSettings, 0, 90); + GenerateFlatMesh(mesh, mesh_generator_settings, 0, 90); const auto material = ProjectManager::CreateTemporaryAsset(); - const auto meshRenderer = scene->GetOrSetPrivateComponent(flatEntity2).lock(); + const auto mesh_renderer = scene->GetOrSetPrivateComponent(flat_entity2).lock(); material->material_properties.roughness = 1.0f; material->material_properties.metallic = 0.0f; material->vertex_color_only = true; - meshRenderer->mesh = mesh; - meshRenderer->material = material; + mesh_renderer->mesh = mesh; + mesh_renderer->material = material; } - xOffset += circleLength / 4.0f + 0.2f; - const auto flatEntity3 = scene->CreateEntity("Log Wood Flat Mesh 3"); - if (scene->IsEntityValid(flatEntity3)) { - scene->SetParent(flatEntity3, self); + x_offset += circle_length / 4.0f + 0.2f; + if (const auto flat_entity3 = scene->CreateEntity("Log Wood Flat Mesh 3"); scene->IsEntityValid(flat_entity3)) { + scene->SetParent(flat_entity3, self); Transform transform{}; - transform.SetPosition({xOffset, 0, 0}); + transform.SetPosition({x_offset, 0, 0}); transform.SetEulerRotation(glm::radians(glm::vec3(0, 180, 0))); - scene->SetDataComponent(flatEntity3, transform); + scene->SetDataComponent(flat_entity3, transform); const auto mesh = ProjectManager::CreateTemporaryAsset(); - GenerateFlatMesh(mesh, meshGeneratorSettings, 270, 360); + GenerateFlatMesh(mesh, mesh_generator_settings, 270, 360); const auto material = ProjectManager::CreateTemporaryAsset(); - const auto meshRenderer = scene->GetOrSetPrivateComponent(flatEntity3).lock(); + const auto mesh_renderer = scene->GetOrSetPrivateComponent(flat_entity3).lock(); material->material_properties.roughness = 1.0f; material->material_properties.metallic = 0.0f; material->vertex_color_only = true; - meshRenderer->mesh = mesh; - meshRenderer->material = material; + mesh_renderer->mesh = mesh; + mesh_renderer->material = material; } - xOffset += circleLength / 4.0f + 0.2f; - const auto flatEntity4 = scene->CreateEntity("Log Wood Flat Mesh 4"); - if (scene->IsEntityValid(flatEntity4)) { - scene->SetParent(flatEntity4, self); + x_offset += circle_length / 4.0f + 0.2f; + if (const auto flat_entity4 = scene->CreateEntity("Log Wood Flat Mesh 4"); scene->IsEntityValid(flat_entity4)) { + scene->SetParent(flat_entity4, self); Transform transform{}; - transform.SetPosition({xOffset, 0, 0}); + transform.SetPosition({x_offset, 0, 0}); transform.SetEulerRotation(glm::radians(glm::vec3(0, 180, 0))); - scene->SetDataComponent(flatEntity4, transform); + scene->SetDataComponent(flat_entity4, transform); const auto mesh = ProjectManager::CreateTemporaryAsset(); - GenerateFlatMesh(mesh, meshGeneratorSettings, 180, 270); + GenerateFlatMesh(mesh, mesh_generator_settings, 180, 270); const auto material = ProjectManager::CreateTemporaryAsset(); - const auto meshRenderer = scene->GetOrSetPrivateComponent(flatEntity4).lock(); + const auto mesh_renderer = scene->GetOrSetPrivateComponent(flat_entity4).lock(); material->material_properties.roughness = 1.0f; material->material_properties.metallic = 0.0f; material->vertex_color_only = true; - meshRenderer->mesh = mesh; - meshRenderer->material = material; + mesh_renderer->mesh = mesh; + mesh_renderer->material = material; } } diff --git a/EvoEngine_Plugins/LogGrading/src/LogWood.cpp b/EvoEngine_Plugins/LogGrading/src/LogWood.cpp index 20cdca6..d9f9299 100644 --- a/EvoEngine_Plugins/LogGrading/src/LogWood.cpp +++ b/EvoEngine_Plugins/LogGrading/src/LogWood.cpp @@ -2,117 +2,162 @@ using namespace log_grading_plugin; +float radians(const float degrees) { + return degrees * static_cast(0.01745329251994329576923690768489); +} + +Vec4 Vec4::Multiply(const float other) const { + return {v0 * other, v1 * other, v2 * other, v3 * other}; +} + +Vec4 Vec4::Add(const Vec4& other) const { + return {v0 + other.v0, v1 + other.v1, v2 + other.v2, v3 + other.v3}; +} + +Vec3 Vec3::Add(const Vec3& other) const { + return {v0 + other.v0, v1 + other.v1, v2 + other.v2}; +} + +Vec3 Vec3::Subtract(const Vec3& other) const { + return {v0 - other.v0, v1 - other.v1, v2 - other.v2}; +} + +Vec3 Vec3::Div(const float other) const { + return {v0 / other, v1 / other, v2 / other}; +} + +Vec3 Vec3::Multiply(const float other) const { + return {v0 * other, v1 * other, v2 * other}; +} + +float Vec3::Distance(const Vec3& other) const { + return std::sqrt(std::abs(v0 * v0 - other.v0 * other.v0) + std::abs(v1 * v1 - other.v1 * other.v1) + + std::abs(v2 * v2 - other.v2 * other.v2)); +} + +float Vec3::Dot(const Vec3& other) const { + return v0 * other.v0 + v1 * other.v1 + v2 * other.v2; +} + +Vec2 Vec2::Multiply(const float rhs) const { + return {v0 * rhs, v1 * rhs}; +} + +Vec2 Vec2::Add(const Vec2& rhs) const { + return {v0 + rhs.v0, v1 + rhs.v1}; +} + float LogWoodIntersection::GetCenterDistance(const float angle) const { assert(m_boundary.size() == 360); - const int startIndex = static_cast(angle) % 360; + const int start_index = static_cast(angle) % 360; const float a = angle - static_cast(angle); - const int endIndex = (startIndex + 1) % 360; - return glm::mix(m_boundary[startIndex].m_centerDistance, m_boundary[endIndex].m_centerDistance, a); + const int end_index = (start_index + 1) % 360; + return m_boundary[start_index].m_center_distance * a + m_boundary[end_index].m_center_distance * (1.f - a); } -glm::vec2 LogWoodIntersection::GetBoundaryPoint(const float angle) const { - return m_center + glm::vec2(glm::cos(glm::radians(angle)), glm::sin(glm::radians(angle))) * GetCenterDistance(angle); +Vec2 LogWoodIntersection::GetBoundaryPoint(const float angle) const { + return m_center.Add(Vec2{std::cos(radians(angle)), std::sin(radians(angle))}.Multiply(GetCenterDistance(angle))); } float LogWoodIntersection::GetDefectStatus(const float angle) const { assert(m_boundary.size() == 360); - const int startIndex = static_cast(angle) % 360; + const int start_index = static_cast(angle) % 360; const float a = angle - static_cast(angle); - const int endIndex = (startIndex + 1) % 360; - return glm::mix(m_boundary[startIndex].m_defectStatus, m_boundary[endIndex].m_defectStatus, a); + const int end_index = (start_index + 1) % 360; + return m_boundary[start_index].m_defect_status * a + m_boundary[end_index].m_defect_status * (1.f - a); } -glm::vec4 LogWoodIntersection::GetColor(const float angle) const { +Vec4 LogWoodIntersection::GetColor(const float angle) const { assert(m_boundary.size() == 360); - const int startIndex = static_cast(angle) % 360; + const int start_index = static_cast(angle) % 360; const float a = angle - static_cast(angle); - const int endIndex = (startIndex + 1) % 360; - return glm::mix(m_boundary[startIndex].m_color, m_boundary[endIndex].m_color, a); + const int end_index = (start_index + 1) % 360; + return m_boundary[start_index].m_color.Multiply(a).Add(m_boundary[end_index].m_color.Multiply(1.f - a)); } float LogWoodIntersection::GetAverageDistance() const { - float retVal = 0.0f; + float ret_val = 0.f; for (const auto& i : m_boundary) - retVal += i.m_centerDistance; - return retVal / m_boundary.size(); + ret_val += i.m_center_distance; + return ret_val / static_cast(m_boundary.size()); } float LogWoodIntersection::GetMaxDistance() const { - float retVal = FLT_MIN; + float ret_val = 0.f; for (const auto& i : m_boundary) { - retVal = glm::max(retVal, i.m_centerDistance); + ret_val = std::max(ret_val, i.m_center_distance); } - return retVal; + return ret_val; } float LogWoodIntersection::GetMinDistance() const { - float retVal = FLT_MAX; + float ret_val = 3.402823466e+38F; for (const auto& i : m_boundary) { - retVal = glm::min(retVal, i.m_centerDistance); + ret_val = std::min(ret_val, i.m_center_distance); } - return retVal; + return ret_val; } -glm::vec2 LogWood::GetSurfacePoint(const float height, const float angle) const { - const float heightStep = m_length / m_intersections.size(); - const int index = static_cast(height / heightStep); - const float a = (height - heightStep * index) / heightStep; - const auto actualAngle = glm::mod(angle, 360.0f); +Vec2 LogWood::GetSurfacePoint(const float height, const float angle) const { + const float height_step = m_length / static_cast(m_intersections.size()); + const int index = static_cast(height / height_step); + const float a = (height - height_step * static_cast(index)) / height_step; + const auto actual_angle = std::fmod(angle, 360.0f); if (index < m_intersections.size() - 1) { - return glm::mix(m_intersections.at(index).GetBoundaryPoint(actualAngle), - m_intersections.at(index + 1).GetBoundaryPoint(actualAngle), a); + return m_intersections.at(index).GetBoundaryPoint(actual_angle).Multiply(a).Add( + m_intersections.at(index + 1).GetBoundaryPoint(actual_angle).Multiply(1.f - a)); } - return m_intersections.back().GetBoundaryPoint(actualAngle); + return m_intersections.back().GetBoundaryPoint(actual_angle); } float LogWood::GetCenterDistance(const float height, const float angle) const { - const float heightStep = m_length / m_intersections.size(); - const int index = height / heightStep; - const float a = (height - heightStep * index) / heightStep; - const auto actualAngle = glm::mod(angle, 360.0f); + const float height_step = m_length / static_cast(m_intersections.size()); + const int index = static_cast(height / height_step); + const float a = (height - height_step * static_cast(index)) / height_step; + const auto actual_angle = std::fmod(angle, 360.0f); if (index < m_intersections.size() - 1) { - return glm::mix(m_intersections.at(index).GetCenterDistance(actualAngle), - m_intersections.at(index + 1).GetCenterDistance(actualAngle), a); + return m_intersections.at(index).GetCenterDistance(actual_angle) * a + + m_intersections.at(index + 1).GetCenterDistance(actual_angle) * (1.f - a); } - return m_intersections.back().GetCenterDistance(actualAngle); + return m_intersections.back().GetCenterDistance(actual_angle); } float LogWood::GetDefectStatus(const float height, const float angle) const { - const float heightStep = m_length / m_intersections.size(); - const int index = height / heightStep; - const float a = (height - heightStep * index) / heightStep; - const auto actualAngle = glm::mod(angle, 360.0f); + const float height_step = m_length / static_cast(m_intersections.size()); + const int index = static_cast(height / height_step); + const float a = (height - height_step * static_cast(index)) / height_step; + const auto actual_angle = std::fmod(angle, 360.0f); if (index < m_intersections.size() - 1) { - return glm::mix(m_intersections.at(index).GetDefectStatus(actualAngle), - m_intersections.at(index + 1).GetDefectStatus(actualAngle), a); + return m_intersections.at(index).GetDefectStatus(actual_angle) * a + + m_intersections.at(index + 1).GetDefectStatus(actual_angle) * (1.f - a); } - return m_intersections.back().GetDefectStatus(actualAngle); + return m_intersections.back().GetDefectStatus(actual_angle); } -glm::vec4 LogWood::GetColor(const float height, const float angle) const { - const float heightStep = m_length / m_intersections.size(); - const int index = height / heightStep; - const float a = (height - heightStep * index) / heightStep; - const auto actualAngle = glm::mod(angle, 360.0f); +Vec4 LogWood::GetColor(const float height, const float angle) const { + const float height_step = m_length / static_cast(m_intersections.size()); + const int index = static_cast(height / height_step); + const float a = (height - height_step * static_cast(index)) / height_step; + const auto actual_angle = std::fmod(angle, 360.0f); if (index < m_intersections.size() - 1) { - return glm::mix(m_intersections.at(index).GetColor(actualAngle), - m_intersections.at(index + 1).GetColor(actualAngle), a); + return m_intersections.at(index).GetColor(actual_angle).Multiply(a).Add( + m_intersections.at(index + 1).GetColor(actual_angle).Multiply(1.f - a)); } - return m_intersections.back().GetColor(actualAngle); + return m_intersections.back().GetColor(actual_angle); } LogWoodIntersectionBoundaryPoint& LogWood::GetBoundaryPoint(const float height, const float angle) { - const float heightStep = m_length / m_intersections.size(); - const int index = height / heightStep; - const float a = (height - heightStep * index) / heightStep; - const auto actualAngle = glm::mod(angle, 360.0f); + const float height_step = m_length / static_cast(m_intersections.size()); + const int index = static_cast(height / height_step); + const float a = (height - height_step * static_cast(index)) / height_step; + const auto actual_angle = static_cast(std::fmod(angle, 360.0f)); if (index < m_intersections.size() - 1) { if (a < 0.5f) { - return m_intersections.at(index).m_boundary.at(actualAngle); + return m_intersections.at(index).m_boundary.at(actual_angle); } - return m_intersections.at(index + 1).m_boundary.at(actualAngle); + return m_intersections.at(index + 1).m_boundary.at(actual_angle); } - return m_intersections.back().m_boundary.at(actualAngle); + return m_intersections.back().m_boundary.at(actual_angle); } void LogWood::Rotate(int degrees) { @@ -122,7 +167,11 @@ void LogWood::Rotate(int degrees) { if (degrees == 0) return; for (auto& intersection : m_intersections) { - intersection.m_center = glm::rotate(intersection.m_center, glm::radians(static_cast(degrees))); + const float cos = std::cos(radians(static_cast(degrees))); + const float sin = std::sin(radians(static_cast(degrees))); + const Vec2 result = {intersection.m_center.v0 * cos - intersection.m_center.v1 * sin, + intersection.m_center.v0 * sin - intersection.m_center.v1 * cos}; + intersection.m_center = result; const std::vector last = {intersection.m_boundary.end() - degrees, intersection.m_boundary.end()}; std::copy(intersection.m_boundary.begin(), intersection.m_boundary.end() - degrees, @@ -132,9 +181,9 @@ void LogWood::Rotate(int degrees) { } float LogWood::GetAverageDistance(const float height) const { - const float heightStep = m_length / m_intersections.size(); - const int index = height / heightStep; - const float a = (height - heightStep * index) / heightStep; + const float height_step = m_length / m_intersections.size(); + const int index = height / height_step; + const float a = (height - height_step * index) / height_step; if (index < m_intersections.size() - 1) { if (a < 0.5f) { return m_intersections.at(index).GetAverageDistance(); @@ -145,111 +194,112 @@ float LogWood::GetAverageDistance(const float height) const { } float LogWood::GetAverageDistance() const { - float sumDistance = 0.0f; + float sum_distance = 0.0f; for (const auto& intersection : m_intersections) { for (const auto& point : intersection.m_boundary) - sumDistance += point.m_centerDistance; + sum_distance += point.m_center_distance; } - return sumDistance / m_intersections.size() / 360.0f; + return sum_distance / m_intersections.size() / 360.0f; } float LogWood::GetMaxAverageDistance() const { - float retVal = FLT_MIN; + float ret_val = 0.f; for (const auto& i : m_intersections) { - retVal = glm::max(i.GetAverageDistance(), retVal); + ret_val = std::max(i.GetAverageDistance(), ret_val); } - return retVal; + return ret_val; } float LogWood::GetMinAverageDistance() const { - float retVal = FLT_MAX; + float ret_val = 3.402823466e+38F; for (const auto& i : m_intersections) { - retVal = glm::min(i.GetAverageDistance(), retVal); + ret_val = std::min(i.GetAverageDistance(), ret_val); } - return retVal; + return ret_val; } float LogWood::GetMaxDistance() const { - float retVal = FLT_MIN; + float ret_val = 0.f; for (const auto& i : m_intersections) { - retVal = glm::max(i.GetMaxDistance(), retVal); + ret_val = std::max(i.GetMaxDistance(), ret_val); } - return retVal; + return ret_val; } float LogWood::GetMinDistance() const { - float retVal = FLT_MAX; + float ret_val = 3.402823466e+38F; for (const auto& i : m_intersections) { - retVal = glm::min(i.GetMinDistance(), retVal); + ret_val = std::min(i.GetMinDistance(), ret_val); } - return retVal; -} - -void LogWood::MarkDefectRegion(const float height, const float angle, const float heightRange, const float angleRange) { - const float heightStep = m_length / m_intersections.size(); - const int heightStepSize = heightRange / heightStep; - for (int yIndex = -heightStepSize; yIndex <= heightStepSize; yIndex++) { - const auto sinVal = glm::abs(static_cast(yIndex)) / heightStepSize; - const auto sinAngle = glm::asin(sinVal); - const float maxAngleRange = glm::cos(sinAngle); - for (int xIndex = -angleRange; xIndex <= angleRange; xIndex++) { - const auto actualYIndex = yIndex + height / heightStep; - if (actualYIndex < 0 || actualYIndex >= m_intersections.size()) + return ret_val; +} + +void LogWood::MarkDefectRegion(const float height, const float angle, const float height_range, const float angle_range) { + const float height_step = m_length / static_cast(m_intersections.size()); + const int height_step_size = static_cast(height_range / height_step); + for (int y_index = -height_step_size; y_index <= height_step_size; y_index++) { + const auto sin_val = std::abs(static_cast(y_index)) / height_step_size; + const auto sin_angle = std::asin(sin_val); + const float max_angle_range = std::cos(sin_angle); + for (int x_index = -angle_range; x_index <= angle_range; x_index++) { + const int actual_y_index = y_index + height / height_step; + if (actual_y_index < 0 || actual_y_index >= m_intersections.size()) continue; - if (glm::abs(static_cast(xIndex)) / angleRange > maxAngleRange) + if (std::abs(static_cast(x_index)) / angle_range > max_angle_range) continue; - const auto actualXIndex = static_cast(360 + xIndex + angle) % 360; - m_intersections.at(actualYIndex).m_boundary.at(actualXIndex).m_defectStatus = 1.0f; + const auto actual_x_index = static_cast(360.0f + static_cast(x_index) + angle) % 360; + m_intersections.at(actual_y_index).m_boundary.at(actual_x_index).m_defect_status = 1.0f; } } } -void LogWood::EraseDefectRegion(const float height, const float angle, const float heightRange, - const float angleRange) { - const float heightStep = m_length / m_intersections.size(); - const int heightStepSize = heightRange / heightStep; - for (int yIndex = -heightStepSize; yIndex <= heightStepSize; yIndex++) { - const auto sinVal = glm::abs(static_cast(yIndex)) / heightStepSize; - const auto sinAngle = glm::asin(sinVal); - const float maxAngleRange = glm::cos(sinAngle); - for (int xIndex = -angleRange; xIndex <= angleRange; xIndex++) { - const auto actualYIndex = yIndex + height / heightStep; - if (actualYIndex < 0 || actualYIndex >= m_intersections.size()) +void LogWood::EraseDefectRegion(const float height, const float angle, const float height_range, + const float angle_range) { + const float height_step = m_length / static_cast(m_intersections.size()); + const int height_step_size = static_cast(height_range / height_step); + for (int y_index = -height_step_size; y_index <= height_step_size; y_index++) { + const auto sin_val = std::abs(static_cast(y_index)) / height_step_size; + const auto sin_angle = std::asin(sin_val); + const float max_angle_range = std::cos(sin_angle); + for (int x_index = -angle_range; x_index <= angle_range; x_index++) { + const int actual_y_index = y_index + height / height_step; + if (actual_y_index < 0 || actual_y_index >= m_intersections.size()) continue; - if (glm::abs(static_cast(xIndex)) / angleRange > maxAngleRange) + if (std::abs(static_cast(x_index)) / angle_range > max_angle_range) continue; - const auto actualXIndex = static_cast(xIndex + angle) % 360; - m_intersections.at(actualYIndex).m_boundary.at(actualXIndex).m_defectStatus = 0.0f; + const auto actual_x_index = static_cast(360.0f + static_cast(x_index) + angle) % 360; + m_intersections.at(actual_y_index).m_boundary.at(actual_x_index).m_defect_status = 0.0f; } } } void LogWood::ClearDefects() { for (auto& intersection : m_intersections) { - for (auto& boundaryPoint : intersection.m_boundary) { - boundaryPoint.m_defectStatus = 0.0f; - boundaryPoint.m_color = glm::vec4(212.f / 255, 175.f / 255, 55.f / 255, 1); + for (auto& boundary_point : intersection.m_boundary) { + boundary_point.m_defect_status = 0.0f; + boundary_point.m_color = Vec4{212.f / 255, 175.f / 255, 55.f / 255, 1}; } } } -bool LogWood::RayCastSelection(const glm::mat4& transform, const float pointDistanceThreshold, const Ray& ray, +bool LogWood::RayCastSelection(const glm::mat4& transform, const float point_distance_threshold, const Ray& ray, float& height, float& angle) const { - float minDistance = FLT_MAX; + float min_distance = 3.402823466e+38F; bool found = false; - const float heightStep = m_length / m_intersections.size(); - for (int yIndex = 0; yIndex < m_intersections.size(); yIndex++) { - const auto testHeight = yIndex * heightStep; - for (int xIndex = 0; xIndex < 360; xIndex++) { - const auto surfacePoint = GetSurfacePoint(testHeight, xIndex); - const glm::vec3 position = (transform * glm::translate(glm::vec3(surfacePoint.x, testHeight, surfacePoint.y)))[3]; - glm::vec3 closestPoint = Ray::ClosestPointOnLine(position, ray.start, ray.start + ray.direction * 10000.0f); - const float pointDistance = glm::distance(closestPoint, position); - const float distanceToStart = glm::distance(ray.start, position); - if (distanceToStart < minDistance && pointDistance < pointDistanceThreshold) { - minDistance = distanceToStart; - height = testHeight; - angle = xIndex; + const float height_step = m_length / m_intersections.size(); + for (int y_index = 0; y_index < m_intersections.size(); y_index++) { + const auto test_height = y_index * height_step; + for (int x_index = 0; x_index < 360; x_index++) { + const auto surface_point = GetSurfacePoint(test_height, x_index); + const glm::vec3 position = + (transform * glm::translate(glm::vec3(surface_point.v0, test_height, surface_point.v1)))[3]; + glm::vec3 closest_point = Ray::ClosestPointOnLine(position, ray.start, ray.start + ray.direction * 10000.0f); + const float point_distance = glm::distance(closest_point, position); + if (const float distance_to_start = glm::distance(ray.start, position); + distance_to_start < min_distance && point_distance < point_distance_threshold) { + min_distance = distance_to_start; + height = test_height; + angle = x_index; found = true; } } @@ -257,39 +307,39 @@ bool LogWood::RayCastSelection(const glm::mat4& transform, const float pointDist return found; } -std::vector CalculateCuttings(const float trim, const std::vector& defectMarks, - const float heightStep, const float minDistance, - const float startHeight) { - int lastDefectIndex = 0.0f; +std::vector CalculateCuttings(const float trim, const std::vector& defect_marks, + const float height_step, const float min_distance, + const float start_height) { + int last_defect_index = 0.0f; std::vector cuttings{}; - for (int intersectionIndex = 0; intersectionIndex < defectMarks.size(); intersectionIndex++) { - if (defectMarks[intersectionIndex] || intersectionIndex == defectMarks.size() - 1) { - if (heightStep * (intersectionIndex - lastDefectIndex) >= minDistance + trim + trim) { + for (int intersection_index = 0; intersection_index < defect_marks.size(); intersection_index++) { + if (defect_marks[intersection_index] || intersection_index == defect_marks.size() - 1) { + if (height_step * (intersection_index - last_defect_index) >= min_distance + trim + trim) { LogGradeFaceCutting cutting; - cutting.m_startInMeters = heightStep * lastDefectIndex + startHeight + trim; - cutting.m_endInMeters = heightStep * intersectionIndex + startHeight - trim; + cutting.m_start_in_meters = height_step * last_defect_index + start_height + trim; + cutting.m_end_in_meters = height_step * intersection_index + start_height - trim; cuttings.emplace_back(cutting); } - lastDefectIndex = intersectionIndex; + last_defect_index = intersection_index; } } return cuttings; } -bool TestCutting(const std::vector& cuttings, const int maxNumber, const float minProportion, - const float logLength, float& minCuttingLength, float& proportion) { - const auto cuttingNumber = cuttings.size(); - if (cuttingNumber == 0) +bool TestCutting(const std::vector& cuttings, const int max_number, const float min_proportion, + const float log_length, float& min_cutting_length, float& proportion) { + const auto cutting_number = cuttings.size(); + if (cutting_number == 0) return false; - float cuttingSumLength = 0.0f; - minCuttingLength = FLT_MAX; + float cutting_sum_length = 0.0f; + min_cutting_length = 3.402823466e+38F; for (const auto& cutting : cuttings) { - const float length = cutting.m_endInMeters - cutting.m_startInMeters; - cuttingSumLength += length; - minCuttingLength = glm::min(minCuttingLength, length); + const float length = cutting.m_end_in_meters - cutting.m_start_in_meters; + cutting_sum_length += length; + min_cutting_length = std::min(min_cutting_length, length); } - proportion = cuttingSumLength / logLength; - if (cuttingNumber <= maxNumber && proportion >= minProportion) { + proportion = cutting_sum_length / log_length; + if (cutting_number <= max_number && proportion >= min_proportion) { return true; } return false; @@ -311,340 +361,340 @@ float LogWood::MetersToFeet(const float meters) { return meters * 3.28084f; } -void LogWood::CalculateGradingData(std::vector& logGrading) const { +void LogWood::CalculateGradingData(std::vector& log_grading) const { std::vector results{}; - const float intersectionLength = m_length / m_intersections.size(); - const int gradingSectionIntersectionCount = - glm::min(glm::ceil(FeetToMeter(12) / intersectionLength), static_cast(m_intersections.size()) - 1); - - float cuttingTrim = InchesToMeters(3); - for (int startIntersectionIndex = 0; - startIntersectionIndex < m_intersections.size() - gradingSectionIntersectionCount; startIntersectionIndex++) { - for (int angleOffset = 0; angleOffset < 90; angleOffset++) { + const float intersection_length = m_length / m_intersections.size(); + const int grading_section_intersection_count = + std::min(std::ceil(FeetToMeter(12) / intersection_length), static_cast(m_intersections.size()) - 1); + + float cutting_trim = InchesToMeters(3); + for (int start_intersection_index = 0; + start_intersection_index < m_intersections.size() - grading_section_intersection_count; start_intersection_index++) { + for (int angle_offset = 0; angle_offset < 90; angle_offset++) { results.emplace_back(); - auto& tempLogGrading = results.back(); - tempLogGrading.m_angleOffset = angleOffset; + auto& temp_log_grading = results.back(); + temp_log_grading.m_angle_offset = angle_offset; // TODO: Calculate Scaling Diameter correctly. - tempLogGrading.m_scalingDiameterInMeters = GetMinAverageDistance() * 2.f; - tempLogGrading.m_startHeightInMeters = startIntersectionIndex * intersectionLength; - tempLogGrading.m_startIntersectionIndex = startIntersectionIndex; - tempLogGrading.m_lengthWithoutTrimInMeters = gradingSectionIntersectionCount * intersectionLength; - const int d = static_cast(glm::round(MetersToInches(tempLogGrading.m_scalingDiameterInMeters))); - const int l = static_cast(glm::round(MetersToFeet(tempLogGrading.m_lengthWithoutTrimInMeters))); - tempLogGrading.m_doyleRuleScale = (d - 4.f) * (d - 4.f) * l / 16.f; - tempLogGrading.m_scribnerRuleScale = (0.79f * d * d - d * 2.f - 4.f) * l / 16.f; - tempLogGrading.m_internationalRuleScale = + temp_log_grading.m_scaling_diameter_in_meters = GetMinAverageDistance() * 2.f; + temp_log_grading.m_start_height_in_meters = start_intersection_index * intersection_length; + temp_log_grading.m_start_intersection_index = start_intersection_index; + temp_log_grading.m_length_without_trim_in_meters = grading_section_intersection_count * intersection_length; + const int d = static_cast(std::round(MetersToInches(temp_log_grading.m_scaling_diameter_in_meters))); + const int l = static_cast(std::round(MetersToFeet(temp_log_grading.m_length_without_trim_in_meters))); + temp_log_grading.m_doyle_rule_scale = (d - 4.f) * (d - 4.f) * l / 16.f; + temp_log_grading.m_scribner_rule_scale = (0.79f * d * d - d * 2.f - 4.f) * l / 16.f; + temp_log_grading.m_international_rule_scale = static_cast(0.04976191 * l * d * d + 0.006220239 * l * l * d - 0.1854762 * l * d + 0.0002591767 * l * l * l - 0.01159226 * l * l + 0.04222222 * l); if (l <= 10) { - tempLogGrading.m_sweepDeduction = glm::max(0.0f, (m_sweepInInches - 1.f) / d); + temp_log_grading.m_sweep_deduction = std::max(0.0f, (m_sweep_in_inches - 1.f) / d); } else if (l <= 13) { - tempLogGrading.m_sweepDeduction = glm::max(0.0f, (m_sweepInInches - 1.5f) / d); + temp_log_grading.m_sweep_deduction = std::max(0.0f, (m_sweep_in_inches - 1.5f) / d); } else { - tempLogGrading.m_sweepDeduction = glm::max(0.0f, (m_sweepInInches - 2.f) / d); + temp_log_grading.m_sweep_deduction = std::max(0.0f, (m_sweep_in_inches - 2.f) / d); } - tempLogGrading.m_crookDeduction = m_crookCInInches / d * m_crookCLInFeet / l; - - for (int faceIndex = 0; faceIndex < 4; faceIndex++) { - auto& face = tempLogGrading.m_faces[faceIndex]; - face.m_startAngle = (angleOffset + faceIndex * 90) % 360; - face.m_endAngle = (angleOffset + faceIndex * 90 + 90) % 360; - std::vector defectMarks; - defectMarks.resize(gradingSectionIntersectionCount); - for (int intersectionIndex = 0; intersectionIndex < gradingSectionIntersectionCount; intersectionIndex++) { - const auto& intersection = m_intersections[intersectionIndex + startIntersectionIndex]; + temp_log_grading.m_crook_deduction = m_crook_cl_in_inches / d * m_crook_cl_in_feet / l; + + for (int face_index = 0; face_index < 4; face_index++) { + auto& face = temp_log_grading.m_faces[face_index]; + face.m_start_angle = (angle_offset + face_index * 90) % 360; + face.m_end_angle = (angle_offset + face_index * 90 + 90) % 360; + std::vector defect_marks; + defect_marks.resize(grading_section_intersection_count); + for (int intersection_index = 0; intersection_index < grading_section_intersection_count; intersection_index++) { + const auto& intersection = m_intersections[intersection_index + start_intersection_index]; for (int angle = 0; angle < 90; angle++) { - const int actualAngle = (face.m_startAngle + angle) % 360; - if (intersection.m_boundary[actualAngle].m_defectStatus != 0.0f) { - defectMarks[intersectionIndex] = true; + const int actual_angle = (face.m_start_angle + angle) % 360; + if (intersection.m_boundary[actual_angle].m_defect_status != 0.0f) { + defect_marks[intersection_index] = true; break; } } } - bool f1Possible = true; + bool f1_possible = true; - if (!m_soundDefect) { - if (tempLogGrading.m_crookDeduction > 0.15f || tempLogGrading.m_sweepDeduction > 0.15f) { - f1Possible = false; + if (!m_sound_defect) { + if (temp_log_grading.m_crook_deduction > 0.15f || temp_log_grading.m_sweep_deduction > 0.15f) { + f1_possible = false; } } else { - if (tempLogGrading.m_crookDeduction > 0.1f || tempLogGrading.m_sweepDeduction > 0.1f) { - f1Possible = false; + if (temp_log_grading.m_crook_deduction > 0.1f || temp_log_grading.m_sweep_deduction > 0.1f) { + f1_possible = false; } } - bool f2Possible = true; - if (!f1Possible) { - if (!m_soundDefect) { - if (tempLogGrading.m_crookDeduction > 0.3f || tempLogGrading.m_sweepDeduction > 0.3f) { - f2Possible = false; + bool f2_possible = true; + if (!f1_possible) { + if (!m_sound_defect) { + if (temp_log_grading.m_crook_deduction > 0.3f || temp_log_grading.m_sweep_deduction > 0.3f) { + f2_possible = false; } } else { - if (tempLogGrading.m_crookDeduction > 0.2f || tempLogGrading.m_sweepDeduction > 0.2f) { - f2Possible = false; + if (temp_log_grading.m_crook_deduction > 0.2f || temp_log_grading.m_sweep_deduction > 0.2f) { + f2_possible = false; } } } - bool f3Possible = true; - if (!f2Possible) { - if (!m_soundDefect) { - if (tempLogGrading.m_crookDeduction > 0.5f || tempLogGrading.m_sweepDeduction > 0.5f) { - f3Possible = false; + bool f3_possible = true; + if (!f2_possible) { + if (!m_sound_defect) { + if (temp_log_grading.m_crook_deduction > 0.5f || temp_log_grading.m_sweep_deduction > 0.5f) { + f3_possible = false; } } else { - if (tempLogGrading.m_crookDeduction > 0.35f || tempLogGrading.m_sweepDeduction > 0.35f) { - f3Possible = false; + if (temp_log_grading.m_crook_deduction > 0.35f || temp_log_grading.m_sweep_deduction > 0.35f) { + f3_possible = false; } } } bool succeed = false; - if (f1Possible && m_butt && tempLogGrading.m_scalingDiameterInMeters >= InchesToMeters(13) && - tempLogGrading.m_scalingDiameterInMeters <= InchesToMeters(16) && - tempLogGrading.m_lengthWithoutTrimInMeters >= FeetToMeter(10)) { + if (f1_possible && m_butt && temp_log_grading.m_scaling_diameter_in_meters >= InchesToMeters(13) && + temp_log_grading.m_scaling_diameter_in_meters <= InchesToMeters(16) && + temp_log_grading.m_length_without_trim_in_meters >= FeetToMeter(10)) { // F1: Butt, Scaling diameter 13-15(16), Length 10+ - const auto cuttings7 = CalculateCuttings(cuttingTrim, defectMarks, intersectionLength, FeetToMeter(7), - tempLogGrading.m_startHeightInMeters); - float minCuttingLength = 0.0f; + const auto cuttings7 = CalculateCuttings(cutting_trim, defect_marks, intersection_length, FeetToMeter(7), + temp_log_grading.m_start_height_in_meters); + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings7, 2, 5.0f / 6.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings7, 2, 5.0f / 6.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - face.m_faceGrade = 1; - face.m_clearCuttings = cuttings7; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 1; + face.m_clear_cuttings = cuttings7; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - if (f1Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(16) && - tempLogGrading.m_scalingDiameterInMeters <= InchesToMeters(20) && - tempLogGrading.m_lengthWithoutTrimInMeters >= FeetToMeter(10)) { + if (f1_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(16) && + temp_log_grading.m_scaling_diameter_in_meters <= InchesToMeters(20) && + temp_log_grading.m_length_without_trim_in_meters >= FeetToMeter(10)) { // F1: Butt & uppers, Scaling diameter 16-19(20), Length 10+ - const auto cuttings5 = CalculateCuttings(cuttingTrim, defectMarks, intersectionLength, FeetToMeter(5), - tempLogGrading.m_startHeightInMeters); - float minCuttingLength = 0.0f; + const auto cuttings5 = CalculateCuttings(cutting_trim, defect_marks, intersection_length, FeetToMeter(5), + temp_log_grading.m_start_height_in_meters); + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings5, 2, 5.0f / 6.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings5, 2, 5.0f / 6.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - face.m_faceGrade = 2; - face.m_clearCuttings = cuttings5; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 2; + face.m_clear_cuttings = cuttings5; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - const auto cuttings3 = CalculateCuttings(cuttingTrim, defectMarks, intersectionLength, FeetToMeter(3), - tempLogGrading.m_startHeightInMeters); - if (f1Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(20) && - tempLogGrading.m_lengthWithoutTrimInMeters >= FeetToMeter(10)) { + const auto cuttings3 = CalculateCuttings(cutting_trim, defect_marks, intersection_length, FeetToMeter(3), + temp_log_grading.m_start_height_in_meters); + if (f1_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(20) && + temp_log_grading.m_length_without_trim_in_meters >= FeetToMeter(10)) { // F1: Butt & uppers, Scaling diameter 20+, Length 10+ - // const auto cuttings3 = CalculateCuttings(defectMarks, heightStep, FeetToMeter(3)); - float minCuttingLength = 0.0f; + // const auto cuttings3 = CalculateCuttings(defectMarks, height_step, FeetToMeter(3)); + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings3, 2, 5.0f / 6.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings3, 2, 5.0f / 6.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - face.m_faceGrade = 3; - face.m_clearCuttings = cuttings3; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 3; + face.m_clear_cuttings = cuttings3; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - if (f2Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(11) && - tempLogGrading.m_lengthWithoutTrimInMeters >= FeetToMeter(10)) { + if (f2_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(11) && + temp_log_grading.m_length_without_trim_in_meters >= FeetToMeter(10)) { // F2: Butt & uppers, Scaling diameter 11+, Length 10+ - float minCuttingLength = 0.0f; + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings3, 2, 2.0f / 3.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings3, 2, 2.0f / 3.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - face.m_faceGrade = 4; - face.m_clearCuttings = cuttings3; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 4; + face.m_clear_cuttings = cuttings3; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - if (f2Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(12) && - tempLogGrading.m_lengthWithoutTrimInMeters > FeetToMeter(8) && - tempLogGrading.m_lengthWithoutTrimInMeters <= FeetToMeter(10)) { + if (f2_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(12) && + temp_log_grading.m_length_without_trim_in_meters > FeetToMeter(8) && + temp_log_grading.m_length_without_trim_in_meters <= FeetToMeter(10)) { // F2: Butt & uppers, Scaling diameter 12+, Length 8-9(10) - float minCuttingLength = 0.0f; + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings3, 2, 3.0f / 4.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings3, 2, 3.0f / 4.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - if (!m_soundDefect) { - if (tempLogGrading.m_crookDeduction > 0.3f || tempLogGrading.m_sweepDeduction > 0.3f) { + if (!m_sound_defect) { + if (temp_log_grading.m_crook_deduction > 0.3f || temp_log_grading.m_sweep_deduction > 0.3f) { succeed = false; } } else { - if (tempLogGrading.m_crookDeduction > 0.2f || tempLogGrading.m_sweepDeduction > 0.2f) { + if (temp_log_grading.m_crook_deduction > 0.2f || temp_log_grading.m_sweep_deduction > 0.2f) { succeed = false; } } } if (succeed) { - face.m_faceGrade = 5; - face.m_clearCuttings = cuttings3; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 5; + face.m_clear_cuttings = cuttings3; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - if (f2Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(12) && - tempLogGrading.m_lengthWithoutTrimInMeters > FeetToMeter(10) && - tempLogGrading.m_lengthWithoutTrimInMeters <= FeetToMeter(12)) { + if (f2_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(12) && + temp_log_grading.m_length_without_trim_in_meters > FeetToMeter(10) && + temp_log_grading.m_length_without_trim_in_meters <= FeetToMeter(12)) { // F2: Butt & uppers, Scaling diameter 12+, Length 10-11(12) - float minCuttingLength = 0.0f; + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings3, 2, 2.0f / 3.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings3, 2, 2.0f / 3.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - if (!m_soundDefect) { - if (tempLogGrading.m_crookDeduction > 0.3f || tempLogGrading.m_sweepDeduction > 0.3f) { + if (!m_sound_defect) { + if (temp_log_grading.m_crook_deduction > 0.3f || temp_log_grading.m_sweep_deduction > 0.3f) { succeed = false; } } else { - if (tempLogGrading.m_crookDeduction > 0.2f || tempLogGrading.m_sweepDeduction > 0.2f) { + if (temp_log_grading.m_crook_deduction > 0.2f || temp_log_grading.m_sweep_deduction > 0.2f) { succeed = false; } } } if (succeed) { - face.m_faceGrade = 6; - face.m_clearCuttings = cuttings3; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 6; + face.m_clear_cuttings = cuttings3; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - if (f2Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(12) && - tempLogGrading.m_lengthWithoutTrimInMeters > FeetToMeter(12)) { + if (f2_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(12) && + temp_log_grading.m_length_without_trim_in_meters > FeetToMeter(12)) { // F2: Butt & uppers, Scaling diameter 12+, Length 12+ - float minCuttingLength = 0.0f; + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings3, 3, 2.0f / 3.0f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings3, 3, 2.0f / 3.0f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); if (succeed) { - if (!m_soundDefect) { - if (tempLogGrading.m_crookDeduction > 0.3f || tempLogGrading.m_sweepDeduction > 0.3f) { + if (!m_sound_defect) { + if (temp_log_grading.m_crook_deduction > 0.3f || temp_log_grading.m_sweep_deduction > 0.3f) { succeed = false; } } else { - if (tempLogGrading.m_crookDeduction > 0.2f || tempLogGrading.m_sweepDeduction > 0.2f) { + if (temp_log_grading.m_crook_deduction > 0.2f || temp_log_grading.m_sweep_deduction > 0.2f) { succeed = false; } } } if (succeed) { - face.m_faceGrade = 7; - face.m_clearCuttings = cuttings3; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 7; + face.m_clear_cuttings = cuttings3; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - const auto cuttings2 = CalculateCuttings(cuttingTrim, defectMarks, intersectionLength, FeetToMeter(2), - tempLogGrading.m_startHeightInMeters); - if (f3Possible && !succeed && tempLogGrading.m_scalingDiameterInMeters > InchesToMeters(8) && - tempLogGrading.m_lengthWithoutTrimInMeters > FeetToMeter(8)) { + const auto cuttings2 = CalculateCuttings(cutting_trim, defect_marks, intersection_length, FeetToMeter(2), + temp_log_grading.m_start_height_in_meters); + if (f3_possible && !succeed && temp_log_grading.m_scaling_diameter_in_meters > InchesToMeters(8) && + temp_log_grading.m_length_without_trim_in_meters > FeetToMeter(8)) { // F3: Butt & uppers, Scaling diameter 8+, Length 8+ - float minCuttingLength = 0.0f; + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings2, 999, 1.0f / 2.0f, tempLogGrading.m_lengthWithoutTrimInMeters, - minCuttingLength, proportion); + succeed = TestCutting(cuttings2, 999, 1.0f / 2.0f, temp_log_grading.m_length_without_trim_in_meters, + min_cutting_length, proportion); if (succeed) { - face.m_faceGrade = 8; - face.m_clearCuttings = cuttings2; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 8; + face.m_clear_cuttings = cuttings2; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } if (!succeed) { - float minCuttingLength = 0.0f; + float min_cutting_length = 0.0f; float proportion = 0.0f; - succeed = TestCutting(cuttings2, 999, 0.f, tempLogGrading.m_lengthWithoutTrimInMeters, minCuttingLength, + succeed = TestCutting(cuttings2, 999, 0.f, temp_log_grading.m_length_without_trim_in_meters, min_cutting_length, proportion); - face.m_faceGrade = 9; - face.m_clearCuttings = cuttings2; - face.m_clearCuttingMinLengthInMeters = minCuttingLength; - face.m_clearCuttingMinProportion = proportion; + face.m_face_grade = 9; + face.m_clear_cuttings = cuttings2; + face.m_clear_cutting_min_length_in_meters = min_cutting_length; + face.m_clear_cutting_min_proportion = proportion; } } - int worstGradeIndex = -1; - int worstGrade = 0; + int worst_grade_index = -1; + int worst_grade = 0; for (int i = 0; i < 4; i++) { - if (tempLogGrading.m_faces[i].m_faceGrade > worstGrade) { - worstGradeIndex = i; - worstGrade = tempLogGrading.m_faces[i].m_faceGrade; + if (temp_log_grading.m_faces[i].m_face_grade > worst_grade) { + worst_grade_index = i; + worst_grade = temp_log_grading.m_faces[i].m_face_grade; } } - int secondWorstGradeIndex = -1; - worstGrade = 0; + int second_worst_grade_index = -1; + worst_grade = 0; for (int i = 0; i < 4; i++) { - if (i != worstGradeIndex && tempLogGrading.m_faces[i].m_faceGrade > worstGrade) { - secondWorstGradeIndex = i; - worstGrade = tempLogGrading.m_faces[i].m_faceGrade; + if (i != worst_grade_index && temp_log_grading.m_faces[i].m_face_grade > worst_grade) { + second_worst_grade_index = i; + worst_grade = temp_log_grading.m_faces[i].m_face_grade; } } - tempLogGrading.m_gradeDetermineFaceIndex = secondWorstGradeIndex; - tempLogGrading.m_grade = worstGrade; + temp_log_grading.m_grade_determine_face_index = second_worst_grade_index; + temp_log_grading.m_grade = worst_grade; } } - int bestGrade = INT_MAX; + int best_grade = INT_MAX; for (const auto& result : results) { - if (result.m_grade < bestGrade) { - bestGrade = result.m_grade; - logGrading.clear(); - logGrading.emplace_back(result); - } else if (result.m_grade == bestGrade) { - logGrading.emplace_back(result); + if (result.m_grade < best_grade) { + best_grade = result.m_grade; + log_grading.clear(); + log_grading.emplace_back(result); + } else if (result.m_grade == best_grade) { + log_grading.emplace_back(result); } } } -void LogWood::ColorBasedOnGrading(const LogGrading& logGradingData) { - const float intersectionLength = m_length / m_intersections.size(); - const int gradingSectionIntersectionCount = glm::ceil(FeetToMeter(12) / intersectionLength); - for (const auto& face : logGradingData.m_faces) { - for (int intersectionIndex = 0; intersectionIndex < m_intersections.size(); intersectionIndex++) { - auto& intersection = m_intersections[intersectionIndex]; +void LogWood::ColorBasedOnGrading(const LogGrading& log_grading_data) { + const float intersection_length = m_length / m_intersections.size(); + const int grading_section_intersection_count = std::ceil(FeetToMeter(12) / intersection_length); + for (const auto& face : log_grading_data.m_faces) { + for (int intersection_index = 0; intersection_index < m_intersections.size(); intersection_index++) { + auto& intersection = m_intersections[intersection_index]; for (int angle = 0; angle < 90; angle++) { - const int actualAngle = (face.m_startAngle + angle) % 360; - auto& point = intersection.m_boundary[actualAngle]; + const int actual_angle = (face.m_start_angle + angle) % 360; + auto& point = intersection.m_boundary[actual_angle]; - if (point.m_defectStatus != 0.0f) { - point.m_color = glm::vec4(1, 0, 0, 1); + if (point.m_defect_status != 0.0f) { + point.m_color = Vec4{1, 0, 0, 1}; continue; } - const float height = intersectionLength * intersectionIndex; - bool isCutting = false; - for (const auto& cutting : face.m_clearCuttings) { - if (height >= cutting.m_startInMeters && height <= cutting.m_endInMeters) { - if (face.m_faceGrade <= 3) { - point.m_color = glm::vec4(212.f / 255, 175.f / 255, 55.f / 255, 1); - } else if (face.m_faceGrade <= 7) { - point.m_color = glm::vec4(170.f / 255, 169.f / 255, 173.f / 255, 1); - } else if (face.m_faceGrade <= 8) { - point.m_color = glm::vec4(131.f / 255, 105.f / 255, 83.f / 255, 1); + const float height = intersection_length * intersection_index; + bool is_cutting = false; + for (const auto& cutting : face.m_clear_cuttings) { + if (height >= cutting.m_start_in_meters && height <= cutting.m_end_in_meters) { + if (face.m_face_grade <= 3) { + point.m_color = Vec4{212.f / 255, 175.f / 255, 55.f / 255, 1}; + } else if (face.m_face_grade <= 7) { + point.m_color = Vec4{170.f / 255, 169.f / 255, 173.f / 255, 1}; + } else if (face.m_face_grade <= 8) { + point.m_color = Vec4{131.f / 255, 105.f / 255, 83.f / 255, 1}; } else { - point.m_color = glm::vec4(0.1f, 0.1f, 0.1f, 1); + point.m_color = Vec4{0.1f, 0.1f, 0.1f, 1}; } - isCutting = true; + is_cutting = true; break; } } - if (!isCutting) { - if (intersectionIndex < logGradingData.m_startIntersectionIndex || - intersectionIndex > logGradingData.m_startIntersectionIndex + gradingSectionIntersectionCount) { - point.m_color = glm::vec4(0, 0, 0, 1); + if (!is_cutting) { + if (intersection_index < log_grading_data.m_start_intersection_index || + intersection_index > log_grading_data.m_start_intersection_index + grading_section_intersection_count) { + point.m_color = Vec4{0, 0, 0, 1}; } else { - point.m_color = glm::vec4(0.2f, 0.0f, 0.0f, 1); + point.m_color = Vec4{0.2f, 0.0f, 0.0f, 1}; } } } diff --git a/EvoEngine_SDK/src/Bound.cpp b/EvoEngine_SDK/src/Bound.cpp index e3f1cbe..a3288ff 100644 --- a/EvoEngine_SDK/src/Bound.cpp +++ b/EvoEngine_SDK/src/Bound.cpp @@ -185,12 +185,12 @@ glm::vec3 Ray::GetEnd() const { } glm::vec3 Ray::ClosestPointOnLine(const glm::vec3& point, const glm::vec3& a, const glm::vec3& b) { - const float line_length = distance(a, b); + const float line_length = glm::distance(a, b); const glm::vec3 vector = point - a; const glm::vec3 line_direction = (b - a) / line_length; // Project Vector to LineDirection to get the distance of point from a - const float distance = dot(vector, line_direction); + const float distance = glm::dot(vector, line_direction); return a + line_direction * distance; }