UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

83 lines (57 loc) 2.72 kB
import { query_vertex_is_boundary } from "../query/query_vertex_is_boundary.js"; import { compute_face_normal_change_dot_product } from "./compute_face_normal_change_dot_product.js"; import { compute_edge_collapse_cost_quadratic } from "./quadratic/compute_edge_collapse_cost_quadratic.js"; /** * Value to be used when collapse would flip normal of one or more adjacent faces * @type {number} */ const INVALID_FLIP_COST = Number.MAX_VALUE; /** * Approximate cost of collapsing an edge, removing victim vertex from topology and merging it with the target vertex * NOTE: adapted from THREE.js mesh simplification code * @param {TopoVertex} victim * @param {TopoVertex} target * @param {TopoEdge} victim_edge * @param {Map<number, Quadratic3>} vertex_quadratics * @return {number} */ export function computeEdgeCollapseCost(victim, target, victim_edge, vertex_quadratics) { // console.warn('+computeEdgeCollapseCost'); // if we collapse edge uv by moving u to v then how // much different will the model change, i.e. the "error". const edge_length = victim_edge.lengthSqr; let curvature = 0; let normal_cost = 0; // find the "sides" triangles that are on the edge uv const side_faces = victim_edge.faces; const side_face_count = side_faces.length; // use the triangle facing most away from the sides // to determine our curvature term const victim_faces = victim.faces; const victim_face_count = victim_faces.length; let fixed_cost = 0; for (let i = 0; i < victim_face_count; i++) { const face = victim_faces[i]; // check if face normal would be flipped by the operation, this is very undesirable const face_normal_change = compute_face_normal_change_dot_product(face, victim, target); if (face_normal_change < 0) { // normal change beyond 90deg, increase the cost significantly return INVALID_FLIP_COST; } } const quadratic_cost = compute_edge_collapse_cost_quadratic(victim, target, target, vertex_quadratics); if (side_face_count < 2) { // we add some arbitrary cost for borders, curvature = 1; fixed_cost += 1; } if (query_vertex_is_boundary(victim)) { // prefer not to erase border vertices to preserve shape curvature += 1; fixed_cost += 1; } const amt = quadratic_cost + edge_length * (curvature + normal_cost) + fixed_cost; // console.warn(`edge_length:${edge_length}, curvature:${curvature}, normal_cost:${normal_cost}`); // console.warn('-computeEdgeCollapseCost'); return amt; }