Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save EncodeTheCode/0a18aaa307a52c4081b90501ed9d9e5c to your computer and use it in GitHub Desktop.
Save EncodeTheCode/0a18aaa307a52c4081b90501ed9d9e5c to your computer and use it in GitHub Desktop.
<canvas id="canvas" width="800" height="600"></canvas>
<script>
// --- Vector3 Class ---
class Vector3 {
constructor(x = 0, y = 0, z = 0) {
this.x = x; this.y = y; this.z = z;
}
add(v) {
return new Vector3(this.x + v.x, this.y + v.y, this.z + v.z);
}
rotateY(angle) {
const cos = Math.cos(angle), sin = Math.sin(angle);
return new Vector3(this.x * cos - this.z * sin, this.y, this.x * sin + this.z * cos);
}
project(w, h, scale = 300, depth = 5) {
const z = this.z + depth;
const f = scale / z;
return {
x: this.x * f + w / 2,
y: -this.y * f + h / 2
};
}
}
// --- Box Mesh Generator ---
function createBox(size = 1, center = new Vector3()) {
const s = size / 2;
const v = [
new Vector3(-s, -s, -s), new Vector3(s, -s, -s),
new Vector3(s, s, -s), new Vector3(-s, s, -s),
new Vector3(-s, -s, s), new Vector3(s, -s, s),
new Vector3(s, s, s), new Vector3(-s, s, s),
].map(p => p.add(center));
const faces = [
[0,1,2,3], [4,5,6,7],
[0,1,5,4], [2,3,7,6],
[0,3,7,4], [1,2,6,5],
];
return { vertices: v, faces };
}
// --- Scene Setup ---
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const roomSize = 10;
const sceneMeshes = [];
// Room walls (large cube)
sceneMeshes.push(createBox(roomSize));
// Fill room with smaller boxes
const spacing = 2;
for (let x = -3; x <= 3; x++) {
for (let y = -1; y <= 1; y++) {
for (let z = -3; z <= 3; z++) {
const center = new Vector3(x * spacing, y * spacing, z * spacing);
sceneMeshes.push(createBox(0.9, center));
}
}
}
// --- Renderer ---
let angle = 0;
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
angle += 0.01;
ctx.strokeStyle = '#0ff';
ctx.lineWidth = 1;
for (const mesh of sceneMeshes) {
const projected = mesh.vertices.map(v => v.rotateY(angle).project(canvas.width, canvas.height));
for (const face of mesh.faces) {
ctx.beginPath();
ctx.moveTo(projected[face[0]].x, projected[face[0]].y);
for (let i = 1; i < face.length; i++) {
ctx.lineTo(projected[face[i]].x, projected[face[i]].y);
}
ctx.closePath();
ctx.stroke();
}
}
requestAnimationFrame(render);
}
render();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment