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