@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
82 lines (62 loc) • 2.13 kB
JavaScript
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();