Skip to content
This repository was archived by the owner on Jan 18, 2019. It is now read-only.

Commit 7c8e6b4

Browse files
committed
add physics example (cannon js)
1 parent bf348bf commit 7c8e6b4

File tree

5 files changed

+185
-1
lines changed

5 files changed

+185
-1
lines changed

index.html

+5
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ <h1>Using THREE.js' Box3 and Sphere</h1>
3131
<li><a href="raw_box.html">Box vs Box and Sphere</a></li>
3232
<li><a href="raw_sphere.html">Sphere vs Box and Sphere</a></li>
3333
</ul>
34+
35+
<h1>Using a physics engine</h1>
36+
<ul>
37+
<li><a href="physics.html">Using cannon.js</a></li>
38+
</ul>
3439
</nav>
3540

3641
<footer class="main-footer">

js/common.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Utils.createShadow = function (mesh, material) {
9494
var params = mesh.geometry.parameters;
9595
var geo = mesh.geometry.type === 'BoxGeometry'
9696
? new THREE.PlaneGeometry(params.width, params.depth)
97-
: new THREE.CircleGeometry(params.radius, 24);
97+
: new THREE.CircleGeometry(mesh.geometry.boundingSphere.radius, 24);
9898

9999
var shadow = new THREE.Mesh(geo, material);
100100
shadow.rotation.x = -Math.PI / 2;

js/lib/cannon.min.js

+28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/physics.js

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
Game.init = function () {
2+
this.knot = new THREE.Mesh(
3+
new THREE.TorusKnotGeometry(0.5, 0.1), this.materials.solid);
4+
this.knot.position.set(-3, 2, 1);
5+
this.knot.geometry.computeBoundingSphere();
6+
7+
this.sphere = new THREE.Mesh(
8+
new THREE.SphereGeometry(1), this.materials.solid);
9+
this.sphere.position.set(2, 2, 0);
10+
this.sphereShadow = Utils.createShadow(this.sphere, this.materials.shadow);
11+
12+
// the object the user can control to check for collisions
13+
this.cube = new THREE.Mesh(new THREE.BoxGeometry(0.75, 0.75, 0.75),
14+
this.materials.solid);
15+
this.cube.position.set(2, 2, 1.74);
16+
this.cubeShadow = Utils.createShadow(this.cube, this.materials.shadow);
17+
18+
// add objects to the scene
19+
this.scene.add(this.cube);
20+
this.scene.add(this.knot);
21+
this.scene.add(this.sphere);
22+
23+
// add fake shadows to the scene
24+
this.scene.add(Utils.createShadow(this.knot, this.materials.shadow));
25+
this.scene.add(this.sphereShadow);
26+
this.scene.add(this.cubeShadow);
27+
28+
this.controls = new THREE.TransformControls(
29+
this.camera, this.renderer.domElement);
30+
this.controls.space = 'world';
31+
this.controls.attach(this.cube);
32+
this.scene.add(this.controls);
33+
34+
this.timestamp = 0;
35+
36+
// setup physic world
37+
this.initPhysicalWorld();
38+
};
39+
40+
Game.update = function (delta) {
41+
this.timestamp += delta;
42+
43+
// move the cube body with mouse controls
44+
this.controls.update();
45+
this.cubeBody.position.copy(this.cube.position);
46+
// update the cube shadow
47+
Utils.updateShadow(this.cubeShadow, this.cube);
48+
49+
// update knot mesh rotation
50+
this.knot.quaternion.copy(this.knotBody.quaternion);
51+
52+
// reset materials
53+
this.sphere.material = this.materials.solid;
54+
this.knot.material = this.materials.solid;
55+
56+
this.updatePhysics(delta);
57+
};
58+
59+
Game.updatePhysics = function (delta) {
60+
this.world.step(delta);
61+
62+
this.world.contacts.forEach(function (contact) {
63+
contact.bi.mesh.material = this.materials.colliding;
64+
contact.bj.mesh.material = this.materials.colliding;
65+
this.cube.material = this.materials.solid;
66+
}.bind(this));
67+
};
68+
69+
Game.initPhysicalWorld = function () {
70+
this.world = new CANNON.World();
71+
72+
// add physical bodies
73+
this.knotBody = this.addPhysicalBody(this.knot, {mass: 1});
74+
this.addPhysicalBody(this.sphere, {mass: 1});
75+
this.cubeBody = this.addPhysicalBody(this.cube, {mass: 1});
76+
77+
// register for collide events
78+
this.cubeBody.addEventListener('collide', function (e) {
79+
console.log('Collision!');
80+
}.bind(this));
81+
82+
// rotate the knot
83+
this.knotBody.angularVelocity.x = Math.PI / 4;
84+
};
85+
86+
Game.addPhysicalBody = function (mesh, bodyOptions) {
87+
var shape;
88+
// create a Sphere shape for spheres and thorus knots,
89+
// a Box shape otherwise
90+
if (mesh.geometry.type === 'SphereGeometry' ||
91+
mesh.geometry.type === 'ThorusKnotGeometry') {
92+
mesh.geometry.computeBoundingSphere();
93+
shape = new CANNON.Sphere(mesh.geometry.boundingSphere.radius);
94+
}
95+
else {
96+
mesh.geometry.computeBoundingBox();
97+
var box = mesh.geometry.boundingBox;
98+
shape = new CANNON.Box(new CANNON.Vec3(
99+
(box.max.x - box.min.x) / 2,
100+
(box.max.y - box.min.y) / 2,
101+
(box.max.z - box.min.z) / 2
102+
));
103+
}
104+
105+
var body = new CANNON.Body(bodyOptions);
106+
body.addShape(shape);
107+
body.position.copy(mesh.position);
108+
body.computeAABB();
109+
// disable collision response so objects don't move when they collide
110+
// against each other
111+
body.collisionResponse = false;
112+
// keep a reference to the mesh so we can update its properties later
113+
body.mesh = mesh;
114+
115+
this.world.addBody(body);
116+
return body;
117+
};

physics.html

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>3D AABB collisions</title>
5+
<meta charset="utf-8">
6+
<link rel="stylesheet" href="styles.css" type="text/css">
7+
<script src="js/lib/three.min.js"></script>
8+
<script src="js/lib/transform-controls.js"></script>
9+
<script src="js/lib/cannon.min.js"></script>
10+
<script src="js/common.js"></script>
11+
<script src="js/physics.js"></script>
12+
</head>
13+
<body>
14+
15+
<header class="main-header">
16+
<h1><a href="index.html">3D AABB collisions</a></h1>
17+
<p>Using cannon.js (physics engine)</p>
18+
</header>
19+
20+
<div class="main-wrapper">
21+
<div class="canvas-wrapper">
22+
<canvas id="demo" width="512" height="512"></canvas>
23+
<aside class="message">
24+
<strong>Drag</strong> the ball around
25+
</aside>
26+
</div><!-- canvas wrapper -->
27+
28+
<footer class="main-footer">
29+
<p>Source code on <a href="https://github.com/mozdevs/gamedev-js-3d-aabb">the Github repository</a>.</p>
30+
</footer>
31+
</div><!-- main wrapper -->
32+
33+
</body>
34+
</html>

0 commit comments

Comments
 (0)