UNPKG

threefiz

Version:

Implementation of a physics engine based on the [Three.js](https://github.com/mrdoob/three.js) library.

82 lines (74 loc) 2.53 kB
import { Sphere as SphereT, SphereGeometry, Vector3, Mesh } from "three"; import RigidBody, { RigidBodyProps } from "./RigidBody"; import Cuboid from "./Cuboid"; class Sphere extends RigidBody { readonly ShapeType = 0; readonly meshGeometry: SphereGeometry; collider: SphereT; helper: Mesh | null; constructor(params: Partial<RigidBodyProps>) { super(params); this.meshGeometry = this.mesh.geometry as SphereGeometry; const { radius } = this.meshGeometry.parameters; this.collider = new SphereT(this.position.clone(), radius); this.helper = null; this.invertedInertia .set( 0.4 * this.mass * radius ** 2, 0, 0, 0, 0.4 * this.mass * radius ** 2, 0, 0, 0, 0.4 * this.mass * radius ** 2 ) .invert(); } intersects(object: RigidBody) { if (object instanceof Sphere) return this.intersectsSphere(object); if (object instanceof Cuboid) return object.sphereBoxIntersect(this); return false; } getCollision(object: Cuboid | Sphere): { point: Vector3; normal: Vector3; depth: number; } { if (object instanceof Cuboid) { const collision = object.getCollision(this); collision.normal.negate(); return collision; } const point = new Vector3(); this.collider.clampPoint(object.collider.center, point); const normal = this.collider.center.clone().sub(point).normalize(); const distance = this.position.distanceTo(object.position); const depth = Math.abs( distance - object.collider.radius - this.collider.radius ); return { point, normal, depth }; } intersectsSphere(object: Sphere) { const distance = this.collider.center.distanceTo(object.collider.center); return distance < object.collider.radius + this.collider.radius; } updateAABB() { this.aabb.min.set( this.position.x - this.meshGeometry.parameters.radius, this.position.y - this.meshGeometry.parameters.radius, this.position.z - this.meshGeometry.parameters.radius ); this.aabb.max.set( this.position.x + this.meshGeometry.parameters.radius, this.position.y + this.meshGeometry.parameters.radius, this.position.z + this.meshGeometry.parameters.radius ); } updateCollider() { this.collider.applyMatrix4(this.mesh.matrixWorld); this.collider.center.copy(this.position); } } export default Sphere;