@hatiolab/figure-model 0.1.76 → 0.1.78
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 +12 -0
- package/README.md +60 -138
- package/dist/index.d.ts +1 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -26
- package/dist/index.js.map +1 -1
- package/dist/v3-asset-types.d.ts +1 -2
- package/dist/v3-asset-types.d.ts.map +1 -1
- package/dist/v3-asset.js +1 -1
- package/dist/v3-asset.js.map +1 -1
- package/dist/v3-authoring-actions.d.ts +9 -12
- package/dist/v3-authoring-actions.d.ts.map +1 -1
- package/dist/v3-authoring-actions.js +4 -5
- package/dist/v3-authoring-actions.js.map +1 -1
- package/dist/v3-capabilities.js +4 -1
- package/dist/v3-capabilities.js.map +1 -1
- package/dist/v3-cost.d.ts.map +1 -1
- package/dist/v3-cost.js +3 -5
- package/dist/v3-cost.js.map +1 -1
- package/dist/v3-create.d.ts +1 -1
- package/dist/v3-create.d.ts.map +1 -1
- package/dist/v3-examples.js +1 -1
- package/dist/v3-gate.d.ts +7 -8
- package/dist/v3-gate.d.ts.map +1 -1
- package/dist/v3-gate.js +11 -14
- package/dist/v3-gate.js.map +1 -1
- package/dist/v3-graph.d.ts +1 -2
- package/dist/v3-graph.d.ts.map +1 -1
- package/dist/v3-graph.js +5 -7
- package/dist/v3-graph.js.map +1 -1
- package/dist/v3-instance-size.d.ts +3 -5
- package/dist/v3-instance-size.d.ts.map +1 -1
- package/dist/v3-instance-size.js +2 -4
- package/dist/v3-instance-size.js.map +1 -1
- package/dist/v3-kernel-version.d.ts +1 -1
- package/dist/v3-kernel-version.js +1 -1
- package/dist/v3-part-edit.d.ts +4 -5
- package/dist/v3-part-edit.d.ts.map +1 -1
- package/dist/v3-part-edit.js +2 -2
- package/dist/v3-part-edit.js.map +1 -1
- package/dist/v3-proposal.js +1 -1
- package/dist/v3-proposal.js.map +1 -1
- package/dist/v3-release-contract.js +1 -1
- package/dist/v3-release-contract.js.map +1 -1
- package/dist/v3-score.d.ts +4 -5
- package/dist/v3-score.d.ts.map +1 -1
- package/dist/v3-score.js +7 -8
- package/dist/v3-score.js.map +1 -1
- package/dist/v3-words.d.ts +105 -0
- package/dist/v3-words.d.ts.map +1 -0
- package/dist/v3-words.js +107 -0
- package/dist/v3-words.js.map +1 -0
- package/docs/assembly-constraints-v3.md +13 -23
- package/docs/v3-asset-persistence.md +4 -4
- package/docs/v3-common-kernel-experiment.md +1 -1
- package/docs/v3-core-semantics.md +3 -3
- package/docs/v3-cutover.md +5 -3
- package/docs/v3-design.md +13 -26
- package/docs/v3-editor-integration.md +2 -2
- package/docs/v3-full-conveyor-validation.md +3 -3
- package/docs/v3-layout-system.md +1 -1
- package/docs/v3-minimal-model.md +0 -1
- package/docs/v3-motion-contract.md +21 -56
- package/docs/v3-runtime-extraction.md +7 -7
- package/docs/v3-sample-validation-expanded.md +1 -1
- package/docs/v3-sample-validation.md +1 -1
- package/docs/v3-shape-dimension-contract.md +23 -57
- package/docs/v3-status.md +5 -5
- package/docs/v3-storage-integration.md +4 -4
- package/package.json +2 -20
- package/dist/blueprint-shape.d.ts +0 -10
- package/dist/blueprint-shape.d.ts.map +0 -1
- package/dist/blueprint-shape.js +0 -194
- package/dist/blueprint-shape.js.map +0 -1
- package/dist/blueprint.d.ts +0 -73
- package/dist/blueprint.d.ts.map +0 -1
- package/dist/blueprint.js +0 -388
- package/dist/blueprint.js.map +0 -1
- package/dist/cost-chart.d.ts +0 -35
- package/dist/cost-chart.d.ts.map +0 -1
- package/dist/cost-chart.js +0 -150
- package/dist/cost-chart.js.map +0 -1
- package/dist/cost.d.ts +0 -162
- package/dist/cost.d.ts.map +0 -1
- package/dist/cost.js +0 -194
- package/dist/cost.js.map +0 -1
- package/dist/gate.d.ts +0 -65
- package/dist/gate.d.ts.map +0 -1
- package/dist/gate.js +0 -284
- package/dist/gate.js.map +0 -1
- package/dist/grouping.d.ts +0 -121
- package/dist/grouping.d.ts.map +0 -1
- package/dist/grouping.js +0 -224
- package/dist/grouping.js.map +0 -1
- package/dist/keys.d.ts +0 -45
- package/dist/keys.d.ts.map +0 -1
- package/dist/keys.js +0 -84
- package/dist/keys.js.map +0 -1
- package/dist/origin.d.ts +0 -33
- package/dist/origin.d.ts.map +0 -1
- package/dist/origin.js +0 -46
- package/dist/origin.js.map +0 -1
- package/dist/release-contract.d.ts +0 -38
- package/dist/release-contract.d.ts.map +0 -1
- package/dist/release-contract.js +0 -246
- package/dist/release-contract.js.map +0 -1
- package/dist/sizing.d.ts +0 -231
- package/dist/sizing.d.ts.map +0 -1
- package/dist/sizing.js +0 -550
- package/dist/sizing.js.map +0 -1
- package/dist/types.d.ts +0 -1233
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -547
- package/dist/types.js.map +0 -1
- package/dist/v3-from-v2.d.ts +0 -203
- package/dist/v3-from-v2.d.ts.map +0 -1
- package/dist/v3-from-v2.js +0 -2053
- package/dist/v3-from-v2.js.map +0 -1
- package/dist/v3-mesh-compare.d.ts +0 -24
- package/dist/v3-mesh-compare.d.ts.map +0 -1
- package/dist/v3-mesh-compare.js +0 -55
- package/dist/v3-mesh-compare.js.map +0 -1
- package/dist/validate.d.ts +0 -7
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -1119
- package/dist/validate.js.map +0 -1
- package/dist/visual-evidence.d.ts +0 -21
- package/dist/visual-evidence.d.ts.map +0 -1
- package/dist/visual-evidence.js +0 -52
- package/dist/visual-evidence.js.map +0 -1
- package/docs/design.md +0 -193
- package/docs/format-survey.md +0 -108
- package/docs/format.md +0 -704
- package/docs/sizing.md +0 -183
- package/docs/validation.md +0 -357
package/dist/blueprint.js
DELETED
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
-
*
|
|
4
|
-
* 원본 데이터 → 청사진 컴파일.
|
|
5
|
-
*
|
|
6
|
-
* 원본 데이터는 편집을 위한 형식이다. 씬이 그것을 그대로 렌더링하면 부품마다 mesh 가 생겨서
|
|
7
|
-
* 자산 500 개 × 부품 8 개 = 4000 draw call 이 된다. 청사진은 그것을 줄인 형식이다.
|
|
8
|
-
*
|
|
9
|
-
* 핵심은 **병합**이다. 같은 재질·슬롯을 쓰고 애니메이션이 없는 부품을 한 묶음으로
|
|
10
|
-
* 묶는다. 3D 는 그 묶음의 geometry 를 합치고, 2D 는 윤곽을 한 path 로 합쳐 한 번에
|
|
11
|
-
* 채운다. 병목이 양쪽 다 묶음 수여서 같은 병합이 함께 값을 한다.
|
|
12
|
-
*
|
|
13
|
-
* 자산당 묶음 수 = 재질·슬롯 조합 수 + 애니메이션 포인트 수 + 크기 반응이 다른 부품 수
|
|
14
|
-
*
|
|
15
|
-
* **합칠 수 없는 부품이 둘 있다.**
|
|
16
|
-
*
|
|
17
|
-
* 애니메이션이 걸린 부품은 합치지 않는다. 합치면 그 부품만 따로 움직일 수 없다.
|
|
18
|
-
*
|
|
19
|
-
* `sizing` 이 `'scale'` 이 아닌 부품도 합치지 않는다. 이유가 같다 — 합친 geometry 는
|
|
20
|
-
* 변환을 하나만 받는데, `fixed` 는 크기를 그대로 두고 `stretch` 는 한 축만 늘리고
|
|
21
|
-
* `repeat` 는 개수를 바꾼다. 인스턴스마다 다르게 반응해야 하므로 각자 서야 한다.
|
|
22
|
-
*/
|
|
23
|
-
import { validate } from "./validate.js";
|
|
24
|
-
import { centredSource } from "./origin.js";
|
|
25
|
-
import { geometryKeyOf, materialKeyOf, usesSegments } from "./keys.js";
|
|
26
|
-
import { jointFrames, mergeKeyOf, movingNames, standsAlone } from "./grouping.js";
|
|
27
|
-
// 키는 keys.ts 가 기준이 되는 원본이다. 소비처가 쓰던 이름 그대로 다시 내보낸다.
|
|
28
|
-
export { geometryKeyOf, emissiveKeyOf, materialKeyOf, usesSegments } from "./keys.js";
|
|
29
|
-
import { BLUEPRINT_VERSION, DEFAULT_SIZING, FIGURE_SOURCE_VERSION, SEGMENT_PRESETS } from "./types.js";
|
|
30
|
-
/** 컴파일할 수 없을 때 던진다. 오류보고없이 빈 청사진을 돌려주지 않는다. */
|
|
31
|
-
export class FigureCompileError extends Error {
|
|
32
|
-
errors;
|
|
33
|
-
constructor(errors) {
|
|
34
|
-
const head = errors
|
|
35
|
-
.slice(0, 3)
|
|
36
|
-
.map(e => `${e.path || '(root)'}: ${e.message}`)
|
|
37
|
-
.join(' / ');
|
|
38
|
-
super(`정본을 컴파일할 수 없다 — ${errors.length}건. ${head}`);
|
|
39
|
-
this.name = 'FigureCompileError';
|
|
40
|
-
this.errors = errors;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* 삼각형 수 추정.
|
|
45
|
-
*
|
|
46
|
-
* 근거는 things-scene 의 geometry 생성 인자다.
|
|
47
|
-
*
|
|
48
|
-
* cube · wall BoxGeometry 면 6 × 2 = 12
|
|
49
|
-
* cylinder CylinderGeometry(seg) 측면 2·seg + 캡 2·seg = 4·seg
|
|
50
|
-
* 민 것(n 점) ExtrudeGeometry 캡 2·(n−2) + 측면 2·n = 4n − 4
|
|
51
|
-
* 속 판 것 ExtrudeGeometry+구멍 4·(n + m) m 은 안쪽 테의 점 수
|
|
52
|
-
*
|
|
53
|
-
* ## 라운드를 안 세다가 12 배를 놓쳤다
|
|
54
|
-
*
|
|
55
|
-
* 한동안 `rect` 를 라운드와 무관하게 12 로 셌다. 「베벨과 라운드는 세지 않는다」고
|
|
56
|
-
* 적어 두기까지 했다. three 로 실제로 만들어 세어 보면
|
|
57
|
-
*
|
|
58
|
-
* rect 각짐 12 cube 와 같다 — 민다고 비싸지지 않는다
|
|
59
|
-
* rect round=24 140 모서리마다 8 점으로 뽑으므로 테가 36 점이 된다
|
|
60
|
-
* 속 판 rect round=24 160 구멍은 +20 이다. 고리의 캡이 통짜 캡보다 싸다
|
|
61
|
-
*
|
|
62
|
-
* **비싼 것은 미는 것이 아니라 라운드다.** 그리고 라운드는 저작자가 무심코 넣는
|
|
63
|
-
* 값이라, 예산이 12 배 적게 세고 있으면 그 선택의 대가가 화면에 안 나타난다.
|
|
64
|
-
*
|
|
65
|
-
* 그리는 쪽이 테를 몇 점으로 뽑는지(`SEGMENT_PRESETS[0]`)와 **같은 수**를 쓴다.
|
|
66
|
-
* 다르면 재는 값과 그려지는 것이 갈린다.
|
|
67
|
-
*/
|
|
68
|
-
export function trianglesOf(part) {
|
|
69
|
-
const seg = part.segments ?? 12;
|
|
70
|
-
switch (part.primitive) {
|
|
71
|
-
case 'cube':
|
|
72
|
-
case 'wall':
|
|
73
|
-
return 12;
|
|
74
|
-
case 'cylinder':
|
|
75
|
-
return 4 * seg;
|
|
76
|
-
case 'sphere': {
|
|
77
|
-
const h = Math.max(2, Math.round(seg / 2));
|
|
78
|
-
return 2 * seg * (h - 1);
|
|
79
|
-
}
|
|
80
|
-
case 'rect':
|
|
81
|
-
case 'polygon': {
|
|
82
|
-
const n = outlinePointsOf(part);
|
|
83
|
-
const hollow = part.shape?.hollow;
|
|
84
|
-
if (!hollow)
|
|
85
|
-
return 4 * n - 4;
|
|
86
|
-
const m = innerPointsOf(part);
|
|
87
|
-
const ring = 4 * (n + m);
|
|
88
|
-
// 바닥이 0 이면 위아래가 다 뚫린 테두리다 — 덮는 판이 없다.
|
|
89
|
-
const floor = (hollow.floor ?? hollow.wall) > 0 ? 4 * n - 4 : 0;
|
|
90
|
-
return ring + floor;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* 민 단면의 테가 몇 점인가.
|
|
96
|
-
*
|
|
97
|
-
* 라운드가 있으면 모서리 넷이 저마다 곡선이 되고, 그리는 쪽이 곡선 하나를
|
|
98
|
-
* `SEGMENT_PRESETS[0]` 점으로 뽑는다. 곡선 사이를 잇는 직선의 끝점 넷이 더 붙는다.
|
|
99
|
-
*
|
|
100
|
-
* `polygon` 은 라운드를 쓰지 않는다 — 그리는 쪽이 적힌 점을 그대로 잇는다.
|
|
101
|
-
*/
|
|
102
|
-
function outlinePointsOf(part) {
|
|
103
|
-
if (part.primitive === 'polygon')
|
|
104
|
-
return part.shape?.path?.length ?? 3;
|
|
105
|
-
return part.shape?.round ? 4 * SEGMENT_PRESETS[0] + 4 : 4;
|
|
106
|
-
}
|
|
107
|
-
/** 안쪽 테. 벽 두께만큼 들어오므로 라운드가 그만큼 줄고, 0 이 되면 각진 모서리가 된다. */
|
|
108
|
-
function innerPointsOf(part) {
|
|
109
|
-
if (part.primitive === 'polygon')
|
|
110
|
-
return part.shape?.path?.length ?? 3;
|
|
111
|
-
const round = (part.shape?.round ?? 0) - (part.shape?.hollow?.wall ?? 0);
|
|
112
|
-
return round > 0 ? 4 * SEGMENT_PRESETS[0] + 4 : 4;
|
|
113
|
-
}
|
|
114
|
-
/** `sizing` 이 없으면 무엇으로 보나 — 비례 확대가 가장 예측 가능하다. */
|
|
115
|
-
/**
|
|
116
|
-
* 회전까지 반영한 부품의 축별 크기.
|
|
117
|
-
*
|
|
118
|
-
* 회전한 상자의 여덟 꼭짓점을 각 축에 내린 것 — 축에 맞춘 경계다. 회전 행렬은
|
|
119
|
-
* `Rx·Ry·Rz` 이고 three 의 기본 Euler 순서('XYZ')와 같다. 그리는 쪽이 같은 순서로
|
|
120
|
-
* 돌리므로 여기서만 다르면 답이 달라진다.
|
|
121
|
-
*/
|
|
122
|
-
export function rotatedExtentOf(part) {
|
|
123
|
-
const { size, rotation } = part.transform;
|
|
124
|
-
if (!rotation)
|
|
125
|
-
return { ...size };
|
|
126
|
-
const rad = Math.PI / 180;
|
|
127
|
-
const cx = Math.cos((rotation.x ?? 0) * rad);
|
|
128
|
-
const sx = Math.sin((rotation.x ?? 0) * rad);
|
|
129
|
-
const cy = Math.cos((rotation.y ?? 0) * rad);
|
|
130
|
-
const sy = Math.sin((rotation.y ?? 0) * rad);
|
|
131
|
-
const cz = Math.cos((rotation.z ?? 0) * rad);
|
|
132
|
-
const sz = Math.sin((rotation.z ?? 0) * rad);
|
|
133
|
-
// Rx·Ry·Rz 의 세 줄
|
|
134
|
-
const r = [
|
|
135
|
-
[cy * cz, -cy * sz, sy],
|
|
136
|
-
[sx * sy * cz + cx * sz, -sx * sy * sz + cx * cz, -sx * cy],
|
|
137
|
-
[-cx * sy * cz + sx * sz, cx * sy * sz + sx * cz, cx * cy]
|
|
138
|
-
];
|
|
139
|
-
const along = (row) => Math.abs(row[0]) * size.x + Math.abs(row[1]) * size.y + Math.abs(row[2]) * size.z;
|
|
140
|
-
return { x: along(r[0]), y: along(r[1]), z: along(r[2]) };
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* `stretch` 일 때 늘어나는 축.
|
|
144
|
-
*
|
|
145
|
-
* 형식에 축을 적는 자리가 없다. 대신 **부품이 가장 길게 뻗은 축**으로 정한다. 문서가
|
|
146
|
-
* 든 예(프레임 · 벨트 · 레일)가 전부 "길어서 그 물건인 것"이라 이 규칙과 맞는다.
|
|
147
|
-
* 정육면체에 가까운 부품에는 뜻이 없는데, 그런 부품은 애초에 `stretch` 를 쓸 자리가 아니다.
|
|
148
|
-
*
|
|
149
|
-
* **회전을 반영해 측정한다.** 크기만 보면 x 로 길게 그린 레일을 y 로 90° 돌려 세워도 여전히
|
|
150
|
-
* x 라고 답한다. 그러면 레일이 길이가 아니라 두께 쪽으로 늘어난다.
|
|
151
|
-
*
|
|
152
|
-
* 두 축의 길이가 같으면 x → z → y 순으로 정한다. 순서를 정해 두지 않으면 같은 부품이
|
|
153
|
-
* 소비처마다 다른 축으로 늘어난다.
|
|
154
|
-
*
|
|
155
|
-
* **소비처가 저마다 계산하면 안 된다.** 3D 와 2D 톱뷰와 속성 편집기가 같은 답을 내야
|
|
156
|
-
* 하므로 여기 한 곳에서만 정한다.
|
|
157
|
-
*/
|
|
158
|
-
export function stretchAxisOf(part) {
|
|
159
|
-
const { x, y, z } = rotatedExtentOf(part);
|
|
160
|
-
if (x >= z && x >= y)
|
|
161
|
-
return 'x';
|
|
162
|
-
if (z >= y)
|
|
163
|
-
return 'z';
|
|
164
|
-
return 'y';
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* 능력의 닻 — 그리지 않는 자리를 청사진으로 옮긴다.
|
|
168
|
-
*
|
|
169
|
-
* 기하를 안 만든다(`geometryKey`·`triangles` 없음). 자리 계산에 필요한 넷만 실어 나른다.
|
|
170
|
-
*
|
|
171
|
-
* 이름을 `anchorOf` 로 두지 않는다 — 그 이름은 `sizing.ts` 에서 「어느 **면**을 붙잡나」를 뜻한다.
|
|
172
|
-
* 한 형식 안에서 같은 이름이 두 가지를 뜻하면 읽는 사람이 매번 어느 쪽인지 가려야 한다.
|
|
173
|
-
*/
|
|
174
|
-
function capabilityAnchorOf(part) {
|
|
175
|
-
const spec = part.capability;
|
|
176
|
-
/* The part is already centred, so the anchor carries the brand it came with. */
|
|
177
|
-
const at = {
|
|
178
|
-
name: part.name,
|
|
179
|
-
roles: [...spec.roles],
|
|
180
|
-
transform: part.transform,
|
|
181
|
-
sizing: part.sizing ?? DEFAULT_SIZING
|
|
182
|
-
};
|
|
183
|
-
if (part.anchor !== undefined)
|
|
184
|
-
at.anchor = part.anchor;
|
|
185
|
-
if (part.repeat !== undefined)
|
|
186
|
-
at.repeat = part.repeat;
|
|
187
|
-
if (spec.accepts !== undefined)
|
|
188
|
-
at.accepts = spec.accepts;
|
|
189
|
-
if (spec.capacity !== undefined)
|
|
190
|
-
at.capacity = spec.capacity;
|
|
191
|
-
if (spec.direction !== undefined)
|
|
192
|
-
at.direction = spec.direction;
|
|
193
|
-
return at;
|
|
194
|
-
}
|
|
195
|
-
function memberOf(part) {
|
|
196
|
-
/* The part is already centred, so the member carries the brand it came with. */
|
|
197
|
-
const member = {
|
|
198
|
-
name: part.name,
|
|
199
|
-
primitive: part.primitive,
|
|
200
|
-
geometryKey: geometryKeyOf(part),
|
|
201
|
-
transform: part.transform,
|
|
202
|
-
sizing: part.sizing ?? DEFAULT_SIZING,
|
|
203
|
-
triangles: trianglesOf(part)
|
|
204
|
-
};
|
|
205
|
-
if (usesSegments(part.primitive) && part.segments !== undefined)
|
|
206
|
-
member.segments = part.segments;
|
|
207
|
-
if (part.keepRound !== undefined)
|
|
208
|
-
member.keepRound = part.keepRound;
|
|
209
|
-
if (part.anchor !== undefined)
|
|
210
|
-
member.anchor = part.anchor;
|
|
211
|
-
if (part.repeat !== undefined)
|
|
212
|
-
member.repeat = part.repeat;
|
|
213
|
-
if (part.shape !== undefined)
|
|
214
|
-
member.shape = part.shape;
|
|
215
|
-
return member;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Joints as nodes, parents before children (ADR-0066).
|
|
219
|
-
*
|
|
220
|
-
* A joint's parent node is the frame its child's parent part moves in, and `attach` names that part so
|
|
221
|
-
* the runtime can move the origin with it under sizing. The axis is made unit length here, once, so every
|
|
222
|
-
* consumer turns by the same angle per degree.
|
|
223
|
-
*/
|
|
224
|
-
function jointsOf(src, frames) {
|
|
225
|
-
const parentOf = new Map(src.parts.filter(part => part.parent !== undefined).map(part => [part.name, part.parent]));
|
|
226
|
-
const nodes = (src.joints ?? []).map(joint => {
|
|
227
|
-
const length = Math.hypot(joint.axis.x, joint.axis.y, joint.axis.z);
|
|
228
|
-
const node = {
|
|
229
|
-
name: joint.name,
|
|
230
|
-
type: joint.type,
|
|
231
|
-
child: joint.child,
|
|
232
|
-
origin: { ...joint.origin },
|
|
233
|
-
axis: { x: joint.axis.x / length, y: joint.axis.y / length, z: joint.axis.z / length }
|
|
234
|
-
};
|
|
235
|
-
if (joint.limits !== undefined)
|
|
236
|
-
node.limits = { min: joint.limits.min, max: joint.limits.max };
|
|
237
|
-
const attach = parentOf.get(joint.child);
|
|
238
|
-
if (attach !== undefined) {
|
|
239
|
-
node.attach = attach;
|
|
240
|
-
const parent = frames.get(attach);
|
|
241
|
-
if (parent !== undefined)
|
|
242
|
-
node.parent = parent;
|
|
243
|
-
}
|
|
244
|
-
return node;
|
|
245
|
-
});
|
|
246
|
-
// Parents first: a node can be built only once the node it sits in exists.
|
|
247
|
-
const ordered = [];
|
|
248
|
-
const placed = new Set();
|
|
249
|
-
let pending = nodes;
|
|
250
|
-
while (pending.length > 0) {
|
|
251
|
-
const ready = pending.filter(node => node.parent === undefined || placed.has(node.parent));
|
|
252
|
-
// validate refuses cycles, so every pass places at least one node
|
|
253
|
-
for (const node of ready) {
|
|
254
|
-
ordered.push(node);
|
|
255
|
-
placed.add(node.name);
|
|
256
|
-
}
|
|
257
|
-
pending = pending.filter(node => !placed.has(node.name));
|
|
258
|
-
}
|
|
259
|
-
return ordered;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* 원본 데이터를 청사진으로 컴파일한다.
|
|
263
|
-
*
|
|
264
|
-
* `errors` 가 있으면 던진다 — 세울 수 없는 것을 반쯤 세운 청사진으로 돌려주면
|
|
265
|
-
* 어디서 잘못됐는지 알 수 없다. `violations` 는 청사진에 담아 돌려준다. 정책 위반은
|
|
266
|
-
* 컴파일을 막지 않고 숫자로 보인다.
|
|
267
|
-
*/
|
|
268
|
-
export function compile(source) {
|
|
269
|
-
const { errors, violations } = validate(source);
|
|
270
|
-
if (errors.length > 0)
|
|
271
|
-
throw new FigureCompileError(errors);
|
|
272
|
-
/* Everything below reads box-centred coordinates, as the blueprint and the runtime do (origin.ts). */
|
|
273
|
-
const src = centredSource(source);
|
|
274
|
-
const groups = [];
|
|
275
|
-
const animations = src.animations ?? [];
|
|
276
|
-
const parameters = src.parameters ?? [];
|
|
277
|
-
/*
|
|
278
|
-
어느 부품이 **따로 변환되나.** 묶음을 가르는 판단이 이걸 먼저 알아야 한다.
|
|
279
|
-
|
|
280
|
-
파라미터가 모는 부품도 같이 센다 — 값이 몰든 시각이 몰든 **따로 변환되는 부품은 따로
|
|
281
|
-
그린다.** 묶음 수는 구동 방식과 무관하다.
|
|
282
|
-
*/
|
|
283
|
-
const moving = movingNames({ animations, parameters });
|
|
284
|
-
/* Which joint frame each part moves in. Parts merge only within one frame (ADR-0066 decision 4). */
|
|
285
|
-
const frames = jointFrames(src);
|
|
286
|
-
const labels = [];
|
|
287
|
-
const anchors = [];
|
|
288
|
-
const byKey = new Map();
|
|
289
|
-
for (const part of src.parts) {
|
|
290
|
-
if (part.label !== undefined) {
|
|
291
|
-
labels.push({ ...part.label, at: part.name });
|
|
292
|
-
}
|
|
293
|
-
/*
|
|
294
|
-
능력의 닻은 **그리는 목록에 넣지 않는다.** 그리지 않고 세지도 않는다 — `costOf` 가 보는 것이
|
|
295
|
-
`groups` 이므로, 여기서 가르면 자리가 삼각형·묶음·부품 수에 끼어들 길이 없다.
|
|
296
|
-
*/
|
|
297
|
-
const frame = frames.get(part.name);
|
|
298
|
-
if (part.capability !== undefined) {
|
|
299
|
-
const anchor = capabilityAnchorOf(part);
|
|
300
|
-
if (frame !== undefined)
|
|
301
|
-
anchor.joint = frame;
|
|
302
|
-
anchors.push(anchor);
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
if (moving.has(part.name)) {
|
|
306
|
-
// clip 이 움직이는 부품은 단독 묶음이다 — 합치면 따로 움직일 수 없다
|
|
307
|
-
const group = {
|
|
308
|
-
materialKey: materialKeyOf(part),
|
|
309
|
-
material: part.material,
|
|
310
|
-
animated: true,
|
|
311
|
-
members: [memberOf(part)]
|
|
312
|
-
};
|
|
313
|
-
if (part.materialSlot !== undefined)
|
|
314
|
-
group.materialSlot = part.materialSlot;
|
|
315
|
-
if (frame !== undefined)
|
|
316
|
-
group.joint = frame;
|
|
317
|
-
groups.push(group);
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
if (standsAlone(part, moving)) {
|
|
321
|
-
// 크기 반응이 다른 부품도 단독 묶음이다 — 합친 geometry 는 변환을 하나만 받는다
|
|
322
|
-
const group = {
|
|
323
|
-
materialKey: materialKeyOf(part),
|
|
324
|
-
material: part.material,
|
|
325
|
-
animated: false,
|
|
326
|
-
members: [memberOf(part)]
|
|
327
|
-
};
|
|
328
|
-
if (part.materialSlot !== undefined)
|
|
329
|
-
group.materialSlot = part.materialSlot;
|
|
330
|
-
if (frame !== undefined)
|
|
331
|
-
group.joint = frame;
|
|
332
|
-
groups.push(group);
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
const key = mergeKeyOf(part, frames);
|
|
336
|
-
const existing = byKey.get(key);
|
|
337
|
-
if (existing) {
|
|
338
|
-
existing.members.push(memberOf(part));
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
const group = {
|
|
342
|
-
materialKey: materialKeyOf(part),
|
|
343
|
-
material: part.material,
|
|
344
|
-
animated: false,
|
|
345
|
-
members: [memberOf(part)]
|
|
346
|
-
};
|
|
347
|
-
if (part.materialSlot !== undefined)
|
|
348
|
-
group.materialSlot = part.materialSlot;
|
|
349
|
-
if (frame !== undefined)
|
|
350
|
-
group.joint = frame;
|
|
351
|
-
byKey.set(key, group);
|
|
352
|
-
groups.push(group);
|
|
353
|
-
}
|
|
354
|
-
const triangles = groups.reduce((sum, g) => sum + g.members.reduce((s, m) => s + m.triangles, 0), 0);
|
|
355
|
-
const blueprint = {
|
|
356
|
-
version: BLUEPRINT_VERSION,
|
|
357
|
-
/*
|
|
358
|
-
The source edition travels with the blueprint. A consumer never sees the source — it asks
|
|
359
|
-
the service for a compiled blueprint — so without this it cannot tell which edition of the
|
|
360
|
-
format it is holding, which is the whole reason `FigureSource.version` exists.
|
|
361
|
-
|
|
362
|
-
validate has already refused any other edition, including a missing one.
|
|
363
|
-
*/
|
|
364
|
-
sourceVersion: FIGURE_SOURCE_VERSION,
|
|
365
|
-
type: src.type,
|
|
366
|
-
base: src.base,
|
|
367
|
-
budget: { triangles, groups: groups.length },
|
|
368
|
-
groups,
|
|
369
|
-
anchors,
|
|
370
|
-
animations,
|
|
371
|
-
parameters,
|
|
372
|
-
labels,
|
|
373
|
-
/* 정본이 선언한 능력을 그대로 실어 나른다 — 판정은 씬이 한다. */
|
|
374
|
-
capabilities: src.capabilities ?? [],
|
|
375
|
-
violations
|
|
376
|
-
};
|
|
377
|
-
// 등급을 실어 보낸다 — 부품 수 한도가 여기서 나오므로, 없으면 소비처가 예산을
|
|
378
|
-
// 판단할 수 없다.
|
|
379
|
-
if (src.detailLevel !== undefined)
|
|
380
|
-
blueprint.detailLevel = src.detailLevel;
|
|
381
|
-
if (src.placement !== undefined)
|
|
382
|
-
blueprint.placement = src.placement;
|
|
383
|
-
// Carried only when the source declares joints, so blueprints without them keep their exact shape.
|
|
384
|
-
if (src.joints !== undefined && src.joints.length > 0)
|
|
385
|
-
blueprint.joints = jointsOf(src, frames);
|
|
386
|
-
return blueprint;
|
|
387
|
-
}
|
|
388
|
-
//# sourceMappingURL=blueprint.js.map
|
package/dist/blueprint.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint.js","sourceRoot":"","sources":["../src/blueprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,QAAQ,EAAuB,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEjF,oDAAoD;AACpD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACrF,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,eAAe,EAkBhB,MAAM,YAAY,CAAA;AAEnB,+CAA+C;AAC/C,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,MAAM,CAA0B;IAEzC,YAAY,MAAgC;QAC1C,MAAM,IAAI,GAAG,MAAM;aAChB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aAC/C,IAAI,CAAC,KAAK,CAAC,CAAA;QACd,KAAK,CAAC,mBAAmB,MAAM,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAA;QACnD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAA;IAE/B,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,EAAE,CAAA;QACX,KAAK,UAAU;YACb,OAAO,CAAC,GAAG,GAAG,CAAA;QAChB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;YAC1C,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1B,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,CAAA;YACjC,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAE7B,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;YAC7B,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACxB,sCAAsC;YACtC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC/D,OAAO,IAAI,GAAG,KAAK,CAAA;QACrB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,IAAgB;IACvC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC,CAAA;IACtE,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED,yDAAyD;AACzD,SAAS,aAAa,CAAC,IAAgB;IACrC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC,CAAA;IAEtE,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,CAAA;IACxE,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACpD,CAAC;AAED,kDAAkD;AAElD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAkC;IAChE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAA;IACzC,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAA;IAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAA;IACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAE5C,iBAAiB;IACjB,MAAM,CAAC,GAAG;QACR,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;QACvB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;QAC3D,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;KAC3D,CAAA;IAED,MAAM,KAAK,GAAG,CAAC,GAAa,EAAE,EAAE,CAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IAEtF,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,EAAE,CAAA;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAC,IAAkC;IAC9D,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAA;IAChC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAA;IACtB,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAAC,IAAyB;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAW,CAAA;IAC7B,gFAAgF;IAChF,MAAM,EAAE,GAAG;QACT,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACtB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc;KACnB,CAAA;IACpB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IACtD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IACtD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IACzD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC5D,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;IAC/D,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,IAAyB;IACzC,gFAAgF;IAChF,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC;QAChC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc;QACrC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC;KACV,CAAA;IACpB,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAChG,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;IACnE,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC1D,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC1D,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACvD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,GAAkB,EAAE,MAAmC;IACvE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAO,CAAC,CAAC,CAAC,CAAA;IACpH,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACnE,MAAM,IAAI,GAAmB;YAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE;YAC3B,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,EAAE;SACvF,CAAA;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;QAC9F,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;YACpB,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACjC,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QAChD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IAEF,2EAA2E;IAC3E,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;IAChC,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAC1F,kEAAkE;QAClE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1D,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,MAAe;IACrC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC/C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAE3D,sGAAsG;IACtG,MAAM,GAAG,GAAG,aAAa,CAAC,MAAsB,CAAC,CAAA;IAEjD,MAAM,MAAM,GAAqB,EAAE,CAAA;IACnC,MAAM,UAAU,GAAoB,GAAG,CAAC,UAAU,IAAI,EAAE,CAAA;IACxD,MAAM,UAAU,GAAyB,GAAG,CAAC,UAAU,IAAI,EAAE,CAAA;IAC7D;;;;;MAKE;IACF,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAA;IACtD,oGAAoG;IACpG,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAqB,EAAE,CAAA;IACnC,MAAM,OAAO,GAAsB,EAAE,CAAA;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAA;IAE/C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAC/C,CAAC;QAED;;;UAGE;QACF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEnC,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;YACvC,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;YAC7C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACpB,SAAQ;QACV,CAAC;QAED,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,4CAA4C;YAC5C,MAAM,KAAK,GAAmB;gBAC5B,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC;gBAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC1B,CAAA;YACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;gBAAE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;YAC3E,IAAI,KAAK,KAAK,SAAS;gBAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAA;YAC5C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAClB,SAAQ;QACV,CAAC;QAED,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9B,oDAAoD;YACpD,MAAM,KAAK,GAAmB;gBAC5B,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC;gBAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,KAAK;gBACf,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC1B,CAAA;YACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;gBAAE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;YAC3E,IAAI,KAAK,KAAK,SAAS;gBAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAA;YAC5C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAClB,SAAQ;QACV,CAAC;QAED,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;YACrC,SAAQ;QACV,CAAC;QAED,MAAM,KAAK,GAAmB;YAC5B,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC;YAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SAC1B,CAAA;QACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;QAC3E,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAA;QAC5C,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACrB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACpB,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAEpG,MAAM,SAAS,GAAoB;QACjC,OAAO,EAAE,iBAAiB;QAC1B;;;;;;UAME;QACF,aAAa,EAAE,qBAAqB;QACpC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAC5C,MAAM;QACN,OAAO;QACP,UAAU;QACV,UAAU;QACV,MAAM;QACN,yCAAyC;QACzC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE;QACpC,UAAU;KACX,CAAA;IACD,+CAA+C;IAC/C,YAAY;IACZ,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS;QAAE,SAAS,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAA;IAC1E,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS;QAAE,SAAS,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAA;IACpE,mGAAmG;IACnG,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAE/F,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
package/dist/cost-chart.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 원가 추이 — 인스턴스가 1 개에서 10,000 개로 갈 때 무엇이 늘고 무엇이 그대로인가.
|
|
3
|
-
*
|
|
4
|
-
* 표 하나로는 그 대비가 안 보인다. **같은 그림 안에서 오르는 선과 평평한 선을 함께
|
|
5
|
-
* 봐야** 「재활용된다」는 말이 눈에 들어온다.
|
|
6
|
-
*
|
|
7
|
-
* 삼각형 · draw call 인스턴스에 비례해 오른다
|
|
8
|
-
* 정점 버퍼 · 재질 10,000 개에서도 그대로다 ← 재활용되는 것
|
|
9
|
-
* InstancedMesh 의 draw call 평평하다 ← 아직 얻지 않은 몫
|
|
10
|
-
*
|
|
11
|
-
* 의존을 만들지 않으려고 SVG 를 문자열로 낸다. 브라우저에서도 node 에서도 그대로 동작한다.
|
|
12
|
-
* 색은 다섯 계열만 쓰고 축과 글자는 `currentColor` 라서 밝은 테마·어두운 테마 양쪽에서
|
|
13
|
-
* 읽힌다.
|
|
14
|
-
*/
|
|
15
|
-
import type { FigureCostAt } from './cost.ts';
|
|
16
|
-
import type { FigureBlueprint } from './types.ts';
|
|
17
|
-
/** 추이의 한 점. */
|
|
18
|
-
export interface CostCurvePoint extends FigureCostAt {
|
|
19
|
-
}
|
|
20
|
-
export interface CostCurveOptions {
|
|
21
|
-
/** 시작 인스턴스 수. 기본 1 */
|
|
22
|
-
from?: number;
|
|
23
|
-
/** 끝 인스턴스 수. 기본 10000 */
|
|
24
|
-
to?: number;
|
|
25
|
-
}
|
|
26
|
-
/** 인스턴스 수를 훑으며 원가를 낸다. */
|
|
27
|
-
export declare function costCurve(blueprint: FigureBlueprint, options?: CostCurveOptions): CostCurvePoint[];
|
|
28
|
-
/**
|
|
29
|
-
* 추이를 SVG 문자열로 낸다.
|
|
30
|
-
*
|
|
31
|
-
* 두 축 모두 로그다. 선형 축으로 그리면 10,000 쪽 값이 화면을 다 먹어 1 개 근처가
|
|
32
|
-
* 뭉개지고, 정작 보여 줄 것 — **평평한 선과 오르는 선의 대비** — 가 안 보인다.
|
|
33
|
-
*/
|
|
34
|
-
export declare function costCurveSvg(blueprint: FigureBlueprint, options?: CostCurveOptions): string;
|
|
35
|
-
//# sourceMappingURL=cost-chart.d.ts.map
|
package/dist/cost-chart.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cost-chart.d.ts","sourceRoot":"","sources":["../src/cost-chart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,eAAe;AACf,MAAM,WAAW,cAAe,SAAQ,YAAY;CAAG;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yBAAyB;IACzB,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAsBD,0BAA0B;AAC1B,wBAAgB,SAAS,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,GAAE,gBAAqB,GAAG,cAAc,EAAE,CAItG;AA6CD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAuG/F"}
|
package/dist/cost-chart.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 원가 추이 — 인스턴스가 1 개에서 10,000 개로 갈 때 무엇이 늘고 무엇이 그대로인가.
|
|
3
|
-
*
|
|
4
|
-
* 표 하나로는 그 대비가 안 보인다. **같은 그림 안에서 오르는 선과 평평한 선을 함께
|
|
5
|
-
* 봐야** 「재활용된다」는 말이 눈에 들어온다.
|
|
6
|
-
*
|
|
7
|
-
* 삼각형 · draw call 인스턴스에 비례해 오른다
|
|
8
|
-
* 정점 버퍼 · 재질 10,000 개에서도 그대로다 ← 재활용되는 것
|
|
9
|
-
* InstancedMesh 의 draw call 평평하다 ← 아직 얻지 않은 몫
|
|
10
|
-
*
|
|
11
|
-
* 의존을 만들지 않으려고 SVG 를 문자열로 낸다. 브라우저에서도 node 에서도 그대로 동작한다.
|
|
12
|
-
* 색은 다섯 계열만 쓰고 축과 글자는 `currentColor` 라서 밝은 테마·어두운 테마 양쪽에서
|
|
13
|
-
* 읽힌다.
|
|
14
|
-
*/
|
|
15
|
-
import { costOf } from "./cost.js";
|
|
16
|
-
/**
|
|
17
|
-
* 1-2-5 간격으로 자릿수를 순회한다.
|
|
18
|
-
*
|
|
19
|
-
* 로그 축에서 눈에 고르게 놓이는 값들이다. 1·2·5·10·20·50·100 … 등비로 늘리면 자릿수
|
|
20
|
-
* 하나에 점이 셋씩 놓여 곡선이 매끄럽다.
|
|
21
|
-
*/
|
|
22
|
-
function decadeSteps(from, to) {
|
|
23
|
-
const out = [];
|
|
24
|
-
let decade = 1;
|
|
25
|
-
while (decade <= to) {
|
|
26
|
-
for (const m of [1, 2, 5]) {
|
|
27
|
-
const v = decade * m;
|
|
28
|
-
if (v >= from && v <= to)
|
|
29
|
-
out.push(v);
|
|
30
|
-
}
|
|
31
|
-
decade *= 10;
|
|
32
|
-
}
|
|
33
|
-
if (out.length === 0 || out[out.length - 1] !== to)
|
|
34
|
-
out.push(to);
|
|
35
|
-
return [...new Set(out)].sort((a, b) => a - b);
|
|
36
|
-
}
|
|
37
|
-
/** 인스턴스 수를 훑으며 원가를 낸다. */
|
|
38
|
-
export function costCurve(blueprint, options = {}) {
|
|
39
|
-
const from = Math.max(1, Math.floor(options.from ?? 1));
|
|
40
|
-
const to = Math.max(from, Math.floor(options.to ?? 10000));
|
|
41
|
-
return decadeSteps(from, to).map(n => costOf(blueprint, n).at);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* 그리는 계열 넷.
|
|
45
|
-
*
|
|
46
|
-
* `drawCallsIfInstanced` 는 선으로 그리지 않는다 — 구조적으로 `geometries` 와 **항상
|
|
47
|
-
* 같은 값**이기 때문이다(둘 다 묶음 수). 절대 갈릴 수 없는 선을 둘 그리면 하나가 다른
|
|
48
|
-
* 하나를 덮어 정보가 오히려 준다. 대신 그 뜻을 이름에 담았다.
|
|
49
|
-
*
|
|
50
|
-
* `materials` 는 `geometries` 와 같을 수도 다를 수도 있다(재질이 슬롯으로 더 갈리면
|
|
51
|
-
* 묶음이 더 많다). 겹칠 때 아래 선이 보이도록 점선으로 마지막에 그린다.
|
|
52
|
-
*/
|
|
53
|
-
const SERIES = [
|
|
54
|
-
{ key: 'triangles', label: '삼각형', color: '#e5534b', flat: false },
|
|
55
|
-
{ key: 'drawCalls', label: 'draw call', color: '#e09b13', flat: false },
|
|
56
|
-
{ key: 'geometries', label: '정점 버퍼', color: '#4a9eff', flat: true },
|
|
57
|
-
{ key: 'materials', label: '재질', color: '#a371f7', flat: true, dashed: true }
|
|
58
|
-
];
|
|
59
|
-
const W = 680;
|
|
60
|
-
const H = 380;
|
|
61
|
-
const PAD = { top: 52, right: 208, bottom: 44, left: 62 };
|
|
62
|
-
const log10 = (v) => Math.log(Math.max(v, 1)) / Math.LN10;
|
|
63
|
-
function escapeText(s) {
|
|
64
|
-
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
65
|
-
}
|
|
66
|
-
/** 1, 10, 100 … 형태로 짧게. */
|
|
67
|
-
function shortNumber(v) {
|
|
68
|
-
if (v >= 1_000_000)
|
|
69
|
-
return `${v / 1_000_000}M`;
|
|
70
|
-
if (v >= 1_000)
|
|
71
|
-
return `${v / 1_000}k`;
|
|
72
|
-
return String(v);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* 추이를 SVG 문자열로 낸다.
|
|
76
|
-
*
|
|
77
|
-
* 두 축 모두 로그다. 선형 축으로 그리면 10,000 쪽 값이 화면을 다 먹어 1 개 근처가
|
|
78
|
-
* 뭉개지고, 정작 보여 줄 것 — **평평한 선과 오르는 선의 대비** — 가 안 보인다.
|
|
79
|
-
*/
|
|
80
|
-
export function costCurveSvg(blueprint, options = {}) {
|
|
81
|
-
const points = costCurve(blueprint, options);
|
|
82
|
-
if (points.length === 0)
|
|
83
|
-
return '';
|
|
84
|
-
const xs = points.map(p => p.instances);
|
|
85
|
-
const minX = xs[0];
|
|
86
|
-
const maxX = xs[xs.length - 1];
|
|
87
|
-
let maxY = 1;
|
|
88
|
-
for (const p of points) {
|
|
89
|
-
for (const s of SERIES)
|
|
90
|
-
maxY = Math.max(maxY, p[s.key]);
|
|
91
|
-
}
|
|
92
|
-
const plotW = W - PAD.left - PAD.right;
|
|
93
|
-
const plotH = H - PAD.top - PAD.bottom;
|
|
94
|
-
const spanX = Math.max(log10(maxX) - log10(minX), 1e-9);
|
|
95
|
-
const spanY = Math.max(log10(maxY), 1e-9);
|
|
96
|
-
const px = (v) => PAD.left + ((log10(v) - log10(minX)) / spanX) * plotW;
|
|
97
|
-
const py = (v) => PAD.top + plotH - (log10(v) / spanY) * plotH;
|
|
98
|
-
const parts = [];
|
|
99
|
-
parts.push(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}" ` +
|
|
100
|
-
`font-family="system-ui, sans-serif" font-size="11" fill="currentColor">`);
|
|
101
|
-
parts.push(`<text x="${PAD.left}" y="22" font-size="13" font-weight="600">` +
|
|
102
|
-
`${escapeText(blueprint.type)} — 인스턴스가 늘 때의 원가</text>`, `<text x="${PAD.left}" y="38" opacity="0.6">` +
|
|
103
|
-
`평평한 선은 인스턴스가 늘어도 그대로다 — 그것이 재활용되는 것이다</text>`);
|
|
104
|
-
// 세로 눈금 — 자릿수마다
|
|
105
|
-
for (let e = 0; Math.pow(10, e) <= maxY * 1.001; e++) {
|
|
106
|
-
const v = Math.pow(10, e);
|
|
107
|
-
const y = py(v);
|
|
108
|
-
parts.push(`<line x1="${PAD.left}" y1="${y.toFixed(1)}" x2="${(PAD.left + plotW).toFixed(1)}" y2="${y.toFixed(1)}" ` +
|
|
109
|
-
`stroke="currentColor" stroke-opacity="0.12"/>`, `<text x="${PAD.left - 8}" y="${(y + 3.5).toFixed(1)}" text-anchor="end" opacity="0.55">${shortNumber(v)}</text>`);
|
|
110
|
-
}
|
|
111
|
-
// 가로 눈금 — 자릿수마다
|
|
112
|
-
for (let e = 0; Math.pow(10, e) <= maxX * 1.001; e++) {
|
|
113
|
-
const v = Math.pow(10, e);
|
|
114
|
-
if (v < minX)
|
|
115
|
-
continue;
|
|
116
|
-
const x = px(v);
|
|
117
|
-
parts.push(`<line x1="${x.toFixed(1)}" y1="${PAD.top}" x2="${x.toFixed(1)}" y2="${(PAD.top + plotH).toFixed(1)}" ` +
|
|
118
|
-
`stroke="currentColor" stroke-opacity="0.12"/>`, `<text x="${x.toFixed(1)}" y="${(PAD.top + plotH + 16).toFixed(1)}" text-anchor="middle" opacity="0.55">` +
|
|
119
|
-
`${shortNumber(v)}</text>`);
|
|
120
|
-
}
|
|
121
|
-
parts.push(`<text x="${(PAD.left + plotW / 2).toFixed(1)}" y="${H - 8}" text-anchor="middle" opacity="0.55">인스턴스 수</text>`);
|
|
122
|
-
// 선
|
|
123
|
-
for (const s of SERIES) {
|
|
124
|
-
const d = points
|
|
125
|
-
.map((p, i) => `${i === 0 ? 'M' : 'L'}${px(p.instances).toFixed(1)},${py(p[s.key]).toFixed(1)}`)
|
|
126
|
-
.join(' ');
|
|
127
|
-
parts.push(`<path d="${d}" fill="none" stroke="${s.color}" stroke-width="2" ` +
|
|
128
|
-
`stroke-linejoin="round"${s.dashed ? ' stroke-dasharray="3 7"' : ''}/>`);
|
|
129
|
-
}
|
|
130
|
-
// 범례 — 끝 값을 함께 보인다. 「10,000 개면 얼마인가」가 바로 읽힌다.
|
|
131
|
-
const last = points[points.length - 1];
|
|
132
|
-
parts.push(`<g transform="translate(${W - PAD.right + 14}, ${PAD.top - 6})">`);
|
|
133
|
-
parts.push(`<text x="0" y="0" font-weight="600">${shortNumber(last.instances)} 개일 때</text>`);
|
|
134
|
-
SERIES.forEach((s, i) => {
|
|
135
|
-
const y = 24 + i * 34;
|
|
136
|
-
parts.push(`<line x1="0" y1="${y - 4}" x2="18" y2="${y - 4}" stroke="${s.color}" stroke-width="2"` +
|
|
137
|
-
`${s.dashed ? ' stroke-dasharray="3 7"' : ''}/>`, `<text x="24" y="${y}" opacity="0.85">${escapeText(s.label)}</text>`, `<text x="24" y="${y + 12}" font-weight="600" fill="${s.color}">` +
|
|
138
|
-
`${last[s.key].toLocaleString('en-US')}${s.flat ? ' · 그대로' : ''}</text>`);
|
|
139
|
-
});
|
|
140
|
-
// 겹쳐 보이는 것을 말로 밝힌다 — 값이 같으면 선이 포개진다.
|
|
141
|
-
const flatValues = new Set(SERIES.filter(x => x.flat).map(x => last[x.key]));
|
|
142
|
-
const note = flatValues.size === 1
|
|
143
|
-
? `평평한 선들이 ${[...flatValues][0]} 에서 포개져 있다`
|
|
144
|
-
: 'InstancedMesh 를 쓰면 draw call 이 정점 버퍼 수까지 내려간다';
|
|
145
|
-
parts.push(`<text x="0" y="${24 + SERIES.length * 34 + 6}" opacity="0.55">${escapeText(note)}</text>`, `<text x="0" y="${24 + SERIES.length * 34 + 20}" opacity="0.55">InstancedMesh 면 draw call = 정점 버퍼 수</text>`);
|
|
146
|
-
parts.push('</g>');
|
|
147
|
-
parts.push('</svg>');
|
|
148
|
-
return parts.join('\n');
|
|
149
|
-
}
|
|
150
|
-
//# sourceMappingURL=cost-chart.js.map
|
package/dist/cost-chart.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cost-chart.js","sourceRoot":"","sources":["../src/cost-chart.ts"],"names":[],"mappings":"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"}
|