1 module ws.math.collision;
2 
3 
4 import 
5 	ws.math.math,
6 	ws.math.vector;
7 
8 
9 struct Line {
10 	float[3] origin;
11 	float[3] dir;
12 }
13 
14 struct Plane {
15 	float[3] origin;
16 	float[3] normal;
17 }
18 
19 struct Cube {
20 	float[3] origin;
21 	float scale;
22 }
23 
24 class Result {
25 	bool hit;
26 }
27 
28 class LinePlaneResult: Result {
29 	float[3] pos;
30 }
31 
32 class LineCubeResult: Result {
33 	float[3] pos;
34 	float[3] normal;
35 	float distance;
36 }
37 
38 LinePlaneResult collide(Line line, Plane plane){
39 	auto numerator = (plane.origin.vec - line.origin.vec) * plane.normal.vec;
40 	auto denominator = line.dir.vec*plane.normal.vec;
41 	auto res = new LinePlaneResult;
42 	res.hit = numerator/denominator > 0.0001;
43 	res.pos = line.origin.vec + line.dir.vec*(numerator/denominator);
44 	return res;
45 }
46 
47 
48 LineCubeResult collide(Line line, Cube cube){
49 	
50 	auto lb = cube.origin.vec-vec(1,1,1)/2*cube.scale;
51 	auto rt = cube.origin.vec+vec(1,1,1)/2*cube.scale;
52 	
53 	float[3] dirfrac;
54 	dirfrac.x = 1.0f / line.dir.x;
55 	dirfrac.y = 1.0f / line.dir.y;
56 	dirfrac.z = 1.0f / line.dir.z;
57 
58 	float t1 = (lb.x - line.origin.x)*dirfrac.x;
59 	float t2 = (rt.x - line.origin.x)*dirfrac.x;
60 	float t3 = (lb.y - line.origin.y)*dirfrac.y;
61 	float t4 = (rt.y - line.origin.y)*dirfrac.y;
62 	float t5 = (lb.z - line.origin.z)*dirfrac.z;
63 	float t6 = (rt.z - line.origin.z)*dirfrac.z;
64 
65 	float tmin = fmax(fmax(fmin(t1, t2), fmin(t3, t4)), fmin(t5, t6));
66 	float tmax = fmin(fmin(fmax(t1, t2), fmax(t3, t4)), fmax(t5, t6));
67 
68 	if (tmax < 0 || tmin > tmax)
69 	    return null;
70 
71 	auto res = new LineCubeResult;
72 	res.distance = tmin;
73 	res.pos = line.origin.vec + line.dir.vec*res.distance;
74 	auto help = (res.pos.vec - cube.origin.vec)/cube.scale*2.0001;
75 	res.normal = help.to!int.to!float;
76 	return res;
77 }
78 
79 
80 float[3] line_plane(float[3] lineStart, float[3] lineDir, float[3] planeOrigin, float[3] planeNormal){
81 	auto numerator = (vec(planeOrigin) - vec(lineStart)) * vec(planeNormal);
82 	auto denominator = vec(lineDir)*vec(planeNormal);
83 	return vec(lineStart) + vec(lineDir)*(numerator/denominator);
84 }