@vctrl/hooks 0.0.9 → 0.1.1
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/LICENSE.md +650 -0
- package/index.cjs.js +1 -0
- package/index.es.js +8 -0
- package/model-context-ClI5AGc8.js +19136 -0
- package/model-context-mPTTbSMx.cjs +3849 -0
- package/package.json +1 -1
- package/use-load-model/event-system.d.ts +7 -0
- package/use-load-model/file-type-hooks/use-load-binary.d.ts +11 -0
- package/use-load-model/file-type-hooks/use-load-gltf.d.ts +5 -0
- package/use-load-model/loaders/create-gltf-loader.d.ts +3 -0
- package/{src/use-load-model/loaders/create-usdz-loader.ts → use-load-model/loaders/create-usdz-loader.d.ts} +1 -7
- package/use-load-model/model-context.d.ts +20 -0
- package/use-load-model/state.d.ts +11 -0
- package/use-load-model/types.d.ts +48 -0
- package/use-load-model/use-load-model.d.ts +11 -0
- package/use-load-model/utils/array-buffer-to-base64.d.ts +2 -0
- package/use-load-model/utils/read-directory.d.ts +8 -0
- package/use-load-model.cjs.js +1 -0
- package/use-load-model.es.js +8 -0
- package/.babelrc +0 -12
- package/.eslintrc.json +0 -18
- package/LICENSE +0 -0
- package/project.json +0 -16
- package/src/use-load-model/event-system.ts +0 -29
- package/src/use-load-model/file-type-hooks/use-load-binary.ts +0 -74
- package/src/use-load-model/file-type-hooks/use-load-gltf.ts +0 -115
- package/src/use-load-model/loaders/create-gltf-loader.ts +0 -20
- package/src/use-load-model/model-context.tsx +0 -18
- package/src/use-load-model/state.ts +0 -33
- package/src/use-load-model/types.ts +0 -53
- package/src/use-load-model/use-load-model.ts +0 -111
- package/src/use-load-model/utils/array-buffer-to-base64.ts +0 -20
- package/src/use-load-model/utils/read-directory.ts +0 -31
- package/tsconfig.json +0 -21
- package/tsconfig.lib.json +0 -25
- package/vite.config.ts +0 -59
- /package/{src/index.ts → index.d.ts} +0 -0
- /package/{src/use-load-model/file-type-hooks/index.ts → use-load-model/file-type-hooks/index.d.ts} +0 -0
- /package/{src/use-load-model/index.ts → use-load-model/index.d.ts} +0 -0
- /package/{src/use-load-model/loaders/index.ts → use-load-model/loaders/index.d.ts} +0 -0
- /package/{src/use-load-model/utils/index.ts → use-load-model/utils/index.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.1.1",
|
|
3
3
|
"name": "@vctrl/hooks",
|
|
4
4
|
"description": "vctrl/hooks is a React hooks package designed to simplify 3D model loading and management within React applications. It's part of the vectreal-core ecosystem and is primarily used in the vctrl/viewer React component and the official website application.",
|
|
5
5
|
"bugs": {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EventData, EventHandler, EventTypes } from './types';
|
|
2
|
+
declare const eventSystem: {
|
|
3
|
+
emit<T extends EventTypes>(event: T, data: EventData[T]): void;
|
|
4
|
+
on<T extends EventTypes>(event: T, handler: EventHandler<T>): void;
|
|
5
|
+
off<T extends EventTypes>(event: T, handler: EventHandler<T>): void;
|
|
6
|
+
};
|
|
7
|
+
export default eventSystem;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Action, ModelFileTypes } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to load binary files
|
|
4
|
+
*
|
|
5
|
+
* @param dispatch - The dispatch function from the useReducer hook
|
|
6
|
+
* @returns An object containing the loadBinary function
|
|
7
|
+
*/
|
|
8
|
+
declare function useLoadBinary(dispatch: React.Dispatch<Action>): {
|
|
9
|
+
loadBinary: (file: File, fileType: ModelFileTypes, onProgress: () => void) => void;
|
|
10
|
+
};
|
|
11
|
+
export default useLoadBinary;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare const ModelContext: import('react').Context<{
|
|
2
|
+
on: <T extends import('./types').EventTypes>(event: T, handler: import('./types').EventHandler<T>) => void;
|
|
3
|
+
off: <T extends import('./types').EventTypes>(event: T, handler: import('./types').EventHandler<T>) => void;
|
|
4
|
+
handleFileUpload: (filesOrDirectories: import('./types').InputFileOrDirectory) => Promise<void>;
|
|
5
|
+
file: import('./types').ModelFile | null;
|
|
6
|
+
isFileLoading: boolean;
|
|
7
|
+
progress: number;
|
|
8
|
+
supportedFileTypes: import('./types').ModelFileTypes[];
|
|
9
|
+
}>;
|
|
10
|
+
declare const ModelProvider: ({ children }: React.PropsWithChildren) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
declare const useModelContext: () => {
|
|
12
|
+
on: <T extends import('./types').EventTypes>(event: T, handler: import('./types').EventHandler<T>) => void;
|
|
13
|
+
off: <T extends import('./types').EventTypes>(event: T, handler: import('./types').EventHandler<T>) => void;
|
|
14
|
+
handleFileUpload: (filesOrDirectories: import('./types').InputFileOrDirectory) => Promise<void>;
|
|
15
|
+
file: import('./types').ModelFile | null;
|
|
16
|
+
isFileLoading: boolean;
|
|
17
|
+
progress: number;
|
|
18
|
+
supportedFileTypes: import('./types').ModelFileTypes[];
|
|
19
|
+
};
|
|
20
|
+
export { ModelContext, ModelProvider, useModelContext };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Action, State } from './types';
|
|
2
|
+
export declare const initialState: State;
|
|
3
|
+
/**
|
|
4
|
+
* Reducer function for the useReadModelFiles hook
|
|
5
|
+
*
|
|
6
|
+
* @param state - The current state of the reducer
|
|
7
|
+
* @param action - The action to be performed
|
|
8
|
+
* @returns The updated state
|
|
9
|
+
*/
|
|
10
|
+
declare function reducer(state: State, action: Action): State;
|
|
11
|
+
export default reducer;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Object3D } from 'three';
|
|
2
|
+
export declare enum ModelFileTypes {
|
|
3
|
+
gltf = "gltf",
|
|
4
|
+
glb = "glb",
|
|
5
|
+
usdz = "usdz"
|
|
6
|
+
}
|
|
7
|
+
export type InputFileOrDirectory = (File | FileSystemDirectoryHandle)[];
|
|
8
|
+
export interface ReducedGltf {
|
|
9
|
+
images: {
|
|
10
|
+
name: string;
|
|
11
|
+
uri: string;
|
|
12
|
+
}[];
|
|
13
|
+
buffers: {
|
|
14
|
+
bytelength: string;
|
|
15
|
+
uri: string;
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
export interface ModelFile {
|
|
19
|
+
model: Object3D;
|
|
20
|
+
type: ModelFileTypes;
|
|
21
|
+
name: string;
|
|
22
|
+
}
|
|
23
|
+
export interface State {
|
|
24
|
+
file: ModelFile | null;
|
|
25
|
+
isFileLoading: boolean;
|
|
26
|
+
progress: number;
|
|
27
|
+
supportedFileTypes: ModelFileTypes[];
|
|
28
|
+
}
|
|
29
|
+
export type Action = {
|
|
30
|
+
type: 'SET_FILE';
|
|
31
|
+
payload: ModelFile;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'SET_FILE_LOADING';
|
|
34
|
+
payload: boolean;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'SET_PROGRESS';
|
|
37
|
+
payload: number;
|
|
38
|
+
} | {
|
|
39
|
+
type: 'RESET_STATE';
|
|
40
|
+
};
|
|
41
|
+
export type EventTypes = 'MULTIPLE_3D_MODELS' | 'UNSUPPORTED_FILE_TYPE' | 'UPLOAD_PROGRESS' | 'UPLOAD_COMPLETE';
|
|
42
|
+
export type EventData = {
|
|
43
|
+
MULTIPLE_3D_MODELS: File[];
|
|
44
|
+
UNSUPPORTED_FILE_TYPE: File[];
|
|
45
|
+
UPLOAD_PROGRESS: number;
|
|
46
|
+
UPLOAD_COMPLETE: State['file'];
|
|
47
|
+
};
|
|
48
|
+
export type EventHandler<T extends EventTypes> = (data: EventData[T]) => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ModelFileTypes, InputFileOrDirectory } from './types';
|
|
2
|
+
declare function useLoadModel(): {
|
|
3
|
+
on: <T extends import('./types').EventTypes>(event: T, handler: import('./types').EventHandler<T>) => void;
|
|
4
|
+
off: <T extends import('./types').EventTypes>(event: T, handler: import('./types').EventHandler<T>) => void;
|
|
5
|
+
handleFileUpload: (filesOrDirectories: InputFileOrDirectory) => Promise<void>;
|
|
6
|
+
file: import('./types').ModelFile | null;
|
|
7
|
+
isFileLoading: boolean;
|
|
8
|
+
progress: number;
|
|
9
|
+
supportedFileTypes: ModelFileTypes[];
|
|
10
|
+
};
|
|
11
|
+
export default useLoadModel;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively reads a directory
|
|
3
|
+
*
|
|
4
|
+
* @param directoryHandle - The directory handle to read
|
|
5
|
+
* @returns - An array of file objects
|
|
6
|
+
*/
|
|
7
|
+
declare function readDirectory(directoryHandle: FileSystemDirectoryHandle): Promise<File[]>;
|
|
8
|
+
export default readDirectory;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./model-context-mPTTbSMx.cjs");exports.ModelContext=e.ModelContext;exports.ModelFileTypes=e.ModelFileTypes;exports.ModelProvider=e.ModelProvider;exports.useLoadModel=e.useLoadModel;exports.useModelContext=e.useModelContext;
|
package/.babelrc
DELETED
package/.eslintrc.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
|
|
3
|
-
"ignorePatterns": ["!**/*"],
|
|
4
|
-
"overrides": [
|
|
5
|
-
{
|
|
6
|
-
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
7
|
-
"rules": {}
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"files": ["*.ts", "*.tsx"],
|
|
11
|
-
"rules": {}
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"files": ["*.js", "*.jsx"],
|
|
15
|
-
"rules": {}
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
}
|
package/LICENSE
DELETED
|
File without changes
|
package/project.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vctrl/hooks",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/hooks/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"tags": [],
|
|
7
|
-
"targets": {
|
|
8
|
-
"build": {
|
|
9
|
-
"executor": "@nx/vite:build",
|
|
10
|
-
"options": {
|
|
11
|
-
"outputPath": "dist/packages/vctrl/hooks",
|
|
12
|
-
"configFile": "packages/hooks/vite.config.ts"
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { EventData, EventHandler, EventTypes } from './types';
|
|
2
|
-
|
|
3
|
-
const listeners = {} as Record<EventTypes, EventHandler<EventTypes>[]>;
|
|
4
|
-
const eventSystem = {
|
|
5
|
-
emit<T extends EventTypes>(event: T, data: EventData[T]): void {
|
|
6
|
-
const handlers = listeners[event];
|
|
7
|
-
if (handlers) {
|
|
8
|
-
handlers.forEach((handler) => handler(data));
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
|
|
12
|
-
on<T extends EventTypes>(event: T, handler: EventHandler<T>): void {
|
|
13
|
-
if (!listeners[event]) {
|
|
14
|
-
listeners[event] = [];
|
|
15
|
-
}
|
|
16
|
-
listeners[event].push(handler as EventHandler<EventTypes>);
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
off<T extends EventTypes>(event: T, handler: EventHandler<T>): void {
|
|
20
|
-
const handlers = listeners[event];
|
|
21
|
-
if (handlers) {
|
|
22
|
-
listeners[event] = handlers.filter(
|
|
23
|
-
(h) => h !== handler,
|
|
24
|
-
) as EventHandler<EventTypes>[];
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default eventSystem;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
|
|
3
|
-
import { Action, ModelFileTypes } from '../types';
|
|
4
|
-
import { createGltfLoader, createUsdzLoader } from '../loaders';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Hook to load binary files
|
|
8
|
-
*
|
|
9
|
-
* @param dispatch - The dispatch function from the useReducer hook
|
|
10
|
-
* @returns An object containing the loadBinary function
|
|
11
|
-
*/
|
|
12
|
-
function useLoadBinary(dispatch: React.Dispatch<Action>) {
|
|
13
|
-
/**
|
|
14
|
-
* Function to read binary files
|
|
15
|
-
*
|
|
16
|
-
* @param file - The binary file to read
|
|
17
|
-
* @param fileType - The type of file to read
|
|
18
|
-
* @param onProgress - The function to call when progress is made
|
|
19
|
-
* @returns {void}
|
|
20
|
-
*/
|
|
21
|
-
const loadBinary = useCallback(
|
|
22
|
-
(file: File, fileType: ModelFileTypes, onProgress: () => void) => {
|
|
23
|
-
const reader = new FileReader();
|
|
24
|
-
|
|
25
|
-
reader.onload = async (event: ProgressEvent<FileReader>) => {
|
|
26
|
-
if (event.target?.result) {
|
|
27
|
-
const arrayBuffer = event.target.result as ArrayBuffer;
|
|
28
|
-
|
|
29
|
-
if (fileType === ModelFileTypes.glb) {
|
|
30
|
-
const gltfLoader = createGltfLoader();
|
|
31
|
-
|
|
32
|
-
gltfLoader.parse(arrayBuffer, '', (gltf) => {
|
|
33
|
-
dispatch({
|
|
34
|
-
type: 'SET_FILE',
|
|
35
|
-
payload: {
|
|
36
|
-
model: gltf.scene,
|
|
37
|
-
type: ModelFileTypes.glb,
|
|
38
|
-
name: file.name,
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
} else if (fileType === ModelFileTypes.usdz) {
|
|
43
|
-
const usdzLoader = createUsdzLoader();
|
|
44
|
-
const model = usdzLoader.parse(arrayBuffer);
|
|
45
|
-
|
|
46
|
-
dispatch({
|
|
47
|
-
type: 'SET_FILE',
|
|
48
|
-
payload: {
|
|
49
|
-
model: model,
|
|
50
|
-
type: ModelFileTypes.usdz,
|
|
51
|
-
name: file.name,
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
onProgress(); // Call progress callback when binary file is loaded
|
|
57
|
-
dispatch({ type: 'SET_FILE_LOADING', payload: false });
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
reader.onerror = (error) => {
|
|
62
|
-
console.error('Error reading file:', error);
|
|
63
|
-
dispatch({ type: 'SET_FILE_LOADING', payload: false });
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
reader.readAsArrayBuffer(file);
|
|
67
|
-
},
|
|
68
|
-
[dispatch],
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
return { loadBinary };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export default useLoadBinary;
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
|
|
3
|
-
import { Action, ModelFileTypes, ReducedGltf } from '../types';
|
|
4
|
-
import { arrayBufferToBase64 } from '../utils';
|
|
5
|
-
import { createGltfLoader } from '../loaders';
|
|
6
|
-
|
|
7
|
-
function useLoadGltf(dispatch: React.Dispatch<Action>) {
|
|
8
|
-
const embedExternalResources = useCallback(
|
|
9
|
-
async (
|
|
10
|
-
gltfContent: ReducedGltf,
|
|
11
|
-
otherFiles: File[],
|
|
12
|
-
onProgress: (progress: number) => void,
|
|
13
|
-
) => {
|
|
14
|
-
const fileMap = new Map(otherFiles.map((file) => [file.name, file]));
|
|
15
|
-
const totalFiles =
|
|
16
|
-
(gltfContent.buffers?.length || 0) + (gltfContent.images?.length || 0);
|
|
17
|
-
let processedFiles = 0;
|
|
18
|
-
|
|
19
|
-
const updateProgress = () => {
|
|
20
|
-
processedFiles++;
|
|
21
|
-
onProgress((processedFiles / totalFiles) * 100);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Embed buffers
|
|
25
|
-
if (gltfContent.buffers) {
|
|
26
|
-
for (let i = 0; i < gltfContent.buffers.length; i++) {
|
|
27
|
-
const buffer = gltfContent.buffers[i];
|
|
28
|
-
if (!buffer.uri || buffer.uri.startsWith('data:')) {
|
|
29
|
-
updateProgress();
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const fileName = buffer.uri.split('/').pop() || '';
|
|
34
|
-
const file = fileMap.get(fileName);
|
|
35
|
-
if (file) {
|
|
36
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
37
|
-
const base64 = await arrayBufferToBase64(arrayBuffer);
|
|
38
|
-
buffer.uri = `data:application/octet-stream;base64,${base64}`;
|
|
39
|
-
}
|
|
40
|
-
updateProgress();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Embed images
|
|
45
|
-
if (gltfContent.images) {
|
|
46
|
-
for (let i = 0; i < gltfContent.images.length; i++) {
|
|
47
|
-
const image = gltfContent.images[i];
|
|
48
|
-
if (!image.uri || image.uri.startsWith('data:')) {
|
|
49
|
-
updateProgress();
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const fileName = image.uri.split('/').pop() || '';
|
|
54
|
-
const file = fileMap.get(fileName);
|
|
55
|
-
if (file) {
|
|
56
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
57
|
-
const base64 = await arrayBufferToBase64(arrayBuffer);
|
|
58
|
-
const mimeType = file.type || 'image/png';
|
|
59
|
-
image.uri = `data:${mimeType};base64,${base64}`;
|
|
60
|
-
}
|
|
61
|
-
updateProgress();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return gltfContent;
|
|
66
|
-
},
|
|
67
|
-
[],
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const loadGltf = useCallback(
|
|
71
|
-
(
|
|
72
|
-
gltfFile: File,
|
|
73
|
-
otherFiles: File[],
|
|
74
|
-
onProgress: (progress: number) => void,
|
|
75
|
-
) => {
|
|
76
|
-
const reader = new FileReader();
|
|
77
|
-
reader.onload = async (e) => {
|
|
78
|
-
const gltfContent = JSON.parse(e.target?.result as string);
|
|
79
|
-
onProgress(10); // Initial progress after parsing GLTF
|
|
80
|
-
|
|
81
|
-
const modifiedGLTF = await embedExternalResources(
|
|
82
|
-
gltfContent,
|
|
83
|
-
otherFiles,
|
|
84
|
-
(embeddingProgress) => {
|
|
85
|
-
// Map embedding progress to 10-90% range
|
|
86
|
-
onProgress(10 + embeddingProgress * 0.8);
|
|
87
|
-
},
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const gltfLoader = createGltfLoader();
|
|
91
|
-
|
|
92
|
-
gltfLoader.parse(JSON.stringify(modifiedGLTF), '', (gltf) => {
|
|
93
|
-
dispatch({
|
|
94
|
-
type: 'SET_FILE',
|
|
95
|
-
payload: {
|
|
96
|
-
model: gltf.scene,
|
|
97
|
-
type: ModelFileTypes.gltf,
|
|
98
|
-
name: gltfFile.name,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
onProgress(100); // Final progress
|
|
104
|
-
dispatch({ type: 'SET_FILE_LOADING', payload: false });
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
reader.readAsText(gltfFile);
|
|
108
|
-
},
|
|
109
|
-
[dispatch, embedExternalResources],
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
return { loadGltf };
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export default useLoadGltf;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { WebGLRenderer } from 'three';
|
|
2
|
-
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
3
|
-
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
|
4
|
-
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader';
|
|
5
|
-
|
|
6
|
-
function createGltfLoader() {
|
|
7
|
-
const dracoLoader = new DRACOLoader();
|
|
8
|
-
dracoLoader.setDecoderPath('/draco/');
|
|
9
|
-
|
|
10
|
-
const ktxLoader = new KTX2Loader();
|
|
11
|
-
ktxLoader.setTranscoderPath('/draco/');
|
|
12
|
-
|
|
13
|
-
const gltfLoader = new GLTFLoader()
|
|
14
|
-
.setDRACOLoader(dracoLoader)
|
|
15
|
-
.setKTX2Loader(ktxLoader.detectSupport(new WebGLRenderer()));
|
|
16
|
-
|
|
17
|
-
return gltfLoader;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default createGltfLoader;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from 'react';
|
|
2
|
-
import useLoadModel from './use-load-model';
|
|
3
|
-
|
|
4
|
-
const ModelContext = createContext({} as ReturnType<typeof useLoadModel>);
|
|
5
|
-
|
|
6
|
-
const ModelProvider = ({ children }: React.PropsWithChildren) => {
|
|
7
|
-
const value = useLoadModel();
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<ModelContext.Provider value={value}>{children}</ModelContext.Provider>
|
|
11
|
-
);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const useModelContext = () => {
|
|
15
|
-
return useContext(ModelContext);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export { ModelContext, ModelProvider, useModelContext };
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Action, ModelFileTypes, State } from './types';
|
|
2
|
-
|
|
3
|
-
// Initial state
|
|
4
|
-
export const initialState: State = {
|
|
5
|
-
file: null,
|
|
6
|
-
isFileLoading: false,
|
|
7
|
-
progress: 0,
|
|
8
|
-
supportedFileTypes: Object.values(ModelFileTypes),
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Reducer function for the useReadModelFiles hook
|
|
13
|
-
*
|
|
14
|
-
* @param state - The current state of the reducer
|
|
15
|
-
* @param action - The action to be performed
|
|
16
|
-
* @returns The updated state
|
|
17
|
-
*/
|
|
18
|
-
function reducer(state: State, action: Action): State {
|
|
19
|
-
switch (action.type) {
|
|
20
|
-
case 'SET_FILE':
|
|
21
|
-
return { ...state, file: action.payload };
|
|
22
|
-
case 'SET_FILE_LOADING':
|
|
23
|
-
return { ...state, isFileLoading: action.payload };
|
|
24
|
-
case 'SET_PROGRESS':
|
|
25
|
-
return { ...state, progress: action.payload };
|
|
26
|
-
case 'RESET_STATE':
|
|
27
|
-
return { ...initialState };
|
|
28
|
-
default:
|
|
29
|
-
return state;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default reducer;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Object3D } from 'three';
|
|
2
|
-
|
|
3
|
-
export enum ModelFileTypes {
|
|
4
|
-
gltf = 'gltf',
|
|
5
|
-
glb = 'glb',
|
|
6
|
-
usdz = 'usdz',
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type InputFileOrDirectory = (File | FileSystemDirectoryHandle)[];
|
|
10
|
-
|
|
11
|
-
export interface ReducedGltf {
|
|
12
|
-
images: { name: string; uri: string }[];
|
|
13
|
-
buffers: { bytelength: string; uri: string }[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ModelFile {
|
|
17
|
-
model: Object3D;
|
|
18
|
-
type: ModelFileTypes;
|
|
19
|
-
name: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Updated State interface
|
|
23
|
-
export interface State {
|
|
24
|
-
file: ModelFile | null;
|
|
25
|
-
isFileLoading: boolean;
|
|
26
|
-
progress: number;
|
|
27
|
-
supportedFileTypes: ModelFileTypes[];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Updated Action types
|
|
31
|
-
export type Action =
|
|
32
|
-
| { type: 'SET_FILE'; payload: ModelFile }
|
|
33
|
-
| { type: 'SET_FILE_LOADING'; payload: boolean }
|
|
34
|
-
| { type: 'SET_PROGRESS'; payload: number }
|
|
35
|
-
| { type: 'RESET_STATE' };
|
|
36
|
-
|
|
37
|
-
// Updated Event types
|
|
38
|
-
export type EventTypes =
|
|
39
|
-
| 'MULTIPLE_3D_MODELS'
|
|
40
|
-
| 'UNSUPPORTED_FILE_TYPE'
|
|
41
|
-
| 'UPLOAD_PROGRESS'
|
|
42
|
-
| 'UPLOAD_COMPLETE';
|
|
43
|
-
|
|
44
|
-
// Updated event data types
|
|
45
|
-
export type EventData = {
|
|
46
|
-
MULTIPLE_3D_MODELS: File[];
|
|
47
|
-
UNSUPPORTED_FILE_TYPE: File[];
|
|
48
|
-
UPLOAD_PROGRESS: number;
|
|
49
|
-
UPLOAD_COMPLETE: State['file'];
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Updated EventHandler type
|
|
53
|
-
export type EventHandler<T extends EventTypes> = (data: EventData[T]) => void;
|