-
Notifications
You must be signed in to change notification settings - Fork 12
/
collision_checker.rb
145 lines (128 loc) · 5.85 KB
/
collision_checker.rb
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
module DXOpal
class Sprite
module CollisionChecker
class Base
def check_triangle_triangle(ox, oy, dx, dy)
raise "override me"
end
end
class OpalChecker
def check_triangle_triangle(ox, oy, dx, dy)
return check_line_line(ox[0], oy[0], ox[1], oy[1], dx[1], dy[1], dx[2], dy[2]) ||
check_line_line(ox[0], oy[0], ox[1], oy[1], dx[2], dy[2], dx[0], dy[0]) ||
check_line_line(ox[1], oy[1], ox[2], oy[2], dx[0], dy[0], dx[1], dy[1]) ||
check_line_line(ox[1], oy[1], ox[2], oy[2], dx[2], dy[2], dx[0], dy[0]) ||
check_line_line(ox[2], oy[2], ox[0], oy[0], dx[0], dy[0], dx[1], dy[1]) ||
check_line_line(ox[2], oy[2], ox[0], oy[0], dx[1], dy[1], dx[2], dy[2]) ||
check_point_triangle(ox[0], oy[0], dx[0], dy[0], dx[1], dy[1], dx[2], dy[2]) ||
check_point_triangle(dx[0], dy[0], ox[0], oy[0], ox[1], oy[1], ox[2], oy[2])
end
private
def check_line_line(x1, y1, x2, y2, x3, y3, x4, y4)
!((((x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3)) *
((x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4)) > 0.0) ||
(((x3 - x4) * (y1 - y3) + (y3 - y4) * (x3 - x1)) *
((x3 - x4) * (y2 - y3) + (y3 - y4) * (x3 - x2)) > 0.0 ))
end
# checktriangle
def check_point_triangle(x, y, x1, y1, x2, y2, x3, y3)
return false if (x1 - x3) * (y1 - y2) == (x1 - x2) * (y1 - y3)
cx = (x1 + x2 + x3) / 3
cy = (y1 + y2 + y3) / 3
if (intersect( x1, y1, x2, y2, x, y, cx, cy ) < 0.0 ||
intersect( x2, y2, x3, y3, x, y, cx, cy ) < 0.0 ||
intersect( x3, y3, x1, y1, x, y, cx, cy ) < 0.0 )
return false
end
return true
end
def intersect(x1, y1, x2, y2, x3, y3, x4, y4)
((x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3)) *
((x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4))
end
end
class JsChecker
%x{
(function(){
var check_line_line = function(x1, y1, x2, y2, x3, y3, x4, y4){
return !((((x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3)) *
((x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4)) > 0.0) ||
(((x3 - x4) * (y1 - y3) + (y3 - y4) * (x3 - x1)) *
((x3 - x4) * (y2 - y3) + (y3 - y4) * (x3 - x2)) > 0.0 ));
};
var check_point_triangle = function(x, y, x1, y1, x2, y2, x3, y3){
if ((x1 - x3) * (y1 - y2) == (x1 - x2) * (y1 - y3))
return false;
var cx = (x1 + x2 + x3) / 3,
cy = (y1 + y2 + y3) / 3;
if (intersect( x1, y1, x2, y2, x, y, cx, cy ) < 0.0 ||
intersect( x2, y2, x3, y3, x, y, cx, cy ) < 0.0 ||
intersect( x3, y3, x1, y1, x, y, cx, cy ) < 0.0 ) {
return false;
}
return true;
};
var intersect = function(x1, y1, x2, y2, x3, y3, x4, y4){
return ((x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3)) *
((x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4));
};
Opal.DXOpal.JsCollisionChecker = {
check_triangle_triangle: function(ox, oy, dx, dy) {
return check_line_line(ox[0], oy[0], ox[1], oy[1], dx[1], dy[1], dx[2], dy[2]) ||
check_line_line(ox[0], oy[0], ox[1], oy[1], dx[2], dy[2], dx[0], dy[0]) ||
check_line_line(ox[1], oy[1], ox[2], oy[2], dx[0], dy[0], dx[1], dy[1]) ||
check_line_line(ox[1], oy[1], ox[2], oy[2], dx[2], dy[2], dx[0], dy[0]) ||
check_line_line(ox[2], oy[2], ox[0], oy[0], dx[0], dy[0], dx[1], dy[1]) ||
check_line_line(ox[2], oy[2], ox[0], oy[0], dx[1], dy[1], dx[2], dy[2]) ||
check_point_triangle(ox[0], oy[0], dx[0], dy[0], dx[1], dy[1], dx[2], dy[2]) ||
check_point_triangle(dx[0], dy[0], ox[0], oy[0], ox[1], oy[1], ox[2], oy[2]);
}
};
})();
}
def check_triangle_triangle(ox, oy, dx, dy)
`Opal.DXOpal.JsCollisionChecker.check_triangle_triangle(ox, oy, dx, dy)`
end
end
class WasmChecker
def self.load(path, &after)
%x{
var importObject = {imports: {}};
fetch(path + '/wasm/collision_checker_double.wasm').then(function(response){
return response.arrayBuffer();
}).then(function(buffer){
return WebAssembly.instantiate(buffer, importObject);
}).then(function(result) {
var instance = result.instance;
Opal.DXOpal.WasmCollisionChecker = {
check_triangle_triangle: function(ox, oy, dx, dy) {
var i32 = new Float32Array(instance.exports.memory.buffer);
i32[ 0] = ox[0];
i32[ 1] = ox[1];
i32[ 2] = ox[2];
i32[ 3] = oy[0];
i32[ 4] = oy[1];
i32[ 5] = oy[2];
i32[ 6] = dx[0];
i32[ 7] = dx[1];
i32[ 8] = dx[2];
i32[ 9] = dy[0];
i32[10] = dy[1];
i32[11] = dy[2];
return instance.exports.check_triangle_triangle(0*4, 3*4, 6*4, 9*4);
}
};
}).then(after)
.catch((reason) => {
console.error("Failed to load wasm file. Reason:", reason);
after();
});
}
end
def check_triangle_triangle(ox, oy, dx, dy)
`Opal.DXOpal.WasmCollisionChecker.check_triangle_triangle(ox, oy, dx, dy) != 0`
end
end
end
end
end