From 8522c256ad2d3588c6e28a833c082869ec7d1c28 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Mon, 8 Jun 2026 17:13:21 +0200 Subject: [PATCH 1/3] Port demos to ES6, add pure flavors, and remove all UMD demos Migrate the legacy UMD demos to ES6 `@babylonjs/*` packages, each in both the compiled (`src/compiledDemos`) and tree-shaken pure (`src/pureCompiledDemos`) flavors, and remove the legacy UMD code from the website per AGENTS.md ("no UMD demos"). - Add ES6 compiled + pure versions of the ported demos, wired through the shared demoRunner and registered in both manifests. - Strip leftover legacy UMD code (*.js and legacy index.html) from already ported static/Demos folders; keep all asset files (textures, .babylon, .hdr, .fx, screenshots). Fully ported demos with no assets are removed. - Register RegisterEnginesExtensionsEngineRawTexture in the Simplification pure scene so the Dude scene textures load under the pure barrel. - Smoke harness, shared demoRunners, and AGENTS.md contributor guide updates. Validation: full build, compiled smoke (85/86, Flat2009 render-check disabled for headless video), and pure smoke (85) all pass. --- AGENTS.md | 201 ++++ docs/compiled-demos.md | 6 + package-lock.json | 45 + package.json | 4 + scripts/demos/check-smoke.mjs | 29 +- src/compiledDemos/Actions/index.html | 105 ++ src/compiledDemos/Actions/main.ts | 4 + src/compiledDemos/Actions/scene.ts | 212 ++++ src/compiledDemos/Bones/index.html | 105 ++ src/compiledDemos/Bones/main.ts | 4 + src/compiledDemos/Bones/scene.ts | 65 ++ src/compiledDemos/Charting/index.html | 105 ++ src/compiledDemos/Charting/main.ts | 4 + src/compiledDemos/Charting/scene.ts | 147 +++ src/compiledDemos/Dancers/index.html | 105 ++ src/compiledDemos/Dancers/main.ts | 4 + src/compiledDemos/Dancers/scene.ts | 55 + src/compiledDemos/DragNDrop/index.html | 105 ++ src/compiledDemos/DragNDrop/main.ts | 4 + src/compiledDemos/DragNDrop/scene.ts | 136 +++ src/compiledDemos/Espilit/index.html | 105 ++ src/compiledDemos/Espilit/main.ts | 4 + src/compiledDemos/Espilit/scene.ts | 33 + src/compiledDemos/ExtrudePolygon/index.html | 105 ++ src/compiledDemos/ExtrudePolygon/main.ts | 4 + src/compiledDemos/ExtrudePolygon/scene.ts | 758 ++++++++++++++ src/compiledDemos/Facets/index.html | 105 ++ src/compiledDemos/Facets/main.ts | 4 + src/compiledDemos/Facets/scene.ts | 156 +++ src/compiledDemos/Flat2009/index.html | 105 ++ src/compiledDemos/Flat2009/main.ts | 4 + src/compiledDemos/Flat2009/scene.ts | 31 + src/compiledDemos/GlowingEspilit/index.html | 105 ++ src/compiledDemos/GlowingEspilit/main.ts | 4 + src/compiledDemos/GlowingEspilit/scene.ts | 38 + src/compiledDemos/Heart/index.html | 105 ++ src/compiledDemos/Heart/main.ts | 4 + src/compiledDemos/Heart/scene.ts | 18 + src/compiledDemos/HillValley/index.html | 105 ++ src/compiledDemos/HillValley/main.ts | 4 + src/compiledDemos/HillValley/scene.ts | 23 + src/compiledDemos/InstancedBones/index.html | 105 ++ src/compiledDemos/InstancedBones/main.ts | 4 + src/compiledDemos/InstancedBones/scene.ts | 73 ++ src/compiledDemos/Instances/index.html | 105 ++ src/compiledDemos/Instances/main.ts | 4 + src/compiledDemos/Instances/scene.ts | 129 +++ src/compiledDemos/Instances2/index.html | 105 ++ src/compiledDemos/Instances2/main.ts | 4 + src/compiledDemos/Instances2/scene.ts | 153 +++ src/compiledDemos/Mansion/index.html | 105 ++ src/compiledDemos/Mansion/main.ts | 4 + src/compiledDemos/Mansion/scene.ts | 14 + src/compiledDemos/MorphTargets/index.html | 105 ++ src/compiledDemos/MorphTargets/main.ts | 4 + src/compiledDemos/MorphTargets/scene.ts | 101 ++ src/compiledDemos/Particles2/index.html | 105 ++ src/compiledDemos/Particles2/main.ts | 4 + src/compiledDemos/Particles2/scene.ts | 77 ++ src/compiledDemos/Polygon/index.html | 105 ++ src/compiledDemos/Polygon/main.ts | 4 + src/compiledDemos/Polygon/scene.ts | 65 ++ src/compiledDemos/Procedural/index.html | 105 ++ src/compiledDemos/Procedural/main.ts | 4 + src/compiledDemos/Procedural/scene.ts | 196 ++++ src/compiledDemos/RefProbe/index.html | 105 ++ src/compiledDemos/RefProbe/main.ts | 4 + src/compiledDemos/RefProbe/scene.ts | 105 ++ src/compiledDemos/SPS/index.html | 105 ++ src/compiledDemos/SPS/main.ts | 4 + src/compiledDemos/SPS/scene.ts | 149 +++ src/compiledDemos/SPSCollisions/index.html | 105 ++ src/compiledDemos/SPSCollisions/main.ts | 4 + src/compiledDemos/SPSCollisions/scene.ts | 164 +++ src/compiledDemos/SSAO/index.html | 105 ++ src/compiledDemos/SSAO/main.ts | 4 + src/compiledDemos/SSAO/scene.ts | 30 + src/compiledDemos/SSAO2/index.html | 105 ++ src/compiledDemos/SSAO2/main.ts | 4 + src/compiledDemos/SSAO2/scene.ts | 38 + src/compiledDemos/SelfShadowing/index.html | 105 ++ src/compiledDemos/SelfShadowing/main.ts | 4 + src/compiledDemos/SelfShadowing/scene.ts | 49 + src/compiledDemos/Simplification/index.html | 105 ++ src/compiledDemos/Simplification/main.ts | 4 + src/compiledDemos/Simplification/scene.ts | 41 + src/compiledDemos/SoftShadows/index.html | 105 ++ src/compiledDemos/SoftShadows/main.ts | 4 + src/compiledDemos/SoftShadows/scene.ts | 66 ++ src/compiledDemos/SpaceDeK/index.html | 105 ++ src/compiledDemos/SpaceDeK/main.ts | 4 + src/compiledDemos/SpaceDeK/scene.ts | 11 + src/compiledDemos/Spaceship/index.html | 105 ++ src/compiledDemos/Spaceship/main.ts | 4 + src/compiledDemos/Spaceship/scene.ts | 11 + .../SponzaDynamicShadows/index.html | 105 ++ .../SponzaDynamicShadows/main.ts | 4 + .../SponzaDynamicShadows/scene.ts | 74 ++ src/compiledDemos/Starfield/index.html | 105 ++ src/compiledDemos/Starfield/main.ts | 4 + src/compiledDemos/Starfield/scene.ts | 39 + src/compiledDemos/Train/index.html | 105 ++ src/compiledDemos/Train/main.ts | 4 + src/compiledDemos/Train/scene.ts | 70 ++ src/compiledDemos/Tunnel/index.html | 105 ++ src/compiledDemos/Tunnel/main.ts | 4 + src/compiledDemos/Tunnel/scene.ts | 57 ++ src/compiledDemos/V8/index.html | 105 ++ src/compiledDemos/V8/main.ts | 4 + src/compiledDemos/V8/scene.ts | 24 + src/compiledDemos/Viper/index.html | 105 ++ src/compiledDemos/Viper/main.ts | 4 + src/compiledDemos/Viper/scene.ts | 11 + src/compiledDemos/WCafe/index.html | 105 ++ src/compiledDemos/WCafe/main.ts | 4 + src/compiledDemos/WCafe/scene.ts | 11 + src/compiledDemos/manifest.json | 372 +++++++ src/compiledDemos/shared/demoRunner.ts | 9 + src/pureCompiledDemos/Actions/index.html | 105 ++ src/pureCompiledDemos/Actions/main.ts | 4 + src/pureCompiledDemos/Actions/scene.ts | 223 ++++ .../AssetsManager/index.html | 112 ++ src/pureCompiledDemos/AssetsManager/main.ts | 6 + src/pureCompiledDemos/AssetsManager/scene.ts | 52 + src/pureCompiledDemos/Bones/index.html | 105 ++ src/pureCompiledDemos/Bones/main.ts | 4 + src/pureCompiledDemos/Bones/scene.ts | 79 ++ src/pureCompiledDemos/Boom/index.html | 105 ++ src/pureCompiledDemos/Boom/main.ts | 6 + src/pureCompiledDemos/Boom/scene.ts | 271 +++++ src/pureCompiledDemos/CellShading/index.html | 96 ++ src/pureCompiledDemos/CellShading/main.ts | 4 + src/pureCompiledDemos/CellShading/scene.ts | 63 ++ src/pureCompiledDemos/Charting/index.html | 105 ++ src/pureCompiledDemos/Charting/main.ts | 4 + src/pureCompiledDemos/Charting/scene.ts | 160 +++ src/pureCompiledDemos/Dancers/index.html | 105 ++ src/pureCompiledDemos/Dancers/main.ts | 4 + src/pureCompiledDemos/Dancers/scene.ts | 67 ++ src/pureCompiledDemos/DragNDrop/index.html | 105 ++ src/pureCompiledDemos/DragNDrop/main.ts | 4 + src/pureCompiledDemos/DragNDrop/scene.ts | 137 +++ src/pureCompiledDemos/Espilit/index.html | 105 ++ src/pureCompiledDemos/Espilit/main.ts | 4 + src/pureCompiledDemos/Espilit/scene.ts | 39 + .../ExtrudePolygon/index.html | 105 ++ src/pureCompiledDemos/ExtrudePolygon/main.ts | 4 + src/pureCompiledDemos/ExtrudePolygon/scene.ts | 765 ++++++++++++++ src/pureCompiledDemos/Facets/index.html | 105 ++ src/pureCompiledDemos/Facets/main.ts | 4 + src/pureCompiledDemos/Facets/scene.ts | 158 +++ src/pureCompiledDemos/FireMaterial/index.html | 96 ++ src/pureCompiledDemos/FireMaterial/main.ts | 4 + src/pureCompiledDemos/FireMaterial/scene.ts | 51 + src/pureCompiledDemos/Flat2009/index.html | 105 ++ src/pureCompiledDemos/Flat2009/main.ts | 4 + src/pureCompiledDemos/Flat2009/scene.ts | 46 + src/pureCompiledDemos/Fresnel/index.html | 105 ++ src/pureCompiledDemos/Fresnel/main.ts | 6 + src/pureCompiledDemos/Fresnel/scene.ts | 157 +++ src/pureCompiledDemos/Fur/index.html | 96 ++ src/pureCompiledDemos/Fur/main.ts | 4 + src/pureCompiledDemos/Fur/scene.ts | 23 + src/pureCompiledDemos/GLTF/index.html | 105 ++ src/pureCompiledDemos/GLTF/main.ts | 6 + src/pureCompiledDemos/GLTF/scene.ts | 49 + .../GLTFMeshPrimitiveAttributeTest/index.html | 105 ++ .../GLTFMeshPrimitiveAttributeTest/main.ts | 6 + .../GLTFMeshPrimitiveAttributeTest/scene.ts | 92 ++ src/pureCompiledDemos/GLTFNormals/index.html | 105 ++ src/pureCompiledDemos/GLTFNormals/main.ts | 6 + src/pureCompiledDemos/GLTFNormals/scene.ts | 88 ++ src/pureCompiledDemos/GUI/index.html | 96 ++ src/pureCompiledDemos/GUI/main.ts | 4 + src/pureCompiledDemos/GUI/scene.ts | 49 + .../GlowingEspilit/index.html | 105 ++ src/pureCompiledDemos/GlowingEspilit/main.ts | 4 + src/pureCompiledDemos/GlowingEspilit/scene.ts | 59 ++ src/pureCompiledDemos/Heart/index.html | 105 ++ src/pureCompiledDemos/Heart/main.ts | 4 + src/pureCompiledDemos/Heart/scene.ts | 17 + src/pureCompiledDemos/HillValley/index.html | 105 ++ src/pureCompiledDemos/HillValley/main.ts | 4 + src/pureCompiledDemos/HillValley/scene.ts | 26 + .../InstancedBones/index.html | 105 ++ src/pureCompiledDemos/InstancedBones/main.ts | 4 + src/pureCompiledDemos/InstancedBones/scene.ts | 88 ++ src/pureCompiledDemos/Instances/index.html | 105 ++ src/pureCompiledDemos/Instances/main.ts | 4 + src/pureCompiledDemos/Instances/scene.ts | 146 +++ src/pureCompiledDemos/Instances2/index.html | 105 ++ src/pureCompiledDemos/Instances2/main.ts | 4 + src/pureCompiledDemos/Instances2/scene.ts | 172 ++++ src/pureCompiledDemos/LOD/index.html | 96 ++ src/pureCompiledDemos/LOD/main.ts | 4 + src/pureCompiledDemos/LOD/scene.ts | 66 ++ src/pureCompiledDemos/LookAt/index.html | 96 ++ src/pureCompiledDemos/LookAt/main.ts | 4 + src/pureCompiledDemos/LookAt/scene.ts | 80 ++ src/pureCompiledDemos/Mansion/index.html | 105 ++ src/pureCompiledDemos/Mansion/main.ts | 4 + src/pureCompiledDemos/Mansion/scene.ts | 19 + src/pureCompiledDemos/MorphTargets/index.html | 105 ++ src/pureCompiledDemos/MorphTargets/main.ts | 4 + src/pureCompiledDemos/MorphTargets/scene.ts | 113 ++ src/pureCompiledDemos/Octree/index.html | 96 ++ src/pureCompiledDemos/Octree/main.ts | 4 + src/pureCompiledDemos/Octree/scene.ts | 56 + src/pureCompiledDemos/Offscreen/index.html | 187 ++++ src/pureCompiledDemos/Offscreen/main.ts | 137 +++ src/pureCompiledDemos/Offscreen/scene.ts | 48 + src/pureCompiledDemos/Offscreen/worker.ts | 69 ++ src/pureCompiledDemos/Particles2/index.html | 105 ++ src/pureCompiledDemos/Particles2/main.ts | 4 + src/pureCompiledDemos/Particles2/scene.ts | 79 ++ .../PointLightShadowMap/index.html | 96 ++ .../PointLightShadowMap/main.ts | 6 + .../PointLightShadowMap/scene.ts | 88 ++ src/pureCompiledDemos/Polygon/index.html | 105 ++ src/pureCompiledDemos/Polygon/main.ts | 4 + src/pureCompiledDemos/Polygon/scene.ts | 68 ++ src/pureCompiledDemos/Procedural/index.html | 105 ++ src/pureCompiledDemos/Procedural/main.ts | 4 + src/pureCompiledDemos/Procedural/scene.ts | 208 ++++ src/pureCompiledDemos/RefProbe/index.html | 105 ++ src/pureCompiledDemos/RefProbe/main.ts | 4 + src/pureCompiledDemos/RefProbe/scene.ts | 120 +++ src/pureCompiledDemos/SPS/index.html | 105 ++ src/pureCompiledDemos/SPS/main.ts | 4 + src/pureCompiledDemos/SPS/scene.ts | 164 +++ .../SPSCollisions/index.html | 105 ++ src/pureCompiledDemos/SPSCollisions/main.ts | 4 + src/pureCompiledDemos/SPSCollisions/scene.ts | 169 +++ src/pureCompiledDemos/SSAO/index.html | 105 ++ src/pureCompiledDemos/SSAO/main.ts | 4 + src/pureCompiledDemos/SSAO/scene.ts | 49 + src/pureCompiledDemos/SSAO2/index.html | 105 ++ src/pureCompiledDemos/SSAO2/main.ts | 4 + src/pureCompiledDemos/SSAO2/scene.ts | 60 ++ .../SelfShadowing/index.html | 105 ++ src/pureCompiledDemos/SelfShadowing/main.ts | 4 + src/pureCompiledDemos/SelfShadowing/scene.ts | 59 ++ src/pureCompiledDemos/Shadows/index.html | 96 ++ src/pureCompiledDemos/Shadows/main.ts | 6 + src/pureCompiledDemos/Shadows/scene.ts | 94 ++ .../Simplification/index.html | 105 ++ src/pureCompiledDemos/Simplification/main.ts | 4 + src/pureCompiledDemos/Simplification/scene.ts | 48 + src/pureCompiledDemos/SoftShadows/index.html | 105 ++ src/pureCompiledDemos/SoftShadows/main.ts | 4 + src/pureCompiledDemos/SoftShadows/scene.ts | 77 ++ src/pureCompiledDemos/SpaceDeK/index.html | 105 ++ src/pureCompiledDemos/SpaceDeK/main.ts | 4 + src/pureCompiledDemos/SpaceDeK/scene.ts | 10 + src/pureCompiledDemos/Spaceship/index.html | 105 ++ src/pureCompiledDemos/Spaceship/main.ts | 4 + src/pureCompiledDemos/Spaceship/scene.ts | 10 + .../SponzaDynamicShadows/index.html | 105 ++ .../SponzaDynamicShadows/main.ts | 4 + .../SponzaDynamicShadows/scene.ts | 84 ++ src/pureCompiledDemos/Starfield/index.html | 105 ++ src/pureCompiledDemos/Starfield/main.ts | 4 + src/pureCompiledDemos/Starfield/scene.ts | 48 + src/pureCompiledDemos/Train/index.html | 105 ++ src/pureCompiledDemos/Train/main.ts | 4 + src/pureCompiledDemos/Train/scene.ts | 90 ++ src/pureCompiledDemos/Tunnel/index.html | 105 ++ src/pureCompiledDemos/Tunnel/main.ts | 4 + src/pureCompiledDemos/Tunnel/scene.ts | 66 ++ src/pureCompiledDemos/V8/index.html | 105 ++ src/pureCompiledDemos/V8/main.ts | 4 + src/pureCompiledDemos/V8/scene.ts | 33 + src/pureCompiledDemos/Viper/index.html | 105 ++ src/pureCompiledDemos/Viper/main.ts | 4 + src/pureCompiledDemos/Viper/scene.ts | 10 + .../VolumetricLightScattering/index.html | 105 ++ .../VolumetricLightScattering/main.ts | 6 + .../VolumetricLightScattering/scene.ts | 77 ++ src/pureCompiledDemos/WCafe/index.html | 105 ++ src/pureCompiledDemos/WCafe/main.ts | 4 + src/pureCompiledDemos/WCafe/scene.ts | 10 + .../WaterMaterial/index.html | 96 ++ src/pureCompiledDemos/WaterMaterial/main.ts | 4 + src/pureCompiledDemos/WaterMaterial/scene.ts | 57 ++ src/pureCompiledDemos/Yeti/index.html | 113 ++ src/pureCompiledDemos/Yeti/main.ts | 6 + src/pureCompiledDemos/Yeti/scene.ts | 109 ++ src/pureCompiledDemos/manifest.json | 564 ++++++++++ src/pureCompiledDemos/shared/demoRunner.ts | 18 + static/Demos/Actions/actions.js | 149 --- static/Demos/Actions/demo.js | 5 - static/Demos/Actions/index.html | 87 -- .../Demos/AdvancedShadows/advancedShadows.js | 218 ---- static/Demos/AdvancedShadows/demo.js | 5 - static/Demos/AdvancedShadows/index.html | 88 -- static/Demos/AssetsManager/assets.js | 63 -- static/Demos/AssetsManager/index.html | 41 - static/Demos/Bones/bones.js | 61 -- static/Demos/Bones/demo.js | 5 - static/Demos/Bones/index.html | 87 -- static/Demos/Boom/boom.js | 250 ----- static/Demos/Boom/demo.js | 5 - static/Demos/Boom/index.html | 87 -- static/Demos/Bump/bump.js | 21 - static/Demos/Bump/demo.js | 5 - static/Demos/Bump/index.html | 87 -- static/Demos/CSG/csg.js | 64 -- static/Demos/CSG/demo.js | 5 - static/Demos/CSG/index.html | 87 -- static/Demos/CellShading/cellShading.js | 49 - static/Demos/CellShading/demo.js | 5 - static/Demos/CellShading/index.html | 88 -- static/Demos/Charting/charting.js | 130 --- static/Demos/Charting/demo.js | 5 - static/Demos/Charting/index.html | 87 -- .../CustomRenderTarget/customRenderTarget.js | 103 -- static/Demos/CustomRenderTarget/demo.js | 5 - static/Demos/CustomRenderTarget/index.html | 87 -- static/Demos/CustomShader/cellShading.js | 41 - static/Demos/CustomShader/demo.js | 5 - static/Demos/CustomShader/index.html | 87 -- static/Demos/DOF/demo.js | 5 - static/Demos/DOF/dof.js | 115 --- static/Demos/DOF/index.html | 87 -- static/Demos/Dancers/dat.gui.min.js | 95 -- static/Demos/Dancers/index.html | 155 --- static/Demos/Decals/decals.js | 45 - static/Demos/Decals/demo.js | 5 - static/Demos/Decals/index.html | 87 -- .../Demos/DefaultRenderingPipeline/default.js | 216 ---- static/Demos/DefaultRenderingPipeline/demo.js | 5 - .../Demos/DefaultRenderingPipeline/index.html | 88 -- static/Demos/DisplacementMap/demo.js | 5 - .../Demos/DisplacementMap/displacementMap.js | 29 - static/Demos/DisplacementMap/index.html | 87 -- static/Demos/DragNDrop/demo.js | 5 - static/Demos/DragNDrop/dragdrop.js | 130 --- static/Demos/DragNDrop/index.html | 87 -- static/Demos/Espilit/demo.js | 16 - static/Demos/Espilit/index.html | 86 -- static/Demos/ExtrudePolygon/demo.js | 5 - static/Demos/ExtrudePolygon/extrude.js | 961 ------------------ static/Demos/ExtrudePolygon/index.html | 89 -- static/Demos/Facets/demo.js | 5 - static/Demos/Facets/facets.js | 158 --- static/Demos/Facets/index.html | 87 -- .../FireMaterial/babylon.fireMaterial.min.js | 1 - static/Demos/FireMaterial/demo.js | 5 - static/Demos/FireMaterial/fire.js | 96 -- static/Demos/FireMaterial/index.html | 88 -- static/Demos/Flat2009/demo.js | 14 - static/Demos/Flat2009/index.html | 86 -- static/Demos/FlightHelmet/demo.js | 5 - static/Demos/FlightHelmet/index.html | 71 -- static/Demos/FlightHelmet/index.js | 52 - static/Demos/Fog/demo.js | 5 - static/Demos/Fog/fog.js | 42 - static/Demos/Fog/index.html | 87 -- static/Demos/Fresnel/demo.js | 5 - static/Demos/Fresnel/fresnel.js | 143 --- static/Demos/Fresnel/index.html | 87 -- static/Demos/Fur/demo.js | 5 - static/Demos/Fur/fur.js | 35 - static/Demos/Fur/index.html | 88 -- static/Demos/GLTF/demo.js | 5 - static/Demos/GLTF/gltf.js | 19 - static/Demos/GLTF/index.html | 88 -- static/Demos/GLTF1CesiumMan/demo.js | 5 - static/Demos/GLTF1CesiumMan/index.html | 88 -- static/Demos/GLTF1CesiumMan/index.js | 41 - .../GLTFMeshPrimitiveAttributeTest/demo.js | 5 - .../GLTFMeshPrimitiveAttributeTest/index.html | 88 -- .../GLTFMeshPrimitiveAttributeTest/index.js | 51 - static/Demos/GLTFNormals/demo.js | 5 - static/Demos/GLTFNormals/index.html | 88 -- static/Demos/GLTFNormals/index.js | 51 - static/Demos/GUI/demo.js | 5 - static/Demos/GUI/gui.js | 258 ----- static/Demos/GUI/index.html | 88 -- static/Demos/GlowLayer/demo.js | 6 - static/Demos/GlowLayer/index.html | 49 - static/Demos/GlowLayer/index.js | 52 - static/Demos/GlowingEspilit/demo.js | 28 - static/Demos/GlowingEspilit/index.html | 88 -- static/Demos/Heart/demo.js | 13 - static/Demos/Heart/index.html | 86 -- static/Demos/Heightmap/demo.js | 5 - static/Demos/Heightmap/heightMap.js | 47 - static/Demos/Heightmap/index.html | 87 -- static/Demos/Highlights/demo.js | 5 - static/Demos/Highlights/highlights.js | 107 -- static/Demos/Highlights/index.html | 87 -- static/Demos/HillValley/demo.js | 18 - static/Demos/HillValley/index.html | 95 -- static/Demos/InstancedBones/bones2.js | 57 -- static/Demos/InstancedBones/demo.js | 5 - static/Demos/InstancedBones/index.html | 87 -- static/Demos/Instances/demo.js | 5 - static/Demos/Instances/index.html | 87 -- static/Demos/Instances/instances.js | 110 -- static/Demos/Instances2/demo.js | 5 - static/Demos/Instances2/index.html | 87 -- static/Demos/Instances2/instances.js | 145 --- static/Demos/LOD/demo.js | 5 - static/Demos/LOD/index.html | 87 -- static/Demos/LOD/lod.js | 56 - static/Demos/Lens/demo.js | 5 - static/Demos/Lens/index.html | 87 -- static/Demos/Lens/lensFlares.js | 39 - static/Demos/Lights/demo.js | 5 - static/Demos/Lights/index.html | 87 -- static/Demos/Lights/lights.js | 79 -- static/Demos/Lines/demo.js | 5 - static/Demos/Lines/index.html | 87 -- static/Demos/Lines/lines.js | 40 - static/Demos/LookAt/demo.js | 5 - static/Demos/LookAt/index.html | 87 -- static/Demos/LookAt/lookAt.js | 107 -- static/Demos/Mansion/demo.js | 11 - static/Demos/Mansion/index.html | 86 -- static/Demos/MorphTargets/dat.gui.min.js | 95 -- static/Demos/MorphTargets/demo.js | 5 - static/Demos/MorphTargets/index.html | 88 -- static/Demos/MorphTargets/morphTargets.js | 135 --- static/Demos/MotionBlur/demo.js | 5 - static/Demos/MotionBlur/index.html | 87 -- static/Demos/MotionBlur/motionBlur.js | 102 -- static/Demos/Multimaterial/demo.js | 5 - static/Demos/Multimaterial/index.html | 87 -- static/Demos/Multimaterial/multimat.js | 40 - static/Demos/Octree/demo.js | 5 - static/Demos/Octree/index.html | 87 -- static/Demos/Octree/octree.js | 33 - static/Demos/Offscreen/index.html | 185 ---- static/Demos/Offscreen/index.js | 14 - static/Demos/Offscreen/worker.js | 24 - static/Demos/PBR/demo.js | 5 - static/Demos/PBR/index.html | 87 -- static/Demos/PBR/pbr.js | 75 -- static/Demos/PBRGlossy/demo.js | 5 - static/Demos/PBRGlossy/index.html | 89 -- static/Demos/PBRGlossy/index.js | 36 - static/Demos/PBRGlossyBloom/demo.js | 5 - static/Demos/PBRGlossyBloom/index.html | 89 -- static/Demos/PBRGlossyBloom/index.js | 34 - static/Demos/PBRRough/demo.js | 5 - static/Demos/PBRRough/index.html | 88 -- static/Demos/PBRRough/index.js | 49 - static/Demos/PPBloom/demo.js | 5 - static/Demos/PPBloom/index.html | 87 -- static/Demos/PPBloom/postprocessBloom.js | 78 -- static/Demos/PPConvolution/demo.js | 5 - static/Demos/PPConvolution/index.html | 87 -- .../PPConvolution/postprocessConvolution.js | 63 -- static/Demos/PPRef/demo.js | 5 - static/Demos/PPRef/index.html | 87 -- static/Demos/PPRef/postprocessRefraction.js | 57 -- static/Demos/Particles/demo.js | 5 - static/Demos/Particles/index.html | 87 -- static/Demos/Particles/particles.js | 81 -- static/Demos/Particles2/demo.js | 5 - static/Demos/Particles2/index.html | 87 -- static/Demos/Particles2/particles2.js | 80 -- static/Demos/PointLightShadowMap/demo.js | 5 - static/Demos/PointLightShadowMap/index.html | 87 -- .../PointLightShadowMap/pointLightShadows.js | 61 -- static/Demos/Polygon/demo.js | 5 - static/Demos/Polygon/index.html | 89 -- static/Demos/Polygon/poly2tri.js | 2 - static/Demos/Polygon/polygon.js | 56 - static/Demos/Procedural/demo.js | 5 - static/Demos/Procedural/index.html | 97 -- static/Demos/Procedural/proceduralTexture.js | 165 --- static/Demos/RefProbe/demo.js | 5 - static/Demos/RefProbe/index.html | 87 -- static/Demos/RefProbe/reflectionProbe.js | 91 -- static/Demos/Refraction/dat.gui.min.js | 95 -- static/Demos/Refraction/demo.js | 5 - static/Demos/Refraction/index.html | 88 -- static/Demos/Refraction/refraction.js | 100 -- static/Demos/Ribbons/demo.js | 5 - static/Demos/Ribbons/index.html | 88 -- static/Demos/Ribbons/ribbons.js | 163 --- static/Demos/SPS/demo.js | 5 - static/Demos/SPS/index.html | 87 -- static/Demos/SPS/sps.js | 128 --- static/Demos/SPSCollisions/demo.js | 5 - static/Demos/SPSCollisions/index.html | 87 -- static/Demos/SPSCollisions/spscollisions.jpg | Bin 133745 -> 0 bytes static/Demos/SPSCollisions/spscollisions.js | 152 --- static/Demos/SSAO/demo.js | 5 - static/Demos/SSAO/index.html | 87 -- static/Demos/SSAO/ssao.js | 48 - static/Demos/SSAO2/demo.js | 5 - static/Demos/SSAO2/index.html | 89 -- static/Demos/SSAO2/ssao.js | 75 -- static/Demos/SelfShadowing/demo.js | 5 - static/Demos/SelfShadowing/index.html | 87 -- static/Demos/SelfShadowing/shadows.js | 35 - static/Demos/Shadows/demo.js | 5 - static/Demos/Shadows/index.html | 87 -- static/Demos/Shadows/shadows.js | 89 -- static/Demos/Simplification/index.html | 45 - static/Demos/Simplification/main.js | 133 --- static/Demos/SoftShadows/demo.js | 5 - static/Demos/SoftShadows/index.html | 87 -- static/Demos/SoftShadows/softShadows.js | 58 -- static/Demos/SpaceDeK/demo.js | 11 - static/Demos/SpaceDeK/index.html | 86 -- static/Demos/Spaceship/demo.js | 12 - static/Demos/Spaceship/demoNoRendering.js | 11 - static/Demos/Spaceship/index.html | 86 -- static/Demos/Spaceship/indexNoRendering.html | 73 -- static/Demos/SponzaDynamicShadows/demo.js | 61 -- .../SponzaDynamicShadows/img/SponzaDSFB.jpg | Bin 74570 -> 0 bytes .../img/SponzaDSTwitter.jpg | Bin 55331 -> 0 bytes static/Demos/SponzaDynamicShadows/index.html | 111 -- .../Demos/StandardRenderingPipeline/demo.js | 5 - .../StandardRenderingPipeline/index.html | 88 -- .../standardRenderingPipeline.js | 95 -- .../babylon.starfieldProceduralTexture.min.js | 1 - static/Demos/Starfield/demo.js | 6 - static/Demos/Starfield/index.html | 88 -- static/Demos/Starfield/starfield.js | 42 - static/Demos/TheCar/demo.js | 12 - static/Demos/TheCar/index.html | 86 -- static/Demos/Train/demo.js | 42 - static/Demos/Train/index.html | 86 -- static/Demos/Tunnel/demo.js | 5 - static/Demos/Tunnel/index.html | 87 -- static/Demos/Tunnel/tunnel.js | 26 - static/Demos/V8/demo.js | 13 - static/Demos/V8/index.html | 86 -- static/Demos/VertexData/clouds.js | 84 -- static/Demos/VertexData/demo.js | 6 - static/Demos/VertexData/index.html | 134 --- static/Demos/Viper/demo.js | 12 - static/Demos/Viper/index.html | 86 -- .../Demos/VolumetricLightScattering/demo.js | 5 - .../VolumetricLightScattering/index.html | 87 -- .../volumetricLightScattering.js | 32 - static/Demos/WCafe/demo.js | 12 - static/Demos/WCafe/index.html | 86 -- .../WaterMaterial/babylon.waterMaterial.js | 662 ------------ static/Demos/WaterMaterial/demo.js | 5 - static/Demos/WaterMaterial/index.html | 88 -- static/Demos/WaterMaterial/water.js | 62 -- static/Demos/Yeti/demo.js | 6 - static/Demos/Yeti/index.html | 55 - static/Demos/Yeti/index.js | 91 -- 550 files changed, 20389 insertions(+), 16628 deletions(-) create mode 100644 AGENTS.md create mode 100644 src/compiledDemos/Actions/index.html create mode 100644 src/compiledDemos/Actions/main.ts create mode 100644 src/compiledDemos/Actions/scene.ts create mode 100644 src/compiledDemos/Bones/index.html create mode 100644 src/compiledDemos/Bones/main.ts create mode 100644 src/compiledDemos/Bones/scene.ts create mode 100644 src/compiledDemos/Charting/index.html create mode 100644 src/compiledDemos/Charting/main.ts create mode 100644 src/compiledDemos/Charting/scene.ts create mode 100644 src/compiledDemos/Dancers/index.html create mode 100644 src/compiledDemos/Dancers/main.ts create mode 100644 src/compiledDemos/Dancers/scene.ts create mode 100644 src/compiledDemos/DragNDrop/index.html create mode 100644 src/compiledDemos/DragNDrop/main.ts create mode 100644 src/compiledDemos/DragNDrop/scene.ts create mode 100644 src/compiledDemos/Espilit/index.html create mode 100644 src/compiledDemos/Espilit/main.ts create mode 100644 src/compiledDemos/Espilit/scene.ts create mode 100644 src/compiledDemos/ExtrudePolygon/index.html create mode 100644 src/compiledDemos/ExtrudePolygon/main.ts create mode 100644 src/compiledDemos/ExtrudePolygon/scene.ts create mode 100644 src/compiledDemos/Facets/index.html create mode 100644 src/compiledDemos/Facets/main.ts create mode 100644 src/compiledDemos/Facets/scene.ts create mode 100644 src/compiledDemos/Flat2009/index.html create mode 100644 src/compiledDemos/Flat2009/main.ts create mode 100644 src/compiledDemos/Flat2009/scene.ts create mode 100644 src/compiledDemos/GlowingEspilit/index.html create mode 100644 src/compiledDemos/GlowingEspilit/main.ts create mode 100644 src/compiledDemos/GlowingEspilit/scene.ts create mode 100644 src/compiledDemos/Heart/index.html create mode 100644 src/compiledDemos/Heart/main.ts create mode 100644 src/compiledDemos/Heart/scene.ts create mode 100644 src/compiledDemos/HillValley/index.html create mode 100644 src/compiledDemos/HillValley/main.ts create mode 100644 src/compiledDemos/HillValley/scene.ts create mode 100644 src/compiledDemos/InstancedBones/index.html create mode 100644 src/compiledDemos/InstancedBones/main.ts create mode 100644 src/compiledDemos/InstancedBones/scene.ts create mode 100644 src/compiledDemos/Instances/index.html create mode 100644 src/compiledDemos/Instances/main.ts create mode 100644 src/compiledDemos/Instances/scene.ts create mode 100644 src/compiledDemos/Instances2/index.html create mode 100644 src/compiledDemos/Instances2/main.ts create mode 100644 src/compiledDemos/Instances2/scene.ts create mode 100644 src/compiledDemos/Mansion/index.html create mode 100644 src/compiledDemos/Mansion/main.ts create mode 100644 src/compiledDemos/Mansion/scene.ts create mode 100644 src/compiledDemos/MorphTargets/index.html create mode 100644 src/compiledDemos/MorphTargets/main.ts create mode 100644 src/compiledDemos/MorphTargets/scene.ts create mode 100644 src/compiledDemos/Particles2/index.html create mode 100644 src/compiledDemos/Particles2/main.ts create mode 100644 src/compiledDemos/Particles2/scene.ts create mode 100644 src/compiledDemos/Polygon/index.html create mode 100644 src/compiledDemos/Polygon/main.ts create mode 100644 src/compiledDemos/Polygon/scene.ts create mode 100644 src/compiledDemos/Procedural/index.html create mode 100644 src/compiledDemos/Procedural/main.ts create mode 100644 src/compiledDemos/Procedural/scene.ts create mode 100644 src/compiledDemos/RefProbe/index.html create mode 100644 src/compiledDemos/RefProbe/main.ts create mode 100644 src/compiledDemos/RefProbe/scene.ts create mode 100644 src/compiledDemos/SPS/index.html create mode 100644 src/compiledDemos/SPS/main.ts create mode 100644 src/compiledDemos/SPS/scene.ts create mode 100644 src/compiledDemos/SPSCollisions/index.html create mode 100644 src/compiledDemos/SPSCollisions/main.ts create mode 100644 src/compiledDemos/SPSCollisions/scene.ts create mode 100644 src/compiledDemos/SSAO/index.html create mode 100644 src/compiledDemos/SSAO/main.ts create mode 100644 src/compiledDemos/SSAO/scene.ts create mode 100644 src/compiledDemos/SSAO2/index.html create mode 100644 src/compiledDemos/SSAO2/main.ts create mode 100644 src/compiledDemos/SSAO2/scene.ts create mode 100644 src/compiledDemos/SelfShadowing/index.html create mode 100644 src/compiledDemos/SelfShadowing/main.ts create mode 100644 src/compiledDemos/SelfShadowing/scene.ts create mode 100644 src/compiledDemos/Simplification/index.html create mode 100644 src/compiledDemos/Simplification/main.ts create mode 100644 src/compiledDemos/Simplification/scene.ts create mode 100644 src/compiledDemos/SoftShadows/index.html create mode 100644 src/compiledDemos/SoftShadows/main.ts create mode 100644 src/compiledDemos/SoftShadows/scene.ts create mode 100644 src/compiledDemos/SpaceDeK/index.html create mode 100644 src/compiledDemos/SpaceDeK/main.ts create mode 100644 src/compiledDemos/SpaceDeK/scene.ts create mode 100644 src/compiledDemos/Spaceship/index.html create mode 100644 src/compiledDemos/Spaceship/main.ts create mode 100644 src/compiledDemos/Spaceship/scene.ts create mode 100644 src/compiledDemos/SponzaDynamicShadows/index.html create mode 100644 src/compiledDemos/SponzaDynamicShadows/main.ts create mode 100644 src/compiledDemos/SponzaDynamicShadows/scene.ts create mode 100644 src/compiledDemos/Starfield/index.html create mode 100644 src/compiledDemos/Starfield/main.ts create mode 100644 src/compiledDemos/Starfield/scene.ts create mode 100644 src/compiledDemos/Train/index.html create mode 100644 src/compiledDemos/Train/main.ts create mode 100644 src/compiledDemos/Train/scene.ts create mode 100644 src/compiledDemos/Tunnel/index.html create mode 100644 src/compiledDemos/Tunnel/main.ts create mode 100644 src/compiledDemos/Tunnel/scene.ts create mode 100644 src/compiledDemos/V8/index.html create mode 100644 src/compiledDemos/V8/main.ts create mode 100644 src/compiledDemos/V8/scene.ts create mode 100644 src/compiledDemos/Viper/index.html create mode 100644 src/compiledDemos/Viper/main.ts create mode 100644 src/compiledDemos/Viper/scene.ts create mode 100644 src/compiledDemos/WCafe/index.html create mode 100644 src/compiledDemos/WCafe/main.ts create mode 100644 src/compiledDemos/WCafe/scene.ts create mode 100644 src/pureCompiledDemos/Actions/index.html create mode 100644 src/pureCompiledDemos/Actions/main.ts create mode 100644 src/pureCompiledDemos/Actions/scene.ts create mode 100644 src/pureCompiledDemos/AssetsManager/index.html create mode 100644 src/pureCompiledDemos/AssetsManager/main.ts create mode 100644 src/pureCompiledDemos/AssetsManager/scene.ts create mode 100644 src/pureCompiledDemos/Bones/index.html create mode 100644 src/pureCompiledDemos/Bones/main.ts create mode 100644 src/pureCompiledDemos/Bones/scene.ts create mode 100644 src/pureCompiledDemos/Boom/index.html create mode 100644 src/pureCompiledDemos/Boom/main.ts create mode 100644 src/pureCompiledDemos/Boom/scene.ts create mode 100644 src/pureCompiledDemos/CellShading/index.html create mode 100644 src/pureCompiledDemos/CellShading/main.ts create mode 100644 src/pureCompiledDemos/CellShading/scene.ts create mode 100644 src/pureCompiledDemos/Charting/index.html create mode 100644 src/pureCompiledDemos/Charting/main.ts create mode 100644 src/pureCompiledDemos/Charting/scene.ts create mode 100644 src/pureCompiledDemos/Dancers/index.html create mode 100644 src/pureCompiledDemos/Dancers/main.ts create mode 100644 src/pureCompiledDemos/Dancers/scene.ts create mode 100644 src/pureCompiledDemos/DragNDrop/index.html create mode 100644 src/pureCompiledDemos/DragNDrop/main.ts create mode 100644 src/pureCompiledDemos/DragNDrop/scene.ts create mode 100644 src/pureCompiledDemos/Espilit/index.html create mode 100644 src/pureCompiledDemos/Espilit/main.ts create mode 100644 src/pureCompiledDemos/Espilit/scene.ts create mode 100644 src/pureCompiledDemos/ExtrudePolygon/index.html create mode 100644 src/pureCompiledDemos/ExtrudePolygon/main.ts create mode 100644 src/pureCompiledDemos/ExtrudePolygon/scene.ts create mode 100644 src/pureCompiledDemos/Facets/index.html create mode 100644 src/pureCompiledDemos/Facets/main.ts create mode 100644 src/pureCompiledDemos/Facets/scene.ts create mode 100644 src/pureCompiledDemos/FireMaterial/index.html create mode 100644 src/pureCompiledDemos/FireMaterial/main.ts create mode 100644 src/pureCompiledDemos/FireMaterial/scene.ts create mode 100644 src/pureCompiledDemos/Flat2009/index.html create mode 100644 src/pureCompiledDemos/Flat2009/main.ts create mode 100644 src/pureCompiledDemos/Flat2009/scene.ts create mode 100644 src/pureCompiledDemos/Fresnel/index.html create mode 100644 src/pureCompiledDemos/Fresnel/main.ts create mode 100644 src/pureCompiledDemos/Fresnel/scene.ts create mode 100644 src/pureCompiledDemos/Fur/index.html create mode 100644 src/pureCompiledDemos/Fur/main.ts create mode 100644 src/pureCompiledDemos/Fur/scene.ts create mode 100644 src/pureCompiledDemos/GLTF/index.html create mode 100644 src/pureCompiledDemos/GLTF/main.ts create mode 100644 src/pureCompiledDemos/GLTF/scene.ts create mode 100644 src/pureCompiledDemos/GLTFMeshPrimitiveAttributeTest/index.html create mode 100644 src/pureCompiledDemos/GLTFMeshPrimitiveAttributeTest/main.ts create mode 100644 src/pureCompiledDemos/GLTFMeshPrimitiveAttributeTest/scene.ts create mode 100644 src/pureCompiledDemos/GLTFNormals/index.html create mode 100644 src/pureCompiledDemos/GLTFNormals/main.ts create mode 100644 src/pureCompiledDemos/GLTFNormals/scene.ts create mode 100644 src/pureCompiledDemos/GUI/index.html create mode 100644 src/pureCompiledDemos/GUI/main.ts create mode 100644 src/pureCompiledDemos/GUI/scene.ts create mode 100644 src/pureCompiledDemos/GlowingEspilit/index.html create mode 100644 src/pureCompiledDemos/GlowingEspilit/main.ts create mode 100644 src/pureCompiledDemos/GlowingEspilit/scene.ts create mode 100644 src/pureCompiledDemos/Heart/index.html create mode 100644 src/pureCompiledDemos/Heart/main.ts create mode 100644 src/pureCompiledDemos/Heart/scene.ts create mode 100644 src/pureCompiledDemos/HillValley/index.html create mode 100644 src/pureCompiledDemos/HillValley/main.ts create mode 100644 src/pureCompiledDemos/HillValley/scene.ts create mode 100644 src/pureCompiledDemos/InstancedBones/index.html create mode 100644 src/pureCompiledDemos/InstancedBones/main.ts create mode 100644 src/pureCompiledDemos/InstancedBones/scene.ts create mode 100644 src/pureCompiledDemos/Instances/index.html create mode 100644 src/pureCompiledDemos/Instances/main.ts create mode 100644 src/pureCompiledDemos/Instances/scene.ts create mode 100644 src/pureCompiledDemos/Instances2/index.html create mode 100644 src/pureCompiledDemos/Instances2/main.ts create mode 100644 src/pureCompiledDemos/Instances2/scene.ts create mode 100644 src/pureCompiledDemos/LOD/index.html create mode 100644 src/pureCompiledDemos/LOD/main.ts create mode 100644 src/pureCompiledDemos/LOD/scene.ts create mode 100644 src/pureCompiledDemos/LookAt/index.html create mode 100644 src/pureCompiledDemos/LookAt/main.ts create mode 100644 src/pureCompiledDemos/LookAt/scene.ts create mode 100644 src/pureCompiledDemos/Mansion/index.html create mode 100644 src/pureCompiledDemos/Mansion/main.ts create mode 100644 src/pureCompiledDemos/Mansion/scene.ts create mode 100644 src/pureCompiledDemos/MorphTargets/index.html create mode 100644 src/pureCompiledDemos/MorphTargets/main.ts create mode 100644 src/pureCompiledDemos/MorphTargets/scene.ts create mode 100644 src/pureCompiledDemos/Octree/index.html create mode 100644 src/pureCompiledDemos/Octree/main.ts create mode 100644 src/pureCompiledDemos/Octree/scene.ts create mode 100644 src/pureCompiledDemos/Offscreen/index.html create mode 100644 src/pureCompiledDemos/Offscreen/main.ts create mode 100644 src/pureCompiledDemos/Offscreen/scene.ts create mode 100644 src/pureCompiledDemos/Offscreen/worker.ts create mode 100644 src/pureCompiledDemos/Particles2/index.html create mode 100644 src/pureCompiledDemos/Particles2/main.ts create mode 100644 src/pureCompiledDemos/Particles2/scene.ts create mode 100644 src/pureCompiledDemos/PointLightShadowMap/index.html create mode 100644 src/pureCompiledDemos/PointLightShadowMap/main.ts create mode 100644 src/pureCompiledDemos/PointLightShadowMap/scene.ts create mode 100644 src/pureCompiledDemos/Polygon/index.html create mode 100644 src/pureCompiledDemos/Polygon/main.ts create mode 100644 src/pureCompiledDemos/Polygon/scene.ts create mode 100644 src/pureCompiledDemos/Procedural/index.html create mode 100644 src/pureCompiledDemos/Procedural/main.ts create mode 100644 src/pureCompiledDemos/Procedural/scene.ts create mode 100644 src/pureCompiledDemos/RefProbe/index.html create mode 100644 src/pureCompiledDemos/RefProbe/main.ts create mode 100644 src/pureCompiledDemos/RefProbe/scene.ts create mode 100644 src/pureCompiledDemos/SPS/index.html create mode 100644 src/pureCompiledDemos/SPS/main.ts create mode 100644 src/pureCompiledDemos/SPS/scene.ts create mode 100644 src/pureCompiledDemos/SPSCollisions/index.html create mode 100644 src/pureCompiledDemos/SPSCollisions/main.ts create mode 100644 src/pureCompiledDemos/SPSCollisions/scene.ts create mode 100644 src/pureCompiledDemos/SSAO/index.html create mode 100644 src/pureCompiledDemos/SSAO/main.ts create mode 100644 src/pureCompiledDemos/SSAO/scene.ts create mode 100644 src/pureCompiledDemos/SSAO2/index.html create mode 100644 src/pureCompiledDemos/SSAO2/main.ts create mode 100644 src/pureCompiledDemos/SSAO2/scene.ts create mode 100644 src/pureCompiledDemos/SelfShadowing/index.html create mode 100644 src/pureCompiledDemos/SelfShadowing/main.ts create mode 100644 src/pureCompiledDemos/SelfShadowing/scene.ts create mode 100644 src/pureCompiledDemos/Shadows/index.html create mode 100644 src/pureCompiledDemos/Shadows/main.ts create mode 100644 src/pureCompiledDemos/Shadows/scene.ts create mode 100644 src/pureCompiledDemos/Simplification/index.html create mode 100644 src/pureCompiledDemos/Simplification/main.ts create mode 100644 src/pureCompiledDemos/Simplification/scene.ts create mode 100644 src/pureCompiledDemos/SoftShadows/index.html create mode 100644 src/pureCompiledDemos/SoftShadows/main.ts create mode 100644 src/pureCompiledDemos/SoftShadows/scene.ts create mode 100644 src/pureCompiledDemos/SpaceDeK/index.html create mode 100644 src/pureCompiledDemos/SpaceDeK/main.ts create mode 100644 src/pureCompiledDemos/SpaceDeK/scene.ts create mode 100644 src/pureCompiledDemos/Spaceship/index.html create mode 100644 src/pureCompiledDemos/Spaceship/main.ts create mode 100644 src/pureCompiledDemos/Spaceship/scene.ts create mode 100644 src/pureCompiledDemos/SponzaDynamicShadows/index.html create mode 100644 src/pureCompiledDemos/SponzaDynamicShadows/main.ts create mode 100644 src/pureCompiledDemos/SponzaDynamicShadows/scene.ts create mode 100644 src/pureCompiledDemos/Starfield/index.html create mode 100644 src/pureCompiledDemos/Starfield/main.ts create mode 100644 src/pureCompiledDemos/Starfield/scene.ts create mode 100644 src/pureCompiledDemos/Train/index.html create mode 100644 src/pureCompiledDemos/Train/main.ts create mode 100644 src/pureCompiledDemos/Train/scene.ts create mode 100644 src/pureCompiledDemos/Tunnel/index.html create mode 100644 src/pureCompiledDemos/Tunnel/main.ts create mode 100644 src/pureCompiledDemos/Tunnel/scene.ts create mode 100644 src/pureCompiledDemos/V8/index.html create mode 100644 src/pureCompiledDemos/V8/main.ts create mode 100644 src/pureCompiledDemos/V8/scene.ts create mode 100644 src/pureCompiledDemos/Viper/index.html create mode 100644 src/pureCompiledDemos/Viper/main.ts create mode 100644 src/pureCompiledDemos/Viper/scene.ts create mode 100644 src/pureCompiledDemos/VolumetricLightScattering/index.html create mode 100644 src/pureCompiledDemos/VolumetricLightScattering/main.ts create mode 100644 src/pureCompiledDemos/VolumetricLightScattering/scene.ts create mode 100644 src/pureCompiledDemos/WCafe/index.html create mode 100644 src/pureCompiledDemos/WCafe/main.ts create mode 100644 src/pureCompiledDemos/WCafe/scene.ts create mode 100644 src/pureCompiledDemos/WaterMaterial/index.html create mode 100644 src/pureCompiledDemos/WaterMaterial/main.ts create mode 100644 src/pureCompiledDemos/WaterMaterial/scene.ts create mode 100644 src/pureCompiledDemos/Yeti/index.html create mode 100644 src/pureCompiledDemos/Yeti/main.ts create mode 100644 src/pureCompiledDemos/Yeti/scene.ts delete mode 100644 static/Demos/Actions/actions.js delete mode 100644 static/Demos/Actions/demo.js delete mode 100644 static/Demos/Actions/index.html delete mode 100644 static/Demos/AdvancedShadows/advancedShadows.js delete mode 100644 static/Demos/AdvancedShadows/demo.js delete mode 100644 static/Demos/AdvancedShadows/index.html delete mode 100644 static/Demos/AssetsManager/assets.js delete mode 100644 static/Demos/AssetsManager/index.html delete mode 100644 static/Demos/Bones/bones.js delete mode 100644 static/Demos/Bones/demo.js delete mode 100644 static/Demos/Bones/index.html delete mode 100644 static/Demos/Boom/boom.js delete mode 100644 static/Demos/Boom/demo.js delete mode 100644 static/Demos/Boom/index.html delete mode 100644 static/Demos/Bump/bump.js delete mode 100644 static/Demos/Bump/demo.js delete mode 100644 static/Demos/Bump/index.html delete mode 100644 static/Demos/CSG/csg.js delete mode 100644 static/Demos/CSG/demo.js delete mode 100644 static/Demos/CSG/index.html delete mode 100644 static/Demos/CellShading/cellShading.js delete mode 100644 static/Demos/CellShading/demo.js delete mode 100644 static/Demos/CellShading/index.html delete mode 100644 static/Demos/Charting/charting.js delete mode 100644 static/Demos/Charting/demo.js delete mode 100644 static/Demos/Charting/index.html delete mode 100644 static/Demos/CustomRenderTarget/customRenderTarget.js delete mode 100644 static/Demos/CustomRenderTarget/demo.js delete mode 100644 static/Demos/CustomRenderTarget/index.html delete mode 100644 static/Demos/CustomShader/cellShading.js delete mode 100644 static/Demos/CustomShader/demo.js delete mode 100644 static/Demos/CustomShader/index.html delete mode 100644 static/Demos/DOF/demo.js delete mode 100644 static/Demos/DOF/dof.js delete mode 100644 static/Demos/DOF/index.html delete mode 100644 static/Demos/Dancers/dat.gui.min.js delete mode 100644 static/Demos/Dancers/index.html delete mode 100644 static/Demos/Decals/decals.js delete mode 100644 static/Demos/Decals/demo.js delete mode 100644 static/Demos/Decals/index.html delete mode 100644 static/Demos/DefaultRenderingPipeline/default.js delete mode 100644 static/Demos/DefaultRenderingPipeline/demo.js delete mode 100644 static/Demos/DefaultRenderingPipeline/index.html delete mode 100644 static/Demos/DisplacementMap/demo.js delete mode 100644 static/Demos/DisplacementMap/displacementMap.js delete mode 100644 static/Demos/DisplacementMap/index.html delete mode 100644 static/Demos/DragNDrop/demo.js delete mode 100644 static/Demos/DragNDrop/dragdrop.js delete mode 100644 static/Demos/DragNDrop/index.html delete mode 100644 static/Demos/Espilit/demo.js delete mode 100644 static/Demos/Espilit/index.html delete mode 100644 static/Demos/ExtrudePolygon/demo.js delete mode 100644 static/Demos/ExtrudePolygon/extrude.js delete mode 100644 static/Demos/ExtrudePolygon/index.html delete mode 100644 static/Demos/Facets/demo.js delete mode 100644 static/Demos/Facets/facets.js delete mode 100644 static/Demos/Facets/index.html delete mode 100644 static/Demos/FireMaterial/babylon.fireMaterial.min.js delete mode 100644 static/Demos/FireMaterial/demo.js delete mode 100644 static/Demos/FireMaterial/fire.js delete mode 100644 static/Demos/FireMaterial/index.html delete mode 100644 static/Demos/Flat2009/demo.js delete mode 100644 static/Demos/Flat2009/index.html delete mode 100644 static/Demos/FlightHelmet/demo.js delete mode 100644 static/Demos/FlightHelmet/index.html delete mode 100644 static/Demos/FlightHelmet/index.js delete mode 100644 static/Demos/Fog/demo.js delete mode 100644 static/Demos/Fog/fog.js delete mode 100644 static/Demos/Fog/index.html delete mode 100644 static/Demos/Fresnel/demo.js delete mode 100644 static/Demos/Fresnel/fresnel.js delete mode 100644 static/Demos/Fresnel/index.html delete mode 100644 static/Demos/Fur/demo.js delete mode 100644 static/Demos/Fur/fur.js delete mode 100644 static/Demos/Fur/index.html delete mode 100644 static/Demos/GLTF/demo.js delete mode 100644 static/Demos/GLTF/gltf.js delete mode 100644 static/Demos/GLTF/index.html delete mode 100644 static/Demos/GLTF1CesiumMan/demo.js delete mode 100644 static/Demos/GLTF1CesiumMan/index.html delete mode 100644 static/Demos/GLTF1CesiumMan/index.js delete mode 100644 static/Demos/GLTFMeshPrimitiveAttributeTest/demo.js delete mode 100644 static/Demos/GLTFMeshPrimitiveAttributeTest/index.html delete mode 100644 static/Demos/GLTFMeshPrimitiveAttributeTest/index.js delete mode 100644 static/Demos/GLTFNormals/demo.js delete mode 100644 static/Demos/GLTFNormals/index.html delete mode 100644 static/Demos/GLTFNormals/index.js delete mode 100644 static/Demos/GUI/demo.js delete mode 100644 static/Demos/GUI/gui.js delete mode 100644 static/Demos/GUI/index.html delete mode 100644 static/Demos/GlowLayer/demo.js delete mode 100644 static/Demos/GlowLayer/index.html delete mode 100644 static/Demos/GlowLayer/index.js delete mode 100644 static/Demos/GlowingEspilit/demo.js delete mode 100644 static/Demos/GlowingEspilit/index.html delete mode 100644 static/Demos/Heart/demo.js delete mode 100644 static/Demos/Heart/index.html delete mode 100644 static/Demos/Heightmap/demo.js delete mode 100644 static/Demos/Heightmap/heightMap.js delete mode 100644 static/Demos/Heightmap/index.html delete mode 100644 static/Demos/Highlights/demo.js delete mode 100644 static/Demos/Highlights/highlights.js delete mode 100644 static/Demos/Highlights/index.html delete mode 100644 static/Demos/HillValley/demo.js delete mode 100644 static/Demos/HillValley/index.html delete mode 100644 static/Demos/InstancedBones/bones2.js delete mode 100644 static/Demos/InstancedBones/demo.js delete mode 100644 static/Demos/InstancedBones/index.html delete mode 100644 static/Demos/Instances/demo.js delete mode 100644 static/Demos/Instances/index.html delete mode 100644 static/Demos/Instances/instances.js delete mode 100644 static/Demos/Instances2/demo.js delete mode 100644 static/Demos/Instances2/index.html delete mode 100644 static/Demos/Instances2/instances.js delete mode 100644 static/Demos/LOD/demo.js delete mode 100644 static/Demos/LOD/index.html delete mode 100644 static/Demos/LOD/lod.js delete mode 100644 static/Demos/Lens/demo.js delete mode 100644 static/Demos/Lens/index.html delete mode 100644 static/Demos/Lens/lensFlares.js delete mode 100644 static/Demos/Lights/demo.js delete mode 100644 static/Demos/Lights/index.html delete mode 100644 static/Demos/Lights/lights.js delete mode 100644 static/Demos/Lines/demo.js delete mode 100644 static/Demos/Lines/index.html delete mode 100644 static/Demos/Lines/lines.js delete mode 100644 static/Demos/LookAt/demo.js delete mode 100644 static/Demos/LookAt/index.html delete mode 100644 static/Demos/LookAt/lookAt.js delete mode 100644 static/Demos/Mansion/demo.js delete mode 100644 static/Demos/Mansion/index.html delete mode 100644 static/Demos/MorphTargets/dat.gui.min.js delete mode 100644 static/Demos/MorphTargets/demo.js delete mode 100644 static/Demos/MorphTargets/index.html delete mode 100644 static/Demos/MorphTargets/morphTargets.js delete mode 100644 static/Demos/MotionBlur/demo.js delete mode 100644 static/Demos/MotionBlur/index.html delete mode 100644 static/Demos/MotionBlur/motionBlur.js delete mode 100644 static/Demos/Multimaterial/demo.js delete mode 100644 static/Demos/Multimaterial/index.html delete mode 100644 static/Demos/Multimaterial/multimat.js delete mode 100644 static/Demos/Octree/demo.js delete mode 100644 static/Demos/Octree/index.html delete mode 100644 static/Demos/Octree/octree.js delete mode 100644 static/Demos/Offscreen/index.html delete mode 100644 static/Demos/Offscreen/index.js delete mode 100644 static/Demos/Offscreen/worker.js delete mode 100644 static/Demos/PBR/demo.js delete mode 100644 static/Demos/PBR/index.html delete mode 100644 static/Demos/PBR/pbr.js delete mode 100644 static/Demos/PBRGlossy/demo.js delete mode 100644 static/Demos/PBRGlossy/index.html delete mode 100644 static/Demos/PBRGlossy/index.js delete mode 100644 static/Demos/PBRGlossyBloom/demo.js delete mode 100644 static/Demos/PBRGlossyBloom/index.html delete mode 100644 static/Demos/PBRGlossyBloom/index.js delete mode 100644 static/Demos/PBRRough/demo.js delete mode 100644 static/Demos/PBRRough/index.html delete mode 100644 static/Demos/PBRRough/index.js delete mode 100644 static/Demos/PPBloom/demo.js delete mode 100644 static/Demos/PPBloom/index.html delete mode 100644 static/Demos/PPBloom/postprocessBloom.js delete mode 100644 static/Demos/PPConvolution/demo.js delete mode 100644 static/Demos/PPConvolution/index.html delete mode 100644 static/Demos/PPConvolution/postprocessConvolution.js delete mode 100644 static/Demos/PPRef/demo.js delete mode 100644 static/Demos/PPRef/index.html delete mode 100644 static/Demos/PPRef/postprocessRefraction.js delete mode 100644 static/Demos/Particles/demo.js delete mode 100644 static/Demos/Particles/index.html delete mode 100644 static/Demos/Particles/particles.js delete mode 100644 static/Demos/Particles2/demo.js delete mode 100644 static/Demos/Particles2/index.html delete mode 100644 static/Demos/Particles2/particles2.js delete mode 100644 static/Demos/PointLightShadowMap/demo.js delete mode 100644 static/Demos/PointLightShadowMap/index.html delete mode 100644 static/Demos/PointLightShadowMap/pointLightShadows.js delete mode 100644 static/Demos/Polygon/demo.js delete mode 100644 static/Demos/Polygon/index.html delete mode 100644 static/Demos/Polygon/poly2tri.js delete mode 100644 static/Demos/Polygon/polygon.js delete mode 100644 static/Demos/Procedural/demo.js delete mode 100644 static/Demos/Procedural/index.html delete mode 100644 static/Demos/Procedural/proceduralTexture.js delete mode 100644 static/Demos/RefProbe/demo.js delete mode 100644 static/Demos/RefProbe/index.html delete mode 100644 static/Demos/RefProbe/reflectionProbe.js delete mode 100644 static/Demos/Refraction/dat.gui.min.js delete mode 100644 static/Demos/Refraction/demo.js delete mode 100644 static/Demos/Refraction/index.html delete mode 100644 static/Demos/Refraction/refraction.js delete mode 100644 static/Demos/Ribbons/demo.js delete mode 100644 static/Demos/Ribbons/index.html delete mode 100644 static/Demos/Ribbons/ribbons.js delete mode 100644 static/Demos/SPS/demo.js delete mode 100644 static/Demos/SPS/index.html delete mode 100644 static/Demos/SPS/sps.js delete mode 100644 static/Demos/SPSCollisions/demo.js delete mode 100644 static/Demos/SPSCollisions/index.html delete mode 100644 static/Demos/SPSCollisions/spscollisions.jpg delete mode 100644 static/Demos/SPSCollisions/spscollisions.js delete mode 100644 static/Demos/SSAO/demo.js delete mode 100644 static/Demos/SSAO/index.html delete mode 100644 static/Demos/SSAO/ssao.js delete mode 100644 static/Demos/SSAO2/demo.js delete mode 100644 static/Demos/SSAO2/index.html delete mode 100644 static/Demos/SSAO2/ssao.js delete mode 100644 static/Demos/SelfShadowing/demo.js delete mode 100644 static/Demos/SelfShadowing/index.html delete mode 100644 static/Demos/SelfShadowing/shadows.js delete mode 100644 static/Demos/Shadows/demo.js delete mode 100644 static/Demos/Shadows/index.html delete mode 100644 static/Demos/Shadows/shadows.js delete mode 100644 static/Demos/Simplification/index.html delete mode 100644 static/Demos/Simplification/main.js delete mode 100644 static/Demos/SoftShadows/demo.js delete mode 100644 static/Demos/SoftShadows/index.html delete mode 100644 static/Demos/SoftShadows/softShadows.js delete mode 100644 static/Demos/SpaceDeK/demo.js delete mode 100644 static/Demos/SpaceDeK/index.html delete mode 100644 static/Demos/Spaceship/demo.js delete mode 100644 static/Demos/Spaceship/demoNoRendering.js delete mode 100644 static/Demos/Spaceship/index.html delete mode 100644 static/Demos/Spaceship/indexNoRendering.html delete mode 100644 static/Demos/SponzaDynamicShadows/demo.js delete mode 100644 static/Demos/SponzaDynamicShadows/img/SponzaDSFB.jpg delete mode 100644 static/Demos/SponzaDynamicShadows/img/SponzaDSTwitter.jpg delete mode 100644 static/Demos/SponzaDynamicShadows/index.html delete mode 100644 static/Demos/StandardRenderingPipeline/demo.js delete mode 100644 static/Demos/StandardRenderingPipeline/index.html delete mode 100644 static/Demos/StandardRenderingPipeline/standardRenderingPipeline.js delete mode 100644 static/Demos/Starfield/babylon.starfieldProceduralTexture.min.js delete mode 100644 static/Demos/Starfield/demo.js delete mode 100644 static/Demos/Starfield/index.html delete mode 100644 static/Demos/Starfield/starfield.js delete mode 100644 static/Demos/TheCar/demo.js delete mode 100644 static/Demos/TheCar/index.html delete mode 100644 static/Demos/Train/demo.js delete mode 100644 static/Demos/Train/index.html delete mode 100644 static/Demos/Tunnel/demo.js delete mode 100644 static/Demos/Tunnel/index.html delete mode 100644 static/Demos/Tunnel/tunnel.js delete mode 100644 static/Demos/V8/demo.js delete mode 100644 static/Demos/V8/index.html delete mode 100644 static/Demos/VertexData/clouds.js delete mode 100644 static/Demos/VertexData/demo.js delete mode 100644 static/Demos/VertexData/index.html delete mode 100644 static/Demos/Viper/demo.js delete mode 100644 static/Demos/Viper/index.html delete mode 100644 static/Demos/VolumetricLightScattering/demo.js delete mode 100644 static/Demos/VolumetricLightScattering/index.html delete mode 100644 static/Demos/VolumetricLightScattering/volumetricLightScattering.js delete mode 100644 static/Demos/WCafe/demo.js delete mode 100644 static/Demos/WCafe/index.html delete mode 100644 static/Demos/WaterMaterial/babylon.waterMaterial.js delete mode 100644 static/Demos/WaterMaterial/demo.js delete mode 100644 static/Demos/WaterMaterial/index.html delete mode 100644 static/Demos/WaterMaterial/water.js delete mode 100644 static/Demos/Yeti/demo.js delete mode 100644 static/Demos/Yeti/index.html delete mode 100644 static/Demos/Yeti/index.js diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..4d4382aa3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,201 @@ +# AGENTS.md — Contributing demos to the Babylon.js website + +This file tells automated agents (and humans) how to add or change demos on the +Babylon.js website. Read it before touching anything under `src/compiledDemos/`, +`src/pureCompiledDemos/`, or `static/Demos/`. + +## The one hard rule: no UMD demos + +**Every demo on the website MUST use the ES6 `@babylonjs/*` packages. UMD is not +allowed.** + +- ❌ Do **not** add a demo that loads Babylon from a UMD/CDN script tag, e.g. + `` or any + `BABYLON.*` global usage. +- ❌ Do **not** add a demo to `static/Demos/`. That folder is the legacy UMD tree + and is being removed. Nothing new goes there. +- ✅ Add demos as ES6 TypeScript that imports named symbols from + `@babylonjs/core` (and sibling packages), bundled by Vite. + +If you are porting a legacy `static/Demos//` demo, you replace every +`BABYLON.*` global with an explicit ES6 import and delete the legacy folder once +the port is verified. + +## Two flavors, add BOTH + +Every demo exists in two forms. When you add or port a demo, add it in **both**: + +1. **Compiled demo** — `src/compiledDemos//`. Imports from the standard + deep ESM paths such as `@babylonjs/core/Engines/engine`. Built to + `build/Demos//` and served at `/Demos//`. +2. **Pure demo** — `src/pureCompiledDemos//`. Imports from the tree-shaken + `@babylonjs/core/pure` barrel and calls the explicit `Register*()` side-effect + functions it needs. Built to `build/PureDemos//` and served at + `/PureDemos//`. + +The pure flavor exists to prove the demo works against the side-effect-free +barrel. If a feature cannot be expressed in pure form, say so explicitly in the +PR/commit rather than silently skipping it. + +## File layout per demo + +```text +src/compiledDemos// + index.html # canvas shell; copy an existing demo's index.html, change + main.ts # 5-line wrapper that calls runDemo({ createScene }) + scene.ts # the actual scene factory — the only file with real logic + +src/pureCompiledDemos/<Slug>/ + index.html # same shell + main.ts # same wrapper, imports ../shared/demoRunner (the pure one) + scene.ts # same scene, but imports from @babylonjs/core/pure +``` + +`main.ts` is always: + +```ts +import { runDemo } from "../shared/demoRunner"; +import { createMyScene } from "./scene"; + +runDemo({ createScene: createMyScene }); +``` + +`scene.ts` exports a factory. It may return `Scene` or `Promise<Scene>` (use the +Promise form for demos that load assets): + +```ts +export function createMyScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + // ...build the scene... + return scene; +} +``` + +`index.html` is identical across demos except the `<title>`. Copy it from a +neighboring demo (for example `src/compiledDemos/Fog/index.html`). It must keep +the `#renderCanvas` element, the `#enableDebug`/`#fullscreen` buttons, the +`<a id="sourceLink" href="./source/">Source</a>` link, and +`<script type="module" src="./main.ts"></script>`. + +## Imports: compiled vs pure + +Compiled (`src/compiledDemos`) — deep named imports plus side-effect imports for +prototype-augmented APIs: + +```ts +import { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; // side effect: .babylon loader +``` + +Pure (`src/pureCompiledDemos`) — import everything from the `pure` barrel and +register side effects with the matching `Register*()` call. Shared registrations +(StandardMaterial, dynamic/read texture, cube texture, depth renderer, outline) +already live in `src/pureCompiledDemos/shared/demoRunner.ts`; only add +registrations specific to your demo in your `scene.ts`. + +```ts +import type { Engine, Scene } from "@babylonjs/core/pure"; +import { StandardMaterial, RegisterBabylonFileLoader } from "@babylonjs/core/pure"; + +RegisterBabylonFileLoader(); // pure equivalent of the side-effect import above +``` + +> **Critical (pure only):** if `Engine`/`Scene` (or any symbol) are used **only as +> types**, import them with `import type`. Importing them as values and silencing +> the unused-var lint with `void Engine;` makes the bundler emit +> `init_engine_pure()` / `init_scene_pure()` calls **without importing them**, +> which fails at runtime with `ReferenceError: init_engine_pure is not defined`. +> Keep genuine value imports (e.g. `ShadowGenerator` used with `instanceof`) in a +> separate, non-`type` import statement. + +Common compiled side-effect → pure registration pairs: + +| Feature | Compiled side-effect import | Pure registration | +| --- | --- | --- | +| `.babylon` file loading | `@babylonjs/core/Loading/Plugins/babylonFileLoader` | `RegisterBabylonFileLoader()` | +| StandardMaterial | `@babylonjs/core/Materials/standardMaterial` | `RegisterStandardMaterial()` | +| MultiMaterial | `@babylonjs/core/Materials/multiMaterial` | `RegisterMultiMaterial()` | +| Fresnel parameters | `@babylonjs/core/Materials/fresnelParameters` | `RegisterFresnelParameters()` | +| Loading screen | `@babylonjs/core/Loading/loadingScreen` | `RegisterLoadingScreen()` | +| Universal/Arc cameras | `@babylonjs/core/Cameras/universalCamera` (etc.) | `RegisterUniversalCamera()` / `RegisterArcRotateCamera()` | +| Lights (dir/point/spot/hemi) | imported transitively | `RegisterDirectionalLight()` / `RegisterPointLight()` / `RegisterSpotLight()` / `RegisterHemisphericLight()` | +| Dynamic texture | `@babylonjs/core/Engines/Extensions/engine.dynamicTexture` | `RegisterEnginesExtensionsEngineDynamicTexture()` | +| Cube texture / skybox | `@babylonjs/core/Engines/Extensions/engine.cubeTexture` | `RegisterAbstractEngineCubeTexture()` + `RegisterEnginesExtensionsEngineCubeTexture()` | +| Render target / shadow map | `@babylonjs/core/Engines/Extensions/engine.renderTarget` | `RegisterEnginesExtensionsEngineRenderTarget()` + `RegisterEnginesExtensionsEngineRenderTargetTexture()` + `RegisterRenderTargetTexture()` | +| Shadow generator | `@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent` + `import { ShadowGenerator }` | `RegisterShadowGeneratorSceneComponent(ShadowGenerator)` (also needs render-target + light regs above) | +| Mesh actions | `@babylonjs/core/Actions/directActions` + `directAudioActions` + `interpolateValueAction` | `RegisterDirectActions()` + `RegisterDirectAudioActions()` + `RegisterInterpolateValueAction()` | +| Depth renderer | `@babylonjs/core/Rendering/depthRendererSceneComponent` | `RegisterDepthRendererSceneComponent(DepthRenderer)` | +| Outline renderer | `@babylonjs/core/Rendering/outlineRenderer` | `RegisterOutlineRenderer()` | + +The shared `demoRunner.ts` (compiled and pure) already registers the common ones: +loading screen, standard/multi-material, fresnel, dynamic/read/cube texture, depth +renderer, outline, universal/arc cameras, and the four common light types. Only add +registrations specific to your demo (e.g. shadow-map render targets, actions) in +your own `scene.ts`. + +If a registration is missing in pure mode the symptom is usually a silent no-op +(textures never become ready, a scene component is a stub). When in doubt, search +`node_modules/@babylonjs/core/**/pure.d.ts` for the matching `Register*` export. + +## Assets + +- Keep asset URLs rooted at stable public paths. Legacy `.babylon` scenes and + textures live under `static/Scenes/<Name>/` and are served from `/Scenes/...`. +- Do not enable `engine.enableOfflineSupport`; it triggers `.manifest` requests + that fail the smoke test. The shared `demoRunner` already creates the engine + for you, so just don't turn offline support on. + +## Manifests + +Register the compiled demo in `src/compiledDemos/manifest.json` and the pure demo +in `src/pureCompiledDemos/manifest.json`: + +```json +{ + "slug": "<Slug>", + "title": "Babylon.js - <Name> demo", + "legacyPath": "static/Demos/<Slug>", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { "timeoutMs": 20000, "minimumColoredSamples": 120 } +} +``` + +- `sourceFiles` are the files shown on the generated `/Demos/<Slug>/source/` page. +- `renderCheck.timeoutMs` should be generous for asset-loading demos (30–60s). +- `minimumColoredSamples` is the blank-canvas guard; lower it for sparse scenes + (for example `Lines` uses 10). + +## Removing the legacy UMD demo + +Once the ES6 compiled + pure versions are verified, delete the legacy folder +`static/Demos/<Slug>/`. Do not leave a UMD copy behind — the website must not +ship any UMD demos. + +## Validate before you are done + +From the repo root: + +```bash +npm run demos:format:write # apply prettier +npm run build # site + compiled demos + pure demos +npm run demos:smoke # browser smoke: console/page/request errors +npm run demos:pure:smoke # same for /PureDemos/ +``` + +For full validation (typecheck + render/pixel checks) run `npm run demos:ci` and +`npm run demos:pure:ci`. The smoke test loads each demo in headless Chromium, +waits for `window.__babylonDemoReady`, and fails on any console error, page +error, or failed network request. A demo is not "done" until both smoke tests +pass with no scene-related console errors. + +## Checklist + +- [ ] No `BABYLON.*` globals, no UMD/CDN script tags anywhere. +- [ ] `src/compiledDemos/<Slug>/` added (index.html, main.ts, scene.ts). +- [ ] `src/pureCompiledDemos/<Slug>/` added, importing from `@babylonjs/core/pure`. +- [ ] Both manifests updated. +- [ ] Legacy `static/Demos/<Slug>/` deleted. +- [ ] `npm run build` succeeds. +- [ ] `npm run demos:smoke` and `npm run demos:pure:smoke` pass with no errors. diff --git a/docs/compiled-demos.md b/docs/compiled-demos.md index be1a6ac73..6f17b42ba 100644 --- a/docs/compiled-demos.md +++ b/docs/compiled-demos.md @@ -264,6 +264,12 @@ Each demo page should include a small source link at the bottom of the viewport: ## Adding A Demo +> Demos on the website must use the ES6 `@babylonjs/*` packages. UMD/CDN demos +> are not allowed and nothing new should be added to `static/Demos/`. Every demo +> is added in both compiled (`src/compiledDemos/`) and pure +> (`src/pureCompiledDemos/`) form. See [AGENTS.md](../AGENTS.md) for the full +> policy and the compiled→pure registration map. + 1. Create `src/compiledDemos/<Slug>/index.html`, `main.ts`, and `scene.ts`. 2. Export a scene factory from `scene.ts`: diff --git a/package-lock.json b/package-lock.json index 3fb074a90..7bbb61cf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,10 +15,14 @@ "devDependencies": { "@babylonjs/core": "^9.9.1", "@babylonjs/gui": "^9.9.1", + "@babylonjs/havok": "^1.3.12", "@babylonjs/inspector": "^9.9.1", "@babylonjs/loaders": "^9.9.1", "@babylonjs/materials": "^9.9.1", + "@babylonjs/procedural-textures": "^9.11.0", "@eslint/js": "^10.0.1", + "@types/earcut": "^3.0.0", + "earcut": "^3.0.2", "eslint": "^10.3.0", "globals": "^17.6.0", "playwright": "^1.59.1", @@ -257,6 +261,16 @@ "@types/react-dom": ">=16.0.9" } }, + "node_modules/@babylonjs/havok": { + "version": "1.3.12", + "resolved": "https://registry.npmjs.org/@babylonjs/havok/-/havok-1.3.12.tgz", + "integrity": "sha512-KR5Z7DBkVEgdvHLMDh2VWe/nHvUG8+MdLBiAE0iM19KIHAPqPRVITPAZKx4SQusK5nqm4ZXDcKv5OYtViIxLzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/emscripten": "^1.39.6" + } + }, "node_modules/@babylonjs/inspector": { "version": "9.9.1", "resolved": "https://registry.npmjs.org/@babylonjs/inspector/-/inspector-9.9.1.tgz", @@ -304,6 +318,16 @@ "@babylonjs/core": "^9.0.0" } }, + "node_modules/@babylonjs/procedural-textures": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@babylonjs/procedural-textures/-/procedural-textures-9.11.0.tgz", + "integrity": "sha512-fezdsmU6wfVTQ/r22h4D1wSFoGNk9aQt3m5liL+K6KaPEnPRdBZtEfRiaKURyMOQddoeHBDDyj4zpm1NVHmGpQ==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "@babylonjs/core": "^9.0.0" + } + }, "node_modules/@babylonjs/serializers": { "version": "9.5.2", "resolved": "https://registry.npmjs.org/@babylonjs/serializers/-/serializers-9.5.2.tgz", @@ -3114,6 +3138,20 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/earcut": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-k/9fOUGO39yd2sCjrbAJvGDEQvRwRnQIZlBz43roGwUZo5SHAmyVvSFyaVVZkicRVCaDXPKlbxrUcBuJoSWunQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/emscripten": { + "version": "1.41.5", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz", + "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -3825,6 +3863,13 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/earcut": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/package.json b/package.json index beb0ab29a..3dc8cad08 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,14 @@ "devDependencies": { "@babylonjs/core": "^9.9.1", "@babylonjs/gui": "^9.9.1", + "@babylonjs/havok": "^1.3.12", "@babylonjs/inspector": "^9.9.1", "@babylonjs/loaders": "^9.9.1", "@babylonjs/materials": "^9.9.1", + "@babylonjs/procedural-textures": "^9.11.0", "@eslint/js": "^10.0.1", + "@types/earcut": "^3.0.0", + "earcut": "^3.0.2", "eslint": "^10.3.0", "globals": "^17.6.0", "playwright": "^1.59.1", diff --git a/scripts/demos/check-smoke.mjs b/scripts/demos/check-smoke.mjs index 8d6d5dc79..fd95180d5 100644 --- a/scripts/demos/check-smoke.mjs +++ b/scripts/demos/check-smoke.mjs @@ -27,6 +27,8 @@ const contentTypes = new Map([ [".webp", "image/webp"], [".hdr", "application/octet-stream"], [".wasm", "application/wasm"], + [".mp4", "video/mp4"], + [".webm", "video/webm"], ]); function escapeAzureDevOpsMessage(message) { @@ -82,8 +84,33 @@ const server = http.createServer(async (request, response) => { } const body = await fs.readFile(filePath); + const contentType = contentTypes.get(path.extname(filePath).toLowerCase()) || "application/octet-stream"; + + // Support HTTP Range requests so that <video>/<audio> elements (which + // request partial content) load correctly instead of being aborted. + const rangeHeader = request.headers.range; + if (rangeHeader) { + const match = /^bytes=(\d*)-(\d*)$/.exec(rangeHeader); + if (match) { + const start = match[1] ? Number.parseInt(match[1], 10) : 0; + const end = match[2] ? Number.parseInt(match[2], 10) : body.length - 1; + if (start <= end && end < body.length) { + response.writeHead(206, { + "content-type": contentType, + "content-range": `bytes ${start}-${end}/${body.length}`, + "accept-ranges": "bytes", + "content-length": end - start + 1, + }); + response.end(body.subarray(start, end + 1)); + return; + } + } + } + response.writeHead(200, { - "content-type": contentTypes.get(path.extname(filePath).toLowerCase()) || "application/octet-stream", + "content-type": contentType, + "accept-ranges": "bytes", + "content-length": body.length, }); response.end(body); } catch { diff --git a/src/compiledDemos/Actions/index.html b/src/compiledDemos/Actions/index.html new file mode 100644 index 000000000..28ae0e5f4 --- /dev/null +++ b/src/compiledDemos/Actions/index.html @@ -0,0 +1,105 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Babylon.js - Actions demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Actions/main.ts b/src/compiledDemos/Actions/main.ts new file mode 100644 index 000000000..27888f4c1 --- /dev/null +++ b/src/compiledDemos/Actions/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createActionsScene } from "./scene"; + +runDemo({ createScene: createActionsScene }); diff --git a/src/compiledDemos/Actions/scene.ts b/src/compiledDemos/Actions/scene.ts new file mode 100644 index 000000000..9a80080c5 --- /dev/null +++ b/src/compiledDemos/Actions/scene.ts @@ -0,0 +1,212 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { CreateTorus } from "@babylonjs/core/Meshes/Builders/torusBuilder"; +import { ActionManager } from "@babylonjs/core/Actions/actionManager"; +import { InterpolateValueAction } from "@babylonjs/core/Actions/interpolateValueAction"; +import { + CombineAction, + DoNothingAction, + ExecuteCodeAction, + IncrementValueAction, + SetStateAction, + SetValueAction, +} from "@babylonjs/core/Actions/directActions"; +import { StateCondition } from "@babylonjs/core/Actions/condition"; +import { Scene } from "@babylonjs/core/scene"; +import type { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import type { Light } from "@babylonjs/core/Lights/light"; + +export function createActionsScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", 0, 0, 10, new Vector3(0, 0, 0), scene); + camera.setPosition(new Vector3(20, 200, 400)); + camera.attachControl(canvas, true); + + camera.lowerBetaLimit = 0.1; + camera.upperBetaLimit = (Math.PI / 2) * 0.99; + camera.lowerRadiusLimit = 150; + + scene.clearColor = new Color3(0, 0, 0).toColor4(1); + + const light1 = new PointLight("omni", new Vector3(0, 50, 0), scene); + const light2 = new PointLight("omni", new Vector3(0, 50, 0), scene); + const light3 = new PointLight("omni", new Vector3(0, 50, 0), scene); + + light1.diffuse = Color3.Red(); + light2.diffuse = Color3.Green(); + light3.diffuse = Color3.Blue(); + + light1.state = "on"; + light2.state = "on"; + light3.state = "on"; + + const ground = CreateGround("ground", { width: 1000, height: 1000, subdivisions: 1 }, scene); + const groundMaterial = new StandardMaterial("ground", scene); + groundMaterial.specularColor = Color3.Black(); + ground.material = groundMaterial; + + const redBox = CreateBox("red", { size: 20 }, scene); + const redMat = new StandardMaterial("ground", scene); + redMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + redMat.specularColor = new Color3(0.4, 0.4, 0.4); + redMat.emissiveColor = Color3.Red(); + redBox.material = redMat; + redBox.position.x -= 100; + + const greenBox = CreateBox("green", { size: 20 }, scene); + const greenMat = new StandardMaterial("ground", scene); + greenMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + greenMat.specularColor = new Color3(0.4, 0.4, 0.4); + greenMat.emissiveColor = Color3.Green(); + greenBox.material = greenMat; + greenBox.position.z -= 100; + + const blueBox = CreateBox("blue", { size: 20 }, scene); + const blueMat = new StandardMaterial("ground", scene); + blueMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + blueMat.specularColor = new Color3(0.4, 0.4, 0.4); + blueMat.emissiveColor = Color3.Blue(); + blueBox.material = blueMat; + blueBox.position.x += 100; + + const sphere = CreateSphere("sphere", { segments: 16, diameter: 20 }, scene); + const sphereMat = new StandardMaterial("ground", scene); + sphereMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + sphereMat.specularColor = new Color3(0.4, 0.4, 0.4); + sphereMat.emissiveColor = Color3.Purple(); + sphere.material = sphereMat; + sphere.position.z += 100; + + const donut = CreateTorus("donut", { diameter: 20, thickness: 8, tessellation: 16 }, scene); + + const prepareButton = (mesh: AbstractMesh, color: Color3, light: Light) => { + const goToColorAction = new InterpolateValueAction( + ActionManager.OnPickTrigger, + light, + "diffuse", + color, + 1000, + undefined, + true + ); + + mesh.actionManager = new ActionManager(scene); + mesh.actionManager + .registerAction( + new InterpolateValueAction(ActionManager.OnPickTrigger, light, "diffuse", Color3.Black(), 1000) + )! + .then( + new CombineAction(ActionManager.NothingTrigger, [ + goToColorAction, + new SetValueAction(ActionManager.NothingTrigger, mesh.material, "wireframe", false), + ]) + ); + mesh.actionManager + .registerAction(new SetValueAction(ActionManager.OnPickTrigger, mesh.material, "wireframe", true))! + .then(new DoNothingAction()); + mesh.actionManager + .registerAction(new SetStateAction(ActionManager.OnPickTrigger, light, "off"))! + .then(new SetStateAction(ActionManager.OnPickTrigger, light, "on")); + }; + + prepareButton(redBox, Color3.Red(), light1); + prepareButton(greenBox, Color3.Green(), light2); + prepareButton(blueBox, Color3.Blue(), light3); + + sphere.actionManager = new ActionManager(scene); + const sphereActionManager = sphere.actionManager as ActionManager; + const condition1 = new StateCondition(sphereActionManager, light1, "off"); + const condition2 = new StateCondition(sphereActionManager, light1, "on"); + + sphere.actionManager.registerAction( + new InterpolateValueAction(ActionManager.OnLeftPickTrigger, camera, "alpha", 0, 500, condition1) + ); + sphere.actionManager.registerAction( + new InterpolateValueAction(ActionManager.OnLeftPickTrigger, camera, "alpha", Math.PI, 500, condition2) + ); + + const makeOverOut = (mesh: AbstractMesh) => { + mesh.actionManager!.registerAction( + new SetValueAction( + ActionManager.OnPointerOutTrigger, + mesh.material, + "emissiveColor", + (mesh.material as StandardMaterial).emissiveColor + ) + ); + mesh.actionManager!.registerAction( + new SetValueAction(ActionManager.OnPointerOverTrigger, mesh.material, "emissiveColor", Color3.White()) + ); + mesh.actionManager!.registerAction( + new InterpolateValueAction(ActionManager.OnPointerOutTrigger, mesh, "scaling", new Vector3(1, 1, 1), 150) + ); + mesh.actionManager!.registerAction( + new InterpolateValueAction( + ActionManager.OnPointerOverTrigger, + mesh, + "scaling", + new Vector3(1.1, 1.1, 1.1), + 150 + ) + ); + }; + + makeOverOut(redBox); + makeOverOut(greenBox); + makeOverOut(blueBox); + makeOverOut(sphere); + + scene.actionManager = new ActionManager(scene); + + const rotate = (mesh: AbstractMesh) => { + scene.actionManager!.registerAction( + new IncrementValueAction(ActionManager.OnEveryFrameTrigger, mesh, "rotation.y", 0.01) + ); + }; + + rotate(redBox); + rotate(greenBox); + rotate(blueBox); + + donut.actionManager = new ActionManager(scene); + + donut.actionManager.registerAction( + new SetValueAction( + { trigger: ActionManager.OnIntersectionEnterTrigger, parameter: sphere }, + donut, + "scaling", + new Vector3(1.2, 1.2, 1.2) + ) + ); + donut.actionManager.registerAction( + new SetValueAction( + { trigger: ActionManager.OnIntersectionExitTrigger, parameter: sphere }, + donut, + "scaling", + new Vector3(1, 1, 1) + ) + ); + + scene.actionManager.registerAction( + new ExecuteCodeAction({ trigger: ActionManager.OnKeyUpTrigger, parameter: "r" }, () => { + camera.setPosition(new Vector3(20, 200, 400)); + }) + ); + + let alpha = 0; + scene.registerBeforeRender(() => { + donut.position.x = 100 * Math.cos(alpha); + donut.position.y = 5; + donut.position.z = 100 * Math.sin(alpha); + alpha += 0.01; + }); + + return scene; +} diff --git a/src/compiledDemos/Bones/index.html b/src/compiledDemos/Bones/index.html new file mode 100644 index 000000000..6e0a0c8e0 --- /dev/null +++ b/src/compiledDemos/Bones/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Bones demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Bones/main.ts b/src/compiledDemos/Bones/main.ts new file mode 100644 index 000000000..ee9aee712 --- /dev/null +++ b/src/compiledDemos/Bones/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createBonesScene } from "./scene"; + +runDemo({ createScene: createBonesScene }); diff --git a/src/compiledDemos/Bones/scene.ts b/src/compiledDemos/Bones/scene.ts new file mode 100644 index 000000000..5e2aee4ed --- /dev/null +++ b/src/compiledDemos/Bones/scene.ts @@ -0,0 +1,65 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import { ImportMeshAsync } from "@babylonjs/core/Loading/sceneLoader"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import "@babylonjs/core/Animations/animatable"; + +export async function createBonesScene(engine: Engine): Promise { + const scene = new Scene(engine); + const light = new DirectionalLight("dir01", new Vector3(0, -0.5, -1.0), scene); + const camera = new ArcRotateCamera("Camera", 0, 0, 10, new Vector3(0, 30, 0), scene); + camera.setPosition(new Vector3(20, 70, 120)); + light.position = new Vector3(20, 150, 70); + camera.minZ = 10.0; + + scene.ambientColor = new Color3(0.3, 0.3, 0.3); + + const ground = CreateGround("ground", { width: 1000, height: 1000, subdivisions: 1 }, scene); + const groundMaterial = new StandardMaterial("ground", scene); + groundMaterial.diffuseColor = new Color3(0.2, 0.2, 0.2); + groundMaterial.specularColor = new Color3(0, 0, 0); + ground.material = groundMaterial; + ground.receiveShadows = true; + + const shadowGenerator = new ShadowGenerator(1024, light); + + const rabbitResult = await ImportMeshAsync("/Scenes/Rabbit/Rabbit.babylon", scene, { meshNames: "Rabbit" }); + const rabbit = rabbitResult.meshes[1] as Mesh; + rabbit.scaling = new Vector3(0.4, 0.4, 0.4); + shadowGenerator.getShadowMap()!.renderList!.push(rabbit); + + const rabbit2 = rabbit.clone("rabbit2", null)!; + const rabbit3 = rabbit.clone("rabbit3", null)!; + shadowGenerator.getShadowMap()!.renderList!.push(rabbit2); + shadowGenerator.getShadowMap()!.renderList!.push(rabbit3); + + rabbit2.position = new Vector3(-50, 0, -20); + rabbit2.skeleton = rabbit.skeleton!.clone("clonedSkeleton"); + + rabbit3.position = new Vector3(50, 0, -20); + rabbit3.skeleton = rabbit.skeleton!.clone("clonedSkeleton2"); + + scene.beginAnimation(rabbitResult.skeletons[0], 0, 100, true, 0.8); + scene.beginAnimation(rabbit2.skeleton, 73, 100, true, 0.8); + scene.beginAnimation(rabbit3.skeleton, 0, 72, true, 0.8); + + const dudeResult = await ImportMeshAsync("/Scenes/Dude/Dude.babylon", scene, { meshNames: "him" }); + const dude = dudeResult.meshes[0] as Mesh; + for (const mesh of dudeResult.meshes) { + shadowGenerator.getShadowMap()!.renderList!.push(mesh); + } + dude.rotation.y = Math.PI; + dude.position = new Vector3(0, 0, -80); + scene.beginAnimation(dudeResult.skeletons[0], 0, 100, true, 1.0); + + return scene; +} diff --git a/src/compiledDemos/Charting/index.html b/src/compiledDemos/Charting/index.html new file mode 100644 index 000000000..a098e8e8a --- /dev/null +++ b/src/compiledDemos/Charting/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Charting demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Charting/main.ts b/src/compiledDemos/Charting/main.ts new file mode 100644 index 000000000..a1b2eab3f --- /dev/null +++ b/src/compiledDemos/Charting/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createChartingTestScene } from "./scene"; + +runDemo({ createScene: createChartingTestScene }); diff --git a/src/compiledDemos/Charting/scene.ts b/src/compiledDemos/Charting/scene.ts new file mode 100644 index 000000000..c63d9b769 --- /dev/null +++ b/src/compiledDemos/Charting/scene.ts @@ -0,0 +1,147 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { DynamicTexture } from "@babylonjs/core/Materials/Textures/dynamicTexture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Animation } from "@babylonjs/core/Animations/animation"; +import { CreatePlane } from "@babylonjs/core/Meshes/Builders/planeBuilder"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import "@babylonjs/core/Animations/animatable"; + +interface IChartSeries { + label: string; + value: number; + color: Color3; +} + +export function createChartingTestScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const light = new DirectionalLight("dir01", new Vector3(0, -0.5, 1.0), scene); + const camera = new ArcRotateCamera("Camera", 0, 0, 10, Vector3.Zero(), scene); + camera.setPosition(new Vector3(20, 70, -100)); + camera.attachControl(canvas, true); + light.position = new Vector3(0, 25, -50); + + const scale = 0.6; + + const browsersSeries: IChartSeries[] = [ + { label: "IE", value: 32, color: new Color3(0, 0, 1) }, + { label: "Chrome", value: 28, color: new Color3(1, 0, 0) }, + { label: "Firefox", value: 16, color: new Color3(1, 0, 1) }, + { label: "Opera", value: 14, color: new Color3(1, 1, 0) }, + { label: "Safari", value: 10, color: new Color3(0, 1, 1) }, + ]; + + const playgroundSize = 100; + + // Background + const background = CreatePlane("background", { size: playgroundSize }, scene); + const backgroundMaterial = new StandardMaterial("background", scene); + background.material = backgroundMaterial; + background.scaling.y = 0.5; + background.position.z = playgroundSize / 2 - 0.5; + background.position.y = playgroundSize / 4; + background.receiveShadows = true; + const backgroundTexture = new DynamicTexture("dynamic texture", 512, scene, true); + backgroundMaterial.diffuseTexture = backgroundTexture; + backgroundMaterial.specularColor = new Color3(0, 0, 0); + backgroundMaterial.backFaceCulling = false; + + backgroundTexture.drawText("Eternalcoding", null, 80, "bold 70px Segoe UI", "white", "#555555"); + backgroundTexture.drawText("- browsers statistics -", null, 250, "35px Segoe UI", "white", null); + + // Ground + const ground = CreateGround("ground", { width: playgroundSize, height: playgroundSize, subdivisions: 1 }, scene); + const groundMaterial = new StandardMaterial("ground", scene); + groundMaterial.diffuseColor = new Color3(0.5, 0.5, 0.5); + groundMaterial.specularColor = new Color3(0, 0, 0); + ground.material = groundMaterial; + ground.receiveShadows = true; + ground.position.y = -0.1; + + const shadowGenerator = new ShadowGenerator(1024, light); + shadowGenerator.usePoissonSampling = true; + + const createSeries = function (series: IChartSeries[]) { + const margin = 2; + const offset = playgroundSize / series.length - margin; + let x = -playgroundSize / 2 + offset / 2; + + for (let index = 0; index < series.length; index++) { + const data = series[index]; + + const bar = CreateBox(data.label, { size: 1.0 }, scene); + bar.scaling = new Vector3(offset / 2.0, 0, offset / 2.0); + bar.position.x = x; + bar.position.y = 0; + + let animation = new Animation("anim", "scaling", 30, Animation.ANIMATIONTYPE_VECTOR3); + animation.setKeys([ + { frame: 0, value: new Vector3(offset / 2.0, 0, offset / 2.0) }, + { frame: 100, value: new Vector3(offset / 2.0, data.value * scale, offset / 2.0) }, + ]); + bar.animations.push(animation); + + animation = new Animation("anim2", "position.y", 30, Animation.ANIMATIONTYPE_FLOAT); + animation.setKeys([ + { frame: 0, value: 0 }, + { frame: 100, value: (data.value * scale) / 2 }, + ]); + bar.animations.push(animation); + scene.beginAnimation(bar, 0, 100, false, 2.0); + + const barMaterial = new StandardMaterial(data.label + "mat", scene); + barMaterial.diffuseColor = data.color; + barMaterial.emissiveColor = data.color.scale(0.3); + barMaterial.specularColor = new Color3(0, 0, 0); + bar.material = barMaterial; + + shadowGenerator.getShadowMap()!.renderList!.push(bar); + + const barLegend = CreateGround( + data.label + "Legend", + { width: playgroundSize / 2, height: offset * 2, subdivisions: 1 }, + scene + ); + barLegend.position.x = x; + barLegend.position.z = -playgroundSize / 4; + barLegend.rotation.y = Math.PI / 2; + + const barLegendMaterial = new StandardMaterial(data.label + "LegendMat", scene); + const barLegendTexture = new DynamicTexture("dynamic texture", 512, scene, true); + barLegendTexture.hasAlpha = true; + barLegendMaterial.diffuseTexture = barLegendTexture; + barLegendMaterial.emissiveColor = new Color3(0.4, 0.4, 0.4); + barLegend.material = barLegendMaterial; + + const size = barLegendTexture.getSize(); + barLegendTexture.drawText( + data.label + " (" + data.value + "%)", + 80, + size.height / 2 + 30, + "bold 50px Segoe UI", + "white", + "transparent" + ); + + x += offset + margin; + } + }; + + createSeries(browsersSeries); + + camera.lowerAlphaLimit = Math.PI; + camera.upperAlphaLimit = 2 * Math.PI; + camera.lowerBetaLimit = 0.1; + camera.upperBetaLimit = (Math.PI / 2) * 0.99; + camera.lowerRadiusLimit = 5; + camera.upperRadiusLimit = 150; + + return scene; +} diff --git a/src/compiledDemos/Dancers/index.html b/src/compiledDemos/Dancers/index.html new file mode 100644 index 000000000..e550101cb --- /dev/null +++ b/src/compiledDemos/Dancers/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Dancers demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Dancers/main.ts b/src/compiledDemos/Dancers/main.ts new file mode 100644 index 000000000..324193675 --- /dev/null +++ b/src/compiledDemos/Dancers/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createDancersScene } from "./scene"; + +runDemo({ createScene: createDancersScene }); diff --git a/src/compiledDemos/Dancers/scene.ts b/src/compiledDemos/Dancers/scene.ts new file mode 100644 index 000000000..a63e869a2 --- /dev/null +++ b/src/compiledDemos/Dancers/scene.ts @@ -0,0 +1,55 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { MirrorTexture } from "@babylonjs/core/Materials/Textures/mirrorTexture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Plane } from "@babylonjs/core/Maths/math.plane"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Animations/animatable"; +import "@babylonjs/core/Engines/Extensions/engine.renderTarget"; +import "@babylonjs/core/Engines/Extensions/engine.renderTargetTexture"; + +export function createDancersScene(engine: Engine, canvas: HTMLCanvasElement): Promise { + return LoadSceneAsync("/Scenes/DanceMoves/DanceMoves.babylon", engine).then((scene) => { + scene.activeCamera!.maxZ = 10000.0; + (scene.activeCamera as { position: { z: number } }).position.z = 600.0; + + // Mirror ground + const groundMaterial = new StandardMaterial("ground", scene); + const mirror = new MirrorTexture("mirror", 1024, scene, true); + mirror.mirrorPlane = new Plane(0, -1.0, 0, 0); + mirror.level = 0.5; + groundMaterial.reflectionTexture = mirror; + groundMaterial.diffuseColor = new Color3(1.0, 1.0, 1.0); + groundMaterial.specularColor = new Color3(0, 0, 0); + + const ground = CreateGround("ground", { width: 1000, height: 1000, subdivisions: 1 }, scene); + ground.material = groundMaterial; + + const dancer = scene.meshes[1] as Mesh; + mirror.renderList!.push(dancer); + scene.beginAnimation(dancer.skeleton!, 2, 100, true, 0.05); + + // Clone a handful of dancers (replaces the legacy FPS-driven cloning + dat.GUI) + let total = 1; + for (let i = 0; i < 8; i++) { + const newOne = dancer.clone("clone" + total, null) as Mesh; + newOne.skeleton = dancer.skeleton!.clone("skeleton" + total); + newOne.material!.freeze(); + newOne.position.x = 250 - Math.random() * 500; + newOne.position.z = 250 - Math.random() * 500; + mirror.renderList!.push(newOne); + scene.beginAnimation(newOne.skeleton, 2, 100, true, 0.05); + total++; + } + + scene.executeWhenReady(function () { + scene.activeCamera!.attachControl(canvas); + }); + + return scene; + }); +} diff --git a/src/compiledDemos/DragNDrop/index.html b/src/compiledDemos/DragNDrop/index.html new file mode 100644 index 000000000..1fa8ecff9 --- /dev/null +++ b/src/compiledDemos/DragNDrop/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Drag and Drop demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/DragNDrop/main.ts b/src/compiledDemos/DragNDrop/main.ts new file mode 100644 index 000000000..2b3c615cd --- /dev/null +++ b/src/compiledDemos/DragNDrop/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createDragDropTestScene } from "./scene"; + +runDemo({ createScene: createDragDropTestScene }); diff --git a/src/compiledDemos/DragNDrop/scene.ts b/src/compiledDemos/DragNDrop/scene.ts new file mode 100644 index 000000000..f15213aff --- /dev/null +++ b/src/compiledDemos/DragNDrop/scene.ts @@ -0,0 +1,136 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreateTorus } from "@babylonjs/core/Meshes/Builders/torusBuilder"; +import type { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import { Scene } from "@babylonjs/core/scene"; + +export function createDragDropTestScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", 0, 0, 10, new Vector3(0, 0, 0), scene); + camera.setPosition(new Vector3(20, 200, 400)); + camera.attachControl(canvas, true); + + camera.lowerBetaLimit = 0.1; + camera.upperBetaLimit = (Math.PI / 2) * 0.99; + camera.lowerRadiusLimit = 150; + + scene.clearColor = new Color3(0, 0, 0).toColor4(1); + + new PointLight("omni", new Vector3(0, 50, 0), scene); + + // Ground + const ground = CreateGround("ground", { width: 1000, height: 1000, subdivisions: 1 }, scene); + const groundMaterial = new StandardMaterial("ground", scene); + groundMaterial.specularColor = Color3.Black(); + ground.material = groundMaterial; + + // Meshes + const redSphere = CreateSphere("red", { segments: 32, diameter: 20 }, scene); + const redMat = new StandardMaterial("red", scene); + redMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + redMat.specularColor = new Color3(0.4, 0.4, 0.4); + redMat.emissiveColor = Color3.Red(); + redSphere.material = redMat; + redSphere.position.y = 10; + redSphere.position.x -= 100; + + const greenBox = CreateBox("green", { size: 20 }, scene); + const greenMat = new StandardMaterial("green", scene); + greenMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + greenMat.specularColor = new Color3(0.4, 0.4, 0.4); + greenMat.emissiveColor = Color3.Green(); + greenBox.material = greenMat; + greenBox.position.z -= 100; + greenBox.position.y = 10; + + const blueBox = CreateBox("blue", { size: 20 }, scene); + const blueMat = new StandardMaterial("blue", scene); + blueMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + blueMat.specularColor = new Color3(0.4, 0.4, 0.4); + blueMat.emissiveColor = Color3.Blue(); + blueBox.material = blueMat; + blueBox.position.x += 100; + blueBox.position.y = 10; + + const purpleDonut = CreateTorus("purple", { diameter: 30, thickness: 10, tessellation: 32 }, scene); + const purpleMat = new StandardMaterial("purple", scene); + purpleMat.diffuseColor = new Color3(0.4, 0.4, 0.4); + purpleMat.specularColor = new Color3(0.4, 0.4, 0.4); + purpleMat.emissiveColor = Color3.Purple(); + purpleDonut.material = purpleMat; + purpleDonut.position.y = 10; + purpleDonut.position.z += 100; + + // Drag & drop events + let startingPoint: Vector3 | null; + let currentMesh: AbstractMesh; + + const getGroundPosition = () => { + const pickinfo = scene.pick(scene.pointerX, scene.pointerY, (mesh) => mesh === ground); + if (pickinfo.hit) { + return pickinfo.pickedPoint; + } + return null; + }; + + const onPointerDown = (evt: PointerEvent) => { + if (evt.button !== 0) { + return; + } + + const pickInfo = scene.pick(scene.pointerX, scene.pointerY, (mesh) => mesh !== ground); + if (pickInfo.hit && pickInfo.pickedMesh) { + currentMesh = pickInfo.pickedMesh; + startingPoint = getGroundPosition(); + + if (startingPoint) { + setTimeout(() => { + camera.detachControl(); + }, 0); + } + } + }; + + const onPointerUp = () => { + if (startingPoint) { + camera.attachControl(canvas, true); + startingPoint = null; + return; + } + }; + + const onPointerMove = () => { + if (!startingPoint) { + return; + } + + const current = getGroundPosition(); + if (!current) { + return; + } + + const diff = current.subtract(startingPoint); + currentMesh.position.addInPlace(diff); + + startingPoint = current; + }; + + canvas.addEventListener("pointerdown", onPointerDown, false); + canvas.addEventListener("pointerup", onPointerUp, false); + canvas.addEventListener("pointermove", onPointerMove, false); + + scene.onDispose = () => { + canvas.removeEventListener("pointerdown", onPointerDown); + canvas.removeEventListener("pointerup", onPointerUp); + canvas.removeEventListener("pointermove", onPointerMove); + }; + + return scene; +} diff --git a/src/compiledDemos/Espilit/index.html b/src/compiledDemos/Espilit/index.html new file mode 100644 index 000000000..495cd55b3 --- /dev/null +++ b/src/compiledDemos/Espilit/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Espilit demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Espilit/main.ts b/src/compiledDemos/Espilit/main.ts new file mode 100644 index 000000000..e210efef7 --- /dev/null +++ b/src/compiledDemos/Espilit/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createEspilitScene } from "./scene"; + +runDemo({ createScene: createEspilitScene }); diff --git a/src/compiledDemos/Espilit/scene.ts b/src/compiledDemos/Espilit/scene.ts new file mode 100644 index 000000000..a843b0809 --- /dev/null +++ b/src/compiledDemos/Espilit/scene.ts @@ -0,0 +1,33 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { RefractionPostProcess } from "@babylonjs/core/PostProcesses/refractionPostProcess"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; +import "@babylonjs/core/Culling/Octrees/octreeSceneComponent"; + +export async function createEspilitScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Espilit/Espilit.binary.babylon", engine); + scene.collisionsEnabled = true; + scene.autoClear = true; + scene.createOrUpdateSelectionOctree(); + const sol = scene.getMeshByName("Sol loin") as Mesh | null; + if (sol) { + sol.useVertexColors = false; + } + scene.gravity.scaleInPlace(0.5); + if (scene.cameras.length > 1) { + new RefractionPostProcess( + "Refraction", + "/Scenes/customs/refMap.jpg", + new Color3(1.0, 1.0, 1.0), + 0.5, + 0.5, + 1.0, + scene.cameras[1] + ); + } + return scene; +} diff --git a/src/compiledDemos/ExtrudePolygon/index.html b/src/compiledDemos/ExtrudePolygon/index.html new file mode 100644 index 000000000..3fef2ae85 --- /dev/null +++ b/src/compiledDemos/ExtrudePolygon/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Extrude Polygon demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/ExtrudePolygon/main.ts b/src/compiledDemos/ExtrudePolygon/main.ts new file mode 100644 index 000000000..24b9fe035 --- /dev/null +++ b/src/compiledDemos/ExtrudePolygon/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createExtrudePolygonScene } from "./scene"; + +runDemo({ createScene: createExtrudePolygonScene }); diff --git a/src/compiledDemos/ExtrudePolygon/scene.ts b/src/compiledDemos/ExtrudePolygon/scene.ts new file mode 100644 index 000000000..535b55c03 --- /dev/null +++ b/src/compiledDemos/ExtrudePolygon/scene.ts @@ -0,0 +1,758 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Color3, Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3, Vector4 } from "@babylonjs/core/Maths/math.vector"; +import { ExtrudePolygon } from "@babylonjs/core/Meshes/Builders/polygonBuilder"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { Scene } from "@babylonjs/core/scene"; +import earcut from "earcut"; + +export function createExtrudePolygonScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + + const extrudePolygon = ( + name: string, + options: { shape: Vector3[]; holes?: Vector3[][]; depth?: number; faceUV?: Vector4[]; faceColors?: Color4[] }, + scn: Scene + ) => ExtrudePolygon(name, options, scn, earcut); + + // camera + var camera = new ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 3, 25, new Vector3(0, 0, 4.5), scene); + camera.attachControl(canvas, true); + + var light = new HemisphericLight("hemiLight", new Vector3(10, 10, 0), scene); + + var wallmat = new StandardMaterial("wallmaterial", scene); + wallmat.diffuseTexture = new Texture("/Scenes/Customs/Ground.jpg", scene); + + var innerwallmat = new StandardMaterial("innerwallmaterial", scene); + innerwallmat.diffuseColor = new Color3(240 / 255, 223 / 255, 203 / 255); + + //Polygon shape in XoZ plane + var frontWallData = [ + new Vector3(-5.5, 0, -3), + new Vector3(-0.5, 0, -3), + new Vector3(-0.5, 0, -0.75), + new Vector3(0.5, 0, -0.75), + new Vector3(0.5, 0, -3), + new Vector3(5.5, 0, -3), + new Vector3(5.5, 0, 3), + new Vector3(-5.5, 0, 3), + ]; + + //Holes in XoZ plane + var frontWindowHoles = []; + frontWindowHoles[0] = [ + new Vector3(-4.78, 0, -2.3), + new Vector3(-1.58, 0, -2.3), + new Vector3(-1.58, 0, -0.3), + new Vector3(-4.78, 0, -0.3), + ]; + frontWindowHoles[1] = [ + new Vector3(1.58, 0, -2.3), + new Vector3(4.78, 0, -2.3), + new Vector3(4.78, 0, -0.3), + new Vector3(1.58, 0, -0.3), + ]; + frontWindowHoles[2] = [ + new Vector3(-4.03, 0, 0.75), + new Vector3(-2.13, 0, 0.75), + new Vector3(-2.13, 0, 2.55), + new Vector3(-4.03, 0, 2.55), + ]; + frontWindowHoles[3] = [ + new Vector3(-0.65, 0, 0.75), + new Vector3(0.65, 0, 0.75), + new Vector3(0.65, 0, 2.55), + new Vector3(-0.65, 0, 2.55), + ]; + frontWindowHoles[4] = [ + new Vector3(2.13, 0, 0.75), + new Vector3(4.03, 0, 0.75), + new Vector3(4.03, 0, 2.55), + new Vector3(2.13, 0, 2.55), + ]; + + var faceUV = new Array(3); + + faceUV[0] = new Vector4(0, 0, 7 / 15, 1); + faceUV[1] = new Vector4(14 / 15, 0, 1, 1); + faceUV[2] = new Vector4(7 / 15, 0, 14 / 15, 1); + + var frontWall = extrudePolygon( + "wall", + { shape: frontWallData, depth: 0.15, holes: frontWindowHoles, faceUV: faceUV }, + scene + ); + frontWall.rotation.x = -Math.PI / 2; + + frontWall.material = wallmat; + + var rearWallnb1Data = [ + new Vector3(1.4, 0, -3), + new Vector3(5.5, 0, -3), + new Vector3(5.5, 0, 3), + new Vector3(1.4, 0, 3), + ]; + + //Holes in XoZ plane + var rear1WindowHoles = []; + rear1WindowHoles[0] = [ + new Vector3(3.7, 0, -1.8), + new Vector3(4.5, 0, -1.8), + new Vector3(4.5, 0, -0.3), + new Vector3(3.7, 0, -0.3), + ]; + rear1WindowHoles[1] = [ + new Vector3(1.9, 0, 0.75), + new Vector3(2.7, 0, 0.75), + new Vector3(2.7, 0, 2.55), + new Vector3(1.9, 0, 2.55), + ]; + rear1WindowHoles[2] = [ + new Vector3(4.2, 0, 0.75), + new Vector3(5, 0, 0.75), + new Vector3(5, 0, 2.55), + new Vector3(4.2, 0, 2.55), + ]; + + var rearFaceUV = []; + rearFaceUV[0] = new Vector4(7 / 15, 0, 14 / 15, 1); + rearFaceUV[1] = new Vector4(14 / 15, 0, 1, 1); + rearFaceUV[2] = new Vector4(0, 0, 7 / 15, 1); + + var rearWallnb1 = extrudePolygon( + "rearWallnb1", + { shape: rearWallnb1Data, depth: 0.1, holes: rear1WindowHoles, faceUV: rearFaceUV }, + scene + ); + rearWallnb1.rotation.x = -Math.PI / 2; + rearWallnb1.position.z = 6.15; + + rearWallnb1.material = wallmat; + + var rearWallnb2Data = [ + new Vector3(-5.6, 0, -3), + new Vector3(1.45, 0, -3), + new Vector3(1.45, 0, 3), + new Vector3(-2.075, 0, 5.5), + new Vector3(-5.6, 0, 3), + ]; + + var rear2WindowHoles = []; + rear2WindowHoles[0] = [ + new Vector3(-5, 0, -1.8), + new Vector3(-1.85, 0, -1.8), + new Vector3(-1.85, 0, -0.3), + new Vector3(-5, 0, -0.3), + ]; + rear2WindowHoles[1] = [ + new Vector3(-0.8, 0, -1.8), + new Vector3(0.9, 0, -1.8), + new Vector3(0.9, 0, -0.3), + new Vector3(-0.8, 0, -0.3), + ]; + rear2WindowHoles[2] = [ + new Vector3(-5, 0, 0.75), + new Vector3(-1.85, 0, 0.75), + new Vector3(-1.85, 0, 2.55), + new Vector3(-5, 0, 2.55), + ]; + rear2WindowHoles[3] = [ + new Vector3(-0.6, 0, 1.75), + new Vector3(0.7, 0, 1.75), + new Vector3(0.7, 0, 2.55), + new Vector3(-0.6, 0, 2.55), + ]; + + var rearWallnb2 = extrudePolygon( + "rearWallnb2", + { shape: rearWallnb2Data, holes: rear2WindowHoles, depth: 0.1, faceUV: rearFaceUV }, + scene + ); + rearWallnb2.rotation.x = -Math.PI / 2; + rearWallnb2.position.z = 9.15; + + rearWallnb2.material = wallmat; + + var sideWallnb1Data = [ + new Vector3(-3.15, 0, -3), + new Vector3(3.1, 0, -3), + new Vector3(3.1, 0, 3), + new Vector3(0, 0, 5.5), + new Vector3(-3.15, 0, 3), + ]; + + var side1FaceUV = new Array(3); + + side1FaceUV[0] = new Vector4(0, 0, 7 / 15, 1); + side1FaceUV[1] = new Vector4(14 / 15, 0, 1, 1); + side1FaceUV[2] = new Vector4(7 / 15, 0, 14 / 15, 1); + + var sideWallnb1 = extrudePolygon("sideWallnb1", { shape: sideWallnb1Data, depth: 0.1, faceUV: side1FaceUV }, scene); + sideWallnb1.rotation.z = -Math.PI / 2; + sideWallnb1.rotation.x = -Math.PI / 2; + sideWallnb1.position.x = 5.6; + sideWallnb1.position.z = 3.15; + + sideWallnb1.material = wallmat; + + var sideWallnb2Data = [ + new Vector3(-3.15, 0, -3), + new Vector3(6, 0, -3), + new Vector3(6, 0, 3), + new Vector3(3.1, 0, 3), + new Vector3(0, 0, 5.5), + new Vector3(-3.15, 0, 3), + ]; + + var side2FaceUV = new Array(3); + + side2FaceUV[0] = new Vector4(7 / 15, 0, 14 / 15, 1); + side2FaceUV[1] = new Vector4(14 / 15, 0, 1, 1); + side2FaceUV[2] = new Vector4(0, 0, 7 / 15, 1); + + var sideWallnb2 = extrudePolygon("sideWallnb2", { shape: sideWallnb2Data, depth: 0.1, faceUV: side2FaceUV }, scene); + sideWallnb2.rotation.z = -Math.PI / 2; + sideWallnb2.rotation.x = -Math.PI / 2; + sideWallnb2.position.x = -5.5; + sideWallnb2.position.z = 3.15; + + sideWallnb2.material = wallmat; + + var sideWallnb3Data = [ + new Vector3(3.1, 0, -3), + new Vector3(4.5, 0, -3), + new Vector3(4.5, 0, -0.75), + new Vector3(5.5, 0, -0.75), + new Vector3(5.5, 0, -3), + new Vector3(6, 0, -3), + new Vector3(6, 0, 3), + new Vector3(3.1, 0, 3), + ]; + + var side3FaceUV = new Array(3); + + side3FaceUV[0] = new Vector4(0, 0, 7 / 15, 1); + side3FaceUV[1] = new Vector4(14 / 15, 0, 1, 1); + side3FaceUV[2] = new Vector4(7 / 15, 0, 14 / 15, 1); + + var sideWallnb3 = extrudePolygon("sideWallnb3", { shape: sideWallnb3Data, depth: 0.1, faceUV: side3FaceUV }, scene); + sideWallnb3.rotation.z = -Math.PI / 2; + sideWallnb3.rotation.x = -Math.PI / 2; + sideWallnb3.position.x = 1.45; + sideWallnb3.position.z = 3.15; + + sideWallnb3.material = wallmat; + + var roofmat = new StandardMaterial("roofmat", scene); + roofmat.diffuseTexture = new Texture("/Scenes/Customs/Ground.jpg", scene); + + var roof1Data = [ + new Vector3(-0.05, 0, 0), + new Vector3(0.1, 0, 0), + new Vector3(3.3, 0, 2.65), + new Vector3(6.5, 0, 0), + new Vector3(6.6, 0, 0), + new Vector3(3.3, 0, 2.8), + ]; + + var roof1 = extrudePolygon("roof1", { shape: roof1Data, depth: 11.5 }, scene); + roof1.rotation.z = -Math.PI / 2; + roof1.rotation.x = -Math.PI / 2; + roof1.position.x = 5.7; + roof1.position.y = 2.9; + roof1.position.z = -0.15; + + roof1.material = roofmat; + + var roof2Data = [ + new Vector3(0, 0, 0), + new Vector3(0.142, 0, 0), + new Vector3(3.834, 0, 2.6), + new Vector3(7.476, 0, 0), + new Vector3(7.618, 0, 0), + new Vector3(3.834, 0, 2.7), + ]; + + var roof2 = extrudePolygon("roof2", { shape: roof2Data, depth: 3.2 }, scene); + roof2.rotation.x = -Math.PI / 2; + roof2.position.x = -5.9; + roof2.position.y = 2.9; + roof2.position.z = 6.3; + + roof2.material = roofmat; + + var roof3Data = [ + new Vector3(0.3, 0, 0.2), + new Vector3(0.442, 0, 0.2), + new Vector3(3.834, 0, 2.6), + new Vector3(7.476, 0, 0), + new Vector3(7.618, 0, 0), + new Vector3(3.834, 0, 2.7), + ]; + + var roof3 = extrudePolygon("roof3", { shape: roof3Data, depth: 3.2 }, scene); + roof3.rotation.x = -Math.PI / 2; + roof3.position.x = -5.9; + roof3.position.y = 2.9; + roof3.position.z = 3.1; + + roof3.material = roofmat; + + var roof = Mesh.MergeMeshes([roof1, roof2, roof3], true); + + var stairsDepth = 2; + var stairsHeight = 3.0; + var stairsThickness = 0.05; + var nBStairs = 12; + var stairs = []; + var x = 0; + var z = 0; + //up + stairs.push(new Vector3(x, 0, z)); + z += stairsHeight / nBStairs - stairsThickness; + stairs.push(new Vector3(x, 0, z)); + for (var i = 0; i < nBStairs; i++) { + x += stairsDepth / nBStairs; + stairs.push(new Vector3(x, 0, z)); + z += stairsHeight / nBStairs; + stairs.push(new Vector3(x, 0, z)); + } + x += stairsDepth / nBStairs - stairsThickness; + stairs.push(new Vector3(x, 0, z)); + + //down + for (var i = 0; i <= nBStairs; i++) { + x -= stairsDepth / nBStairs; + stairs.push(new Vector3(x, 0, z)); + z -= stairsHeight / nBStairs; + stairs.push(new Vector3(x, 0, z)); + } + const faceColors = []; + faceColors[0] = new Color4(0, 0, 0, 1); + faceColors[1] = new Color4(190 / 255, 139 / 255, 94 / 255, 1); + faceColors[2] = new Color4(0, 0, 0, 1); + + var stairsWidth = 1.0; + var stairCase = extrudePolygon("stairs", { shape: stairs, depth: stairsWidth, faceColors: faceColors }, scene); + stairCase.position.x = 1.37; + stairCase.position.y = -3.0; + stairCase.position.z = 2.51; + stairCase.rotation.x = -Math.PI / 2; + stairCase.rotation.y = -Math.PI / 2; + + var floormat = new StandardMaterial("floormaterial", scene); + floormat.diffuseTexture = new Texture("/Scenes/Customs/Ground.jpg", scene); + + var floorData = [ + new Vector3(-5.5, 0, 0), + new Vector3(5.5, 0, 0), + new Vector3(5.5, 0, 6), + new Vector3(1.345, 0, 6), + new Vector3(1.345, 0, 9), + new Vector3(-5.5, 0, 9), + ]; + + var stairSpace = []; + stairSpace[0] = [ + new Vector3(0.27, 0, 2.5), + new Vector3(0.27, 0, 4.5), + new Vector3(1.37, 0, 4.5), + new Vector3(1.37, 0, 2.5), + ]; + + var floorFaceUV = new Array(3); + + floorFaceUV[0] = new Vector4(0, 0, 0.5, 1); + floorFaceUV[2] = new Vector4(0.5, 0, 1, 1); + + var floor = extrudePolygon( + "floor", + { shape: floorData, holes: stairSpace, depth: 0.1, faceUV: floorFaceUV }, + scene + ); + floor.position.y = 0.21; + floor.position.z = 0.15; + + floor.material = floormat; + + var groundFloorData = [ + new Vector3(-5.6, 0, -0.1), + new Vector3(5.6, 0, -0.1), + new Vector3(5.6, 0, 6.1), + new Vector3(1.36, 0, 6.1), + new Vector3(1.36, 0, 9.1), + new Vector3(-5.6, 0, 9.1), + ]; + + var groundFloorFaceUV = new Array(3); + + groundFloorFaceUV[0] = new Vector4(0, 0, 0.5, 1); + groundFloorFaceUV[2] = new Vector4(0.5, 0, 1, 1); + + var groundFloor = extrudePolygon( + "groundFloor", + { shape: groundFloorData, depth: 0.04, faceUV: groundFloorFaceUV }, + scene + ); + groundFloor.position.y = -3; + groundFloor.position.z = 0.15; + groundFloor.material = floormat; + + var ceilingData = [ + new Vector3(-5.5, 0, 0), + new Vector3(5.5, 0, 0), + new Vector3(5.5, 0, 6), + new Vector3(1.345, 0, 6), + new Vector3(1.345, 0, 9), + new Vector3(-5.5, 0, 9), + ]; + + var ceiling = extrudePolygon("ceiling", { shape: ceilingData, depth: 0.1 }, scene); + ceiling.position.y = 2.8; + ceiling.position.z = 0.15; + + ceiling.material = innerwallmat; + + var innerWallnb1Data = [ + new Vector3(-3, 0, 0.6), + new Vector3(-3, 0, 0), + new Vector3(3, 0, 0), + new Vector3(3, 0, 6.1), + new Vector3(-3, 0, 6.1), + new Vector3(-3, 0, 1.6), + new Vector3(-1, 0, 1.6), + new Vector3(-1, 0, 0.6), + ]; + + var doorSpace1 = []; + doorSpace1[0] = [ + new Vector3(0.1, 0, 1.6), + new Vector3(0.1, 0, 0.6), + new Vector3(2, 0, 0.6), + new Vector3(2, 0, 1.6), + ]; + + var innerWallnb1 = extrudePolygon( + "innerWallnb1", + { shape: innerWallnb1Data, holes: doorSpace1, depth: 0.1 }, + scene + ); + innerWallnb1.rotation.z = Math.PI / 2; + innerWallnb1.position.x = 1.35; + innerWallnb1.position.z = 0.15; + + innerWallnb1.material = innerwallmat; + + var innerWallnb2Data = [ + new Vector3(-3, 0, 0), + new Vector3(3, 0, 0), + new Vector3(3, 0, 9), + new Vector3(-3, 0, 9), + new Vector3(-3, 0, 7.6), + new Vector3(-1, 0, 7.6), + new Vector3(-1, 0, 6.6), + new Vector3(-3, 0, 6.6), + new Vector3(-3, 0, 1.6), + new Vector3(-1, 0, 1.6), + new Vector3(-1, 0, 0.6), + new Vector3(-3, 0, 0.6), + ]; + + var doorSpace2 = []; + doorSpace2[0] = [ + new Vector3(0.1, 0, 0.6), + new Vector3(2, 0, 0.6), + new Vector3(2, 0, 1.6), + new Vector3(0.1, 0, 1.6), + ]; + doorSpace2[1] = [ + new Vector3(0.1, 0, 4.6), + new Vector3(2, 0, 4.6), + new Vector3(2, 0, 5.6), + new Vector3(0.1, 0, 5.6), + ]; + + var innerWallnb2 = extrudePolygon( + "innerWallnb2", + { shape: innerWallnb2Data, holes: doorSpace2, depth: 0.1 }, + scene + ); + innerWallnb2.rotation.z = Math.PI / 2; + innerWallnb2.position.x = 1.35; + innerWallnb2.position.z = 0.15; + innerWallnb2.position.x = -1.4; + + innerWallnb2.material = innerwallmat; + + var bathroomWallData = [ + new Vector3(-1.4, 0, 0), + new Vector3(-0.5, 0, 0), + new Vector3(-0.5, 0, 2), + new Vector3(0.5, 0, 2), + new Vector3(0.5, 0, 0), + new Vector3(1.4, 0, 0), + new Vector3(1.4, 0, 6), + new Vector3(-1.4, 0, 6), + ]; + + var doorSpace3 = []; + doorSpace3[0] = [ + new Vector3(-0.5, 0, 3.2), + new Vector3(-0.5, 0, 5.2), + new Vector3(0.5, 0, 5.2), + new Vector3(0.5, 0, 3.2), + ]; + + var bathroomWall = extrudePolygon( + "bathroomWall", + { shape: bathroomWallData, depth: 0.1, holes: doorSpace3 }, + scene + ); + bathroomWall.rotation.x = -Math.PI / 2; + bathroomWall.position.y = -3; + bathroomWall.position.z = 6; + + bathroomWall.material = innerwallmat; + + var bedroom1WallData = [ + new Vector3(-5.5, 0, 0), + new Vector3(-2.9, 0, 0), + new Vector3(-2.9, 0, 2), + new Vector3(-1.9, 0, 2), + new Vector3(-1.9, 0, 0), + new Vector3(-1.4, 0, 0), + new Vector3(-1.4, 0, 6), + new Vector3(-5.5, 0, 6), + ]; + + var bedroom1Wall = extrudePolygon("bedroom1Wall", { shape: bedroom1WallData, depth: 0.1 }, scene); + bedroom1Wall.rotation.x = -Math.PI / 2; + bedroom1Wall.position.y = -3; + bedroom1Wall.position.z = 4.5; + + bedroom1Wall.material = innerwallmat; + + var bannisterWallData = [ + new Vector3(0, 0, 0), + new Vector3(1, 0, 0), + new Vector3(1, 0, 1.4), + new Vector3(1.75, 0, 1.4), + new Vector3(1.75, 0, 0), + new Vector3(3.5, 0, 0), + new Vector3(3.5, 0, 3.2), + new Vector3(1.5, 0, 3.2), + new Vector3(0, 0, 0.75), + ]; + var spindleThickness = 0.05; + var spindles = 12; + var railGap = (1.5 - spindles * spindleThickness) / (spindles - 1); + var rail = []; + var ac = spindleThickness; + for (var s = 0; s < spindles - 1; s++) { + rail[s] = []; + rail[s].push(new Vector3(ac, 0, 0.1 + 1.6 * ac)); + rail[s].push(new Vector3(ac, 0, 0.75 - spindleThickness + 1.6 * ac)); + rail[s].push(new Vector3(ac + railGap, 0, 0.75 - spindleThickness + 1.6 * (ac + railGap))); + rail[s].push(new Vector3(ac + railGap, 0, 1.6 * (ac + railGap))); + ac += spindleThickness + railGap; + } + + var bannisterWall = extrudePolygon("bannisterWall", { shape: bannisterWallData, holes: rail, depth: 0.1 }, scene); + bannisterWall.rotation.x = -Math.PI / 2; + bannisterWall.rotation.z = -Math.PI / 2; + bannisterWall.position.x = 0.4; + bannisterWall.position.y = -3; + bannisterWall.position.z = 2.51; + + var bannister1Data = [new Vector3(0, 0, 0), new Vector3(2, 0, 0), new Vector3(2, 0, 0.75), new Vector3(0, 0, 0.75)]; + var spindle1Thickness = 0.05; + var spindles1 = 12; + var rail1Gap = (2 - spindles1 * spindle1Thickness) / (spindles1 - 1); + var rail1 = []; + var ac1 = spindle1Thickness; + for (var s = 0; s < spindles1 - 1; s++) { + rail1[s] = []; + rail1[s].push(new Vector3(ac1, 0, spindle1Thickness)); + rail1[s].push(new Vector3(ac1, 0, 0.75 - spindle1Thickness)); + rail1[s].push(new Vector3(ac1 + rail1Gap, 0, 0.75 - spindle1Thickness)); + rail1[s].push(new Vector3(ac1 + rail1Gap, 0, spindle1Thickness)); + ac1 += spindle1Thickness + rail1Gap; + } + + var bannister1 = extrudePolygon("bannister1", { shape: bannister1Data, holes: rail1, depth: 0.1 }, scene); + bannister1.rotation.x = -Math.PI / 2; + bannister1.rotation.z = -Math.PI / 2; + bannister1.position.x = 0.3; + bannister1.position.y = 0.2; + bannister1.position.z = 2.61; + + var bannister2Data = [new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0.75), new Vector3(0, 0, 0.75)]; + var spindle2Thickness = 0.05; + var spindles2 = 6; + var rail2Gap = (1 - spindles2 * spindle2Thickness) / (spindles2 - 1); + var rail2 = []; + var ac2 = spindle2Thickness; + for (var s = 0; s < spindles2 - 1; s++) { + rail2[s] = []; + rail2[s].push(new Vector3(ac2, 0, spindle2Thickness)); + rail2[s].push(new Vector3(ac2, 0, 0.75 - spindle2Thickness)); + rail2[s].push(new Vector3(ac2 + rail2Gap, 0, 0.75 - spindle2Thickness)); + rail2[s].push(new Vector3(ac2 + rail2Gap, 0, spindle2Thickness)); + ac2 += spindle2Thickness + rail2Gap; + } + + var bannister2 = extrudePolygon("bannister2", { shape: bannister2Data, holes: rail2, depth: 0.1 }, scene); + bannister2.rotation.x = -Math.PI / 2; + bannister2.position.x = 0.3; + bannister2.position.y = 0.2; + bannister2.position.z = 2.61; + + var windowMaker = function (width, height, frames, frameDepth, frameThickness) { + var windowShape = [ + new Vector3(0, 0, 0), + new Vector3(width, 0, 0), + new Vector3(width, 0, height), + new Vector3(0, 0, height), + ]; + var glassWidth = (width - (frames + 1) * frameThickness) / frames; + var glassTopHeight = height / 3 - frameThickness; + var glassBotHeight = 2 * glassTopHeight; + var glass = []; + var acf = frameThickness; + for (var f = 0; f < frames; f++) { + glass[2 * f] = []; + glass[2 * f].push(new Vector3(acf, 0, 2 * frameThickness + glassBotHeight)); + glass[2 * f].push(new Vector3(acf + glassWidth, 0, 2 * frameThickness + glassBotHeight)); + glass[2 * f].push(new Vector3(acf + glassWidth, 0, 2 * frameThickness + glassBotHeight + glassTopHeight)); + glass[2 * f].push(new Vector3(acf, 0, 2 * frameThickness + glassBotHeight + glassTopHeight)); + glass[2 * f + 1] = []; + glass[2 * f + 1].push(new Vector3(acf, 0, frameThickness)); + glass[2 * f + 1].push(new Vector3(acf + glassWidth, 0, frameThickness)); + glass[2 * f + 1].push(new Vector3(acf + glassWidth, 0, frameThickness + glassBotHeight)); + glass[2 * f + 1].push(new Vector3(acf, 0, frameThickness + glassBotHeight)); + acf += frameThickness + glassWidth; + } + var window = extrudePolygon("window", { shape: windowShape, holes: glass, depth: frameDepth }, scene); + window.rotation.x = -Math.PI / 2; + return window; + }; + + var windowFBL = windowMaker(3.2, 2, 4, 0.15, 0.1); + windowFBL.position.x = -4.78; + windowFBL.position.y = -2.3; + windowFBL.position.z = 0.1; + + var windowFBR = windowMaker(3.2, 2, 4, 0.15, 0.1); + windowFBR.position.x = 1.58; + windowFBR.position.y = -2.3; + windowFBR.position.z = 0.1; + + var windowFTL = windowMaker(1.9, 1.8, 2, 0.15, 0.1); + windowFTL.position.x = -4.03; + windowFTL.position.y = 0.75; + windowFTL.position.z = 0.1; + + var windowFTR = windowMaker(1.9, 1.8, 2, 0.15, 0.1); + windowFTR.position.x = 2.13; + windowFTR.position.y = 0.75; + windowFTR.position.z = 0.1; + + var windowFTM = windowMaker(1.3, 1.8, 2, 0.15, 0.1); + windowFTM.position.x = -0.65; + windowFTM.position.y = 0.75; + windowFTM.position.z = 0.1; + + var windowRBL = windowMaker(3.15, 1.5, 4, 0.15, 0.1); + windowRBL.position.x = -5; + windowRBL.position.y = -1.8; + windowRBL.position.z = 9; + + var windowRBR = windowMaker(1.7, 1.5, 2, 0.15, 0.1); + windowRBR.position.x = -0.8; + windowRBR.position.y = -1.8; + windowRBR.position.z = 9; + + var windowRTL = windowMaker(3.15, 1.8, 4, 0.15, 0.1); + windowRTL.position.x = -5; + windowRTL.position.y = 0.75; + windowRTL.position.z = 9; + + var windowRTR = windowMaker(1.3, 0.8, 1, 0.15, 0.1); + windowRTR.position.x = -0.6; + windowRTR.position.y = 1.75; + windowRTR.position.z = 9; + + var windowR1BL = windowMaker(0.8, 1.5, 1, 0.15, 0.1); + windowR1BL.position.x = 3.7; + windowR1BL.position.y = -1.8; + windowR1BL.position.z = 6; + + var windowR1TL = windowMaker(0.8, 1.8, 1, 0.15, 0.1); + windowR1TL.position.x = 1.9; + windowR1TL.position.y = 0.75; + windowR1TL.position.z = 6; + + var windowR1TR = windowMaker(0.8, 1.8, 1, 0.15, 0.1); + windowR1TR.position.x = 4.2; + windowR1TR.position.y = 0.75; + windowR1TR.position.z = 6; + + var doorMaker = function (width, height, depth) { + var doorShape = [ + new Vector3(0, 0, 0), + new Vector3(width, 0, 0), + new Vector3(width, 0, height), + new Vector3(0, 0, height), + ]; + const edgeThickness = width / 8; + var panelWidth = width - 2 * edgeThickness; + var panelBotHeight = (height - 3 * edgeThickness) / 1.75; + var panelTopHeight = 0.75 * panelBotHeight; + var panel = []; + panel[0] = []; + panel[0].push(new Vector3(edgeThickness, 0, 2 * edgeThickness + panelBotHeight)); + panel[0].push(new Vector3(edgeThickness + panelWidth, 0, 2 * edgeThickness + panelBotHeight)); + panel[0].push(new Vector3(edgeThickness + panelWidth, 0, 2 * edgeThickness + panelBotHeight + panelTopHeight)); + panel[0].push(new Vector3(edgeThickness, 0, 2 * edgeThickness + panelBotHeight + panelTopHeight)); + panel[1] = []; + panel[1].push(new Vector3(edgeThickness, 0, edgeThickness)); + panel[1].push(new Vector3(edgeThickness + panelWidth, 0, edgeThickness)); + panel[1].push(new Vector3(edgeThickness + panelWidth, 0, edgeThickness + panelBotHeight)); + panel[1].push(new Vector3(edgeThickness, 0, edgeThickness + panelBotHeight)); + var door = extrudePolygon("door", { shape: doorShape, holes: panel, depth: depth }, scene); + door.rotation.x = -Math.PI / 2; + var panelB = CreateBox("p1b", { width: panelWidth, height: panelBotHeight, depth: depth / 2 }, scene); + panelB.position.x = edgeThickness + panelWidth / 2; + panelB.position.y = edgeThickness + panelBotHeight / 2; + panelB.position.z = depth / 2; + var panelT = CreateBox("p1t", { width: panelWidth, height: panelTopHeight, depth: depth / 2 }, scene); + panelT.position.x = edgeThickness + panelWidth / 2; + panelT.position.y = 2 * edgeThickness + panelBotHeight + panelTopHeight / 2; + panelT.position.z = depth / 2; + + return Mesh.MergeMeshes([door, panelB, panelT], true); + }; + + var doormat = new StandardMaterial("door", scene); + doormat.diffuseColor = new Color3(82 / 255, 172 / 255, 106 / 255); + + var frontDoor = doorMaker(1, 2.25, 0.1); + frontDoor.position.x = -0.5; + frontDoor.position.y = -3; + frontDoor.position.z = 0.1; + frontDoor.material = doormat; + + var backDoor = doorMaker(1, 2.25, 0.1); + backDoor.rotation.y = Math.PI / 2; + backDoor.position.x = 1.3; + backDoor.position.y = -3; + backDoor.position.z = 8.65; + backDoor.material = doormat; + return scene; +} diff --git a/src/compiledDemos/Facets/index.html b/src/compiledDemos/Facets/index.html new file mode 100644 index 000000000..1f3ee4a27 --- /dev/null +++ b/src/compiledDemos/Facets/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Facets demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Facets/main.ts b/src/compiledDemos/Facets/main.ts new file mode 100644 index 000000000..7895e8452 --- /dev/null +++ b/src/compiledDemos/Facets/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createFacetsScene } from "./scene"; + +runDemo({ createScene: createFacetsScene }); diff --git a/src/compiledDemos/Facets/scene.ts b/src/compiledDemos/Facets/scene.ts new file mode 100644 index 000000000..d4573d49d --- /dev/null +++ b/src/compiledDemos/Facets/scene.ts @@ -0,0 +1,156 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateTorusKnot } from "@babylonjs/core/Meshes/Builders/torusKnotBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; +import type { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; + +export function createFacetsScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + scene.clearColor = new Color3(0.15, 0.15, 0.3).toColor4(1); + + const camera = new ArcRotateCamera("Camera", 0, 0, 0, Vector3.Zero(), scene); + camera.attachControl(canvas, true); + camera.setPosition(new Vector3(0, 10.0, -150.0)); + + const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene); + light.intensity = 0.2; + const pl = new PointLight("pl", camera.position, scene); + pl.intensity = 0.9; + + new StandardMaterial("sm", scene); + + const gravity = new Vector3(0, -0.01, 0); + const ballOrigin = new Vector3(-20.0, 60.0, 0.0); + const restitution = 0.6; + const speed = 0.05; + const sceneLimit = ballOrigin.y + 2.0; + + const model1 = CreateTorusKnot("m1", { radius: 8.0, tube: 1.2, radialSegments: 48 }, scene); + const posfunc = (p: SolidParticle): void => { + p.position.x = ((0.5 - Math.random()) * sceneLimit) / 1.5; + p.position.y = (0.5 - Math.random()) * sceneLimit; + p.position.z = ((0.5 - Math.random()) * sceneLimit) / 1.5; + p.rotation.x = 3.2 * Math.random(); + p.rotation.y = 3.2 * Math.random(); + p.rotation.z = 3.2 * Math.random(); + p.scaling.x = 0.5 + Math.random() * 0.5; + p.scaling.y = p.scaling.x; + p.scaling.z = p.scaling.x; + }; + const meshSPS = new SolidParticleSystem("m", scene, { updatable: false }); + meshSPS.addShape(model1, 30, { positionFunction: posfunc }); + meshSPS.buildMesh(); + model1.dispose(); + + meshSPS.refreshVisibleSize(); + const mesh = meshSPS.mesh; + mesh.partitioningSubdivisions = 40; + mesh.updateFacetData(); + + const ballRadius = 1.0; + const ballNb = 2000; + const radiusSquared = ballRadius * ballRadius; + const ball = CreateSphere("b", { diameter: ballRadius * 2.0, segments: 3 }, scene); + const sps = new SolidParticleSystem("sps", scene); + sps.addShape(ball, ballNb); + ball.dispose(); + sps.buildMesh(); + sps.isAlwaysVisible = true; + sps.computeParticleRotation = false; + sps.computeParticleTexture = false; + + sps.recycleParticle = function (p: SolidParticle): SolidParticle { + p.position.copyFrom(this.vars.origin); + p.velocity.x = (Math.random() - 0.5) * this.vars.speed * 3.0 + this.vars.speed * 3.0; + p.velocity.z = (Math.random() - 0.5) * this.vars.speed * 6.0; + p.velocity.y = Math.random() * this.vars.speed * 10.0; + p.scaling.x = 1.0; + p.scaling.y = p.scaling.x; + p.scaling.z = p.scaling.x; + return p; + }; + sps.initParticles = function (): void { + for (let p = 0; p < this.nbParticles; p++) { + this.recycleParticle(sps.particles[p]); + this.particles[p].color!.r = 0.4 + Math.random() * 0.6; + this.particles[p].color!.g = 0.4 + Math.random() * 0.6; + this.particles[p].color!.b = 0.4 + Math.random() * 0.6; + this.particles[p].rotation.x = Math.random() * 3.2; + this.particles[p].rotation.y = Math.random() * 3.2; + this.particles[p].rotation.z = Math.random() * 3.2; + } + }; + + const projected = Vector3.Zero(); + const facetNorm = Vector3.Zero(); + const normPos = Vector3.Zero(); + const tmpVect = Vector3.Zero(); + + sps.updateParticle = function (p: SolidParticle): SolidParticle { + if ( + Math.abs(p.position.x) > sceneLimit || + Math.abs(p.position.y) > sceneLimit || + Math.abs(p.position.z) > sceneLimit + ) { + sps.recycleParticle(p); + return p; + } + + p.velocity.addInPlace(gravity); + p.position.addInPlace(p.velocity); + + const closest = mesh.getClosestFacetAtCoordinates( + p.position.x, + p.position.y, + p.position.z, + projected, + true, + true + ); + if (closest !== null) { + mesh.getFacetNormalToRef(closest, facetNorm); + + p.position.subtractToRef(projected, tmpVect); + + if (tmpVect.lengthSquared() < radiusSquared) { + const tmpDotVel = Vector3.Dot(p.velocity, facetNorm); + p.velocity.x = (p.velocity.x - 2.0 * tmpDotVel * facetNorm.x) * restitution; + p.velocity.y = (p.velocity.y - 2.0 * tmpDotVel * facetNorm.y) * restitution; + p.velocity.z = (p.velocity.z - 2.0 * tmpDotVel * facetNorm.z) * restitution; + + facetNorm.scaleToRef(ballRadius * 1.01, normPos); + projected.addToRef(normPos, p.position); + } + } + p.scaling.x = 0.4 + Math.abs(p.velocity.x); + p.scaling.y = 0.4 + Math.abs(p.velocity.y); + p.scaling.z = 0.4 + Math.abs(p.velocity.z); + return p; + }; + + sps.vars.origin = ballOrigin.clone(); + sps.vars.speed = speed; + sps.initParticles(); + sps.setParticles(); + + let k = 0.0; + scene.registerBeforeRender(() => { + mesh.rotation.y += 0.01; + mesh.rotation.x = 0.6 * Math.sin(k); + sps.setParticles(); + k += 0.02; + }); + + scene.onDisposeObservable.add(() => { + mesh.disableFacetData(); + }); + + return scene; +} diff --git a/src/compiledDemos/Flat2009/index.html b/src/compiledDemos/Flat2009/index.html new file mode 100644 index 000000000..d5bbc8358 --- /dev/null +++ b/src/compiledDemos/Flat2009/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Flat 2009 demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Flat2009/main.ts b/src/compiledDemos/Flat2009/main.ts new file mode 100644 index 000000000..76ab70a79 --- /dev/null +++ b/src/compiledDemos/Flat2009/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createFlat2009Scene } from "./scene"; + +runDemo({ createScene: createFlat2009Scene }); diff --git a/src/compiledDemos/Flat2009/scene.ts b/src/compiledDemos/Flat2009/scene.ts new file mode 100644 index 000000000..823314110 --- /dev/null +++ b/src/compiledDemos/Flat2009/scene.ts @@ -0,0 +1,31 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import type { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { VideoTexture } from "@babylonjs/core/Materials/Textures/videoTexture"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Materials/Textures/mirrorTexture"; +import "@babylonjs/core/Particles/particleSystemComponent"; +import "@babylonjs/core/Culling/Octrees/octreeSceneComponent"; + +export async function createFlat2009Scene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Flat2009/Flat2009.babylon", engine); + scene.collisionsEnabled = true; + + const ecran = scene.getMeshByName("Ecran") as Mesh | null; + if (ecran && ecran.material) { + (ecran.material as StandardMaterial).diffuseTexture = new VideoTexture( + "video", + ["/Scenes/Flat2009/babylonjs.mp4", "/Scenes/Flat2009/babylonjs.webm"], + scene, + true, + true + ); + } + + scene.createOrUpdateSelectionOctree(); + scene.gravity.scaleInPlace(0.5); + + return scene; +} diff --git a/src/compiledDemos/GlowingEspilit/index.html b/src/compiledDemos/GlowingEspilit/index.html new file mode 100644 index 000000000..c854c6a1d --- /dev/null +++ b/src/compiledDemos/GlowingEspilit/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Glowing Espilit demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/GlowingEspilit/main.ts b/src/compiledDemos/GlowingEspilit/main.ts new file mode 100644 index 000000000..9cbb21a0e --- /dev/null +++ b/src/compiledDemos/GlowingEspilit/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createGlowingEspilitScene } from "./scene"; + +runDemo({ createScene: createGlowingEspilitScene }); diff --git a/src/compiledDemos/GlowingEspilit/scene.ts b/src/compiledDemos/GlowingEspilit/scene.ts new file mode 100644 index 000000000..291366d4b --- /dev/null +++ b/src/compiledDemos/GlowingEspilit/scene.ts @@ -0,0 +1,38 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import type { SubMesh } from "@babylonjs/core/Meshes/subMesh"; +import type { Material } from "@babylonjs/core/Materials/material"; +import type { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { GlowLayer } from "@babylonjs/core/Layers/glowLayer"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createGlowingEspilitScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Espilit/Espilit.binary.babylon", engine); + scene.collisionsEnabled = true; + scene.autoClear = true; + + const solLoin = scene.getMeshByName("Sol loin") as Mesh | null; + if (solLoin) { + solLoin.useVertexColors = false; + } + scene.gravity.scaleInPlace(0.5); + + const glow = new GlowLayer("glow", scene, { mainTextureSamples: 4 }); + glow.customEmissiveColorSelector = (mesh: Mesh, _subMesh: SubMesh, _material: Material, result: Color4): void => { + if (mesh.name === "Bandes lum") { + result.set(1, 1, 1, 1); + } else { + result.set(0, 0, 0, 0); + } + }; + + const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene); + light.intensity = 0.7; + + return scene; +} diff --git a/src/compiledDemos/Heart/index.html b/src/compiledDemos/Heart/index.html new file mode 100644 index 000000000..9bc6fdbbf --- /dev/null +++ b/src/compiledDemos/Heart/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Heart demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Heart/main.ts b/src/compiledDemos/Heart/main.ts new file mode 100644 index 000000000..ab9059ae7 --- /dev/null +++ b/src/compiledDemos/Heart/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createHeartScene } from "./scene"; + +runDemo({ createScene: createHeartScene }); diff --git a/src/compiledDemos/Heart/scene.ts b/src/compiledDemos/Heart/scene.ts new file mode 100644 index 000000000..5642e3f2a --- /dev/null +++ b/src/compiledDemos/Heart/scene.ts @@ -0,0 +1,18 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createHeartScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Heart/Heart.babylon", engine); + scene.collisionsEnabled = true; + scene.getMeshByName("Labels")?.setEnabled(false); + const lums = scene.getMeshByName("lums") as Mesh | null; + if (lums) { + lums.useVertexColors = false; + } + scene.gravity.scaleInPlace(0.5); + return scene; +} diff --git a/src/compiledDemos/HillValley/index.html b/src/compiledDemos/HillValley/index.html new file mode 100644 index 000000000..19b7fd9cb --- /dev/null +++ b/src/compiledDemos/HillValley/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - HillValley demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/HillValley/main.ts b/src/compiledDemos/HillValley/main.ts new file mode 100644 index 000000000..82c636553 --- /dev/null +++ b/src/compiledDemos/HillValley/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createHillValleyScene } from "./scene"; + +runDemo({ createScene: createHillValleyScene }); diff --git a/src/compiledDemos/HillValley/scene.ts b/src/compiledDemos/HillValley/scene.ts new file mode 100644 index 000000000..c3ac027d4 --- /dev/null +++ b/src/compiledDemos/HillValley/scene.ts @@ -0,0 +1,23 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { FreeCamera } from "@babylonjs/core/Cameras/freeCamera"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { SceneLoaderFlags } from "@babylonjs/core/Loading/sceneLoaderFlags"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; +import "@babylonjs/core/Culling/Octrees/octreeSceneComponent"; + +export async function createHillValleyScene(engine: Engine): Promise { + SceneLoaderFlags.ForceFullSceneLoadingForIncremental = true; + const scene = await LoadSceneAsync("/Scenes/hillvalley/HillValley.incremental.babylon", engine); + scene.collisionsEnabled = false; + scene.lightsEnabled = false; + if (scene.activeCamera) { + (scene.activeCamera as FreeCamera).applyGravity = true; + } + scene.createOrUpdateSelectionOctree(); + for (const material of scene.materials) { + material.checkReadyOnEveryCall = false; + } + return scene; +} diff --git a/src/compiledDemos/InstancedBones/index.html b/src/compiledDemos/InstancedBones/index.html new file mode 100644 index 000000000..df584b601 --- /dev/null +++ b/src/compiledDemos/InstancedBones/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Instanced Bones demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/InstancedBones/main.ts b/src/compiledDemos/InstancedBones/main.ts new file mode 100644 index 000000000..d5ff32511 --- /dev/null +++ b/src/compiledDemos/InstancedBones/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createBones2TestScene } from "./scene"; + +runDemo({ createScene: createBones2TestScene }); diff --git a/src/compiledDemos/InstancedBones/scene.ts b/src/compiledDemos/InstancedBones/scene.ts new file mode 100644 index 000000000..abfaf401f --- /dev/null +++ b/src/compiledDemos/InstancedBones/scene.ts @@ -0,0 +1,73 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import { ImportMeshAsync } from "@babylonjs/core/Loading/sceneLoader"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import "@babylonjs/core/Meshes/instancedMesh"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import "@babylonjs/core/Animations/animatable"; + +export async function createBones2TestScene(engine: Engine): Promise { + const scene = new Scene(engine); + const light = new DirectionalLight("dir01", new Vector3(0, -0.5, -1.0), scene); + const camera = new ArcRotateCamera("Camera", 0, 0, 10, new Vector3(0, 30, 0), scene); + camera.setPosition(new Vector3(20, 70, 120)); + light.position = new Vector3(50, 250, 200); + light.shadowOrthoScale = 2.0; + camera.minZ = 1.0; + + scene.ambientColor = new Color3(0.3, 0.3, 0.3); + + // Ground + const ground = CreateGround("ground", { width: 1000, height: 1000, subdivisions: 1 }, scene); + const groundMaterial = new StandardMaterial("ground", scene); + groundMaterial.diffuseColor = new Color3(0.2, 0.2, 0.2); + groundMaterial.specularColor = new Color3(0, 0, 0); + ground.material = groundMaterial; + ground.receiveShadows = true; + + // Shadows + const shadowGenerator = new ShadowGenerator(1024, light); + shadowGenerator.useBlurExponentialShadowMap = true; + + // Dude + const result = await ImportMeshAsync("/Scenes/Dude/Dude.babylon", scene, { meshNames: "him" }); + const newMeshes = result.meshes; + const dude = newMeshes[0] as Mesh; + + for (let index = 1; index < newMeshes.length; index++) { + shadowGenerator.getShadowMap()!.renderList!.push(newMeshes[index]); + } + + for (let count = 0; count < 50; count++) { + const offsetX = 200 * Math.random() - 100; + const offsetZ = 200 * Math.random() - 100; + for (let index = 1; index < newMeshes.length; index++) { + const instance = (newMeshes[index] as Mesh).createInstance("instance" + count); + + shadowGenerator.getShadowMap()!.renderList!.push(instance); + + instance.parent = newMeshes[index].parent; + instance.position = newMeshes[index].position.clone(); + + if (!(instance.parent as Mesh).subMeshes) { + instance.position.x += offsetX; + instance.position.z -= offsetZ; + } + } + } + + dude.rotation.y = Math.PI; + dude.position = new Vector3(0, 0, -80); + + scene.beginAnimation(result.skeletons[0], 0, 100, true, 1.0); + + return scene; +} diff --git a/src/compiledDemos/Instances/index.html b/src/compiledDemos/Instances/index.html new file mode 100644 index 000000000..76ccb09fb --- /dev/null +++ b/src/compiledDemos/Instances/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Instances demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Instances/main.ts b/src/compiledDemos/Instances/main.ts new file mode 100644 index 000000000..cc2e27d66 --- /dev/null +++ b/src/compiledDemos/Instances/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createInstancesScene } from "./scene"; + +runDemo({ createScene: createInstancesScene }); diff --git a/src/compiledDemos/Instances/scene.ts b/src/compiledDemos/Instances/scene.ts new file mode 100644 index 000000000..5b6a2be30 --- /dev/null +++ b/src/compiledDemos/Instances/scene.ts @@ -0,0 +1,129 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { CubeTexture } from "@babylonjs/core/Materials/Textures/cubeTexture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Axis, Space } from "@babylonjs/core/Maths/math.axis"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreateGroundFromHeightMap } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import type { GroundMesh } from "@babylonjs/core/Meshes/groundMesh"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { ImportMeshAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export function createInstancesScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const light = new DirectionalLight("dir01", new Vector3(0, -1, -0.3), scene); + const camera = new FreeCamera("Camera", new Vector3(0, 10, -20), scene); + camera.speed = 0.4; + + light.position = new Vector3(20, 60, 30); + + scene.ambientColor = Color3.FromInts(10, 30, 10); + scene.clearColor = Color3.FromInts(127, 165, 13).toColor4(1); + scene.gravity = new Vector3(0, -0.5, 0); + + scene.fogMode = Scene.FOGMODE_EXP; + scene.fogDensity = 0.02; + scene.fogColor = new Color3(scene.clearColor.r, scene.clearColor.g, scene.clearColor.b); + + const skybox = CreateBox("skyBox", { size: 150.0 }, scene); + const skyboxMaterial = new StandardMaterial("skyBox", scene); + skyboxMaterial.backFaceCulling = false; + skyboxMaterial.reflectionTexture = new CubeTexture("/Scenes/Customs/skybox/TropicalSunnyDay", scene); + skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE; + skyboxMaterial.diffuseColor = new Color3(0, 0, 0); + skyboxMaterial.specularColor = new Color3(0, 0, 0); + skyboxMaterial.disableLighting = true; + skybox.material = skyboxMaterial; + skybox.infiniteDistance = true; + + const makeBorder = (name: string, scaling: Vector3, position: Partial<{ x: number; z: number }>): void => { + const border = CreateBox(name, { size: 1 }, scene); + border.scaling = scaling; + if (position.x !== undefined) { + border.position.x = position.x; + } + if (position.z !== undefined) { + border.position.z = position.z; + } + border.checkCollisions = true; + border.isVisible = false; + }; + makeBorder("border0", new Vector3(1, 100, 100), { x: -50.0 }); + makeBorder("border1", new Vector3(1, 100, 100), { x: 50.0 }); + makeBorder("border2", new Vector3(100, 100, 1), { z: 50.0 }); + makeBorder("border3", new Vector3(100, 100, 1), { z: -50.0 }); + + const ground = CreateGroundFromHeightMap( + "ground", + "/Scenes/Customs/heightMap.png", + { + width: 100, + height: 100, + subdivisions: 100, + minHeight: 0, + maxHeight: 5, + updatable: false, + onReady: (groundMesh: GroundMesh) => { + groundMesh.optimize(100); + + const shadowGenerator = new ShadowGenerator(1024, light); + + void ImportMeshAsync("/Scenes/Tree/tree.babylon", scene).then((result) => { + const tree = result.meshes[0] as Mesh; + const treeMaterial = tree.material as StandardMaterial | null; + if (treeMaterial) { + treeMaterial.opacityTexture = null; + treeMaterial.backFaceCulling = false; + } + tree.isVisible = false; + tree.position.y = groundMesh.getHeightAtCoordinates(0, 0); + + shadowGenerator.getShadowMap()!.renderList!.push(tree); + const range = 60; + const count = 100; + for (let index = 0; index < count; index++) { + const newInstance = tree.createInstance("i" + index); + const x = range / 2 - Math.random() * range; + const z = range / 2 - Math.random() * range; + const y = groundMesh.getHeightAtCoordinates(x, z); + newInstance.position = new Vector3(x, y, z); + newInstance.rotate(Axis.Y, Math.random() * Math.PI * 2, Space.WORLD); + const scale = 0.5 + Math.random() * 2; + newInstance.scaling.addInPlace(new Vector3(scale, scale, scale)); + shadowGenerator.getShadowMap()!.renderList!.push(newInstance); + } + shadowGenerator.getShadowMap()!.refreshRate = 0; + shadowGenerator.usePoissonSampling = true; + + camera.checkCollisions = true; + camera.applyGravity = true; + }); + }, + }, + scene + ); + + const groundMaterial = new StandardMaterial("ground", scene); + const groundTexture = new Texture("/Scenes/Customs/Ground.jpg", scene); + groundMaterial.diffuseTexture = groundTexture; + groundTexture.uScale = 6; + groundTexture.vScale = 6; + groundMaterial.specularColor = new Color3(0, 0, 0); + groundMaterial.emissiveColor = new Color3(0.3, 0.3, 0.3); + ground.material = groundMaterial; + ground.receiveShadows = true; + ground.checkCollisions = true; + + camera.attachControl(canvas, true); + + return scene; +} diff --git a/src/compiledDemos/Instances2/index.html b/src/compiledDemos/Instances2/index.html new file mode 100644 index 000000000..f13508a2f --- /dev/null +++ b/src/compiledDemos/Instances2/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Instances 2 demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Instances2/main.ts b/src/compiledDemos/Instances2/main.ts new file mode 100644 index 000000000..7a6a2d4e2 --- /dev/null +++ b/src/compiledDemos/Instances2/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createInstancesTestScene } from "./scene"; + +runDemo({ createScene: createInstancesTestScene }); diff --git a/src/compiledDemos/Instances2/scene.ts b/src/compiledDemos/Instances2/scene.ts new file mode 100644 index 000000000..64018042b --- /dev/null +++ b/src/compiledDemos/Instances2/scene.ts @@ -0,0 +1,153 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { CubeTexture } from "@babylonjs/core/Materials/Textures/cubeTexture"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Axis, Space } from "@babylonjs/core/Maths/math.axis"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { ImportMeshAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { VolumetricLightScatteringPostProcess } from "@babylonjs/core/PostProcesses/volumetricLightScatteringPostProcess"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import type { InstancedMesh } from "@babylonjs/core/Meshes/instancedMesh"; +import "@babylonjs/core/Meshes/instancedMesh"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Rendering/depthRendererSceneComponent"; + +export function createInstancesTestScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const rings1: InstancedMesh[] = []; + const rings2: InstancedMesh[] = []; + const rings3: InstancedMesh[] = []; + const rings4: InstancedMesh[] = []; + const rings5: InstancedMesh[] = []; + + const radius = 280; + const numPoints = 10; + const TWO_PI = Math.PI * 2; + const angle = TWO_PI / numPoints; + + let scale = 600; + const scene = new Scene(engine); + + const camera = new ArcRotateCamera("Camera", 1.7, 0.7, 1350, Vector3.Zero(), scene); + camera.setTarget(Vector3.Zero()); + camera.attachControl(canvas, false); + + const light = new HemisphericLight("light1", new Vector3(0, 0, 10), scene); + light.intensity = 0.2; + + const plight = new PointLight("plight1", new Vector3(0, 0, 180), scene); + + const mat = new StandardMaterial("mat", scene); + mat.diffuseTexture = new Texture("/Demos/Instances2/test8q_dDo_d.jpg", scene); + mat.bumpTexture = new Texture("/Demos/Instances2/test8q_dDo_n.jpg", scene); + mat.specularTexture = new Texture("/Demos/Instances2/test8q_dDo_s.jpg", scene); + + const skybox = CreateBox("skyBox", { size: 5000 }, scene); + const skyboxMaterial = new StandardMaterial("skyBox", scene); + skyboxMaterial.backFaceCulling = false; + skyboxMaterial.reflectionTexture = new CubeTexture("/Demos/Instances2/skybox/nebula", scene); + skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE; + skyboxMaterial.diffuseColor = new Color3(0, 0, 0); + skyboxMaterial.specularColor = new Color3(0, 0, 0); + skyboxMaterial.disableLighting = true; + skybox.material = skyboxMaterial; + + const emitter = new VolumetricLightScatteringPostProcess( + "godrays", + 1.0, + camera, + undefined, + 100, + Texture.BILINEAR_SAMPLINGMODE, + engine, + false + ); + const emitterMaterial = emitter.mesh.material as StandardMaterial; + emitterMaterial.diffuseTexture = new Texture( + "/Demos/Instances2/sun.png", + scene, + true, + false, + Texture.BILINEAR_SAMPLINGMODE + ); + emitterMaterial.diffuseTexture.hasAlpha = true; + emitter.mesh.position = new Vector3(0, 180, 0); + + ImportMeshAsync("/Demos/Instances2/killer.babylon", scene).then((result) => { + const obj = result.meshes[0] as Mesh; + obj.material = mat; + + for (let index = 0; index < numPoints; index++) { + rings1[index] = obj.createInstance("i1_" + index); + rings2[index] = obj.createInstance("i2_" + index); + rings3[index] = obj.createInstance("i3_" + index); + rings4[index] = obj.createInstance("i4_" + index); + rings5[index] = obj.createInstance("i5_" + index); + } + + obj.rotation.x = 200; + obj.isVisible = false; + + let t = 0.0; + scene.registerBeforeRender(function () { + for (let index = 0; index < numPoints; index++) { + const speed = t / 10.0; + rings1[index].position.x = radius * Math.sin(speed + angle * index); + rings1[index].position.z = radius * Math.cos(speed + angle * index); + rings1[index].lookAt(Vector3.Zero()); + rings1[index].rotate(Axis.Y, 1.6, Space.LOCAL); + } + + for (let index = 0; index < numPoints; index++) { + const speed = -t / 8.0; + rings2[index].position.x = radius * Math.sin(speed + angle * index); + rings2[index].position.y = 70; + rings2[index].position.z = radius * Math.cos(speed + angle * index); + rings2[index].lookAt(new Vector3(0, 100, 0)); + rings2[index].rotate(Axis.Y, 1.6, Space.LOCAL); + } + + for (let index = 0; index < numPoints; index++) { + const speed = t / 12.0; + rings3[index].position.x = 200 * Math.sin(speed + angle * index); + rings3[index].position.y = 180; + rings3[index].position.z = 200 * Math.cos(speed + angle * index); + rings3[index].lookAt(new Vector3(0, 150, 0)); + rings3[index].rotate(Axis.Y, 1.6, Space.LOCAL); + rings3[index].rotate(Axis.Z, -1.2, Space.LOCAL); + } + + for (let index = 0; index < numPoints; index++) { + const speed = -t / 6.0; + rings4[index].position.x = 150 * Math.sin(speed + angle * index); + rings4[index].position.y = 180; + rings4[index].position.z = 150 * Math.cos(speed + angle * index); + rings4[index].scaling = new Vector3(0.8, 0.8, 0.8); + rings4[index].lookAt(new Vector3(0, 150, 0)); + rings4[index].rotate(Axis.Y, 1.6, Space.LOCAL); + rings4[index].rotate(Axis.Z, -1.2, Space.LOCAL); + } + + for (let index = 0; index < numPoints; index++) { + const speed = -t / 10.0; + rings5[index].position.x = 750 * Math.sin(speed + angle * index); + rings5[index].position.z = 750 * Math.cos(speed + angle * index); + rings5[index].scaling = new Vector3(2.5, 2.5, 2.5); + rings5[index].lookAt(Vector3.Zero()); + rings5[index].rotate(Axis.Y, 1.6, Space.LOCAL); + } + + plight.intensity = 1 + Math.random() * 1.0 - 0.5; + scale = Math.random() * 100 - 500; + emitter.mesh.scaling = new Vector3(scale, scale, scale); + t += 0.1; + }); + }); + + return scene; +} diff --git a/src/compiledDemos/Mansion/index.html b/src/compiledDemos/Mansion/index.html new file mode 100644 index 000000000..a1b37571d --- /dev/null +++ b/src/compiledDemos/Mansion/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Mansion demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Mansion/main.ts b/src/compiledDemos/Mansion/main.ts new file mode 100644 index 000000000..1d538c429 --- /dev/null +++ b/src/compiledDemos/Mansion/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createMansionScene } from "./scene"; + +runDemo({ createScene: createMansionScene }); diff --git a/src/compiledDemos/Mansion/scene.ts b/src/compiledDemos/Mansion/scene.ts new file mode 100644 index 000000000..cdb4a698a --- /dev/null +++ b/src/compiledDemos/Mansion/scene.ts @@ -0,0 +1,14 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; +import "@babylonjs/core/Actions/directActions"; +import "@babylonjs/core/Actions/directAudioActions"; +import "@babylonjs/core/Actions/interpolateValueAction"; + +export async function createMansionScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Mansion/Mansion.babylon", engine); + scene.collisionsEnabled = true; + return scene; +} diff --git a/src/compiledDemos/MorphTargets/index.html b/src/compiledDemos/MorphTargets/index.html new file mode 100644 index 000000000..69a242b6b --- /dev/null +++ b/src/compiledDemos/MorphTargets/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Morph Targets demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/MorphTargets/main.ts b/src/compiledDemos/MorphTargets/main.ts new file mode 100644 index 000000000..e89150e0d --- /dev/null +++ b/src/compiledDemos/MorphTargets/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createMorphTargetsTestScene } from "./scene"; + +runDemo({ createScene: createMorphTargetsTestScene }); diff --git a/src/compiledDemos/MorphTargets/scene.ts b/src/compiledDemos/MorphTargets/scene.ts new file mode 100644 index 000000000..bffdbcbe0 --- /dev/null +++ b/src/compiledDemos/MorphTargets/scene.ts @@ -0,0 +1,101 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial"; +import { HDRCubeTexture } from "@babylonjs/core/Materials/Textures/hdrCubeTexture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { VertexBuffer } from "@babylonjs/core/Buffers/buffer"; +import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; +import { MorphTargetManager } from "@babylonjs/core/Morph/morphTargetManager"; +import { MorphTarget } from "@babylonjs/core/Morph/morphTarget"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; + +function addSpike(mesh: Mesh): void { + const positions = mesh.getVerticesData(VertexBuffer.PositionKind)!; + const normals = mesh.getVerticesData(VertexBuffer.NormalKind)!; + const indices = mesh.getIndices()!; + + for (let index = 0; index < 5; index++) { + const randomVertexID = (mesh.getTotalVertices() * Math.random()) | 0; + const position = Vector3.FromArray(positions, randomVertexID * 3); + const normal = Vector3.FromArray(normals, randomVertexID * 3); + + position.addInPlace(normal); + position.toArray(positions, randomVertexID * 3); + } + + VertexData.ComputeNormals(positions, indices, normals); + mesh.updateVerticesData(VertexBuffer.PositionKind, positions, false, false); + mesh.updateVerticesData(VertexBuffer.NormalKind, normals, false, false); +} + +export function createMorphTargetsTestScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + + const camera = new ArcRotateCamera("camera1", 1.14, 1.13, 10, Vector3.Zero(), scene); + camera.setTarget(Vector3.Zero()); + camera.attachControl(canvas, true); + + const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene); + light.intensity = 0.7; + + const sphere = CreateSphere("sphere1", { segments: 16, diameter: 2 }, scene); + + const hdrTexture = new HDRCubeTexture("/Demos/Highlights/room.hdr", scene, 512); + + const glass = new PBRMaterial("glass", scene); + glass.reflectionTexture = hdrTexture; + glass.refractionTexture = hdrTexture; + glass.linkRefractionWithTransparency = true; + glass.indexOfRefraction = 0.52; + glass.alpha = 0; + glass.microSurface = 1; + glass.reflectivityColor = new Color3(0.2, 0.2, 0.2); + glass.albedoColor = new Color3(0.85, 0.85, 0.85); + sphere.material = glass; + + const sphere2 = CreateSphere("sphere2", { segments: 16, diameter: 2 }, scene); + sphere2.setEnabled(false); + addSpike(sphere2); + + const sphere3 = CreateSphere("sphere3", { segments: 16, diameter: 2 }, scene); + sphere3.setEnabled(false); + addSpike(sphere3); + + const sphere4 = CreateSphere("sphere4", { segments: 16, diameter: 2 }, scene); + sphere4.setEnabled(false); + addSpike(sphere4); + + const sphere5 = CreateSphere("sphere5", { segments: 16, diameter: 2 }, scene); + sphere5.setEnabled(false); + addSpike(sphere5); + + const manager = new MorphTargetManager(); + sphere.morphTargetManager = manager; + + const target0 = MorphTarget.FromMesh(sphere2, "sphere2", 0.25); + manager.addTarget(target0); + + const target1 = MorphTarget.FromMesh(sphere3, "sphere3", 0.25); + manager.addTarget(target1); + + const target2 = MorphTarget.FromMesh(sphere4, "sphere4", 0.25); + manager.addTarget(target2); + + const target3 = MorphTarget.FromMesh(sphere5, "sphere5", 0.25); + manager.addTarget(target3); + + let t = 0; + scene.registerBeforeRender(function () { + t += 0.02; + target0.influence = Math.sin(t) * 0.5 + 0.5; + target1.influence = Math.sin(t * 1.3) * 0.5 + 0.5; + target2.influence = Math.sin(t * 0.7) * 0.5 + 0.5; + target3.influence = Math.sin(t * 1.7) * 0.5 + 0.5; + }); + + return scene; +} diff --git a/src/compiledDemos/Particles2/index.html b/src/compiledDemos/Particles2/index.html new file mode 100644 index 000000000..4b19498e0 --- /dev/null +++ b/src/compiledDemos/Particles2/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Particles 2 demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Particles2/main.ts b/src/compiledDemos/Particles2/main.ts new file mode 100644 index 000000000..f657dfd92 --- /dev/null +++ b/src/compiledDemos/Particles2/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createParticles2Scene } from "./scene"; + +runDemo({ createScene: createParticles2Scene }); diff --git a/src/compiledDemos/Particles2/scene.ts b/src/compiledDemos/Particles2/scene.ts new file mode 100644 index 000000000..0990872f2 --- /dev/null +++ b/src/compiledDemos/Particles2/scene.ts @@ -0,0 +1,77 @@ +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Effect } from "@babylonjs/core/Materials/effect"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem"; +import { Scene } from "@babylonjs/core/scene"; + +const particleTextureUrl = "/Scenes/WorldMonger/Assets/Flare.png"; + +Effect.ShadersStore.myParticleFragmentShader = ` +#ifdef GL_ES +precision highp float; +#endif +varying vec2 vUV; +varying vec4 vColor; +uniform sampler2D diffuseSampler; +uniform float time; +void main(void) { + vec2 position = vUV; + float color = 0.0; + vec2 center = vec2(0.5, 0.5); + color = sin(distance(position, center) * 10.0 + time * vColor.g); + vec4 baseColor = texture2D(diffuseSampler, vUV); + gl_FragColor = baseColor * vColor * vec4(vec3(color, color, color), 1.0); +}`; + +export function createParticles2Scene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + + const camera = new ArcRotateCamera("Camera", 0, 0, 10, Vector3.Zero(), scene); + camera.setPosition(new Vector3(-5, 5, 0)); + camera.lowerBetaLimit = 0.1; + camera.upperBetaLimit = (Math.PI / 2) * 0.95; + camera.lowerRadiusLimit = 5; + camera.attachControl(canvas, true); + + const emitter0 = CreateBox("emitter0", { size: 0.1 }, scene); + emitter0.isVisible = false; + + const effect = engine.createEffectForParticles("myParticle", ["time"], [], ""); + + const particleSystem = new ParticleSystem("particles", 4000, scene, effect); + particleSystem.particleTexture = new Texture(particleTextureUrl, scene); + particleSystem.minSize = 0.1; + particleSystem.maxSize = 1.0; + particleSystem.minLifeTime = 0.5; + particleSystem.maxLifeTime = 5.0; + particleSystem.minEmitPower = 0.5; + particleSystem.maxEmitPower = 3.0; + particleSystem.emitter = emitter0; + particleSystem.emitRate = 100; + particleSystem.blendMode = ParticleSystem.BLENDMODE_ONEONE; + particleSystem.direction1 = new Vector3(-1, 1, -1); + particleSystem.direction2 = new Vector3(1, 1, 1); + particleSystem.color1 = new Color4(1, 1, 0, 1); + particleSystem.color2 = new Color4(1, 0.5, 0, 1); + particleSystem.gravity = new Vector3(0, -1.0, 0); + particleSystem.start(); + + let time = 0; + let order = 0.1; + scene.registerBeforeRender(() => { + if (!effect) { + return; + } + effect.setFloat("time", time); + time += order; + if (time > 100 || time < 0) { + order *= -1; + } + }); + + return scene; +} diff --git a/src/compiledDemos/Polygon/index.html b/src/compiledDemos/Polygon/index.html new file mode 100644 index 000000000..74fb3f8e7 --- /dev/null +++ b/src/compiledDemos/Polygon/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Polygon demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Polygon/main.ts b/src/compiledDemos/Polygon/main.ts new file mode 100644 index 000000000..1a39bdcab --- /dev/null +++ b/src/compiledDemos/Polygon/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createPolygonScene } from "./scene"; + +runDemo({ createScene: createPolygonScene }); diff --git a/src/compiledDemos/Polygon/scene.ts b/src/compiledDemos/Polygon/scene.ts new file mode 100644 index 000000000..124609bb7 --- /dev/null +++ b/src/compiledDemos/Polygon/scene.ts @@ -0,0 +1,65 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Polygon, PolygonMeshBuilder } from "@babylonjs/core/Meshes/polygonMesh"; +import { Scene } from "@babylonjs/core/scene"; +import earcut from "earcut"; + +const birdData = + "4.57998 4.03402 4.06435 4.06435 3.51839 4.21601 3.09376 4.42832 2.60846 4.57998 2.09284 4.7013 1.51655 4.82263 0.909929 4.94395 " + + "0.242648 5.06527 -0.30331 5.0956 -1.15258 5.12594 -1.72887 5.12594 -2.48714 5.12594 -2.85111 5.03494 -3.36674 5.30792 -3.70038 5.52024 " + + "-4.15534 5.9752 -4.7013 6.27851 -5.0956 6.61215 -5.73255 6.67281 -6.55149 6.73348 -6.88513 6.61215 -7.46142 6.36951 -7.88605 6.18752 " + + "-8.25003 5.91454 -8.64433 5.61123 -8.88698 5.30792 -9.06896 5.00461 -9.25095 4.88329 -9.94856 4.73163 -10.6462 4.64064 -11.1011 4.54965 " + + "-11.3741 4.42832 -11.5561 4.21601 -11.0101 4.21601 -10.1305 3.94303 -9.61492 3.73071 -9.15996 3.4274 -8.73532 3.00277 -8.34102 2.6388 " + + "-7.97705 2.36582 -7.61308 2.03218 -7.18844 1.45589 -6.79414 1.12225 -6.64248 0.788605 -6.36951 0.242648 -6.24818 -0.212317 -6.00553 -0.515627 " + + "-5.73255 -0.818936 -5.24726 -1.2739 -4.7923 -1.60754 -4.42832 -2.00184 -3.67005 -2.21416 -3.18475 -2.39615 -2.5478 -2.69946 " + + "-1.91085 -2.79045 -1.06158 -2.88144 -0.333641 -2.88144 0.242648 -2.85111 0.94026 -2.82078 1.2739 -2.85111 1.42556 -3.0331 " + + "1.42556 -3.30608 1.33456 -3.57905 1.15258 -4.00369 1.03125 -4.57998 0.849267 -5.15627 0.63695 -5.5809 0.30331 -5.91454 " + + "0.060662 -6.15719 -0.333641 -6.27851 -0.697612 -6.27851 -1.15258 -6.36951 -1.57721 -6.39984 -2.09284 -6.52116 -2.36582 -6.79414 " + + "-2.48714 -7.06712 -2.18383 -6.97612 -1.85019 -6.79414 -1.42556 -6.76381 -1.15258 -6.79414 -1.36489 -6.88513 -1.69853 -6.97612 " + + "-1.97151 -7.12778 -2.12317 -7.37043 -2.27482 -7.64341 -2.39615 -7.91639 -2.36582 -8.21969 -2.03218 -7.85572 -1.81986 -7.7344 " + + "-1.57721 -7.67374 -1.36489 -7.49175 -1.21324 -7.40076 -0.849267 -7.2491 -0.60662 -7.12778 -0.242648 -6.91546 0.030331 -6.70315 " + + "0.363972 -6.4605 0.242648 -6.61215 0.152837 -6.72007 -0.092855 -6.88818 -0.506653 -7.15974 -0.765276 -7.31491 -1.01097 -7.41836 " + + "-1.16614 -7.5606 -1.32132 -7.71577 -1.45063 -7.81922 -1.50235 -8.06492 -1.50235 -8.29768 -1.46356 -8.53044 -1.38597 -8.29768 " + + "-1.28252 -8.05199 -1.14028 -7.87095 -0.985106 -7.84509 -0.817001 -7.84509 -0.623033 -7.70284 -0.390272 -7.52181 -0.105787 -7.31491 " + + "0.178699 -7.06922 0.489047 -6.84939 0.670083 -6.66835 0.928707 -6.47438 1.16147 -6.33214 1.47182 -6.13817 1.82096 -5.91834 " + + "2.04079 -5.84076 2.15717 -5.71144 2.18303 -5.45282 2.06665 -5.28472 1.87268 -5.3623 1.49768 -5.63386 1.22612 -5.81489 1.03216 -5.91834 " + + "0.876982 -5.95714 0.954569 -5.80196 1.00629 -5.60799 1.16147 -5.29765 1.3425 -4.9873 1.45888 -4.65109 1.47182 -4.4054 1.73044 -3.95281 " + + "1.84682 -3.6166 1.98906 -3.30625 2.14424 -2.95711 2.26062 -2.75021 2.42872 -2.59503 2.63562 -2.50452 2.98476 -2.51745 3.12701 -2.71141 " + + "3.06235 -3.09935 2.9589 -3.4097 2.86838 -3.75884 2.79079 -4.12091 2.70028 -4.43126 2.55803 -4.75454 2.48045 -5.03902 2.3382 -5.37523 " + + "2.29941 -5.59506 2.23475 -5.90541 2.11837 -6.21576 1.7951 -6.65542 1.39423 -7.05628 1.09681 -7.26318 0.838188 -7.37956 " + + "0.41146 -7.49594 -0.002337 -7.62526 -0.416135 -7.7675 -0.687689 -8.05199 -0.907519 -8.40113 -0.70062 -8.19423 -0.312685 -8.05199 " + + "-0.015268 -7.89681 0.217493 -7.89681 0.243355 -7.90974 0.023525 -8.1425 -0.157511 -8.25888 -0.403203 -8.43992 -0.648896 -8.75027 " + + "-0.778207 -8.90544 -0.881657 -9.18993 -0.80407 -9.60372 -0.597171 -9.177 -0.14458 -8.9701 0.269217 -8.62096 0.695946 -8.28475 1.13561 -8.00026 " + + "1.52354 -7.62526 1.82096 -7.26318 1.95027 -7.09508 1.9632 -7.15974 1.66578 -7.58646 1.45888 -7.84509 1.13561 -8.20716 0.760601 -8.65975 " + + "0.450253 -8.99596 0.269217 -9.28045 0.126974 -9.65545 0.19163 -10.2761 0.333873 -9.84942 0.63129 -9.68131 0.980431 -9.26751 1.26492 -8.72441 " + + "1.60113 -8.31061 1.98906 -7.7675 2.36407 -7.34077 2.79079 -7.00456 3.13994 -6.7718 3.68304 -6.46145 4.14857 -6.33214 4.7434 -6.09938 " + + "5.19599 -6.13817 4.85978 -5.87955 4.29081 -5.76317 3.77356 -5.81489 3.34683 -6.07352 2.77786 -6.47438 2.41579 -6.60369 " + + "2.41579 -6.28042 2.59683 -5.84076 2.79079 -5.42696 2.99769 -4.90971 3.25632 -4.30195 3.50201 -3.52608 3.83822 -2.63383 4.07098 -2.40107 " + + "4.39426 -2.28469 4.79512 -2.23296 4.54943 -2.02606 4.49771 -1.6252 4.54943 -1.50882 4.91151 -1.50882 5.54513 -1.45709 6.12704 -1.39244 " + + "6.85118 -1.32778 7.44601 -1.14674 7.85981 -0.78467 7.79516 -0.409667 7.49774 -0.151043 7.84688 0.042924 8.23481 0.314479 " + + "8.64861 0.702414 8.70034 1.09035 8.41585 1.42656 8.11843 1.62053 8.3512 2.06019 8.53223 2.38347 8.67447 2.74554 8.66154 3.22399 " + + "8.80379 3.87055 8.90724 4.36193 9.1012 4.85332 9.43741 5.40936 9.90293 6.04298 10.3167 6.58609 10.7047 7.3749 10.9374 7.96973 11.1573 8.40939 " + + "11.1573 8.84905 10.9374 9.05595 10.6659 9.28871 10.3426 9.37922 9.99345 9.34043 9.63138 8.97836 9.20465 8.48697 8.86844 8.1249 8.50637 7.72404 " + + "8.17016 7.28438 7.74343 6.88351 7.43308 6.5473 7.16153 6.1723 6.70894 5.71971 6.20462 5.25418 5.72617 4.80159 5.13134 4.41366 " + + "4.87271 4.16797"; + +export function createPolygonScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", 0, 0, 10, Vector3.Zero(), scene); + camera.setPosition(new Vector3(-20, 20, -10)); + camera.attachControl(canvas, true); + + new PointLight("Omni", new Vector3(20, 100, 2), scene); + + const rectangle = Polygon.Rectangle(-15, -15, 15, 15); + const ground = new PolygonMeshBuilder("ground", rectangle, scene, earcut).addHole(Polygon.Parse(birdData)).build(); + + const material = new StandardMaterial("mat", scene); + material.backFaceCulling = false; + ground.material = material; + + return scene; +} diff --git a/src/compiledDemos/Procedural/index.html b/src/compiledDemos/Procedural/index.html new file mode 100644 index 000000000..67ab9a80a --- /dev/null +++ b/src/compiledDemos/Procedural/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Procedural Textures demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Procedural/main.ts b/src/compiledDemos/Procedural/main.ts new file mode 100644 index 000000000..eed558f72 --- /dev/null +++ b/src/compiledDemos/Procedural/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createProceduralScene } from "./scene"; + +runDemo({ createScene: createProceduralScene }); diff --git a/src/compiledDemos/Procedural/scene.ts b/src/compiledDemos/Procedural/scene.ts new file mode 100644 index 000000000..44bef6258 --- /dev/null +++ b/src/compiledDemos/Procedural/scene.ts @@ -0,0 +1,196 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { CustomProceduralTexture } from "@babylonjs/core/Materials/Textures/Procedurals/customProceduralTexture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Space } from "@babylonjs/core/Maths/math.axis"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreateCylinder } from "@babylonjs/core/Meshes/Builders/cylinderBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { CreateTorus } from "@babylonjs/core/Meshes/Builders/torusBuilder"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { Scene } from "@babylonjs/core/scene"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import { WoodProceduralTexture } from "@babylonjs/procedural-textures/wood/woodProceduralTexture"; +import { GrassProceduralTexture } from "@babylonjs/procedural-textures/grass/grassProceduralTexture"; +import { MarbleProceduralTexture } from "@babylonjs/procedural-textures/marble/marbleProceduralTexture"; +import { FireProceduralTexture } from "@babylonjs/procedural-textures/fire/fireProceduralTexture"; +import { BrickProceduralTexture } from "@babylonjs/procedural-textures/brick/brickProceduralTexture"; +import { RoadProceduralTexture } from "@babylonjs/procedural-textures/road/roadProceduralTexture"; +import { CloudProceduralTexture } from "@babylonjs/procedural-textures/cloud/cloudProceduralTexture"; + +export function createProceduralScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", 1, 1.2, 25, new Vector3(10, 0, 0), scene); + camera.upperBetaLimit = 1.2; + camera.attachControl(canvas, true); + + const name = "town"; + + const woodMaterial = new StandardMaterial(name, scene); + const woodTexture = new WoodProceduralTexture(name + "text", 1024, scene); + woodTexture.ampScale = 50.0; + woodMaterial.diffuseTexture = woodTexture; + + const grassMaterial = new StandardMaterial(name + "bawl", scene); + const grassTexture = new GrassProceduralTexture(name + "textbawl", 256, scene); + grassMaterial.ambientTexture = grassTexture; + + const marbleMaterial = new StandardMaterial("torus", scene); + const marbleTexture = new MarbleProceduralTexture("marble", 512, scene); + marbleTexture.numberOfTilesHeight = 5; + marbleTexture.numberOfTilesWidth = 5; + marbleMaterial.ambientTexture = marbleTexture; + + const fireMaterial = new StandardMaterial("fontainSculptur2", scene); + const fireTexture = new FireProceduralTexture("fire", 256, scene); + fireMaterial.diffuseTexture = fireTexture; + fireMaterial.opacityTexture = fireTexture; + + const brickMaterial = new StandardMaterial(name, scene); + const brickTexture = new BrickProceduralTexture(name + "text", 512, scene); + brickTexture.numberOfBricksHeight = 2; + brickTexture.numberOfBricksWidth = 3; + brickMaterial.diffuseTexture = brickTexture; + + const light = new DirectionalLight("dir01", new Vector3(-0.5, -1, -0.5), scene); + light.diffuse = new Color3(1, 1, 1); + light.specular = new Color3(1, 1, 1); + light.position = new Vector3(20, 40, 20); + + const square = CreateGround("square", { width: 20, height: 20, subdivisions: 2 }, scene); + square.position = new Vector3(0, 0, 0); + const customMaterial = new StandardMaterial("custommat", scene); + const customProcText = new CustomProceduralTexture("customtext", "/Demos/Procedural/land", 1024, scene); + customMaterial.ambientTexture = customProcText; + square.material = customMaterial; + + const shadowGenerator = new ShadowGenerator(1024, light); + shadowGenerator.usePoissonSampling = true; + shadowGenerator.bias = 0; + square.receiveShadows = true; + + const pushShadow = (mesh: Mesh) => { + shadowGenerator.getShadowMap()!.renderList!.push(mesh); + }; + + const createBosquet = (bname: string, x: number, y: number, z: number) => { + const bosquet = CreateBox(bname, { size: 2 }, scene); + bosquet.position = new Vector3(x, y, z); + bosquet.material = grassMaterial; + + const bosquetbawl = CreateBox(bname + "bawl", { size: 1 }, scene); + bosquetbawl.position = new Vector3(x, y + 1, z); + bosquetbawl.material = grassMaterial; + + pushShadow(bosquet); + pushShadow(bosquetbawl); + }; + + const createTree = (tname: string, x: number, y: number, z: number) => { + const trunk = CreateCylinder( + tname + "trunk", + { height: 7, diameterTop: 2, diameterBottom: 2, tessellation: 12, subdivisions: 1 }, + scene + ); + trunk.position = new Vector3(x, y, z); + trunk.material = woodMaterial; + + const leafs = CreateSphere(tname + "leafs", { segments: 20, diameter: 7 }, scene); + leafs.position = new Vector3(x, y + 5.0, z); + leafs.material = grassMaterial; + + pushShadow(trunk); + pushShadow(leafs); + }; + + const createFontain = (x: number, y: number, z: number) => { + const torus = CreateTorus("torus", { diameter: 5, thickness: 1, tessellation: 20 }, scene); + torus.position = new Vector3(x, y, z); + torus.material = marbleMaterial; + + const fontainGround = CreateBox("fontainGround", { size: 4 }, scene); + fontainGround.position = new Vector3(x, y - 2, z); + fontainGround.material = marbleMaterial; + + const fontainSculptur1 = CreateCylinder( + "fontainSculptur1", + { height: 2, diameterTop: 2, diameterBottom: 1, tessellation: 10, subdivisions: 1 }, + scene + ); + fontainSculptur1.position = new Vector3(x, y, z); + fontainSculptur1.material = marbleMaterial; + + const fontainSculptur2 = CreateSphere("fontainSculptur2", { segments: 7, diameter: 1.7 }, scene); + fontainSculptur2.position = new Vector3(x, y + 0.9, z); + fontainSculptur2.material = fireMaterial; + fontainSculptur2.rotate(new Vector3(1.0, 0.0, 0.0), Math.PI / 2.0, Space.LOCAL); + + pushShadow(torus); + pushShadow(fontainSculptur1); + pushShadow(fontainSculptur2); + }; + + const createTorch = (cname: string, x: number, y: number, z: number) => { + const brickblock = CreateBox(cname + "brickblock", { size: 1 }, scene); + brickblock.position = new Vector3(x, y, z); + brickblock.material = brickMaterial; + + const torchwood = CreateCylinder( + cname + "torchwood", + { height: 2, diameterTop: 0.25, diameterBottom: 0.1, tessellation: 12, subdivisions: 1 }, + scene + ); + torchwood.position = new Vector3(x, y + 1, z); + torchwood.material = woodMaterial; + + const leafs2 = CreateSphere(cname + "leafs2", { segments: 10, diameter: 1.2 }, scene); + leafs2.position = new Vector3(x, y + 2, z); + leafs2.material = grassMaterial; + + pushShadow(torchwood); + pushShadow(leafs2); + pushShadow(brickblock); + }; + + createBosquet("b1", -9, 1, 9); + createBosquet("b2", -9, 1, -9); + createBosquet("b3", 9, 1, 9); + createBosquet("b4", 9, 1, -9); + + createTree("a1", 0, 3.5, 0); + + const macadam = CreateGround("macadam", { width: 20, height: 20, subdivisions: 2 }, scene); + macadam.position = new Vector3(20, 0, 0); + const customMaterialmacadam = new StandardMaterial("macadam", scene); + const customProcTextmacadam = new RoadProceduralTexture("customtextroad", 512, scene); + customMaterialmacadam.diffuseTexture = customProcTextmacadam; + macadam.material = customMaterialmacadam; + macadam.receiveShadows = true; + + createFontain(20, 0.25, 0); + createTorch("torch1", 15, 0.5, 5); + createTorch("torch2", 15, 0.5, -5); + createTorch("torch3", 25, 0.5, 5); + createTorch("torch4", 25, 0.5, -5); + + const boxCloud = CreateSphere("boxCloud", { segments: 100, diameter: 1000 }, scene); + boxCloud.position = new Vector3(0, 0, 12); + const cloudMaterial = new StandardMaterial("cloudMat", scene); + const cloudProcText = new CloudProceduralTexture("cloud", 1024, scene); + cloudMaterial.emissiveTexture = cloudProcText; + cloudMaterial.backFaceCulling = false; + cloudMaterial.emissiveTexture.coordinatesMode = Texture.FIXED_EQUIRECTANGULAR_MODE; + boxCloud.material = cloudMaterial; + + scene.registerBeforeRender(() => { + camera.alpha += 0.001 * scene.getAnimationRatio(); + }); + + return scene; +} diff --git a/src/compiledDemos/RefProbe/index.html b/src/compiledDemos/RefProbe/index.html new file mode 100644 index 000000000..092d98e15 --- /dev/null +++ b/src/compiledDemos/RefProbe/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Reflection Probe demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/RefProbe/main.ts b/src/compiledDemos/RefProbe/main.ts new file mode 100644 index 000000000..e3de70af6 --- /dev/null +++ b/src/compiledDemos/RefProbe/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createRefProbeScene } from "./scene"; + +runDemo({ createScene: createRefProbeScene }); diff --git a/src/compiledDemos/RefProbe/scene.ts b/src/compiledDemos/RefProbe/scene.ts new file mode 100644 index 000000000..9bc0120f1 --- /dev/null +++ b/src/compiledDemos/RefProbe/scene.ts @@ -0,0 +1,105 @@ +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { FresnelParameters } from "@babylonjs/core/Materials/fresnelParameters"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { MirrorTexture } from "@babylonjs/core/Materials/Textures/mirrorTexture"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Plane } from "@babylonjs/core/Maths/math.plane"; +import { Matrix, Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { CreateTorusKnot } from "@babylonjs/core/Meshes/Builders/torusKnotBuilder"; +import type { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import { ReflectionProbe } from "@babylonjs/core/Probes/reflectionProbe"; +import { Scene } from "@babylonjs/core/scene"; + +export function createRefProbeScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + + const camera = new ArcRotateCamera("camera1", 0, 0, 10, Vector3.Zero(), scene); + camera.setPosition(new Vector3(0, 5, -10)); + camera.upperBetaLimit = Math.PI / 2; + camera.lowerRadiusLimit = 4; + camera.attachControl(canvas, true); + + const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene); + light.intensity = 0.7; + + const knot = CreateTorusKnot( + "knot", + { radius: 1, tube: 0.4, radialSegments: 128, tubularSegments: 64, p: 2, q: 3 }, + scene + ); + + const yellowSphere = CreateSphere("yellowSphere", { segments: 16, diameter: 1.5 }, scene); + yellowSphere.setPreTransformMatrix(Matrix.Translation(3, 0, 0)); + + const blueSphere = CreateSphere("blueSphere", { segments: 16, diameter: 1.5 }, scene); + blueSphere.setPreTransformMatrix(Matrix.Translation(-1, 3, 0)); + + const greenSphere = CreateSphere("greenSphere", { segments: 16, diameter: 1.5 }, scene); + greenSphere.setPreTransformMatrix(Matrix.Translation(0, 0, 3)); + + const generateSatelliteMaterial = (root: AbstractMesh, color: Color3, others: AbstractMesh[]): void => { + const material = new StandardMaterial("satelliteMat" + root.name, scene); + material.diffuseColor = color; + const probe = new ReflectionProbe("satelliteProbe" + root.name, 512, scene); + for (let index = 0; index < others.length; index++) { + probe.renderList?.push(others[index]); + } + material.reflectionTexture = probe.cubeTexture; + material.reflectionFresnelParameters = new FresnelParameters(); + material.reflectionFresnelParameters.bias = 0.02; + root.material = material; + probe.attachToMesh(root); + }; + + const mirror = CreateBox("Mirror", { size: 1.0 }, scene); + mirror.scaling = new Vector3(100.0, 0.01, 100.0); + const mirrorMaterial = new StandardMaterial("mirror", scene); + const mirrorDiffuse = new Texture("/Scenes/Customs/Ground.jpg", scene); + mirrorDiffuse.uScale = 10; + mirrorDiffuse.vScale = 10; + mirrorMaterial.diffuseTexture = mirrorDiffuse; + const mirrorReflection = new MirrorTexture("mirror", 1024, scene, true); + mirrorReflection.mirrorPlane = new Plane(0, -1.0, 0, -2.0); + mirrorReflection.renderList = [greenSphere, yellowSphere, blueSphere, knot]; + mirrorReflection.level = 0.5; + mirrorMaterial.reflectionTexture = mirrorReflection; + mirror.material = mirrorMaterial; + mirror.position = new Vector3(0, -2, 0); + + const mainMaterial = new StandardMaterial("main", scene); + knot.material = mainMaterial; + + const probe = new ReflectionProbe("main", 512, scene); + probe.renderList?.push(yellowSphere); + probe.renderList?.push(greenSphere); + probe.renderList?.push(blueSphere); + probe.renderList?.push(mirror); + mainMaterial.diffuseColor = new Color3(1, 0.5, 0.5); + mainMaterial.reflectionTexture = probe.cubeTexture; + mainMaterial.reflectionFresnelParameters = new FresnelParameters(); + mainMaterial.reflectionFresnelParameters.bias = 0.02; + + generateSatelliteMaterial(yellowSphere, Color3.Yellow(), [greenSphere, blueSphere, knot, mirror]); + generateSatelliteMaterial(greenSphere, Color3.Green(), [yellowSphere, blueSphere, knot, mirror]); + generateSatelliteMaterial(blueSphere, Color3.Blue(), [greenSphere, yellowSphere, knot, mirror]); + + (yellowSphere.material as StandardMaterial).alpha = 0.8; + + scene.fogMode = Scene.FOGMODE_LINEAR; + scene.fogColor = new Color3(scene.clearColor.r, scene.clearColor.g, scene.clearColor.b); + scene.fogStart = 20.0; + scene.fogEnd = 50.0; + + scene.registerBeforeRender(() => { + yellowSphere.rotation.y += 0.01; + greenSphere.rotation.y += 0.01; + blueSphere.rotation.y += 0.01; + }); + + return scene; +} diff --git a/src/compiledDemos/SPS/index.html b/src/compiledDemos/SPS/index.html new file mode 100644 index 000000000..f9af690a8 --- /dev/null +++ b/src/compiledDemos/SPS/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Solid Particle System demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SPS/main.ts b/src/compiledDemos/SPS/main.ts new file mode 100644 index 000000000..135047fcd --- /dev/null +++ b/src/compiledDemos/SPS/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSPSTestScene } from "./scene"; + +runDemo({ createScene: createSPSTestScene }); diff --git a/src/compiledDemos/SPS/scene.ts b/src/compiledDemos/SPS/scene.ts new file mode 100644 index 000000000..807c3f726 --- /dev/null +++ b/src/compiledDemos/SPS/scene.ts @@ -0,0 +1,149 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { CubeTexture } from "@babylonjs/core/Materials/Textures/cubeTexture"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { FresnelParameters } from "@babylonjs/core/Materials/fresnelParameters"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { CreatePlane } from "@babylonjs/core/Meshes/Builders/planeBuilder"; +import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; +import { VolumetricLightScatteringPostProcess } from "@babylonjs/core/PostProcesses/volumetricLightScatteringPostProcess"; +import type { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Scene } from "@babylonjs/core/scene"; +import "@babylonjs/core/Rendering/depthRendererSceneComponent"; + +function getRandomInt(min: number, max: number): number { + return Math.floor(Math.random() * (max - min + 1) + min); +} + +export function createSPSTestScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + scene.clearColor = Color3.Black().toColor4(1); + + const camera = new ArcRotateCamera("Camera", -1.5, 1.3, 500, Vector3.Zero(), scene); + camera.attachControl(canvas, false); + camera.upperRadiusLimit = 600; + camera.lowerRadiusLimit = 200; + + const light1 = new HemisphericLight("hemi", new Vector3(0, 50, 100), scene); + light1.diffuse = new Color3(0, 10, 10); + + const skybox = CreateBox("skyBox", { size: 1500 }, scene); + const skyboxMaterial = new StandardMaterial("skyBox", scene); + skyboxMaterial.backFaceCulling = false; + skyboxMaterial.reflectionTexture = new CubeTexture("/Scenes/prosecution/assets/skybox/nebula", scene); + skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE; + skyboxMaterial.diffuseColor = new Color3(0, 0, 0); + skyboxMaterial.specularColor = new Color3(0, 0, 0); + skyboxMaterial.disableLighting = true; + skybox.material = skyboxMaterial; + + const saturne = CreateSphere("saturne", { segments: 16, diameter: 80 }, scene); + const saturneMaterial = new StandardMaterial("saturne_material", scene); + saturneMaterial.reflectionTexture = new CubeTexture("/Scenes/prosecution/assets/skybox/nebula", scene); + saturneMaterial.diffuseTexture = new Texture("/Demos/SPS/saturne.jpg", scene); + saturneMaterial.diffuseColor = new Color3(0.8, 0.8, 0.8); + saturneMaterial.emissiveColor = Color3.White(); + saturneMaterial.specularColor = Color3.Black(); + saturneMaterial.backFaceCulling = true; + + saturneMaterial.reflectionFresnelParameters = new FresnelParameters(); + saturneMaterial.reflectionFresnelParameters.bias = 0.2; + + saturneMaterial.emissiveFresnelParameters = new FresnelParameters(); + saturneMaterial.emissiveFresnelParameters.bias = 0.6; + saturneMaterial.emissiveFresnelParameters.power = 4; + saturneMaterial.emissiveFresnelParameters.leftColor = Color3.White(); + saturneMaterial.emissiveFresnelParameters.rightColor = new Color3(0.6, 0.6, 0.6); + + saturne.material = saturneMaterial; + saturne.rotation.y = -12; + + const rings = CreatePlane("rings", { size: 600 }, scene); + const ringsMat = new StandardMaterial("m", scene); + ringsMat.diffuseTexture = new Texture("/Demos/SPS/rings.png", scene); + ringsMat.diffuseTexture.hasAlpha = true; + ringsMat.backFaceCulling = false; + rings.material = ringsMat; + rings.rotation.x = Math.PI / 2; + + const nb = 20000; + + const myVertexFunction = (particle: SolidParticle, vertex: { x: number; y: number; z: number }) => { + vertex.x *= (Math.random() + 0.01) / getRandomInt(5, 10); + vertex.y *= (Math.random() + 0.01) / getRandomInt(5, 10); + vertex.z *= (Math.random() + 0.01) / getRandomInt(5, 10); + }; + + const myPositionFunction = (particle: SolidParticle, i: number) => { + const TWO_PI = Math.PI * 2; + const angle = TWO_PI / nb; + + const x = getRandomInt(90, 350) * Math.sin(angle * i); + const z = getRandomInt(90, 350) * Math.cos(angle * i); + + particle.position.x = x; + particle.position.y = z; + particle.position.z = (Math.random() - 0.5) * 5; + + particle.scaling.x = getRandomInt(5, 35) / 10; + particle.scaling.y = getRandomInt(5, 35) / 10; + particle.scaling.z = getRandomInt(5, 35) / 10; + + particle.rotation.x = Math.random() * 3.15; + particle.rotation.y = Math.random() * 3.15; + particle.rotation.z = Math.random() * 1.5; + }; + + const rock = CreateSphere("s", { segments: 0.5, diameter: 16 }, scene); + const rockMaterial = new StandardMaterial("rock_material", scene); + rockMaterial.diffuseTexture = new Texture("/Demos/SPS/asteroid.jpg", scene); + (rockMaterial.diffuseTexture as Texture).uScale = 16; + (rockMaterial.diffuseTexture as Texture).vScale = 16; + rockMaterial.backFaceCulling = false; + rock.material = rockMaterial; + + // SPS creation : Immutable {updatable: false} + const SPS = new SolidParticleSystem("SPS", scene, { updatable: false }); + SPS.addShape(rock, nb, { positionFunction: myPositionFunction, vertexFunction: myVertexFunction }); + SPS.buildMesh(); + SPS.mesh.material = rock.material; + SPS.mesh.rotation.y = 90; + SPS.mesh.rotation.x = Math.PI / 2; + + rock.dispose(); + + const emitter = new VolumetricLightScatteringPostProcess( + "godrays", + { passRatio: 0.5, postProcessRatio: 1.0 }, + camera, + undefined, + 100, + Texture.BILINEAR_SAMPLINGMODE, + engine, + false + ); + const emitterMaterial = emitter.mesh.material as StandardMaterial; + emitterMaterial.diffuseTexture = new Texture( + "/Demos/SPS/sun.png", + scene, + true, + false, + Texture.BILINEAR_SAMPLINGMODE + ); + emitterMaterial.diffuseTexture.hasAlpha = true; + emitter.mesh.position = new Vector3(200, 0, 500); + emitter.mesh.scaling = new Vector3(250, 250, 250); + + let t = 0.0; + scene.registerBeforeRender(() => { + SPS.mesh.rotation.z = t / 10; + t += 0.1; + }); + + return scene; +} diff --git a/src/compiledDemos/SPSCollisions/index.html b/src/compiledDemos/SPSCollisions/index.html new file mode 100644 index 000000000..ee2a4b85f --- /dev/null +++ b/src/compiledDemos/SPSCollisions/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - SPS Collisions demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SPSCollisions/main.ts b/src/compiledDemos/SPSCollisions/main.ts new file mode 100644 index 000000000..c83701137 --- /dev/null +++ b/src/compiledDemos/SPSCollisions/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSPSCollisionsTestScene } from "./scene"; + +runDemo({ createScene: createSPSCollisionsTestScene }); diff --git a/src/compiledDemos/SPSCollisions/scene.ts b/src/compiledDemos/SPSCollisions/scene.ts new file mode 100644 index 000000000..a002d05b0 --- /dev/null +++ b/src/compiledDemos/SPSCollisions/scene.ts @@ -0,0 +1,164 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; +import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; +import { CreateBox } from "@babylonjs/core/Meshes/Builders/boxBuilder"; +import { CreatePolyhedron } from "@babylonjs/core/Meshes/Builders/polyhedronBuilder"; +import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; +import type { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Scene } from "@babylonjs/core/scene"; + +export function createSPSCollisionsTestScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + scene.clearColor = new Color3(0.4, 0.6, 0.9).toColor4(1); + const camera = new ArcRotateCamera("camera1", 0, 0, 0, new Vector3(0, 0, 0), scene); + camera.setPosition(new Vector3(0, 100, -200)); + camera.attachControl(canvas, true); + + const pl = new PointLight("pl", new Vector3(0, 0, 0), scene); + pl.diffuse = new Color3(1, 1, 1); + pl.specular = new Color3(1, 1, 0.8); + pl.intensity = 0.95; + pl.position = camera.position; + + const sphereRadius = 18.0; + const boxSize = 4.0; + const ground = CreateGround("gd", { width: 1000.0, height: 1000.0 }, scene); + const sphere = CreateSphere("sphere", { segments: 10, diameter: sphereRadius * 2.0 }, scene); + const box = CreateBox("b", { size: boxSize }, scene); + const poly = CreatePolyhedron("p", { size: boxSize, type: 4, flat: true }, scene); + const tetra = CreatePolyhedron("t", { size: boxSize / 2.0, flat: true }, scene); + const matSphere = new StandardMaterial("ms", scene); + const matGround = new StandardMaterial("mg", scene); + matSphere.diffuseColor = Color3.Red(); + matGround.diffuseColor = new Color3(0.65, 0.6, 0.5); + sphere.material = matSphere; + ground.material = matGround; + ground.freezeWorldMatrix(); + matSphere.freeze(); + matGround.freeze(); + + // Particle system + const particleNb = 1200; + const nb = (particleNb / 3) | 0; + const SPS = new SolidParticleSystem("SPS", scene, { particleIntersection: true }); + SPS.addShape(box, nb); + SPS.addShape(poly, nb); + SPS.addShape(tetra, nb); + box.dispose(); + poly.dispose(); + tetra.dispose(); + const mesh = SPS.buildMesh(); + mesh.hasVertexAlpha = true; + SPS.isAlwaysVisible = true; + SPS.computeParticleTexture = false; + + // position things + mesh.position.y = 80.0; + mesh.position.x = -70.0; + const sphereAltitude = mesh.position.y / 2.0; + sphere.position.y = sphereAltitude; + + // shared variables + const speed = 1.9; // particle max speed + const cone = 0.5; // emitter aperture + const gravity = -speed / 100; // gravity + const restitution = 0.99; // energy restitution + let k = 0.0; + let sign = 1; + const tmpPos = Vector3.Zero(); // current particle world position + const tmpNormal = Vector3.Zero(); // current sphere normal on intersection point + let tmpDot = 0.0; // current dot product + let bboxesComputed = false; // the bbox are actually computed only after the first particle.update() + + // SPS initialization : just recycle all + SPS.initParticles = function () { + for (let p = 0; p < SPS.nbParticles; p++) { + SPS.recycleParticle(SPS.particles[p]); + } + }; + + // recycle : reset the particle at the emitter origin + SPS.recycleParticle = function (particle: SolidParticle) { + particle.position.x = 0; + particle.position.y = 0; + particle.position.z = 0; + particle.velocity.x = Math.random() * speed; + particle.velocity.y = (Math.random() - 0.3) * cone * speed; + particle.velocity.z = (Math.random() - 0.5) * cone * speed; + + particle.rotation.x = Math.random() * Math.PI; + particle.rotation.y = Math.random() * Math.PI; + particle.rotation.z = Math.random() * Math.PI; + + particle.scaling.x = Math.random() + 0.1; + particle.scaling.y = Math.random() + 0.1; + particle.scaling.z = Math.random() + 0.1; + + particle.color!.r = Math.random() + 0.1; + particle.color!.g = Math.random() + 0.1; + particle.color!.b = Math.random() + 0.1; + particle.color!.a = 1.0; + return particle; + }; + + // particle behavior + SPS.updateParticle = function (particle: SolidParticle) { + // recycle if touched the ground + if (particle.position.y + mesh.position.y < ground.position.y + boxSize) { + particle.position.y = ground.position.y - mesh.position.y + boxSize / 2.0; + particle.color!.a -= 0.05; + if (particle.color!.a < 0) { + this.recycleParticle(particle); + } + return particle; + } + + // update velocity, rotation and position + particle.velocity.y += gravity; // apply gravity to y + particle.position.addInPlace(particle.velocity); // update particle new position + sign = particle.idx % 2 == 0 ? 1 : -1; // rotation sign and then new value + particle.rotation.z += 0.1 * sign; + particle.rotation.x += 0.05 * sign; + particle.rotation.y += 0.008 * sign; + + // intersection + if (bboxesComputed && particle.intersectsMesh(sphere)) { + particle.position.addToRef(mesh.position, tmpPos); // particle World position + tmpPos.subtractToRef(sphere.position, tmpNormal); // normal to the sphere + tmpNormal.normalize(); // normalize the sphere normal + tmpDot = Vector3.Dot(particle.velocity, tmpNormal); // dot product (velocity, normal) + // bounce result computation + particle.velocity.x = -particle.velocity.x + 2.0 * tmpDot * tmpNormal.x; + particle.velocity.y = -particle.velocity.y + 2.0 * tmpDot * tmpNormal.y; + particle.velocity.z = -particle.velocity.z + 2.0 * tmpDot * tmpNormal.z; + particle.velocity.scaleInPlace(restitution); // aply restitution + particle.rotation.x *= -1.0; + particle.rotation.y *= -1.0; + particle.rotation.z *= -1.0; + } + return particle; + }; + + SPS.afterUpdateParticles = function () { + bboxesComputed = true; + }; + + // init all particle values + SPS.initParticles(); + + // animation + scene.registerBeforeRender(function () { + SPS.setParticles(); + sphere.position.x = 30.0 * Math.sin(k); + sphere.position.z = 20.0 * Math.sin(k * 6.0); + sphere.position.y = 8.0 * Math.sin(k * 8.0) + sphereAltitude; + k += 0.02; + }); + + return scene; +} diff --git a/src/compiledDemos/SSAO/index.html b/src/compiledDemos/SSAO/index.html new file mode 100644 index 000000000..efec1b9b0 --- /dev/null +++ b/src/compiledDemos/SSAO/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - SSAO demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SSAO/main.ts b/src/compiledDemos/SSAO/main.ts new file mode 100644 index 000000000..1703c3821 --- /dev/null +++ b/src/compiledDemos/SSAO/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSSAOScene } from "./scene"; + +runDemo({ createScene: createSSAOScene }); diff --git a/src/compiledDemos/SSAO/scene.ts b/src/compiledDemos/SSAO/scene.ts new file mode 100644 index 000000000..705221fc5 --- /dev/null +++ b/src/compiledDemos/SSAO/scene.ts @@ -0,0 +1,30 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { SSAORenderingPipeline } from "@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline"; +import { AppendSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { Scene } from "@babylonjs/core/scene"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Rendering/depthRendererSceneComponent"; +import "@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent"; + +export async function createSSAOScene(engine: Engine, canvas: HTMLCanvasElement): Promise { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", -2.5, 1.0, 200, new Vector3(0, 0, 0), scene); + camera.attachControl(canvas, true); + + await AppendSceneAsync("/Scenes/Assets/SSAOcat.babylon", scene); + + scene.activeCamera = camera; + + const ssao = new SSAORenderingPipeline("ssaopipeline", scene, { ssaoRatio: 0.5, combineRatio: 1.0 }); + ssao.fallOff = 0.000001; + ssao.area = 1; + ssao.radius = 0.0004; + ssao.totalStrength = 2; + ssao.base = 1.3; + + scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssaopipeline", camera); + + return scene; +} diff --git a/src/compiledDemos/SSAO2/index.html b/src/compiledDemos/SSAO2/index.html new file mode 100644 index 000000000..e14966665 --- /dev/null +++ b/src/compiledDemos/SSAO2/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - SSAO 2 demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SSAO2/main.ts b/src/compiledDemos/SSAO2/main.ts new file mode 100644 index 000000000..1703c3821 --- /dev/null +++ b/src/compiledDemos/SSAO2/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSSAOScene } from "./scene"; + +runDemo({ createScene: createSSAOScene }); diff --git a/src/compiledDemos/SSAO2/scene.ts b/src/compiledDemos/SSAO2/scene.ts new file mode 100644 index 000000000..9e4e1e136 --- /dev/null +++ b/src/compiledDemos/SSAO2/scene.ts @@ -0,0 +1,38 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { SSAO2RenderingPipeline } from "@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline"; +import { AppendSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { Scene } from "@babylonjs/core/scene"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Rendering/depthRendererSceneComponent"; +import "@babylonjs/core/Rendering/geometryBufferRendererSceneComponent"; +import "@babylonjs/core/Rendering/prePassRendererSceneComponent"; +import "@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent"; + +export async function createSSAOScene(engine: Engine, canvas: HTMLCanvasElement): Promise { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", -2.5, 1.0, 200, new Vector3(0, 0, 0), scene); + camera.attachControl(canvas, true); + + await AppendSceneAsync("/Scenes/Assets/SSAOcat.babylon", scene); + + scene.activeCamera = camera; + + const ssaoRatio = { + ssaoRatio: 0.5, + blurRatio: 1.0, + }; + + const ssao = new SSAO2RenderingPipeline("ssao", scene, ssaoRatio); + ssao.radius = 42; + ssao.totalStrength = 0.9; + ssao.base = 0.2; + ssao.expensiveBlur = true; + ssao.samples = 16; + ssao.maxZ = 2500; + + scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera); + + return scene; +} diff --git a/src/compiledDemos/SelfShadowing/index.html b/src/compiledDemos/SelfShadowing/index.html new file mode 100644 index 000000000..75cc05ea5 --- /dev/null +++ b/src/compiledDemos/SelfShadowing/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Self Shadowing demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SelfShadowing/main.ts b/src/compiledDemos/SelfShadowing/main.ts new file mode 100644 index 000000000..08a75e2d7 --- /dev/null +++ b/src/compiledDemos/SelfShadowing/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSelfShadowingScene } from "./scene"; + +runDemo({ createScene: createSelfShadowingScene }); diff --git a/src/compiledDemos/SelfShadowing/scene.ts b/src/compiledDemos/SelfShadowing/scene.ts new file mode 100644 index 000000000..21177dc01 --- /dev/null +++ b/src/compiledDemos/SelfShadowing/scene.ts @@ -0,0 +1,49 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateTorusKnot } from "@babylonjs/core/Meshes/Builders/torusKnotBuilder"; +import { Scene } from "@babylonjs/core/scene"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; + +export function createSelfShadowingScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + + const camera = new FreeCamera("Camera", new Vector3(0, 0, -20), scene); + camera.attachControl(canvas, true); + + const light = new DirectionalLight("dir01", new Vector3(-1, -2, -1), scene); + light.position = new Vector3(20, 40, 20); + + const torus = CreateTorusKnot( + "knot", + { radius: 2, tube: 0.5, radialSegments: 128, tubularSegments: 64, p: 2, q: 3 }, + scene + ); + torus.position.x = -5; + + const torus2 = CreateTorusKnot( + "knot", + { radius: 2, tube: 0.5, radialSegments: 128, tubularSegments: 64, p: 2, q: 3 }, + scene + ); + torus2.position.x = 5; + + const shadowGenerator = new ShadowGenerator(1024, light, true); + shadowGenerator.getShadowMap()!.renderList!.push(torus); + shadowGenerator.useBlurExponentialShadowMap = true; + light.shadowMinZ = 1; + light.shadowMaxZ = 2500; + shadowGenerator.depthScale = 2500; + shadowGenerator.bias = 0.001; + + torus.receiveShadows = true; + + scene.registerBeforeRender(() => { + torus.rotation.x += 0.01; + torus2.rotation.x += 0.01; + }); + + return scene; +} diff --git a/src/compiledDemos/Simplification/index.html b/src/compiledDemos/Simplification/index.html new file mode 100644 index 000000000..12963bfee --- /dev/null +++ b/src/compiledDemos/Simplification/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Simplification demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Simplification/main.ts b/src/compiledDemos/Simplification/main.ts new file mode 100644 index 000000000..d00d6142a --- /dev/null +++ b/src/compiledDemos/Simplification/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSimplificationScene } from "./scene"; + +runDemo({ createScene: createSimplificationScene }); diff --git a/src/compiledDemos/Simplification/scene.ts b/src/compiledDemos/Simplification/scene.ts new file mode 100644 index 000000000..3dbd937a6 --- /dev/null +++ b/src/compiledDemos/Simplification/scene.ts @@ -0,0 +1,41 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { Scene } from "@babylonjs/core/scene"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { ImportMeshAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { SimplificationType } from "@babylonjs/core/Meshes/meshSimplification"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Meshes/meshSimplificationSceneComponent"; + +export function createSimplificationScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("ArcRotateCamera", 1, 0.8, 100, Vector3.Zero(), scene); + camera.setTarget(Vector3.Zero()); + camera.attachControl(canvas, false); + const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene); + light.intensity = 0.5; + + scene.registerBeforeRender(function () { + camera.alpha += 0.005; + }); + + ImportMeshAsync("/Scenes/Dude/Dude.babylon", scene).then((result) => { + const mainMesh = (result.meshes[1] || result.meshes[0]) as Mesh; + camera.setTarget(mainMesh.getBoundingInfo().boundingBox.center); + + // Progressive mesh simplification: builds decimated LOD levels shown at distance. + mainMesh.simplify( + [ + { quality: 0.8, distance: 30, optimizeMesh: true }, + { quality: 0.5, distance: 60, optimizeMesh: true }, + { quality: 0.3, distance: 100, optimizeMesh: true }, + ], + true, + SimplificationType.QUADRATIC + ); + }); + + return scene; +} diff --git a/src/compiledDemos/SoftShadows/index.html b/src/compiledDemos/SoftShadows/index.html new file mode 100644 index 000000000..07d8dde74 --- /dev/null +++ b/src/compiledDemos/SoftShadows/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Soft Shadows demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SoftShadows/main.ts b/src/compiledDemos/SoftShadows/main.ts new file mode 100644 index 000000000..59cb7d535 --- /dev/null +++ b/src/compiledDemos/SoftShadows/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSoftShadowsScene } from "./scene"; + +runDemo({ createScene: createSoftShadowsScene }); diff --git a/src/compiledDemos/SoftShadows/scene.ts b/src/compiledDemos/SoftShadows/scene.ts new file mode 100644 index 000000000..e164ad526 --- /dev/null +++ b/src/compiledDemos/SoftShadows/scene.ts @@ -0,0 +1,66 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { AppendSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { Scene } from "@babylonjs/core/scene"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; + +export async function createSoftShadowsScene(engine: Engine, canvas: HTMLCanvasElement): Promise { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", -2.5, 1.0, 200, new Vector3(0, 1.0, 0), scene); + + await AppendSceneAsync("/Scenes/Assets/SSAOcat.babylon", scene); + + scene.lights[0].dispose(); + scene.activeCamera = camera; + camera.attachControl(canvas, false); + + const light = new DirectionalLight("light", new Vector3(0, -0.5, 0.8), scene); + const light2 = new DirectionalLight("light", new Vector3(0, -0.5, 0.8), scene); + const light3 = new DirectionalLight("light", new Vector3(0, -0.5, 0.8), scene); + + light.position = new Vector3(0, 120.0, -10); + light2.position = new Vector3(0, 120.0, -10); + light3.position = new Vector3(0, 120.0, -10); + + light.diffuse = Color3.Red(); + light2.diffuse = Color3.Green(); + light3.diffuse = Color3.Blue(); + + const cat = scene.meshes[2]; + cat.receiveShadows = false; + + const generator = new ShadowGenerator(512, light); + generator.getShadowMap()!.renderList!.push(cat); + generator.useBlurExponentialShadowMap = true; + generator.blurBoxOffset = 2.0; + + const generator2 = new ShadowGenerator(512, light2); + generator2.getShadowMap()!.renderList!.push(cat); + generator2.useBlurExponentialShadowMap = true; + generator2.blurBoxOffset = 2.0; + + const generator3 = new ShadowGenerator(512, light3); + generator3.getShadowMap()!.renderList!.push(cat); + generator3.useBlurExponentialShadowMap = true; + generator3.blurBoxOffset = 2.0; + + let alpha = 0; + scene.registerBeforeRender(() => { + light.direction.z = 0.8 * Math.cos(alpha); + light.direction.x = 0.3 * Math.sin(alpha); + + light2.direction.z = 0.3 * Math.cos(alpha); + light2.direction.x = 0.8 * Math.sin(alpha); + + light3.direction.x = 0.3 * Math.cos(alpha); + light3.direction.z = 0.8 * Math.sin(alpha); + alpha += 0.01; + }); + + return scene; +} diff --git a/src/compiledDemos/SpaceDeK/index.html b/src/compiledDemos/SpaceDeK/index.html new file mode 100644 index 000000000..d1e4ee473 --- /dev/null +++ b/src/compiledDemos/SpaceDeK/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - SpaceDeK demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SpaceDeK/main.ts b/src/compiledDemos/SpaceDeK/main.ts new file mode 100644 index 000000000..f77882a54 --- /dev/null +++ b/src/compiledDemos/SpaceDeK/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSpaceDeKScene } from "./scene"; + +runDemo({ createScene: createSpaceDeKScene }); diff --git a/src/compiledDemos/SpaceDeK/scene.ts b/src/compiledDemos/SpaceDeK/scene.ts new file mode 100644 index 000000000..515b7e9a0 --- /dev/null +++ b/src/compiledDemos/SpaceDeK/scene.ts @@ -0,0 +1,11 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createSpaceDeKScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/SpaceDeK/SpaceDek.babylon", engine); + scene.collisionsEnabled = false; + return scene; +} diff --git a/src/compiledDemos/Spaceship/index.html b/src/compiledDemos/Spaceship/index.html new file mode 100644 index 000000000..e9f86b268 --- /dev/null +++ b/src/compiledDemos/Spaceship/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Spaceship demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Spaceship/main.ts b/src/compiledDemos/Spaceship/main.ts new file mode 100644 index 000000000..c52e7e7d3 --- /dev/null +++ b/src/compiledDemos/Spaceship/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSpaceshipScene } from "./scene"; + +runDemo({ createScene: createSpaceshipScene }); diff --git a/src/compiledDemos/Spaceship/scene.ts b/src/compiledDemos/Spaceship/scene.ts new file mode 100644 index 000000000..cd8467daf --- /dev/null +++ b/src/compiledDemos/Spaceship/scene.ts @@ -0,0 +1,11 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createSpaceshipScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Spaceship/Spaceship.babylon", engine); + scene.collisionsEnabled = true; + return scene; +} diff --git a/src/compiledDemos/SponzaDynamicShadows/index.html b/src/compiledDemos/SponzaDynamicShadows/index.html new file mode 100644 index 000000000..b61a44193 --- /dev/null +++ b/src/compiledDemos/SponzaDynamicShadows/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Sponza Dynamic Shadows demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/SponzaDynamicShadows/main.ts b/src/compiledDemos/SponzaDynamicShadows/main.ts new file mode 100644 index 000000000..902f97277 --- /dev/null +++ b/src/compiledDemos/SponzaDynamicShadows/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createSponzaDynamicShadowsScene } from "./scene"; + +runDemo({ createScene: createSponzaDynamicShadowsScene }); diff --git a/src/compiledDemos/SponzaDynamicShadows/scene.ts b/src/compiledDemos/SponzaDynamicShadows/scene.ts new file mode 100644 index 000000000..11f595837 --- /dev/null +++ b/src/compiledDemos/SponzaDynamicShadows/scene.ts @@ -0,0 +1,74 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { Mesh } from "@babylonjs/core/Meshes/mesh"; +import type { ShadowLight } from "@babylonjs/core/Lights/shadowLight"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import { RegisterShadowGeneratorSceneComponent } from "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3, Quaternion } from "@babylonjs/core/Maths/math.vector"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.renderTargetCube"; + +// The shadow-generator .babylon parser is only registered when a ShadowGenerator is +// constructed; this scene parses pre-authored generators from the file, so register it first. +RegisterShadowGeneratorSceneComponent(ShadowGenerator); + +export async function createSponzaDynamicShadowsScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/SponzaDynamicShadows/SponzaDynamicShadows.babylon", engine); + scene.collisionsEnabled = true; + + const node = scene.getMeshByName("litghtmesh") as Mesh; + const particleSystem = new ParticleSystem("New Particle System", 1000, scene); + particleSystem.emitter = node; + particleSystem.renderingGroupId = 0; + particleSystem.emitRate = 200; + particleSystem.manualEmitCount = -1; + particleSystem.updateSpeed = 0.005; + particleSystem.targetStopDuration = 0; + particleSystem.disposeOnStop = false; + particleSystem.minEmitPower = 0; + particleSystem.maxEmitPower = 0.3; + particleSystem.minLifeTime = 0.2; + particleSystem.maxLifeTime = 0.5; + particleSystem.minSize = 0.05; + particleSystem.maxSize = 0.8; + particleSystem.minAngularSpeed = 0; + particleSystem.maxAngularSpeed = 6.283185307179586; + particleSystem.layerMask = 268435455; + particleSystem.blendMode = 0; + particleSystem.forceDepthWrite = false; + particleSystem.gravity = new Vector3(0, 0, 0); + particleSystem.direction1 = new Vector3(-7, 8, 3); + particleSystem.direction2 = new Vector3(7, 8, -3); + particleSystem.minEmitBox = new Vector3(0, 0, 0); + particleSystem.maxEmitBox = new Vector3(0, 0, 0); + particleSystem.color1 = new Color4(0.7, 0.8, 0.5465114353377606, 1); + particleSystem.color2 = new Color4(0.6707185797327061, 0.5, 0.23185333620389842, 1); + particleSystem.colorDead = new Color4(0.2980971465478694, 0, 0.3312190517198549, 1); + particleSystem.textureMask = new Color4(1, 1, 1, 1); + particleSystem.particleTexture = new Texture("/Scenes/WorldMonger/Assets/Flare.png", scene); + particleSystem.start(); + + node.position = new Vector3(2.5223299803446766, 2.0876, -3.525673483620715); + node.rotation = new Vector3(0, 0, 0); + node.rotationQuaternion = new Quaternion(0, 0, 0, -1); + node.scaling = new Vector3(1, 1, 1); + + // Clear the serialized direction so the point lights cast full omnidirectional cube shadows + (scene.getLightByName("Omni002") as unknown as { direction: Vector3 | null }).direction = null; + (scene.getLightByName("Omni001") as unknown as { direction: Vector3 | null }).direction = null; + + let shadowGenerator = (scene.getLightByName("Omni002") as ShadowLight).getShadowGenerator() as ShadowGenerator; + shadowGenerator.getShadowMap()!.refreshRate = 0; + shadowGenerator.forceBackFacesOnly = true; + shadowGenerator.bias = 0.01; + + shadowGenerator = (scene.getLightByName("Omni001") as ShadowLight).getShadowGenerator() as ShadowGenerator; + shadowGenerator.forceBackFacesOnly = true; + shadowGenerator.bias = 0.01; + + return scene; +} diff --git a/src/compiledDemos/Starfield/index.html b/src/compiledDemos/Starfield/index.html new file mode 100644 index 000000000..7a5b626c3 --- /dev/null +++ b/src/compiledDemos/Starfield/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Starfield demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Starfield/main.ts b/src/compiledDemos/Starfield/main.ts new file mode 100644 index 000000000..134e8ce0b --- /dev/null +++ b/src/compiledDemos/Starfield/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createStarfieldScene } from "./scene"; + +runDemo({ createScene: createStarfieldScene }); diff --git a/src/compiledDemos/Starfield/scene.ts b/src/compiledDemos/Starfield/scene.ts new file mode 100644 index 000000000..adbda8b38 --- /dev/null +++ b/src/compiledDemos/Starfield/scene.ts @@ -0,0 +1,39 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; +import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { CreateCylinder } from "@babylonjs/core/Meshes/Builders/cylinderBuilder"; +import { Scene } from "@babylonjs/core/scene"; +import { StarfieldProceduralTexture } from "@babylonjs/procedural-textures/starfield/starfieldProceduralTexture"; + +export function createStarfieldScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + const camera = new ArcRotateCamera("Camera", 0, 0, -30, Vector3.Zero(), scene); + camera.attachControl(canvas, true); + + new HemisphericLight("hemi", new Vector3(0, 0.5, 0), scene); + + const spaceScale = 10.0; + const space = CreateCylinder( + "space", + { height: 10 * spaceScale, diameterTop: 0, diameterBottom: 6 * spaceScale, tessellation: 20, subdivisions: 20 }, + scene + ); + + const starfieldPT = new StarfieldProceduralTexture("starfieldPT", 512, scene); + const starfieldMaterial = new StandardMaterial("starfield", scene); + starfieldMaterial.diffuseTexture = starfieldPT; + starfieldMaterial.diffuseTexture.coordinatesMode = Texture.SKYBOX_MODE; + starfieldMaterial.backFaceCulling = false; + starfieldPT.beta = 0.1; + + space.material = starfieldMaterial; + + scene.registerBeforeRender(() => { + starfieldPT.time += scene.getAnimationRatio() * 0.8; + }); + + return scene; +} diff --git a/src/compiledDemos/Train/index.html b/src/compiledDemos/Train/index.html new file mode 100644 index 000000000..9945fbc71 --- /dev/null +++ b/src/compiledDemos/Train/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Train demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Train/main.ts b/src/compiledDemos/Train/main.ts new file mode 100644 index 000000000..13aa1b374 --- /dev/null +++ b/src/compiledDemos/Train/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createTrainScene } from "./scene"; + +runDemo({ createScene: createTrainScene }); diff --git a/src/compiledDemos/Train/scene.ts b/src/compiledDemos/Train/scene.ts new file mode 100644 index 000000000..18995d800 --- /dev/null +++ b/src/compiledDemos/Train/scene.ts @@ -0,0 +1,70 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import type { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial"; +import { Matrix } from "@babylonjs/core/Maths/math.vector"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { BlackAndWhitePostProcess } from "@babylonjs/core/PostProcesses/blackAndWhitePostProcess"; +import { FilterPostProcess } from "@babylonjs/core/PostProcesses/filterPostProcess"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Materials/Textures/mirrorTexture"; +import "@babylonjs/core/Particles/particleSystemComponent"; +import "@babylonjs/core/LensFlares/lensFlareSystemSceneComponent"; + +export async function createTrainScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Train/Train.babylon", engine); + scene.collisionsEnabled = false; + + for (const camera of scene.cameras) { + camera.minZ = 10; + } + + if (scene.cameras.length > 6) { + scene.activeCamera = scene.cameras[6]; + } + + const terrainEau = scene.getMaterialByName("terrain_eau") as StandardMaterial | null; + if (terrainEau) { + terrainEau.bumpTexture = null; + } + + // The scene file declares the lens flare emitter (emitterId) as the "sun" light. + // Re-wire it explicitly in case the loader leaves the emitter unresolved. + for (const lensFlareSystem of scene.lensFlareSystems) { + if (!lensFlareSystem.getEmitter()) { + const sun = scene.getLightByName("sun"); + if (sun) { + lensFlareSystem.setEmitter(sun); + } + } + } + + if (scene.cameras.length > 2) { + new BlackAndWhitePostProcess("Black and White", 1.0, scene.cameras[2]); + scene.cameras[2].name = "B&W"; + } + + if (scene.cameras.length > 3) { + const sepiaKernelMatrix = Matrix.FromValues( + 0.393, + 0.349, + 0.272, + 0, + 0.769, + 0.686, + 0.534, + 0, + 0.189, + 0.168, + 0.131, + 0, + 0, + 0, + 0, + 0 + ); + new FilterPostProcess("Sepia", sepiaKernelMatrix, 1.0, scene.cameras[3]); + scene.cameras[3].name = "SEPIA"; + } + + return scene; +} diff --git a/src/compiledDemos/Tunnel/index.html b/src/compiledDemos/Tunnel/index.html new file mode 100644 index 000000000..4442dc2bf --- /dev/null +++ b/src/compiledDemos/Tunnel/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Tunnel demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Tunnel/main.ts b/src/compiledDemos/Tunnel/main.ts new file mode 100644 index 000000000..b82652072 --- /dev/null +++ b/src/compiledDemos/Tunnel/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createTunnelScene } from "./scene"; + +runDemo({ createScene: createTunnelScene }); diff --git a/src/compiledDemos/Tunnel/scene.ts b/src/compiledDemos/Tunnel/scene.ts new file mode 100644 index 000000000..b524305f2 --- /dev/null +++ b/src/compiledDemos/Tunnel/scene.ts @@ -0,0 +1,57 @@ +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import type { Engine } from "@babylonjs/core/Engines/engine"; +import { PointLight } from "@babylonjs/core/Lights/pointLight"; +import { Effect } from "@babylonjs/core/Materials/effect"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { PostProcess } from "@babylonjs/core/PostProcesses/postProcess"; +import { Scene } from "@babylonjs/core/scene"; + +Effect.ShadersStore.tunnelppFragmentShader = ` +precision highp float; +varying vec2 vUV; +uniform sampler2D tunnelSampler; +uniform float time; +void main(void) { + vec2 position = -1.0 + 2.0 * vUV; + vec2 uv; + float r = sqrt(dot(position, position)); + float a = atan(position.y, position.x) + 0.9 * sin(0.5 * r - 0.5 * time); + float h = (0.5 + 0.5 * sin(9.0 * a)); + float s = smoothstep(0.4, 0.5, h); + uv.x = time + 1.0 / (r + 0.1 * s); + uv.y = 3.0 * a / 3.1416; + vec3 col = texture2D(tunnelSampler, uv).xyz; + float ao = smoothstep(0.0, 0.3, h) - smoothstep(0.5, 1.0, h); + col *= 1.0 - 0.6 * ao * r; + col *= r * r; + gl_FragColor = vec4(col, 1.0); +}`; + +export function createTunnelScene(engine: Engine, canvas: HTMLCanvasElement): Scene { + const scene = new Scene(engine); + scene.clearColor = new Color4(0, 0, 0, 1); + + const camera = new ArcRotateCamera("Camera", 0, Math.PI / 2, 400, Vector3.Zero(), scene); + camera.setTarget(Vector3.Zero()); + camera.attachControl(canvas, true); + + const light = new PointLight("light1", new Vector3(0, 0, 10), scene); + light.position = camera.position; + + const tunnelTexture = new Texture("/Demos/Tunnel/Inundation.jpg", scene); + + const tunnelShader = new PostProcess("Tunnel", "tunnelpp", ["time"], ["tunnelSampler"], 0.9, camera); + + let time = 0.0; + tunnelShader.onApply = (effect) => { + effect.setFloat("time", time / 5.0); + if (tunnelTexture.isReady()) { + effect.setTexture("tunnelSampler", tunnelTexture); + } + time += 0.1; + }; + + return scene; +} diff --git a/src/compiledDemos/V8/index.html b/src/compiledDemos/V8/index.html new file mode 100644 index 000000000..54e28cf57 --- /dev/null +++ b/src/compiledDemos/V8/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - V8 demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/V8/main.ts b/src/compiledDemos/V8/main.ts new file mode 100644 index 000000000..01fb53b09 --- /dev/null +++ b/src/compiledDemos/V8/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createV8Scene } from "./scene"; + +runDemo({ createScene: createV8Scene }); diff --git a/src/compiledDemos/V8/scene.ts b/src/compiledDemos/V8/scene.ts new file mode 100644 index 000000000..ce8ce35c7 --- /dev/null +++ b/src/compiledDemos/V8/scene.ts @@ -0,0 +1,24 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator"; +import "@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createV8Scene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/V8/v8.babylon", engine); + scene.collisionsEnabled = true; + + if (scene.activeCamera) { + scene.activeCamera.minZ = 1; + } + + const shadowGenerator = scene.lights[0]?.getShadowGenerator(); + if (shadowGenerator instanceof ShadowGenerator) { + shadowGenerator.usePoissonSampling = true; + shadowGenerator.bias = 0.01; + } + + return scene; +} diff --git a/src/compiledDemos/Viper/index.html b/src/compiledDemos/Viper/index.html new file mode 100644 index 000000000..4ab98a299 --- /dev/null +++ b/src/compiledDemos/Viper/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - Viper demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/Viper/main.ts b/src/compiledDemos/Viper/main.ts new file mode 100644 index 000000000..a23e55dfc --- /dev/null +++ b/src/compiledDemos/Viper/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createViperScene } from "./scene"; + +runDemo({ createScene: createViperScene }); diff --git a/src/compiledDemos/Viper/scene.ts b/src/compiledDemos/Viper/scene.ts new file mode 100644 index 000000000..8e1a1a8b8 --- /dev/null +++ b/src/compiledDemos/Viper/scene.ts @@ -0,0 +1,11 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createViperScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/Viper/Viper.babylon", engine); + scene.collisionsEnabled = true; + return scene; +} diff --git a/src/compiledDemos/WCafe/index.html b/src/compiledDemos/WCafe/index.html new file mode 100644 index 000000000..32e2881e9 --- /dev/null +++ b/src/compiledDemos/WCafe/index.html @@ -0,0 +1,105 @@ + + + + + + Babylon.js - WCafe demo + + + + +
+ + +
+ Source +
+
+ + + + diff --git a/src/compiledDemos/WCafe/main.ts b/src/compiledDemos/WCafe/main.ts new file mode 100644 index 000000000..7f21ba7b5 --- /dev/null +++ b/src/compiledDemos/WCafe/main.ts @@ -0,0 +1,4 @@ +import { runDemo } from "../shared/demoRunner"; +import { createWCafeScene } from "./scene"; + +runDemo({ createScene: createWCafeScene }); diff --git a/src/compiledDemos/WCafe/scene.ts b/src/compiledDemos/WCafe/scene.ts new file mode 100644 index 000000000..92515c820 --- /dev/null +++ b/src/compiledDemos/WCafe/scene.ts @@ -0,0 +1,11 @@ +import type { Engine } from "@babylonjs/core/Engines/engine"; +import type { Scene } from "@babylonjs/core/scene"; +import { LoadSceneAsync } from "@babylonjs/core/Loading/sceneLoader"; +import "@babylonjs/core/Loading/Plugins/babylonFileLoader"; +import "@babylonjs/core/Engines/Extensions/engine.cubeTexture"; + +export async function createWCafeScene(engine: Engine): Promise { + const scene = await LoadSceneAsync("/Scenes/WCafe/WCafe.babylon", engine); + scene.collisionsEnabled = true; + return scene; +} diff --git a/src/compiledDemos/manifest.json b/src/compiledDemos/manifest.json index d3e43c54b..9ee764cbb 100644 --- a/src/compiledDemos/manifest.json +++ b/src/compiledDemos/manifest.json @@ -453,6 +453,378 @@ "timeoutMs": 60000, "minimumColoredSamples": 160 } + }, + { + "slug": "Viper", + "title": "Babylon.js - Viper demo", + "legacyPath": "static/Demos/Viper", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Mansion", + "title": "Babylon.js - Mansion demo", + "legacyPath": "static/Demos/Mansion", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "V8", + "title": "Babylon.js - V8 demo", + "legacyPath": "static/Demos/V8", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Heart", + "title": "Babylon.js - Heart demo", + "legacyPath": "static/Demos/Heart", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "WCafe", + "title": "Babylon.js - WCafe demo", + "legacyPath": "static/Demos/WCafe", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Spaceship", + "title": "Babylon.js - Spaceship demo", + "legacyPath": "static/Demos/Spaceship", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "SpaceDeK", + "title": "Babylon.js - SpaceDeK demo", + "legacyPath": "static/Demos/SpaceDeK", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Espilit", + "title": "Babylon.js - Espilit demo", + "legacyPath": "static/Demos/Espilit", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 60000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "HillValley", + "title": "Babylon.js - HillValley demo", + "legacyPath": "static/Demos/HillValley", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 60000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Facets", + "title": "Babylon.js - Facets demo", + "legacyPath": "static/Demos/Facets", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Bones", + "title": "Babylon.js - Bones demo", + "legacyPath": "static/Demos/Bones", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 40000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Instances", + "title": "Babylon.js - Instances demo", + "legacyPath": "static/Demos/Instances", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "timeoutMs": 60000, + "minimumColoredSamples": 80 + } + }, + { + "slug": "Flat2009", + "title": "Babylon.js - Flat 2009 demo", + "legacyPath": "static/Demos/Flat2009", + "sourceFiles": ["main.ts", "scene.ts"], + "renderCheck": { + "disabled": true, + "disabledReason": "VideoTexture GPU upload (texImage2D of a