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> | |
<style> | |
canvas { width: 100%; height: 100%; touch-action: none; } | |
</style> | |
</head> | |
<body> | |
<canvas id="renderCanvas"></canvas> | |
<script> | |
const canvas = document.getElementById('renderCanvas'); | |
const engine = new BABYLON.Engine(canvas, true); | |
const createScene = () => { | |
const scene = new BABYLON.Scene(engine); | |
const camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene); | |
const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); | |
const texture = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/floor.png", scene); | |
const bumpMap = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/floor_n.jpg", scene); | |
const rules = {F: "F+F-F-F+F"}; | |
const axiom = "F-F-F-F"; | |
const angle = Math.PI / 2, length = 1, iterations = 3; | |
let lSystemString = axiom, position = BABYLON.Vector3.Zero(), direction = BABYLON.Vector3.Forward(); | |
for (let i = 0; i < iterations; i++) { | |
let newString = ""; | |
for (let j = 0; j < lSystemString.length; j++) { | |
const char = lSystemString.charAt(j); | |
newString += rules[char] || char; | |
} | |
lSystemString = newString; | |
} | |
for (let i = 0; i < lSystemString.length; i++) { | |
const char = lSystemString.charAt(i); | |
if (char === "F") { | |
const 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; | |
const textureAnimation = new BABYLON.Animation("textureAnimation", "material.diffuseTexture.uOffset", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, true); | |
textureAnimation.setKeys([{ frame: 0, value: 0 }, { frame: 100, value: 1 }]); | |
sphere.material.diffuseTexture.wrapU = sphere.material.diffuseTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE; | |
sphere.material.diffuseTexture.uScale = sphere.material.diffuseTexture.vScale = 10; | |
sphere.animations.push(textureAnimation); | |
scene.beginAnimation(sphere, 0, 100, true); | |
const animation = new BABYLON.Animation("myAnimation", "position", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE, true); | |
animation.setKeys([{ frame: 0, value: position.clone() }, { frame: 100, value: position.addInPlace(direction.scale(length)).clone() }]); | |
sphere.animations.push(animation); | |
scene.beginAnimation(sphere, 0, 100, true); | |
} else if (char === "+") { | |
direction.rotateByQuaternionToRef(BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.Up(), -angle), direction); | |
} else if (char === "-") { | |
direction.rotateByQuaternionToRef(BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.Up(), angle), direction); | |
} | |
} | |
return scene; | |
}; | |
const scene = createScene(); | |
engine.runRenderLoop(() => scene.render()); | |
window.addEventListener('resize', () => engine.resize()); | |
</script> | |
</body> | |
</html> | |