├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml └── workflows │ └── deploy.yml ├── .gitignore ├── .prettierrc ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── fiveserver.config.js ├── package-lock.json ├── package.json ├── scripts ├── deploy.js └── ssr.js └── src ├── assets ├── atlas │ ├── ninja-texture-atlas.json │ └── ninja-texture-atlas.png ├── button │ └── button_sprite_sheet.png ├── fbx │ ├── BodyJabCross.fbx │ ├── HipHopDancing.fbx │ ├── Idle.fbx │ ├── Jumping.fbx │ ├── LookingAround.fbx │ ├── Running.fbx │ └── Walking.fbx ├── glb │ ├── Duck.glb │ ├── M4A1.glb │ ├── Sail_Ship_mod.glb │ ├── Tank.glb │ ├── book.glb │ ├── book_mod.glb │ ├── box_man.glb │ ├── car.glb │ ├── robot.glb │ ├── suzanne.glb │ └── suzannemorphed.glb ├── gltf │ └── drone │ │ ├── drone.bin │ │ ├── drone.gltf │ │ └── textures │ │ ├── 1001_baseColor.png │ │ ├── 1001_metallicRoughness.png │ │ ├── 1001_normal.png │ │ └── ai_whitePlastic_tex_baseColor.png ├── heightmap │ ├── heightmap-island.png │ └── heightmap-simple.png ├── img │ ├── box-bottom.png │ ├── box-side.png │ ├── box-top.png │ ├── grass.jpg │ ├── grass.md │ ├── grid.png │ └── sky.png ├── physics │ ├── fruit-shapes.json │ ├── fruit-sprites.json │ └── fruit-sprites.png ├── spritesheet │ └── adventurer-Sheet.png ├── svg │ ├── bridge.svg │ └── star.svg └── water │ ├── Water_1_M_Normal.jpg │ └── Water_2_M_Normal.jpg ├── css ├── examples.css ├── floating-action-button.css └── style.css ├── docs.html ├── docs ├── Basic-Setup.md ├── Basic-Shapes.md ├── Collisions.md ├── Compound-Shapes.md ├── Constraints.md ├── Controls.md ├── Factory.md ├── Lights.md ├── Loaders.md ├── Misc.md ├── Physics-Body.md ├── Physics-Configuration.md ├── Position-Rotation-Scale.md ├── Raycasting.md ├── Tweens.md ├── Warp-Speed.md └── WebXR.md ├── examples.html ├── examples ├── 3rd-person-camera.html ├── adjust-gamma-factor-and-shadows.html ├── camera-lerping-and-player-controls.html ├── car-using-physics-constraints.html ├── carousel.html ├── change-material-of-3d-model.html ├── collision-detection.html ├── collisiongroup-and-collisionmask.html ├── compare-physics-body-shapes.html ├── constructive-solid-geometry-physics-and-breakable.html ├── constructive-solid-geometry-physics.html ├── constructive-solid-geometry.html ├── convex-objects-breaking-phaser.html ├── convex-objects-breaking.html ├── create-3d-geometry-from-2d-path.html ├── create-3d-geometry-from-png-file.html ├── create-3d-geometry-from-svg-file.html ├── create-and-destroy-objects-and-physics.html ├── custom-setup.html ├── dash-and-blast-prototype.html ├── debug-bodies.html ├── enemy-patrols-on-platform.html ├── fbx-loader-and-animations-hitbox.html ├── fbx-loader-and-animations.html ├── first-person-shooter.html ├── first-phaser-game-3d-version.html ├── flat │ ├── button-spritesheet.html │ ├── draw-sprite.html │ ├── matter-physics-advanced-shapes.html │ ├── matter-physics.html │ ├── pixel-perfect.html │ ├── sprite-sheet.html │ ├── text-sprite.html │ └── texture-atlas.html ├── gltf-loader-and-animations.html ├── gltf-loader-with-physics.html ├── headless-fbx-loader.html ├── headless-fbx-loader.js ├── headless-gltf-loader.html ├── headless-gltf-loader.js ├── headless-mode.html ├── headless-mode.js ├── heightmap-with-color-scale.html ├── hollow-cylinder.html ├── isometric-game-orthographic-camera.html ├── jenga-game.html ├── kinematic-body-orbiting-around-sun.html ├── lights.html ├── load-and-use-textures.html ├── material-showcase.html ├── medieval-fantasy-book-standalone.html ├── medieval-fantasy-book.html ├── morphed-mesh.html ├── native-three-with-physics.html ├── objects-recycling.html ├── per-body-gravity.html ├── phaser-gltf-loader-with-animation-speed.html ├── physics-raycaster.html ├── play-with-physics-bodies.html ├── point-to-point-constraint.html ├── post-processing.html ├── project-options-and-multiple-scenes.html ├── railway-with-compound-body.html ├── railway-with-constraints.html ├── railway-with-csg.html ├── raycast-vehicle.html ├── resize-window.html ├── shape-showcase.html ├── simple-setup.html ├── simplify-physics-mesh.html ├── slider-constraints.html ├── slope-angle-and-moving-platform.html ├── softbody-cloth.html ├── spotlight.html ├── standalone-mode.html ├── standalone │ ├── compound-hacd-shape.html │ ├── pick-up-objects.html │ ├── snapshot-interpolation.html │ ├── texture-cube.html │ └── work-with-objects-factory.html ├── switch-camera-between-2d-and-3d.html ├── sync-2d-to-3d.html ├── sync-3d-to-2d.html ├── teleport-a-dynamic-body.html ├── texture-on-a-plane.html ├── threejs │ └── vhacd-shape-webworker.html ├── tween-manager.html ├── types-of-constraints.html ├── use-native-three-code.html ├── use-tweenjs.html ├── virtual-reality-phaser.html ├── virtual-reality.html ├── water.html └── wrecking-ball-with-metal-chain.html ├── favicon.ico ├── img ├── become_a_patron_button@2x.png ├── enable3d-logo-dark.png ├── enable3d-logo-square.png ├── enable3d-logo.png ├── github-sponsor.png ├── icon │ ├── logo-16x16.png │ ├── logo-32x32.png │ └── logo-96x96.png ├── placeholder │ ├── badge-blue.png │ ├── badge-green.png │ ├── badge-orange.png │ └── badge-pink.png ├── welcome-game-screenshot.png └── youtube-thumbnail.jpg ├── index.html ├── js ├── examples.js └── load-images.js ├── lib ├── BufferGeometryUtils.js ├── ConvexGeometry.js ├── ConvexHull.js ├── GLTFLoader.js ├── OrbitControls.js ├── SimplifyModifier.js ├── ammo │ ├── kripken │ │ ├── ammo.js │ │ ├── ammo.wasm.js │ │ └── ammo.wasm.wasm │ └── moz │ │ ├── ammo.js │ │ ├── ammo.wasm.js │ │ └── ammo.wasm.wasm ├── chroma.min.js ├── enable3d │ ├── enable3d.ammoPhysics.0.25.4.min.js │ ├── enable3d.ammoPhysics.0.26.0_dev0.module.min.js │ ├── enable3d.framework.0.25.4.min.js │ ├── enable3d.framework.0.26.0_dev0.module.min.js │ └── enable3d.phaserExtension.0.25.4.min.js ├── matter.min.js ├── nano.slim.0.0.15.min.js ├── phaser.min.js ├── three.min.js ├── threejs │ └── r171 │ │ ├── BufferGeometryUtils.module.min.js │ │ ├── ConvexGeometry.module.min.js │ │ ├── FBXLoader.module.min.js │ │ ├── GLTFLoader.module.min.js │ │ ├── OrbitControls.module.min.js │ │ ├── three.core.min.js │ │ └── three.module.min.js ├── tween.umd.js └── vhacd-wasm │ ├── index.js │ ├── lib │ ├── comlink.js │ └── comlink.mjs │ ├── vhacd-wasm_no-modules.js │ ├── vhacd-wasm_no-modules_bg.wasm │ └── worker.js └── welcome-game.js /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Have a question?** 14 | Join the [discussions](https://github.com/enable3d/enable3d/discussions) instead. 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Ask a question 4 | url: https://github.com/enable3d/enable3d/discussions 5 | about: Ask questions and discuss with other community members 6 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy-to-AWS 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | timeout-minutes: 5 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | 15 | - name: npm install 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: 20 19 | - run: npm install --only=dev 20 | - run: node scripts/ssr.js --no-sandbox 21 | - run: BUCKET=${{secrets.BUCKET}} AWS_ACCESS_KEY_ID=${{secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY=${{secrets.AWS_SECRET_ACCESS_KEY}} DISTRIBUTION_ID=${{secrets.DISTRIBUTION_ID}} node scripts/deploy.js 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /debug.log 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | "@yandeu/prettier-config" 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode" 4 | ] 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Yannick Deubel (https://github.com/yandeu) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | This repository contains the website enable3d.io 4 | 5 | You'll find some nice examples in [/src/examples](/src/examples). 6 | 7 | ## Run 8 | 9 | To run the demos locally, run `npm install && npm start` and navigate to `http://127.0.0.1:8081/` 10 | -------------------------------------------------------------------------------- /fiveserver.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: 'src', 3 | port: 8081, 4 | highlight: false, 5 | injectBody: false, 6 | navigate: false 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "enable3d-website", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "five-server", 8 | "format": "prettier --write src/*.{html,js} src/{js,css,examples}/*" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/enable3d/enable3d-website.git" 13 | }, 14 | "author": "Yannick Deubel", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/enable3d/enable3d-website/issues" 18 | }, 19 | "homepage": "https://github.com/enable3d/enable3d-website#readme", 20 | "dependencies": { 21 | "@enable3d/ammo-on-nodejs": "0.25.3", 22 | "three": "0.144.0" 23 | }, 24 | "devDependencies": { 25 | "@yandeu/prettier-config": "^0.0.4", 26 | "aws-sdk": "^2.819.0", 27 | "express": "^4.17.1", 28 | "five-server": "^0.1.1", 29 | "mime": "^2.4.7", 30 | "prettier": "^3.4.2", 31 | "puppeteer": "^10.1.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /scripts/deploy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Deploy Website to AWS S3 3 | */ 4 | 5 | const S3 = require('aws-sdk/clients/s3') 6 | const CloudFront = require('aws-sdk/clients/cloudfront') 7 | const fs = require('fs') 8 | const path = require('path') 9 | const mime = require('mime') 10 | 11 | const Bucket = process.env.BUCKET 12 | const accessKeyId = process.env.AWS_ACCESS_KEY_ID 13 | const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY 14 | const DistributionId = process.env.DISTRIBUTION_ID 15 | 16 | const s3 = new S3({ apiVersion: '2006-03-01', accessKeyId, secretAccessKey }) 17 | const cloudfront = new CloudFront({ apiVersion: '2019-03-26', accessKeyId, secretAccessKey }) 18 | 19 | const params = { 20 | DistributionId: DistributionId, 21 | InvalidationBatch: { 22 | CallerReference: Math.round(new Date().getTime() / 1000).toString(), 23 | Paths: { 24 | Quantity: 1, 25 | Items: ['/*'] 26 | } 27 | } 28 | } 29 | 30 | const { resolve } = require('path') 31 | const { readdir } = require('fs').promises 32 | 33 | const getFiles = async dir => { 34 | const dirents = await readdir(dir, { withFileTypes: true }) 35 | const files = await Promise.all( 36 | dirents.map(dirent => { 37 | const res = resolve(dir, dirent.name) 38 | return dirent.isDirectory() ? getFiles(res) : res 39 | }) 40 | ) 41 | return Array.prototype.concat(...files) 42 | } 43 | 44 | const readFile = (path, cb) => { 45 | fs.readFile(path, (err, data) => { 46 | if (err) { 47 | console.log(err, err.stack) 48 | throw err 49 | } 50 | cb(data) 51 | }) 52 | } 53 | 54 | const upload = (file, data) => { 55 | const Key = file.match(/\/src\/[\S]+$/gm)[0].replace('/src/', '') 56 | const Body = data 57 | const ContentType = mime.getType(file) 58 | 59 | let CacheControl = 'public, max-age=300, s-maxage=864000' // public, 5 minutes, 10 days 60 | const oneMonth = 'public, max-age=2592000, s-maxage=864000' // public, 30 days, 10 days 61 | if (/css/.test(ContentType)) CacheControl = oneMonth 62 | if (/image/.test(ContentType)) CacheControl = oneMonth 63 | if (/model/.test(ContentType)) CacheControl = oneMonth 64 | if (/application/.test(ContentType)) CacheControl = oneMonth 65 | 66 | s3.putObject({ Bucket, Key, Body, ContentType, CacheControl }, (err, data) => { 67 | if (err) { 68 | console.log(err, err.stack) 69 | throw err 70 | } 71 | // an error occurred 72 | // else console.log(data) // successful response 73 | }) 74 | } 75 | 76 | ;(async () => { 77 | const paths = await getFiles('./src') 78 | 79 | paths.forEach(p => { 80 | readFile(p, data => { 81 | upload(p, data) 82 | }) 83 | }) 84 | 85 | cloudfront.createInvalidation(params, (err, data) => { 86 | if (err) { 87 | console.log(err, err.stack) 88 | throw err 89 | } 90 | }) 91 | })() 92 | -------------------------------------------------------------------------------- /scripts/ssr.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** 4 | * Pre Render JavaScript 5 | */ 6 | 7 | const express = require('express') 8 | const puppeteer = require('puppeteer') 9 | const fs = require('fs') 10 | const path = require('path') 11 | const { argv } = require('process') 12 | 13 | const app = express() 14 | const port = 8989 15 | 16 | const args = argv.slice(2).join(' ') 17 | const noSandbox = args.includes('--no-sandbox') 18 | 19 | app.use(express.static('src')) 20 | 21 | const server = app.listen(port, () => console.log('Server started. Press Ctrl+C to quit')) 22 | 23 | const ssr = async url => { 24 | const args = [] 25 | if (noSandbox) args.push('--no-sandbox', '--disable-setuid-sandbox') 26 | 27 | const browser = await puppeteer.launch({ headless: true, noSandbox: noSandbox, args }) 28 | const page = await browser.newPage() 29 | 30 | await page.setRequestInterception(true) 31 | 32 | page.on('request', req => { 33 | const blacklist = ['buttons.github.io/buttons.js', 'img.shields.io'] 34 | if (blacklist.find(regex => req.url().match(regex))) { 35 | return req.abort() 36 | } 37 | 38 | req.continue() 39 | }) 40 | 41 | await page.evaluateOnNewDocument(() => { 42 | window.isPuppeteer = true 43 | }) 44 | await page.goto(url, { waitUntil: 'networkidle2' }) 45 | 46 | // https://github.com/lichtquelle/generate-static-site/blob/main/src/crawl.ts 47 | await page 48 | .evaluate(() => { 49 | const ssr = document.querySelectorAll('[SSROnly]') 50 | for (let i = 0; i < ssr.length; i++) { 51 | ssr[i].remove() 52 | } 53 | }) 54 | .catch(err => { 55 | console.log('[evaluate] remove SSROnly', err.message) 56 | }) 57 | 58 | const html = await page.content() // serialized HTML of page DOM. 59 | await browser.close() 60 | return html 61 | } 62 | 63 | const render = async () => { 64 | const html = await ssr(`http://localhost:${port}/docs.html`) 65 | fs.writeFileSync(path.resolve(__dirname, '../src', 'docs.html'), html) 66 | server.close() 67 | process.exit(0) 68 | } 69 | 70 | render() 71 | -------------------------------------------------------------------------------- /src/assets/atlas/ninja-texture-atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/atlas/ninja-texture-atlas.png -------------------------------------------------------------------------------- /src/assets/button/button_sprite_sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/button/button_sprite_sheet.png -------------------------------------------------------------------------------- /src/assets/fbx/BodyJabCross.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/BodyJabCross.fbx -------------------------------------------------------------------------------- /src/assets/fbx/HipHopDancing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/HipHopDancing.fbx -------------------------------------------------------------------------------- /src/assets/fbx/Idle.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/Idle.fbx -------------------------------------------------------------------------------- /src/assets/fbx/Jumping.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/Jumping.fbx -------------------------------------------------------------------------------- /src/assets/fbx/LookingAround.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/LookingAround.fbx -------------------------------------------------------------------------------- /src/assets/fbx/Running.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/Running.fbx -------------------------------------------------------------------------------- /src/assets/fbx/Walking.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/fbx/Walking.fbx -------------------------------------------------------------------------------- /src/assets/glb/Duck.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/Duck.glb -------------------------------------------------------------------------------- /src/assets/glb/M4A1.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/M4A1.glb -------------------------------------------------------------------------------- /src/assets/glb/Sail_Ship_mod.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/Sail_Ship_mod.glb -------------------------------------------------------------------------------- /src/assets/glb/Tank.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/Tank.glb -------------------------------------------------------------------------------- /src/assets/glb/book.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/book.glb -------------------------------------------------------------------------------- /src/assets/glb/book_mod.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/book_mod.glb -------------------------------------------------------------------------------- /src/assets/glb/box_man.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/box_man.glb -------------------------------------------------------------------------------- /src/assets/glb/car.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/car.glb -------------------------------------------------------------------------------- /src/assets/glb/robot.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/robot.glb -------------------------------------------------------------------------------- /src/assets/glb/suzanne.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/suzanne.glb -------------------------------------------------------------------------------- /src/assets/glb/suzannemorphed.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/glb/suzannemorphed.glb -------------------------------------------------------------------------------- /src/assets/gltf/drone/drone.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/gltf/drone/drone.bin -------------------------------------------------------------------------------- /src/assets/gltf/drone/textures/1001_baseColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/gltf/drone/textures/1001_baseColor.png -------------------------------------------------------------------------------- /src/assets/gltf/drone/textures/1001_metallicRoughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/gltf/drone/textures/1001_metallicRoughness.png -------------------------------------------------------------------------------- /src/assets/gltf/drone/textures/1001_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/gltf/drone/textures/1001_normal.png -------------------------------------------------------------------------------- /src/assets/gltf/drone/textures/ai_whitePlastic_tex_baseColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/gltf/drone/textures/ai_whitePlastic_tex_baseColor.png -------------------------------------------------------------------------------- /src/assets/heightmap/heightmap-island.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/heightmap/heightmap-island.png -------------------------------------------------------------------------------- /src/assets/heightmap/heightmap-simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/heightmap/heightmap-simple.png -------------------------------------------------------------------------------- /src/assets/img/box-bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/img/box-bottom.png -------------------------------------------------------------------------------- /src/assets/img/box-side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/img/box-side.png -------------------------------------------------------------------------------- /src/assets/img/box-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/img/box-top.png -------------------------------------------------------------------------------- /src/assets/img/grass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/img/grass.jpg -------------------------------------------------------------------------------- /src/assets/img/grass.md: -------------------------------------------------------------------------------- 1 | Textures from: 2 | http://opengameart.org/ 3 | http://opengameart.org/content/dark-grass 4 | 5 | Licensed under a Creative Commons Attribution 3.0 Unported License: 6 | http://creativecommons.org/licenses/by/3.0/ 7 | 8 | Copied from: 9 | https://github.com/mrdoob/three.js/tree/master/examples/textures/terrain 10 | -------------------------------------------------------------------------------- /src/assets/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/img/grid.png -------------------------------------------------------------------------------- /src/assets/img/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/img/sky.png -------------------------------------------------------------------------------- /src/assets/physics/fruit-sprites.json: -------------------------------------------------------------------------------- 1 | { 2 | "textures": [ 3 | { 4 | "image": "fruit-sprites.png", 5 | "format": "RGBA8888", 6 | "size": { 7 | "w": 602, 8 | "h": 1205 9 | }, 10 | "scale": 1, 11 | "frames": [ 12 | { 13 | "filename": "crate", 14 | "rotated": false, 15 | "trimmed": true, 16 | "sourceSize": { 17 | "w": 128, 18 | "h": 128 19 | }, 20 | "spriteSourceSize": { 21 | "x": 3, 22 | "y": 7, 23 | "w": 123, 24 | "h": 121 25 | }, 26 | "frame": { 27 | "x": 1, 28 | "y": 1, 29 | "w": 123, 30 | "h": 121 31 | } 32 | }, 33 | { 34 | "filename": "orange", 35 | "rotated": false, 36 | "trimmed": true, 37 | "sourceSize": { 38 | "w": 128, 39 | "h": 128 40 | }, 41 | "spriteSourceSize": { 42 | "x": 1, 43 | "y": 5, 44 | "w": 127, 45 | "h": 123 46 | }, 47 | "frame": { 48 | "x": 126, 49 | "y": 1, 50 | "w": 127, 51 | "h": 123 52 | } 53 | }, 54 | { 55 | "filename": "cherries", 56 | "rotated": false, 57 | "trimmed": true, 58 | "sourceSize": { 59 | "w": 128, 60 | "h": 128 61 | }, 62 | "spriteSourceSize": { 63 | "x": 5, 64 | "y": 3, 65 | "w": 120, 66 | "h": 125 67 | }, 68 | "frame": { 69 | "x": 255, 70 | "y": 1, 71 | "w": 120, 72 | "h": 125 73 | } 74 | }, 75 | { 76 | "filename": "banana", 77 | "rotated": false, 78 | "trimmed": true, 79 | "sourceSize": { 80 | "w": 128, 81 | "h": 128 82 | }, 83 | "spriteSourceSize": { 84 | "x": 0, 85 | "y": 0, 86 | "w": 127, 87 | "h": 128 88 | }, 89 | "frame": { 90 | "x": 377, 91 | "y": 1, 92 | "w": 127, 93 | "h": 128 94 | } 95 | }, 96 | { 97 | "filename": "ground", 98 | "rotated": false, 99 | "trimmed": true, 100 | "sourceSize": { 101 | "w": 600, 102 | "h": 800 103 | }, 104 | "spriteSourceSize": { 105 | "x": 0, 106 | "y": 529, 107 | "w": 600, 108 | "h": 271 109 | }, 110 | "frame": { 111 | "x": 1, 112 | "y": 131, 113 | "w": 600, 114 | "h": 271 115 | } 116 | }, 117 | { 118 | "filename": "background", 119 | "rotated": false, 120 | "trimmed": false, 121 | "sourceSize": { 122 | "w": 600, 123 | "h": 800 124 | }, 125 | "spriteSourceSize": { 126 | "x": 0, 127 | "y": 0, 128 | "w": 600, 129 | "h": 800 130 | }, 131 | "frame": { 132 | "x": 1, 133 | "y": 404, 134 | "w": 600, 135 | "h": 800 136 | } 137 | } 138 | ] 139 | } 140 | ], 141 | "meta": { 142 | "app": "https://www.codeandweb.com/texturepacker", 143 | "version": "3.0", 144 | "smartupdate": "$TexturePacker:SmartUpdate:f2982f4262d1a5cba9bfe98b319e0845:ad33ba4ab5ef58959f83c7c5817889ff:25f385b2bb08c04649fd253213a50a44$" 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/assets/physics/fruit-sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/physics/fruit-sprites.png -------------------------------------------------------------------------------- /src/assets/spritesheet/adventurer-Sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/spritesheet/adventurer-Sheet.png -------------------------------------------------------------------------------- /src/assets/svg/bridge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 63 | -------------------------------------------------------------------------------- /src/assets/svg/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 75 | -------------------------------------------------------------------------------- /src/assets/water/Water_1_M_Normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/water/Water_1_M_Normal.jpg -------------------------------------------------------------------------------- /src/assets/water/Water_2_M_Normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enable3d/enable3d-website/82e7c9556427798e3e266024f45e6de808ecf647/src/assets/water/Water_2_M_Normal.jpg -------------------------------------------------------------------------------- /src/css/examples.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 5 | 'Droid Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 6 | } 7 | 8 | * { 9 | -webkit-user-select: none; /* Safari */ 10 | -ms-user-select: none; /* IE 10 and IE 11 */ 11 | user-select: none; /* Standard syntax */ 12 | -webkit-tap-highlight-color: transparent; 13 | } 14 | 15 | canvas { 16 | -webkit-tap-highlight-color: transparent; 17 | } 18 | 19 | body { 20 | color: #1b1b1b; 21 | overflow: hidden; 22 | } 23 | 24 | div#info-text { 25 | position: relative; 26 | justify-content: center; 27 | font-size: 18px; 28 | height: 0; 29 | top: 36px; 30 | z-index: 1; 31 | margin: 0px 48px; 32 | text-align: center; 33 | } 34 | 35 | div#info-text p { 36 | margin-bottom: 16px; 37 | } 38 | -------------------------------------------------------------------------------- /src/css/floating-action-button.css: -------------------------------------------------------------------------------- 1 | /** FAB */ 2 | div#floating-action-button { 3 | z-index: 1; 4 | position: fixed; 5 | background: white; 6 | bottom: 36px; 7 | right: 36px; 8 | width: 60px; 9 | height: 60px; 10 | border-radius: 50%; 11 | cursor: pointer; 12 | 13 | -webkit-box-shadow: 5px 5px 5px 0px rgb(0, 0, 0, 0.1); 14 | -moz-box-shadow: 5px 5px 5px 0px rgb(0, 0, 0, 0.1); 15 | box-shadow: 5px 5px 5px 0px rgb(0, 0, 0, 0.1); 16 | 17 | -webkit-user-select: none; /* Safari */ 18 | -ms-user-select: none; /* IE 10 and IE 11 */ 19 | user-select: none; /* Standard syntax */ 20 | } 21 | 22 | div#floating-action-button div { 23 | color: black; 24 | font-size: 24px; 25 | width: 60px; 26 | height: 60px; 27 | line-height: 56px; 28 | text-align: center; 29 | } 30 | -------------------------------------------------------------------------------- /src/docs/Basic-Setup.md: -------------------------------------------------------------------------------- 1 | ## Getting Started 2 | 3 | The project enable3d offers 4 different ways. As a Standalone 3D Framework, a Physics Plugin for [three.js](https://threejs.org/), as a 3D Objects and Physics extension for [Phaser](http://phaser.io/) or as a library to run Ammo.js on Node.js 4 | 5 | In this guide, you will learn how to use the Standalone 3D Framework. Most of what you learn, will be applicable to all packages. Just take a look at the [examples](https://enable3d.io/examples.html) to see what Enable3d can do and how to use the different packages. 6 | 7 | _Note: Not everything is documented yet, the [examples](https://enable3d.io/examples.html) page helps a lot!_ 8 | 9 | _Help: Do you know something that is not documented yet? Help improving the documentation on [GitHub](https://github.com/enable3d/enable3d-website/tree/master/src/docs)!_ 10 | 11 | ### Introduction Video 12 | 13 | Watch a great introduction video on YouTube 14 | 15 | ### Basic Setup 16 | 17 | ```ts 18 | // import the UMD bundle enable3d.framework.min.js 19 | // or from npm enable3d 20 | import { Project, Scene3D, PhysicsLoader } from 'enable3d' 21 | 22 | class MainScene extends Scene3D { 23 | constructor() { 24 | super('MainScene') 25 | } 26 | 27 | async init() { 28 | this.renderer.setPixelRatio(1) 29 | this.renderer.setSize(window.innerWidth, window.innerHeight) 30 | } 31 | 32 | async preload() { 33 | // preload your assets here 34 | } 35 | 36 | async create() { 37 | // set up scene (light, ground, grid, sky, orbitControls) 38 | this.warpSpeed() 39 | 40 | // enable physics debug 41 | this.physics.debug.enable() 42 | 43 | // position camera 44 | this.camera.position.set(10, 10, 20) 45 | 46 | // blue box (without physics) 47 | this.add.box({ y: 2 }, { lambert: { color: 'deepskyblue' } }) 48 | 49 | // pink box (with physics) 50 | this.physics.add.box({ y: 10 }, { lambert: { color: 'hotpink' } }) 51 | } 52 | 53 | update() { 54 | this.box.rotation.x += 0.01 55 | this.box.rotation.y += 0.01 56 | } 57 | } 58 | 59 | // set your project configs 60 | const config = { scenes: [MainScene] } 61 | 62 | // load the ammo.js file from the /lib folder and start the project 63 | PhysicsLoader('/lib', () => new Project(config)) 64 | ``` 65 | 66 | ### Native Three.js Objects 67 | 68 | You can use native Three.js objects if you include THREE 69 | 70 | ```ts 71 | import { THREE } from 'enable3d' 72 | 73 | // green sphere 74 | const geometry = new THREE.SphereGeometry(0.8, 16, 16) 75 | const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 }) 76 | const cube = new THREE.Mesh(geometry, material) 77 | cube.position.set(0.2, 3, 0) 78 | this.scene.add(cube) 79 | // add physics to an existing object 80 | this.physics.add.existing(cube) 81 | ``` 82 | 83 | ### Extended Three.js Objects 84 | 85 | To have more functionalities and a better compatibility, use `new ExtendedMesh()` and `new ExtendedGroup()` instead of `new THREE.Mesh()` and `new THREE.Group()` 86 | 87 | ```ts 88 | import { THREE, ExtendedMesh, ExtendedGroup } from 'enable3d' 89 | 90 | const cube = new ExtendedMesh(geometry, material) 91 | // instead of 92 | const cube = new THREE.Mesh(geometry, material) 93 | 94 | const object = new ExtendedGroup() 95 | // instead of 96 | const object = new THREE.Group() 97 | ``` 98 | -------------------------------------------------------------------------------- /src/docs/Basic-Shapes.md: -------------------------------------------------------------------------------- 1 | ## Basic Shapes 2 | 3 | Enable3d supports these shapes: 4 | 5 | - Plane 6 | - Box 7 | - Sphere 8 | - Cylinder 9 | - Cone 10 | - Capsule 11 | - Compound 12 | - Hull 13 | - HACD (Hierarchical Approximate Convex Decomposition) 14 | - ConvexMesh 15 | - ConcaveMesh 16 | - Heightfield (not yet) 17 | 18 | Enable3d does automatically recognize the shape of simple three.js object when adding it via `physics.add.existing(object)`. But you can also change the shape like so `physics.add.existing(object, { shape: 'hacd' })` 19 | 20 | Take a look at the [compare-physics-body-shapes](https://enable3d.io/examples/compare-physics-body-shapes.html) and the [play-with-physics-bodies](https://enable3d.io/examples/play-with-physics-bodies.html) examples to see creating & adding shapes in action. 21 | -------------------------------------------------------------------------------- /src/docs/Collisions.md: -------------------------------------------------------------------------------- 1 | ## Collisions 2 | 3 | You can check all collisions on a single body or check for collision between 2 specific bodies or check all collisions on bodies with checkCollisions set to true. The event will be `start`, `colliding` or `end`. 4 | 5 | ```javascript 6 | // all collision for blueBox (will set body.checkCollisions = true, on the blueBox) 7 | blueBox.body.on.collision((otherObject, event) => { 8 | if (otherObject.name !== 'ground') { 9 | console.log('blueBox collided with another object than the ground') 10 | } 11 | }) 12 | ``` 13 | 14 | ```javascript 15 | // collision between blueBox and redBox// 16 | // (will set body.checkCollisions = true, on the blueBox and the redBox) 17 | physics.add.collider(blueBox, redBox, event => { 18 | console.log(`blueBox and redBox: ${event}`) 19 | }) 20 | ``` 21 | 22 | ```javascript 23 | // show all collision for object that have { checkCollisions: true } 24 | physics.collisionEvents.on('collision', data => { 25 | const { bodies, event } = data 26 | console.log(bodies[0].name, bodies[1].name, event) 27 | }) 28 | 29 | const box = physics.add.box({ y: 10 }) 30 | box.body.checkCollisions = true // set checkCollisions to true 31 | ``` 32 | 33 | See the [collisions example](https://enable3d.io/examples/collision-detection.html) for details on implementing and using this event. 34 | 35 | ### Motion Clamping 36 | 37 | When an object has a high velocity, collisions can be missed if it moves through and past other objects between simulation steps. To fix this, enable CCD motion clamping. For a cube of size 1 try: 38 | 39 | ```javascript 40 | // Enable CCD if the object moves more than 1 meter in one simulation frame 41 | object.body.setCcdMotionThreshold(1) 42 | 43 | // Set the radius of the embedded sphere such that it is smaller than the object 44 | object.body.setCcdSweptSphereRadius(0.2) 45 | ``` 46 | -------------------------------------------------------------------------------- /src/docs/Compound-Shapes.md: -------------------------------------------------------------------------------- 1 | ## Compound shapes 2 | 3 | There are 3 ways to use compound shapes. Automatically generated (child or group) and manually generated. The automatically generated follow three.js objects structure. To manually generate a compound shape, simply add multiple shapes to the second parameter of `physics.add.existing()` 4 | 5 | ### Automatically 6 | 7 | ```js 8 | // example: https://enable3d.io/examples/play-with-physics-bodies.html 9 | 10 | // compound shape (child based) 11 | // (the center of mass is the center of the box) 12 | let box1 = this.add.box({ x: 0, y: 2 }) 13 | let sphere3 = this.add.sphere({ radius: 0.5, x: 0.25, y: 0.5 }) // relative position to box1 14 | box1.add(sphere3) 15 | this.physics.add.existing(box1) 16 | 17 | // compound shape (group based) 18 | // (the center of mass is 0,0,0) 19 | let group = new THREE.Group() 20 | const body = this.add.box({ height: 0.8, y: 1, width: 0.4, depth: 0.4 }, { lambert: { color: 0xffff00 } }) 21 | const head = this.add.sphere({ radius: 0.25, y: 1.7, z: 0.05 }, { lambert: { color: 0xffff00 } }) 22 | group.add(body, head) 23 | group.position.setX(3) 24 | this.add.existing(group) 25 | this.physics.add.existing(group) 26 | ``` 27 | 28 | ### Manually 29 | 30 | ```javascript 31 | // example: https://enable3d.io/examples/play-with-physics-bodies.html 32 | 33 | // custom compound shape 34 | const box = this.add.box({ x: 9 }) 35 | const compound = [ 36 | { shape: 'box', width: 0.5, height: 1, depth: 0.4, y: -0.5, z: 0.5 }, 37 | { shape: 'box', width: 2.4, height: 0.6, depth: 0.4, z: -0.4, y: 0.2 }, 38 | { shape: 'sphere', radius: 0.65, z: -0.25, y: 0.35 }, 39 | { shape: 'box', width: 1.5, height: 0.8, depth: 1, y: 0.2, z: 0.2 } 40 | ] 41 | this.physics.add.existing(box, { compound }) 42 | ``` 43 | -------------------------------------------------------------------------------- /src/docs/Constraints.md: -------------------------------------------------------------------------------- 1 | ## Constraints 2 | 3 | The following constraints are available, but I have not yet written the documentation. 4 | 5 | - Lock 6 | - Fixed 7 | - Spring 8 | - Slider 9 | - Hinge 10 | - Cone Twist 11 | - Point To Point 12 | 13 | You will find an [example of all constraints here](https://enable3d.io/examples/types-of-constraints.html). 14 | -------------------------------------------------------------------------------- /src/docs/Controls.md: -------------------------------------------------------------------------------- 1 | ## Controls 2 | 3 | ### JoyStick 4 | 5 | Not documented yet. 6 | 7 | ### FirstPersonControls 8 | 9 | Not documented yet. 10 | 11 | ### ThirdPersonControls 12 | 13 | Not documented yet. 14 | 15 | ### PointerDrag 16 | 17 | Not documented yet. 18 | 19 | ### PointerLock 20 | 21 | ### Audio, Keyboard and Mouse 22 | 23 | Take a look at the following packages: 24 | 25 | | Package | Description | 26 | | ------------------------------------------------------------ | ------------------------------------------------------------------------- | 27 | | [`audio`](https://www.npmjs.com/package/@yandeu/audio) | 🎵 Audio library for the Web Audio API. | 28 | | [`keyboard`](https://www.npmjs.com/package/@yandeu/keyboard) | ⌨️ Handling of keyboard events. | 29 | | [`tap`](https://www.npmjs.com/package/@yandeu/tap) | 🖱️ Handling of user interactions such as mouse, touch and pointer events. | 30 | -------------------------------------------------------------------------------- /src/docs/Factory.md: -------------------------------------------------------------------------------- 1 | ## Factory 2 | 3 | Enable3d provides a simple factory for creating physical objects. 4 | 5 | ```js 6 | // will add a 5x3x1 red box 7 | const box = physics.add.box( 8 | { x: 1, y: 2, z: 10, width: 5, height: 3, depth: 1, mass: 2, collisionFlags: 0 }, 9 | { lambert: { color: 'red', transparent: true, opacity: 0.5 } } 10 | ) 11 | ``` 12 | 13 | If you want to use the factory without adding physics to the object, extract the factory from physics. 14 | 15 | ```js 16 | // get the objects factory 17 | const { factory } = physics 18 | 19 | // add the same box as above, but without physics 20 | const box = factory.add.box({ x: 1, y: 2, z: 10, width: 5, height: 3, depth: 1 }, { lambert: { color: 'red', transparent: true, opacity: 0.5 } }) 21 | 22 | // you can later add physics to it 23 | physics.add.existing(box, { mass: 2, collisionFlags: 0 }) 24 | ``` 25 | 26 | You can also add custom materials like so: 27 | 28 | ```js 29 | physics.add.box({}, { custom: THREE.MeshLambertMaterial({ color: 0x2194ce }) }) 30 | ``` 31 | -------------------------------------------------------------------------------- /src/docs/Lights.md: -------------------------------------------------------------------------------- 1 | ## Lights 2 | 3 | Not documented yet. -------------------------------------------------------------------------------- /src/docs/Loaders.md: -------------------------------------------------------------------------------- 1 | ## Loaders 2 | 3 | Not documented yet. 4 | -------------------------------------------------------------------------------- /src/docs/Misc.md: -------------------------------------------------------------------------------- 1 | ## Misc 2 | 3 | Not documented yet. 4 | 5 | ### Water 6 | -------------------------------------------------------------------------------- /src/docs/Physics-Body.md: -------------------------------------------------------------------------------- 1 | ## Physics Body 2 | 3 | ### Body Types 4 | 5 | There are 4 different body types you can choose from by setting `object.body.setCollisionFlags(number)` accordingly. 6 | 7 | - 0 - Dynamic 8 | - 1 - Static 9 | - 2 - Kinematic 10 | - 4 - Ghost (aka Sensor or NO_CONTACT_RESPONSE). 11 | 12 | #### Dynamic 13 | 14 | The dynamic bodies react to force and gravity and you can apply velocity and torque to them. 15 | 16 | ```js 17 | // example: https://enable3d.io/examples/first-phaser-game-3d-version.html 18 | 19 | jump() { 20 | dynamicObject.body.applyForceY(16) 21 | } 22 | ``` 23 | 24 | #### Static 25 | 26 | These object are just there but do not move at all. 27 | 28 | #### Kinematic 29 | 30 | These bodies do NOT react to force or gravity. You can only move them by adjusting its position or rotation. 31 | 32 | ```js 33 | // example: https://enable3d.io/examples/kinematic-body-orbiting-around-sun.html 34 | 35 | update() { 36 | kinematicObject.position.set(0,5,0) 37 | kinematicObject.rotation.x += 0.01 38 | // set needUpdate to true, every time you want 39 | // to adjust the position or rotation of a kinematic body 40 | kinematicObject.body.needUpdate = true 41 | } 42 | ``` 43 | 44 | #### Ghost 45 | 46 | These bodies do never interact with other bodies. But they fire collision events. Use them as sensory in your game. Ghost can be dynamic (4), static (5) or kinematic (6), by settings the `collisionFlags` accordingly. 47 | 48 | ### Headless Physics 49 | 50 | In headless mode, make sure you call `transform` and `refresh` on the body when updating the position or rotation. See [#242](https://github.com/enable3d/enable3d/issues/242). 51 | 52 | ### Body Methods 53 | 54 | You can use a lot of method on the body (`object.body.something()`). It does not make sense listing them all here. 55 | 56 | Just take a look the the [physicsBody.ts source code](https://github.com/enable3d/enable3d/blob/master/packages/common/src/physicsBody.ts). 57 | -------------------------------------------------------------------------------- /src/docs/Physics-Configuration.md: -------------------------------------------------------------------------------- 1 | ## Physics Configuration 2 | 3 | When we add Enable3d to the scene, there are a few choices we can make. 4 | 5 | ```js 6 | new Project({ gravity: { x: 0, y: -9.81, z: 0 }, maxSubSteps: 4, fixedTimeStep: 1 / 60 }) 7 | ``` 8 | 9 | - **gravity** `default { x: 0, y: -9.81, z: 0 }` _Sets the amount and direction of gravitational forces_ 10 | 11 | - **maxSubSteps** `default 2` _Set the max sub steps allowed._ 12 | 13 | - **fixedTimeStep** `default 1 / 60` _This number determines how much time one simulation step is to simulate. The smaller the number, the more accurate (and slower) the simulation._ 14 | 15 | You must always satisfy the equation **timeStep(fps) < maxSubSteps \* fixedTimeStep** 16 | -------------------------------------------------------------------------------- /src/docs/Position-Rotation-Scale.md: -------------------------------------------------------------------------------- 1 | ## Position, Rotation and Scale 2 | 3 | ### Position 4 | 5 | You can only set the position (and rotation) at any moment if it the body is of type [kinematic](#kinematic). See [Body Types](#body-types). For all other types, you have to set the position and the rotation before you add a physics body to it. 6 | 7 | Example of a non kinematic box: 8 | 9 | ```js 10 | const { factory } = physics 11 | 12 | // add a box without physics 13 | const box = factory.add.box() 14 | // set position and rotation 15 | box.position.set(10, 10, 0) 16 | box.rotation.set(0, Math.PI / 2, 0) 17 | // add physics to the box 18 | physics.add.existing(box) 19 | ``` 20 | 21 | But if you really need to set a new position or rotation to any other type than kinematic, see the [Teleport Example](https://enable3d.io/examples/teleport-a-dynamic-body.html). 22 | 23 | ### Rotation 24 | 25 | Same as [Position](#position). 26 | 27 | ### Scale 28 | 29 | You can't scale a physics body after added to the world. But you can scale your object before adding physics to it or remove the physics body and add a new one. 30 | 31 | Example of a Torus: 32 | 33 | ```js 34 | const { factory } = physics 35 | 36 | // add torus (without physics) 37 | let torus = factory.add.torus() 38 | // scale the torus 39 | torus.scale.set(2, 2, 2) 40 | // add a rigid body to it 41 | physics.add.existing(torus, { shape: 'hacd' }) 42 | 43 | // add torus (with physics) 44 | let torus = physics.add.torus() 45 | // remove the rigid body 46 | physics.destroy(torus.body) 47 | // scale the torus 48 | torus.scale.set(2, 2, 2) 49 | // add a new rigid body to it 50 | physics.add.existing(torus, { shape: 'hacd' }) 51 | ``` 52 | -------------------------------------------------------------------------------- /src/docs/Raycasting.md: -------------------------------------------------------------------------------- 1 | ## Raycasting 2 | 3 | Not documented yet. 4 | 5 | ### Objects Raycasting 6 | 7 | ### Physics Raycasting 8 | -------------------------------------------------------------------------------- /src/docs/Tweens.md: -------------------------------------------------------------------------------- 1 | ## Tweens 2 | 3 | Want to use Tweens? Checkout [https://github.com/tweenjs/tween.js](https://github.com/tweenjs/tween.js) 4 | -------------------------------------------------------------------------------- /src/docs/Warp-Speed.md: -------------------------------------------------------------------------------- 1 | ## Warp Speed 2 | 3 | When building your projects, you need to set up the _third-dimension_ most of the time. For instance, you need a basic setup with at least one camera, lights, orbit controls, and so on. To design all these things takes a long time. 4 | 5 | You can shorten that time by using Enable3d `warpSpeed()` function. The function supports the following features: 6 | 7 | - light 8 | - camera 9 | - lookAtCenter 10 | - ground 11 | - grid 12 | - orbitControls 13 | - sky 14 | - fog 15 | 16 | By default, the function enables all the features. 17 | 18 | ```js 19 | class MainScene extends Scene3D { 20 | 21 | async create() { 22 | // set up scene (light, ground, grid, sky, orbitControls) 23 | await this.warpSpeed() 24 | 25 | // additionally warpSpeed() returns the camera, ground, lights, orbitControls. 26 | const { camera, ground, lights, orbitControls } = await this.warpSpeed() 27 | 28 | // now modify the features (if needed) 29 | // example: 30 | camera.position.set(10, 10, 10) 31 | camera.lookAt(0, 5, 0) 32 | 33 | const { hemisphereLight, ambientLight, directionalLight } = lights 34 | hemisphereLight.intensity = 0.65 35 | 36 | orbitControls.target.set(0, 5, 0) 37 | } 38 | ``` 39 | 40 | If you only want to set up particular features, you can call the function passing the feature name. 41 | 42 | ```js 43 | this.warpSpeed('light', 'ground', 'sky') 44 | ``` 45 | 46 | Also, if you want to enable all the features but some, you can specify the feature name with the minus sign. 47 | 48 | ```js 49 | // enable all the features but the orbit controls 50 | this.warpSpeed('-orbitControls') 51 | ``` 52 | 53 | The following sections provide some details on all features. 54 | 55 | ### Light 56 | 57 | Including 'light' among the features in `warpSpeed()`, Enable3D will place three lights in the scene: 58 | 59 | - a hemisphere light 60 | - an ambient light 61 | - a directional light 62 | 63 | The directional light is positioned at `(100, 200, 50)`. 64 | 65 | ### Camera 66 | 67 | Including 'camera' among the features in `warpSpeed()`, Enable3D will place a camera in position `(0, 6, 12)` 68 | 69 | ### Look at Center 70 | 71 | Including 'lookAtCenter' among the features in `warpSpeed()`, Enable3D will make the camera looking at the scene's initial position. 72 | 73 | ### Ground 74 | 75 | Including 'ground' among the features in `warpSpeed()`, Enable3D will create a ground platform in the scene. 76 | The ground platform measures 21x21x1, and it is positioned 0.5 under the origin. By default, the ground platform is not texturized. 77 | 78 | ### Grid 79 | 80 | The 'grid' feature of `warpSpeed()` is available only when the 'ground' feature is included in the feature list. 81 | When included, Enable3D will texturize the ground platform with a grid composed of white 1x1 squares with a black border. 82 | 83 | ### Orbit Controls 84 | 85 | Including 'orbitControls' among the features in `warpSpeed()`, Enable3D will include a set of controllers to allow the camera to orbit around a target. 86 | 87 | The Orbit Controller is documented in [this example from ThreeJS](https://threejs.org/docs/#examples/en/controls/OrbitControls) 88 | 89 | ### Sky 90 | 91 | Including 'orbitControls' among the features in `warpSpeed()`, Enable3D will include a Mesh and a set of shaders to simulate the effect of an azure sky. Shaders derive from the example documented in [this example from ThreeJS](https://threejs.org/examples/webgl_lights_hemisphere) 92 | 93 | ### Fog 94 | 95 | Not available in the current release. 96 | -------------------------------------------------------------------------------- /src/docs/WebXR.md: -------------------------------------------------------------------------------- 1 | ## WebXR 2 | 3 | Not documented yet. 4 | 5 | ### Virtual Reality 6 | 7 | ### Augmented Reality 8 | -------------------------------------------------------------------------------- /src/examples/adjust-gamma-factor-and-shadows.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 9 | 10 |
54 |
55 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/examples/headless-fbx-loader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeScript Example: https://github.com/enable3d/ammo-on-nodejs-example
3 | */
4 |
5 | var _ammo = require('@enable3d/ammo-on-nodejs/ammo/ammo.js')
6 | const { Physics, ServerClock, Loaders, ExtendedObject3D } = require('@enable3d/ammo-on-nodejs')
7 | const path = require('path')
8 |
9 | class ServerScene {
10 | constructor() {
11 | this.init()
12 | this.create()
13 | }
14 |
15 | init() {
16 | // test if we have access to Ammo
17 | console.log('Ammo', new Ammo.btVector3(1, 2, 3).y() === 2)
18 |
19 | // init the Physics
20 | this.physics = new Physics()
21 | this.factory = this.physics.factory
22 | }
23 |
24 | create() {
25 | const ground = this.physics.add.box({
26 | name: 'ground',
27 | width: 40,
28 | depth: 40,
29 | collisionFlags: 2,
30 | mass: 0
31 | })
32 |
33 | const FBXLoader = new Loaders.FBXLoader()
34 | FBXLoader.load(path.resolve(__dirname, '../assets/fbx/Idle.fbx')).then(fbx => {
35 | const robot = new ExtendedObject3D()
36 | robot.name = 'robot'
37 |
38 | robot.add(fbx)
39 | robot.scale.set(0.05, 0.05, 0.05)
40 | robot.position.set(0, 10, 0)
41 |
42 | const physicsOptions = {
43 | addChildren: false,
44 | shape: 'hull' // or any other shape you want
45 | }
46 |
47 | this.physics.add.existing(robot, physicsOptions)
48 | this.robot = robot
49 | })
50 |
51 | // clock
52 | const clock = new ServerClock()
53 |
54 | // for debugging you disable high accuracy
55 | // high accuracy uses much more cpu power
56 | if (process.env.NODE_ENV !== 'production') clock.disableHighAccuracy()
57 |
58 | clock.onTick(delta => this.update(delta))
59 | }
60 |
61 | update(delta) {
62 | this.physics.update(delta * 1000)
63 |
64 | if (!this.robot) return // robot has not been parsed yet
65 |
66 | const y = this.robot.position.y.toFixed(2)
67 |
68 | // watch the y position fall down from 5 to the ground
69 | if (y > 2) console.log('y:', y)
70 |
71 | // TODO
72 | // send new positions to the client
73 | }
74 | }
75 |
76 | // wait for Ammo to be loaded
77 | _ammo().then(ammo => {
78 | globalThis.Ammo = ammo
79 |
80 | // start server scene
81 | new ServerScene()
82 | })
83 |
--------------------------------------------------------------------------------
/src/examples/headless-gltf-loader.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
54 |
55 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/examples/headless-gltf-loader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeScript Example: https://github.com/enable3d/ammo-on-nodejs-example
3 | */
4 |
5 | var _ammo = require('@enable3d/ammo-on-nodejs/ammo/ammo.js')
6 | const { Physics, ServerClock, Loaders, ExtendedObject3D } = require('@enable3d/ammo-on-nodejs')
7 | const path = require('path')
8 |
9 | class ServerScene {
10 | constructor() {
11 | this.init()
12 | this.create()
13 | }
14 |
15 | init() {
16 | // test if we have access to Ammo
17 | console.log('Ammo', new Ammo.btVector3(1, 2, 3).y() === 2)
18 |
19 | // init the Physics
20 | this.physics = new Physics()
21 | this.factory = this.physics.factory
22 | }
23 |
24 | create() {
25 | const ground = this.physics.add.box({
26 | name: 'ground',
27 | width: 40,
28 | depth: 40,
29 | collisionFlags: 2,
30 | mass: 0
31 | })
32 |
33 | this.objects = [ground]
34 |
35 | const GLTFLoader = new Loaders.GLTFLoader()
36 | GLTFLoader.load(path.resolve(__dirname, '../assets/glb/suzanne.glb')).then(gltf => {
37 | const child = gltf.scene.children[0]
38 | const suzanne = new ExtendedObject3D()
39 |
40 | suzanne.add(child)
41 | suzanne.position.set(0, 5, 0)
42 |
43 | const physicsOptions = {
44 | addChildren: false,
45 | shape: 'hacd' // or any other shape you want
46 | }
47 |
48 | this.factory.add.existing(suzanne)
49 | this.physics.add.existing(suzanne, physicsOptions)
50 |
51 | suzanne.body.setFriction(1)
52 |
53 | this.objects.push(suzanne)
54 | })
55 |
56 | // clock
57 | const clock = new ServerClock()
58 |
59 | // for debugging you disable high accuracy
60 | // high accuracy uses much more cpu power
61 | if (process.env.NODE_ENV !== 'production') clock.disableHighAccuracy()
62 |
63 | clock.onTick(delta => this.update(delta))
64 | }
65 |
66 | update(delta) {
67 | this.physics.update(delta * 1000)
68 |
69 | const suzanne = this.objects[1]
70 | if (!suzanne) return // suzanne has not been parsed yet
71 |
72 | const y = suzanne.position.y.toFixed(2)
73 |
74 | // watch the y position fall down from 5 to the ground
75 | if (y > 2) console.log('y:', suzanne.body.position.y.toFixed(2))
76 |
77 | // TODO
78 | // send new positions to the client
79 | }
80 | }
81 |
82 | // wait for Ammo to be loaded
83 | _ammo().then(ammo => {
84 | globalThis.Ammo = ammo
85 |
86 | // start server scene
87 | new ServerScene()
88 | })
89 |
--------------------------------------------------------------------------------
/src/examples/headless-mode.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
54 |
55 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/examples/headless-mode.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeScript Example: https://github.com/enable3d/ammo-on-nodejs-example
3 | */
4 |
5 | var _ammo = require('@enable3d/ammo-on-nodejs/ammo/ammo.js')
6 | const { Physics, ServerClock } = require('@enable3d/ammo-on-nodejs')
7 |
8 | class ServerScene {
9 | constructor() {
10 | this.init()
11 | this.create()
12 | }
13 |
14 | init() {
15 | // test if we have access to Ammo
16 | console.log('Ammo', new Ammo.btVector3(1, 2, 3).y() === 2)
17 |
18 | // init the Physics
19 | this.physics = new Physics()
20 | this.factory = this.physics.factory
21 | }
22 |
23 | create() {
24 | const ground = this.physics.add.box({
25 | name: 'ground',
26 | width: 40,
27 | depth: 40,
28 | collisionFlags: 2,
29 | mass: 0
30 | })
31 |
32 | const box = this.physics.add.box({ name: 'box', y: 5 })
33 |
34 | /**
35 | * "this.physics.add.box({ name: 'box', y: 5 })"
36 | * is exactly the same as you would do:
37 | *
38 | * const geometry = new THREE.BoxGeometry()
39 | * const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
40 | * const box = new THREE.Mesh(geometry, material)
41 | * box.name = 'box' // give it a name
42 | * box.position.set(0, 5, 0) // set y to 5
43 | * this.physics.add.existing(box) // add physics to the box
44 | *
45 | * of course you would have to include three first
46 | * const THREE = require('three')
47 | */
48 |
49 | this.objects = [ground, box]
50 |
51 | // clock
52 | const clock = new ServerClock()
53 |
54 | // for debugging you disable high accuracy
55 | // high accuracy uses much more cpu power
56 | if (process.env.NODE_ENV !== 'production') clock.disableHighAccuracy()
57 |
58 | clock.onTick(delta => this.update(delta))
59 | }
60 |
61 | update(delta) {
62 | this.physics.update(delta * 1000)
63 |
64 | const box = this.objects[1]
65 | const y = box.position.y.toFixed(2)
66 |
67 | // will print the y position of the box from 5.00 to 1.00
68 | if (y > 1) console.log('y:', y)
69 |
70 | // TODO
71 | // send new positions to the client
72 | }
73 | }
74 |
75 | // wait for Ammo to be loaded
76 | _ammo().then(ammo => {
77 | globalThis.Ammo = ammo
78 |
79 | // start server scene
80 | new ServerScene()
81 | })
82 |
--------------------------------------------------------------------------------
/src/examples/heightmap-with-color-scale.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |