@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
148 lines • 13 kB
JavaScript
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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