@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
64 lines (49 loc) • 2.46 kB
JavaScript
import { array_copy } from "../../../../../core/collection/array/array_copy.js";
import { compute_polygon_area_2d } from "../../../../../core/geom/2d/compute_polygon_area_2d.js";
import { convex_hull_jarvis_2d } from "../../../../../core/geom/2d/convex-hull/convex_hull_jarvis_2d.js";
import { fixed_convex_hull_relaxation } from "../../../../../core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js";
import {
make_edge_condition_channel_threshold
} from "../../../texture/sampler/search/make_edge_condition_channel_threshold.js";
import { sampler2d_find_pixels } from "../../../texture/sampler/search/sampler2d_find_pixels.js";
/**
*
* @param {Sampler2D} accumulator
* @param {number} vertex_limit
* @param {number} frame_size
* @returns {Float32Array}
*/
export function sampler2d_build_cutout(accumulator, vertex_limit, frame_size) {
const edge_pixels = sampler2d_find_pixels(accumulator, make_edge_condition_channel_threshold(0, 5));
// filtered pixels
const filtered_edge_pixels = [];
const half_pixel = 0.5;
for (let i = 0; i < edge_pixels.length; i += 2) {
const x = edge_pixels[i];
const y = edge_pixels[i + 1];
filtered_edge_pixels.push(x - half_pixel, y - half_pixel);
filtered_edge_pixels.push(x + half_pixel, y - half_pixel);
filtered_edge_pixels.push(x + half_pixel, y + half_pixel);
filtered_edge_pixels.push(x - half_pixel, y + half_pixel);
}
const hull_point_indices = convex_hull_jarvis_2d(filtered_edge_pixels, filtered_edge_pixels.length / 2);
const hull_points = [];
for (let i = 0; i < hull_point_indices.length; i++) {
const hpi = hull_point_indices[i];
array_copy(filtered_edge_pixels, hpi * 2, hull_points, i * 2, 2);
}
const cutout_points = new Float32Array(vertex_limit * 2);
fixed_convex_hull_relaxation(cutout_points, 0, vertex_limit, hull_points, hull_point_indices.length);
const area = compute_polygon_area_2d(cutout_points, vertex_limit);
console.log(`Cutout area: ${area}`);
if (area >= 0.99 && vertex_limit >= 4) {
// default back to aligned quad, produced result is a degradation
return new Float32Array([
0, 0,
accumulator.width, 0,
accumulator.width, accumulator.height,
0, accumulator.height
]);
}
return cutout_points;
}