diff options
author | jjesswan <jessica_wan@brown.edu> | 2024-04-22 21:56:26 -0400 |
---|---|---|
committer | jjesswan <jessica_wan@brown.edu> | 2024-04-22 21:56:26 -0400 |
commit | a556b45abf18f1bd509daaf63b66b7d55e9fd291 (patch) | |
tree | bc9b8a2d184c12aee236e7f9f276a34b84ca552d /engine-ocean/Game/Components/CollisionComponents/BoundingTriangle.cpp | |
parent | cd7c76017a12bb548036571c1ff13e551369d06d (diff) |
add engine version
Diffstat (limited to 'engine-ocean/Game/Components/CollisionComponents/BoundingTriangle.cpp')
-rw-r--r-- | engine-ocean/Game/Components/CollisionComponents/BoundingTriangle.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/engine-ocean/Game/Components/CollisionComponents/BoundingTriangle.cpp b/engine-ocean/Game/Components/CollisionComponents/BoundingTriangle.cpp new file mode 100644 index 0000000..519d9c7 --- /dev/null +++ b/engine-ocean/Game/Components/CollisionComponents/BoundingTriangle.cpp @@ -0,0 +1,200 @@ +#include "boundingtriangle.h" +#include "Graphics/global.h" +#include "Graphics/modeltransform.h" +#include <iostream> +#include "glm/gtx/hash.hpp" + +// ONLY FOR ENVIRONMENTS +BoundingTriangle::BoundingTriangle(const std::vector<glm::vec3> &obj_data, + const std::shared_ptr<ModelTransform> &mt, + bool isGround) : + obj_mt(mt), + m_isGround(isGround) +{ + populateTriangleData(obj_data); + calculateBounds(obj_data); + //m_datasize = obj_data.size(); +} + +glm::vec3 BoundingTriangle::getRandomSurfacePos(){ + int randomIndex = std::floor(Global::graphics.generateRandomNumbers(0, m_triangles.size()-1)); + int randomVertex = std::floor(Global::graphics.generateRandomNumbers(0, 3)); + + Triangle randomTri = m_triangles[randomIndex]; + + if (glm::dot(glm::vec3(0,1,0), randomTri.normal) > 0.2f){ + switch(randomVertex){ + case 0: + return randomTri.vertexA; + break; + case 1: + return randomTri.vertexB; + break; + default: + return randomTri.vertexC; + break; + } + } else { + // do again until returning a surface triangle + getRandomSurfacePos(); + } +} + + +void BoundingTriangle::addTriangle(const glm::vec3 &vertexA, const glm::vec3 &vertexB, const glm::vec3 &vertexC){ + Triangle tri; + tri.vertexA = vertexA; + tri.vertexB = vertexB; + tri.vertexC = vertexC; + + tri.edge1 = vertexB - vertexA; // edge ab + tri.edge2 = vertexC - vertexA; // edge bc + tri.normal = glm::normalize(glm::cross(tri.edge1, tri.edge2)); + tri.bounds = calculateTriangleBounds(vertexA, vertexB, vertexC); + + // if triangle is a ground triangle + if (m_isGround){ + if (glm::dot(glm::vec3(0,1,0), tri.normal) > 0.2f){ + //std::cout << "area: " << getArea(vertexA, vertexB, vertexC) << std::endl; + tesselateTriangle(vertexA, vertexB, vertexC); + } + } + + m_triangles.push_back(tri); +} + +float BoundingTriangle::getArea(const glm::vec3 &A, const glm::vec3 &B, const glm::vec3 &C){ + glm::vec3 AB = B-A; + glm::vec3 AC = C-A; + return .5f*glm::length((glm::cross(AB,AC))); + +} + +glm::vec3 BoundingTriangle::getCentroid(const glm::vec3 &A, const glm::vec3 &B, const glm::vec3 &C){ + return .333f*(A + B + C); +} + +// tesselation into smaller triangles +void BoundingTriangle::tesselateTriangle(const glm::vec3 &A, const glm::vec3 &B, const glm::vec3 &C){ + float min_area = 1.5f; + + // add centroid if area is small enough + if (getArea(A,B,C) <= min_area){ + m_surface_points.push_back(getCentroid(A, B, C)); + return; + } + + // otherwise divide triangle in 4 (tesselate) + + glm::vec3 ab_mid = .5f*(A+B); + glm::vec3 ac_mid = .5f*(A+C); + glm::vec3 bc_mid = .5f*(B+C); + m_surface_points.push_back(ab_mid); + m_surface_points.push_back(ac_mid); + m_surface_points.push_back(bc_mid); + + tesselateTriangle(ab_mid, ac_mid, A); + tesselateTriangle(bc_mid, ab_mid, B); + tesselateTriangle(bc_mid, ac_mid, C); + tesselateTriangle(ab_mid, ac_mid, bc_mid); +} + + +void BoundingTriangle::populateTriangleData(const std::vector<glm::vec3> &obj_data){ + for (int i=0; i<obj_data.size(); i += 3){ + // convert to worldspace + glm::mat4 modelMat = obj_mt->getModelMatrix(); + glm::vec3 v1 = modelMat*glm::vec4(obj_data[i],1.0); + glm::vec3 v2 = modelMat*glm::vec4(obj_data[i+1],1.0); + glm::vec3 v3 = modelMat*glm::vec4(obj_data[i+2],1.0); + + // make triangle + addTriangle(v1, v2, v3); + } + +// m_surface_points.reserve(m_unique_surface_points.size()); +// std::copy(m_unique_surface_points.begin(), m_unique_surface_points.end(), m_surface_points.begin()); +} + +Bounds3f BoundingTriangle::calculateTriangleBounds(const glm::vec3 &vertexA, + const glm::vec3 &vertexB, + const glm::vec3 &vertexC){ + Bounds3f bounds; + + float max_x, min_x = vertexA.x; + float max_y, min_y = vertexA.y; + float max_z, min_z = vertexA.z; + + if (vertexB.x > max_x) max_x = vertexB.x; + if (vertexB.y > max_y) max_y = vertexB.y; + if (vertexB.z > max_z) max_z = vertexB.z; + + if (vertexC.x > max_x) max_x = vertexC.x; + if (vertexC.y > max_y) max_y = vertexC.y; + if (vertexC.z > max_z) max_z = vertexC.z; + + if (vertexB.x < min_x) min_x = vertexB.x; + if (vertexB.y < min_y) min_y = vertexB.y; + if (vertexB.z < min_z) min_z = vertexB.z; + + if (vertexC.x < min_x) min_x = vertexC.x; + if (vertexC.y < min_y) min_y = vertexC.y; + if (vertexC.z < min_z) min_z = vertexC.z; + + + bounds.max = glm::vec3(max_x, max_y, max_z); + bounds.min = glm::vec3(min_x, min_y, min_z); + + return bounds; +} + +void BoundingTriangle::calculateBounds(const std::vector<glm::vec3> &obj_data){ + max_x = obj_data[0].x; + min_x = obj_data[0].x; + max_y = obj_data[0].y; + min_y = obj_data[0].y; + max_z = obj_data[0].z; + min_z = obj_data[0].z; + + for (const glm::vec3 &v : obj_data){ + // check max + if (v.x > max_x){ + max_x = v.x; + } + if (v.y > max_y){ + max_y = v.y; + } + if (v.z > max_z){ + max_z = v.z; + } + + // check mins + if (v.x < min_x){ + min_x = v.x; + } + if (v.y < min_y){ + min_y = v.y; + } + if (v.z < min_z){ + min_z = v.z; + } + } +} + +Bounds3f BoundingTriangle::getMeshBounds(){ + Bounds3f bounds; + bounds.max = glm::vec3(max_x, max_y, max_z); + bounds.min = glm::vec3(min_x, min_y, min_z); + return bounds; +} + +std::vector<glm::vec3> BoundingTriangle::getSurfacePoints(){ + if (!m_isGround){ + std::cout << "getting surface points of not-ground object!" << std::endl; + } + return m_surface_points; +} + +std::vector<Triangle> BoundingTriangle::getTriangleData(){ + return m_triangles; +} |