Spaces:
Running
Running
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Babylon.js L-system Fractal Example</title> | |
<script src="https://cdn.babylonjs.com/babylon.js"></script> | |
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script> | |
<style> | |
canvas { | |
width: 100%; | |
height: 100%; | |
touch-action: none; | |
} | |
</style> | |
</head> | |
<body> | |
<canvas id="renderCanvas"></canvas> | |
<script> | |
window.addEventListener('DOMContentLoaded', function () { | |
var canvas = document.getElementById('renderCanvas'); | |
var engine = new BABYLON.Engine(canvas, true); | |
var createScene = function () { | |
var scene = new BABYLON.Scene(engine); | |
// Create a camera | |
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene); | |
// Create a light | |
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); | |
// Create an array to hold the spheres | |
var spheres = []; | |
// Load the texture and bump map | |
var texture = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/floor.png", scene); | |
var bumpMap = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/floor_n.jpg", scene); | |
// Define the L-system rules and starting axiom | |
var rules = { | |
F: "F+F-F-F+F" | |
}; | |
var axiom = "F-F-F-F"; | |
var angle = Math.PI / 2; | |
var length = 1; | |
var iterations = 3; | |
// Generate the L-system string | |
var lSystemString = axiom; | |
for (var i = 0; i < iterations; i++) { | |
var newString = ""; | |
for (var j = 0; j < lSystemString.length; j++) { | |
var char = lSystemString.charAt(j); | |
if (rules[char]) { | |
newString += rules[char]; | |
} else { | |
newString += char; | |
} | |
} | |
lSystemString = newString; | |
} | |
// Create a fountain of spheres that follow the L-system string | |
var position = BABYLON.Vector3.Zero(); | |
var direction = BABYLON.Vector3.Forward(); | |
for (var i = 0; i < lSystemString.length; i++) { | |
var char = lSystemString.charAt(i); | |
if (char === "F") { | |
// Create a new sphere | |
var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: length, segments: 16}, scene); | |
sphere.position = position.clone(); | |
sphere.material = new BABYLON.StandardMaterial("texture", scene); | |
sphere.material.diffuseTexture = texture; | |
sphere.material.bumpTexture = bumpMap; | |
spheres.push(sphere); | |
// Animate the texture of the sphere | |
var textureAnimation = new BABYLON.Animation("textureAnimation", "material.diffuseTexture.uOffset", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE); | |
var keys = []; | |
keys.push({frame: 0, value:0}); | |
keys.push({frame: 100, value: 1}); | |
textureAnimation.setKeys(keys); | |
sphere.material.diffuseTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE; | |
sphere.material.diffuseTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE; | |
sphere.material.diffuseTexture.uScale = 10; | |
sphere.material.diffuseTexture.vScale = 10; | |
sphere.animations.push(textureAnimation); | |
scene.beginAnimation(sphere, 0, 100, true); | |
// Animate the sphere | |
var animation = new BABYLON.Animation("myAnimation", "position", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE); | |
keys = []; | |
keys.push({frame: 0, value: position.clone()}); | |
position.addInPlace(direction.scale(length)); | |
keys.push({frame: 100, value: position.clone()}); | |
animation.setKeys(keys); | |
sphere.animations.push(animation); | |
scene.beginAnimation(sphere, 0, 100, true); | |
} else if (char === "+") { | |
// Rotate clockwise | |
direction.rotateByQuaternionToRef(BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.Up(), -angle), direction); | |
} else if (char === "-") { | |
// Rotate counterclockwise | |
direction.rotateByQuaternionToRef(BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.Up(), angle), direction); | |
} | |
} | |
return scene; | |
} | |
var scene = createScene(); | |
engine.runRenderLoop(function () { | |
scene.render(); | |
}); | |
window.addEventListener('resize', function () { | |
engine.resize(); | |
}); | |
}); | |
</script> | |
</body> | |
</html> | |