Added basic triangle raycasting.
This commit is contained in:
@ -23,6 +23,9 @@ bool_t Dawn::raytestSphere(
|
|||||||
glm::vec3 *hit,
|
glm::vec3 *hit,
|
||||||
glm::vec3 *normal
|
glm::vec3 *normal
|
||||||
) {
|
) {
|
||||||
|
assertNotNull(hit);
|
||||||
|
assertNotNull(normal);
|
||||||
|
|
||||||
glm::vec3 h, n;
|
glm::vec3 h, n;
|
||||||
auto result = glm::intersectRaySphere(
|
auto result = glm::intersectRaySphere(
|
||||||
ray.origin, ray.direction,
|
ray.origin, ray.direction,
|
||||||
@ -30,8 +33,8 @@ bool_t Dawn::raytestSphere(
|
|||||||
h, n
|
h, n
|
||||||
);
|
);
|
||||||
|
|
||||||
if(hit != nullptr) *hit = h;
|
*hit = h;
|
||||||
if(normal != nullptr) *normal = n;
|
*normal = n;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -39,19 +42,54 @@ bool_t Dawn::raytestSphere(
|
|||||||
bool_t Dawn::raytestTriangle(
|
bool_t Dawn::raytestTriangle(
|
||||||
struct Ray3D ray,
|
struct Ray3D ray,
|
||||||
struct PhysicsTriangle triangle,
|
struct PhysicsTriangle triangle,
|
||||||
glm::vec2 *hit,
|
glm::vec3 *hitPoint,
|
||||||
float_t *distance
|
glm::vec3 *hitNormal,
|
||||||
|
float_t *hitDistance
|
||||||
) {
|
) {
|
||||||
glm::vec2 h;
|
assertNotNull(hitPoint);
|
||||||
float_t d;
|
assertNotNull(hitNormal);
|
||||||
auto result = glm::intersectRayTriangle(
|
assertNotNull(hitDistance);
|
||||||
ray.origin, ray.direction,
|
|
||||||
triangle.v0, triangle.v1, triangle.v2,
|
// Calculate the normal of the triangle
|
||||||
h, d
|
glm::vec3 e0 = triangle.v1 - triangle.v0;
|
||||||
);
|
glm::vec3 e1 = triangle.v2 - triangle.v0;
|
||||||
if(hit != nullptr) *hit = h;
|
glm::vec3 normal = glm::normalize(glm::cross(e0, e1));
|
||||||
if(distance != nullptr) *distance = d;
|
|
||||||
return result;
|
// Calculate the denominator of the ray-triangle intersection formula
|
||||||
|
float_t denominator = glm::dot(normal, ray.direction);
|
||||||
|
|
||||||
|
// If the denominator is zero, the ray and triangle are parallel and there is no intersection
|
||||||
|
if(denominator == 0) return -1;
|
||||||
|
|
||||||
|
// Calculate the distance from the ray origin to the plane of the triangle
|
||||||
|
float_t d = glm::dot(triangle.v0 - ray.origin, normal) / denominator;
|
||||||
|
|
||||||
|
// If the distance is negative, the intersection point is behind the ray origin and there is no intersection
|
||||||
|
if(d < 0) return -1;
|
||||||
|
|
||||||
|
// Calculate the intersection point
|
||||||
|
glm::vec3 intersectionPoint = ray.origin + d * ray.direction;
|
||||||
|
|
||||||
|
// Check if the intersection point is inside the triangle
|
||||||
|
glm::vec3 edge0 = triangle.v1 - triangle.v0;
|
||||||
|
glm::vec3 edge1 = triangle.v2 - triangle.v1;
|
||||||
|
glm::vec3 edge2 = triangle.v0 - triangle.v2;
|
||||||
|
glm::vec3 c0 = intersectionPoint - triangle.v0;
|
||||||
|
glm::vec3 c1 = intersectionPoint - triangle.v1;
|
||||||
|
glm::vec3 c2 = intersectionPoint - triangle.v2;
|
||||||
|
glm::vec3 n0 = glm::cross(edge0, c0);
|
||||||
|
glm::vec3 n1 = glm::cross(edge1, c1);
|
||||||
|
glm::vec3 n2 = glm::cross(edge2, c2);
|
||||||
|
if (glm::dot(n0, normal) >= 0 && glm::dot(n1, normal) >= 0 && glm::dot(n2, normal) >= 0) {
|
||||||
|
// If the intersection point is inside the triangle, set the hit point, normal and distance
|
||||||
|
*hitPoint = intersectionPoint;
|
||||||
|
*hitNormal = normal;
|
||||||
|
*hitDistance = d;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the intersection point is outside the triangle, there is no intersection
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t Dawn::raytestAABB(
|
bool_t Dawn::raytestAABB(
|
||||||
|
@ -26,8 +26,9 @@ namespace Dawn {
|
|||||||
bool_t raytestTriangle(
|
bool_t raytestTriangle(
|
||||||
struct Ray3D ray,
|
struct Ray3D ray,
|
||||||
struct PhysicsTriangle triangle,
|
struct PhysicsTriangle triangle,
|
||||||
glm::vec2 *hit,
|
glm::vec3 *hitPoint,
|
||||||
float_t *distance
|
glm::vec3 *hitNormal,
|
||||||
|
float_t *hitDistance
|
||||||
);
|
);
|
||||||
|
|
||||||
bool_t raytestAABB(
|
bool_t raytestAABB(
|
||||||
|
@ -18,8 +18,10 @@ void RayTester3D::onStart() {
|
|||||||
|
|
||||||
void RayTester3D::onUpdate() {
|
void RayTester3D::onUpdate() {
|
||||||
prefab->transform.setLocalPosition(glm::vec3(0, 0, 0));
|
prefab->transform.setLocalPosition(glm::vec3(0, 0, 0));
|
||||||
box.max = glm::vec3( 0.5f, 0.5f, 0.5f);
|
|
||||||
box.min = glm::vec3(-0.5f, -0.5f, -0.5f);
|
triangle.v0 = glm::vec3(-0.5f, -0.5f, 0);
|
||||||
|
triangle.v1 = glm::vec3(0.5f, -0.5f, 0);
|
||||||
|
triangle.v2 = glm::vec3(0, 0.5f, 0);
|
||||||
|
|
||||||
auto mouse = this->getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
|
auto mouse = this->getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
|
||||||
mouse *= 2.0f;
|
mouse *= 2.0f;
|
||||||
@ -32,7 +34,7 @@ void RayTester3D::onUpdate() {
|
|||||||
// prefab->transform.setLocalPosition(pos);
|
// prefab->transform.setLocalPosition(pos);
|
||||||
// ray.origin = glm::vec3(0, 0, 5);
|
// ray.origin = glm::vec3(0, 0, 5);
|
||||||
|
|
||||||
bool_t x = raytestAABB(ray, box, &hit, &normal, &distance);
|
bool_t x = raytestTriangle(ray, triangle, &hit, &normal, &distance);
|
||||||
|
|
||||||
if(x) {
|
if(x) {
|
||||||
prefab->material->color = COLOR_RED;
|
prefab->material->color = COLOR_RED;
|
||||||
|
@ -14,7 +14,7 @@ namespace Dawn {
|
|||||||
public:
|
public:
|
||||||
SimpleSpinningCubePrefab *prefab;
|
SimpleSpinningCubePrefab *prefab;
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
struct AABB3D box;
|
struct PhysicsTriangle triangle;
|
||||||
struct Ray3D ray;
|
struct Ray3D ray;
|
||||||
glm::vec3 hit;
|
glm::vec3 hit;
|
||||||
glm::vec3 normal;
|
glm::vec3 normal;
|
||||||
|
@ -9,8 +9,4 @@ using namespace Dawn;
|
|||||||
|
|
||||||
CubeCollider::CubeCollider(SceneItem *item) : Collider3D(item) {
|
CubeCollider::CubeCollider(SceneItem *item) : Collider3D(item) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool_t CubeCollider::raycast(struct Ray3D ray, struct Collider3DRayResult *out){
|
|
||||||
return false;
|
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Collider3D.hpp"
|
#include "Collider3D.hpp"
|
||||||
|
#include "physics/3d/Ray3D.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class CubeCollider : public Collider3D {
|
class CubeCollider : public Collider3D {
|
||||||
@ -13,7 +14,5 @@ namespace Dawn {
|
|||||||
glm::vec3 size = glm::vec3(1, 1, 1);
|
glm::vec3 size = glm::vec3(1, 1, 1);
|
||||||
|
|
||||||
CubeCollider(SceneItem *item);
|
CubeCollider(SceneItem *item);
|
||||||
|
|
||||||
bool_t raycast(struct Ray3D ray, struct Collider3DRayResult *out)override;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,7 +7,7 @@
|
|||||||
#include "scene/Scene.hpp"
|
#include "scene/Scene.hpp"
|
||||||
#include "prefabs/SimpleSpinningCubePrefab.hpp"
|
#include "prefabs/SimpleSpinningCubePrefab.hpp"
|
||||||
#include "prefabs/TicTacToeTilePrefab.hpp"
|
#include "prefabs/TicTacToeTilePrefab.hpp"
|
||||||
#include "display/mesh/SphereMesh.hpp"
|
#include "display/mesh/TriangleMesh.hpp"
|
||||||
|
|
||||||
#include "scene/components/physics/3d/RayTester3D.hpp"
|
#include "scene/components/physics/3d/RayTester3D.hpp"
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ namespace Dawn {
|
|||||||
camera->orthoRight = s * ratio;
|
camera->orthoRight = s * ratio;
|
||||||
|
|
||||||
auto cube = SimpleSpinningCubePrefab::create(this);
|
auto cube = SimpleSpinningCubePrefab::create(this);
|
||||||
|
TriangleMesh::createTriangleMesh(&cube->meshHost->mesh);
|
||||||
// SphereMesh::createSphere(&cube->meshHost->mesh, 1.0f, 16, 16);
|
// SphereMesh::createSphere(&cube->meshHost->mesh, 1.0f, 16, 16);
|
||||||
auto tester = cube->addComponent<RayTester3D>();
|
auto tester = cube->addComponent<RayTester3D>();
|
||||||
tester->prefab = cube;
|
tester->prefab = cube;
|
||||||
|
Reference in New Issue
Block a user