@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.
237 lines • 9.78 kB
JavaScript
import { Vector3 } from "../Maths/math.vector.js";
import { VertexBuffer } from "../Buffers/buffer.js";
import { Mesh } from "../Meshes/mesh.js";
import { Color4 } from "../Maths/math.color.js";
import { Logger } from "../Misc/logger.js";
Mesh._GoldbergMeshParser = (parsedMesh, scene) => {
    return GoldbergMesh.Parse(parsedMesh, scene);
};
/**
 * Mesh for a Goldberg Polyhedron which is made from 12 pentagonal and the rest hexagonal faces
 * @see https://en.wikipedia.org/wiki/Goldberg_polyhedron
 */
export class GoldbergMesh extends Mesh {
    constructor() {
        super(...arguments);
        /**
         * Defines the specific Goldberg data used in this mesh construction.
         */
        this.goldbergData = {
            faceColors: [],
            faceCenters: [],
            faceZaxis: [],
            faceXaxis: [],
            faceYaxis: [],
            nbSharedFaces: 0,
            nbUnsharedFaces: 0,
            nbFaces: 0,
            nbFacesAtPole: 0,
            adjacentFaces: [],
        };
    }
    /**
     * Gets the related Goldberg face from pole infos
     * @param poleOrShared Defines the pole index or the shared face index if the fromPole parameter is passed in
     * @param fromPole Defines an optional pole index to find the related info from
     * @returns the goldberg face number
     */
    relatedGoldbergFace(poleOrShared, fromPole) {
        if (fromPole === void 0) {
            if (poleOrShared > this.goldbergData.nbUnsharedFaces - 1) {
                Logger.Warn("Maximum number of unshared faces used");
                poleOrShared = this.goldbergData.nbUnsharedFaces - 1;
            }
            return this.goldbergData.nbUnsharedFaces + poleOrShared;
        }
        if (poleOrShared > 11) {
            Logger.Warn("Last pole used");
            poleOrShared = 11;
        }
        if (fromPole > this.goldbergData.nbFacesAtPole - 1) {
            Logger.Warn("Maximum number of faces at a pole used");
            fromPole = this.goldbergData.nbFacesAtPole - 1;
        }
        return 12 + poleOrShared * this.goldbergData.nbFacesAtPole + fromPole;
    }
    _changeGoldbergFaceColors(colorRange) {
        for (let i = 0; i < colorRange.length; i++) {
            const min = colorRange[i][0];
            const max = colorRange[i][1];
            const col = colorRange[i][2];
            for (let f = min; f < max + 1; f++) {
                this.goldbergData.faceColors[f] = col;
            }
        }
        const newCols = [];
        for (let f = 0; f < 12; f++) {
            for (let i = 0; i < 5; i++) {
                newCols.push(this.goldbergData.faceColors[f].r, this.goldbergData.faceColors[f].g, this.goldbergData.faceColors[f].b, this.goldbergData.faceColors[f].a);
            }
        }
        for (let f = 12; f < this.goldbergData.faceColors.length; f++) {
            for (let i = 0; i < 6; i++) {
                newCols.push(this.goldbergData.faceColors[f].r, this.goldbergData.faceColors[f].g, this.goldbergData.faceColors[f].b, this.goldbergData.faceColors[f].a);
            }
        }
        return newCols;
    }
    /**
     * Set new goldberg face colors
     * @param colorRange the new color to apply to the mesh
     */
    setGoldbergFaceColors(colorRange) {
        const newCols = this._changeGoldbergFaceColors(colorRange);
        this.setVerticesData(VertexBuffer.ColorKind, newCols);
    }
    /**
     * Updates new goldberg face colors
     * @param colorRange the new color to apply to the mesh
     */
    updateGoldbergFaceColors(colorRange) {
        const newCols = this._changeGoldbergFaceColors(colorRange);
        this.updateVerticesData(VertexBuffer.ColorKind, newCols);
    }
    _changeGoldbergFaceUVs(uvRange) {
        const uvs = this.getVerticesData(VertexBuffer.UVKind);
        for (let i = 0; i < uvRange.length; i++) {
            const min = uvRange[i][0];
            const max = uvRange[i][1];
            const center = uvRange[i][2];
            const radius = uvRange[i][3];
            const angle = uvRange[i][4];
            const points5 = [];
            const points6 = [];
            let u;
            let v;
            for (let p = 0; p < 5; p++) {
                u = center.x + radius * Math.cos(angle + (p * Math.PI) / 2.5);
                v = center.y + radius * Math.sin(angle + (p * Math.PI) / 2.5);
                if (u < 0) {
                    u = 0;
                }
                if (u > 1) {
                    u = 1;
                }
                points5.push(u, v);
            }
            for (let p = 0; p < 6; p++) {
                u = center.x + radius * Math.cos(angle + (p * Math.PI) / 3);
                v = center.y + radius * Math.sin(angle + (p * Math.PI) / 3);
                if (u < 0) {
                    u = 0;
                }
                if (u > 1) {
                    u = 1;
                }
                points6.push(u, v);
            }
            for (let f = min; f < Math.min(12, max + 1); f++) {
                for (let p = 0; p < 5; p++) {
                    uvs[10 * f + 2 * p] = points5[2 * p];
                    uvs[10 * f + 2 * p + 1] = points5[2 * p + 1];
                }
            }
            for (let f = Math.max(12, min); f < max + 1; f++) {
                for (let p = 0; p < 6; p++) {
                    //120 + 12 * (f - 12) = 12 * f - 24
                    uvs[12 * f - 24 + 2 * p] = points6[2 * p];
                    uvs[12 * f - 23 + 2 * p] = points6[2 * p + 1];
                }
            }
        }
        return uvs;
    }
    /**
     * set new goldberg face UVs
     * @param uvRange the new UVs to apply to the mesh
     */
    setGoldbergFaceUVs(uvRange) {
        const newUVs = this._changeGoldbergFaceUVs(uvRange);
        this.setVerticesData(VertexBuffer.UVKind, newUVs);
    }
    /**
     * Updates new goldberg face UVs
     * @param uvRange the new UVs to apply to the mesh
     */
    updateGoldbergFaceUVs(uvRange) {
        const newUVs = this._changeGoldbergFaceUVs(uvRange);
        this.updateVerticesData(VertexBuffer.UVKind, newUVs);
    }
    /**
     * Places a mesh on a particular face of the goldberg polygon
     * @param mesh Defines the mesh to position
     * @param face Defines the face to position onto
     * @param position Defines the position relative to the face we are positioning the mesh onto
     */
    placeOnGoldbergFaceAt(mesh, face, position) {
        const orientation = Vector3.RotationFromAxis(this.goldbergData.faceXaxis[face], this.goldbergData.faceYaxis[face], this.goldbergData.faceZaxis[face]);
        mesh.rotation = orientation;
        mesh.position = this.goldbergData.faceCenters[face]
            .add(this.goldbergData.faceXaxis[face].scale(position.x))
            .add(this.goldbergData.faceYaxis[face].scale(position.y))
            .add(this.goldbergData.faceZaxis[face].scale(position.z));
    }
    /**
     * Serialize current mesh
     * @param serializationObject defines the object which will receive the serialization data
     */
    serialize(serializationObject) {
        super.serialize(serializationObject);
        serializationObject.type = "GoldbergMesh";
        const goldbergData = {};
        goldbergData.adjacentFaces = this.goldbergData.adjacentFaces;
        goldbergData.nbSharedFaces = this.goldbergData.nbSharedFaces;
        goldbergData.nbUnsharedFaces = this.goldbergData.nbUnsharedFaces;
        goldbergData.nbFaces = this.goldbergData.nbFaces;
        goldbergData.nbFacesAtPole = this.goldbergData.nbFacesAtPole;
        if (this.goldbergData.faceColors) {
            goldbergData.faceColors = [];
            for (const color of this.goldbergData.faceColors) {
                goldbergData.faceColors.push(color.asArray());
            }
        }
        if (this.goldbergData.faceCenters) {
            goldbergData.faceCenters = [];
            for (const vector of this.goldbergData.faceCenters) {
                goldbergData.faceCenters.push(vector.asArray());
            }
        }
        if (this.goldbergData.faceZaxis) {
            goldbergData.faceZaxis = [];
            for (const vector of this.goldbergData.faceZaxis) {
                goldbergData.faceZaxis.push(vector.asArray());
            }
        }
        if (this.goldbergData.faceYaxis) {
            goldbergData.faceYaxis = [];
            for (const vector of this.goldbergData.faceYaxis) {
                goldbergData.faceYaxis.push(vector.asArray());
            }
        }
        if (this.goldbergData.faceXaxis) {
            goldbergData.faceXaxis = [];
            for (const vector of this.goldbergData.faceXaxis) {
                goldbergData.faceXaxis.push(vector.asArray());
            }
        }
        serializationObject.goldbergData = goldbergData;
    }
    /**
     * Parses a serialized goldberg mesh
     * @param parsedMesh the serialized mesh
     * @param scene the scene to create the goldberg mesh in
     * @returns the created goldberg mesh
     */
    static Parse(parsedMesh, scene) {
        const goldbergData = parsedMesh.goldbergData;
        goldbergData.faceColors = goldbergData.faceColors.map((el) => Color4.FromArray(el));
        goldbergData.faceCenters = goldbergData.faceCenters.map((el) => Vector3.FromArray(el));
        goldbergData.faceZaxis = goldbergData.faceZaxis.map((el) => Vector3.FromArray(el));
        goldbergData.faceXaxis = goldbergData.faceXaxis.map((el) => Vector3.FromArray(el));
        goldbergData.faceYaxis = goldbergData.faceYaxis.map((el) => Vector3.FromArray(el));
        const goldberg = new GoldbergMesh(parsedMesh.name, scene);
        goldberg.goldbergData = goldbergData;
        return goldberg;
    }
}
//# sourceMappingURL=goldbergMesh.js.map