Skip to content

Instantly share code, notes, and snippets.

@neilisaac
Created April 26, 2015 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neilisaac/372f168a78a46a53f392 to your computer and use it in GitHub Desktop.
Save neilisaac/372f168a78a46a53f392 to your computer and use it in GitHub Desktop.
genmaze - generative art hackathon 2015
// a hack by neil isaac
function stringTexture(text, color) {
var canvas = document.createElement("canvas");
canvas.width = 256;
canvas.height = 256;
var ctx = canvas.getContext("2d");
ctx.fillStyle = color;
ctx.fillRect(0, 0, 256, 256);
ctx.font = "48px Arial";
ctx.fillStyle = "#000000";
ctx.fillText(text, 50, 50);
var imgtexture = THREE.ImageUtils.loadTexture(canvas.toDataURL());
return new THREE.MeshLambertMaterial({map: imgtexture});
}
function getRndColor() {
var r = 255*Math.random()|0,
g = 255*Math.random()|0,
b = 255*Math.random()|0;
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
function gradientTexture() {
var canvas = document.createElement("canvas");
canvas.width = 256;
canvas.height = 256;
var ctx = canvas.getContext("2d");
var grd = ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0, getRndColor());
grd.addColorStop(1, getRndColor());
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 256, 256);
var imgtexture = THREE.ImageUtils.loadTexture(canvas.toDataURL());
return new THREE.MeshLambertMaterial({map: imgtexture});
}
function stringPlane(text, color) {
var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(1, 1), stringTexture(text, color));
mesh.addToScene = function(scene) {
scene.add(mesh);
}
return mesh;
}
function snazzyPlane() {
var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(1, 1), gradientTexture());
mesh.material.side = THREE.DoubleSide;
return mesh;
}
function node(x, y, z) {
this.f = stringPlane(x + " " + z + "\nfront", "#ff0000");
this.f.rotation.set(0, 0, 0);
this.f.position.set(x, y, z - 0.5);
this.l = stringPlane(x + " " + z + "\nleft", "#00ff00");
this.l.rotation.set(0, Math.PI/2, 0);
this.l.position.set(x - 0.5, y, z);
this.b = stringPlane(x + " " + z + "\nback", "#ffff00");
this.b.rotation.set(0, Math.PI, 0);
this.b.position.set(x, y, z + 0.5);
this.r = stringPlane(x + " " + z + "\nright", "#0000ff");
this.r.rotation.set(0, -Math.PI/2, 0);
this.r.position.set(x + 0.5, y, z);
this.addToScene = function(scene) {
if (this.l) { this.l.addToScene(scene); }
if (this.r) { this.r.addToScene(scene); }
if (this.f) { this.f.addToScene(scene); }
if (this.b) { this.b.addToScene(scene); }
}
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
body {margin: 0; padding: 0;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.js" defer></script>
<script src="geo.js" defer></script>
<script src="maze.js" defer></script>
<script src="sketch.js" defer></script>
</head>
<body>
</body>
</html>
// a hack by neil isaac
var MAZE_BOUND = 10;
function populateMaze(maze, x, y) {
if (maze[x][y] != null) {
return false;
}
if (x <= -MAZE_BOUND || x >= MAZE_BOUND || y <= -MAZE_BOUND || y >= MAZE_BOUND) {
maze[x][y] = 1;
return true;
}
var borders = 0;
if (maze[x][y+1] == 1) {borders++;}
if (maze[x][y-1] == 1) {borders++;}
if (maze[x+1][y] == 1) {borders++;}
if (maze[x-1][y] == 1) {borders++;}
if (borders > 1) {
maze[x][y] = 3;
return false;
}
maze[x][y] = 1;
var exits = false;
var funcs = [
function() {return populateMaze(maze, x+1, y)},
function() {return populateMaze(maze, x-1, y)},
function() {return populateMaze(maze, x, y-1)},
function() {return populateMaze(maze, x, y+1)}]
while (funcs.length) {
var index = Math.floor(Math.random() * funcs.length);
var func = funcs[index];
funcs.splice(index, 1);
exits |= func();
}
if (exits) {
return true;
} else {
maze[x][y] = null;
return false;
}
}
function createMaze() {
var maze = [];
for (var x = -MAZE_BOUND; x < MAZE_BOUND+1; x++) {
maze[x] = [];
for (var y = -MAZE_BOUND; y < MAZE_BOUND+1; y++) {
maze[x][y] = null;
}
}
return maze;
}
function solveMaze(maze, x, z) {
if (Math.abs(x) == MAZE_BOUND || Math.abs(z) == MAZE_BOUND) {
return [[x, z]];
}
if (maze[x][z] != 1) {
return null;
}
maze[x][z] = 2;
var exits = false;
var funcs = [
function() {return solveMaze(maze, x+1, z)},
function() {return solveMaze(maze, x-1, z)},
function() {return solveMaze(maze, x, z-1)},
function() {return solveMaze(maze, x, z+1)}]
while (funcs.length) {
var index = Math.floor(Math.random() * funcs.length);
var func = funcs[index];
funcs.splice(index, 1);
var result = func();
if (result != null) {
result.push([x, z]);
return result;
}
}
return null;
}
function printMaze(maze) {
var output = "";
for (var y = -MAZE_BOUND; y < MAZE_BOUND+1; y++) {
for (var x = -MAZE_BOUND; x < MAZE_BOUND+1; x++) {
if (x == 0 && y == 0) {output += "o"}
else if (maze[x][y] == 1) {output += " "}
else if (maze[x][y] == 0) {output += "."}
else {output += "x"}
}
output += "\n";
}
console.log(output);
}
function cubeNode(maze, x, z) {
var y = 0;
this.f = null;
this.b = null;
this.l = null;
this.r = null;
if (maze[x][z-1] != 1) {
this.f = snazzyPlane();
this.f.rotation.set(0, 0, 0);
this.f.position.set(x, y, z - 0.5);
}
if (maze[x-1][z] != 1) {
this.l = snazzyPlane();
this.l.rotation.set(0, Math.PI/2, 0);
this.l.position.set(x - 0.5, y, z);
}
if (maze[x][z+1] != 1) {
this.b = snazzyPlane();
this.b.rotation.set(0, Math.PI, 0);
this.b.position.set(x, y, z + 0.5);
}
if (maze[x+1][z] != 1) {
this.r = snazzyPlane();
this.r.rotation.set(0, -Math.PI/2, 0);
this.r.position.set(x + 0.5, y, z);
}
this.addToScene = function(scene) {
if (this.l) { scene.add(this.l) }
if (this.r) { scene.add(this.r) }
if (this.f) { scene.add(this.f) }
if (this.b) { scene.add(this.b) }
}
}
function createCubes(maze) {
var cubes = [];
for (var x = -MAZE_BOUND; x < MAZE_BOUND+1; x++) {
for (var z = -MAZE_BOUND; z < MAZE_BOUND+1; z++) {
if (maze[x][z] == 1 && Math.abs(x) < MAZE_BOUND && Math.abs(z) < MAZE_BOUND) {
cubes.push(new cubeNode(maze, x, z));
}
}
}
return cubes;
}
// a hack by neil isaac
var renderer = new THREE.WebGLRenderer({devicePixelRatio: window.devicePixelRatio});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var STEP = 0.016;
var scene = null;
var solution = null;
var target = null;
var camera = null;
function dist(x1, z1, x2, z2) {
return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(z1-z2, 2));
}
function animate() {
requestAnimationFrame(animate);
if (solution == null || target == null && solution.length == 0) {
console.log("making new scene");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 0);
camera.rotation.set(0, 0, 0);
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(0, 10, 0);
scene.add(light);
scene.add(new THREE.AmbientLight(0x202020));
var maze = createMaze();
populateMaze(maze, 0, 0);
printMaze(maze);
var cubes = createCubes(maze);
for (var i = 0; i < cubes.length; i++) {
cubes[i].addToScene(scene);
}
solution = solveMaze(maze, 0, 0).reverse();
for (var i = 0; i < solution.length; i++) {
console.log(solution[i]);
}
}
if (target != null && dist(camera.position.x, camera.position.z, target[0], target[1]) < 0.02) {
console.log("reached " + target);
target = null;
}
if (target == null && solution != null && solution.length > 0) {
target = solution[0];
solution.splice(0, 1);
console.log("moving towards " + target);
}
if (target != null) {
var dx = target[0] - camera.position.x;
var dz = target[1] - camera.position.z;
var mag = dist(0, 0, dx, dz) + 0.00001;
camera.position.x += dx * STEP / mag;
camera.position.z += dz * STEP / mag;
var x = camera.rotation.x;
var y = camera.rotation.y;
var z = camera.rotation.z;
var d = dist(camera.position.x, camera.position.z, target[0], target[1]);
camera.position.y = 0;
camera.lookAt(new THREE.Vector3(target[0], 0, target[1]));
camera.rotation.y = y + (camera.rotation.y - y) * Math.sin((1-d) / 8);
camera.position.y = 0.6;
}
renderer.render(scene, camera);
}
animate();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment