@manycore/aholo-splat-transform 1.2.8 → 1.2.9
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 +120 -113
- package/README.md +39 -39
- package/THIRD_PARTY_LICENSES.txt +1373 -1373
- package/bin/cli.js +125 -118
- package/dist/SplatData.d.ts +67 -67
- package/dist/SplatData.js +167 -150
- package/dist/constant.d.ts +3 -3
- package/dist/constant.js +13 -13
- package/dist/file/IFile.d.ts +5 -5
- package/dist/file/IFile.js +1 -1
- package/dist/file/esz.d.ts +11 -11
- package/dist/file/esz.js +337 -322
- package/dist/file/index.d.ts +8 -8
- package/dist/file/index.js +7 -7
- package/dist/file/ksplat.d.ts +12 -12
- package/dist/file/ksplat.js +293 -231
- package/dist/file/lcc.d.ts +11 -11
- package/dist/file/lcc.js +161 -158
- package/dist/file/ply.d.ts +13 -13
- package/dist/file/ply.js +439 -390
- package/dist/file/sog.d.ts +80 -80
- package/dist/file/sog.js +525 -494
- package/dist/file/splat.d.ts +6 -6
- package/dist/file/splat.js +119 -99
- package/dist/file/spz.d.ts +11 -11
- package/dist/file/spz.js +597 -583
- package/dist/file/voxel.d.ts +43 -37
- package/dist/file/voxel.js +411 -280
- package/dist/index.d.ts +33 -33
- package/dist/index.js +54 -54
- package/dist/native/index.d.ts +54 -54
- package/dist/native/index.js +122 -129
- package/dist/native/utils.d.ts +1 -0
- package/dist/native/utils.js +54 -0
- package/dist/tasks/AutoChunkLodTask.d.ts +13 -13
- package/dist/tasks/AutoChunkLodTask.js +117 -117
- package/dist/tasks/AutoLodTask.d.ts +10 -10
- package/dist/tasks/AutoLodTask.js +20 -20
- package/dist/tasks/BaseTask.d.ts +15 -15
- package/dist/tasks/BaseTask.js +5 -5
- package/dist/tasks/FlexLodTask.d.ts +12 -12
- package/dist/tasks/FlexLodTask.js +54 -44
- package/dist/tasks/ModifyTask.d.ts +9 -9
- package/dist/tasks/ModifyTask.js +166 -156
- package/dist/tasks/ReadTask.d.ts +9 -9
- package/dist/tasks/ReadTask.js +29 -29
- package/dist/tasks/SkeletonLodTask.d.ts +10 -10
- package/dist/tasks/SkeletonLodTask.js +176 -156
- package/dist/tasks/VoxelTask.d.ts +35 -30
- package/dist/tasks/VoxelTask.js +40 -37
- package/dist/tasks/WriteTask.d.ts +12 -12
- package/dist/tasks/WriteTask.js +70 -70
- package/dist/utils/BufferReader.d.ts +12 -12
- package/dist/utils/BufferReader.js +45 -45
- package/dist/utils/Logger.d.ts +11 -11
- package/dist/utils/Logger.js +40 -40
- package/dist/utils/StreamChunkDecoder.d.ts +16 -16
- package/dist/utils/StreamChunkDecoder.js +31 -31
- package/dist/utils/index.d.ts +27 -27
- package/dist/utils/index.js +101 -101
- package/dist/utils/k-means.d.ts +4 -4
- package/dist/utils/k-means.js +340 -341
- package/dist/utils/math.d.ts +46 -46
- package/dist/utils/math.js +350 -346
- package/dist/utils/quantize-1d.d.ts +4 -4
- package/dist/utils/quantize-1d.js +164 -164
- package/dist/utils/sh-rotate.d.ts +2 -2
- package/dist/utils/sh-rotate.js +236 -175
- package/dist/utils/splat.d.ts +21 -21
- package/dist/utils/splat.js +397 -387
- package/dist/utils/voxel/binary.d.ts +8 -0
- package/dist/utils/voxel/binary.js +176 -0
- package/dist/utils/voxel/common.d.ts +178 -162
- package/dist/utils/voxel/common.js +1752 -1682
- package/dist/utils/voxel/coplanar-merge.d.ts +63 -63
- package/dist/utils/voxel/coplanar-merge.js +818 -819
- package/dist/utils/voxel/filter-cluster.d.ts +20 -0
- package/dist/utils/voxel/filter-cluster.js +628 -0
- package/dist/utils/voxel/gpu-dilation.d.ts +2 -2
- package/dist/utils/voxel/gpu-dilation.js +677 -656
- package/dist/utils/voxel/marching-cubes.d.ts +42 -42
- package/dist/utils/voxel/marching-cubes.js +1645 -1657
- package/dist/utils/voxel/mesh.d.ts +3 -3
- package/dist/utils/voxel/mesh.js +130 -130
- package/dist/utils/voxel/nav.d.ts +29 -29
- package/dist/utils/voxel/nav.js +1068 -1043
- package/dist/utils/voxel/postprocess.d.ts +23 -23
- package/dist/utils/voxel/postprocess.js +408 -375
- package/dist/utils/voxel/voxel-faces.d.ts +18 -18
- package/dist/utils/voxel/voxel-faces.js +662 -663
- package/dist/utils/voxel/voxelize.d.ts +34 -33
- package/dist/utils/voxel/voxelize.js +1208 -1193
- package/dist/utils/webgpu.d.ts +8 -8
- package/dist/utils/webgpu.js +122 -122
- package/package.json +37 -39
- package/dist/native/cpp/bin/linux/binding.node +0 -0
- package/dist/native/cpp/bin/windows/binding.node +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { Config as AutoChunkLodConfig } from './tasks/AutoChunkLodTask.js';
|
|
2
|
-
import { Config as AutoLodConfig } from './tasks/AutoLodTask.js';
|
|
3
|
-
import { Config as FlexLodConfig } from './tasks/FlexLodTask.js';
|
|
4
|
-
import { Config as SkeletonLodConfig } from './tasks/SkeletonLodTask.js';
|
|
5
|
-
import { Config as ModifyConfig } from './tasks/ModifyTask.js';
|
|
6
|
-
import { Config as ReadConfig } from './tasks/ReadTask.js';
|
|
7
|
-
import { Config as WriteConfig } from './tasks/WriteTask.js';
|
|
8
|
-
import { VoxelTaskConfig } from './tasks/VoxelTask.js';
|
|
9
|
-
interface TaskConfigMap {
|
|
10
|
-
Read: ReadConfig;
|
|
11
|
-
Write: WriteConfig;
|
|
12
|
-
Voxel: VoxelTaskConfig;
|
|
13
|
-
Modify: ModifyConfig;
|
|
14
|
-
SkeletonLod: SkeletonLodConfig;
|
|
15
|
-
FlexLod: FlexLodConfig;
|
|
16
|
-
AutoLod: AutoLodConfig;
|
|
17
|
-
AutoChunkLod: AutoChunkLodConfig;
|
|
18
|
-
}
|
|
19
|
-
type PipelineTask = {
|
|
20
|
-
[K in keyof TaskConfigMap]: {
|
|
21
|
-
id: string;
|
|
22
|
-
type: K;
|
|
23
|
-
config: TaskConfigMap[K];
|
|
24
|
-
release?: string[];
|
|
25
|
-
};
|
|
26
|
-
}[keyof TaskConfigMap];
|
|
27
|
-
interface PipelineConfig {
|
|
28
|
-
version: number;
|
|
29
|
-
gpu?: number;
|
|
30
|
-
tasks: PipelineTask[];
|
|
31
|
-
}
|
|
32
|
-
export declare function runner(config: PipelineConfig): Promise<void>;
|
|
33
|
-
export {};
|
|
1
|
+
import { type Config as AutoChunkLodConfig } from './tasks/AutoChunkLodTask.js';
|
|
2
|
+
import { type Config as AutoLodConfig } from './tasks/AutoLodTask.js';
|
|
3
|
+
import { type Config as FlexLodConfig } from './tasks/FlexLodTask.js';
|
|
4
|
+
import { type Config as SkeletonLodConfig } from './tasks/SkeletonLodTask.js';
|
|
5
|
+
import { type Config as ModifyConfig } from './tasks/ModifyTask.js';
|
|
6
|
+
import { type Config as ReadConfig } from './tasks/ReadTask.js';
|
|
7
|
+
import { type Config as WriteConfig } from './tasks/WriteTask.js';
|
|
8
|
+
import { type VoxelTaskConfig } from './tasks/VoxelTask.js';
|
|
9
|
+
interface TaskConfigMap {
|
|
10
|
+
Read: ReadConfig;
|
|
11
|
+
Write: WriteConfig;
|
|
12
|
+
Voxel: VoxelTaskConfig;
|
|
13
|
+
Modify: ModifyConfig;
|
|
14
|
+
SkeletonLod: SkeletonLodConfig;
|
|
15
|
+
FlexLod: FlexLodConfig;
|
|
16
|
+
AutoLod: AutoLodConfig;
|
|
17
|
+
AutoChunkLod: AutoChunkLodConfig;
|
|
18
|
+
}
|
|
19
|
+
type PipelineTask = {
|
|
20
|
+
[K in keyof TaskConfigMap]: {
|
|
21
|
+
id: string;
|
|
22
|
+
type: K;
|
|
23
|
+
config: TaskConfigMap[K];
|
|
24
|
+
release?: string[];
|
|
25
|
+
};
|
|
26
|
+
}[keyof TaskConfigMap];
|
|
27
|
+
interface PipelineConfig {
|
|
28
|
+
version: number;
|
|
29
|
+
gpu?: number;
|
|
30
|
+
tasks: PipelineTask[];
|
|
31
|
+
}
|
|
32
|
+
export declare function runner(config: PipelineConfig): Promise<void>;
|
|
33
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import { AutoChunkLodTask } from './tasks/AutoChunkLodTask.js';
|
|
2
|
-
import { AutoLodTask } from './tasks/AutoLodTask.js';
|
|
3
|
-
import { FlexLodTask } from './tasks/FlexLodTask.js';
|
|
4
|
-
import { SkeletonLodTask } from './tasks/SkeletonLodTask.js';
|
|
5
|
-
import { ModifyTask } from './tasks/ModifyTask.js';
|
|
6
|
-
import { ReadTask } from './tasks/ReadTask.js';
|
|
7
|
-
import { WriteTask } from './tasks/WriteTask.js';
|
|
8
|
-
import { VoxelTask } from './tasks/VoxelTask.js';
|
|
9
|
-
import { enumerateAdapters, logger, releaseSharedDevice, initGPUAdapter } from './utils/index.js';
|
|
10
|
-
const TaskMap = {
|
|
11
|
-
Read: new ReadTask(),
|
|
12
|
-
Write: new WriteTask(),
|
|
13
|
-
Voxel: new VoxelTask(),
|
|
14
|
-
Modify: new ModifyTask(),
|
|
15
|
-
SkeletonLod: new SkeletonLodTask(),
|
|
16
|
-
FlexLod: new FlexLodTask(),
|
|
17
|
-
AutoLod: new AutoLodTask(),
|
|
18
|
-
AutoChunkLod: new AutoChunkLodTask(),
|
|
19
|
-
};
|
|
20
|
-
function anyTaskRequireGPU(tasks) {
|
|
21
|
-
for (const t of tasks) {
|
|
22
|
-
if (TaskMap[t.type].requiresGPU(t.config)) {
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
export async function runner(config) {
|
|
29
|
-
console.time('Total elapsed time');
|
|
30
|
-
const ctx = {
|
|
31
|
-
logger,
|
|
32
|
-
resources: new Map(),
|
|
33
|
-
};
|
|
34
|
-
if (anyTaskRequireGPU(config.tasks)) {
|
|
35
|
-
logger.prefix = `[Task:GPU]`;
|
|
36
|
-
logger.info('Any task requires GPU detected, initialize GPU adapter.');
|
|
37
|
-
const adapter = (await enumerateAdapters())[config.gpu ?? 0];
|
|
38
|
-
initGPUAdapter([`adapter=${adapter.name}`]);
|
|
39
|
-
}
|
|
40
|
-
for (const taskDef of config.tasks) {
|
|
41
|
-
const { id, type, config: taskConfig, release = [] } = taskDef;
|
|
42
|
-
const task = TaskMap[type];
|
|
43
|
-
if (!task) {
|
|
44
|
-
throw new Error(`Task not found: ${type} (id: ${id})`);
|
|
45
|
-
}
|
|
46
|
-
logger.prefix = `[Task:${type}#${id}]`;
|
|
47
|
-
logger.time('elapsed time');
|
|
48
|
-
await task.exec(taskConfig, ctx);
|
|
49
|
-
release.forEach(v => ctx.resources.delete(v));
|
|
50
|
-
logger.timeEnd('elapsed time');
|
|
51
|
-
}
|
|
52
|
-
releaseSharedDevice();
|
|
53
|
-
console.timeEnd('Total elapsed time');
|
|
54
|
-
}
|
|
1
|
+
import { AutoChunkLodTask } from './tasks/AutoChunkLodTask.js';
|
|
2
|
+
import { AutoLodTask } from './tasks/AutoLodTask.js';
|
|
3
|
+
import { FlexLodTask } from './tasks/FlexLodTask.js';
|
|
4
|
+
import { SkeletonLodTask } from './tasks/SkeletonLodTask.js';
|
|
5
|
+
import { ModifyTask } from './tasks/ModifyTask.js';
|
|
6
|
+
import { ReadTask } from './tasks/ReadTask.js';
|
|
7
|
+
import { WriteTask } from './tasks/WriteTask.js';
|
|
8
|
+
import { VoxelTask } from './tasks/VoxelTask.js';
|
|
9
|
+
import { enumerateAdapters, logger, releaseSharedDevice, initGPUAdapter } from './utils/index.js';
|
|
10
|
+
const TaskMap = {
|
|
11
|
+
Read: new ReadTask(),
|
|
12
|
+
Write: new WriteTask(),
|
|
13
|
+
Voxel: new VoxelTask(),
|
|
14
|
+
Modify: new ModifyTask(),
|
|
15
|
+
SkeletonLod: new SkeletonLodTask(),
|
|
16
|
+
FlexLod: new FlexLodTask(),
|
|
17
|
+
AutoLod: new AutoLodTask(),
|
|
18
|
+
AutoChunkLod: new AutoChunkLodTask(),
|
|
19
|
+
};
|
|
20
|
+
function anyTaskRequireGPU(tasks) {
|
|
21
|
+
for (const t of tasks) {
|
|
22
|
+
if (TaskMap[t.type].requiresGPU(t.config)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
export async function runner(config) {
|
|
29
|
+
console.time('Total elapsed time');
|
|
30
|
+
const ctx = {
|
|
31
|
+
logger,
|
|
32
|
+
resources: new Map(),
|
|
33
|
+
};
|
|
34
|
+
if (anyTaskRequireGPU(config.tasks)) {
|
|
35
|
+
logger.prefix = `[Task:GPU]`;
|
|
36
|
+
logger.info('Any task requires GPU detected, initialize GPU adapter.');
|
|
37
|
+
const adapter = (await enumerateAdapters())[config.gpu ?? 0];
|
|
38
|
+
initGPUAdapter([`adapter=${adapter.name}`]);
|
|
39
|
+
}
|
|
40
|
+
for (const taskDef of config.tasks) {
|
|
41
|
+
const { id, type, config: taskConfig, release = [] } = taskDef;
|
|
42
|
+
const task = TaskMap[type];
|
|
43
|
+
if (!task) {
|
|
44
|
+
throw new Error(`Task not found: ${type} (id: ${id})`);
|
|
45
|
+
}
|
|
46
|
+
logger.prefix = `[Task:${type}#${id}]`;
|
|
47
|
+
logger.time('elapsed time');
|
|
48
|
+
await task.exec(taskConfig, ctx);
|
|
49
|
+
release.forEach(v => ctx.resources.delete(v));
|
|
50
|
+
logger.timeEnd('elapsed time');
|
|
51
|
+
}
|
|
52
|
+
releaseSharedDevice();
|
|
53
|
+
console.timeEnd('Total elapsed time');
|
|
54
|
+
}
|
package/dist/native/index.d.ts
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import { SplatData } from '../SplatData.js';
|
|
2
|
-
import { Buffer } from 'node:buffer';
|
|
3
|
-
export interface LevelParameter {
|
|
4
|
-
precision: number;
|
|
5
|
-
scaleBoost: number;
|
|
6
|
-
}
|
|
7
|
-
export interface BlockedSplats {
|
|
8
|
-
box: {
|
|
9
|
-
min: [number, number, number];
|
|
10
|
-
max: [number, number, number];
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* current block referenced splats, level ordered.
|
|
14
|
-
*/
|
|
15
|
-
refs: number[];
|
|
16
|
-
}
|
|
17
|
-
export interface BlockedResult {
|
|
18
|
-
splats: SplatData[];
|
|
19
|
-
blocks: BlockedSplats[];
|
|
20
|
-
}
|
|
21
|
-
export declare function generateLod(splat: SplatData, levelParameters: LevelParameter[], blockPrecision: number, minSize: number, maxStep: number): BlockedResult;
|
|
22
|
-
export declare class WebPLosslessProfile {
|
|
23
|
-
readonly lossless = true;
|
|
24
|
-
}
|
|
25
|
-
export declare class WebPQualityProfile {
|
|
26
|
-
readonly quality: number;
|
|
27
|
-
readonly lossless = false;
|
|
28
|
-
constructor(quality: number);
|
|
29
|
-
}
|
|
30
|
-
export declare function encodeWebP(data: Uint8Array | Buffer, width: number, height: number, profile: WebPLosslessProfile | WebPQualityProfile): Buffer<ArrayBufferLike>;
|
|
31
|
-
export declare function decodeWebP(data: Uint8Array | Buffer): {
|
|
32
|
-
data: Buffer;
|
|
33
|
-
width: number;
|
|
34
|
-
height: number;
|
|
35
|
-
};
|
|
36
|
-
export declare function encodeAVIF(data: Uint8Array | Buffer, width: number, height: number, quality: number): Buffer<ArrayBufferLike>;
|
|
37
|
-
export interface AVIFEncodeInput {
|
|
38
|
-
data: Uint8Array | Buffer;
|
|
39
|
-
width: number;
|
|
40
|
-
height: number;
|
|
41
|
-
quality: number;
|
|
42
|
-
}
|
|
43
|
-
export declare function encodeAVIFBatched(inputs: AVIFEncodeInput[]): Buffer<ArrayBufferLike>[];
|
|
44
|
-
export declare function decodeAVIF(data: Uint8Array | Buffer): {
|
|
45
|
-
data: Buffer;
|
|
46
|
-
width: number;
|
|
47
|
-
height: number;
|
|
48
|
-
};
|
|
49
|
-
export declare function decodeAVIFBatched(inputs: Array<Uint8Array | Buffer>): {
|
|
50
|
-
data: Buffer;
|
|
51
|
-
width: number;
|
|
52
|
-
height: number;
|
|
53
|
-
}[];
|
|
54
|
-
export declare function clusterAverage(dataTable: Float32Array[], clusters: Uint32Array[], output: Float32Array[]): void;
|
|
1
|
+
import { SplatData } from '../SplatData.js';
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
export interface LevelParameter {
|
|
4
|
+
precision: number;
|
|
5
|
+
scaleBoost: number;
|
|
6
|
+
}
|
|
7
|
+
export interface BlockedSplats {
|
|
8
|
+
box: {
|
|
9
|
+
min: [number, number, number];
|
|
10
|
+
max: [number, number, number];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* current block referenced splats, level ordered.
|
|
14
|
+
*/
|
|
15
|
+
refs: number[];
|
|
16
|
+
}
|
|
17
|
+
export interface BlockedResult {
|
|
18
|
+
splats: SplatData[];
|
|
19
|
+
blocks: BlockedSplats[];
|
|
20
|
+
}
|
|
21
|
+
export declare function generateLod(splat: SplatData, levelParameters: LevelParameter[], blockPrecision: number, minSize: number, maxStep: number): BlockedResult;
|
|
22
|
+
export declare class WebPLosslessProfile {
|
|
23
|
+
readonly lossless = true;
|
|
24
|
+
}
|
|
25
|
+
export declare class WebPQualityProfile {
|
|
26
|
+
readonly quality: number;
|
|
27
|
+
readonly lossless = false;
|
|
28
|
+
constructor(quality: number);
|
|
29
|
+
}
|
|
30
|
+
export declare function encodeWebP(data: Uint8Array | Buffer, width: number, height: number, profile: WebPLosslessProfile | WebPQualityProfile): Buffer<ArrayBufferLike>;
|
|
31
|
+
export declare function decodeWebP(data: Uint8Array | Buffer): {
|
|
32
|
+
data: Buffer;
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
};
|
|
36
|
+
export declare function encodeAVIF(data: Uint8Array | Buffer, width: number, height: number, quality: number): Buffer<ArrayBufferLike>;
|
|
37
|
+
export interface AVIFEncodeInput {
|
|
38
|
+
data: Uint8Array | Buffer;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
quality: number;
|
|
42
|
+
}
|
|
43
|
+
export declare function encodeAVIFBatched(inputs: AVIFEncodeInput[]): Buffer<ArrayBufferLike>[];
|
|
44
|
+
export declare function decodeAVIF(data: Uint8Array | Buffer): {
|
|
45
|
+
data: Buffer;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
};
|
|
49
|
+
export declare function decodeAVIFBatched(inputs: Array<Uint8Array | Buffer>): {
|
|
50
|
+
data: Buffer;
|
|
51
|
+
width: number;
|
|
52
|
+
height: number;
|
|
53
|
+
}[];
|
|
54
|
+
export declare function clusterAverage(dataTable: Float32Array[], clusters: Uint32Array[], output: Float32Array[]): void;
|
package/dist/native/index.js
CHANGED
|
@@ -1,129 +1,122 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
export function
|
|
114
|
-
const buffer = data instanceof Buffer ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
115
|
-
return getModule().
|
|
116
|
-
}
|
|
117
|
-
export function
|
|
118
|
-
return getModule().
|
|
119
|
-
}
|
|
120
|
-
export function
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
export function decodeAVIFBatched(inputs) {
|
|
125
|
-
return getModule().avif_decode_rgba_batched(inputs.map(i => i instanceof Buffer ? i : Buffer.from(i.buffer, i.byteOffset, i.byteLength)));
|
|
126
|
-
}
|
|
127
|
-
export function clusterAverage(dataTable, clusters, output) {
|
|
128
|
-
return getModule().cluster_average(dataTable.map(t => Buffer.from(t.buffer, t.byteOffset, t.byteLength)), clusters.map(t => Buffer.from(t.buffer, t.byteOffset, t.byteLength)), output.map(t => Buffer.from(t.buffer, t.byteOffset, t.byteLength)));
|
|
129
|
-
}
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { SplatData } from '../SplatData.js';
|
|
3
|
+
import { Buffer } from 'node:buffer';
|
|
4
|
+
import { isMusl } from './utils.js';
|
|
5
|
+
import p from '../../package.json' with { type: 'json' };
|
|
6
|
+
const getModule = (function () {
|
|
7
|
+
let m = undefined;
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
let runtime = undefined;
|
|
10
|
+
if (process.platform === 'win32') {
|
|
11
|
+
runtime = 'msvc';
|
|
12
|
+
}
|
|
13
|
+
else if (process.platform === 'linux') {
|
|
14
|
+
runtime = isMusl() ? 'musl' : 'gnu';
|
|
15
|
+
}
|
|
16
|
+
const binaryPackage = `${p.name}-${process.platform}-${process.arch}${runtime ? `-${runtime}` : ''}`;
|
|
17
|
+
return function () {
|
|
18
|
+
if (!m) {
|
|
19
|
+
m = require(binaryPackage);
|
|
20
|
+
}
|
|
21
|
+
return m;
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
export function generateLod(splat, levelParameters, blockPrecision, minSize, maxStep) {
|
|
25
|
+
if (splat.counts === 0) {
|
|
26
|
+
return {
|
|
27
|
+
splats: [splat],
|
|
28
|
+
blocks: [
|
|
29
|
+
{
|
|
30
|
+
box: { min: [0, 0, 0], max: [0, 0, 0] },
|
|
31
|
+
refs: new Array(levelParameters.length).fill(0),
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const levels = levelParameters.length;
|
|
37
|
+
const inputBuffers = splat.table.map(b => Buffer.from(b.buffer, b.byteOffset, b.byteLength));
|
|
38
|
+
const buffer = Buffer.alloc(levels * 8);
|
|
39
|
+
{
|
|
40
|
+
const parameters = new Float32Array(buffer.buffer, buffer.byteOffset, levels * 2);
|
|
41
|
+
for (let i = 0; i < levelParameters.length; i++) {
|
|
42
|
+
const { precision, scaleBoost } = levelParameters[i];
|
|
43
|
+
parameters[i * 2] = precision;
|
|
44
|
+
parameters[i * 2 + 1] = scaleBoost;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const { blockBoxes, blockRefs, gaussianCount, data } = getModule().generate_lod(inputBuffers, splat.shCounts, buffer, blockPrecision, minSize, maxStep);
|
|
48
|
+
const blockView = new Float32Array(blockBoxes.buffer, blockBoxes.byteOffset, blockBoxes.byteLength / 4);
|
|
49
|
+
const blockRefsView = new Uint32Array(blockRefs.buffer, blockRefs.byteOffset, blockRefs.byteLength / 4);
|
|
50
|
+
const blockCount = blockView.length / 6;
|
|
51
|
+
const gaussianCountView = new Uint32Array(gaussianCount.buffer, gaussianCount.byteOffset, gaussianCount.byteLength / 4);
|
|
52
|
+
const blocks = [];
|
|
53
|
+
const splats = [];
|
|
54
|
+
// read splats
|
|
55
|
+
{
|
|
56
|
+
let gaussianOffset = 0;
|
|
57
|
+
for (const count of gaussianCountView) {
|
|
58
|
+
const splatData = new SplatData(1, splat.shDegree);
|
|
59
|
+
splatData.shDegree = splat.shDegree;
|
|
60
|
+
splatData.shCounts = splat.shCounts;
|
|
61
|
+
splatData.counts = count;
|
|
62
|
+
splatData.table = data.map(buffer => new Float32Array(buffer.buffer, buffer.byteOffset + gaussianOffset * 4, count));
|
|
63
|
+
splats.push(splatData);
|
|
64
|
+
gaussianOffset += count;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (let i = 0; i < blockCount; i++) {
|
|
68
|
+
const block = {
|
|
69
|
+
box: {
|
|
70
|
+
min: [blockView[i * 6], blockView[i * 6 + 1], blockView[i * 6 + 2]],
|
|
71
|
+
max: [blockView[i * 6 + 3], blockView[i * 6 + 4], blockView[i * 6 + 5]],
|
|
72
|
+
},
|
|
73
|
+
refs: Array.from(blockRefsView.subarray(i * levels, i * levels + levels)),
|
|
74
|
+
};
|
|
75
|
+
blocks.push(block);
|
|
76
|
+
}
|
|
77
|
+
return { splats, blocks };
|
|
78
|
+
}
|
|
79
|
+
export class WebPLosslessProfile {
|
|
80
|
+
constructor() {
|
|
81
|
+
this.lossless = true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export class WebPQualityProfile {
|
|
85
|
+
constructor(quality) {
|
|
86
|
+
this.quality = quality;
|
|
87
|
+
this.lossless = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function encodeWebP(data, width, height, profile) {
|
|
91
|
+
const buffer = data instanceof Buffer ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
92
|
+
if (profile.lossless) {
|
|
93
|
+
return getModule().webp_encode_rgba_lossless(buffer, width, height);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
return getModule().webp_encode_rgba(buffer, width, height, profile.quality);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function decodeWebP(data) {
|
|
100
|
+
const buffer = data instanceof Buffer ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
101
|
+
return getModule().webp_decode_rgba(buffer);
|
|
102
|
+
}
|
|
103
|
+
export function encodeAVIF(data, width, height, quality) {
|
|
104
|
+
const buffer = data instanceof Buffer ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
105
|
+
return getModule().avif_encode_rgba(buffer, width, height, quality);
|
|
106
|
+
}
|
|
107
|
+
export function encodeAVIFBatched(inputs) {
|
|
108
|
+
return getModule().avif_encode_rgba_batched(inputs.map(i => ({
|
|
109
|
+
...i,
|
|
110
|
+
data: i.data instanceof Buffer ? i.data : Buffer.from(i.data.buffer, i.data.byteOffset, i.data.byteLength),
|
|
111
|
+
})));
|
|
112
|
+
}
|
|
113
|
+
export function decodeAVIF(data) {
|
|
114
|
+
const buffer = data instanceof Buffer ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
115
|
+
return getModule().avif_decode_rgba(buffer);
|
|
116
|
+
}
|
|
117
|
+
export function decodeAVIFBatched(inputs) {
|
|
118
|
+
return getModule().avif_decode_rgba_batched(inputs.map(i => (i instanceof Buffer ? i : Buffer.from(i.buffer, i.byteOffset, i.byteLength))));
|
|
119
|
+
}
|
|
120
|
+
export function clusterAverage(dataTable, clusters, output) {
|
|
121
|
+
return getModule().cluster_average(dataTable.map(t => Buffer.from(t.buffer, t.byteOffset, t.byteLength)), clusters.map(t => Buffer.from(t.buffer, t.byteOffset, t.byteLength)), output.map(t => Buffer.from(t.buffer, t.byteOffset, t.byteLength)));
|
|
122
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isMusl(): boolean;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import child_process from 'node:child_process';
|
|
3
|
+
export function isMusl() {
|
|
4
|
+
let musl = false;
|
|
5
|
+
if (process.platform === 'linux') {
|
|
6
|
+
musl = isMuslFromFilesystem();
|
|
7
|
+
if (musl == null) {
|
|
8
|
+
musl = isMuslFromReport();
|
|
9
|
+
}
|
|
10
|
+
if (musl == null) {
|
|
11
|
+
musl = isMuslFromChildProcess();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return musl;
|
|
15
|
+
}
|
|
16
|
+
function isFileMusl(f) {
|
|
17
|
+
return f.includes('libc.musl-') || f.includes('ld-musl-');
|
|
18
|
+
}
|
|
19
|
+
function isMuslFromFilesystem() {
|
|
20
|
+
try {
|
|
21
|
+
return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl');
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function isMuslFromReport() {
|
|
28
|
+
let report = null;
|
|
29
|
+
if (typeof process.report?.getReport === 'function') {
|
|
30
|
+
process.report.excludeNetwork = true;
|
|
31
|
+
report = process.report.getReport();
|
|
32
|
+
}
|
|
33
|
+
if (!report) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (report.header && report.header.glibcVersionRuntime) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(report.sharedObjects)) {
|
|
40
|
+
if (report.sharedObjects.some(isFileMusl)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
function isMuslFromChildProcess() {
|
|
47
|
+
try {
|
|
48
|
+
return child_process.execSync('ldd --version', { encoding: 'utf8' }).includes('musl');
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Context, BaseTask } from './BaseTask.js';
|
|
2
|
-
import { LevelParameter } from '../native/index.js';
|
|
3
|
-
export interface Config {
|
|
4
|
-
input: string;
|
|
5
|
-
output: string;
|
|
6
|
-
type: string;
|
|
7
|
-
maxChunkCounts?: number;
|
|
8
|
-
levels?: LevelParameter[];
|
|
9
|
-
}
|
|
10
|
-
export declare class AutoChunkLodTask extends BaseTask<Config> {
|
|
11
|
-
exec(config: Config, { logger, resources }: Context): Promise<void>;
|
|
12
|
-
requiresGPU(config: Config): boolean;
|
|
13
|
-
}
|
|
1
|
+
import { type Context, BaseTask } from './BaseTask.js';
|
|
2
|
+
import { type LevelParameter } from '../native/index.js';
|
|
3
|
+
export interface Config {
|
|
4
|
+
input: string;
|
|
5
|
+
output: string;
|
|
6
|
+
type: string;
|
|
7
|
+
maxChunkCounts?: number;
|
|
8
|
+
levels?: LevelParameter[];
|
|
9
|
+
}
|
|
10
|
+
export declare class AutoChunkLodTask extends BaseTask<Config> {
|
|
11
|
+
exec(config: Config, { logger, resources }: Context): Promise<void>;
|
|
12
|
+
requiresGPU(config: Config): boolean;
|
|
13
|
+
}
|