UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

82 lines (62 loc) 2.13 kB
import { randomPointInSphere } from "../../random/randomPointInSphere.js"; import { v3_length } from "../../vec3/v3_length.js"; import { AbstractShape3D } from "./AbstractShape3D.js"; import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js"; /** * Sphere with diameter of 2 (radius = 1) */ export class UnitSphereShape3D extends AbstractShape3D { get volume() { return (4 / 3) * Math.PI; } get surface_area() { return Math.PI * 4; } support(result, result_offset, direction_x, direction_y, direction_z) { // since the sphere has a radius of 1, we don't have to multiply by it result[result_offset] = direction_x; result[result_offset + 1] = direction_y; result[result_offset + 2] = direction_z; } compute_bounding_box(result) { result[0] = -1; result[1] = -1; result[2] = -1; result[3] = 1; result[4] = 1; result[5] = 1; } nearest_point_on_surface(result, reference) { const r_x = reference[0]; const r_y = reference[1]; const r_z = reference[2]; // normalize vector to 1 radius const d = 1 / v3_length(r_x, r_y, r_z); result[0] = r_x * d; result[1] = r_y * d; result[2] = r_z * d; } signed_distance_gradient_at_point(result, point) { return compute_signed_distance_gradient_by_sampling(result, this, point); } signed_distance_at_point(point) { return v3_length( point[0], point[1], point[2] ) - 1; } contains_point(point) { const x = point[0]; const y = point[1]; const z = point[2]; return (x * x + y * y + z * z) < 1; } sample_random_point_in_volume(result, result_offset, random) { randomPointInSphere(random, result, result_offset); } hash() { return 13; } } UnitSphereShape3D.INSTANCE = new UnitSphereShape3D();