UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

99 lines (81 loc) 2.94 kB
import { max2 } from "../../../math/max2.js"; import { max3 } from "../../../math/max3.js"; import { min2 } from "../../../math/min2.js"; import { sign_not_zero } from "../../../math/sign_not_zero.js"; import { randomPointInBox } from "../../random/randomPointInBox.js"; import { v3_length } from "../../vec3/v3_length.js"; import { aabb3_nearest_point_on_surface } from "../aabb/aabb3_nearest_point_on_surface.js"; import { AbstractShape3D } from "./AbstractShape3D.js"; import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js"; export class UnitCubeShape3D extends AbstractShape3D { get volume() { return 1; } get surface_area() { return 6; } compute_bounding_box(result) { result[0] = -0.5; result[1] = -0.5; result[2] = -0.5; result[3] = 0.5; result[4] = 0.5; result[5] = 0.5; } nearest_point_on_surface(result, reference) { const r_x = reference[0]; const r_y = reference[1]; const r_z = reference[2]; aabb3_nearest_point_on_surface( result, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, r_x, r_y, r_z ); } support(result, result_offset, direction_x, direction_y, direction_z) { result[result_offset] = sign_not_zero(direction_x) * 0.5; result[result_offset + 1] = sign_not_zero(direction_y) * 0.5; result[result_offset + 2] = sign_not_zero(direction_z) * 0.5; } signed_distance_gradient_at_point(result, point) { return compute_signed_distance_gradient_by_sampling(result, this, point); } signed_distance_at_point(point) { /* based on https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm original shader code: ------------ float sdBox( vec3 p, vec3 b ) { vec3 q = abs(p) - b; return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); } ------------ */ const q_x = Math.abs(point[0]) - 0.5; const q_y = Math.abs(point[1]) - 0.5; const q_z = Math.abs(point[2]) - 0.5; return v3_length( max2(q_x, 0), max2(q_y, 0), max2(q_z, 0) ) + min2(max3(q_x, q_y, q_z), 0); } contains_point(point) { const x = point[0]; const y = point[1]; const z = point[2]; return x > -0.5 && x < 0.5 && y > -0.5 && y < 0.5 && z > -0.5 && z < 0.5 ; } sample_random_point_in_volume(result, result_offset, random) { randomPointInBox(random, result, result_offset); } hash() { return 1; } static INSTANCE = new UnitCubeShape3D(); }