@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
JavaScript
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