@treasuryspatial/viewer-kit 0.2.45 → 0.2.50
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/dist/autoGenerate.d.ts.map +1 -1
- package/dist/autoGenerate.js +7 -1
- package/dist/camera.d.ts +1 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +8 -1
- package/dist/engine/ViewerEngine.d.ts +20 -0
- package/dist/engine/ViewerEngine.d.ts.map +1 -1
- package/dist/engine/ViewerEngine.js +254 -63
- package/dist/engine/types.d.ts +69 -3
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/exports/download.d.ts +6 -0
- package/dist/exports/download.d.ts.map +1 -1
- package/dist/exports/download.js +142 -0
- package/dist/exports/three-export.d.ts +4 -1
- package/dist/exports/three-export.d.ts.map +1 -1
- package/dist/exports/three-export.js +138 -4
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/materials/architectural.d.ts +3 -3
- package/dist/materials/architectural.d.ts.map +1 -1
- package/dist/materials/architectural.js +295 -37
- package/dist/materials/catalogue-data.d.ts +15 -0
- package/dist/materials/catalogue-data.d.ts.map +1 -1
- package/dist/materials/catalogue-data.js +16 -0
- package/dist/materials/presets.d.ts +15 -8
- package/dist/materials/presets.d.ts.map +1 -1
- package/dist/materials/presets.js +140 -39
- package/dist/materials/resolve.d.ts +42 -0
- package/dist/materials/resolve.d.ts.map +1 -1
- package/dist/materials/resolve.js +228 -13
- package/dist/materials/types.d.ts +32 -3
- package/dist/materials/types.d.ts.map +1 -1
- package/dist/presets/defaults.d.ts.map +1 -1
- package/dist/presets/defaults.js +17 -1
- package/dist/presets/sciencePresets.d.ts.map +1 -1
- package/dist/presets/sciencePresets.js +167 -50
- package/dist/scene.d.ts +28 -4
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +196 -31
- package/dist/sceneSemanticRegistry.d.ts +64 -0
- package/dist/sceneSemanticRegistry.d.ts.map +1 -0
- package/dist/sceneSemanticRegistry.js +199 -0
- package/dist/sky/scienceSky.d.ts.map +1 -1
- package/dist/sky/scienceSky.js +16 -0
- package/dist/systems/debugSystem.d.ts +24 -1
- package/dist/systems/debugSystem.d.ts.map +1 -1
- package/dist/systems/debugSystem.js +324 -77
- package/dist/systems/environmentSystem.d.ts +5 -4
- package/dist/systems/environmentSystem.d.ts.map +1 -1
- package/dist/systems/environmentSystem.js +138 -62
- package/dist/systems/lightingSystem.d.ts +10 -1
- package/dist/systems/lightingSystem.d.ts.map +1 -1
- package/dist/systems/lightingSystem.js +118 -17
- package/dist/systems/postfxSystem.d.ts +5 -1
- package/dist/systems/postfxSystem.d.ts.map +1 -1
- package/dist/systems/postfxSystem.js +84 -1
- package/dist/systems/rendererSystem.d.ts.map +1 -1
- package/dist/systems/rendererSystem.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/uploads/geometry3dm.d.ts.map +1 -1
- package/dist/uploads/geometry3dm.js +1 -0
- package/dist/uploads/grasshopper.d.ts.map +1 -1
- package/dist/uploads/grasshopper.js +63 -5
- package/dist/uploads/mesh.js +5 -5
- package/dist/uploads/types.d.ts +4 -0
- package/dist/uploads/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
|
-
import type { MaterialId, MaterialsConfig, SurfaceMaterialConfig } from "./types";
|
|
2
|
+
import type { MaterialApplicationPolicy, MaterialId, MaterialSurfaceRole, MaterialsConfig, SurfaceMaterialConfig } from "./types";
|
|
3
3
|
export declare const setTextureBaseUrl: (baseUrl?: string) => void;
|
|
4
|
-
export declare function buildSurfaceMaterial(surface:
|
|
4
|
+
export declare function buildSurfaceMaterial(surface: MaterialSurfaceRole | string, config: SurfaceMaterialConfig): THREE.MeshStandardMaterial;
|
|
5
5
|
export declare function buildCatalogMaterial(materialId: MaterialId, overrides?: Partial<SurfaceMaterialConfig>): THREE.MeshStandardMaterial;
|
|
6
|
-
export declare function applyMaterialsToGroup(group: THREE.Group, materialsConfig?: MaterialsConfig | null, floorLevel?: number, ceilingHeight?: number): void;
|
|
6
|
+
export declare function applyMaterialsToGroup(group: THREE.Group, materialsConfig?: MaterialsConfig | null, floorLevel?: number, ceilingHeight?: number, policy?: MaterialApplicationPolicy): void;
|
|
7
7
|
//# sourceMappingURL=architectural.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"architectural.d.ts","sourceRoot":"","sources":["../../src/materials/architectural.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"architectural.d.ts","sourceRoot":"","sources":["../../src/materials/architectural.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EACV,yBAAyB,EACzB,UAAU,EACV,mBAAmB,EACnB,eAAe,EAEf,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAcjB,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,SAMjD,CAAC;AAsHF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,EAAE,MAAM,EAAE,qBAAqB,8BAExG;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,8BAiBtG;AAqND,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,EACxC,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,MAAM,GAAE,yBAA8B,GACrC,IAAI,CA6JN"}
|
|
@@ -4,6 +4,7 @@ import { getRenderMaterialMetadata } from "./renderMetadata";
|
|
|
4
4
|
const clamp01 = (value) => Math.min(Math.max(value, 0), 1);
|
|
5
5
|
const colorFromRGB = (rgb) => new THREE.Color(rgb.r / 255, rgb.g / 255, rgb.b / 255);
|
|
6
6
|
const textureLoader = new THREE.TextureLoader();
|
|
7
|
+
textureLoader.setCrossOrigin("anonymous");
|
|
7
8
|
const textureCache = new Map();
|
|
8
9
|
let textureBaseUrl = "";
|
|
9
10
|
export const setTextureBaseUrl = (baseUrl) => {
|
|
@@ -112,6 +113,16 @@ const buildMaterial = (surface, config) => {
|
|
|
112
113
|
material.name = `${surface}-material`;
|
|
113
114
|
return material;
|
|
114
115
|
};
|
|
116
|
+
const buildFallbackMaterial = () => new THREE.MeshStandardMaterial({
|
|
117
|
+
color: new THREE.Color("#d6d9e0"),
|
|
118
|
+
roughness: 0.72,
|
|
119
|
+
metalness: 0.02,
|
|
120
|
+
emissive: new THREE.Color("#eef1f7"),
|
|
121
|
+
emissiveIntensity: 0.02,
|
|
122
|
+
depthWrite: true,
|
|
123
|
+
depthTest: true,
|
|
124
|
+
side: THREE.DoubleSide,
|
|
125
|
+
});
|
|
115
126
|
export function buildSurfaceMaterial(surface, config) {
|
|
116
127
|
return buildMaterial(surface, config);
|
|
117
128
|
}
|
|
@@ -133,55 +144,302 @@ export function buildCatalogMaterial(materialId, overrides) {
|
|
|
133
144
|
};
|
|
134
145
|
return buildMaterial(materialId, config);
|
|
135
146
|
}
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const isBroadHorizontal = dy <= 0.35 && dx >= 0.8 && dz >= 0.8;
|
|
143
|
-
if (isBroadHorizontal) {
|
|
144
|
-
return centerY <= midY ? "floor" : "ceiling";
|
|
145
|
-
}
|
|
146
|
-
const isSlabLike = dy <= 1.0 && dx >= 0.8 && dz >= 0.8;
|
|
147
|
-
if (isSlabLike) {
|
|
148
|
-
if (bboxWorld.max.y <= floorY + 0.6)
|
|
149
|
-
return "floor";
|
|
150
|
-
if (bboxWorld.min.y >= ceilingY - 0.6)
|
|
151
|
-
return "ceiling";
|
|
152
|
-
return centerY <= midY ? "floor" : "ceiling";
|
|
153
|
-
}
|
|
154
|
-
return "walls";
|
|
147
|
+
const CORE_MATERIAL_SURFACES = ["walls", "floor", "ceiling"];
|
|
148
|
+
const CORE_SURFACE_MATERIAL_ROLES = {
|
|
149
|
+
walls: "walls",
|
|
150
|
+
floor: "floor",
|
|
151
|
+
ceiling: "ceiling",
|
|
152
|
+
roof: "ceiling",
|
|
155
153
|
};
|
|
156
|
-
|
|
154
|
+
const normalizeTagValue = (value) => {
|
|
155
|
+
if (typeof value !== "string")
|
|
156
|
+
return null;
|
|
157
|
+
const normalized = value.trim().toLowerCase();
|
|
158
|
+
return normalized.length > 0 ? normalized : null;
|
|
159
|
+
};
|
|
160
|
+
const hasRuleValues = (values) => Array.isArray(values) && values.some((value) => Boolean(normalizeTagValue(value)));
|
|
161
|
+
const matchesRuleValues = (candidate, values) => {
|
|
162
|
+
if (!hasRuleValues(values))
|
|
163
|
+
return true;
|
|
164
|
+
if (!candidate)
|
|
165
|
+
return false;
|
|
166
|
+
return (values ?? []).some((value) => normalizeTagValue(value) === candidate);
|
|
167
|
+
};
|
|
168
|
+
const isCatalogMaterialId = (value) => Boolean(value && findMaterial(value));
|
|
169
|
+
const buildSurfaceRegistry = (policy) => {
|
|
170
|
+
const registry = new Map();
|
|
171
|
+
if (policy.includeCoreSurfaceRoles ?? true) {
|
|
172
|
+
Object.entries(CORE_SURFACE_MATERIAL_ROLES).forEach(([surfaceId, role]) => {
|
|
173
|
+
registry.set(surfaceId, {
|
|
174
|
+
id: surfaceId,
|
|
175
|
+
parentId: surfaceId !== role ? role : undefined,
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
(policy.surfaceDefinitions ?? []).forEach((surface) => {
|
|
180
|
+
const normalized = normalizeTagValue(surface.id);
|
|
181
|
+
if (!normalized || registry.has(normalized))
|
|
182
|
+
return;
|
|
183
|
+
registry.set(normalized, {
|
|
184
|
+
id: surface.id,
|
|
185
|
+
parentId: surface.parentId ? normalizeTagValue(surface.parentId) ?? undefined : undefined,
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
return registry;
|
|
189
|
+
};
|
|
190
|
+
const mappingHasCriteria = (mapping) => hasRuleValues(mapping.surfaceIds) ||
|
|
191
|
+
hasRuleValues(mapping.classes) ||
|
|
192
|
+
hasRuleValues(mapping.subclasses) ||
|
|
193
|
+
hasRuleValues(mapping.roles) ||
|
|
194
|
+
hasRuleValues(mapping.layers) ||
|
|
195
|
+
hasRuleValues(mapping.materials);
|
|
196
|
+
const describeSurfaceMappingFailure = (candidate) => {
|
|
197
|
+
const parts = [
|
|
198
|
+
candidate.surface ? `surface='${candidate.surface}'` : null,
|
|
199
|
+
candidate.className ? `class='${candidate.className}'` : null,
|
|
200
|
+
candidate.subclassName ? `subclass='${candidate.subclassName}'` : null,
|
|
201
|
+
].filter((value) => Boolean(value));
|
|
202
|
+
return parts.join(", ");
|
|
203
|
+
};
|
|
204
|
+
const resolveSurfaceFromTags = (userData, policy) => {
|
|
205
|
+
const registry = buildSurfaceRegistry(policy);
|
|
206
|
+
const candidate = {
|
|
207
|
+
surface: normalizeTagValue(userData?.surface),
|
|
208
|
+
className: normalizeTagValue(userData?.class),
|
|
209
|
+
subclassName: normalizeTagValue(userData?.subclass),
|
|
210
|
+
role: normalizeTagValue(userData?.role),
|
|
211
|
+
layer: normalizeTagValue(userData?.layer),
|
|
212
|
+
material: normalizeTagValue(userData?.material),
|
|
213
|
+
};
|
|
214
|
+
if (candidate.surface) {
|
|
215
|
+
const direct = registry.get(candidate.surface);
|
|
216
|
+
if (direct) {
|
|
217
|
+
return { surfaceId: direct.id, parentSurfaceId: direct.parentId ?? null, unresolvedMapping: null };
|
|
218
|
+
}
|
|
219
|
+
if (isCatalogMaterialId(candidate.surface)) {
|
|
220
|
+
return { surfaceId: null, parentSurfaceId: null, unresolvedMapping: null };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const mappedSurface = (policy.surfaceMappings ?? []).find((mapping) => mappingHasCriteria(mapping) &&
|
|
224
|
+
matchesRuleValues(candidate.surface, mapping.surfaceIds) &&
|
|
225
|
+
matchesRuleValues(candidate.className, mapping.classes) &&
|
|
226
|
+
matchesRuleValues(candidate.subclassName, mapping.subclasses) &&
|
|
227
|
+
matchesRuleValues(candidate.role, mapping.roles) &&
|
|
228
|
+
matchesRuleValues(candidate.layer, mapping.layers) &&
|
|
229
|
+
matchesRuleValues(candidate.material, mapping.materials));
|
|
230
|
+
if (mappedSurface?.surfaceId) {
|
|
231
|
+
const normalizedMappedSurface = normalizeTagValue(mappedSurface.surfaceId);
|
|
232
|
+
const registeredSurface = normalizedMappedSurface ? registry.get(normalizedMappedSurface) : null;
|
|
233
|
+
return {
|
|
234
|
+
surfaceId: registeredSurface?.id ?? mappedSurface.surfaceId,
|
|
235
|
+
parentSurfaceId: registeredSurface?.parentId ?? null,
|
|
236
|
+
unresolvedMapping: null,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const directClassMatch = candidate.className ? registry.get(candidate.className) : null;
|
|
240
|
+
if (directClassMatch) {
|
|
241
|
+
return { surfaceId: directClassMatch.id, parentSurfaceId: directClassMatch.parentId ?? null, unresolvedMapping: null };
|
|
242
|
+
}
|
|
243
|
+
const directSubclassMatch = candidate.subclassName ? registry.get(candidate.subclassName) : null;
|
|
244
|
+
if (directSubclassMatch) {
|
|
245
|
+
return { surfaceId: directSubclassMatch.id, parentSurfaceId: directSubclassMatch.parentId ?? null, unresolvedMapping: null };
|
|
246
|
+
}
|
|
247
|
+
if (candidate.surface || candidate.className || candidate.subclassName) {
|
|
248
|
+
return {
|
|
249
|
+
surfaceId: null,
|
|
250
|
+
parentSurfaceId: null,
|
|
251
|
+
unresolvedMapping: describeSurfaceMappingFailure(candidate),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return { surfaceId: null, parentSurfaceId: null, unresolvedMapping: null };
|
|
255
|
+
};
|
|
256
|
+
const lookupSurfaceMaterial = (materialSet, surfaceId, parentSurfaceId, requiredSurfaceBindingIds, policy) => {
|
|
257
|
+
if (!materialSet || !surfaceId)
|
|
258
|
+
return null;
|
|
259
|
+
const honorCoreSurfaceMaterials = policy.honorCoreSurfaceMaterials ?? true;
|
|
260
|
+
const honorSurfaceParentMaterials = policy.honorSurfaceParentMaterials ?? true;
|
|
261
|
+
const normalizedSurfaceId = normalizeTagValue(surfaceId);
|
|
262
|
+
// Manifest-authored exact surface materials must win before core parent defaults.
|
|
263
|
+
const exactSurfaceMaterial = materialSet.surfaces[surfaceId] ?? (normalizedSurfaceId ? materialSet.surfaces[normalizedSurfaceId] : null) ?? null;
|
|
264
|
+
if (exactSurfaceMaterial || (normalizedSurfaceId && requiredSurfaceBindingIds.has(normalizedSurfaceId))) {
|
|
265
|
+
return exactSurfaceMaterial;
|
|
266
|
+
}
|
|
267
|
+
const coreSurfaceRole = normalizedSurfaceId ? CORE_SURFACE_MATERIAL_ROLES[normalizedSurfaceId] : undefined;
|
|
268
|
+
if (honorCoreSurfaceMaterials && coreSurfaceRole) {
|
|
269
|
+
return materialSet[coreSurfaceRole];
|
|
270
|
+
}
|
|
271
|
+
if (!honorSurfaceParentMaterials) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
const normalizedParentSurfaceId = normalizeTagValue(parentSurfaceId);
|
|
275
|
+
const exactParentSurfaceMaterial = parentSurfaceId
|
|
276
|
+
? materialSet.surfaces[parentSurfaceId] ??
|
|
277
|
+
(normalizedParentSurfaceId ? materialSet.surfaces[normalizedParentSurfaceId] : null) ??
|
|
278
|
+
null
|
|
279
|
+
: null;
|
|
280
|
+
if (exactParentSurfaceMaterial) {
|
|
281
|
+
return exactParentSurfaceMaterial;
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
};
|
|
285
|
+
const resolveShadowPolicy = (surface) => {
|
|
286
|
+
const normalizedSurface = surface?.trim().toLowerCase() ?? "";
|
|
287
|
+
if (normalizedSurface === "plaster" ||
|
|
288
|
+
normalizedSurface === "dormer-body" ||
|
|
289
|
+
normalizedSurface === "plaster_flat" ||
|
|
290
|
+
normalizedSurface === "walls") {
|
|
291
|
+
return { cast: false, receive: true };
|
|
292
|
+
}
|
|
293
|
+
if (normalizedSurface === "zinc" ||
|
|
294
|
+
normalizedSurface === "membrane" ||
|
|
295
|
+
normalizedSurface === "terrace-deck" ||
|
|
296
|
+
normalizedSurface === "dormer-roof") {
|
|
297
|
+
return { cast: true, receive: true };
|
|
298
|
+
}
|
|
299
|
+
if (normalizedSurface.includes("glass") || normalizedSurface.includes("glazing")) {
|
|
300
|
+
return { cast: false, receive: false };
|
|
301
|
+
}
|
|
302
|
+
if (normalizedSurface === "floor" || normalizedSurface === "ceiling") {
|
|
303
|
+
return { cast: false, receive: true };
|
|
304
|
+
}
|
|
305
|
+
return { cast: true, receive: true };
|
|
306
|
+
};
|
|
307
|
+
export function applyMaterialsToGroup(group, materialsConfig, floorLevel, ceilingHeight, policy = {}) {
|
|
157
308
|
if (!group || typeof group.traverse !== "function")
|
|
158
309
|
return;
|
|
159
|
-
|
|
160
|
-
|
|
310
|
+
void floorLevel;
|
|
311
|
+
void ceilingHeight;
|
|
161
312
|
const materialSet = materialsConfig
|
|
162
313
|
? {
|
|
163
|
-
walls: buildSurfaceMaterial("walls", materialsConfig.walls),
|
|
164
|
-
floor: buildSurfaceMaterial("floor", materialsConfig.floor),
|
|
165
|
-
ceiling: buildSurfaceMaterial("ceiling", materialsConfig.ceiling),
|
|
314
|
+
walls: materialsConfig.walls ? buildSurfaceMaterial("walls", materialsConfig.walls) : null,
|
|
315
|
+
floor: materialsConfig.floor ? buildSurfaceMaterial("floor", materialsConfig.floor) : null,
|
|
316
|
+
ceiling: materialsConfig.ceiling ? buildSurfaceMaterial("ceiling", materialsConfig.ceiling) : null,
|
|
317
|
+
surfaces: Object.fromEntries(Object.entries(materialsConfig.surfaces ?? {}).map(([surfaceId, config]) => [
|
|
318
|
+
surfaceId,
|
|
319
|
+
buildSurfaceMaterial(surfaceId, config),
|
|
320
|
+
])),
|
|
166
321
|
}
|
|
167
322
|
: null;
|
|
168
323
|
group.updateMatrixWorld(true);
|
|
324
|
+
const honorObjectColor = policy.honorObjectColor ?? true;
|
|
325
|
+
const requiredSurfaceBindingIds = new Set((policy.requiredSurfaceBindingIds ?? []).map((surfaceId) => normalizeTagValue(surfaceId)).filter(Boolean));
|
|
326
|
+
const defaultSurfaceMaterial = policy.defaultSurfaceMaterial
|
|
327
|
+
? buildSurfaceMaterial("default", policy.defaultSurfaceMaterial)
|
|
328
|
+
: null;
|
|
329
|
+
const resolveMappedSurfaceMaterial = (surfaceId, parentSurfaceId) => {
|
|
330
|
+
const mappedSurfaceMaterial = lookupSurfaceMaterial(materialSet, surfaceId, parentSurfaceId, requiredSurfaceBindingIds, policy);
|
|
331
|
+
if (mappedSurfaceMaterial)
|
|
332
|
+
return mappedSurfaceMaterial;
|
|
333
|
+
const normalizedSurfaceId = normalizeTagValue(surfaceId);
|
|
334
|
+
if (defaultSurfaceMaterial && normalizedSurfaceId && !requiredSurfaceBindingIds.has(normalizedSurfaceId)) {
|
|
335
|
+
return defaultSurfaceMaterial;
|
|
336
|
+
}
|
|
337
|
+
return null;
|
|
338
|
+
};
|
|
169
339
|
group.traverse((child) => {
|
|
170
340
|
if (!child?.isMesh)
|
|
171
341
|
return;
|
|
172
|
-
|
|
173
|
-
child.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
child.
|
|
342
|
+
let resolvedSurface = null;
|
|
343
|
+
const objectColor = typeof child.userData?.objectColor === "string" ? child.userData.objectColor.trim() : null;
|
|
344
|
+
let materialApplied = false;
|
|
345
|
+
let pendingSurfaceFailure = null;
|
|
346
|
+
const taggedSurface = resolveSurfaceFromTags(child.userData, policy);
|
|
347
|
+
const clearSurfaceDiagnostics = () => {
|
|
348
|
+
if (!child.userData)
|
|
349
|
+
return;
|
|
350
|
+
delete child.userData.unresolvedSurfaceType;
|
|
351
|
+
delete child.userData.unresolvedSurfaceMapping;
|
|
352
|
+
};
|
|
353
|
+
const applyFallbackSurfaceMaterial = () => {
|
|
354
|
+
child.material = defaultSurfaceMaterial ? defaultSurfaceMaterial.clone() : buildFallbackMaterial();
|
|
355
|
+
materialApplied = true;
|
|
356
|
+
};
|
|
357
|
+
const applyContractFailure = (detail) => {
|
|
358
|
+
child.userData = {
|
|
359
|
+
...child.userData,
|
|
360
|
+
unresolvedSurfaceMapping: detail,
|
|
361
|
+
};
|
|
362
|
+
applyFallbackSurfaceMaterial();
|
|
363
|
+
};
|
|
364
|
+
const tryApplySurfaceBinding = () => {
|
|
365
|
+
if (taggedSurface.surfaceId) {
|
|
366
|
+
const mappedSurfaceMaterial = resolveMappedSurfaceMaterial(taggedSurface.surfaceId, taggedSurface.parentSurfaceId);
|
|
367
|
+
child.userData = {
|
|
368
|
+
...child.userData,
|
|
369
|
+
surfaceType: taggedSurface.surfaceId,
|
|
370
|
+
};
|
|
371
|
+
resolvedSurface = taggedSurface.surfaceId;
|
|
372
|
+
if (mappedSurfaceMaterial) {
|
|
373
|
+
clearSurfaceDiagnostics();
|
|
374
|
+
child.material = mappedSurfaceMaterial.clone();
|
|
375
|
+
materialApplied = true;
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
child.userData = {
|
|
379
|
+
...child.userData,
|
|
380
|
+
unresolvedSurfaceType: taggedSurface.surfaceId,
|
|
381
|
+
};
|
|
382
|
+
pendingSurfaceFailure = `surface '${taggedSurface.surfaceId}' has no material binding`;
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (taggedSurface.unresolvedMapping) {
|
|
386
|
+
child.userData = {
|
|
387
|
+
...child.userData,
|
|
388
|
+
unresolvedSurfaceMapping: taggedSurface.unresolvedMapping,
|
|
389
|
+
};
|
|
390
|
+
pendingSurfaceFailure = taggedSurface.unresolvedMapping;
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (objectColor && honorObjectColor) {
|
|
394
|
+
const parsedHex = Number.parseInt(objectColor.replace(/^#/, ""), 16);
|
|
395
|
+
if (Number.isFinite(parsedHex)) {
|
|
396
|
+
clearSurfaceDiagnostics();
|
|
397
|
+
child.material = new THREE.MeshStandardMaterial({
|
|
398
|
+
color: parsedHex,
|
|
399
|
+
roughness: 0.65,
|
|
400
|
+
metalness: 0.1,
|
|
401
|
+
});
|
|
402
|
+
materialApplied = true;
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
pendingSurfaceFailure = "missing explicit surface classification";
|
|
407
|
+
};
|
|
408
|
+
if (!materialApplied && taggedSurface.surfaceId) {
|
|
409
|
+
const mappedSurfaceMaterial = resolveMappedSurfaceMaterial(taggedSurface.surfaceId, taggedSurface.parentSurfaceId);
|
|
410
|
+
child.userData = {
|
|
411
|
+
...child.userData,
|
|
412
|
+
surfaceType: taggedSurface.surfaceId,
|
|
413
|
+
};
|
|
414
|
+
resolvedSurface = taggedSurface.surfaceId;
|
|
415
|
+
if (mappedSurfaceMaterial) {
|
|
416
|
+
clearSurfaceDiagnostics();
|
|
417
|
+
child.material = mappedSurfaceMaterial.clone();
|
|
418
|
+
materialApplied = true;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
pendingSurfaceFailure = `surface '${taggedSurface.surfaceId}' has no material binding`;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
else if (!materialApplied && taggedSurface.unresolvedMapping) {
|
|
425
|
+
child.userData = {
|
|
426
|
+
...child.userData,
|
|
427
|
+
unresolvedSurfaceMapping: taggedSurface.unresolvedMapping,
|
|
428
|
+
};
|
|
429
|
+
pendingSurfaceFailure = taggedSurface.unresolvedMapping;
|
|
430
|
+
}
|
|
431
|
+
if (!materialApplied) {
|
|
432
|
+
tryApplySurfaceBinding();
|
|
433
|
+
}
|
|
434
|
+
if (!materialApplied) {
|
|
435
|
+
applyContractFailure(pendingSurfaceFailure ?? "missing explicit surface classification");
|
|
179
436
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
437
|
+
const shadowPolicy = resolveShadowPolicy(resolvedSurface);
|
|
438
|
+
child.castShadow = shadowPolicy.cast;
|
|
439
|
+
child.receiveShadow = shadowPolicy.receive;
|
|
440
|
+
const normal = child.geometry.getAttribute("normal");
|
|
441
|
+
if (!normal || normal.count === 0) {
|
|
442
|
+
child.geometry.computeVertexNormals();
|
|
184
443
|
}
|
|
185
|
-
child.geometry.computeVertexNormals();
|
|
186
444
|
});
|
|
187
445
|
}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
export declare const MATERIAL_CATALOGUE: {
|
|
2
2
|
readonly version: 1;
|
|
3
3
|
readonly materials: readonly [{
|
|
4
|
+
readonly materialId: "plaster_flat";
|
|
5
|
+
readonly label: "flat mineral plaster";
|
|
6
|
+
readonly category: "walls";
|
|
7
|
+
readonly baseline: {
|
|
8
|
+
readonly color: "#F3F1EC";
|
|
9
|
+
readonly finish: "matte";
|
|
10
|
+
};
|
|
11
|
+
readonly pbr: {
|
|
12
|
+
readonly baseColor: "#F5F3EE";
|
|
13
|
+
readonly roughness: 0.72;
|
|
14
|
+
readonly metalness: 0;
|
|
15
|
+
readonly emissive: "#FFFFFF";
|
|
16
|
+
readonly emissiveIntensity: 0.02;
|
|
17
|
+
};
|
|
18
|
+
}, {
|
|
4
19
|
readonly materialId: "white_wall";
|
|
5
20
|
readonly label: "white plaster wall";
|
|
6
21
|
readonly category: "walls";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalogue-data.d.ts","sourceRoot":"","sources":["../../src/materials/catalogue-data.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"catalogue-data.d.ts","sourceRoot":"","sources":["../../src/materials/catalogue-data.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6KrB,CAAC"}
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
export const MATERIAL_CATALOGUE = {
|
|
2
2
|
"version": 1,
|
|
3
3
|
"materials": [
|
|
4
|
+
{
|
|
5
|
+
"materialId": "plaster_flat",
|
|
6
|
+
"label": "flat mineral plaster",
|
|
7
|
+
"category": "walls",
|
|
8
|
+
"baseline": {
|
|
9
|
+
"color": "#F3F1EC",
|
|
10
|
+
"finish": "matte"
|
|
11
|
+
},
|
|
12
|
+
"pbr": {
|
|
13
|
+
"baseColor": "#F5F3EE",
|
|
14
|
+
"roughness": 0.72,
|
|
15
|
+
"metalness": 0.0,
|
|
16
|
+
"emissive": "#FFFFFF",
|
|
17
|
+
"emissiveIntensity": 0.02
|
|
18
|
+
}
|
|
19
|
+
},
|
|
4
20
|
{
|
|
5
21
|
"materialId": "white_wall",
|
|
6
22
|
"label": "white plaster wall",
|
|
@@ -1,21 +1,28 @@
|
|
|
1
|
-
import type { MaterialId, MaterialsConfig, SurfaceMaterialConfig } from "./types";
|
|
2
|
-
export type
|
|
1
|
+
import type { MaterialDefinition, MaterialId, MaterialSurfaceConfigMap, MaterialsConfig, SurfaceMaterialConfig } from "./types";
|
|
2
|
+
export type MaterialBindingReference = {
|
|
3
3
|
catalogId: MaterialId;
|
|
4
4
|
overrides?: Partial<SurfaceMaterialConfig>;
|
|
5
5
|
};
|
|
6
|
+
export type MaterialBindingReferenceMap = Record<string, MaterialBindingReference>;
|
|
7
|
+
export type MaterialDefinitionLookup = ReadonlyArray<MaterialDefinition> | ReadonlyMap<string, MaterialDefinition>;
|
|
6
8
|
export type MaterialPresetDefinition = {
|
|
7
9
|
id: string;
|
|
8
10
|
label: string;
|
|
9
11
|
materials: {
|
|
10
|
-
walls:
|
|
11
|
-
floor:
|
|
12
|
-
ceiling:
|
|
12
|
+
walls: MaterialBindingReference;
|
|
13
|
+
floor: MaterialBindingReference;
|
|
14
|
+
ceiling: MaterialBindingReference;
|
|
15
|
+
surfaces?: MaterialBindingReferenceMap;
|
|
13
16
|
};
|
|
14
17
|
};
|
|
15
|
-
export declare const
|
|
18
|
+
export declare const ARCHITECTURAL_WHITE_MATERIAL_PRESET_ID = "architectural-white";
|
|
19
|
+
export declare const MONOCHROME_CLAY_MATERIAL_PRESET_ID = "monochrome-clay";
|
|
20
|
+
export declare const UPLOAD_VISIBLE_MATERIAL_PRESET_ID = "upload-visible";
|
|
16
21
|
export declare const MATERIAL_PRESET_DATA: Record<string, MaterialPresetDefinition>;
|
|
17
|
-
export declare
|
|
18
|
-
export declare function
|
|
22
|
+
export declare const hasMaterialDefinition: (materialId: MaterialId, materialDefinitions?: MaterialDefinitionLookup) => boolean;
|
|
23
|
+
export declare function resolveMaterialBinding(binding: MaterialBindingReference, materialDefinitions?: MaterialDefinitionLookup): SurfaceMaterialConfig;
|
|
24
|
+
export declare function resolveMaterialSurfaceMap(surfaces?: MaterialBindingReferenceMap | null, materialDefinitions?: MaterialDefinitionLookup): MaterialSurfaceConfigMap | undefined;
|
|
25
|
+
export declare function resolveMaterialPresetMaterials(preset: MaterialPresetDefinition, materialDefinitions?: MaterialDefinitionLookup): MaterialsConfig;
|
|
19
26
|
export declare function listMaterialPresets(): MaterialPresetDefinition[];
|
|
20
27
|
export declare function getMaterialPreset(id: string): MaterialPresetDefinition;
|
|
21
28
|
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/materials/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/materials/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,UAAU,EACV,wBAAwB,EACxB,eAAe,EACf,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;AACnF,MAAM,MAAM,wBAAwB,GAAG,aAAa,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAEnH,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE;QACT,KAAK,EAAE,wBAAwB,CAAC;QAChC,KAAK,EAAE,wBAAwB,CAAC;QAChC,OAAO,EAAE,wBAAwB,CAAC;QAClC,QAAQ,CAAC,EAAE,2BAA2B,CAAC;KACxC,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,sCAAsC,wBAAwB,CAAC;AAC5E,eAAO,MAAM,kCAAkC,oBAAoB,CAAC;AACpE,eAAO,MAAM,iCAAiC,mBAAmB,CAAC;AAOlE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CA0OzE,CAAC;AAsBF,eAAO,MAAM,qBAAqB,GAAI,YAAY,UAAU,EAAE,sBAAsB,wBAAwB,YAC1C,CAAC;AAmBnE,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,wBAAwB,EACjC,mBAAmB,CAAC,EAAE,wBAAwB,GAC7C,qBAAqB,CAGvB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,CAAC,EAAE,2BAA2B,GAAG,IAAI,EAC7C,mBAAmB,CAAC,EAAE,wBAAwB,GAC7C,wBAAwB,GAAG,SAAS,CAMtC;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,wBAAwB,EAChC,mBAAmB,CAAC,EAAE,wBAAwB,GAC7C,eAAe,CA2BjB;AAED,wBAAgB,mBAAmB,IAAI,wBAAwB,EAAE,CAEhE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,wBAAwB,CAMtE"}
|