51 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (c) 2023 Dominic Masters
 | |
| // 
 | |
| // This software is released under the MIT License.
 | |
| // https://opensource.org/licenses/MIT
 | |
| 
 | |
| #include "Ray3D.hpp"
 | |
| #include "assert/assert.hpp"
 | |
| 
 | |
| using namespace Dawn;
 | |
| 
 | |
| bool_t Dawn::raytestQuad(
 | |
|   const struct Ray3D ray,
 | |
|   const glm::vec2 min,
 | |
|   const glm::vec2 max,
 | |
|   const glm::mat4 transform,
 | |
|   glm::vec3 &point,
 | |
|   glm::vec3 &normal,
 | |
|   float_t &distance
 | |
| ) {
 | |
|   // transform ray into local space of the quad
 | |
|   glm::mat4 inverseTransform = glm::inverse(transform);
 | |
|   glm::vec3 localRayOrigin = glm::vec3(
 | |
|     inverseTransform * glm::vec4(ray.origin, 1.0f)
 | |
|   );
 | |
|   glm::vec3 localRayDirection = glm::vec3(
 | |
|     inverseTransform * glm::vec4(ray.direction, 0.0f)
 | |
|   );
 | |
| 
 | |
|   // perform ray-quad intersection test
 | |
|   float_t t = -localRayOrigin.z / localRayDirection.z; // intersection distance along ray
 | |
|   if(t < 0) return false; // intersection is behind the ray origin
 | |
|   glm::vec2 intersectionPoint = (
 | |
|     glm::vec2(localRayOrigin) + t * glm::vec2(localRayDirection)
 | |
|   );
 | |
|   if(
 | |
|     glm::any(glm::lessThan(intersectionPoint, min)) ||
 | |
|     glm::any(glm::greaterThan(intersectionPoint, max))
 | |
|   ) {
 | |
|     return false; // intersection is outside the quad
 | |
|   }
 | |
|   distance = t;
 | |
| 
 | |
|   // compute point and normal of intersection in world space
 | |
|   glm::vec3 localIntersectionPoint = glm::vec3(intersectionPoint, 0.0f);
 | |
|   point = glm::vec3(transform * glm::vec4(localIntersectionPoint, 1.0f));
 | |
|   normal = glm::normalize(
 | |
|     glm::vec3(transform * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f))
 | |
|   );
 | |
| 
 | |
|   return true; // intersection found
 | |
| } |