UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

103 lines (82 loc) 2.92 kB
import { lerp } from "../../../math/lerp.js"; import Vector3 from "../../Vector3.js"; import { v3_dot } from "../../vec3/v3_dot.js"; import { v3_length_sqr } from "../../vec3/v3_length_sqr.js"; import { v3_slerp } from "../../vec3/v3_slerp.js"; import { EPSILON } from "../../../math/EPSILON.js"; const e = new Vector3(); const point = new Vector3(); const v0 = new Vector3(); const v1 = new Vector3(); /** * @see https://stackoverflow.com/a/57824137 * @param {number[]} destination * @param {number} destination_offset * @param {number} a_normal_x * @param {number} a_normal_y * @param {number} a_normal_z * @param {number} a_constant * @param {number} b_normal_x * @param {number} b_normal_y * @param {number} b_normal_z * @param {number} b_constant * @param {number} t */ export function plane3_slerp( destination, destination_offset, a_normal_x, a_normal_y, a_normal_z, a_constant, b_normal_x, b_normal_y, b_normal_z, b_constant, t ) { // The common line of the two planes is along the (non-unit) direction e._crossVectors( a_normal_x, a_normal_y, a_normal_z, b_normal_x, b_normal_y, b_normal_z ); const determinant = v3_length_sqr(e.x, e.y, e.z); if (determinant < EPSILON) { // no intersection, planes are parallel // determine if planes are facing the same direction or not const d = v3_dot( a_normal_x, a_normal_y, a_normal_z, b_normal_x, b_normal_y, b_normal_z ); // if planes are parallel, we assume normal of one of the planes destination[destination_offset] = a_normal_x; destination[destination_offset + 1] = a_normal_y; destination[destination_offset + 2] = a_normal_z; destination[destination_offset + 3] = lerp(a_constant, b_constant * d, t); return; } v0._crossVectors( a_normal_x, a_normal_y, a_normal_z, e.x, e.y, e.z ); v0.multiplyScalar(b_constant); v1._crossVectors( b_normal_x, b_normal_y, b_normal_z, e.x, e.y, e.z ); v1.multiplyScalar(a_constant); // The point on this line closest to the origin // point = (d_1*cross(n_2,e)-d_2*cross(n_1,e))/dot(e.e) point.subVectors(v0, v1); const inv_determinant = 1 / determinant; point.multiplyScalar(inv_determinant); // compute normal v3_slerp( v0, a_normal_x, a_normal_y, a_normal_z, b_normal_x, b_normal_y, b_normal_z, t ); // compute distance (constant) const d = v3_dot( v0.x, v0.y, v0.z, point.x, point.y, point.z ); destination[destination_offset] = v0.x; destination[destination_offset + 1] = v0.y; destination[destination_offset + 2] = v0.z; destination[destination_offset + 3] = -d; }