직렬화 함수 작성 끝

This commit is contained in:
2025-06-09 03:47:48 +09:00
parent 5ba62b5312
commit 50c9bd68fc
47 changed files with 324 additions and 201 deletions

View File

@@ -0,0 +1,121 @@
#include "vulkan_engine/vulkan/physics.h"
#include <iostream>
#include <limits>
namespace veng {
void Physics::invokeOnColisionEvent(
gsl::not_null<utils::ThreadPool*> thread_pool, gsl::span<Model*> models) {
constexpr std::float_t EPSILON = std::numeric_limits<std::float_t>::epsilon();
for (int first = 0; first < models.size(); first++) {
if (!models[first]->colision) continue;
for (int second = first + 1; second < models.size(); second++) {
if (!models[second]->colision) continue;
std::float_t distance =
glm::distance(models[first]->position, models[second]->position);
std::float_t model1_radius =
models[first]->radius * models[first]->scale.x;
std::float_t model2_radius =
models[second]->radius * models[second]->scale.x;
if (distance <= model1_radius + model2_radius) {
if (models[first]->OnColision != nullptr)
thread_pool->enqueueJob(
[OnColision = models[first]->OnColision](
utils::ThreadPool* thread_pool, Model* self, Model* other) {
OnColision(self, other);
},
models[first], models[second]);
if (models[second]->OnColision != nullptr)
thread_pool->enqueueJob(
[OnColision = models[second]->OnColision](
utils::ThreadPool* thread_pool, Model* self, Model* other) {
OnColision(self, other);
},
models[second], models[first]);
break;
}
}
}
}
bool Physics::RayTrace(const glm::vec3& rayOrigin, const glm::vec3& rayDir,
const glm::vec3& v0, const glm::vec3& v1,
const glm::vec3& v2, std::float_t& outDistance) {
const std::float_t EPSILON = std::numeric_limits<std::float_t>::epsilon();
// 삼각형 엣지와 노멀 계산
glm::vec3 edge1 = v1 - v0;
glm::vec3 edge2 = v2 - v0;
glm::vec3 normal = glm::cross(edge1, edge2);
// 평행 여부 판단
glm::vec3 h = glm::cross(rayDir, edge2);
std::float_t a = glm::dot(edge1, h);
if (fabs(a) < EPSILON) {
// 광선 방향과 삼각형 평면이 거의 평행 → coplanar 검사
// 시작점이 평면 위에 있는지
std::float_t distToPlane = glm::dot(normal, rayOrigin - v0);
if (fabs(distToPlane) < EPSILON) {
// 평면 위에 있다면, 점이 삼각형 내부에 있는지 검사
auto pointInTri = [&](const glm::vec3& P) {
// 엣지마다 P가 같은 반대 방향 노멀 쪽에 있는지
glm::vec3 c0 = glm::cross(v1 - v0, P - v0);
glm::vec3 c1 = glm::cross(v2 - v1, P - v1);
glm::vec3 c2 = glm::cross(v0 - v2, P - v2);
std::float_t f0 = glm::dot(normal, c0);
std::float_t f1 = glm::dot(normal, c1);
std::float_t f2 = glm::dot(normal, c2);
return (f0 >= EPSILON && f1 >= EPSILON && f2 >= EPSILON);
};
if (pointInTri(rayOrigin)) {
outDistance = 0.0f;
return true;
}
}
return false;
}
// 기존 MöllerTrumbore 알고리즘
std::float_t f = 1.0f / a;
glm::vec3 s = rayOrigin - v0;
std::float_t u = f * glm::dot(s, h);
if (u < 0.0f || u > 1.0f) return false;
glm::vec3 q = glm::cross(s, edge1);
std::float_t v = f * glm::dot(rayDir, q);
if (v < 0.0f || u + v > 1.0f) return false;
std::float_t t = f * glm::dot(edge2, q);
if (t > EPSILON) {
outDistance = t;
return true;
}
return false;
}
bool Physics::IsPointInsideMesh_(const glm::vec3& point,
const std::vector<veng::Vertex>& vertices,
const std::vector<std::uint32_t>& indices) {
glm::vec3 rayDir = glm::vec3(1.0f, 0.0f, 0.0f); // X+ 방향 광선
int intersectionCount = 0;
for (size_t i = 0; i < indices.size(); i += 3) {
const glm::vec3& v0 = vertices[indices[i + 0]].position;
const glm::vec3& v1 = vertices[indices[i + 1]].position;
const glm::vec3& v2 = vertices[indices[i + 2]].position;
std::float_t t;
if (RayTrace(point, rayDir, v0, v1, v2, t)) {
intersectionCount++;
}
}
return (intersectionCount % 2 == 1); // 홀수면 내부}
}
} // namespace veng