UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

148 lines 13 kB
import { TgdColor } from "./../../../color/index.js"; import { TgdDataset } from "./../../../dataset/index.js"; import { TgdGeometry } from "./../../../geometry/index.js"; import { TgdMaterial } from "./../../../material/index.js"; import { TgdMaterialGltf } from "./../../../material/gltf.js"; import { tgdCalcRandom } from "./../../../math/index.js"; import { TgdTexture2D, TgdTextureCube } from "./../../../texture/index.js"; import { tgdCanvasCreateFill } from "./../../../utils/index.js"; import { TgdPainterMesh } from "../mesh/index.js"; /** */ export class TgdPainterMeshGltf extends TgdPainterMesh { constructor(context, options) { const { asset, meshIndexOrName = 0, primitiveIndex = 0, skybox, material: materialFactory = makeMaterial, } = options; const materialDescription = figureMaterialDescription({ asset, meshIndexOrName, primitiveIndex, context, skybox, }); const material = materialFactory instanceof TgdMaterial ? materialFactory : materialFactory(materialDescription); let computeNormals = false; const attributes = { POSITION: "vec3", NORMAL: "vec3", }; const primitive = asset.getMeshPrimitive(); if (primitive.attributes.TEXCOORD_0) { attributes.TEXCOORD_0 = "vec2"; } const dataset = new TgdDataset(attributes); asset.setAttrib(dataset, "POSITION", meshIndexOrName, primitiveIndex); if (primitive.attributes.NORMAL) { asset.setAttrib(dataset, "NORMAL", meshIndexOrName, primitiveIndex); } else { // It seems to be impossible to retrieve normals. // We will compute them with a smooth shading. context.console.warn("No normals found! We will apply smooth shading."); computeNormals = true; } if (primitive.attributes.TEXCOORD_0) { asset.setAttrib(dataset, "TEXCOORD_0", meshIndexOrName, primitiveIndex); } super(context, { geometry: new TgdGeometry({ dataset, elements: asset.getMeshPrimitiveIndices(meshIndexOrName, primitiveIndex), drawMode: "TRIANGLES", computeNormalsIfMissing: computeNormals, }), material, }); this.name = options.name ?? `Gltf/${this.name}`; } } const DEFAULT_COLOR = [0.9, 0.5, 0.1, 1]; function figureMaterialDescription({ asset, meshIndexOrName, primitiveIndex, context, skybox, }) { const description = { asset, context, name: "Material", skybox, }; const primitive = asset.getMeshPrimitive(meshIndexOrName, primitiveIndex); const materialIndex = primitive.material ?? -1; if (materialIndex === -1) { return { ...description, color: DEFAULT_COLOR, }; } const material = asset.getMaterial(materialIndex); description.name = material.name ?? description.name; description.color = material.pbrMetallicRoughness?.baseColorFactor; const abedoIndex = material.pbrMetallicRoughness?.baseColorTexture?.index; if (typeof abedoIndex === "number") { description.abedo = { imageIndex: abedoIndex, }; } const roughnessIndex = material.pbrMetallicRoughness?.metallicRoughnessTexture?.index; if (typeof roughnessIndex === "number") { description.metallicRoughness = { imageIndex: roughnessIndex, }; } const normalIndex = material.normalTexture?.index; if (typeof normalIndex === "number") { description.normal = { imageIndex: normalIndex, }; } const occlusionIndex = material.occlusionTexture?.index; if (typeof occlusionIndex === "number") { description.occlusion = { imageIndex: occlusionIndex, }; } const emissionIndex = material.emissiveTexture?.index; if (typeof emissionIndex === "number") { description.emission = { imageIndex: emissionIndex, strength: material.emissiveFactor ?? [1, 1, 1], }; } return description; } function makeMaterial({ asset, context, normal, abedo, emission, occlusion, metallicRoughness, color, skybox, }) { const makeTexture = (index, name) => { if (typeof index === "number") { const texture = asset.createTexture2D(context, index); texture.name = name; return texture; } }; const fill = ([R, G, B, A]) => { const texture = new TgdTexture2D(context); texture.loadBitmap(tgdCanvasCreateFill(1, 1, new TgdColor(R, G, B, A).toString())); return texture; }; return new TgdMaterialGltf({ textures: { normal: makeTexture(normal?.imageIndex, "Normal") ?? fill([0.5, 0.5, 1, 1]), albedo: makeTexture(abedo?.imageIndex, "Abedo") ?? fill(color ?? DEFAULT_COLOR), emission: makeTexture(emission?.imageIndex, "Emission") ?? fill([0, 0, 0, 1]), occlusion: makeTexture(occlusion?.imageIndex, "Occlusion"), metallicRoughness: makeTexture(metallicRoughness?.imageIndex, "Roughness") ?? fill([0, 0.5, 0.5, 1]), skybox: skybox ?? makeDefaultSkybox(context), }, }); } function makeDefaultSkybox(context) { const skybox = new TgdTextureCube(context, { imageNegX: randomCanvas(), imageNegY: randomCanvas(), imageNegZ: randomCanvas(), imagePosX: randomCanvas(), imagePosY: randomCanvas(), imagePosZ: randomCanvas(), }); return skybox; } function randomCanvas() { return tgdCanvasCreateFill(1, 1, new TgdColor(tgdCalcRandom(0, 0.2), tgdCalcRandom(0.5, 0.7), tgdCalcRandom(0.7, 1), 1)); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2x0Zi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wYWludGVyL21lc2gvZ2x0Zi9nbHRmLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFckMsT0FBTyxFQUFFLFVBQVUsRUFBNkIsTUFBTSxjQUFjLENBQUE7QUFDcEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXpDLE9BQU8sRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBRTNELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBbUN4QztHQUNHO0FBQ0gsTUFBTSxPQUFPLGtCQUFtQixTQUFRLGNBQWM7SUFDbEQsWUFBWSxPQUFtQixFQUFFLE9BQWtDO1FBQy9ELE1BQU0sRUFDRixLQUFLLEVBQ0wsZUFBZSxHQUFHLENBQUMsRUFDbkIsY0FBYyxHQUFHLENBQUMsRUFDbEIsTUFBTSxFQUNOLFFBQVEsRUFBRSxlQUFlLEdBQUcsWUFBWSxHQUMzQyxHQUFHLE9BQU8sQ0FBQTtRQUNYLE1BQU0sbUJBQW1CLEdBQUcseUJBQXlCLENBQUM7WUFDbEQsS0FBSztZQUNMLGVBQWU7WUFDZixjQUFjO1lBQ2QsT0FBTztZQUNQLE1BQU07U0FDVCxDQUFDLENBQUE7UUFDRixNQUFNLFFBQVEsR0FBRyxlQUFlLFlBQVksV0FBVyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFB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