@vctrl/hooks 0.9.5 → 0.16.2
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 +380 -0
- package/README.md +202 -383
- package/package.json +66 -55
- package/project.json +55 -0
- package/src/index.ts +38 -0
- package/src/use-export-model/use-export-model.ts +113 -0
- package/src/use-load-model/event-system.ts +46 -0
- package/src/use-load-model/index.ts +15 -0
- package/src/use-load-model/model-context.tsx +174 -0
- package/src/use-load-model/state.ts +75 -0
- package/src/use-load-model/types.ts +284 -0
- package/src/use-load-model/use-load-model.ts +682 -0
- package/src/use-load-model/utils/calculate-referenced-bytes.ts +123 -0
- package/src/use-load-model/utils/index.ts +7 -0
- package/src/use-load-model/utils/read-directory.ts +35 -0
- package/src/use-load-model/utils/reconstruct-files.ts +85 -0
- package/src/use-load-model/utils/resolve-scene-payload.ts +151 -0
- package/{use-optimize-model/index.d.ts → src/use-optimize-model/index.ts} +2 -1
- package/src/use-optimize-model/state.ts +40 -0
- package/src/use-optimize-model/types.ts +37 -0
- package/src/use-optimize-model/use-calc-optimization-info.ts +101 -0
- package/src/use-optimize-model/use-optimize-model.ts +467 -0
- package/src/use-optimize-model/utils/index.ts +29 -0
- package/src/use-optimize-model/utils/texture-optimization.ts +292 -0
- package/src/use-optimize-model/utils/validation.ts +62 -0
- package/src/utils/server-communication.ts +351 -0
- package/tsconfig.json +21 -0
- package/tsconfig.lib.json +16 -0
- package/vite.config.ts +77 -0
- package/GLTFExporter-BmLF430n.cjs +0 -18
- package/GLTFExporter-C4hCeb4H.js +0 -1263
- package/index.cjs.js +0 -1
- package/index.d.ts +0 -3
- package/index.es.js +0 -12
- package/model-context-CQJta_vi.cjs +0 -9
- package/model-context-D1Q8WdpT.js +0 -3431
- package/use-export-model/types.d.ts +0 -19
- package/use-export-model/use-export-model.d.ts +0 -14
- package/use-export-model/utils/data-uri-to-blob.d.ts +0 -9
- package/use-export-model/utils/export-handlers.d.ts +0 -23
- package/use-export-model/utils/file-helpers.d.ts +0 -17
- package/use-export-model/utils/index.d.ts +0 -3
- package/use-export-model-AFharGg5.js +0 -77
- package/use-export-model-CWcKp4A3.cjs +0 -1
- package/use-export-model.cjs.js +0 -1
- package/use-export-model.es.js +0 -4
- package/use-load-model/event-system.d.ts +0 -7
- package/use-load-model/file-type-hooks/index.d.ts +0 -2
- package/use-load-model/file-type-hooks/use-load-binary.d.ts +0 -11
- package/use-load-model/file-type-hooks/use-load-gltf.d.ts +0 -5
- package/use-load-model/index.d.ts +0 -3
- package/use-load-model/loaders/create-gltf-loader.d.ts +0 -3
- package/use-load-model/loaders/create-usdz-loader.d.ts +0 -3
- package/use-load-model/loaders/index.d.ts +0 -2
- package/use-load-model/model-context.d.ts +0 -78
- package/use-load-model/state.d.ts +0 -19
- package/use-load-model/types.d.ts +0 -51
- package/use-load-model/use-load-model.d.ts +0 -74
- package/use-load-model/utils/array-buffer-to-base64.d.ts +0 -2
- package/use-load-model/utils/index.d.ts +0 -2
- package/use-load-model/utils/read-directory.d.ts +0 -8
- package/use-load-model.cjs.js +0 -1
- package/use-load-model.es.js +0 -8
- package/use-optimize-model/state.d.ts +0 -13
- package/use-optimize-model/types.d.ts +0 -37
- package/use-optimize-model/use-optimize-model.d.ts +0 -29
- package/use-optimize-model-Cqkp__Vi.cjs +0 -1
- package/use-optimize-model-DZWIb_40.js +0 -127
- package/use-optimize-model.cjs.js +0 -1
- package/use-optimize-model.es.js +0 -4
- /package/{use-export-model/index.d.ts → src/use-export-model/index.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,444 +1,263 @@
|
|
|
1
|
-
# vctrl/hooks
|
|
2
|
-
|
|
3
|
-
[
|
|
4
|
-
](https://github.com/Vectreal/vectreal-core/actions/workflows/version-release.yaml)
|
|
5
|
-
[](https://www.npmjs.com/package/@vctrl/hooks)
|
|
6
|
-
|
|
7
|
-
> **Note**: This library is still undergoing heavy development until the first major version is released. This may lead to breaking changes in upcoming updates.
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
`@vctrl/hooks` is a React hooks package designed to simplify 3D model loading, optimization, and exporting within React applications. It's part of the [vectreal-core](https://github.com/vectreal/vectreal-core) ecosystem and is fully integrated into the [official website application](https://core.vectreal.com).
|
|
12
|
-
|
|
13
|
-
The package provides powerful hooks for:
|
|
14
|
-
|
|
15
|
-
- **Loading various 3D model file formats** (`useLoadModel`)
|
|
16
|
-
- **Optimizing 3D models** (`useOptimizeModel`)
|
|
17
|
-
- **Exporting 3D models from Three.js scenes** (`useExportModel`)
|
|
18
|
-
|
|
19
|
-
It also includes a React context (`ModelContext`) for easy state management and an event system for handling different stages of the model loading process.
|
|
20
|
-
|
|
21
|
-
### Table of Contents
|
|
22
|
-
|
|
23
|
-
- [vctrl/hooks](#vctrlhooks)
|
|
24
|
-
- [Overview](#overview)
|
|
25
|
-
- [Table of Contents](#table-of-contents)
|
|
26
|
-
- [Installation](#installation)
|
|
27
|
-
- [Hooks](#hooks)
|
|
28
|
-
- [useLoadModel](#useloadmodel)
|
|
29
|
-
- [Overview](#overview-1)
|
|
30
|
-
- [Features](#features)
|
|
31
|
-
- [Usage](#usage)
|
|
32
|
-
- [API Reference](#api-reference)
|
|
33
|
-
- [Optimization Integration](#optimization-integration)
|
|
34
|
-
- [useOptimizeModel](#useoptimizemodel)
|
|
35
|
-
- [Overview](#overview-2)
|
|
36
|
-
- [Features](#features-1)
|
|
37
|
-
- [Usage](#usage-1)
|
|
38
|
-
- [API Reference](#api-reference-1)
|
|
39
|
-
- [useExportModel](#useexportmodel)
|
|
40
|
-
- [Overview](#overview-3)
|
|
41
|
-
- [Features](#features-2)
|
|
42
|
-
- [Usage](#usage-2)
|
|
43
|
-
- [API Reference](#api-reference-2)
|
|
44
|
-
- [ModelContext](#modelcontext)
|
|
45
|
-
- [Common Concepts](#common-concepts)
|
|
46
|
-
- [Supported File Types](#supported-file-types)
|
|
47
|
-
- [File Loading Process](#file-loading-process)
|
|
48
|
-
- [State Management](#state-management)
|
|
49
|
-
- [Integration with Three.js](#integration-with-threejs)
|
|
50
|
-
- [Development](#development)
|
|
51
|
-
- [License](#license)
|
|
52
|
-
- [Contributing](#contributing)
|
|
53
|
-
- [Support](#support)
|
|
1
|
+
# @vctrl/hooks
|
|
54
2
|
|
|
55
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@vctrl/hooks)
|
|
4
|
+
|
|
5
|
+
Browser-side React hooks for loading, optimizing, and exporting 3D models. The runtime counterpart to [`@vctrl/core`](https://vectreal.com/docs/packages/core), built for React apps that need to handle 3D files directly in the browser.
|
|
56
6
|
|
|
57
|
-
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
58
10
|
|
|
59
11
|
```bash
|
|
60
12
|
npm install @vctrl/hooks
|
|
61
13
|
# or
|
|
62
|
-
|
|
14
|
+
pnpm add @vctrl/hooks
|
|
63
15
|
```
|
|
64
16
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
### useLoadModel
|
|
17
|
+
---
|
|
68
18
|
|
|
69
|
-
|
|
19
|
+
## Hooks overview
|
|
70
20
|
|
|
71
|
-
|
|
21
|
+
| Hook | Import path | Description |
|
|
22
|
+
| ------------------ | --------------------------------- | ------------------------------------------------------------------------------- |
|
|
23
|
+
| `useLoadModel` | `@vctrl/hooks/use-load-model` | Load and parse GLTF, GLB, and USDZ files from file lists or dropped directories |
|
|
24
|
+
| `useOptimizeModel` | `@vctrl/hooks/use-optimize-model` | Run glTF-Transform optimizations on loaded models |
|
|
25
|
+
| `useExportModel` | `@vctrl/hooks/use-export-model` | Export the current scene to GLB or glTF |
|
|
72
26
|
|
|
73
|
-
|
|
27
|
+
---
|
|
74
28
|
|
|
75
|
-
|
|
76
|
-
- Provides loading progress updates
|
|
77
|
-
- Emits events during the loading process
|
|
78
|
-
- Integrates with Three.js
|
|
79
|
-
- Supports multiple file uploads (e.g., `.gltf` with associated `.bin` and texture files)
|
|
80
|
-
- Integrates with `useOptimizeModel` for model optimization
|
|
81
|
-
- TypeScript support
|
|
29
|
+
## `useLoadModel`
|
|
82
30
|
|
|
83
|
-
|
|
31
|
+
Loads 3D files and exposes the parsed Three.js `Object3D` scene.
|
|
84
32
|
|
|
85
|
-
|
|
33
|
+
```tsx
|
|
34
|
+
import { ModelProvider, useLoadModel } from '@vctrl/hooks/use-load-model'
|
|
86
35
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
import { useLoadModel } from '@vctrl/hooks/use-load-model';
|
|
36
|
+
function Uploader() {
|
|
37
|
+
const { load, file, isFileLoading } = useLoadModel()
|
|
90
38
|
|
|
91
|
-
|
|
92
|
-
|
|
39
|
+
const handleDrop = (e: React.DragEvent) => {
|
|
40
|
+
e.preventDefault()
|
|
41
|
+
void load(Array.from(e.dataTransfer.files))
|
|
42
|
+
}
|
|
93
43
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
load(files);
|
|
97
|
-
};
|
|
44
|
+
if (isFileLoading) return <p>Loading...</p>
|
|
45
|
+
if (file?.model) return <p>Model loaded: {file.name}</p>
|
|
98
46
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
</div>
|
|
105
|
-
);
|
|
47
|
+
return (
|
|
48
|
+
<div onDrop={handleDrop} onDragOver={(e) => e.preventDefault()}>
|
|
49
|
+
Drop a file
|
|
50
|
+
</div>
|
|
51
|
+
)
|
|
106
52
|
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
> **Note**: Multiple files can be handled, e.g., when uploading a `.gltf` model along with its `.bin` file and relevant texture files (e.g., `.jpeg`, `.png`).
|
|
110
|
-
|
|
111
|
-
You can also use the `ModelProvider` and `useModelContext` to access the model state across your application:
|
|
112
53
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function App() {
|
|
120
|
-
return (
|
|
121
|
-
<ModelProvider>
|
|
122
|
-
<ModelConsumer />
|
|
123
|
-
</ModelProvider>
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// ModelConsumer.jsx
|
|
128
|
-
import React from 'react';
|
|
129
|
-
import { useModelContext } from '@vctrl/hooks/use-load-model';
|
|
130
|
-
|
|
131
|
-
function ModelConsumer() {
|
|
132
|
-
const { file, isLoading, progress, load } = useModelContext();
|
|
133
|
-
|
|
134
|
-
// Use the context values
|
|
135
|
-
return (
|
|
136
|
-
// ... your component logic
|
|
137
|
-
);
|
|
54
|
+
export default function App() {
|
|
55
|
+
return (
|
|
56
|
+
<ModelProvider>
|
|
57
|
+
<Uploader />
|
|
58
|
+
</ModelProvider>
|
|
59
|
+
)
|
|
138
60
|
}
|
|
139
61
|
```
|
|
140
62
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
63
|
+
### Context and direct usage
|
|
64
|
+
|
|
65
|
+
`useLoadModel` can be used in two ways:
|
|
66
|
+
|
|
67
|
+
1. Context mode: wrap your app with `ModelProvider`, then consume with `useModelContext()` anywhere in that tree.
|
|
68
|
+
2. Direct mode: call `useLoadModel()` outside a provider to manage a local model state.
|
|
69
|
+
|
|
70
|
+
### Return values
|
|
71
|
+
|
|
72
|
+
| Value | Type | Description |
|
|
73
|
+
| -------------------------- | ------------------------------------ | ----------------------------------------------------------- |
|
|
74
|
+
| `file` | `ModelFile \| null` | Loaded file metadata and Three.js model |
|
|
75
|
+
| `isFileLoading` | `boolean` | True while loading and parsing |
|
|
76
|
+
| `progress` | `number` | Progress value from 0 to 100 |
|
|
77
|
+
| `load(filesOrDirectories)` | `Promise<void>` | Load files or dropped `FileSystemDirectoryHandle` entries |
|
|
78
|
+
| `loadFromData(options)` | `Promise<SceneLoadResult>` | Load already-resolved server scene payload |
|
|
79
|
+
| `loadFromServer(options)` | `Promise<SceneLoadResult>` | Fetch and load scene from an API endpoint |
|
|
80
|
+
| `reset` | `() => void` | Clear the current model |
|
|
81
|
+
| `on` / `off` | Event helpers | Subscribe and unsubscribe to loader lifecycle events |
|
|
82
|
+
| `optimizer` | `OptimizerIntegrationReturn \| null` | Populated when the hook is called with `useOptimizeModel()` |
|
|
83
|
+
|
|
84
|
+
### `useLoadModel` events
|
|
85
|
+
|
|
86
|
+
`on` and `off` support these typed events:
|
|
87
|
+
|
|
88
|
+
| Event | Payload |
|
|
89
|
+
| ---------------------- | ------------------- |
|
|
90
|
+
| `multiple-models` | `File[]` |
|
|
91
|
+
| `not-loaded-files` | `File[]` |
|
|
92
|
+
| `load-start` | `null` |
|
|
93
|
+
| `load-progress` | `number` |
|
|
94
|
+
| `load-complete` | `ModelFile \| null` |
|
|
95
|
+
| `load-reset` | `null` |
|
|
96
|
+
| `load-error` | `Error \| unknown` |
|
|
97
|
+
| `server-load-start` | `string` |
|
|
98
|
+
| `server-load-complete` | `SceneLoadResult` |
|
|
99
|
+
| `server-load-error` | `Error \| unknown` |
|
|
100
|
+
|
|
101
|
+
### Scene loading option types
|
|
102
|
+
|
|
103
|
+
`loadFromServer(options)` uses:
|
|
104
|
+
|
|
105
|
+
| Field | Type | Description |
|
|
106
|
+
| --------------- | --------------- | --------------------------------------------- |
|
|
107
|
+
| `sceneId` | `string` | Scene identifier to fetch |
|
|
108
|
+
| `serverOptions` | `ServerOptions` | Endpoint, auth, and header configuration |
|
|
109
|
+
| `applySettings` | `boolean` | Whether scene settings are applied after load |
|
|
110
|
+
|
|
111
|
+
`loadFromData(options)` uses:
|
|
112
|
+
|
|
113
|
+
| Field | Type | Description |
|
|
114
|
+
| --------------- | --------------------- | -------------------------------------------------------------- |
|
|
115
|
+
| `sceneId` | `string \| undefined` | Optional scene identifier |
|
|
116
|
+
| `sceneData` | `ServerSceneData` | Already-resolved payload containing glTF, settings, and assets |
|
|
117
|
+
| `applySettings` | `boolean` | Whether scene settings are applied after load |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## `useOptimizeModel`
|
|
122
|
+
|
|
123
|
+
Runs mesh simplification and texture compression using [glTF-Transform](https://gltf-transform.dev) in a Web Worker.
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
import { useOptimizeModel } from '@vctrl/hooks/use-optimize-model'
|
|
127
|
+
import { useLoadModel } from '@vctrl/hooks/use-load-model'
|
|
128
|
+
|
|
129
|
+
function Optimizer() {
|
|
130
|
+
const optimizer = useOptimizeModel()
|
|
131
|
+
const { file, optimizer: integrated } = useLoadModel(optimizer)
|
|
132
|
+
|
|
133
|
+
const handleOptimize = async () => {
|
|
134
|
+
if (!file?.model || !integrated) return
|
|
135
|
+
await integrated.applyOptimization(integrated.simplifyOptimization, {
|
|
136
|
+
ratio: 0.6,
|
|
137
|
+
error: 0.001
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<button onClick={handleOptimize} disabled={optimizer.loading}>
|
|
143
|
+
{optimizer.loading ? 'Optimizing...' : 'Optimize model'}
|
|
144
|
+
</button>
|
|
145
|
+
)
|
|
177
146
|
}
|
|
178
147
|
```
|
|
179
148
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
- `simplifyOptimization(options)`: Simplifies the model using mesh simplification.
|
|
183
|
-
- `dedupOptimization(options)`: Removes duplicate vertices and meshes.
|
|
184
|
-
- `quantizeOptimization(options)`: Reduces the precision of vertex attributes.
|
|
185
|
-
- `normalsOptimization(options)`: Overrides the normals of each object in the scene.
|
|
186
|
-
- `texturesCompressionOptimization(options)`: Compresses the relevant textures in the model file using texture compression.
|
|
187
|
-
|
|
188
|
-
### useOptimizeModel
|
|
189
|
-
|
|
190
|
-
#### Overview
|
|
191
|
-
|
|
192
|
-
`useOptimizeModel` is a React hook used to optimize 3D models, particularly GLTF-based scenes. It can be used in conjunction with `useLoadModel` or independently.
|
|
193
|
-
|
|
194
|
-
#### Features
|
|
195
|
-
|
|
196
|
-
- Simplifies 3D models using mesh optimization algorithms
|
|
197
|
-
- Provides deduplication and quantization optimizations
|
|
198
|
-
- Integrates with `useLoadModel` and `ModelContext`
|
|
199
|
-
- TypeScript support
|
|
200
|
-
|
|
201
|
-
#### Usage
|
|
202
|
-
|
|
203
|
-
There are two ways to use the `useOptimizeModel` hook:
|
|
204
|
-
|
|
205
|
-
1. **Directly with `useLoadModel`**
|
|
206
|
-
|
|
207
|
-
```jsx
|
|
208
|
-
import React from 'react';
|
|
209
|
-
import { useLoadModel } from '@vctrl/hooks/use-load-model';
|
|
210
|
-
import { useOptimizeModel } from '@vctrl/hooks/use-optimize-model';
|
|
211
|
-
|
|
212
|
-
function ModelLoader() {
|
|
213
|
-
const optimizer = useOptimizeModel();
|
|
214
|
-
const { load, file, optimize } = useLoadModel(optimizer);
|
|
215
|
-
|
|
216
|
-
const handleSimplify = async () => {
|
|
217
|
-
await optimize.simplifyOptimization();
|
|
218
|
-
// The optimized model is now in file.model
|
|
219
|
-
};
|
|
149
|
+
### Key API surface
|
|
220
150
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
151
|
+
| Method / State | Type | Description |
|
|
152
|
+
| ------------------------------------ | ------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
153
|
+
| `load(model)` | `(model: Object3D) => Promise<void>` | Load a Three.js scene into the optimizer |
|
|
154
|
+
| `loadFromServerSceneData(sceneData)` | `Promise<void>` | Initialize optimizer from a server scene payload |
|
|
155
|
+
| `applyOptimization(fn, opts?)` | `<T>(fn?: (opts?: T) => Promise<void>, opts?: T) => Promise<void>` | Apply optimization and sync the optimized model back into loader state |
|
|
156
|
+
| `simplifyOptimization(options?)` | `Promise<void>` | Simplify mesh geometry |
|
|
157
|
+
| `dedupOptimization(options?)` | `Promise<void>` | Deduplicate model data |
|
|
158
|
+
| `quantizeOptimization(options?)` | `Promise<void>` | Quantize vertex attributes |
|
|
159
|
+
| `normalsOptimization(options?)` | `Promise<void>` | Recompute or normalize normals |
|
|
160
|
+
| `texturesOptimization(options?)` | `Promise<void>` | Run texture compression flow |
|
|
161
|
+
| `getModel()` | `Promise<Uint8Array \| null>` | Export the current optimized model as GLB binary |
|
|
162
|
+
| `report` / `info` | Objects | Optimization metrics and derived stats |
|
|
163
|
+
| `loading` / `error` | State | Optimization status |
|
|
224
164
|
|
|
225
|
-
|
|
226
|
-
await optimize.quantizeOptimization();
|
|
227
|
-
};
|
|
165
|
+
### Optimization option types
|
|
228
166
|
|
|
229
|
-
|
|
230
|
-
<div>
|
|
231
|
-
<input
|
|
232
|
-
type="file"
|
|
233
|
-
onChange={(e) => load(Array.from(e.target.files))}
|
|
234
|
-
multiple
|
|
235
|
-
/>
|
|
236
|
-
<button onClick={handleSimplify}>Simplify Model</button>
|
|
237
|
-
<button onClick={handleDedup}>Deduplicate Model</button>
|
|
238
|
-
<button onClick={handleQuantize}>Quantize Model</button>
|
|
239
|
-
</div>
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
```
|
|
167
|
+
`useOptimizeModel` methods map directly to `@vctrl/core/model-optimizer` option types:
|
|
243
168
|
|
|
244
|
-
|
|
169
|
+
| Method | Option fields |
|
|
170
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
171
|
+
| `simplifyOptimization` | `ratio?: number`, `error?: number` |
|
|
172
|
+
| `dedupOptimization` | `textures?: boolean`, `materials?: boolean`, `meshes?: boolean`, `accessors?: boolean` |
|
|
173
|
+
| `quantizeOptimization` | `quantizePosition?: number`, `quantizeNormal?: number`, `quantizeColor?: number`, `quantizeTexcoord?: number` |
|
|
174
|
+
| `normalsOptimization` | `overwrite?: boolean` |
|
|
175
|
+
| `texturesOptimization` | `resize?: [number, number]`, `targetFormat?: 'webp' \| 'jpeg' \| 'png'`, `quality?: number`, `requestTimeoutMs?: number`, `maxTextureUploadBytes?: number`, `maxRetries?: number`, `maxConcurrentRequests?: number`, `serverOptions?: ServerOptions` |
|
|
245
176
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
```jsx
|
|
249
|
-
// App.jsx
|
|
250
|
-
import React from 'react';
|
|
251
|
-
import { ModelProvider } from '@vctrl/hooks/use-load-model';
|
|
252
|
-
import { useOptimizeModel } from '@vctrl/hooks/use-optimize-model';
|
|
253
|
-
import Scene from './Scene';
|
|
254
|
-
|
|
255
|
-
function App() {
|
|
256
|
-
const optimizer = useOptimizeModel();
|
|
257
|
-
|
|
258
|
-
return (
|
|
259
|
-
<ModelProvider optimizer={optimizer}>
|
|
260
|
-
<Scene />
|
|
261
|
-
</ModelProvider>
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Scene.jsx
|
|
266
|
-
import React from 'react';
|
|
267
|
-
import { useModelContext } from '@vctrl/hooks/use-load-model';
|
|
268
|
-
|
|
269
|
-
function Scene() {
|
|
270
|
-
const { optimize } = useModelContext();
|
|
271
|
-
|
|
272
|
-
const handleSimplify = async () => {
|
|
273
|
-
await optimize.simplifyOptimization();
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
const handleDedup = async () => {
|
|
277
|
-
await optimize.dedupOptimization();
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const handleQuantize = async () => {
|
|
281
|
-
await optimize.quantizeOptimization();
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
return (
|
|
285
|
-
<div>
|
|
286
|
-
<button onClick={handleSimplify}>Simplify Model</button>
|
|
287
|
-
<button onClick={handleDedup}>Deduplicate Model</button>
|
|
288
|
-
<button onClick={handleQuantize}>Quantize Model</button>
|
|
289
|
-
</div>
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
#### API Reference
|
|
295
|
-
|
|
296
|
-
The `useOptimizeModel` hook returns the following:
|
|
297
|
-
|
|
298
|
-
- `load(model)`: Loads a Three.js `Object3D` model into the optimizer.
|
|
299
|
-
- `getModel()`: Retrieves the optimized model as a binary array buffer.
|
|
300
|
-
- `simplifyOptimization(options)`: Simplifies the current model using the `MeshoptSimplifier`.
|
|
301
|
-
- `dedupOptimization(options)`: Removes duplicate vertices and meshes.
|
|
302
|
-
- `quantizeOptimization(options)`: Reduces the precision of vertex attributes.
|
|
303
|
-
- `normalsOptimization`: Overrides normals
|
|
304
|
-
- `texturesOptimization(options)`: Compresses related textures.
|
|
305
|
-
- `getSize()`: Object with byte size of gltf scene and a formatted megabyte string
|
|
306
|
-
- `reset()`: Resets the current optimizer model and report state.
|
|
307
|
-
- `report`: @gltf-transform gltf report object with relevant details about a gltf scene
|
|
308
|
-
- `error`: Stores any possible optimization errors
|
|
309
|
-
- `loading`: Boolean for when the model is being loaded
|
|
310
|
-
|
|
311
|
-
### useExportModel
|
|
312
|
-
|
|
313
|
-
#### Overview
|
|
314
|
-
|
|
315
|
-
`useExportModel` is a React hook for exporting 3D models from a Three.js scene.
|
|
316
|
-
|
|
317
|
-
#### Features
|
|
318
|
-
|
|
319
|
-
- Exports models in GLTF or GLB format
|
|
320
|
-
- Handles embedded resources and textures
|
|
321
|
-
- Integrates with Three.js scenes
|
|
322
|
-
- TypeScript support
|
|
323
|
-
|
|
324
|
-
#### Usage
|
|
325
|
-
|
|
326
|
-
```jsx
|
|
327
|
-
import React from 'react';
|
|
328
|
-
import { useExportModel } from '@vctrl/hooks/use-export-model';
|
|
329
|
-
|
|
330
|
-
function ExportButton({ file }) {
|
|
331
|
-
const { handleGltfExport } = useExportModel(
|
|
332
|
-
() => console.log('Export complete'),
|
|
333
|
-
(error) => console.error('Export error:', error),
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
const exportAsGlb = () => {
|
|
337
|
-
handleGltfExport(file, true); // Export as GLB (binary)
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
const exportAsGltf = () => {
|
|
341
|
-
handleGltfExport(file, false); // Export as GLTF
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
return (
|
|
345
|
-
<div>
|
|
346
|
-
<button onClick={exportAsGlb}>Export as GLB</button>
|
|
347
|
-
<button onClick={exportAsGltf}>Export as GLTF</button>
|
|
348
|
-
</div>
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
#### API Reference
|
|
177
|
+
`serverOptions` is provided by `@vctrl/core` and supports endpoint, API key, and headers.
|
|
354
178
|
|
|
355
|
-
|
|
179
|
+
---
|
|
356
180
|
|
|
357
|
-
|
|
358
|
-
- `file`: The `ModelFile` object to export.
|
|
359
|
-
- `binary`: A boolean indicating whether to export in binary format (`true` for GLB, `false` for GLTF).
|
|
360
|
-
- The function exports the model and triggers file download.
|
|
181
|
+
## `useExportModel`
|
|
361
182
|
|
|
362
|
-
|
|
183
|
+
Exports the current scene from `ModelProvider` context to a downloadable file.
|
|
363
184
|
|
|
364
|
-
|
|
185
|
+
```tsx
|
|
186
|
+
import { useExportModel } from '@vctrl/hooks/use-export-model'
|
|
187
|
+
import type { ModelFile } from '@vctrl/hooks/use-load-model'
|
|
365
188
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
function App() {
|
|
370
|
-
return (
|
|
371
|
-
<ModelProvider>
|
|
372
|
-
<ModelConsumer />
|
|
373
|
-
</ModelProvider>
|
|
374
|
-
);
|
|
375
|
-
}
|
|
189
|
+
function ExportButton({ file }: { file: ModelFile | null }) {
|
|
190
|
+
const { handleThreeGltfExport } = useExportModel()
|
|
376
191
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
192
|
+
return (
|
|
193
|
+
<button onClick={() => void handleThreeGltfExport(file, true)}>
|
|
194
|
+
Download GLB
|
|
195
|
+
</button>
|
|
196
|
+
)
|
|
380
197
|
}
|
|
381
198
|
```
|
|
382
199
|
|
|
383
|
-
|
|
200
|
+
### Methods
|
|
384
201
|
|
|
385
|
-
|
|
202
|
+
| Method | Description |
|
|
203
|
+
| -------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
204
|
+
| `handleThreeGltfExport(file, binary)` | Export a loaded Three.js model to `.glb` or a zipped `.gltf` bundle |
|
|
205
|
+
| `handleDocumentGltfExport(document, file, binary?, download?)` | Export from a glTF-Transform `Document` |
|
|
386
206
|
|
|
387
|
-
|
|
207
|
+
`binary = true` writes `.glb`; `binary = false` writes a zipped `.gltf` package.
|
|
388
208
|
|
|
389
|
-
|
|
209
|
+
---
|
|
390
210
|
|
|
391
|
-
|
|
392
|
-
- GLB (`.glb`)
|
|
393
|
-
- USDZ (`.usdz`)
|
|
211
|
+
## Additional exports
|
|
394
212
|
|
|
395
|
-
|
|
213
|
+
- `ServerCommunicationService` from `@vctrl/hooks`
|
|
214
|
+
- `reconstructGltfFiles` from `@vctrl/hooks`
|
|
215
|
+
- `ModelProvider` and `useModelContext` from `@vctrl/hooks/use-load-model`
|
|
216
|
+
- Shared types such as `ModelFile`, `SceneLoadResult`, and `ServerSceneData`
|
|
396
217
|
|
|
397
|
-
|
|
218
|
+
`ServerCommunicationService` methods:
|
|
398
219
|
|
|
399
|
-
|
|
220
|
+
| Method | Description |
|
|
221
|
+
| -------------------------------------------------- | ------------------------- |
|
|
222
|
+
| `request(config)` | Generic request helper |
|
|
223
|
+
| `get(endpoint, serverOptions?)` | Convenience GET |
|
|
224
|
+
| `post(endpoint, body, serverOptions?)` | Convenience JSON POST |
|
|
225
|
+
| `postFormData(endpoint, formData, serverOptions?)` | Convenience FormData POST |
|
|
400
226
|
|
|
401
|
-
|
|
402
|
-
2. Embedding external resources (buffers and images) into the GLTF content.
|
|
403
|
-
3. Using Three.js `GLTFLoader` to parse the modified GLTF content.
|
|
404
|
-
4. Updating the state with the loaded model.
|
|
405
|
-
5. Integrating with the optimizer if provided.
|
|
227
|
+
`ServerRequestConfig` fields:
|
|
406
228
|
|
|
407
|
-
|
|
229
|
+
| Field | Type |
|
|
230
|
+
| --------------- | ------------------------------------------------- |
|
|
231
|
+
| `endpoint` | `string` |
|
|
232
|
+
| `method` | `'GET' \| 'POST' \| 'PUT' \| 'DELETE' \| 'PATCH'` |
|
|
233
|
+
| `body` | `FormData \| Record<string, unknown> \| string` |
|
|
234
|
+
| `serverOptions` | `ServerOptions` |
|
|
235
|
+
| `contentType` | `string` |
|
|
408
236
|
|
|
409
|
-
|
|
237
|
+
---
|
|
410
238
|
|
|
411
|
-
|
|
239
|
+
## Peer dependencies
|
|
412
240
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
241
|
+
| Package | Version |
|
|
242
|
+
| -------------------- | -------------- |
|
|
243
|
+
| `react` | `^18 \|\| ^19` |
|
|
244
|
+
| `three` | `^0.170` |
|
|
245
|
+
| `@react-three/fiber` | `^9` |
|
|
417
246
|
|
|
418
|
-
|
|
247
|
+
---
|
|
419
248
|
|
|
420
|
-
|
|
249
|
+
## Related docs
|
|
421
250
|
|
|
422
|
-
|
|
251
|
+
- [Uploading Models](https://vectreal.com/docs/guides/upload)
|
|
252
|
+
- [Optimizing & Configuring](https://vectreal.com/docs/guides/optimize)
|
|
253
|
+
- [@vctrl/viewer](https://vectreal.com/docs/packages/viewer)
|
|
423
254
|
|
|
424
|
-
|
|
255
|
+
---
|
|
425
256
|
|
|
426
|
-
|
|
257
|
+
## Source
|
|
427
258
|
|
|
428
|
-
|
|
429
|
-
2. Install dependencies: `npm install` or `yarn install`.
|
|
430
|
-
3. Make your changes.
|
|
431
|
-
4. Build the package: `nx build vctrl/hooks`.
|
|
432
|
-
5. Test your changes: `nx test vctrl/hooks`.
|
|
259
|
+
The full source and README live in [packages/hooks](https://github.com/Vectreal/vectreal-platform/tree/main/packages/hooks).
|
|
433
260
|
|
|
434
261
|
## License
|
|
435
262
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
## Contributing
|
|
439
|
-
|
|
440
|
-
Contributions are welcome! Please read the contributing guidelines in the [vectreal-core](https://github.com/vectreal/vectreal-core) monorepo before submitting pull requests.
|
|
441
|
-
|
|
442
|
-
## Support
|
|
443
|
-
|
|
444
|
-
For issues, feature requests, or questions, please file an issue in the [GitHub repository](https://github.com/vectreal/vectreal-core/issues).
|
|
263
|
+
AGPL-3.0-only. See [LICENSE.md](https://github.com/Vectreal/vectreal-platform/blob/main/packages/hooks/LICENSE.md).
|