forked from DishpitDev/Slopify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdonut.le
87 lines (67 loc) · 2.63 KB
/
donut.le
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
use std/vectors;
use std/prelude;
const f32 THETA_SPACING = 0.07;
const f32 PHI_SPACING = 0.02;
const string LIGHTING = ".,-~:;=!*#$@";
const i32 WIDTH = 60;
const i32 HEIGHT = 24;
const i32 SIZE = WIDTH * HEIGHT;
fn update(f32 rotX, f32 rotZ, f32 *zBuffer, string output, Vector3 *lightDirection) {
memset(zBuffer, 0, SIZE * #size(f32));
memset(output, 32, SIZE * #size(char));
f32 sinRotX = math::sin(rotX);
f32 cosRotX = math::cos(rotX);
f32 sinRotZ = math::sin(rotZ);
f32 cosRotZ = math::cos(rotZ);
for let theta = 0.0; theta < 2 * PI; theta += THETA_SPACING {
f32 sinTheta = math::sin(theta);
f32 cosTheta = math::cos(theta);
for let phi = 0.0; phi < 2 * PI; phi += PHI_SPACING {
f32 sinPhi = math::sin(phi);
f32 cosPhi = math::cos(phi);
let surfacePos = Vector3 {
x = cosPhi * (cosTheta + 2),
y = sinPhi * (cosTheta + 2),
z = sinTheta,
};
let depth = 1 / (surfacePos.y * sinRotX + surfacePos.z * cosRotX + 5);
let projectionOffset = surfacePos.y * cosRotX - surfacePos.z * sinRotX;
i32 x = 30 + 36 * depth * (surfacePos.x * cosRotZ - projectionOffset * sinRotZ);
i32 y = 12 + 12 * depth * (surfacePos.x * sinRotZ + projectionOffset * cosRotZ);
i32 offset = x + WIDTH * y;
let normal = surfacePos.clone();
let normalLengthSquared = normal.length_sq();
if normalLengthSquared > 0 {
normal = normal.scale(1.0 / normalLengthSquared);
}
let illumination = normal.dot(*lightDirection);
let lightingIndex = (i32)(math::abs(illumination) * (LIGHTING.len() - 1));
if HEIGHT > y && y > 0 && x > 0 && WIDTH > x && depth > zBuffer[offset] {
zBuffer[offset] = depth;
let lightingMapping = (i32)lightingIndex % (LIGHTING.len() - 1);
output[offset] = LIGHTING[lightingMapping < 0 ? 0 : lightingMapping];
}
}
}
io::print("\x1b[H");
for let character = 0; character < SIZE; character += 1 {
if character % WIDTH {
io::putchar(output[character]);
} else {
io::putchar('\n');
}
}
}
fn main() {
let rotX = 0.0;
let rotZ = 0.0;
f32 *zBuffer = malloc(SIZE * #size(f32));
let output = (string)malloc(SIZE * #size(char));
let lightDirection = Vector3 { x = 0, y = 1, z = -1 };
io::print("\x1b[2J");
while true {
update(rotX, rotZ, zBuffer, output, &lightDirection);
rotX += 0.002;
rotZ += 0.001;
}
}