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