1 module sily.dlib.raycast;
2 
3 // TODO raycast
4 
5 import dlib.math.vector;
6 import dlib.geometry.triangle;
7 
8 struct RayIntersection {
9     vec3 collisionPoint = vec3(0.0f, 0.0f, 0.0f);
10     bool isColliding = false;
11 }
12 
13 /** 
14  * 
15  * Params:
16  *   origin = origin point of collision vector
17  *   target = target point of collision vector
18  *   triangle = triangle to intersect
19  * Returns: `RayIntersection` struct containing intersection results
20  */
21 RayIntersection rayIntersectTriangle(vec3 origin, vec3 target, Triangle triangle) {
22     const float eps = float.epsilon;
23 
24     vec3 v0 = triangle.v[0];
25     vec3 v1 = triangle.v[1];
26     vec3 v2 = triangle.v[2];
27 
28     vec3 edge1, edge2, h, s, q;
29     float a, f, u, v;
30 
31     edge1 = v1 - v0;
32     edge2 = v2 - v0;
33 
34     h = target.cross(edge2);
35     a = edge1.dot(h);
36 
37     if (a > -eps && a < eps) {
38         // ray is parallel
39         return RayIntersection();
40     }
41 
42     f = 1.0 / a;
43     s = origin - v0;
44     u = f * s.dot(h);
45 
46     if (u < 0.0f || u > 1.0f) {
47         return RayIntersection();
48     }
49 
50     q = s.cross(edge1);
51     v = f * target.dot(q);
52 
53     if (v < 0.0 || u + v > 1.0f) {
54         return RayIntersection();
55     }
56 
57     float t = f * edge2.dot(q);
58 
59     if (t > eps) {
60         return RayIntersection(origin + target * t, true);
61     }
62 
63     return RayIntersection();
64 }
65 
66 RayStaticResult rayCast(vec3 origin, vec3 normal, float dist, bool doDraw = false) {
67     bool isBlock = false;
68     // TODO ask world for block
69     float step = 0.1f;
70     vec3 pos = origin;
71     for (int i = 0; i < dist; i++) {
72         // TODO ask for block here 
73         if (isBlock) {
74             return RayStaticResult(
75                 pos, pos, 
76                 vec3(1.0f, 1.0f, 1.0f),
77                 normal, true
78             );
79         }
80         pos += normal * step;
81     }
82     
83     return RayStaticResult();
84 }
85 
86 struct RayStaticResult {
87     vec3 point;
88     vec3 blockCenter;
89     vec3 blockSize;
90     vec3 hitNormal;
91     bool isHit = false;
92 }
93 
94 RayStaticResult rayIntersectStatic(vec3 origin, vec3 normal, float dist, bool doDraw = false) {
95     return RayStaticResult();
96 }
97 
98 RayStaticResult doStaticRaycast(vec3 origin, vec3 normal, float dist, vec3 corner, vec3 step, bool doDraw = false) {
99     vec3 blockCenter = corner - (vec3(0.5f) * step);
100     if (doDraw) {
101         // TODO draw
102     } 
103 
104     return RayStaticResult();
105 }
106 
107 // LINK https://github.com/codingminecraft/StreamMinecraftClone
108 // LINK https://github.com/codingminecraft/StreamMinecraftClone/blob/master/Minecraft/src/physics/Physics.cpp
109