Skip to content

Instantly share code, notes, and snippets.

@thykka
Last active July 3, 2020 18:56
Show Gist options
  • Select an option

  • Save thykka/37ebffd7843394f45d033ce95a9af944 to your computer and use it in GitHub Desktop.

Select an option

Save thykka/37ebffd7843394f45d033ce95a9af944 to your computer and use it in GitHub Desktop.
SCRIPT-8
const WIDTH = 128
const HEIGHT = WIDTH
init = state => {
state.cube = {
type: 'cube',
vertices: [
[-1, -1, -1],
[1, -1, -1],
[1, 1, -1],
[-1, 1, -1],
[-1, -1, 1],
[1, -1, 1],
[1, 1, 1],
[-1, 1, 1]
],
position: [0, 0, -1],
rotation: [0, 0, 0]
}
state.dots = {
type: 'dots',
vertices: [
[0, 0, 1], // 1
[1, 1 / 2, 1 / 2], // 2
[1, -1 / 2, -1 / 2],
[1 / 2, 1, 1 / 2], // 3
[0, 1, 0],
[-1 / 2, 1, -1 / 2],
[1 / 2, -1, 1 / 2], // 4
[-1 / 2, -1, 1 / 2],
[-1 / 2, -1, -1 / 2],
[1 / 2, -1, -1 / 2],
[-1, -1 / 2, -1 / 2], // 5
[-1, 1 / 2, -1 / 2],
[-1, -1 / 2, 1 / 2],
[-1, 1 / 2, 1 / 2],
[-1, 0, 0],
[1 / 2, 1 / 2, -1], // 6
[1 / 2, 0, -1],
[1 / 2, -1 / 2, -1],
[-1 / 2, 1 / 2, -1],
[-1 / 2, 0, -1],
[-1 / 2, -1 / 2, -1]
],
position: [0, 0, 0],
rotation: [0, 0, 0]
}
state.cloud = {
position: [0, 0, 3],
rotation: [0, 0, 0],
vertices: range(0, 256).map(() =>
range(0, 3).map(() => Math.random() * 12 - 6)
)
}
state.camera = {
position: [0, 0, -4],
target: [0, 0, 0],
fov: Math.PI / 1.5
}
state.time = 0
}
update = (state, input, elapsed) => {
state.time += elapsed / 1000
const t = elapsed / 1000
//*
state.cube.rotation[0] += t
state.cube.rotation[1] -= t
state.cube.rotation[2] -= t
state.dots.rotation[0] -= t
state.dots.rotation[1] += t
state.dots.rotation[2] -= t
//*/
state.cloud.rotation[0] -= 0.0005
state.cloud.rotation[1] -= 0.0003
state.cloud.rotation[2] += 0.003 * Math.cos(state.time / 8)
state.letterDist = Math.max(74 - state.time * 10, 5)
}
const letters = {
E: [[1, -1], [-1, -1], [-1, 1], [1, 1], [], [-1, 0], [1, 0], []],
P: [[-1, 1], [-1, -1], [1, -1], [1, 0], [-1, 0], []],
I: [[-1, -1], [1, -1], [], [0, -1], [0, 1], [], [-1, 1], [1, 1], []],
C: [[1, -1], [-1, -1], [-1, 1], [1, 1], []]
}
draw = state => {
clear()
render(state.camera, [state.cloud, state.cube])
}
function render(camera, meshes) {
const viewMatrix = lookAt(camera.position, camera.target)
const projectionMatrix = perspectiveFOV(camera.fov, WIDTH / HEIGHT, 0.01, 1)
meshes.forEach(mesh => {
const rotationMatrix = rotationYawPitchRoll(
mesh.rotation[1],
mesh.rotation[0],
mesh.rotation[2]
)
const translationMatrix = translation(...mesh.position)
const worldMatrix = multiplyMatrix(rotationMatrix, translationMatrix)
const transformMatrix = multiplyMatrix(
multiplyMatrix(worldMatrix, viewMatrix),
projectionMatrix
)
const projectedPoints = mesh.vertices.map(vertex => {
return project(vertex, transformMatrix, worldMatrix, camera)
})
projectedPoints
.sort((a, b) => {
return b[2] - a[2]
})
.forEach(point => {
if (point[0] && point[1]) {
drawPoint(point)
}
})
})
}
function project(vertex, matrix, world, camera) {
const point = transformVector(vertex, matrix)
const x = point[0] * WIDTH + WIDTH / 2
const y = point[1] * HEIGHT + HEIGHT / 2
const z = distance(
...subtract(camera.position, transformVector(vertex, world))
)
return [x, y, z]
}
function drawPoint(point) {
if (
point[0] < -4 ||
point[1] < -4 ||
point[0] > WIDTH + 4 ||
point[1] > HEIGHT + 4
) {
return
}
const x = point[0]
const y = point[1]
const z = Math.round(2 - point[2] || 2)
const s = clamp(Math.round(point[2] - 2.5), 0, 4)
sprite(x - 4, y - 4, s, z)
}
function transformVector(vector, matrix) {
const x =
vector[0] * matrix[0] +
vector[1] * matrix[4] +
vector[2] * matrix[8] +
matrix[12]
const y =
vector[0] * matrix[1] +
vector[1] * matrix[5] +
vector[2] * matrix[9] +
matrix[13]
const z =
vector[0] * matrix[2] +
vector[1] * matrix[6] +
vector[2] * matrix[10] +
matrix[14]
const w =
vector[0] * matrix[3] +
vector[1] * matrix[7] +
vector[2] * matrix[11] +
matrix[15]
return [x / w, y / w, z / w]
}
function lookAt(camera, target, up = [0, 1, 0]) {
const zAxis = normalize(subtract(target, camera))
const xAxis = normalize(cross(up, zAxis))
const yAxis = normalize(cross(zAxis, xAxis))
const xCam = -dot(xAxis, camera)
const yCam = -dot(yAxis, camera)
const zCam = -dot(zAxis, camera)
return [
xAxis[0],
yAxis[0],
zAxis[0],
0,
xAxis[1],
yAxis[1],
zAxis[1],
0,
xAxis[2],
yAxis[2],
zAxis[2],
0,
xCam,
yCam,
zCam,
1
]
}
function perspectiveFOV(fov, aspect, near, far) {
const tan = 1 / Math.tan(fov * 0.5)
return [
tan / aspect, 0, 0, 0,
0, tan, 0, 0,
0, 0, -far / (near - far), 1,
0, 0, (near * far) / (near - far), 0
]
}
function rotationYawPitchRoll(yaw, pitch, roll) {
return multiplyMatrix(multiplyMatrix(rotationZ(roll), rotationX(pitch)), rotationY(yaw))
}
function translation(x, y, z) {
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1
]
}
function rotationX(angle) {
const sin = Math.sin(angle)
const cos = Math.cos(angle)
return [
1, 0, 0, 0,
0, cos, sin, 0,
0, -sin, cos, 0,
0, 0, 0, 1
]
}
function rotationY(angle) {
const sin = Math.sin(angle)
const cos = Math.cos(angle)
return [
cos, 0, -sin, 0,
0, 1, 0, 0,
sin, 0, cos, 0,
0, 0, 0, 1
]
}
function rotationZ(angle) {
const sin = Math.sin(angle)
const cos = Math.cos(angle)
return [
cos, sin, 0, 0,
-sin, cos, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]
}
function multiplyMatrix(a, b) {
return [
a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12],
a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13],
a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14],
a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15],
a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12],
a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13],
a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14],
a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15],
a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12],
a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13],
a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14],
a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15],
a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12],
a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13],
a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14],
a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]
]
}
function multiply(a, b) {
return [a[0] * b[0], a[1] * b[1], a[2] * b[2]]
}
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
function cross(a, b) {
const x = a[1] * b[2] - a[2] * b[1]
const y = a[2] * b[0] - a[0] * b[2]
const z = a[0] * b[1] - a[1] * b[0]
return [x, y, z]
}
function normalize([x, y, z]) {
const len = distance(x, y, z)
if (len === 0) return [x, y, z]
const mult = 1 / len
return [x * mult, y * mult, z * mult]
}
function distance(x, y, z) {
return Math.sqrt(x * x + y * y + z * z)
}
function subtract(a, b) {
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
}
{
"iframeVersion": "0.1.280",
"lines": [
153,
159,
0,
0,
0,
0,
0,
0
]
}
{
"0": [
" 4 ",
" 2 ",
" 515 ",
"4210124 ",
" 515 ",
" 2 ",
" 4 ",
" "
],
"1": [
" ",
" 4 ",
" 2 ",
" 42024 ",
" 2 ",
" 4 ",
" ",
" "
],
"2": [
" ",
" ",
" 4 ",
" 404 ",
" 4 ",
" ",
" ",
" "
],
"3": [
" ",
" ",
" ",
" 0 ",
" ",
" ",
" ",
" "
],
"4": [
" ",
" ",
" ",
" 1 ",
" ",
" ",
" ",
" "
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment