From 1677e5ade8cee023c9a9693ae0104409aa863974 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Fri, 25 Mar 2022 19:55:50 +0100 Subject: [PATCH] [Build] Local Server changes (#12262) * npm start * small changes to the babylon-server * update documentation * update doc * revert cleanup changes * update ignore file * added compute files to ignore list Former-commit-id: 31aaa11300dba1b86788febed3b91a209089ba57 --- .prettierignore | 7 +- buildSystem.md | 4 +- package.json | 3 +- packages/tools/babylonServer/.gitignore | 1 + packages/tools/babylonServer/package.json | 3 +- .../babylonServer/scripts/generateScripts.js | 172 +++++++++++++++++ packages/tools/babylonServer/src/sceneJs.js | 177 +++--------------- packages/tools/babylonServer/tsconfig.json | 3 + packages/tools/guiEditor/webpack.config.js | 1 - 9 files changed, 211 insertions(+), 160 deletions(-) create mode 100644 packages/tools/babylonServer/scripts/generateScripts.js diff --git a/.prettierignore b/.prettierignore index 5befbf1f4f2..b22ce4d61e1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,7 @@ Shaders -ShadersWGSL \ No newline at end of file +ShadersWGSL +createScene.* +createEngine.* +*.vertex.ts +*.fragment.ts +*.compute.ts \ No newline at end of file diff --git a/buildSystem.md b/buildSystem.md index 18551847d12..970386b0ff4 100644 --- a/buildSystem.md +++ b/buildSystem.md @@ -656,7 +656,9 @@ A new package introduced in the babylon server, which is a direct copy of the ba Similar to the dev host, the babylon server will take the latest compiled code from the dev (or lts) packages and serve it to the browser. The default address for the local CDN is -The babylon server's index.html has references to all of our public packages and has the BABYLON namespace populated, similar to the way the playground is working. *If you want to debug a playground scene without starting the playground*, edit the file sceneJs.js or sceneTs.ts for typescript, and open or +The babylon server's index.html has references to all of our public packages and has the BABYLON namespace populated, similar to the way the playground is working. When the repository initializes the server generates two files - createScene and createEngine. Those files are not a part of the git repository and can be changed in any way you wish. createScene can be async if needed. +*If you want to debug a playground scene without starting the playground*, edit the file createScene.js (or sceneTs.ts for typescript), and open or +Open the inspector by pressing Ctrl+Shift+U (or Cmd+Shift+U on Mac). To start the babylon server, run: diff --git a/package.json b/package.json index 4e89aa32931..c14effc1576 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,8 @@ "lint:check": "eslint ./packages/**/src/**/*.{ts,tsx,js,json}", "lint:fix": "eslint ./packages/**/src/**/*.{ts,tsx,js,json} --fix", "update-all-dependencies": "npm update -ws", - "prepare-snapshot": "npm run build:snapshot -w @tools/babylon-server && build-tools -c ps" + "prepare-snapshot": "npm run build:snapshot -w @tools/babylon-server && build-tools -c ps", + "start": "concurrently --kill-others -m 2 -n dev-watch,cdn-server \"npm run watch:dev\" \"npm run serve -w @tools/babylon-server\"" }, "engines": { "node": ">=12.0.0 <17.0.0", diff --git a/packages/tools/babylonServer/.gitignore b/packages/tools/babylonServer/.gitignore index ac920fbb55f..9e62f48245e 100644 --- a/packages/tools/babylonServer/.gitignore +++ b/packages/tools/babylonServer/.gitignore @@ -1 +1,2 @@ declarations/ +create*.* \ No newline at end of file diff --git a/packages/tools/babylonServer/package.json b/packages/tools/babylonServer/package.json index eb9796f02d7..32baeb89939 100644 --- a/packages/tools/babylonServer/package.json +++ b/packages/tools/babylonServer/package.json @@ -19,7 +19,8 @@ "build:declaration": "build-tools -c pud --config ./declarationConfigDev.json", "build:declaration:lts": "build-tools -c pud --config ./declarationConfigLTS.json", "watch:declaration:dev": "build-tools -c pud --config ./declarationConfigDev.json --watch", - "watch:declaration:lts": "build-tools -c pud --config ./declarationConfigLTS.json --watch" + "watch:declaration:lts": "build-tools -c pud --config ./declarationConfigLTS.json --watch", + "prepare": "node ./scripts/generateScripts.js" }, "devDependencies": { "@dev/build-tools": "1.0.0", diff --git a/packages/tools/babylonServer/scripts/generateScripts.js b/packages/tools/babylonServer/scripts/generateScripts.js new file mode 100644 index 00000000000..18b5525e399 --- /dev/null +++ b/packages/tools/babylonServer/scripts/generateScripts.js @@ -0,0 +1,172 @@ +const fs = require("fs"); +const path = require("path"); + +if (!fs.existsSync(path.resolve("./src/createEngine.js"))) { + fs.writeFileSync( + path.resolve("./src/createEngine.js"), + ` +/* global BABYLON */ +export const createEngine = () => { + const canvas = document.getElementById("babylon-canvas"); // Get the canvas element + const engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true} ); + return engine; +} +` + ); +} + +if (!fs.existsSync(path.resolve("./src/createScene.js"))) { + fs.writeFileSync( + path.resolve("./src/createScene.js"), + ` +/* global BABYLON */ +export const createScene = function (engine, canvas) { + // Model by Mixamo + + engine.enableOfflineSupport = false; + + // This is really important to tell Babylon.js to use decomposeLerp and matrix interpolation + BABYLON.Animation.AllowMatricesInterpolation = true; + + const scene = new BABYLON.Scene(engine); + + const camera = new BABYLON.ArcRotateCamera("camera1", Math.PI / 2, Math.PI / 4, 3, new BABYLON.Vector3(0, 1, 0), scene); + camera.attachControl(canvas, true); + + camera.lowerRadiusLimit = 2; + camera.upperRadiusLimit = 10; + camera.wheelDeltaPercentage = 0.01; + + const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); + light.intensity = 0.6; + light.specular = BABYLON.Color3.Black(); + + const light2 = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(0, -0.5, -1.0), scene); + light2.position = new BABYLON.Vector3(0, 5, 5); + + // Shadows + const shadowGenerator = new BABYLON.ShadowGenerator(1024, light2); + shadowGenerator.useBlurExponentialShadowMap = true; + shadowGenerator.blurKernel = 32; + + engine.displayLoadingUI(); + + BABYLON.SceneLoader.ImportMesh("", "https://playground.babylonjs.com/scenes/", "dummy3.babylon", scene, function (newMeshes, particleSystems, skeletons) { + const skeleton = skeletons[0]; + + shadowGenerator.addShadowCaster(scene.meshes[0], true); + for (let index = 0; index < newMeshes.length; index++) { + newMeshes[index].receiveShadows = false; + } + + const helper = scene.createDefaultEnvironment({ + enableGroundShadow: true, + }); + helper.setMainColor(BABYLON.Color3.Gray()); + helper.ground.position.y += 0.01; + + // ROBOT + skeleton.animationPropertiesOverride = new BABYLON.AnimationPropertiesOverride(); + skeleton.animationPropertiesOverride.enableBlending = true; + skeleton.animationPropertiesOverride.blendingSpeed = 0.05; + skeleton.animationPropertiesOverride.loopMode = 1; + + const idleRange = skeleton.getAnimationRange("YBot_Idle"); + const walkRange = skeleton.getAnimationRange("YBot_Walk"); + const runRange = skeleton.getAnimationRange("YBot_Run"); + const leftRange = skeleton.getAnimationRange("YBot_LeftStrafeWalk"); + const rightRange = skeleton.getAnimationRange("YBot_RightStrafeWalk"); + + // IDLE + if (idleRange) scene.beginAnimation(skeleton, idleRange.from, idleRange.to, true); + + // UI + const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"); + const uiPanel = new BABYLON.GUI.StackPanel(); + uiPanel.width = "220px"; + uiPanel.fontSize = "14px"; + uiPanel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT; + uiPanel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER; + advancedTexture.addControl(uiPanel); + // .. + const button = BABYLON.GUI.Button.CreateSimpleButton("but1", "Play Idle"); + button.paddingTop = "10px"; + button.width = "100px"; + button.height = "50px"; + button.color = "white"; + button.background = "green"; + button.onPointerDownObservable.add(() => { + if (idleRange) scene.beginAnimation(skeleton, idleRange.from, idleRange.to, true); + }); + uiPanel.addControl(button); + // .. + let button1 = BABYLON.GUI.Button.CreateSimpleButton("but2", "Play Walk"); + button1.paddingTop = "10px"; + button1.width = "100px"; + button1.height = "50px"; + button1.color = "white"; + button1.background = "green"; + button1.onPointerDownObservable.add(() => { + if (walkRange) scene.beginAnimation(skeleton, walkRange.from, walkRange.to, true); + }); + uiPanel.addControl(button1); + // .. + button1 = BABYLON.GUI.Button.CreateSimpleButton("but3", "Play Run"); + button1.paddingTop = "10px"; + button1.width = "100px"; + button1.height = "50px"; + button1.color = "white"; + button1.background = "green"; + button1.onPointerDownObservable.add(() => { + if (runRange) scene.beginAnimation(skeleton, runRange.from, runRange.to, true); + }); + uiPanel.addControl(button1); + // .. + button1 = BABYLON.GUI.Button.CreateSimpleButton("but4", "Play Left"); + button1.paddingTop = "10px"; + button1.width = "100px"; + button1.height = "50px"; + button1.color = "white"; + button1.background = "green"; + button1.onPointerDownObservable.add(() => { + if (leftRange) scene.beginAnimation(skeleton, leftRange.from, leftRange.to, true); + }); + uiPanel.addControl(button1); + // .. + button1 = BABYLON.GUI.Button.CreateSimpleButton("but5", "Play Right"); + button1.paddingTop = "10px"; + button1.width = "100px"; + button1.height = "50px"; + button1.color = "white"; + button1.background = "green"; + button1.onPointerDownObservable.add(() => { + if (rightRange) scene.beginAnimation(skeleton, rightRange.from, rightRange.to, true); + }); + uiPanel.addControl(button1); + // .. + button1 = BABYLON.GUI.Button.CreateSimpleButton("but6", "Play Blend"); + button1.paddingTop = "10px"; + button1.width = "100px"; + button1.height = "50px"; + button1.color = "white"; + button1.background = "green"; + button1.onPointerDownObservable.add(() => { + if (walkRange && leftRange) { + scene.stopAnimation(skeleton); + const walkAnim = scene.beginWeightedAnimation(skeleton, walkRange.from, walkRange.to, 0.5, true); + const leftAnim = scene.beginWeightedAnimation(skeleton, leftRange.from, leftRange.to, 0.5, true); + + // Note: Sync Speed Ratio With Master Walk Animation + walkAnim.syncWith(null); + leftAnim.syncWith(walkAnim); + } + }); + uiPanel.addControl(button1); + + engine.hideLoadingUI(); + }); + + return scene; +};` + ); +} diff --git a/packages/tools/babylonServer/src/sceneJs.js b/packages/tools/babylonServer/src/sceneJs.js index 7313a3e875e..708cbe8ae87 100644 --- a/packages/tools/babylonServer/src/sceneJs.js +++ b/packages/tools/babylonServer/src/sceneJs.js @@ -1,171 +1,37 @@ -/* global BABYLON */ import { loadPlayground, getPlaygroundId } from "./playground"; const canvas = document.getElementById("babylon-canvas"); // Get the canvas element +import { createScene } from "./createScene"; +import { createEngine } from "./createEngine"; -// Add your code here matching the playground format -const createScene = function (engine) { - // Model by Mixamo - - engine.enableOfflineSupport = false; - - // This is really important to tell Babylon.js to use decomposeLerp and matrix interpolation - BABYLON.Animation.AllowMatricesInterpolation = true; - - const scene = new BABYLON.Scene(engine); - - const camera = new BABYLON.ArcRotateCamera("camera1", Math.PI / 2, Math.PI / 4, 3, new BABYLON.Vector3(0, 1, 0), scene); - camera.attachControl(canvas, true); - - camera.lowerRadiusLimit = 2; - camera.upperRadiusLimit = 10; - camera.wheelDeltaPercentage = 0.01; - - const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); - light.intensity = 0.6; - light.specular = BABYLON.Color3.Black(); - - const light2 = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(0, -0.5, -1.0), scene); - light2.position = new BABYLON.Vector3(0, 5, 5); - - // Shadows - const shadowGenerator = new BABYLON.ShadowGenerator(1024, light2); - shadowGenerator.useBlurExponentialShadowMap = true; - shadowGenerator.blurKernel = 32; - - engine.displayLoadingUI(); - - BABYLON.SceneLoader.ImportMesh("", "https://playground.babylonjs.com/scenes/", "dummy3.babylon", scene, function (newMeshes, particleSystems, skeletons) { - const skeleton = skeletons[0]; - - shadowGenerator.addShadowCaster(scene.meshes[0], true); - for (let index = 0; index < newMeshes.length; index++) { - newMeshes[index].receiveShadows = false; - } - - const helper = scene.createDefaultEnvironment({ - enableGroundShadow: true, - }); - helper.setMainColor(BABYLON.Color3.Gray()); - helper.ground.position.y += 0.01; - - // ROBOT - skeleton.animationPropertiesOverride = new BABYLON.AnimationPropertiesOverride(); - skeleton.animationPropertiesOverride.enableBlending = true; - skeleton.animationPropertiesOverride.blendingSpeed = 0.05; - skeleton.animationPropertiesOverride.loopMode = 1; - - const idleRange = skeleton.getAnimationRange("YBot_Idle"); - const walkRange = skeleton.getAnimationRange("YBot_Walk"); - const runRange = skeleton.getAnimationRange("YBot_Run"); - const leftRange = skeleton.getAnimationRange("YBot_LeftStrafeWalk"); - const rightRange = skeleton.getAnimationRange("YBot_RightStrafeWalk"); - - // IDLE - if (idleRange) scene.beginAnimation(skeleton, idleRange.from, idleRange.to, true); - - // UI - const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"); - const uiPanel = new BABYLON.GUI.StackPanel(); - uiPanel.width = "220px"; - uiPanel.fontSize = "14px"; - uiPanel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT; - uiPanel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER; - advancedTexture.addControl(uiPanel); - // .. - const button = BABYLON.GUI.Button.CreateSimpleButton("but1", "Play Idle"); - button.paddingTop = "10px"; - button.width = "100px"; - button.height = "50px"; - button.color = "white"; - button.background = "green"; - button.onPointerDownObservable.add(() => { - if (idleRange) scene.beginAnimation(skeleton, idleRange.from, idleRange.to, true); - }); - uiPanel.addControl(button); - // .. - let button1 = BABYLON.GUI.Button.CreateSimpleButton("but2", "Play Walk"); - button1.paddingTop = "10px"; - button1.width = "100px"; - button1.height = "50px"; - button1.color = "white"; - button1.background = "green"; - button1.onPointerDownObservable.add(() => { - if (walkRange) scene.beginAnimation(skeleton, walkRange.from, walkRange.to, true); - }); - uiPanel.addControl(button1); - // .. - button1 = BABYLON.GUI.Button.CreateSimpleButton("but3", "Play Run"); - button1.paddingTop = "10px"; - button1.width = "100px"; - button1.height = "50px"; - button1.color = "white"; - button1.background = "green"; - button1.onPointerDownObservable.add(() => { - if (runRange) scene.beginAnimation(skeleton, runRange.from, runRange.to, true); - }); - uiPanel.addControl(button1); - // .. - button1 = BABYLON.GUI.Button.CreateSimpleButton("but4", "Play Left"); - button1.paddingTop = "10px"; - button1.width = "100px"; - button1.height = "50px"; - button1.color = "white"; - button1.background = "green"; - button1.onPointerDownObservable.add(() => { - if (leftRange) scene.beginAnimation(skeleton, leftRange.from, leftRange.to, true); - }); - uiPanel.addControl(button1); - // .. - button1 = BABYLON.GUI.Button.CreateSimpleButton("but5", "Play Right"); - button1.paddingTop = "10px"; - button1.width = "100px"; - button1.height = "50px"; - button1.color = "white"; - button1.background = "green"; - button1.onPointerDownObservable.add(() => { - if (rightRange) scene.beginAnimation(skeleton, rightRange.from, rightRange.to, true); - }); - uiPanel.addControl(button1); - // .. - button1 = BABYLON.GUI.Button.CreateSimpleButton("but6", "Play Blend"); - button1.paddingTop = "10px"; - button1.width = "100px"; - button1.height = "50px"; - button1.color = "white"; - button1.background = "green"; - button1.onPointerDownObservable.add(() => { - if (walkRange && leftRange) { - scene.stopAnimation(skeleton); - const walkAnim = scene.beginWeightedAnimation(skeleton, walkRange.from, walkRange.to, 0.5, true); - const leftAnim = scene.beginWeightedAnimation(skeleton, leftRange.from, leftRange.to, 0.5, true); - - // Note: Sync Speed Ratio With Master Walk Animation - walkAnim.syncWith(null); - leftAnim.syncWith(walkAnim); - } - }); - uiPanel.addControl(button1); - - engine.hideLoadingUI(); - }); - - return scene; -}; let engine; let scene; +const resize = () => { + engine && engine.resize(); +}; +const openInspector = (e) => { + console.log(e); + if (e.keyCode === 85 && e.shiftKey && (e.ctrlKey || e.metaKey) && scene) { + scene.debugLayer.show(); + } +}; const runScene = async () => { const playgroundId = getPlaygroundId(); if (engine) { engine.dispose(); engine = undefined; } - engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine + engine = createEngine(); // Generate the BABYLON 3D engine if (playgroundId) { window.engine = engine; window.canvas = canvas; scene = await loadPlayground(playgroundId); } else { - scene = createScene(engine); //Call the createScene function + const createdScene = createScene(engine, canvas); //Call the createScene function + if (createdScene.then) { + scene = await createdScene; + } else { + scene = createdScene; + } } // Register a render loop to repeatedly render the scene @@ -176,11 +42,12 @@ const runScene = async () => { }); // Watch for browser/canvas resize events - window.addEventListener("resize", function () { - engine.resize(); - }); }; runScene(); +window.addEventListener("resize", resize); window.addEventListener("hashchange", runScene); +window.addEventListener("keydown", openInspector); + +console.log("Open the inspector using Ctrl+Shift+U (or Command+Shift+U on Mac)"); diff --git a/packages/tools/babylonServer/tsconfig.json b/packages/tools/babylonServer/tsconfig.json index f6f4924d570..1bb1d39981d 100644 --- a/packages/tools/babylonServer/tsconfig.json +++ b/packages/tools/babylonServer/tsconfig.json @@ -2,5 +2,8 @@ "extends": "../../../tsconfig.json", "compilerOptions": { + "types": [ + "declarations/**/*.d.ts" + ] }, } diff --git a/packages/tools/guiEditor/webpack.config.js b/packages/tools/guiEditor/webpack.config.js index a8d8d400736..b3bf39e3ec6 100644 --- a/packages/tools/guiEditor/webpack.config.js +++ b/packages/tools/guiEditor/webpack.config.js @@ -1,6 +1,5 @@ const path = require("path"); const webpackTools = require("@dev/build-tools").webpackTools; -require("dotenv").config(); module.exports = (env) => { const production = env.mode === "production" || process.env.NODE_ENV === "production";