engine
ver.2
by Rebecca Chen
HTML
<div id="info">Physics Engine<br>version 2
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
CSS
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 10px;
text-align: center;
color: #ffff00
}
body {
overflow: hidden;
}
JavaScript
class Ball {
constructor (mass = 1, radius=2, friction = 0) {
this.type = 'ball';
this.mass = mass; // may need to differentiate basketball & bowling ball
this.radius = radius;
this.friction = friction; // for contact
// for dynamics calculation
this.pos = new THREE.Vector3();
this.vel = new THREE.Vector3();
this.force = new THREE.Vector3();
this.obj = new THREE.Object3D();
let mesh = new THREE.Mesh (new THREE.CircleGeometry(radius), new THREE.MeshBasicMaterial({wireframe:true}))
this.obj.add (mesh)
scene.add (this.obj)
}
update(dt) {
// after GLOBAL collision & contact
this.vel.add (this.force.clone().multiplyScalar(dt))
this.pos.add (this.vel.clone().multiplyScalar(dt))
this.obj.position.copy (this.pos);
}
// useless API
moveTo(x,y) {
this.pos.set (x,y,0)
}
}
class Plane {
constructor (width=150) {
this.type = 'plane'
this.normal = new THREE.Vector3(0,1,0)
this.pc = new THREE.Vector3()
this.obj = new THREE.Object3D();
this.width = width; // for display purpose, should be infinite
let mesh = new THREE.Mesh (new THREE.PlaneGeometry(width,2), new THREE.MeshBasicMaterial({color:0xff00ff, wireframe:true}))
mesh.position.y = -1
let tip = new THREE.Mesh (new THREE.CylinderGeometry (0,2,4), new THREE.MeshBasicMaterial({color:0xffff00}))
tip.position.y = 2
this.obj.add (tip)
this.obj.add (mesh);
scene.add (this.obj);
}
moveTo (x,y) {
this.pc.set (x, y, 0)
this.obj.position.copy (this.pc);
}
rotateTo (theta) { // abs CCW angle
this.obj.rotation.z = theta;
this.normal.applyEuler (new THREE.Euler (0,0,theta))
}
}
/*
function contact () {
// check all existing contacts ...
// (or remove them all)
// (and reestablish them anew every time)
for (let i = 0; i < balls.length; i++) {
for (let j = 0; j < planes.length; j++) {
// if bi is close to pj
let bi = balls[i]
let pj = planes[j]
...