@needle-tools/gltf-build-pipeline 1.4.1-beta.11 → 1.4.1-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/cache/cache.d.ts +38 -1
- package/dist/cache/cache.js +70 -0
- package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.d.ts +23 -13
- package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.js +7 -5
- package/dist/transforms/needle_progressive.js +15 -11
- package/dist/utils/mesh.d.ts +1 -0
- package/dist/utils/mesh.js +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@ All notable changes to this package will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.4.1-beta.12] - 2023-03-23
|
|
8
|
+
- add: NEEDLE_progressive LODs can now contain more info per texture or mesh. Meshes contain vertex- and index counts
|
|
9
|
+
- change: the cache can now store and retrieve meta information
|
|
10
|
+
|
|
7
11
|
## [1.4.1-beta.11] - 2023-03-20
|
|
8
12
|
- add: NEEDLE_progressive LOD meshes morph targets data
|
|
9
13
|
- fix: NEEDLE_progressive should check if simplifcation did result in improved meshes (> 32 verts removed && > 5 % improvement) and otherwise discard LODs (and the whole extension if no improvement was made)
|
package/dist/cache/cache.d.ts
CHANGED
|
@@ -1,10 +1,47 @@
|
|
|
1
1
|
import { ExtensibleProperty } from "@gltf-transform/core";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Clear the cache.
|
|
4
|
+
* This will remove all files in the cache directory.
|
|
4
5
|
*/
|
|
5
6
|
export declare function clearCache(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Ensure that the cache size does not exceed the given maximum size in MB.
|
|
9
|
+
* @param maxSizeMB The maximum size in MB.
|
|
10
|
+
*/
|
|
6
11
|
export declare function ensureCacheSize(maxSizeMB: number): void;
|
|
12
|
+
/**
|
|
13
|
+
* Add data to the cache.
|
|
14
|
+
* @param key The key to store the data under.
|
|
15
|
+
* @param bytes The data to store as a Uint8Array.
|
|
16
|
+
*/
|
|
7
17
|
export declare function addToCache(key: string, bytes: Uint8Array): void;
|
|
18
|
+
/**
|
|
19
|
+
* Try to get the data from the cache.
|
|
20
|
+
* @param key The key to look up.
|
|
21
|
+
* @returns The data as a Uint8Array or null if not found.
|
|
22
|
+
* @throws If the cache file is corrupted.
|
|
23
|
+
*/
|
|
8
24
|
export declare function tryGetFromCache(key: string): Uint8Array | null;
|
|
25
|
+
/** Add meta data to the cache.
|
|
26
|
+
* @param key The key to store the meta data for.
|
|
27
|
+
* @param meta The meta data object to store. It will be serialized to JSON and stored in a file with the key as the name with the extension ".meta".
|
|
28
|
+
*/
|
|
29
|
+
export declare function addMetaToCache(key: string, meta: object): void;
|
|
30
|
+
/** Try to get the meta data from the cache.
|
|
31
|
+
* @param key The key to look up.
|
|
32
|
+
* @param ignoreVersion If true, the version check is skipped. If false, the version must match the current build pipeline version.
|
|
33
|
+
* @returns The meta data object or null if not found.
|
|
34
|
+
*/
|
|
35
|
+
export declare function tryGetMetaFromCache(key: string, ignoreVersion?: boolean): object | null;
|
|
36
|
+
/**
|
|
37
|
+
* Get the cache key for a property.
|
|
38
|
+
* @param property The property to get the key for.
|
|
39
|
+
* @returns The key as a string.
|
|
40
|
+
*/
|
|
9
41
|
export declare function getKey(property: ExtensibleProperty): string;
|
|
42
|
+
/**
|
|
43
|
+
* Get the hash for a property or an object.
|
|
44
|
+
* @param property The property to get the hash for.
|
|
45
|
+
* @returns The hash as a number.
|
|
46
|
+
*/
|
|
10
47
|
export declare function getHash(property: ExtensibleProperty | object): number;
|
package/dist/cache/cache.js
CHANGED
|
@@ -2,6 +2,7 @@ import { ExtensibleProperty, Texture, Primitive, Accessor, Mesh } from "@gltf-tr
|
|
|
2
2
|
import tmp from 'tmp';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import { getVersion } from "../utils/version.js";
|
|
5
6
|
// import * as CHECKDISCSPACE from 'check-disk-space'
|
|
6
7
|
/**
|
|
7
8
|
* Get the available space on the cache directory in bytes.
|
|
@@ -17,11 +18,20 @@ import path from 'path';
|
|
|
17
18
|
// }
|
|
18
19
|
// return 0;
|
|
19
20
|
// }
|
|
21
|
+
const buildPipelineVersion = getVersion(false);
|
|
22
|
+
/**
|
|
23
|
+
* Clear the cache.
|
|
24
|
+
* This will remove all files in the cache directory.
|
|
25
|
+
*/
|
|
20
26
|
export function clearCache() {
|
|
21
27
|
const dir = getCacheDirectory();
|
|
22
28
|
fs.rmSync(dir, { recursive: true });
|
|
23
29
|
console.log(`Cleared cache at ${dir}`);
|
|
24
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Ensure that the cache size does not exceed the given maximum size in MB.
|
|
33
|
+
* @param maxSizeMB The maximum size in MB.
|
|
34
|
+
*/
|
|
25
35
|
export function ensureCacheSize(maxSizeMB) {
|
|
26
36
|
const dir = getCacheDirectory();
|
|
27
37
|
let totalSize = 0;
|
|
@@ -50,12 +60,23 @@ export function ensureCacheSize(maxSizeMB) {
|
|
|
50
60
|
}
|
|
51
61
|
console.log(`Cache size reduced to ${(totalSize / (1024 * 1024)).toFixed(1)} MB`);
|
|
52
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Add data to the cache.
|
|
65
|
+
* @param key The key to store the data under.
|
|
66
|
+
* @param bytes The data to store as a Uint8Array.
|
|
67
|
+
*/
|
|
53
68
|
export function addToCache(key, bytes) {
|
|
54
69
|
const dir = getCacheDirectory();
|
|
55
70
|
const path = `${dir}/${key}.bin`;
|
|
56
71
|
console.log(`Added ${(bytes.byteLength / 1024).toFixed(1)} KB to cache at \"${path}\"`);
|
|
57
72
|
fs.writeFileSync(path, bytes);
|
|
58
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Try to get the data from the cache.
|
|
76
|
+
* @param key The key to look up.
|
|
77
|
+
* @returns The data as a Uint8Array or null if not found.
|
|
78
|
+
* @throws If the cache file is corrupted.
|
|
79
|
+
*/
|
|
59
80
|
export function tryGetFromCache(key) {
|
|
60
81
|
const dir = getCacheDirectory();
|
|
61
82
|
const path = `${dir}/${key}.bin`;
|
|
@@ -65,6 +86,50 @@ export function tryGetFromCache(key) {
|
|
|
65
86
|
}
|
|
66
87
|
return null;
|
|
67
88
|
}
|
|
89
|
+
/** Add meta data to the cache.
|
|
90
|
+
* @param key The key to store the meta data for.
|
|
91
|
+
* @param meta The meta data object to store. It will be serialized to JSON and stored in a file with the key as the name with the extension ".meta".
|
|
92
|
+
*/
|
|
93
|
+
export function addMetaToCache(key, meta) {
|
|
94
|
+
const dir = getCacheDirectory();
|
|
95
|
+
const metaPath = `${dir}/${key}.meta`;
|
|
96
|
+
meta['needle-build-pipeline:version'] = buildPipelineVersion;
|
|
97
|
+
fs.writeFileSync(metaPath, JSON.stringify(meta));
|
|
98
|
+
}
|
|
99
|
+
/** Try to get the meta data from the cache.
|
|
100
|
+
* @param key The key to look up.
|
|
101
|
+
* @param ignoreVersion If true, the version check is skipped. If false, the version must match the current build pipeline version.
|
|
102
|
+
* @returns The meta data object or null if not found.
|
|
103
|
+
*/
|
|
104
|
+
export function tryGetMetaFromCache(key, ignoreVersion = false) {
|
|
105
|
+
try {
|
|
106
|
+
const dir = getCacheDirectory();
|
|
107
|
+
const path = `${dir}/${key}.meta`;
|
|
108
|
+
if (fs.existsSync(path)) {
|
|
109
|
+
const bytes = fs.readFileSync(path);
|
|
110
|
+
if (bytes?.length > 0) {
|
|
111
|
+
const text = bytes.toString('utf-8');
|
|
112
|
+
if (text) {
|
|
113
|
+
const obj = JSON.parse(text);
|
|
114
|
+
if (ignoreVersion)
|
|
115
|
+
return obj;
|
|
116
|
+
if (obj['needle-build-pipeline:version'] === buildPipelineVersion)
|
|
117
|
+
return obj;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
console.error(`Error reading cache meta: ${e.message}`);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get the cache key for a property.
|
|
130
|
+
* @param property The property to get the key for.
|
|
131
|
+
* @returns The key as a string.
|
|
132
|
+
*/
|
|
68
133
|
export function getKey(property) {
|
|
69
134
|
let prefix = "prop";
|
|
70
135
|
if (property instanceof Texture) {
|
|
@@ -74,6 +139,11 @@ export function getKey(property) {
|
|
|
74
139
|
const key = `${prefix}-${hash}`;
|
|
75
140
|
return key;
|
|
76
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the hash for a property or an object.
|
|
144
|
+
* @param property The property to get the hash for.
|
|
145
|
+
* @returns The hash as a number.
|
|
146
|
+
*/
|
|
77
147
|
export function getHash(property) {
|
|
78
148
|
let hash = 0;
|
|
79
149
|
if (property instanceof ExtensibleProperty) {
|
|
@@ -1,29 +1,39 @@
|
|
|
1
|
-
import { Extension, ExtensionProperty,
|
|
1
|
+
import { Extension, ExtensionProperty, PropertyType, ReaderContext, WriterContext } from "@gltf-transform/core";
|
|
2
2
|
export declare const NEEDLE_PROGRESSIVE_EXTENSION_NAME = "NEEDLE_progressive";
|
|
3
|
-
export
|
|
3
|
+
export type ProgressiveLoadingInfo = {
|
|
4
4
|
/** guid of the asset the LODs belong to */
|
|
5
5
|
guid: string;
|
|
6
|
-
/**
|
|
7
|
-
lods?: Array<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
/** lod infos and paths */
|
|
7
|
+
lods?: Array<LodInfo>;
|
|
8
|
+
};
|
|
9
|
+
type LodInfo = {
|
|
10
|
+
path: string;
|
|
11
|
+
};
|
|
12
|
+
export type ProgressiveTextureModel = ProgressiveLoadingInfo & {
|
|
13
|
+
lods?: Array<LodInfo & {}>;
|
|
14
|
+
};
|
|
15
|
+
export type ProgressiveMeshModel = ProgressiveLoadingInfo & {
|
|
16
|
+
density: number;
|
|
17
|
+
lods?: Array<LodInfo & {
|
|
18
|
+
density: number;
|
|
19
|
+
vertexCount: number;
|
|
20
|
+
indexCount: number;
|
|
11
21
|
}>;
|
|
12
|
-
|
|
13
|
-
}
|
|
22
|
+
};
|
|
14
23
|
export declare class NEEDLE_progressive extends Extension {
|
|
15
24
|
static EXTENSION_NAME: string;
|
|
16
25
|
extensionName: string;
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
createTexture(data: ProgressiveTextureModel): NEEDLE_progressive_property;
|
|
27
|
+
createMesh(data: ProgressiveMeshModel): NEEDLE_progressive_property;
|
|
19
28
|
read(_context: ReaderContext): this;
|
|
20
29
|
write(context: WriterContext): this;
|
|
21
30
|
}
|
|
22
|
-
export declare class
|
|
31
|
+
export declare class NEEDLE_progressive_property extends ExtensionProperty {
|
|
23
32
|
static EXTENSION_NAME: string;
|
|
24
33
|
readonly extensionName: string;
|
|
25
34
|
parentTypes: PropertyType[];
|
|
26
35
|
propertyType: string;
|
|
27
36
|
init(): void;
|
|
28
|
-
model:
|
|
37
|
+
model: ProgressiveLoadingInfo;
|
|
29
38
|
}
|
|
39
|
+
export {};
|
|
@@ -4,13 +4,15 @@ export const NEEDLE_PROGRESSIVE_EXTENSION_NAME = "NEEDLE_progressive";
|
|
|
4
4
|
export class NEEDLE_progressive extends Extension {
|
|
5
5
|
static EXTENSION_NAME = NEEDLE_PROGRESSIVE_EXTENSION_NAME;
|
|
6
6
|
extensionName = NEEDLE_PROGRESSIVE_EXTENSION_NAME;
|
|
7
|
-
|
|
8
|
-
const ext = new
|
|
7
|
+
createTexture(data) {
|
|
8
|
+
const ext = new NEEDLE_progressive_property(this.document.getGraph());
|
|
9
9
|
ext.model = data;
|
|
10
10
|
return ext;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
createMesh(data) {
|
|
13
|
+
const ext = new NEEDLE_progressive_property(this.document.getGraph());
|
|
14
|
+
ext.model = data;
|
|
15
|
+
return ext;
|
|
14
16
|
}
|
|
15
17
|
read(_context) {
|
|
16
18
|
// console.log("READ " + NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME);
|
|
@@ -57,7 +59,7 @@ export class NEEDLE_progressive extends Extension {
|
|
|
57
59
|
return this;
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
|
-
export class
|
|
62
|
+
export class NEEDLE_progressive_property extends ExtensionProperty {
|
|
61
63
|
static EXTENSION_NAME = NEEDLE_PROGRESSIVE_EXTENSION_NAME;
|
|
62
64
|
extensionName = NEEDLE_PROGRESSIVE_EXTENSION_NAME;
|
|
63
65
|
parentTypes = [PropertyType.TEXTURE, PropertyType.MESH];
|
|
@@ -4,7 +4,7 @@ import { NEEDLE_PROGRESSIVE_EXTENSION_NAME, NEEDLE_progressive } from "../extens
|
|
|
4
4
|
import { createOpaqueExtension, NEEDLE_compression_texture, NEEDLE_mesh_compression, NEEDLE_progressive_mesh_settings, NEEDLE_progressive_texture_settings, registerExtensions as registerDefaultExtensions } from '../extensions/index.js';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
7
|
-
import { addToCache, getHash, getKey, tryGetFromCache } from '../cache/index.js';
|
|
7
|
+
import { addMetaToCache, addToCache, getHash, getKey, tryGetFromCache, tryGetMetaFromCache } from '../cache/index.js';
|
|
8
8
|
import sharp from "sharp";
|
|
9
9
|
import { foreachGLTF, generateGuid } from '../utils/index.js';
|
|
10
10
|
import { needle_asset } from './needle_asset.js';
|
|
@@ -139,7 +139,7 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
139
139
|
continue;
|
|
140
140
|
}
|
|
141
141
|
const progressiveExt = doc.createExtension(NEEDLE_progressive);
|
|
142
|
-
if (!progressiveExt || !progressiveExt.
|
|
142
|
+
if (!progressiveExt || !progressiveExt.createTexture) {
|
|
143
143
|
logger.debug(`[${NAME}] Skipping because progressive extension is not available. ${textureIndex}`);
|
|
144
144
|
continue;
|
|
145
145
|
}
|
|
@@ -150,7 +150,7 @@ export function make_progressive_textures(filePath, _options = TEXTURE_RESIZE_DE
|
|
|
150
150
|
}
|
|
151
151
|
const relName = path.relative(directory, outPath);
|
|
152
152
|
// TODO: this path should be added to the NEEDLE dependencies extension
|
|
153
|
-
texture.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.
|
|
153
|
+
texture.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.createTexture({
|
|
154
154
|
guid: textureGuid,
|
|
155
155
|
lods: [
|
|
156
156
|
{
|
|
@@ -231,7 +231,7 @@ function createTextureLod(basePath, level, texture, slots, guid, textureIndex) {
|
|
|
231
231
|
}
|
|
232
232
|
// add progressive texture extension
|
|
233
233
|
const progressiveExt = newDoc.createExtension(NEEDLE_progressive);
|
|
234
|
-
newTexture.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.
|
|
234
|
+
newTexture.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.createTexture({
|
|
235
235
|
guid: guid,
|
|
236
236
|
}));
|
|
237
237
|
const newIo = new NodeIO();
|
|
@@ -355,7 +355,7 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
355
355
|
continue;
|
|
356
356
|
}
|
|
357
357
|
const progressiveExt = doc.createExtension(NEEDLE_progressive);
|
|
358
|
-
if (!progressiveExt || !progressiveExt.
|
|
358
|
+
if (!progressiveExt || !progressiveExt.createMesh) {
|
|
359
359
|
logger.debug(`[${NAME}] Skipping because progressive extension is not available. ${index++}`);
|
|
360
360
|
continue;
|
|
361
361
|
}
|
|
@@ -479,12 +479,14 @@ export function make_progressive_meshes(filePath, _options, opts) {
|
|
|
479
479
|
continue;
|
|
480
480
|
}
|
|
481
481
|
if (generatedLODInfos.length > 0) {
|
|
482
|
-
const model = progressiveExt.
|
|
482
|
+
const model = progressiveExt.createMesh({
|
|
483
483
|
guid: settings.guid,
|
|
484
484
|
lods: generatedLODInfos.map(l => {
|
|
485
485
|
return {
|
|
486
486
|
path: l.path,
|
|
487
487
|
density: l.density,
|
|
488
|
+
vertexCount: l.lodMeshInfo?.totalVertexCount,
|
|
489
|
+
indexCount: l.lodMeshInfo?.totalIndexCount,
|
|
488
490
|
};
|
|
489
491
|
}),
|
|
490
492
|
density: maxDensity,
|
|
@@ -526,10 +528,11 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
526
528
|
hash += getHash(lodLevel);
|
|
527
529
|
cacheKey = `mesh_lod_${level}_${hash}`;
|
|
528
530
|
const cachedValue = tryGetFromCache(cacheKey);
|
|
529
|
-
|
|
531
|
+
const meta = tryGetMetaFromCache(cacheKey);
|
|
532
|
+
if (cachedValue && meta) {
|
|
530
533
|
console.log(`[${NAME}] LOD ${level} loaded ${(cachedValue.length / 1024).toFixed()} KB from cache for \"${mesh.getName()}\"`);
|
|
531
534
|
writeFileSync(outPath, cachedValue);
|
|
532
|
-
return { level, path: fileName, success: true, cacheKey: cacheKey };
|
|
535
|
+
return { level, path: fileName, success: true, cacheKey: cacheKey, lodMeshInfo: meta.meshInfo, density: meta.density };
|
|
533
536
|
}
|
|
534
537
|
}
|
|
535
538
|
const newDoc = new Document();
|
|
@@ -614,7 +617,7 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
614
617
|
const newMeshInformation = getMeshInformation(newMesh);
|
|
615
618
|
if (newMeshInformation.totalVertexCount < 4) {
|
|
616
619
|
console.error(`[${NAME}] mesh LOD ${level} is has less than 4 vertices → skipping`);
|
|
617
|
-
return { level, path: fileName, success: false, cacheKey: cacheKey };
|
|
620
|
+
return { level, path: fileName, success: false, cacheKey: cacheKey, lodMeshInfo: null, density: null, };
|
|
618
621
|
}
|
|
619
622
|
let density = 0;
|
|
620
623
|
for (const prim of newMesh.listPrimitives()) {
|
|
@@ -622,11 +625,11 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
622
625
|
density = Math.max(density, d);
|
|
623
626
|
}
|
|
624
627
|
const progressiveExt = newDoc.createExtension(NEEDLE_progressive);
|
|
625
|
-
if (!progressiveExt || !progressiveExt.
|
|
628
|
+
if (!progressiveExt || !progressiveExt.createMesh) {
|
|
626
629
|
console.error("Failed to create progressive extension");
|
|
627
630
|
return;
|
|
628
631
|
}
|
|
629
|
-
newMesh.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.
|
|
632
|
+
newMesh.setExtension(NEEDLE_PROGRESSIVE_EXTENSION_NAME, progressiveExt.createMesh({
|
|
630
633
|
guid: guid,
|
|
631
634
|
density: density,
|
|
632
635
|
}));
|
|
@@ -648,6 +651,7 @@ async function createMeshLod(doc, basePath, level, mesh, meshInfo, guid, lodLeve
|
|
|
648
651
|
if (cacheKey != undefined) {
|
|
649
652
|
const bytes = readFileSync(outPath);
|
|
650
653
|
addToCache(cacheKey, bytes);
|
|
654
|
+
addMetaToCache(cacheKey, { meshInfo: newMeshInformation, density: density });
|
|
651
655
|
}
|
|
652
656
|
return { level, path: fileName, success: true, lodMeshInfo: newMeshInformation, cacheKey: cacheKey, density: density };
|
|
653
657
|
}
|
package/dist/utils/mesh.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Mesh, Primitive } from "@gltf-transform/core";
|
|
|
2
2
|
export declare type MeshInformation = {
|
|
3
3
|
readonly maxVertexCount: number;
|
|
4
4
|
readonly totalVertexCount: number;
|
|
5
|
+
readonly totalIndexCount: number;
|
|
5
6
|
};
|
|
6
7
|
export declare function getMeshInformation(mesh: Mesh): MeshInformation;
|
|
7
8
|
export declare function calculateMeshDensity(prim: Primitive): number;
|
package/dist/utils/mesh.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export function getMeshInformation(mesh) {
|
|
2
2
|
let maxVertexCount = 0;
|
|
3
|
+
let totalIndexCount = 0;
|
|
3
4
|
const totalVertexCount = mesh.listPrimitives().reduce((acc, prim) => {
|
|
5
|
+
const indices = prim.getIndices()?.getCount() || 0;
|
|
6
|
+
totalIndexCount += indices;
|
|
4
7
|
const vertices = prim.getAttribute('POSITION')?.getCount() || 0;
|
|
5
8
|
maxVertexCount = Math.max(maxVertexCount, vertices);
|
|
6
9
|
return acc + vertices;
|
|
@@ -8,6 +11,7 @@ export function getMeshInformation(mesh) {
|
|
|
8
11
|
return {
|
|
9
12
|
maxVertexCount,
|
|
10
13
|
totalVertexCount,
|
|
14
|
+
totalIndexCount,
|
|
11
15
|
};
|
|
12
16
|
}
|
|
13
17
|
export function calculateMeshDensity(prim) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/gltf-build-pipeline",
|
|
3
|
-
"version": "1.4.1-beta.
|
|
3
|
+
"version": "1.4.1-beta.12",
|
|
4
4
|
"description": "Pipeline and tools for optimizing gltf files using gltf-transform and compression settings within glTF extensions",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"type": "module",
|