Skip to content

Commit c4aa0bf

Browse files
Added multithreaded version of Jolt to the npm package (#210)
Co-authored-by: Jonathan Baran <[email protected]>
1 parent cf53f8f commit c4aa0bf

File tree

12 files changed

+1808
-1536
lines changed

12 files changed

+1808
-1536
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
Build/
22
dist/
33
node_modules
4-
Examples/js/jolt-physics.wasm-compat.js
5-
Examples/js/jolt-physics.wasm-compat.worker.js
4+
Examples/js/jolt-physics.*.js

CMakeLists.txt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,17 @@ set(OBJECT_LAYER_BITS 32)
5252
if (ENABLE_MULTI_THREADING)
5353
set(MULTI_THREADED_FLAG
5454
-pthread
55+
--post-js ${CMAKE_CURRENT_SOURCE_DIR}/multi-threaded.js
5556
-s SHARED_MEMORY)
5657
set(ENVIRONMENT_FLAG
5758
-s ENVIRONMENT='web,node,worker'
5859
-s PTHREAD_POOL_SIZE=16)
5960
set(CMAKE_CXX_FLAGS "-pthread -s SHARED_MEMORY")
61+
set(OUTPUT_BASE_NAME "${OUTPUT_FOLDER}jolt-physics.multithread")
6062
else()
6163
set(MULTI_THREADED_FLAG "")
6264
set(ENVIRONMENT_FLAG "-s ENVIRONMENT='web,node'")
65+
set(OUTPUT_BASE_NAME "${OUTPUT_FOLDER}jolt-physics")
6366
endif()
6467

6568
# Enable SIMD flags
@@ -213,27 +216,27 @@ if (NOT BUILD_WASM_COMPAT_ONLY)
213216
if (NOT ENABLE_MULTI_THREADING # Not compatible with multi threading due to error: 'void wasm::I64ToI32Lowering::visitStore(Store *): Assertion `!curr->isAtomic && "atomic store not implemented"' failed.'
214217
AND NOT ENABLE_SIMD) # Not compatible with SIMD due to error: 'unhandled unaligned load'
215218
add_custom_command(
216-
OUTPUT ${OUTPUT_FOLDER}jolt-physics.js
217-
COMMAND emcc glue.o $<TARGET_FILE:Jolt> ${EMCC_JS_ARGS} -o ${OUTPUT_FOLDER}jolt-physics.js
219+
OUTPUT ${OUTPUT_BASE_NAME}.js
220+
COMMAND emcc glue.o $<TARGET_FILE:Jolt> ${EMCC_JS_ARGS} -o ${OUTPUT_BASE_NAME}.js
218221
DEPENDS jolt-bindings ${JOLT_FRONT_MATTER_FILE} ${JOLT_TARGETS} ${JOLT_IDL_FILE} ${JOLT_HEADER_FILE}
219222
COMMENT "Building JoltPhysics.js javascript"
220223
VERBATIM)
221-
add_custom_target(jolt-javascript ALL DEPENDS ${OUTPUT_FOLDER}jolt-physics.js)
224+
add_custom_target(jolt-javascript ALL DEPENDS ${OUTPUT_BASE_NAME}.js)
222225
endif()
223226

224227
add_custom_command(
225-
OUTPUT ${OUTPUT_FOLDER}jolt-physics.wasm.js ${OUTPUT_FOLDER}jolt-physics.wasm.wasm
226-
COMMAND emcc glue.o $<TARGET_FILE:Jolt> ${EMCC_WASM_ARGS} -o ${OUTPUT_FOLDER}jolt-physics.wasm.js
228+
OUTPUT ${OUTPUT_BASE_NAME}.wasm.js ${OUTPUT_BASE_NAME}.wasm.wasm
229+
COMMAND emcc glue.o $<TARGET_FILE:Jolt> ${EMCC_WASM_ARGS} -o ${OUTPUT_BASE_NAME}.wasm.js
227230
DEPENDS jolt-bindings ${JOLT_FRONT_MATTER_FILE} ${JOLT_TARGETS} ${JOLT_IDL_FILE} ${JOLT_HEADER_FILE}
228231
COMMENT "Building JoltPhysics.js webassembly"
229232
VERBATIM)
230-
add_custom_target(jolt-wasm ALL DEPENDS ${OUTPUT_FOLDER}jolt-physics.wasm.js ${OUTPUT_FOLDER}jolt-physics.wasm.wasm)
233+
add_custom_target(jolt-wasm ALL DEPENDS ${OUTPUT_BASE_NAME}.wasm.js ${OUTPUT_BASE_NAME}.wasm.wasm)
231234
endif()
232235

233236
add_custom_command(
234-
OUTPUT ${OUTPUT_FOLDER}jolt-physics.wasm-compat.js
235-
COMMAND emcc glue.o $<TARGET_FILE:Jolt> ${EMCC_WASM_COMPAT_ARGS} -o ${OUTPUT_FOLDER}jolt-physics.wasm-compat.js
237+
OUTPUT ${OUTPUT_BASE_NAME}.wasm-compat.js
238+
COMMAND emcc glue.o $<TARGET_FILE:Jolt> ${EMCC_WASM_COMPAT_ARGS} -o ${OUTPUT_BASE_NAME}.wasm-compat.js
236239
DEPENDS jolt-bindings ${JOLT_FRONT_MATTER_FILE} ${JOLT_TARGETS} ${JOLT_IDL_FILE} ${JOLT_HEADER_FILE}
237240
COMMENT "Building JoltPhysics.js compat webassembly"
238241
VERBATIM)
239-
add_custom_target(jolt-wasm-compat ALL DEPENDS ${OUTPUT_FOLDER}jolt-physics.wasm-compat.js)
242+
add_custom_target(jolt-wasm-compat ALL DEPENDS ${OUTPUT_BASE_NAME}.wasm-compat.js)
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>JoltPhysics.js demo</title>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
7+
<link rel="stylesheet" type="text/css" href="style.css">
8+
</head>
9+
<body>
10+
<div id="container">Loading...</div>
11+
<div id="info">JoltPhysics.js multi threaded conveyor belt demo<br />
12+
This demo shows how to use the contact listener to modify object angular and linear velocity
13+
</div>
14+
15+
<script src="js/three/three.min.js"></script>
16+
<script src="js/three/OrbitControls.js"></script>
17+
<script src="js/three/WebGL.js"></script>
18+
<script src="js/three/stats.min.js"></script>
19+
<script src="js/example.js"></script>
20+
21+
<script id="workerScript" type="module">
22+
import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/0.161.0/three.module.js';
23+
24+
const wrapQuat = (q) => new THREE.Quaternion(q.GetX(), q.GetY(), q.GetZ(), q.GetW());
25+
const wrapVec3 = (v) => new THREE.Vector3(v.GetX(), v.GetY(), v.GetZ());
26+
const DegreesToRadians = (deg) => deg * (Math.PI / 180.0);
27+
const onWorker = globalThis.onWorker = async (Jolt, args) => {
28+
const { contactListenerPtr, linearBelts, angularBelt } = args;
29+
const contactListener = Jolt.wrapPointer(contactListenerPtr, Jolt.ContactListenerJS);
30+
31+
contactListener.OnContactAdded = (body1, body2, manifold, settings) => {
32+
body1 = Jolt.wrapPointer(body1, Jolt.Body);
33+
body2 = Jolt.wrapPointer(body2, Jolt.Body);
34+
manifold = Jolt.wrapPointer(manifold, Jolt.ContactManifold);
35+
settings = Jolt.wrapPointer(settings, Jolt.ContactSettings);
36+
37+
const body1ID = body1.GetID().GetIndexAndSequenceNumber();
38+
const body2ID = body2.GetID().GetIndexAndSequenceNumber();
39+
const rotation1 = wrapQuat(body1.GetRotation());
40+
const rotation2 = wrapQuat(body2.GetRotation());
41+
42+
const body1LinearBelt = linearBelts.find(belt => belt == body1ID)
43+
const body2LinearBelt = linearBelts.find(belt => belt == body2ID)
44+
if (body1LinearBelt || body2LinearBelt) {
45+
// Determine the world space surface velocity of both bodies
46+
const cLocalSpaceVelocity = new THREE.Vector3(0, 0, -10.0);
47+
const body1LinearSurfaceVelocity = body1LinearBelt ? cLocalSpaceVelocity.applyQuaternion(rotation1) : new THREE.Vector3(0, 0, 0);
48+
const body2LinearSurfaceVelocity = body2LinearBelt ? cLocalSpaceVelocity.applyQuaternion(rotation2) : new THREE.Vector3(0, 0, 0);
49+
50+
// Calculate the relative surface velocity
51+
const v = body2LinearSurfaceVelocity.sub(body1LinearSurfaceVelocity);
52+
settings.mRelativeLinearSurfaceVelocity.Set(v.x, v.y, v.z);
53+
}
54+
55+
const angularBodyId = angularBelt[0];
56+
const body1Angular = body1ID == angularBodyId;
57+
const body2Angular = body2ID == angularBodyId;
58+
if (body1Angular || body2Angular) {
59+
// Determine the world space angular surface velocity of both bodies
60+
const cLocalSpaceAngularVelocity = new THREE.Vector3(0, DegreesToRadians(10.0), 0);
61+
const body1AngularSurfaceVelocity = body1Angular ? cLocalSpaceAngularVelocity.applyQuaternion(rotation1) : new THREE.Vector3(0, 0, 0);
62+
const body2AngularSurfaceVelocity = body2Angular ? cLocalSpaceAngularVelocity.applyQuaternion(rotation2) : new THREE.Vector3(0, 0, 0);
63+
64+
// Note that the angular velocity is the angular velocity around body 1's center of mass, so we need to add the linear velocity of body 2's center of mass
65+
const COM1 = wrapVec3(body1.GetCenterOfMassPosition());
66+
const COM2 = wrapVec3(body2.GetCenterOfMassPosition());
67+
const body2LinearSurfaceVelocity = body2Angular ?
68+
body2AngularSurfaceVelocity.cross(COM1.clone().sub(COM2)) : new THREE.Vector3(0, 0, 0);
69+
70+
// Calculate the relative angular surface velocity
71+
const rls = body2LinearSurfaceVelocity;
72+
settings.mRelativeLinearSurfaceVelocity.Set(rls.x, rls.y, rls.z);
73+
const ras = body2AngularSurfaceVelocity.sub(body1AngularSurfaceVelocity);
74+
settings.mRelativeAngularSurfaceVelocity.Set(ras.x, ras.y, ras.z);
75+
}
76+
77+
};
78+
contactListener.OnContactPersisted = (body1, body2, manifold, settings) => {
79+
// Same behavior as contact added
80+
contactListener.OnContactAdded(body1, body2, manifold, settings);
81+
};
82+
contactListener.OnContactRemoved = (subShapePair) => {
83+
// Required for JSInterface to have this function exist
84+
};
85+
contactListener.OnContactValidate = (body1, body2, baseOffset, collideShapeResult) => {
86+
// Required for JSInterface to have this function exist
87+
return Jolt.ValidateResult_AcceptAllContactsForThisBodyPair;
88+
};
89+
}
90+
export default onWorker;
91+
</script>
92+
93+
94+
<script type="module">
95+
// In case you haven't built the library yourself, replace URL with: https://www.unpkg.com/jolt-physics/dist/jolt-physics.multithread.wasm-compat.js
96+
import initJolt from './js/jolt-physics.multithread.wasm-compat.js';
97+
98+
initJolt().then(function (Jolt) {
99+
100+
const contactListener = new Jolt.ContactListenerJS();
101+
const workerUrl = URL.createObjectURL(new Blob([document.getElementById('workerScript').innerHTML], { type: 'text/javascript' }));
102+
const workerParams = {
103+
contactListenerPtr: Jolt.getPointer(contactListener),
104+
angularBelt: new Uint32Array(new SharedArrayBuffer(4)),
105+
linearBelts: new Uint32Array(new SharedArrayBuffer(20))
106+
}
107+
Jolt.configureWorkerScripts(workerUrl, workerParams);
108+
109+
// Initialize this example
110+
initExample(Jolt, null);
111+
112+
camera.position.z += 60;
113+
camera.position.y += 20;
114+
camera.position.x += 50;
115+
116+
// Create a basic floor
117+
createFloor(100);
118+
119+
// Create conveyor belts
120+
const cBeltWidth = 10.0;
121+
const cBeltLength = 50.0;
122+
const linearBelts = [];
123+
for (let i = 0; i < 4; ++i) {
124+
const friction = 0.25 * (i + 1);
125+
const rot1 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), 0.5 * Math.PI * i);
126+
const rot2 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), DegreesToRadians(1.0));
127+
const rotation = rot1.clone().multiply(rot2);
128+
const position = new THREE.Vector3(cBeltLength, 6.0, cBeltWidth).applyQuaternion(rotation);
129+
const belt = createBox(unwrapRVec3(position), unwrapQuat(rotation), new Jolt.Vec3(cBeltWidth, 0.1, cBeltLength), Jolt.EMotionType_Static, LAYER_NON_MOVING);
130+
belt.SetFriction(friction);
131+
linearBelts.push(belt);
132+
}
133+
134+
// Bodies with decreasing friction
135+
for (let i = 0; i <= 10; ++i) {
136+
const cargo = createBox(new Jolt.RVec3(-cBeltLength + i * 10.0, 10.0, -cBeltLength),
137+
Jolt.Quat.prototype.sIdentity(), new Jolt.Vec3(2, 2, 2), Jolt.EMotionType_Dynamic, LAYER_MOVING);
138+
cargo.SetFriction(Math.max((0.0, 1.0 - 0.1 * i)));
139+
}
140+
141+
// Create 2 cylinders
142+
let cyclinderSettings = new Jolt.BodyCreationSettings(new Jolt.CylinderShape(6.0, 1.0, 0.05),
143+
new Jolt.RVec3(-25.0, 1.0, -20.0), Jolt.Quat.prototype.sRotation(new Jolt.Vec3(0, 0, 1), 0.5 * Math.PI), Jolt.EMotionType_Dynamic, LAYER_MOVING);
144+
addToScene(bodyInterface.CreateBody(cyclinderSettings), 0xff0000);
145+
cyclinderSettings.mPosition.SetZ(20);
146+
addToScene(bodyInterface.CreateBody(cyclinderSettings), 0xff0000);
147+
148+
{
149+
// Let a dynamic belt rest on it
150+
const dynamicBelt = createBox(new Jolt.RVec3(-25.0, 3.0, 0), Jolt.Quat.prototype.sIdentity(), new Jolt.Vec3(5.0, 0.1, 25.0), Jolt.EMotionType_Dynamic, LAYER_MOVING, 0x333399)
151+
linearBelts.push(dynamicBelt);
152+
153+
// Create cargo on the dynamic belt
154+
const cargo = createBox(new Jolt.RVec3(-25.0, 6.0, 15.0),
155+
Jolt.Quat.prototype.sIdentity(), new Jolt.Vec3(2, 2, 2), Jolt.EMotionType_Dynamic, LAYER_MOVING, 0x990099);
156+
cargo.SetFriction(1);
157+
}
158+
159+
// Create an angular belt
160+
const angularBelt = createBox(new Jolt.RVec3(10.0, 3.0, 0), Jolt.Quat.prototype.sIdentity(), new Jolt.Vec3(20.0, 0.1, 20.0), Jolt.EMotionType_Static, LAYER_NON_MOVING, 0x993333)
161+
162+
// Bodies with decreasing friction dropping on the angular belt
163+
for (let i = 0; i <= 6; ++i) {
164+
const cargo = createBox(new Jolt.RVec3(10.0, 10.0, -15.0 + 5.0 * i),
165+
Jolt.Quat.prototype.sIdentity(), new Jolt.Vec3(2, 2, 2), Jolt.EMotionType_Dynamic, LAYER_MOVING, 0x339999);
166+
cargo.SetFriction(Math.max((0.0, 1.0 - 0.1 * i)));
167+
}
168+
169+
// Register contact listener
170+
171+
workerParams.angularBelt[0] = angularBelt.GetID().GetIndexAndSequenceNumber();
172+
workerParams.linearBelts.set(linearBelts.map(belt => belt.GetID().GetIndexAndSequenceNumber()));
173+
onWorker(Jolt, workerParams);
174+
175+
physicsSystem.SetContactListener(contactListener);
176+
});
177+
</script>
178+
</body>
179+
</html>

Examples/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ <h1><a href="https://github.com/jrouwe/JoltPhysics.js">JoltPhysics.js</a> demos<
2929
<li><a href="motor.html">Constraint Motor Demo</a> - Shows how to use constraint motors</li>
3030
<li><a href="2d_funnel.html">2D Funnel</a> - Shows how to limit bodies in a 2D plane</li>
3131
<li><a href="conveyor_belt.html">Conveyor Belt Demo</a> - Shows how to do a conveyor belt</li>
32+
<li><a href="conveyor_belt_threaded.html">Conveyor Belt Demo (Multi Threaded)</a> - Shows how to do a conveyor belt with Jolt running in multi threaded mode</li>
3233
<li><a href="heightfield.html">Height Field Shape Demo</a> - Shows support for loading of height fields as collision surfaces</li>
3334
<li><a href="buoyancy.html">Buoyancy Demo</a> - Shows moving and static fluids and their ability to influence bodies</li>
3435
<li><a href="contact_listener.html">Contact Listener</a> - Shows how to use a contact listener</li>
3536
<li><a href="stress_test.html">Stress Test Demo</a> - Shows big pile of blocks</li>
37+
<li><a href="stress_test_threaded.html">Stress Test Demo (Multi Threaded)</a> - Shows big pile of blocks with Jolt running in multi threaded mode</li>
3638
<li><a href="add_remove_bodies.html">Add/Remove Bodies</a> - Shows how to add and remove bodies</li>
3739
<li><a href="friction.html">Friction Demo</a> - Shows the effect of friction</li>
3840
<li><a href="snapshot.html">Snapshot Demo</a> - Shows how to snapshot and restore the simulation</li>

Examples/stress_test_threaded.html

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>JoltPhysics.js demo</title>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
7+
<link rel="stylesheet" type="text/css" href="style.css">
8+
</head>
9+
<body>
10+
<div id="container">Loading...</div>
11+
<div id="info">JoltPhysics.js multi threaded stress test demo</div>
12+
13+
<script src="js/three/three.min.js"></script>
14+
<script src="js/three/OrbitControls.js"></script>
15+
<script src="js/three/WebGL.js"></script>
16+
<script src="js/three/stats.min.js"></script>
17+
<script src="js/example.js"></script>
18+
19+
<script type="module">
20+
// In case you haven't built the library yourself, replace URL with: https://www.unpkg.com/jolt-physics/dist/jolt-physics.multithread.wasm-compat.js
21+
import initJolt from './js/jolt-physics.multithread.wasm-compat.js';
22+
23+
initJolt().then(function (Jolt) {
24+
let towerHeight = 11;
25+
26+
// Initialize this example
27+
initExample(Jolt, null);
28+
29+
// Create a basic floor
30+
createFloor();
31+
32+
// Create pyramid
33+
let material = new THREE.MeshPhongMaterial({ color: 0xffffff });
34+
let geometry = new THREE.BoxGeometry(1, 1, 1);
35+
let shape = new Jolt.BoxShape(new Jolt.Vec3(0.5, 0.5, 0.5), 0.05, null);
36+
let creationSettings = new Jolt.BodyCreationSettings(shape, Jolt.RVec3.prototype.sZero(), Jolt.Quat.prototype.sIdentity(), Jolt.EMotionType_Dynamic, LAYER_MOVING);
37+
38+
for (let y = 0; y < towerHeight; y++) {
39+
40+
let baseOffset = towerHeight - 1 - y;
41+
42+
for (let x = -baseOffset; x <= baseOffset; x++) {
43+
for (let z = -baseOffset; z <= baseOffset; z++) {
44+
creationSettings.mPosition = new Jolt.RVec3(x, y + 0.5, z);
45+
let body = bodyInterface.CreateBody(creationSettings);
46+
47+
addToScene(body, 0xffffff);
48+
}
49+
}
50+
}
51+
52+
// Create block to fall on scene
53+
shape = new Jolt.BoxShape(new Jolt.Vec3(1, 1, 1), 0.05, null);
54+
let body = bodyInterface.CreateBody(new Jolt.BodyCreationSettings(shape, new Jolt.RVec3(0, 20, 0), Jolt.Quat.prototype.sIdentity(), Jolt.EMotionType_Dynamic, LAYER_MOVING));
55+
addToScene(body, 0xff0000);
56+
});
57+
58+
</script>
59+
</body>
60+
</html>

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ Additional options that can be provided to ```build.sh```:
9191

9292
* ```-DENABLE_MEMORY_PROFILER=ON``` will enable memory tracking to detect leaks.
9393
* ```-DDOUBLE_PRECISION=ON``` will enable the double precision mode. This allows worlds larger than a couple of km.
94-
* ```-DENABLE_SIMD=ON``` will enable SIMD instructions. Safari 16.4 was the last major browser to support this (in March 2023).
95-
* ```-DENABLE_MULTI_THREADING=ON``` will enable multi threading. Note that due to a bug in Safari this currently doesn't work in that brower. It is also incompatible with any JavaScript callback function that are triggered from web workers. See [this](https://github.com/jrouwe/JoltPhysics.js/discussions/110) ticket.
9694
* ```-DBUILD_WASM_COMPAT_ONLY=ON``` speeds up the build by only compiling the WASM compat version which the examples use.
9795

9896
## Running

build.sh

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/sh
2+
set -e
23

34
if [ -z $1 ]
45
then
@@ -9,24 +10,14 @@ else
910
fi
1011

1112
rm -rf ./dist
12-
if [ $? -ne 0 ]; then
13-
exit 1
14-
fi
1513

1614
mkdir dist
17-
if [ $? -ne 0 ]; then
18-
exit 1
19-
fi
2015

21-
cmake -B Build/$BUILD_TYPE -DCMAKE_BUILD_TYPE=$BUILD_TYPE "${@}"
22-
if [ $? -ne 0 ]; then
23-
exit 1
24-
fi
16+
cmake -B Build/$BUILD_TYPE/ST -DCMAKE_BUILD_TYPE=$BUILD_TYPE "${@}"
17+
cmake --build Build/$BUILD_TYPE/ST -j`nproc`
2518

26-
cmake --build Build/$BUILD_TYPE -j`nproc`
27-
if [ $? -ne 0 ]; then
28-
exit 1
29-
fi
19+
cmake -B Build/$BUILD_TYPE/MT -DENABLE_MULTI_THREADING=ON -DENABLE_SIMD=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE "${@}"
20+
cmake --build Build/$BUILD_TYPE/MT -j`nproc` --target jolt-wasm-compat jolt-wasm
3021

3122
cat > ./dist/jolt-physics.d.ts << EOF
3223
import Jolt from "./types";
@@ -35,21 +26,11 @@ export default Jolt;
3526
export * from "./types";
3627
3728
EOF
38-
if [ $? -ne 0 ]; then
39-
exit 1
40-
fi
4129

4230
cp ./dist/jolt-physics.d.ts ./dist/jolt-physics.wasm.d.ts
43-
if [ $? -ne 0 ]; then
44-
exit 1
45-
fi
46-
4731
cp ./dist/jolt-physics.d.ts ./dist/jolt-physics.wasm-compat.d.ts
48-
if [ $? -ne 0 ]; then
49-
exit 1
50-
fi
32+
cp ./dist/jolt-physics.d.ts ./dist/jolt-physics.multithread.d.ts
33+
cp ./dist/jolt-physics.d.ts ./dist/jolt-physics.multithread.wasm.d.ts
34+
cp ./dist/jolt-physics.d.ts ./dist/jolt-physics.multithread.wasm-compat.d.ts
5135

52-
cp ./dist/jolt-physics.wasm-compat*.js ./Examples/js/
53-
if [ $? -ne 0 ]; then
54-
exit 1
55-
fi
36+
cp ./dist/jolt-physics*.wasm-compat.js ./Examples/js/

0 commit comments

Comments
 (0)