├── 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 | };
--------------------------------------------------------------------------------