-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbifilar-coil-1.irmf
70 lines (58 loc) · 2.53 KB
/
bifilar-coil-1.irmf
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
/*{
"author": "Glenn M. Lewis",
"copyright": "Apache-2.0",
"date": "2020-02-13",
"irmf": "1.0",
"materials": ["copper","copper"],
"max": [22,22,0.425],
"min": [-22,-22,-0.425],
"notes": "Simple IRMF shader - bifilar-coil.",
"options": {},
"title": "bifilar-coil",
"units": "mm",
"version": "1.0"
}*/
#define M_PI 3.1415926535897932384626433832795
float spiralSquareFace(float startRadius, float size, float gap, float nTurns, in vec3 xyz) {
// First, trivial reject above and below the spiral.
if (xyz.z < -0.5 * size || xyz.z > 0.5 * size) { return 0.0; }
float r = length(xyz.xy);
if (r < startRadius - 0.5 * size || r > startRadius + 0.5 * size + (size + gap) * nTurns) { return 0.0; }
// If the current point is between the spirals, return no material:
float angle = atan(xyz.y, xyz.x) / (2.0 * M_PI);
if (angle < 0.0) { angle += 1.0; } // 0 <= angle <= 1 between spirals from center to center.
float dr = mod(r - startRadius, size + gap); // 0 <= dr <= (size+gap) between spirals from center to center.
float coilNum = 0.0;
float lastSpiralR = angle * (size + gap);
if (lastSpiralR > dr) {
lastSpiralR -= (size + gap); // center of current coil.
coilNum = -1.0;
}
float nextSpiralR = lastSpiralR + (size + gap); // center of next outer coil.
// If the current point is within the gap between the two coils, reject it.
if (dr > lastSpiralR + 0.5 * size && dr < nextSpiralR - 0.5 * size) { return 0.0; }
coilNum += floor((r - startRadius + (0.5 * size) - lastSpiralR) / (size + gap));
// If the current point is in a coil numbered outside the current range, reject it.
if (coilNum < 0.0 || coilNum >= nTurns) { return 0.0; }
return 1.0;
}
mat3 rotAxis(vec3 axis, float a) {
// This is from: http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
float s = sin(a);
float c = cos(a);
float oc = 1.0 - c;
vec3 as = axis * s;
mat3 p = mat3(axis.x * axis, axis.y * axis, axis.z * axis);
mat3 q = mat3(c, - as.z, as.y, as.z, c, - as.x, - as.y, as.x, c);
return p * oc + q;
}
vec2 bifilarCoil(float startRadius, float size, float gap, float nTurns, in vec3 xyz) {
float coil1 = spiralSquareFace(startRadius, size, (size + 2.0 * gap), nTurns, xyz);
mat4 rot180Z = mat4(rotAxis(vec3(0, 0, 1), M_PI));
xyz = (vec4(xyz, 1.0) * rot180Z).xyz;
float coil2 = spiralSquareFace(startRadius, size, (size + 2.0 * gap), nTurns, xyz);
return vec2(coil1, coil2);
}
void mainModel4(out vec4 materials, in vec3 xyz) {
materials.xy = bifilarCoil(3.0, 0.85, 0.15, 9.0, xyz);
}