abstract-3d 3.1.1 → 4.0.0-beta.0
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/README.md +21 -1
- package/lib/renderers/dxf/dxf-encoding/dxf-build.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-encoding/dxf-build.js +1 -2
- package/lib/renderers/dxf/dxf-encoding/dxf-build.js.map +1 -1
- package/lib/renderers/ifc/ifc.test.d.ts +2 -0
- package/lib/renderers/ifc/ifc.test.d.ts.map +1 -0
- package/lib/renderers/ifc/ifc.test.js +380 -0
- package/lib/renderers/ifc/ifc.test.js.map +1 -0
- package/lib/renderers/index.d.ts +1 -0
- package/lib/renderers/index.d.ts.map +1 -1
- package/lib/renderers/index.js +1 -0
- package/lib/renderers/index.js.map +1 -1
- package/lib/renderers/react/index.d.ts +2 -5
- package/lib/renderers/react/index.d.ts.map +1 -1
- package/lib/renderers/react/index.js +1 -2
- package/lib/renderers/react/index.js.map +1 -1
- package/lib/renderers/react/react.d.ts +16 -42
- package/lib/renderers/react/react.d.ts.map +1 -1
- package/lib/renderers/react/react.js +49 -32
- package/lib/renderers/react/react.js.map +1 -1
- package/lib/renderers/three/appearance/appearance.d.ts +41 -0
- package/lib/renderers/three/appearance/appearance.d.ts.map +1 -0
- package/lib/renderers/three/appearance/appearance.js +89 -0
- package/lib/renderers/three/appearance/appearance.js.map +1 -0
- package/lib/renderers/three/appearance/appearance.test.d.ts +2 -0
- package/lib/renderers/three/appearance/appearance.test.d.ts.map +1 -0
- package/lib/renderers/three/appearance/appearance.test.js +97 -0
- package/lib/renderers/three/appearance/appearance.test.js.map +1 -0
- package/lib/renderers/three/appearance.d.ts +41 -0
- package/lib/renderers/three/appearance.d.ts.map +1 -0
- package/lib/renderers/three/appearance.js +100 -0
- package/lib/renderers/three/appearance.js.map +1 -0
- package/lib/renderers/three/build/build.d.ts +51 -0
- package/lib/renderers/three/build/build.d.ts.map +1 -0
- package/lib/renderers/three/build/build.js +174 -0
- package/lib/renderers/three/build/build.js.map +1 -0
- package/lib/renderers/three/build/build.test.d.ts +2 -0
- package/lib/renderers/three/build/build.test.d.ts.map +1 -0
- package/lib/renderers/three/build/build.test.js +120 -0
- package/lib/renderers/three/build/build.test.js.map +1 -0
- package/lib/renderers/three/build/materials.d.ts +12 -0
- package/lib/renderers/three/build/materials.d.ts.map +1 -0
- package/lib/renderers/three/build/materials.js +55 -0
- package/lib/renderers/three/build/materials.js.map +1 -0
- package/lib/renderers/three/build/parts.d.ts +65 -0
- package/lib/renderers/three/build/parts.d.ts.map +1 -0
- package/lib/renderers/three/build/parts.js +203 -0
- package/lib/renderers/three/build/parts.js.map +1 -0
- package/lib/renderers/three/build.d.ts +50 -0
- package/lib/renderers/three/build.d.ts.map +1 -0
- package/lib/renderers/three/build.js +210 -0
- package/lib/renderers/three/build.js.map +1 -0
- package/lib/renderers/three/camera/camera.d.ts +40 -0
- package/lib/renderers/three/camera/camera.d.ts.map +1 -0
- package/lib/renderers/three/camera/camera.js +51 -0
- package/lib/renderers/three/camera/camera.js.map +1 -0
- package/lib/renderers/three/camera/camera.test.d.ts +2 -0
- package/lib/renderers/three/camera/camera.test.d.ts.map +1 -0
- package/lib/renderers/three/camera/camera.test.js +46 -0
- package/lib/renderers/three/camera/camera.test.js.map +1 -0
- package/lib/renderers/three/camera/controls.d.ts +24 -0
- package/lib/renderers/three/camera/controls.d.ts.map +1 -0
- package/lib/renderers/three/camera/controls.js +39 -0
- package/lib/renderers/three/camera/controls.js.map +1 -0
- package/lib/renderers/three/camera/gizmo.d.ts +44 -0
- package/lib/renderers/three/camera/gizmo.d.ts.map +1 -0
- package/lib/renderers/three/camera/gizmo.js +42 -0
- package/lib/renderers/three/camera/gizmo.js.map +1 -0
- package/lib/renderers/three/camera.d.ts +63 -0
- package/lib/renderers/three/camera.d.ts.map +1 -0
- package/lib/renderers/three/camera.js +85 -0
- package/lib/renderers/three/camera.js.map +1 -0
- package/lib/renderers/three/compile/compile.d.ts +59 -0
- package/lib/renderers/three/compile/compile.d.ts.map +1 -0
- package/lib/renderers/three/compile/compile.js +88 -0
- package/lib/renderers/three/compile/compile.js.map +1 -0
- package/lib/renderers/three/compile/compile.test.d.ts +2 -0
- package/lib/renderers/three/compile/compile.test.d.ts.map +1 -0
- package/lib/renderers/three/compile/compile.test.js +93 -0
- package/lib/renderers/three/compile/compile.test.js.map +1 -0
- package/lib/renderers/three/compile.d.ts +58 -0
- package/lib/renderers/three/compile.d.ts.map +1 -0
- package/lib/renderers/three/compile.js +89 -0
- package/lib/renderers/three/compile.js.map +1 -0
- package/lib/renderers/three/controls.d.ts +27 -0
- package/lib/renderers/three/controls.d.ts.map +1 -0
- package/lib/renderers/three/controls.js +115 -0
- package/lib/renderers/three/controls.js.map +1 -0
- package/lib/renderers/three/geometry/geometry.d.ts +21 -0
- package/lib/renderers/three/geometry/geometry.d.ts.map +1 -0
- package/lib/renderers/three/geometry/geometry.js +132 -0
- package/lib/renderers/three/geometry/geometry.js.map +1 -0
- package/lib/renderers/three/geometry/geometry.test.d.ts +2 -0
- package/lib/renderers/three/geometry/geometry.test.d.ts.map +1 -0
- package/lib/renderers/three/geometry/geometry.test.js +80 -0
- package/lib/renderers/three/geometry/geometry.test.js.map +1 -0
- package/lib/renderers/three/geometry.d.ts +20 -0
- package/lib/renderers/three/geometry.d.ts.map +1 -0
- package/lib/renderers/three/geometry.js +164 -0
- package/lib/renderers/three/geometry.js.map +1 -0
- package/lib/renderers/three/gizmo.d.ts +49 -0
- package/lib/renderers/three/gizmo.d.ts.map +1 -0
- package/lib/renderers/three/gizmo.js +172 -0
- package/lib/renderers/three/gizmo.js.map +1 -0
- package/lib/renderers/three/index.d.ts +16 -0
- package/lib/renderers/three/index.d.ts.map +1 -0
- package/lib/renderers/three/index.js +6 -0
- package/lib/renderers/three/index.js.map +1 -0
- package/lib/renderers/three/input.d.ts +25 -0
- package/lib/renderers/three/input.d.ts.map +1 -0
- package/lib/renderers/three/input.js +71 -0
- package/lib/renderers/three/input.js.map +1 -0
- package/lib/renderers/three/lines.d.ts +16 -0
- package/lib/renderers/three/lines.d.ts.map +1 -0
- package/lib/renderers/three/lines.js +63 -0
- package/lib/renderers/three/lines.js.map +1 -0
- package/lib/renderers/three/materials.d.ts +15 -0
- package/lib/renderers/three/materials.d.ts.map +1 -0
- package/lib/renderers/three/materials.js +70 -0
- package/lib/renderers/three/materials.js.map +1 -0
- package/lib/renderers/three/options.d.ts +68 -0
- package/lib/renderers/three/options.d.ts.map +1 -0
- package/lib/renderers/three/options.js +64 -0
- package/lib/renderers/three/options.js.map +1 -0
- package/lib/renderers/three/overlays.d.ts +25 -0
- package/lib/renderers/three/overlays.d.ts.map +1 -0
- package/lib/renderers/three/overlays.js +57 -0
- package/lib/renderers/three/overlays.js.map +1 -0
- package/lib/renderers/three/quality/quality.d.ts +37 -0
- package/lib/renderers/three/quality/quality.d.ts.map +1 -0
- package/lib/renderers/three/quality/quality.js +64 -0
- package/lib/renderers/three/quality/quality.js.map +1 -0
- package/lib/renderers/three/quality/quality.test.d.ts +2 -0
- package/lib/renderers/three/quality/quality.test.d.ts.map +1 -0
- package/lib/renderers/three/quality/quality.test.js +23 -0
- package/lib/renderers/three/quality/quality.test.js.map +1 -0
- package/lib/renderers/three/quality.d.ts +24 -0
- package/lib/renderers/three/quality.d.ts.map +1 -0
- package/lib/renderers/three/quality.js +67 -0
- package/lib/renderers/three/quality.js.map +1 -0
- package/lib/renderers/three/text/text.d.ts +55 -0
- package/lib/renderers/three/text/text.d.ts.map +1 -0
- package/lib/renderers/three/text/text.js +90 -0
- package/lib/renderers/three/text/text.js.map +1 -0
- package/lib/renderers/three/text/text.test.d.ts +2 -0
- package/lib/renderers/three/text/text.test.d.ts.map +1 -0
- package/lib/renderers/three/text/text.test.js +70 -0
- package/lib/renderers/three/text/text.test.js.map +1 -0
- package/lib/renderers/three/text.d.ts +53 -0
- package/lib/renderers/three/text.d.ts.map +1 -0
- package/lib/renderers/three/text.js +151 -0
- package/lib/renderers/three/text.js.map +1 -0
- package/lib/renderers/three/viewer/options.d.ts +71 -0
- package/lib/renderers/three/viewer/options.d.ts.map +1 -0
- package/lib/renderers/three/viewer/options.js +31 -0
- package/lib/renderers/three/viewer/options.js.map +1 -0
- package/lib/renderers/three/viewer/options.test.d.ts +2 -0
- package/lib/renderers/three/viewer/options.test.d.ts.map +1 -0
- package/lib/renderers/three/viewer/options.test.js +38 -0
- package/lib/renderers/three/viewer/options.test.js.map +1 -0
- package/lib/renderers/three/viewer/overlays.d.ts +31 -0
- package/lib/renderers/three/viewer/overlays.d.ts.map +1 -0
- package/lib/renderers/three/viewer/overlays.js +43 -0
- package/lib/renderers/three/viewer/overlays.js.map +1 -0
- package/lib/renderers/three/viewer/viewer.d.ts +90 -0
- package/lib/renderers/three/viewer/viewer.d.ts.map +1 -0
- package/lib/renderers/three/viewer/viewer.js +432 -0
- package/lib/renderers/three/viewer/viewer.js.map +1 -0
- package/lib/renderers/three/viewer.d.ts +38 -0
- package/lib/renderers/three/viewer.d.ts.map +1 -0
- package/lib/renderers/three/viewer.js +435 -0
- package/lib/renderers/three/viewer.js.map +1 -0
- package/package.json +26 -9
- package/src/abstract-3d.ts +1 -1
- package/src/custom_typings/n8ao.d.ts +11 -0
- package/src/renderers/dxf/dxf-encoding/dxf-build.ts +1 -2
- package/src/renderers/index.ts +1 -0
- package/src/renderers/react/index.ts +2 -5
- package/src/renderers/react/react.tsx +96 -181
- package/src/renderers/three/appearance/appearance.test.ts +116 -0
- package/src/renderers/three/appearance/appearance.ts +132 -0
- package/src/renderers/three/build/build.test.ts +141 -0
- package/src/renderers/three/build/build.ts +270 -0
- package/src/renderers/three/build/materials.ts +85 -0
- package/src/renderers/three/build/parts.ts +277 -0
- package/src/renderers/three/camera/camera.test.ts +53 -0
- package/src/renderers/three/camera/camera.ts +82 -0
- package/src/renderers/three/camera/controls.ts +65 -0
- package/src/renderers/three/camera/gizmo.ts +93 -0
- package/src/renderers/three/compile/compile.test.ts +113 -0
- package/src/renderers/three/compile/compile.ts +151 -0
- package/src/renderers/three/geometry/geometry.test.ts +95 -0
- package/src/renderers/three/geometry/geometry.ts +179 -0
- package/src/renderers/three/index.ts +15 -0
- package/src/renderers/three/quality/quality.test.ts +30 -0
- package/src/renderers/three/quality/quality.ts +95 -0
- package/src/renderers/three/text/text.test.ts +79 -0
- package/src/renderers/three/text/text.ts +128 -0
- package/src/renderers/three/viewer/options.ts +98 -0
- package/src/renderers/three/viewer/overlays.ts +71 -0
- package/src/renderers/three/viewer/viewer.ts +540 -0
- package/lib/renderers/dxf/color.d.ts +0 -7
- package/lib/renderers/dxf/color.d.ts.map +0 -1
- package/lib/renderers/dxf/color.js +0 -311
- package/lib/renderers/dxf/color.js.map +0 -1
- package/lib/renderers/dxf/dxf-encoding.d.ts +0 -17
- package/lib/renderers/dxf/dxf-encoding.d.ts.map +0 -1
- package/lib/renderers/dxf/dxf-encoding.js +0 -18467
- package/lib/renderers/dxf/dxf-encoding.js.map +0 -1
- package/lib/renderers/react/react-hotspot.d.ts +0 -27
- package/lib/renderers/react/react-hotspot.d.ts.map +0 -1
- package/lib/renderers/react/react-hotspot.js +0 -37
- package/lib/renderers/react/react-hotspot.js.map +0 -1
- package/lib/renderers/shared.d.ts +0 -30
- package/lib/renderers/shared.d.ts.map +0 -1
- package/lib/renderers/shared.js +0 -164
- package/lib/renderers/shared.js.map +0 -1
- package/src/custom_typings/react-three-fiber.d.ts +0 -9
- package/src/custom_typings/react-three-postprocessing.d.ts +0 -1
- package/src/renderers/react/react-camera.tsx +0 -391
- package/src/renderers/react/react-dimension.tsx +0 -122
- package/src/renderers/react/react-group.test.ts +0 -56
- package/src/renderers/react/react-group.tsx +0 -202
- package/src/renderers/react/react-image-material.tsx +0 -139
- package/src/renderers/react/react-material.tsx +0 -91
- package/src/renderers/react/react-mesh.tsx +0 -512
- package/src/renderers/react/react-relation.tsx +0 -86
- package/src/renderers/react/react-scene.tsx +0 -111
- package/src/renderers/react/react-types.ts +0 -9
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AmbientLight,
|
|
3
|
+
type BufferGeometry,
|
|
4
|
+
CanvasTexture,
|
|
5
|
+
DirectionalLight,
|
|
6
|
+
EquirectangularReflectionMapping,
|
|
7
|
+
Group,
|
|
8
|
+
NeutralToneMapping,
|
|
9
|
+
type Object3D,
|
|
10
|
+
OrthographicCamera,
|
|
11
|
+
PerspectiveCamera,
|
|
12
|
+
PMREMGenerator,
|
|
13
|
+
Raycaster,
|
|
14
|
+
Scene as ThreeScene,
|
|
15
|
+
SRGBColorSpace,
|
|
16
|
+
type Texture,
|
|
17
|
+
Vector2,
|
|
18
|
+
Vector3,
|
|
19
|
+
WebGLRenderer,
|
|
20
|
+
} from "three";
|
|
21
|
+
import type { ViewportGizmo } from "three-viewport-gizmo";
|
|
22
|
+
import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js";
|
|
23
|
+
import type { StructureState } from "../appearance/appearance.js";
|
|
24
|
+
import type { BuiltScene } from "../build/build.js";
|
|
25
|
+
import { animateScene, buildScene, cullScene, disposeScene, getPickables, getPickedItem, paintScene } from "../build/build.js";
|
|
26
|
+
import type { TextureCache } from "../build/materials.js";
|
|
27
|
+
import { disposeTextures } from "../build/materials.js";
|
|
28
|
+
import type { Placement } from "../camera/camera.js";
|
|
29
|
+
import { fitCamera } from "../camera/camera.js";
|
|
30
|
+
import type { Controls } from "../camera/controls.js";
|
|
31
|
+
import { configureControls, createControls, setPose } from "../camera/controls.js";
|
|
32
|
+
import { createGizmo } from "../camera/gizmo.js";
|
|
33
|
+
import type { CompiledScene } from "../compile/compile.js";
|
|
34
|
+
import { compileScene } from "../compile/compile.js";
|
|
35
|
+
import type { RenderPath, TierGovernor } from "../quality/quality.js";
|
|
36
|
+
import { createRenderPath, disposeRenderPath, recordFrame, renderPath } from "../quality/quality.js";
|
|
37
|
+
import type { GlyphAtlas } from "../text/text.js";
|
|
38
|
+
import { createGlyphAtlas } from "../text/text.js";
|
|
39
|
+
import type { Change, ViewerOptions } from "./options.js";
|
|
40
|
+
import { effects } from "./options.js";
|
|
41
|
+
import type { Overlay, OverlayLayer } from "./overlays.js";
|
|
42
|
+
import { createOverlayLayer, setOverlays } from "./overlays.js";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The interactive viewer: renderer, render on demand, camera, controls, pointer input, overlays and gizmo. Updates are batched into the next frame,
|
|
46
|
+
* as r3f applies props; render on demand and `invalidate` are r3f's `frameloop="demand"`; the state with functions instead of a class keeps it free
|
|
47
|
+
* of `this`
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
type Hit = { readonly item: number; readonly target: number; readonly point: Vector3 };
|
|
51
|
+
|
|
52
|
+
export type Viewer<Content> = {
|
|
53
|
+
options: ViewerOptions<Content>;
|
|
54
|
+
readonly container: HTMLElement;
|
|
55
|
+
readonly canvas: HTMLCanvasElement;
|
|
56
|
+
readonly renderer: WebGLRenderer;
|
|
57
|
+
/** Apps can add their own objects, then `invalidate` */
|
|
58
|
+
readonly scene: ThreeScene;
|
|
59
|
+
readonly lights: Group;
|
|
60
|
+
readonly cameras: { readonly Perspective: PerspectiveCamera; readonly Orthographic: OrthographicCamera };
|
|
61
|
+
camera: PerspectiveCamera | OrthographicCamera;
|
|
62
|
+
readonly controls: Controls;
|
|
63
|
+
readonly geometries: Map<string, BufferGeometry>;
|
|
64
|
+
readonly atlas: GlyphAtlas;
|
|
65
|
+
readonly textures: TextureCache;
|
|
66
|
+
readonly overlays: OverlayLayer<Content>;
|
|
67
|
+
readonly size: { width: number; height: number };
|
|
68
|
+
readonly listeners: AbortController;
|
|
69
|
+
readonly resizeObserver: ResizeObserver;
|
|
70
|
+
readonly pointer: { last?: PointerEvent; down?: { readonly x: number; readonly y: number }; hovered?: Hit; frame: number };
|
|
71
|
+
readonly loop: { frame: number; last: number; wasMoving: boolean; seconds: number };
|
|
72
|
+
/** What the next frame redoes, from the options passed since the last */
|
|
73
|
+
readonly pending: Set<Change>;
|
|
74
|
+
/** CPU times in ms of the last frame, pick and repaint, and the last frame's draw calls, post-processing included */
|
|
75
|
+
readonly stats: { frames: number; frameMs: number; drawCalls: number; pickMs: number; paintMs: number };
|
|
76
|
+
structure: StructureState;
|
|
77
|
+
compiled?: CompiledScene;
|
|
78
|
+
built?: BuiltScene;
|
|
79
|
+
gizmo?: ViewportGizmo;
|
|
80
|
+
path?: RenderPath;
|
|
81
|
+
governor?: TierGovernor;
|
|
82
|
+
readonly environments: Partial<Record<"studio" | "room", Texture>>;
|
|
83
|
+
/** The scene is built and its shaders compiled */
|
|
84
|
+
loaded: boolean;
|
|
85
|
+
fitted: boolean;
|
|
86
|
+
disposed: boolean;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** Pointer travel in CSS pixels below which a press and release is a click, not a drag */
|
|
90
|
+
const clickTolerance = 4;
|
|
91
|
+
|
|
92
|
+
export function createViewer<Content>(container: HTMLElement, options: ViewerOptions<Content>): Viewer<Content> {
|
|
93
|
+
if (getComputedStyle(container).position === "static") {
|
|
94
|
+
container.style.position = "relative";
|
|
95
|
+
}
|
|
96
|
+
const canvas = document.createElement("canvas");
|
|
97
|
+
// Absolutely positioned, so the canvas' own size never feeds back into the container's
|
|
98
|
+
canvas.style.cssText = "position:absolute;inset:0;display:block;width:100%;height:100%;touch-action:none";
|
|
99
|
+
container.prepend(canvas);
|
|
100
|
+
// Khronos PBR Neutral tone mapping keeps product colors true; the canvas is transparent, as r3f's
|
|
101
|
+
const renderer = new WebGLRenderer({ canvas, antialias: true, alpha: true });
|
|
102
|
+
Object.assign(renderer, { toneMapping: NeutralToneMapping });
|
|
103
|
+
renderer.setClearColor(0x000000, 0);
|
|
104
|
+
renderer.info.autoReset = false;
|
|
105
|
+
const cameras = { Perspective: new PerspectiveCamera(45), Orthographic: new OrthographicCamera() };
|
|
106
|
+
const camera = cameras[options.camera?.type ?? "Perspective"];
|
|
107
|
+
const v: Viewer<Content> = {
|
|
108
|
+
options,
|
|
109
|
+
container,
|
|
110
|
+
canvas,
|
|
111
|
+
renderer,
|
|
112
|
+
scene: new ThreeScene(),
|
|
113
|
+
lights: new Group(),
|
|
114
|
+
cameras,
|
|
115
|
+
camera,
|
|
116
|
+
controls: createControls(camera, canvas, options.controls ?? {}, () => invalidate(v)),
|
|
117
|
+
geometries: new Map(),
|
|
118
|
+
atlas: createGlyphAtlas(),
|
|
119
|
+
textures: new Map(),
|
|
120
|
+
overlays: createOverlayLayer(container),
|
|
121
|
+
size: { width: 0, height: 0 },
|
|
122
|
+
listeners: new AbortController(),
|
|
123
|
+
resizeObserver: new ResizeObserver(([entry]) => entry && onResize(v, entry.contentRect)),
|
|
124
|
+
pointer: { frame: 0 },
|
|
125
|
+
loop: { frame: 0, last: 0, wasMoving: false, seconds: 0 },
|
|
126
|
+
pending: new Set(["compile", "build", "camera", "controls", "gizmo", "lights", "quality", "paint", "overlays"]),
|
|
127
|
+
stats: { frames: 0, frameMs: 0, drawCalls: 0, pickMs: 0, paintMs: 0 },
|
|
128
|
+
structure: { activeComponents: options.activeComponents, relationsActive: options.activeRelations !== undefined },
|
|
129
|
+
environments: {},
|
|
130
|
+
loaded: false,
|
|
131
|
+
fitted: false,
|
|
132
|
+
disposed: false,
|
|
133
|
+
};
|
|
134
|
+
v.scene.add(v.lights);
|
|
135
|
+
const signal = { signal: v.listeners.signal };
|
|
136
|
+
canvas.addEventListener("pointermove", (e) => onPointerMove(v, e), signal);
|
|
137
|
+
canvas.addEventListener("pointerleave", (e) => setHovered(v, undefined, e), signal);
|
|
138
|
+
canvas.addEventListener("pointerdown", (e) => (v.pointer.down = { x: e.clientX, y: e.clientY }), signal);
|
|
139
|
+
canvas.addEventListener("click", (e) => onClick(v, e), signal);
|
|
140
|
+
canvas.addEventListener("contextmenu", (e) => onContextMenu(v, e), signal);
|
|
141
|
+
v.resizeObserver.observe(container);
|
|
142
|
+
return v;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Sets the options passed, redone in the next frame; what each redoes is in `effects`, so pass only the ones that changed */
|
|
146
|
+
export function updateViewer<Content>(v: Viewer<Content>, options: Partial<ViewerOptions<Content>>): void {
|
|
147
|
+
v.options = { ...v.options, ...options };
|
|
148
|
+
Object.keys(options).forEach((key) => effects[key as keyof ViewerOptions<Content>].forEach((change) => v.pending.add(change)));
|
|
149
|
+
invalidate(v);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Renders a frame on the next animation frame, e.g. after changing objects added to `scene` */
|
|
153
|
+
export function invalidate<Content>(v: Viewer<Content>): void {
|
|
154
|
+
if (!v.loop.frame && !v.disposed && v.size.width > 0 && v.size.height > 0) {
|
|
155
|
+
v.loop.frame = requestAnimationFrame((now) => renderFrame(v, now));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function disposeViewer<Content>(v: Viewer<Content>): void {
|
|
160
|
+
v.disposed = true;
|
|
161
|
+
cancelAnimationFrame(v.loop.frame);
|
|
162
|
+
cancelAnimationFrame(v.pointer.frame);
|
|
163
|
+
v.listeners.abort();
|
|
164
|
+
v.resizeObserver.disconnect();
|
|
165
|
+
v.controls.orbit.dispose();
|
|
166
|
+
v.gizmo?.dispose();
|
|
167
|
+
if (v.path) {
|
|
168
|
+
disposeRenderPath(v.path);
|
|
169
|
+
}
|
|
170
|
+
if (v.built) {
|
|
171
|
+
disposeScene(v.built);
|
|
172
|
+
}
|
|
173
|
+
Object.values(v.environments).forEach((e) => e.dispose());
|
|
174
|
+
v.geometries.forEach((g) => g.dispose());
|
|
175
|
+
v.atlas.texture.dispose();
|
|
176
|
+
disposeTextures(v.textures);
|
|
177
|
+
setOverlays(v.overlays, [], v.options.onOverlays);
|
|
178
|
+
v.overlays.renderer.domElement.remove();
|
|
179
|
+
v.renderer.dispose();
|
|
180
|
+
v.canvas.remove();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Redoes what the changes need, in dependency order */
|
|
184
|
+
function apply<Content>(v: Viewer<Content>, changes: ReadonlySet<Change>): void {
|
|
185
|
+
const { options } = v;
|
|
186
|
+
if (changes.has("compile")) {
|
|
187
|
+
v.compiled = options.scene && compileScene(options.scene, options.createGroupId);
|
|
188
|
+
v.pointer.hovered = undefined;
|
|
189
|
+
}
|
|
190
|
+
if (changes.has("build")) {
|
|
191
|
+
v.structure = { activeComponents: options.activeComponents, relationsActive: options.activeRelations !== undefined };
|
|
192
|
+
rebuild(v);
|
|
193
|
+
}
|
|
194
|
+
if (changes.has("camera")) {
|
|
195
|
+
const { near = 0.1, far = 2000, ...rest } = options.camera ?? { type: "Perspective" };
|
|
196
|
+
v.camera = v.cameras[rest.type];
|
|
197
|
+
Object.assign(v.camera, { near, far, ...("fov" in rest && rest.fov !== undefined ? { fov: rest.fov } : {}) });
|
|
198
|
+
v.controls.orbit.object = v.camera;
|
|
199
|
+
}
|
|
200
|
+
if (changes.has("controls")) {
|
|
201
|
+
configureControls(v.controls, options.controls ?? {});
|
|
202
|
+
}
|
|
203
|
+
// As the r3f renderer, the scene is fitted at first, and for a new camera or canvas size
|
|
204
|
+
if ((changes.has("build") && !v.fitted) || changes.has("camera")) {
|
|
205
|
+
fitPose(v);
|
|
206
|
+
}
|
|
207
|
+
if (changes.has("gizmo") || changes.has("camera")) {
|
|
208
|
+
updateGizmo(v);
|
|
209
|
+
}
|
|
210
|
+
if (changes.has("lights")) {
|
|
211
|
+
updateLights(v);
|
|
212
|
+
}
|
|
213
|
+
if (changes.has("quality")) {
|
|
214
|
+
const quality = options.quality ?? "low";
|
|
215
|
+
v.governor = { quality, tier: quality === "auto" ? "medium" : quality, sum: 0, count: 0 };
|
|
216
|
+
}
|
|
217
|
+
if (changes.has("quality") || changes.has("camera")) {
|
|
218
|
+
updateRenderPath(v);
|
|
219
|
+
}
|
|
220
|
+
if ((changes.has("paint") || changes.has("build")) && v.built) {
|
|
221
|
+
const start = performance.now();
|
|
222
|
+
paintScene(v.built, {
|
|
223
|
+
...v.structure,
|
|
224
|
+
selectedIds: options.selectedIds,
|
|
225
|
+
hoveredIds: new Set(options.hoveredIds),
|
|
226
|
+
hoveredTarget: v.pointer.hovered?.target,
|
|
227
|
+
dimensionsClickable: options.onClickGroup !== undefined,
|
|
228
|
+
});
|
|
229
|
+
v.stats.paintMs = performance.now() - start;
|
|
230
|
+
}
|
|
231
|
+
if (changes.has("dimensions") && v.built) {
|
|
232
|
+
v.built.dimensions.visible = options.showDimensions ?? true;
|
|
233
|
+
}
|
|
234
|
+
if (changes.has("overlays") || changes.has("build")) {
|
|
235
|
+
updateOverlays(v);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function rebuild<Content>(v: Viewer<Content>): void {
|
|
240
|
+
if (v.built) {
|
|
241
|
+
disposeScene(v.built);
|
|
242
|
+
}
|
|
243
|
+
const { options, compiled } = v;
|
|
244
|
+
v.built =
|
|
245
|
+
compiled &&
|
|
246
|
+
buildScene(compiled, {
|
|
247
|
+
...options,
|
|
248
|
+
structure: v.structure,
|
|
249
|
+
geometries: v.geometries,
|
|
250
|
+
atlas: v.atlas,
|
|
251
|
+
textures: v.textures,
|
|
252
|
+
onTextureLoaded: () => invalidate(v),
|
|
253
|
+
});
|
|
254
|
+
if (v.built) {
|
|
255
|
+
v.scene.add(v.built.root);
|
|
256
|
+
v.built.dimensions.visible = options.showDimensions ?? true;
|
|
257
|
+
// Compiled in parallel where the driver can, as three.js's compileAsync example
|
|
258
|
+
v.renderer
|
|
259
|
+
.compileAsync(v.scene, v.camera)
|
|
260
|
+
.then(() => onLoaded(v))
|
|
261
|
+
.catch(() => undefined);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function onLoaded<Content>(v: Viewer<Content>): void {
|
|
266
|
+
if (!v.disposed) {
|
|
267
|
+
v.loaded = true;
|
|
268
|
+
v.options.onLoad?.();
|
|
269
|
+
invalidate(v);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function renderFrame<Content>(v: Viewer<Content>, now: number): void {
|
|
274
|
+
const { loop, renderer } = v;
|
|
275
|
+
const start = performance.now();
|
|
276
|
+
const interval = loop.last ? now - loop.last : 0;
|
|
277
|
+
loop.frame = 0;
|
|
278
|
+
loop.last = now;
|
|
279
|
+
if (v.pending.size > 0) {
|
|
280
|
+
apply(v, new Set(v.pending));
|
|
281
|
+
v.pending.clear();
|
|
282
|
+
}
|
|
283
|
+
const { built, camera, gizmo } = v;
|
|
284
|
+
renderer.info.reset();
|
|
285
|
+
const moving = v.controls.orbit.update(Math.min(interval / 1000, 0.1)) || !!gizmo?.animating;
|
|
286
|
+
if (moving && loop.wasMoving && v.governor && recordFrame(v.governor, interval)) {
|
|
287
|
+
updateRenderPath(v);
|
|
288
|
+
}
|
|
289
|
+
loop.wasMoving = moving;
|
|
290
|
+
const animated = !!built && built.animatedItems.length > 0;
|
|
291
|
+
if (animated) {
|
|
292
|
+
loop.seconds += Math.min(interval / 1000, 0.1);
|
|
293
|
+
animateScene(built, loop.seconds);
|
|
294
|
+
}
|
|
295
|
+
camera.updateMatrixWorld();
|
|
296
|
+
if (built) {
|
|
297
|
+
cullScene(built, camera.position);
|
|
298
|
+
}
|
|
299
|
+
const fading = v.loaded && v.path ? renderPath(v.path, renderer, v.scene, camera, moving || animated) : false;
|
|
300
|
+
gizmo?.render();
|
|
301
|
+
v.overlays.renderer.render(v.overlays.scene, camera);
|
|
302
|
+
Object.assign(v.stats, { frames: v.stats.frames + 1, frameMs: performance.now() - start, drawCalls: renderer.info.render.calls });
|
|
303
|
+
if (moving || animated || fading) {
|
|
304
|
+
invalidate(v);
|
|
305
|
+
} else {
|
|
306
|
+
loop.last = 0;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function onResize<Content>(v: Viewer<Content>, rect: DOMRectReadOnly): void {
|
|
311
|
+
Object.assign(v.size, { width: rect.width, height: rect.height });
|
|
312
|
+
v.renderer.setSize(rect.width, rect.height, false);
|
|
313
|
+
v.path?.composer?.setSize(rect.width, rect.height);
|
|
314
|
+
v.overlays.renderer.setSize(rect.width, rect.height);
|
|
315
|
+
v.gizmo?.update();
|
|
316
|
+
fitPose(v);
|
|
317
|
+
invalidate(v);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Fits the projection to the scene, and moves the camera to look at it from the view */
|
|
321
|
+
function fitPose<Content>(v: Viewer<Content>): void {
|
|
322
|
+
const placement = fitScene(v);
|
|
323
|
+
if (placement) {
|
|
324
|
+
const { x, y, z } = placement.direction;
|
|
325
|
+
setPose(v.controls, new Vector3(x, y, z).multiplyScalar(placement.distance), new Vector3());
|
|
326
|
+
v.fitted = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function fitScene<Content>(v: Viewer<Content>): Placement | undefined {
|
|
331
|
+
const { scene, view = "front", bufferZones = {}, fitPadding = 0 } = v.options;
|
|
332
|
+
return scene && fitCamera(v.camera, { view, size: scene.size_deprecated, canvas: v.size, bufferZones, fitPadding });
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function updateGizmo<Content>(v: Viewer<Content>): void {
|
|
336
|
+
v.gizmo?.dispose();
|
|
337
|
+
const { gizmo } = v.options;
|
|
338
|
+
v.gizmo = gizmo && createGizmo(v.camera, v.renderer, v.container, gizmo).attachControls(v.controls.orbit);
|
|
339
|
+
v.gizmo?.addEventListener("change", () => invalidate(v));
|
|
340
|
+
v.gizmo?.addEventListener("start", () => onGizmoStart(v));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* A click turns the camera, which can also move the target back to the scene's center and fit the scene. The gizmo turns around its target at the
|
|
345
|
+
* distance it read when pressed, its internal `_distance`, so that's set to the fitted one
|
|
346
|
+
*/
|
|
347
|
+
function onGizmoStart<Content>(v: Viewer<Content>): void {
|
|
348
|
+
const { gizmo } = v.options;
|
|
349
|
+
const reset = gizmo?.type === "Viewcube" ? gizmo.viewcubeProps?.resetZoomAndPanOnClick : gizmo?.viewportProps?.resetZoomAndPanOnClick;
|
|
350
|
+
const placement = v.gizmo?.animating && reset ? fitScene(v) : undefined;
|
|
351
|
+
if (placement) {
|
|
352
|
+
v.controls.orbit.target.set(0, 0, 0);
|
|
353
|
+
Object.assign(v.gizmo!, { _distance: placement.distance });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function onPointerMove<Content>(v: Viewer<Content>, event: PointerEvent): void {
|
|
358
|
+
v.pointer.last = event;
|
|
359
|
+
v.pointer.frame ||= requestAnimationFrame(() => hoverAtPointer(v));
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** One pick per frame at most, paused while the camera is dragged, as the r3f renderer's ControlsWrapper paused pointer events */
|
|
363
|
+
function hoverAtPointer<Content>(v: Viewer<Content>): void {
|
|
364
|
+
v.pointer.frame = 0;
|
|
365
|
+
if (v.pointer.last && !v.controls.drag.moved) {
|
|
366
|
+
setHovered(v, pick(v, v.pointer.last), v.pointer.last);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function onClick<Content>(v: Viewer<Content>, event: MouseEvent): void {
|
|
371
|
+
const { down } = v.pointer;
|
|
372
|
+
const hit = down && Math.hypot(event.clientX - down.x, event.clientY - down.y) <= clickTolerance ? pick(v, event) : undefined;
|
|
373
|
+
const target = hit && v.compiled!.targets[hit.target];
|
|
374
|
+
const args = hit && getGroupArgs(v, hit);
|
|
375
|
+
if (hit && target?.kind === "relation") {
|
|
376
|
+
v.options.onClickRelation?.(target.relation, { nativeEvent: event, point: hit.point });
|
|
377
|
+
} else if (hit && args) {
|
|
378
|
+
v.options.onClickGroup?.(...args, { nativeEvent: event, point: hit.point });
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function onContextMenu<Content>(v: Viewer<Content>, event: MouseEvent): void {
|
|
383
|
+
const hit = pick(v, event);
|
|
384
|
+
const args = hit && getGroupArgs(v, hit);
|
|
385
|
+
if (hit && args) {
|
|
386
|
+
v.options.onContextMenuGroup?.(...args, event.x, event.y, { nativeEvent: event, point: hit.point });
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function setHovered<Content>(v: Viewer<Content>, hit: Hit | undefined, event: PointerEvent): void {
|
|
391
|
+
const previous = v.pointer.hovered;
|
|
392
|
+
v.pointer.hovered = hit;
|
|
393
|
+
v.canvas.style.cursor = hit ? "pointer" : "";
|
|
394
|
+
if (hit?.target === previous?.target) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (previous && getGroupArgs(v, previous)) {
|
|
398
|
+
v.options.onHoverGroup?.(undefined, undefined, undefined, { nativeEvent: event, point: previous.point });
|
|
399
|
+
}
|
|
400
|
+
const args = hit && getGroupArgs(v, hit);
|
|
401
|
+
if (hit && args) {
|
|
402
|
+
v.options.onHoverGroup?.(...args, { nativeEvent: event, point: hit.point });
|
|
403
|
+
}
|
|
404
|
+
v.pending.add("paint").add("overlays");
|
|
405
|
+
invalidate(v);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** The first interactive item under the pointer: groups with an id that aren't disabled, clickable dimensions and active relations */
|
|
409
|
+
function pick<Content>(v: Viewer<Content>, event: MouseEvent): Hit | undefined {
|
|
410
|
+
const { built } = v;
|
|
411
|
+
if (!built) {
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
const start = performance.now();
|
|
415
|
+
const rect = v.canvas.getBoundingClientRect();
|
|
416
|
+
raycaster.setFromCamera(ndc.set(((event.clientX - rect.left) / rect.width) * 2 - 1, -((event.clientY - rect.top) / rect.height) * 2 + 1), v.camera);
|
|
417
|
+
const hits = raycaster.intersectObjects(getPickables(built), false);
|
|
418
|
+
v.stats.pickMs = performance.now() - start;
|
|
419
|
+
for (const hit of hits) {
|
|
420
|
+
const item = getPickedItem(built, hit);
|
|
421
|
+
const target = item === undefined ? undefined : built.compiled.items[item]!.target;
|
|
422
|
+
const kind = target === undefined ? undefined : built.compiled.targets[target]!;
|
|
423
|
+
const interactive =
|
|
424
|
+
kind?.kind === "group"
|
|
425
|
+
? kind.id !== "" && !built.targetStates[target!]!.disabled
|
|
426
|
+
: kind?.kind === "dimension"
|
|
427
|
+
? kind.id !== undefined && v.options.activeRelations === undefined && v.options.onClickGroup !== undefined
|
|
428
|
+
: kind !== undefined;
|
|
429
|
+
if (interactive) {
|
|
430
|
+
return { item: item!, target: target!, point: hit.point.clone() };
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/** The id, top-level group's data and the hit mesh's group's data of a group or dimension hit */
|
|
437
|
+
function getGroupArgs<Content>(
|
|
438
|
+
v: Viewer<Content>,
|
|
439
|
+
hit: Hit
|
|
440
|
+
): readonly [string, Record<string, string> | undefined, Record<string, string> | undefined] | undefined {
|
|
441
|
+
const target = v.compiled!.targets[hit.target]!;
|
|
442
|
+
switch (target.kind) {
|
|
443
|
+
case "group":
|
|
444
|
+
return [target.id, target.rootData, v.compiled!.items[hit.item]!.data];
|
|
445
|
+
case "dimension":
|
|
446
|
+
return [target.id!, undefined, undefined];
|
|
447
|
+
default:
|
|
448
|
+
return undefined;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function updateLights<Content>(v: Viewer<Content>): void {
|
|
453
|
+
const { scene, lights, environment = "studio", environmentIntensity = 1 } = v.options;
|
|
454
|
+
v.lights.clear();
|
|
455
|
+
const objects = typeof lights === "function" ? (scene ? lights(scene) : []) : (lights ?? createLights());
|
|
456
|
+
objects.forEach((o) => v.lights.add(o));
|
|
457
|
+
if (typeof environment === "string") {
|
|
458
|
+
v.environments[environment] ??= createEnvironment(environment, v.renderer);
|
|
459
|
+
}
|
|
460
|
+
Object.assign(v.scene, { environment: typeof environment === "string" ? v.environments[environment] : environment, environmentIntensity });
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* A weak ambient light, so the environment lights faces by which way they turn, with a key light from the upper left for shading and highlights and
|
|
465
|
+
* two fills. Directional lights shine towards the origin, the scene's center, so only their positions' directions matter
|
|
466
|
+
*/
|
|
467
|
+
function createLights(): ReadonlyArray<Object3D> {
|
|
468
|
+
const directional = [
|
|
469
|
+
[-1.9, 1, 0, 3],
|
|
470
|
+
[0, 1, 0.94, 1.2],
|
|
471
|
+
[3.9, 0, 1, 0.3],
|
|
472
|
+
] as const;
|
|
473
|
+
return [
|
|
474
|
+
new AmbientLight(0xffffff, 0.2),
|
|
475
|
+
...directional.map(([x, y, z, i]) => {
|
|
476
|
+
const light = new DirectionalLight(0xffffff, i);
|
|
477
|
+
light.position.set(x, y, z);
|
|
478
|
+
return light;
|
|
479
|
+
}),
|
|
480
|
+
];
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Studio: an equirectangular gradient from a white ceiling to a dark floor, with three softboxes 20-50° up, so faces are brighter from above than
|
|
485
|
+
* from below and metal profiles and panels get reflections. Room: three.js's RoomEnvironment through PMREM, as its examples light models
|
|
486
|
+
*/
|
|
487
|
+
function createEnvironment(kind: "studio" | "room", renderer: WebGLRenderer): Texture {
|
|
488
|
+
if (kind === "room") {
|
|
489
|
+
const pmrem = new PMREMGenerator(renderer);
|
|
490
|
+
const texture = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;
|
|
491
|
+
pmrem.dispose();
|
|
492
|
+
return texture;
|
|
493
|
+
}
|
|
494
|
+
const canvas = Object.assign(document.createElement("canvas"), { width: 1024, height: 512 });
|
|
495
|
+
const ctx = canvas.getContext("2d")!;
|
|
496
|
+
const gradient = ctx.createLinearGradient(0, 0, 0, 512);
|
|
497
|
+
gradient.addColorStop(0, "#ffffff");
|
|
498
|
+
gradient.addColorStop(0.45, "#d8d8d8");
|
|
499
|
+
gradient.addColorStop(0.55, "#8a8a8a");
|
|
500
|
+
gradient.addColorStop(1, "#5a5a5a");
|
|
501
|
+
Object.assign(ctx, { fillStyle: gradient }).fillRect(0, 0, 1024, 512);
|
|
502
|
+
ctx.fillStyle = "#ffffff";
|
|
503
|
+
[
|
|
504
|
+
[80, 120],
|
|
505
|
+
[400, 90],
|
|
506
|
+
[700, 140],
|
|
507
|
+
].forEach(([x, width]) => ctx.fillRect(x!, 110, width!, 90));
|
|
508
|
+
return Object.assign(new CanvasTexture(canvas), { mapping: EquirectangularReflectionMapping, colorSpace: SRGBColorSpace });
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function updateOverlays<Content>(v: Viewer<Content>): void {
|
|
512
|
+
const { compiled, options } = v;
|
|
513
|
+
const target = v.pointer.hovered && compiled?.targets[v.pointer.hovered.target];
|
|
514
|
+
const overlays: Array<Overlay<Content>> = [];
|
|
515
|
+
options.popovers?.forEach(
|
|
516
|
+
(p) =>
|
|
517
|
+
compiled &&
|
|
518
|
+
overlays.push({ key: `popover:${p.id}`, position: new Vector3(p.pos.x, p.pos.y, p.pos.z).applyMatrix4(compiled.matrix), content: p.content })
|
|
519
|
+
);
|
|
520
|
+
if (target?.kind === "group") {
|
|
521
|
+
options.getTooltips?.(target.id).forEach((p) =>
|
|
522
|
+
overlays.push({
|
|
523
|
+
key: `tooltip:${p.id}`,
|
|
524
|
+
position: new Vector3(p.pos.x, p.pos.y, p.pos.z).applyMatrix4(compiled!.roots[target.root]!),
|
|
525
|
+
content: p.content,
|
|
526
|
+
})
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
setOverlays(v.overlays, overlays, options.onOverlays);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function updateRenderPath<Content>(v: Viewer<Content>): void {
|
|
533
|
+
if (v.path) {
|
|
534
|
+
disposeRenderPath(v.path);
|
|
535
|
+
}
|
|
536
|
+
v.path = createRenderPath(v.renderer, v.scene, v.camera, v.governor?.tier ?? "low");
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const raycaster = new Raycaster();
|
|
540
|
+
const ndc = new Vector2();
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Color } from "abstract-image";
|
|
2
|
-
import { Vec3 } from "../../abstract-3d.js";
|
|
3
|
-
export declare function colorToInteger(color: string): number;
|
|
4
|
-
export declare function colorHexFromAbstractImageColor(color: Color): string;
|
|
5
|
-
export declare function color(colorNormal: string | undefined): number;
|
|
6
|
-
export declare const ACI_COLOR_TABLE: ReadonlyArray<Vec3>;
|
|
7
|
-
//# sourceMappingURL=color.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../../src/renderers/dxf/color.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAyB,MAAM,sBAAsB,CAAC;AAEnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEnE;AAED,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAqB7D;AAsBD,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,IAAI,CAiQ/C,CAAC"}
|