1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | using UnityEngine; using System.Collections; // ref #1 : http://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection public class CustomRayCast : MonoBehaviour { public static bool InterSectWithAABB(Ray ray, CustomAABB aabb) { if (!aabb.isEnable) return false; float tmin = (aabb.minExtent.x - ray.origin.x) / ray.direction.normalized.x; float tmax = (aabb.maxExtent.x - ray.origin.x) / ray.direction.normalized.x; if (tmin > tmax) { float tmp = tmin; tmin = tmax; tmax = tmp; } float tymin = (aabb.minExtent.y - ray.origin.y) / ray.direction.normalized.y; float tymax = (aabb.maxExtent.y - ray.origin.y) / ray.direction.normalized.y; if (tymin > tymax) { float tmp = tymin; tymin = tymax; tymax = tmp; } if ((tmin > tymax) || (tymin > tmax)) return false; if (tymin > tmin) tmin = tymin; if (tymax < tmax) tmax = tymax; float tzmin = (aabb.minExtent.z - ray.origin.z) / ray.direction.normalized.z; float tzmax = (aabb.maxExtent.z - ray.origin.z) / ray.direction.normalized.z; if (tzmin > tzmax) { float tmp = tzmin; tzmin = tzmax; tzmax = tmp; } if ((tmin > tzmax) || (tzmin > tmax)) return false; if (tzmin > tmin) tmin = tzmin; if (tzmax < tmax) tmax = tzmax; return true; } /// <summary> /// 테스트버전. /// </summary> /// <param name="r"></param> /// <param name="aabb"></param> /// <returns></returns> public static bool InterSectWithAABB_TEST_Version(Ray r, CustomAABB aabb) { if (!aabb.isEnable) return false; Vector3 dirfrac; float t; // r.direction is unit direction vector of ray dirfrac.x = 1.0f / r.direction.x; dirfrac.y = 1.0f / r.direction.y; dirfrac.z = 1.0f / r.direction.z; // aabb.minExtent is the corner of AABB with minimal coordinates - left bottom, aabb.maxExtent is maximal corner // r.origin is origin of ray float t1 = (aabb.minExtent.x - r.origin.x) * dirfrac.x; float t2 = (aabb.maxExtent.x - r.origin.x) * dirfrac.x; float t3 = (aabb.minExtent.y - r.origin.y) * dirfrac.y; float t4 = (aabb.maxExtent.y - r.origin.y) * dirfrac.y; float t5 = (aabb.minExtent.z - r.origin.z) * dirfrac.z; float t6 = (aabb.maxExtent.z - r.origin.z) * dirfrac.z; float tmin = Mathf.Max(Mathf.Max(Mathf.Min(t1, t2), Mathf.Min(t3, t4)), Mathf.Min(t5, t6)); float tmax = Mathf.Min(Mathf.Min(Mathf.Max(t1, t2), Mathf.Max(t3, t4)), Mathf.Max(t5, t6)); // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us if (tmax < 0) { t = tmax; return false; } // if tmin > tmax, ray doesn't intersect AABB if (tmin > tmax) { t = tmax; return false; } t = tmin; return true; } } |
2019년 4월 13일 토요일
# RayCasting - AABB와의 충돌 구현. ( C# 구현 )
# 픽킹 관련으로 구현하다보니 자연스레 레이캐스팅을 만들어보았다. 이것저것 공부할게 덤으로 생겼다.
# 해당 소스는 레퍼런스에서 C#으로 바꾸었을뿐이다.
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기