├── README.md ├── .gitignore ├── .babelrc ├── app ├── favicon.ico ├── ammo.wasm.wasm └── fizzle-out.html ├── webpack.config.js ├── package.json └── src └── index.js /README.md: -------------------------------------------------------------------------------- 1 | :fish_cake: -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatever/fizzle-out/main/app/favicon.ico -------------------------------------------------------------------------------- /app/ammo.wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatever/fizzle-out/main/app/ammo.wasm.wasm -------------------------------------------------------------------------------- /app/fizzle-out.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | the future is already here... just not evenly distributed 5 | 6 | 7 | 8 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | 4 | module.exports = { 5 | entry: ["@babel/polyfill", "./src/index.js"], 6 | output: { 7 | library: "yikes", 8 | libraryTarget: "var", 9 | path: path.join(__dirname, "dist"), 10 | filename: "build.js" 11 | }, 12 | externals: { 13 | three: "THREE" 14 | }, 15 | devServer: { 16 | port: 8080, 17 | }, 18 | module: { 19 | rules: [ 20 | { 21 | test: /\.js$/, 22 | exclude: /node_modules/, 23 | loader: 'babel-loader', 24 | options: { 25 | presets: ['@babel/preset-env'], 26 | plugins: ["@babel/transform-runtime"] 27 | } 28 | } 29 | ] 30 | }, 31 | experiments: { 32 | syncWebAssembly: true, 33 | topLevelAwait: true, 34 | asyncWebAssembly: true, 35 | }, 36 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fizzle-out", 3 | "version": "0.0.1", 4 | "description": ":fish_cake:", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "ayyy": "webpack --mode production", 8 | "lmao": "webpack serve --config webpack.config.js --static app --open --mode development --host localhost --hot", 9 | "test": "echo do some testing && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/whatever/fizzle-out.git" 14 | }, 15 | "keywords": [ 16 | "fuck", 17 | "fuck", 18 | "party", 19 | "party" 20 | ], 21 | "author": "Matt <3", 22 | "license": "UNLICENSED", 23 | "homepage": "https://github.com/whatever/fizzle-out#readme", 24 | "devDependencies": { 25 | "@babel/core": "^7.12.13", 26 | "@babel/plugin-transform-runtime": "^7.12.15", 27 | "@babel/polyfill": "^7.12.1", 28 | "@babel/preset-env": "^7.12.13", 29 | "@babel/runtime": "^7.12.13", 30 | "babel-loader": "^8.2.2", 31 | "webpack": "^5.21.2", 32 | "webpack-cli": "^4.5.0", 33 | "webpack-dev-server": "^4.0.0-beta.0" 34 | }, 35 | "mode": "development" 36 | } 37 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const THREE = require("three"); 2 | 3 | const COL_GROUP_PLANE = 1; 4 | const COL_GROUP_RED_BALL = 2; 5 | const COL_GROUP_GREEN_BALL = 4; 6 | 7 | export class Fizzle { 8 | 9 | start(ammo) { 10 | let collisionConfiguration = new Ammo.btDefaultCollisionConfiguration(); 11 | let dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration); 12 | let overlappingPairCache = new Ammo.btDbvtBroadphase(); 13 | let solver = new Ammo.btSequentialImpulseConstraintSolver(); 14 | this.physicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); 15 | this.physicsWorld.setGravity(new Ammo.btVector3(0, -10, 0)); 16 | 17 | this.setup(); 18 | } 19 | 20 | constructor(el) { 21 | 22 | this.started = false; 23 | 24 | this.bodies = []; 25 | 26 | this.clock = new THREE.Clock(); 27 | 28 | Ammo().then(this.start.bind(this)); 29 | 30 | this.ctx = el.getContext("webgl"); 31 | this.scene = new THREE.Scene(); 32 | this.renderer = new THREE.WebGLRenderer({ 33 | canvas: el, 34 | antialias: true, 35 | }); 36 | this.renderer.setClearColor("#000000"); 37 | this.camera = new THREE.PerspectiveCamera( 38 | 75, 39 | el.width/el.height, 40 | 0.1, 41 | 1000, 42 | ); 43 | } 44 | 45 | addPlane() { 46 | 47 | // SHARED 48 | 49 | let pos = {x: 0, y: 0, z: 0}; 50 | let scale = {x: 50, y: 2, z: 50}; 51 | let quat = {x: 0, y: 0, z: 0.4, w: 1}; 52 | let mass = 0; 53 | 54 | // THREE 55 | 56 | let plane = new THREE.Mesh( 57 | new THREE.BoxBufferGeometry(), 58 | new THREE.MeshBasicMaterial({color: 0xa0afa4}), 59 | ); 60 | 61 | plane.position.set(pos.x, pos.y, pos.z); 62 | plane.scale.set(scale.x, scale.y, scale.z); 63 | 64 | this.scene.add(plane); 65 | 66 | // AMMO 67 | 68 | let transform = new Ammo.btTransform(); 69 | transform.setIdentity(); 70 | transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z)); 71 | transform.setRotation(new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w)); 72 | 73 | let motionState = new Ammo.btDefaultMotionState(transform); 74 | let colShape = new Ammo.btBoxShape(new Ammo.btVector3(scale.x/2, scale.y/2, scale.z/2)); 75 | colShape.setMargin(0.05); 76 | 77 | let localInertia = new Ammo.btVector3(0, 0, 0); 78 | colShape.calculateLocalInertia(mass, localInertia); 79 | 80 | let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, colShape, localInertia); 81 | let body = new Ammo.btRigidBody(rbInfo); 82 | 83 | this.physicsWorld.addRigidBody(body); 84 | plane.userData.physicsBody = body; 85 | this.bodies.push(plane); 86 | } 87 | 88 | addBall() { 89 | 90 | // SHARED 91 | 92 | let pos = { x: 0, y: 20, z: 0 }; 93 | let radius = 2; 94 | let quat = { x: 0, y: 0, z: 0, w: 1 }; 95 | let mass = 1; 96 | 97 | // THREE 98 | 99 | let ball = new THREE.Mesh( 100 | new THREE.SphereBufferGeometry(radius), 101 | new THREE.MeshBasicMaterial({color: "#433F81"}), 102 | ); 103 | 104 | ball.position.set(pos.x, pos.y, pos.z); 105 | 106 | this.scene.add(ball); 107 | 108 | // AMMO 109 | 110 | let transform = new Ammo.btTransform(); 111 | transform.setIdentity(); 112 | transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z)); 113 | transform.setRotation(new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w)); 114 | let motionState = new Ammo.btDefaultMotionState(transform); 115 | 116 | let colShape = new Ammo.btSphereShape(radius); 117 | colShape.setMargin(0.05); 118 | 119 | let localInertia = new Ammo.btVector3(0, 0, 0); 120 | colShape.calculateLocalInertia(mass, localInertia); 121 | 122 | let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, colShape, localInertia); 123 | let body = new Ammo.btRigidBody(rbInfo); 124 | 125 | this.physicsWorld.addRigidBody(body); 126 | ball.userData.physicsBody = body; 127 | this.bodies.push(ball); 128 | } 129 | 130 | setup() { 131 | this.addPlane(); 132 | this.addBall(); 133 | 134 | this.started = true; 135 | } 136 | 137 | updatePhysics() { 138 | if (!this.started) return; 139 | 140 | let delta = this.clock.getDelta(); 141 | this.physicsWorld.stepSimulation(delta, 10); 142 | 143 | let tmpTrans = new Ammo.btTransform(); 144 | 145 | for (let i=0; i < this.bodies.length; i++) { 146 | let objThree = this.bodies[i]; 147 | let objAmmo = objThree.userData.physicsBody; 148 | 149 | let motionState = objAmmo.getMotionState(); 150 | 151 | if (motionState) { 152 | motionState.getWorldTransform(tmpTrans); 153 | let p = tmpTrans.getOrigin(); 154 | let q = tmpTrans.getRotation(); 155 | objThree.position.set(p.x(), p.y(), p.z()); 156 | objThree.quaternion.set(q.x(), q.y(), q.z(), q.w()); 157 | } 158 | } 159 | } 160 | 161 | update() { 162 | this.camera.position.x = 0.0; 163 | this.camera.position.y = 10.0; 164 | this.camera.position.z = 30.0; 165 | this.camera.lookAt(0, 10, 0); 166 | 167 | this.updatePhysics(); 168 | } 169 | 170 | draw() { 171 | this.renderer.render(this.scene, this.camera); 172 | } 173 | }; --------------------------------------------------------------------------------