feat: faster models

This commit is contained in:
TrèsAbhi committed 2024-10-29 16:21:44 -05:00
1 parent 0f29145ab0
commit e05f02099d
8 files changed
+77 -34

No files matched your search

BIN
View File
Binary file not shown.
+1 -1
View File
@@ -9,7 +9,7 @@
"packages/*"
],
"scripts": {
"build:assets": "bun --filter=@blitzkit/scripts run build:assets",
"build:assets": "cd packages/scripts && bun run build:assets",
"build:averages": "bun --filter=@blitzkit/scripts run build:averages",
"build:bot": "rm -rf dist/bot && mkdir -p dist/bot/prisma && bun build src/index.ts src/workers/bot.ts src/workers/render.ts --outdir dist/bot --target=bun --splitting --sourcemap=inline --external sharp && cp -R src/lang dist/bot/lang && prisma generate && cp prisma/schema.prisma dist/bot/prisma/schema.prisma && cp -R node_modules/prisma/*.node dist/bot/prisma && cd dist/bot && bun init -y && bun add sharp",
"build:website": "bun build:prisma && bun --filter=@blitzkit/website run build",
+12 -8
View File
@@ -9,17 +9,21 @@
"setup:patches": "bun src/applyPatches.ts"
},
"dependencies": {
"progress": "^2.0.3",
"@gltf-transform/core": "^3.10.1",
"decompress": "^4.2.1",
"csv-parse": "^5.5.6",
"googleapis": "^134.0.0",
"@blitzkit/core": "workspace:*",
"fast-xml-parser": "^4.4.1"
"@gltf-transform/core": "^4.0.10",
"@gltf-transform/extensions": "^4.0.10",
"@gltf-transform/functions": "^4.0.10",
"csv-parse": "^5.5.6",
"decompress": "^4.2.1",
"draco3dgltf": "^1.5.7",
"fast-xml-parser": "^4.4.1",
"googleapis": "^134.0.0",
"progress": "^2.0.3"
},
"devDependencies": {
"@types/decompress": "^4.2.7",
"@types/progress": "^2.0.7",
"@types/lodash": "^4.17.7"
"@types/draco3dgltf": "^1.4.3",
"@types/lodash": "^4.17.7",
"@types/progress": "^2.0.7"
}
}
@@ -1,5 +1,7 @@
import { toUniqueId } from '@blitzkit/core';
import { NodeIO } from '@gltf-transform/core';
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
import draco3d from 'draco3dgltf';
import { readdir } from 'fs/promises';
import { extractModel } from '../core/blitz/extractModel';
import { readXMLDVPL } from '../core/blitz/readXMLDVPL';
@@ -13,7 +15,12 @@ import { TankParameters } from './tankIcons';
export async function tankModels() {
console.log('Building tank models...');
const nodeIO = new NodeIO();
const nodeIO = new NodeIO()
.registerExtensions(ALL_EXTENSIONS)
.registerDependencies({
'draco3d.decoder': await draco3d.createDecoderModule(),
'draco3d.encoder': await draco3d.createEncoderModule(),
});
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
(nations) => nations.filter((nation) => nation !== 'common'),
);
@@ -32,6 +39,7 @@ export async function tankModels() {
if (tankKey.includes('tutorial_bot')) return;
const id = toUniqueId(nation, tank.id);
const parameters = await readYAMLDVPL<TankParameters>(
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml.dvpl`,
);
@@ -8,9 +8,6 @@ export const vertexAttributeGLTFName: Partial<Record<VertexAttribute, string>> =
[VertexAttribute.TEXCOORD1]: 'TEXCOORD_0',
[VertexAttribute.TEXCOORD2]: 'TEXCOORD_0',
[VertexAttribute.TEXCOORD3]: 'TEXCOORD_0',
[VertexAttribute.TANGENT]: 'TANGENT',
[VertexAttribute.JOINTINDEX]: 'JOINT_0',
[VertexAttribute.JOINTWEIGHT]: 'WEIGHT_0',
};
export const vertexAttributeGltfVectorSizes = {
...vertexAttributeVectorSizes,
@@ -6,6 +6,8 @@ import {
VertexAttribute,
} from '@blitzkit/core';
import { Document, Material, Node, Scene } from '@gltf-transform/core';
import { KHRDracoMeshCompression } from '@gltf-transform/extensions';
import { dedup, prune } from '@gltf-transform/functions';
import { times } from 'lodash-es';
import { dirname } from 'path';
import { Matrix4, Quaternion, Vector3, Vector4Tuple } from 'three';
@@ -223,7 +225,9 @@ export async function extractModel(data: string, path: string) {
const primitive = document
.createPrimitive()
.setIndices(indicesAccessor)
.setMaterial(material);
.setMaterial(material)
.setName(batchKey);
const attributes = new Map<VertexAttribute, number[][]>();
polygonGroup.vertices.forEach((vertex) => {
@@ -236,25 +240,23 @@ export async function extractModel(data: string, path: string) {
});
});
if (attributes.has(VertexAttribute.TANGENT)) {
attributes.set(
VertexAttribute.TANGENT,
attributes
.get(VertexAttribute.TANGENT)!
.map((tangent) => [...tangent, 1]),
);
}
attributes.forEach((value, attribute) => {
const name = vertexAttributeGLTFName[attribute];
if (!name || primitive.getAttribute(name)) return;
const vertexSize = vertexAttributeGltfVectorSizes[attribute];
if (
name === undefined ||
primitive.getAttribute(name) !== null
) {
return;
}
const vertexSize = vertexAttributeGltfVectorSizes[attribute];
const attributeAccessor = document
.createAccessor(name)
.setType(vertexSize === 1 ? 'SCALAR' : `VEC${vertexSize}`)
.setArray(new Float32Array(value.flat()))
.setBuffer(buffer);
primitive.setAttribute(name, attributeAccessor);
});
@@ -288,5 +290,19 @@ export async function extractModel(data: string, path: string) {
parseHierarchies(sc2['#hierarchy'], scene);
scene.addChild(document.createNode('test'));
await document.transform(prune({ keepAttributes: true }), dedup());
document
.createExtension(KHRDracoMeshCompression)
.setRequired(true)
.setEncoderOptions({
method: KHRDracoMeshCompression.EncoderMethod.EDGEBREAKER,
encodeSpeed: 0,
decodeSpeed: 0,
quantizationVolume: 'scene',
});
return document;
}
@@ -1,9 +1,14 @@
import { DdsReadStream, PvrReadStream } from '@blitzkit/core';
import { existsSync } from 'fs';
import sharp from 'sharp';
import sharp, { JpegOptions } from 'sharp';
import { readDVPLFile } from '../readDVPLFile';
import { TextureMutation } from './constants';
const jpegOptions: JpegOptions = {
quality: 20,
mozjpeg: true,
};
export async function readTexture(path: string, mutation?: TextureMutation) {
const ddsTexturePath = path.replace('.tex', '.dx11.dds.dvpl');
const isDds = existsSync(ddsTexturePath);
@@ -35,7 +40,7 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
raw.data[index + 3] = 255;
}
return await sharp(raw.data, { raw }).jpeg().toBuffer();
return await sharp(raw.data, { raw }).jpeg(jpegOptions).toBuffer();
}
case TextureMutation.RoughnessMetallicness: {
@@ -44,16 +49,16 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
});
const metallicness = sharp(raw.data, { raw })
.extractChannel('green')
.jpeg()
.jpeg(jpegOptions)
.toBuffer();
const roughness = sharp(raw.data, { raw })
.extractChannel('alpha')
.jpeg()
.jpeg(jpegOptions)
.toBuffer();
return await newImage
.joinChannel(await Promise.all([roughness, metallicness]))
.jpeg()
.jpeg(jpegOptions)
.toBuffer();
}
@@ -64,15 +69,18 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
*/
return await sharp(raw.data, { raw })
.extractChannel('alpha')
.jpeg()
.jpeg(jpegOptions)
.toBuffer();
}
case TextureMutation.Albedo: {
return await sharp(raw.data, { raw }).removeAlpha().jpeg().toBuffer();
return await sharp(raw.data, { raw })
.removeAlpha()
.jpeg(jpegOptions)
.toBuffer();
}
default:
return await sharp(raw.data, { raw }).jpeg().toBuffer();
return await sharp(raw.data, { raw }).jpeg(jpegOptions).toBuffer();
}
}
+11 -1
View File
@@ -2,6 +2,7 @@ import { asset } from '@blitzkit/core';
import { type ObjectMap, useLoader } from '@react-three/fiber';
import { Mesh, MeshStandardMaterial } from 'three';
import { type GLTF, GLTFLoader } from 'three-stdlib';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
const cache: Record<
number,
@@ -12,7 +13,16 @@ const cache: Record<
> = {};
export function useModel(id: number) {
const gltf = useLoader(GLTFLoader, asset(`3d/tanks/models/${id}.glb`));
const gltf = useLoader(
GLTFLoader,
asset(`3d/tanks/models/${id}.glb`),
(loader) => {
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');
loader.setDRACOLoader(dracoLoader);
},
);
if (!cache[id]) {
cache[id] = {
gltf,