Add external triangle scene GLTF and update file import handling
This commit is contained in:
65
fixtures/assets/external-triangle/scene.gltf
Normal file
65
fixtures/assets/external-triangle/scene.gltf
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"asset": {
|
||||||
|
"version": "2.0",
|
||||||
|
"generator": "webeditor3d fixture"
|
||||||
|
},
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
"name": "External Triangle Scene",
|
||||||
|
"nodes": [0]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"mesh": 0,
|
||||||
|
"name": "External Triangle Node"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes": [
|
||||||
|
{
|
||||||
|
"name": "External Triangle Mesh",
|
||||||
|
"primitives": [
|
||||||
|
{
|
||||||
|
"attributes": {
|
||||||
|
"POSITION": 0
|
||||||
|
},
|
||||||
|
"material": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"materials": [
|
||||||
|
{
|
||||||
|
"name": "External Material",
|
||||||
|
"pbrMetallicRoughness": {
|
||||||
|
"baseColorFactor": [0.2, 0.6, 0.85, 1],
|
||||||
|
"metallicFactor": 0,
|
||||||
|
"roughnessFactor": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"byteLength": 36,
|
||||||
|
"uri": "triangle.bin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bufferViews": [
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteOffset": 0,
|
||||||
|
"byteLength": 36
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accessors": [
|
||||||
|
{
|
||||||
|
"bufferView": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 3,
|
||||||
|
"type": "VEC3",
|
||||||
|
"min": [0, 0, 0],
|
||||||
|
"max": [1, 1, 0]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ import {
|
|||||||
} from "../assets/model-instance-labels";
|
} from "../assets/model-instance-labels";
|
||||||
import {
|
import {
|
||||||
importModelAssetFromFile,
|
importModelAssetFromFile,
|
||||||
|
importModelAssetFromFiles,
|
||||||
loadModelAssetFromStorage,
|
loadModelAssetFromStorage,
|
||||||
disposeModelTemplate,
|
disposeModelTemplate,
|
||||||
type ImportedModelAssetResult,
|
type ImportedModelAssetResult,
|
||||||
@@ -1938,9 +1939,9 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
|
|
||||||
const handleImportModelChange = async (event: ChangeEvent<HTMLInputElement>) => {
|
const handleImportModelChange = async (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
const input = event.currentTarget;
|
const input = event.currentTarget;
|
||||||
const file = input.files?.[0];
|
const files = Array.from(input.files ?? []);
|
||||||
|
|
||||||
if (file === undefined) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1953,7 +1954,9 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
let importedModelForCleanup: ImportedModelAssetResult | null = null;
|
let importedModelForCleanup: ImportedModelAssetResult | null = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const importedModel = await importModelAssetFromFile(file, projectAssetStorage);
|
const importedModel = files.length === 1
|
||||||
|
? await importModelAssetFromFile(files[0], projectAssetStorage)
|
||||||
|
: await importModelAssetFromFiles(files, projectAssetStorage);
|
||||||
importedModelForCleanup = importedModel;
|
importedModelForCleanup = importedModel;
|
||||||
|
|
||||||
store.executeCommand(
|
store.executeCommand(
|
||||||
@@ -4014,6 +4017,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
ref={importModelInputRef}
|
ref={importModelInputRef}
|
||||||
className="visually-hidden"
|
className="visually-hidden"
|
||||||
type="file"
|
type="file"
|
||||||
|
multiple
|
||||||
accept=".glb,.gltf,model/gltf-binary,model/gltf+json,application/octet-stream"
|
accept=".glb,.gltf,model/gltf-binary,model/gltf+json,application/octet-stream"
|
||||||
onChange={handleImportModelChange}
|
onChange={handleImportModelChange}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -4,21 +4,31 @@ import { createProjectAssetStorageKey } from "../../src/assets/project-assets";
|
|||||||
import { createInMemoryProjectAssetStorage } from "../../src/assets/project-asset-storage";
|
import { createInMemoryProjectAssetStorage } from "../../src/assets/project-asset-storage";
|
||||||
|
|
||||||
describe("project asset storage", () => {
|
describe("project asset storage", () => {
|
||||||
it("stores, clones, and deletes binary asset payloads", async () => {
|
it("stores, clones, and deletes binary asset file packages", async () => {
|
||||||
const storage = createInMemoryProjectAssetStorage();
|
const storage = createInMemoryProjectAssetStorage();
|
||||||
const storageKey = createProjectAssetStorageKey("asset-model-triangle");
|
const storageKey = createProjectAssetStorageKey("asset-model-triangle");
|
||||||
const bytes = new Uint8Array([0, 1, 2, 3, 4]).buffer;
|
const bytes = new Uint8Array([0, 1, 2, 3, 4]).buffer;
|
||||||
|
const sidecarBytes = new Uint8Array([9, 8, 7]).buffer;
|
||||||
|
|
||||||
await storage.putAsset(storageKey, {
|
await storage.putAsset(storageKey, {
|
||||||
bytes,
|
files: {
|
||||||
mimeType: "model/gltf+json"
|
"tiny-triangle.gltf": {
|
||||||
|
bytes,
|
||||||
|
mimeType: "model/gltf+json"
|
||||||
|
},
|
||||||
|
"triangle.bin": {
|
||||||
|
bytes: sidecarBytes,
|
||||||
|
mimeType: "application/octet-stream"
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadedAsset = await storage.getAsset(storageKey);
|
const loadedAsset = await storage.getAsset(storageKey);
|
||||||
|
|
||||||
expect(loadedAsset).not.toBeNull();
|
expect(loadedAsset).not.toBeNull();
|
||||||
expect(loadedAsset?.mimeType).toBe("model/gltf+json");
|
expect(Object.keys(loadedAsset?.files ?? {})).toEqual(["tiny-triangle.gltf", "triangle.bin"]);
|
||||||
expect(Array.from(new Uint8Array(loadedAsset?.bytes ?? new ArrayBuffer(0)))).toEqual([0, 1, 2, 3, 4]);
|
expect(Array.from(new Uint8Array(loadedAsset?.files["tiny-triangle.gltf"].bytes ?? new ArrayBuffer(0)))).toEqual([0, 1, 2, 3, 4]);
|
||||||
|
expect(Array.from(new Uint8Array(loadedAsset?.files["triangle.bin"].bytes ?? new ArrayBuffer(0)))).toEqual([9, 8, 7]);
|
||||||
|
|
||||||
await storage.deleteAsset(storageKey);
|
await storage.deleteAsset(storageKey);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user