UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

133 lines 6.03 kB
import { __decorate } from "../tslib.es6.js"; import { Vector3 } from "./math.vector.js"; import { nativeOverride } from "../Misc/decorators.js"; // This helper class is only here so we can apply the nativeOverride decorator to functions. class MathHelpers { static extractMinAndMaxIndexed(positions, indices, indexStart, indexCount, minimum, maximum) { for (let index = indexStart; index < indexStart + indexCount; index++) { const offset = indices[index] * 3; const x = positions[offset]; const y = positions[offset + 1]; const z = positions[offset + 2]; minimum.minimizeInPlaceFromFloats(x, y, z); maximum.maximizeInPlaceFromFloats(x, y, z); } } static extractMinAndMax(positions, start, count, stride, minimum, maximum) { for (let index = start, offset = start * stride; index < start + count; index++, offset += stride) { const x = positions[offset]; const y = positions[offset + 1]; const z = positions[offset + 2]; minimum.minimizeInPlaceFromFloats(x, y, z); maximum.maximizeInPlaceFromFloats(x, y, z); } } } __decorate([ nativeOverride.filter((...[positions, indices]) => !Array.isArray(positions) && !Array.isArray(indices)) // eslint-disable-next-line @typescript-eslint/naming-convention ], MathHelpers, "extractMinAndMaxIndexed", null); __decorate([ nativeOverride.filter((...[positions]) => !Array.isArray(positions)) // eslint-disable-next-line @typescript-eslint/naming-convention ], MathHelpers, "extractMinAndMax", null); /** * Extracts minimum and maximum values from a list of indexed positions * @param positions defines the positions to use * @param indices defines the indices to the positions * @param indexStart defines the start index * @param indexCount defines the end index * @param bias defines bias value to add to the result * @returns minimum and maximum values */ // eslint-disable-next-line @typescript-eslint/naming-convention export function extractMinAndMaxIndexed(positions, indices, indexStart, indexCount, bias = null) { const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); MathHelpers.extractMinAndMaxIndexed(positions, indices, indexStart, indexCount, minimum, maximum); if (bias) { minimum.x -= minimum.x * bias.x + bias.y; minimum.y -= minimum.y * bias.x + bias.y; minimum.z -= minimum.z * bias.x + bias.y; maximum.x += maximum.x * bias.x + bias.y; maximum.y += maximum.y * bias.x + bias.y; maximum.z += maximum.z * bias.x + bias.y; } return { minimum: minimum, maximum: maximum, }; } /** * Extracts minimum and maximum values from a list of positions * @param positions defines the positions to use * @param start defines the start index in the positions array * @param count defines the number of positions to handle * @param bias defines bias value to add to the result * @param stride defines the stride size to use (distance between two positions in the positions array) * @returns minimum and maximum values */ // eslint-disable-next-line @typescript-eslint/naming-convention export function extractMinAndMax(positions, start, count, bias = null, stride) { const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); if (!stride) { stride = 3; } MathHelpers.extractMinAndMax(positions, start, count, stride, minimum, maximum); if (bias) { minimum.x -= minimum.x * bias.x + bias.y; minimum.y -= minimum.y * bias.x + bias.y; minimum.z -= minimum.z * bias.x + bias.y; maximum.x += maximum.x * bias.x + bias.y; maximum.y += maximum.y * bias.x + bias.y; maximum.z += maximum.z * bias.x + bias.y; } return { minimum: minimum, maximum: maximum, }; } /** * Flip flipped faces * @param positions defines the positions to use * @param indices defines the indices to use and update */ export function FixFlippedFaces(positions, indices) { const boundingInfo = extractMinAndMax(positions, 0, positions.length / 3); const inside = boundingInfo.maximum.subtract(boundingInfo.minimum).scale(0.5).add(boundingInfo.minimum); const tmpVectorA = new Vector3(); const tmpVectorB = new Vector3(); const tmpVectorC = new Vector3(); const tmpVectorAB = new Vector3(); const tmpVectorAC = new Vector3(); const tmpVectorNormal = new Vector3(); const tmpVectorAvgNormal = new Vector3(); // Clean indices for (let index = 0; index < indices.length; index += 3) { const a = indices[index]; const b = indices[index + 1]; const c = indices[index + 2]; // Evaluate face normal tmpVectorA.fromArray(positions, a * 3); tmpVectorB.fromArray(positions, b * 3); tmpVectorC.fromArray(positions, c * 3); tmpVectorB.subtractToRef(tmpVectorA, tmpVectorAB); tmpVectorC.subtractToRef(tmpVectorA, tmpVectorAC); Vector3.CrossToRef(tmpVectorAB, tmpVectorAC, tmpVectorNormal); tmpVectorNormal.normalize(); // Calculate normal from face center to the inside of the geometry const avgX = tmpVectorA.x + tmpVectorB.x + tmpVectorC.x; const avgY = tmpVectorA.y + tmpVectorB.y + tmpVectorC.y; const avgZ = tmpVectorA.z + tmpVectorB.z + tmpVectorC.z; tmpVectorAvgNormal.set(avgX / 3, avgY / 3, avgZ / 3); tmpVectorAvgNormal.subtractInPlace(inside); tmpVectorAvgNormal.normalize(); if (Vector3.Dot(tmpVectorNormal, tmpVectorAvgNormal) >= 0) { // Flip! indices[index] = c; indices[index + 2] = a; } } } //# sourceMappingURL=math.functions.js.map