import { Shape } from '../shapes/Shape' import { Vec3 } from '../math/Vec3' import type { Quaternion } from '../math/Quaternion' /** * Spherical shape * @example * const radius = 1 * const sphereShape = new CANNON.Sphere(radius) * const sphereBody = new CANNON.Body({ mass: 1, shape: sphereShape }) * world.addBody(sphereBody) */ export class Sphere extends Shape { /** * The radius of the sphere. */ radius: number /** * * @param radius The radius of the sphere, a non-negative number. */ constructor(radius: number) { super({ type: Shape.types.SPHERE }) this.radius = radius !== undefined ? radius : 1.0 if (this.radius < 0) { throw new Error('The sphere radius cannot be negative.') } this.updateBoundingSphereRadius() } /** calculateLocalInertia */ calculateLocalInertia(mass: number, target = new Vec3()): Vec3 { const I = (2.0 * mass * this.radius * this.radius) / 5.0 target.x = I target.y = I target.z = I return target } /** volume */ volume(): number { return (4.0 * Math.PI * Math.pow(this.radius, 3)) / 3.0 } updateBoundingSphereRadius(): void { this.boundingSphereRadius = this.radius } calculateWorldAABB(pos: Vec3, quat: Quaternion, min: Vec3, max: Vec3): void { const r = this.radius const axes = ['x', 'y', 'z'] as ['x', 'y', 'z'] for (let i = 0; i < axes.length; i++) { const ax = axes[i] min[ax] = pos[ax] - r max[ax] = pos[ax] + r } } }