@operato/scene-urdf 10.0.0-beta.22 → 10.0.0-beta.30
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/urdf-object.d.ts +257 -18
- package/dist/urdf-object.js +23 -59
- package/dist/urdf-object.js.map +1 -1
- package/package.json +2 -2
package/dist/urdf-object.d.ts
CHANGED
|
@@ -1,6 +1,252 @@
|
|
|
1
|
-
import { Shape, type ComponentNature, type
|
|
1
|
+
import { Shape, type ComponentNature, type IRealObject } from '@hatiolab/things-scene';
|
|
2
2
|
import type { URDFJointState, URDFJointMeta } from './real-object-urdf.js';
|
|
3
3
|
declare const URDFObject_base: (new (...args: any[]) => {
|
|
4
|
+
_topViewSnapshot?: HTMLCanvasElement;
|
|
5
|
+
_snapshotLoading: boolean;
|
|
6
|
+
_ratioLocking: boolean;
|
|
7
|
+
is3dish(): boolean;
|
|
8
|
+
get hasTextProperty(): boolean;
|
|
9
|
+
get controls(): never[];
|
|
10
|
+
render(ctx: CanvasRenderingContext2D): void;
|
|
11
|
+
onchange(after: Record<string, any>, before: Record<string, any>): void;
|
|
12
|
+
_ensureTopViewSnapshot(): void;
|
|
13
|
+
buildRealObject(): IRealObject | undefined;
|
|
14
|
+
get source(): string | undefined;
|
|
15
|
+
set source(v: string | undefined): any;
|
|
16
|
+
get play(): boolean;
|
|
17
|
+
set play(value: boolean): any;
|
|
18
|
+
get nodes(): Record<string, import("@hatiolab/things-scene").GLTFNodeState> | undefined;
|
|
19
|
+
set nodes(value: Record<string, import("@hatiolab/things-scene").GLTFNodeState> | undefined): any;
|
|
20
|
+
get animations(): Record<string, import("@hatiolab/things-scene").GLTFAnimationState> | undefined;
|
|
21
|
+
set animations(value: Record<string, import("@hatiolab/things-scene").GLTFAnimationState> | undefined): any;
|
|
22
|
+
get playTargets(): string[] | string | undefined;
|
|
23
|
+
set playTargets(value: string[] | string | undefined): any;
|
|
24
|
+
get fillStyleTargets(): string[] | undefined;
|
|
25
|
+
set fillStyleTargets(value: string[] | undefined): any;
|
|
26
|
+
get nodeNames(): string[];
|
|
27
|
+
get animationNames(): string[];
|
|
28
|
+
set dimension(dimension: {
|
|
29
|
+
width: number;
|
|
30
|
+
height: number;
|
|
31
|
+
depth: number;
|
|
32
|
+
}): any;
|
|
33
|
+
_applyRatioLock(props: any): any;
|
|
34
|
+
set(props: any, propval?: any): any;
|
|
35
|
+
setState(props: any, propval?: any): any;
|
|
36
|
+
_app: any;
|
|
37
|
+
_model: any;
|
|
38
|
+
_state: any;
|
|
39
|
+
_delta: any;
|
|
40
|
+
_animation: any;
|
|
41
|
+
_animate: any;
|
|
42
|
+
_parent: any;
|
|
43
|
+
_disposed: any;
|
|
44
|
+
_textHidden: any;
|
|
45
|
+
_text_substitutor: any;
|
|
46
|
+
_value_substitutor: any;
|
|
47
|
+
_mappings: any;
|
|
48
|
+
_realObject: IRealObject | undefined;
|
|
49
|
+
_cachedState: any;
|
|
50
|
+
updatedAt: any;
|
|
51
|
+
fontSize: any;
|
|
52
|
+
__cache__: any;
|
|
53
|
+
created(): void;
|
|
54
|
+
added(parent: any): void;
|
|
55
|
+
removed(parent: any): void;
|
|
56
|
+
ready(): Promise<void>;
|
|
57
|
+
touch(): void;
|
|
58
|
+
clearCache(...attrs: any[]): void;
|
|
59
|
+
removeSelf(completely: any): void;
|
|
60
|
+
resetAnimation(): void;
|
|
61
|
+
dispose(): void;
|
|
62
|
+
get nature(): ComponentNature;
|
|
63
|
+
get disposed(): boolean;
|
|
64
|
+
isLayer(): boolean;
|
|
65
|
+
isGroup(): boolean;
|
|
66
|
+
isContainer(): this is import("@hatiolab/things-scene").Container;
|
|
67
|
+
isLine(): boolean;
|
|
68
|
+
isRoot(): boolean;
|
|
69
|
+
isRootModel(): boolean;
|
|
70
|
+
get is3dMode(): boolean;
|
|
71
|
+
isIn3DSpace(): boolean;
|
|
72
|
+
isTemplate(): boolean;
|
|
73
|
+
isHTMLElement(): boolean;
|
|
74
|
+
isConnectable(): boolean;
|
|
75
|
+
isIdentifiable(): boolean;
|
|
76
|
+
isPositionable(): boolean;
|
|
77
|
+
replaceRefids(replaceMap: any): void;
|
|
78
|
+
get(property: any): any;
|
|
79
|
+
getState(property: any): any;
|
|
80
|
+
get model(): any;
|
|
81
|
+
get state(): import("@hatiolab/things-scene").State;
|
|
82
|
+
get hierarchy(): any;
|
|
83
|
+
get volatile(): never[];
|
|
84
|
+
_applyProps(target: any, props: any, options: any): any;
|
|
85
|
+
contains(x: number, y: number): boolean;
|
|
86
|
+
move(offset: {
|
|
87
|
+
x: number;
|
|
88
|
+
y: number;
|
|
89
|
+
}, ...args: boolean[]): void;
|
|
90
|
+
symmetryX(x?: number): void;
|
|
91
|
+
symmetryY(y: number): void;
|
|
92
|
+
adjustResize(bounds: import("@hatiolab/things-scene").BOUNDS, origin_bounds: import("@hatiolab/things-scene").BOUNDS, diagonal: boolean): {
|
|
93
|
+
left: any;
|
|
94
|
+
top: any;
|
|
95
|
+
width: any;
|
|
96
|
+
height: any;
|
|
97
|
+
};
|
|
98
|
+
adjustRotation(rotation: number, step: boolean): number;
|
|
99
|
+
outline(progress: number): any;
|
|
100
|
+
get bounds(): import("@hatiolab/things-scene").BOUNDS;
|
|
101
|
+
set bounds(b: import("@hatiolab/things-scene").BOUNDS): any;
|
|
102
|
+
get center(): import("@hatiolab/things-scene").POINT;
|
|
103
|
+
set center(p: import("@hatiolab/things-scene").POINT): any;
|
|
104
|
+
get location(): import("@hatiolab/things-scene").POINT;
|
|
105
|
+
set location(l: import("@hatiolab/things-scene").POINT): any;
|
|
106
|
+
get rotate(): import("@hatiolab/things-scene").POINT;
|
|
107
|
+
set rotate(r: import("@hatiolab/things-scene").POINT): any;
|
|
108
|
+
get path(): import("@hatiolab/things-scene").POINT[];
|
|
109
|
+
set path(p: import("@hatiolab/things-scene").POINT[]): any;
|
|
110
|
+
get drawPath(): import("@hatiolab/things-scene").POINT[];
|
|
111
|
+
get rotatePoint(): import("@hatiolab/things-scene").POINT;
|
|
112
|
+
get mutable(): boolean;
|
|
113
|
+
get resizable(): boolean;
|
|
114
|
+
get rotatable(): boolean;
|
|
115
|
+
get realObject(): IRealObject | undefined;
|
|
116
|
+
draw(context?: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
117
|
+
prerender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
118
|
+
postrender(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
119
|
+
prepare(resolve: (component: import("@hatiolab/things-scene").Component) => void, reject: (reason: any) => void): void;
|
|
120
|
+
prepareIf(condition: boolean): void;
|
|
121
|
+
drawText(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
122
|
+
drawStroke(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
|
|
123
|
+
drawFill(context: import("@hatiolab/things-scene").SceneRenderContext, override?: Record<string, unknown>): void;
|
|
124
|
+
get strokeStyle(): any;
|
|
125
|
+
set strokeStyle(v: any): any;
|
|
126
|
+
get fillStyle(): any;
|
|
127
|
+
set fillStyle(v: any): any;
|
|
128
|
+
get fontColor(): string;
|
|
129
|
+
set fontColor(v: string): any;
|
|
130
|
+
get rotation(): number;
|
|
131
|
+
set rotation(v: number): any;
|
|
132
|
+
get decorators(): string[];
|
|
133
|
+
get decotag(): string;
|
|
134
|
+
get hidden(): boolean;
|
|
135
|
+
set hidden(v: boolean): any;
|
|
136
|
+
get tag(): string;
|
|
137
|
+
set tag(v: string): any;
|
|
138
|
+
get appendum(): any;
|
|
139
|
+
set appendum(v: any): any;
|
|
140
|
+
defaultTextSubstitutor(): string;
|
|
141
|
+
textLines(context?: import("@hatiolab/things-scene").SceneRenderContext): any[][];
|
|
142
|
+
get font(): string;
|
|
143
|
+
get lineHeight(): number;
|
|
144
|
+
get textSubstitutor(): () => string;
|
|
145
|
+
get text(): string;
|
|
146
|
+
set text(v: string): any;
|
|
147
|
+
get textBounds(): import("@hatiolab/things-scene").BOUNDS;
|
|
148
|
+
get textRotation(): number;
|
|
149
|
+
get textHidden(): boolean;
|
|
150
|
+
set textHidden(v: boolean): any;
|
|
151
|
+
animate(opts: import("@hatiolab/things-scene").AnimationConfig): any;
|
|
152
|
+
effect(context: import("@hatiolab/things-scene").SceneRenderContext, model: any): void;
|
|
153
|
+
serialize(...others: any[]): string;
|
|
154
|
+
trim(): void;
|
|
155
|
+
closeScene(data: any): void;
|
|
156
|
+
delta(attr?: string | object, value?: any): any;
|
|
157
|
+
invalidate(): void;
|
|
158
|
+
get value(): any;
|
|
159
|
+
set value(v: any): any;
|
|
160
|
+
get data(): any;
|
|
161
|
+
set data(v: any): any;
|
|
162
|
+
set tap(v: any): any;
|
|
163
|
+
get mappings(): any[];
|
|
164
|
+
get retention(): number;
|
|
165
|
+
get animation(): import("@hatiolab/things-scene").AnimationController | undefined;
|
|
166
|
+
get started(): boolean;
|
|
167
|
+
set started(v: boolean): any;
|
|
168
|
+
findFirst(finder: string | ((c: import("@hatiolab/things-scene").Component) => boolean), ...others: any[]): import("@hatiolab/things-scene").Component | undefined;
|
|
169
|
+
findAll(s: string | ((c: import("@hatiolab/things-scene").Component) => boolean), ...others: any[]): any[] | undefined;
|
|
170
|
+
capture(x: number, y: number, except?: (c: import("@hatiolab/things-scene").Component) => boolean): any;
|
|
171
|
+
findAnchor(name: string): any;
|
|
172
|
+
isDescendible(container: import("@hatiolab/things-scene").Component): boolean;
|
|
173
|
+
getContext(component?: unknown): any;
|
|
174
|
+
get root(): import("@hatiolab/things-scene").Component;
|
|
175
|
+
get rootModel(): import("@hatiolab/things-scene").Component;
|
|
176
|
+
get parent(): import("@hatiolab/things-scene").Component;
|
|
177
|
+
set parent(v: import("@hatiolab/things-scene").Component): any;
|
|
178
|
+
get anchors(): import("@hatiolab/things-scene").Anchor[];
|
|
179
|
+
get scalable(): boolean;
|
|
180
|
+
get stuck(): boolean;
|
|
181
|
+
get capturable(): boolean;
|
|
182
|
+
get position(): string;
|
|
183
|
+
get origin(): string;
|
|
184
|
+
get offset(): import("@hatiolab/things-scene").POINT;
|
|
185
|
+
get app(): import("@hatiolab/things-scene").ApplicationContext;
|
|
186
|
+
drawEffect(context: import("@hatiolab/things-scene").SceneRenderContext): void;
|
|
187
|
+
prepareFill(resolve: Function, reject: Function): void;
|
|
188
|
+
prepareFillIf(condition: boolean): void;
|
|
189
|
+
onchangeFill(after: Record<string, any>, before: Record<string, any>): void;
|
|
190
|
+
drawImage(context: import("@hatiolab/things-scene").SceneRenderContext, image: HTMLImageElement, left: number, top: number, width: number, height: number): void;
|
|
191
|
+
mutateBounds(logic: ((bounds: import("@hatiolab/things-scene").BOUNDS) => import("@hatiolab/things-scene").BOUNDS | void) | null, context?: any): void;
|
|
192
|
+
mutatePath(beforeLogic: ((path: import("@hatiolab/things-scene").POINT[]) => import("@hatiolab/things-scene").POINT[] | void) | null, afterLogic: ((path: import("@hatiolab/things-scene").POINT[]) => import("@hatiolab/things-scene").POINT[] | void) | null, context?: any): void;
|
|
193
|
+
access(accessor: string): any;
|
|
194
|
+
substitute(template: string, data: any): string | undefined;
|
|
195
|
+
onchangeMappings(after: Record<string, any>, before: Record<string, any>): void;
|
|
196
|
+
onchangeData(after: Record<string, any>, before: Record<string, any>): void;
|
|
197
|
+
buildMappings(): void;
|
|
198
|
+
executeMappings(force?: boolean): void;
|
|
199
|
+
disposeMappings(): void;
|
|
200
|
+
ondropfile(transfered: FileList, files: string[]): void;
|
|
201
|
+
transcoordS2P(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
202
|
+
transcoordP2S(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
203
|
+
transcoordS2T(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
204
|
+
transcoordT2P(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
205
|
+
transcoordT2S(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
206
|
+
transcoordS2TR(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
207
|
+
transcoordS2O(x: number, y: number, target: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
208
|
+
transcoordC2S(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
209
|
+
transcoordS2C(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
210
|
+
toParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
211
|
+
fromParent(x: number, y: number, rp?: import("@hatiolab/things-scene").POINT): import("@hatiolab/things-scene").POINT;
|
|
212
|
+
toScene(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
213
|
+
fromScene(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
214
|
+
toLocal(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
215
|
+
toGlobal(x: number, y: number, top?: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
216
|
+
toOther(x: number, y: number, target: import("@hatiolab/things-scene").Component): import("@hatiolab/things-scene").POINT;
|
|
217
|
+
on(name: string | object, callback: Function, context?: any): any;
|
|
218
|
+
off(name?: string | object, callback?: Function, context?: any): any;
|
|
219
|
+
once(name: string | object, callback: Function, context?: any): any;
|
|
220
|
+
trigger(name: string, ...args: any[]): any;
|
|
221
|
+
delegate_on(delegator: any): any;
|
|
222
|
+
delegate_off(delegator: any): any;
|
|
223
|
+
calculateBounds?(): void;
|
|
224
|
+
oncreate_element?(element: HTMLElement): void;
|
|
225
|
+
removeComponent(component: import("@hatiolab/things-scene").Component, ghost?: boolean): void;
|
|
226
|
+
addComponent(component: import("@hatiolab/things-scene").Component, ghost?: boolean): void;
|
|
227
|
+
insertComponentAt(component: import("@hatiolab/things-scene").Component, index: number, ghost?: boolean): void;
|
|
228
|
+
getOverlay(component: import("@hatiolab/things-scene").Component): HTMLElement | undefined;
|
|
229
|
+
findById(id: string): import("@hatiolab/things-scene").Component | undefined;
|
|
230
|
+
findByRefid(ref: string | number): import("@hatiolab/things-scene").Component | undefined;
|
|
231
|
+
findAllById(id: string): import("@hatiolab/things-scene").Component[];
|
|
232
|
+
resize(): void;
|
|
233
|
+
fit(type?: string): void;
|
|
234
|
+
get components(): import("@hatiolab/things-scene").Component[] | undefined;
|
|
235
|
+
get layout(): any;
|
|
236
|
+
get auxOverlay(): HTMLElement | undefined;
|
|
237
|
+
get isReady(): boolean;
|
|
238
|
+
get unitScale(): number;
|
|
239
|
+
get selected(): import("@hatiolab/things-scene").Component[];
|
|
240
|
+
set selected(_v: import("@hatiolab/things-scene").Component[]): any;
|
|
241
|
+
get focused(): import("@hatiolab/things-scene").Component | null;
|
|
242
|
+
set focused(_v: import("@hatiolab/things-scene").Component | null): any;
|
|
243
|
+
get hasSameParentForAllSelected(): boolean;
|
|
244
|
+
set hasSameParentForAllSelected(_v: boolean): any;
|
|
245
|
+
get fitMode(): string | undefined;
|
|
246
|
+
set fitMode(_v: string | undefined): any;
|
|
247
|
+
get element(): HTMLElement | null;
|
|
248
|
+
set element(_v: HTMLElement | null): any;
|
|
249
|
+
}) & (new (...args: any[]) => {
|
|
4
250
|
contains(x: number, y: number): boolean;
|
|
5
251
|
get path(): {
|
|
6
252
|
x: any;
|
|
@@ -50,7 +296,7 @@ declare const URDFObject_base: (new (...args: any[]) => {
|
|
|
50
296
|
get disposed(): boolean;
|
|
51
297
|
isLayer(): boolean;
|
|
52
298
|
isGroup(): boolean;
|
|
53
|
-
isContainer(): this is import("@hatiolab/things-scene
|
|
299
|
+
isContainer(): this is import("@hatiolab/things-scene").Container;
|
|
54
300
|
isLine(): boolean;
|
|
55
301
|
isRoot(): boolean;
|
|
56
302
|
isRootModel(): boolean;
|
|
@@ -66,9 +312,9 @@ declare const URDFObject_base: (new (...args: any[]) => {
|
|
|
66
312
|
get(property: any): any;
|
|
67
313
|
set(props: any, propval?: any): any;
|
|
68
314
|
getState(property: any): any;
|
|
69
|
-
setState(props:
|
|
315
|
+
setState(props: Partial<import("@hatiolab/things-scene").State> | string, propval?: any): any;
|
|
70
316
|
get model(): any;
|
|
71
|
-
get state():
|
|
317
|
+
get state(): import("@hatiolab/things-scene").State;
|
|
72
318
|
get hierarchy(): any;
|
|
73
319
|
get volatile(): never[];
|
|
74
320
|
_applyProps(target: any, props: any, options: any): any;
|
|
@@ -238,22 +484,15 @@ declare const URDFObject_base: (new (...args: any[]) => {
|
|
|
238
484
|
set element(_v: HTMLElement | null): any;
|
|
239
485
|
}) & typeof Shape;
|
|
240
486
|
export declare class URDFObject extends URDFObject_base {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
487
|
+
/**
|
|
488
|
+
* URDF 캐시 hit 만 처리. miss 시는 RealObjectURDF.\_onLoaded 가
|
|
489
|
+
* 캐시를 채우고 component.\_topViewSnapshot 을 직접 세팅한다 (URDF
|
|
490
|
+
* 로더는 GLB 로더와 다르므로 mixin 의 디폴트 — RealObjectGLTF.loadGLTF
|
|
491
|
+
* 직접 호출 — 을 쓸 수 없다).
|
|
492
|
+
*/
|
|
493
|
+
_ensureTopViewSnapshot(): void;
|
|
248
494
|
buildRealObject(): IRealObject | undefined;
|
|
249
495
|
get nature(): ComponentNature;
|
|
250
|
-
get source(): any;
|
|
251
|
-
set source(source: any);
|
|
252
|
-
set dimension(dimension: {
|
|
253
|
-
width: number;
|
|
254
|
-
height: number;
|
|
255
|
-
depth: number;
|
|
256
|
-
});
|
|
257
496
|
/** 조인트 상태 맵. 값은 숫자(라디안/거리) 또는 { value } 형식 허용. */
|
|
258
497
|
get joints(): Record<string, URDFJointState | number> | undefined;
|
|
259
498
|
set joints(value: Record<string, URDFJointState | number> | undefined);
|
package/dist/urdf-object.js
CHANGED
|
@@ -3,9 +3,23 @@
|
|
|
3
3
|
*
|
|
4
4
|
* URDF 로봇을 things-scene 3D 공간에 네이티브로 임베드한다.
|
|
5
5
|
* GLTFObject와 대칭적인 구조 — 2D 탑뷰는 스냅샷 렌더로 표현한다.
|
|
6
|
+
*
|
|
7
|
+
* GltfComponent mixin 합류 (2026-05): GLB / URDF 양쪽이 공유하는
|
|
8
|
+
* - 2D 탑뷰 fallback render (스냅샷 + 라벨)
|
|
9
|
+
* - src 변경 → 스냅샷 reset → ensure 라이프사이클
|
|
10
|
+
* - is3dish / hasTextProperty / controls / source / dimension 보일러플레이트
|
|
11
|
+
* - ratioLock 인터셉트
|
|
12
|
+
* 를 mixin에서 받음. URDF 고유는:
|
|
13
|
+
* - `_ensureTopViewSnapshot()` override — URDF 로더는 GLB 로더와 다르므로
|
|
14
|
+
* mixin 디폴트(GLB loader 호출)를 쓸 수 없고, 캐시 히트만 처리하고
|
|
15
|
+
* miss 는 RealObjectURDF._onLoaded 가 채우도록 위임.
|
|
16
|
+
* - `buildRealObject()` override — RealObjectURDF 반환.
|
|
17
|
+
* - NATURE — urdf-preset / urdf-joints / upAxis / unitScale / autoAnimate
|
|
18
|
+
* / physics 등 로봇 도메인 전용 properties (GLB의 gltfNatureProperties
|
|
19
|
+
* 와 의미가 다르므로 spread 안 함).
|
|
6
20
|
*/
|
|
7
21
|
import { __decorate } from "tslib";
|
|
8
|
-
import { RectPath, Shape, sceneComponent } from '@hatiolab/things-scene';
|
|
22
|
+
import { GltfComponent, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene';
|
|
9
23
|
import { RealObjectURDF } from './real-object-urdf.js';
|
|
10
24
|
const BASE_URL_ALIAS = '$base_url';
|
|
11
25
|
const NATURE = {
|
|
@@ -91,62 +105,23 @@ const NATURE = {
|
|
|
91
105
|
'value-property': 'source',
|
|
92
106
|
help: 'scene/component/urdf'
|
|
93
107
|
};
|
|
94
|
-
let URDFObject = class URDFObject extends RectPath(Shape) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
get controls() {
|
|
102
|
-
return [];
|
|
103
|
-
}
|
|
104
|
-
render(context) {
|
|
105
|
-
const { left, top, width, height } = this.bounds;
|
|
106
|
-
context.beginPath();
|
|
107
|
-
const snapshot = this._topViewSnapshot;
|
|
108
|
-
if (snapshot) {
|
|
109
|
-
context.drawImage(snapshot, left, top, width, height);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// 폴백: 로봇 아이콘 박스 + 중앙 라벨
|
|
113
|
-
context.rect(left, top, width, height);
|
|
114
|
-
context.fillStyle = '#e3f2fd';
|
|
115
|
-
context.fill();
|
|
116
|
-
context.strokeStyle = '#1976d2';
|
|
117
|
-
context.lineWidth = 1;
|
|
118
|
-
context.stroke();
|
|
119
|
-
const src = this.getState('src');
|
|
120
|
-
const label = src ? src.split('/').pop()?.replace(/\.[^.]+$/, '') || 'URDF' : 'URDF';
|
|
121
|
-
const fontSize = Math.max(10, Math.min(width, height) * 0.12);
|
|
122
|
-
context.fillStyle = '#1976d2';
|
|
123
|
-
context.font = `${fontSize}px sans-serif`;
|
|
124
|
-
context.textAlign = 'center';
|
|
125
|
-
context.textBaseline = 'middle';
|
|
126
|
-
context.fillText(label, left + width / 2, top + height / 2, width * 0.9);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
async ready() {
|
|
130
|
-
await super.ready();
|
|
131
|
-
this._ensureTopViewSnapshot();
|
|
132
|
-
}
|
|
133
|
-
onchange(after, before) {
|
|
134
|
-
super.onchange(after, before);
|
|
135
|
-
if ('src' in after) {
|
|
136
|
-
this._topViewSnapshot = undefined;
|
|
137
|
-
this._ensureTopViewSnapshot();
|
|
138
|
-
}
|
|
139
|
-
}
|
|
108
|
+
let URDFObject = class URDFObject extends GltfComponent(RectPath(Shape)) {
|
|
109
|
+
/**
|
|
110
|
+
* URDF 캐시 hit 만 처리. miss 시는 RealObjectURDF.\_onLoaded 가
|
|
111
|
+
* 캐시를 채우고 component.\_topViewSnapshot 을 직접 세팅한다 (URDF
|
|
112
|
+
* 로더는 GLB 로더와 다르므로 mixin 의 디폴트 — RealObjectGLTF.loadGLTF
|
|
113
|
+
* 직접 호출 — 을 쓸 수 없다).
|
|
114
|
+
*/
|
|
140
115
|
_ensureTopViewSnapshot() {
|
|
141
116
|
const src = this.getState('src');
|
|
142
117
|
if (!src)
|
|
143
118
|
return;
|
|
144
119
|
const cached = RealObjectURDF.getTopViewCache(src);
|
|
145
120
|
if (cached) {
|
|
121
|
+
;
|
|
146
122
|
this._topViewSnapshot = cached;
|
|
147
123
|
this.invalidate();
|
|
148
124
|
}
|
|
149
|
-
// 캐시 miss인 경우 3D 씬이 활성화되면 _onLoaded에서 자동 생성한다.
|
|
150
125
|
}
|
|
151
126
|
buildRealObject() {
|
|
152
127
|
return new RealObjectURDF(this);
|
|
@@ -154,17 +129,6 @@ let URDFObject = class URDFObject extends RectPath(Shape) {
|
|
|
154
129
|
get nature() {
|
|
155
130
|
return NATURE;
|
|
156
131
|
}
|
|
157
|
-
get source() {
|
|
158
|
-
return this.getState('src');
|
|
159
|
-
}
|
|
160
|
-
set source(source) {
|
|
161
|
-
this.setState('src', source);
|
|
162
|
-
}
|
|
163
|
-
set dimension(dimension) {
|
|
164
|
-
const { width = 1, height = 1, depth = 1 } = dimension;
|
|
165
|
-
this.setState({ width, height, depth });
|
|
166
|
-
this.realObject?.updateDimension();
|
|
167
|
-
}
|
|
168
132
|
// --- URDF 바인딩 API ---
|
|
169
133
|
/** 조인트 상태 맵. 값은 숫자(라디안/거리) 또는 { value } 형식 허용. */
|
|
170
134
|
get joints() {
|
package/dist/urdf-object.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urdf-object.js","sourceRoot":"","sources":["../src/urdf-object.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * URDF 로봇을 things-scene 3D 공간에 네이티브로 임베드한다.\n * GLTFObject와 대칭적인 구조 — 2D 탑뷰는 스냅샷 렌더로 표현한다.\n */\n\nimport {\n RectPath,\n Shape,\n sceneComponent,\n type ComponentNature,\n type Control,\n type IRealObject\n} from '@hatiolab/things-scene'\nimport { RealObjectURDF } from './real-object-urdf.js'\nimport type { URDFJointState, URDFJointMeta } from './real-object-urdf.js'\n\nconst BASE_URL_ALIAS = '$base_url'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'urdf-preset',\n label: 'preset',\n name: 'preset'\n },\n {\n type: 'string',\n label: 'url',\n name: 'src',\n property: {\n displayField: 'id',\n displayFullUrl: true,\n baseUrlAlias: BASE_URL_ALIAS,\n defaultStorage: '3d-model',\n storageFilters: {\n type: Array,\n value: [\n {\n name: 'category',\n value: 'urdf'\n }\n ]\n },\n useUpload: true,\n category: 'application'\n }\n },\n {\n type: 'select',\n label: 'up-axis',\n name: 'upAxis',\n property: {\n options: [\n { display: 'Z (URDF default)', value: 'z' },\n { display: 'Y (Three.js default)', value: 'y' }\n ]\n }\n },\n {\n type: 'number',\n label: 'unit-scale',\n name: 'unitScale',\n placeholder: '1000'\n },\n {\n type: 'select',\n label: 'auto-animate',\n name: 'autoAnimate',\n property: {\n options: [\n { display: 'Off', value: 'none' },\n { display: 'Sine swing', value: 'sine' }\n ]\n }\n },\n {\n type: 'select',\n label: 'physics',\n name: 'physics',\n property: {\n options: [\n { display: 'Direct (immediate)', value: 'none' },\n { display: 'Smooth (damped)', value: 'smooth' }\n ]\n }\n },\n {\n type: 'urdf-joints',\n label: '',\n name: 'joints',\n editor: {\n fullwidth: true\n }\n }\n ],\n 'value-property': 'source',\n help: 'scene/component/urdf'\n}\n\n@sceneComponent('urdf')\nexport class URDFObject extends RectPath(Shape) {\n get hasTextProperty() {\n return false\n }\n\n is3dish() {\n return true\n }\n\n get controls(): Array<Control> | undefined {\n return []\n }\n\n render(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n context.beginPath()\n\n const snapshot = (this as any)._topViewSnapshot as HTMLCanvasElement | undefined\n if (snapshot) {\n context.drawImage(snapshot, left, top, width, height)\n } else {\n // 폴백: 로봇 아이콘 박스 + 중앙 라벨\n context.rect(left, top, width, height)\n context.fillStyle = '#e3f2fd'\n context.fill()\n context.strokeStyle = '#1976d2'\n context.lineWidth = 1\n context.stroke()\n\n const src = this.getState('src') as string | undefined\n const label = src ? src.split('/').pop()?.replace(/\\.[^.]+$/, '') || 'URDF' : 'URDF'\n const fontSize = Math.max(10, Math.min(width, height) * 0.12)\n context.fillStyle = '#1976d2'\n context.font = `${fontSize}px sans-serif`\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n context.fillText(label, left + width / 2, top + height / 2, width * 0.9)\n }\n }\n\n async ready() {\n await super.ready()\n this._ensureTopViewSnapshot()\n }\n\n onchange(after: Record<string, any>, before: Record<string, any>) {\n super.onchange(after, before)\n if ('src' in after) {\n (this as any)._topViewSnapshot = undefined\n this._ensureTopViewSnapshot()\n }\n }\n\n private _ensureTopViewSnapshot() {\n const src = this.getState('src') as string | undefined\n if (!src) return\n\n const cached = RealObjectURDF.getTopViewCache(src)\n if (cached) {\n (this as any)._topViewSnapshot = cached\n this.invalidate()\n }\n // 캐시 miss인 경우 3D 씬이 활성화되면 _onLoaded에서 자동 생성한다.\n }\n\n buildRealObject(): IRealObject | undefined {\n return new RealObjectURDF(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n get source() {\n return this.getState('src')\n }\n\n set source(source) {\n this.setState('src', source)\n }\n\n set dimension(dimension: { width: number; height: number; depth: number }) {\n const { width = 1, height = 1, depth = 1 } = dimension\n this.setState({ width, height, depth })\n this.realObject?.updateDimension()\n }\n\n // --- URDF 바인딩 API ---\n\n /** 조인트 상태 맵. 값은 숫자(라디안/거리) 또는 { value } 형식 허용. */\n get joints(): Record<string, URDFJointState | number> | undefined {\n return this.getState('joints')\n }\n\n set joints(value: Record<string, URDFJointState | number> | undefined) {\n this.setState('joints', value)\n }\n\n /** 로드된 URDF의 조인트 메타 정보. property editor가 슬라이더 UI 생성에 사용. */\n get jointMeta(): URDFJointMeta[] {\n const ro = this.realObject as RealObjectURDF | undefined\n return ro?.jointMeta ?? []\n }\n\n get jointNames(): string[] {\n const ro = this.realObject as RealObjectURDF | undefined\n return ro?.jointNames ?? []\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"urdf-object.js","sourceRoot":"","sources":["../src/urdf-object.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * URDF 로봇을 things-scene 3D 공간에 네이티브로 임베드한다.\n * GLTFObject와 대칭적인 구조 — 2D 탑뷰는 스냅샷 렌더로 표현한다.\n *\n * GltfComponent mixin 합류 (2026-05): GLB / URDF 양쪽이 공유하는\n * - 2D 탑뷰 fallback render (스냅샷 + 라벨)\n * - src 변경 → 스냅샷 reset → ensure 라이프사이클\n * - is3dish / hasTextProperty / controls / source / dimension 보일러플레이트\n * - ratioLock 인터셉트\n * 를 mixin에서 받음. URDF 고유는:\n * - `_ensureTopViewSnapshot()` override — URDF 로더는 GLB 로더와 다르므로\n * mixin 디폴트(GLB loader 호출)를 쓸 수 없고, 캐시 히트만 처리하고\n * miss 는 RealObjectURDF._onLoaded 가 채우도록 위임.\n * - `buildRealObject()` override — RealObjectURDF 반환.\n * - NATURE — urdf-preset / urdf-joints / upAxis / unitScale / autoAnimate\n * / physics 등 로봇 도메인 전용 properties (GLB의 gltfNatureProperties\n * 와 의미가 다르므로 spread 안 함).\n */\n\nimport {\n GltfComponent,\n RectPath,\n Shape,\n sceneComponent,\n type ComponentNature,\n type IRealObject\n} from '@hatiolab/things-scene'\n\nimport { RealObjectURDF } from './real-object-urdf.js'\nimport type { URDFJointState, URDFJointMeta } from './real-object-urdf.js'\n\nconst BASE_URL_ALIAS = '$base_url'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'urdf-preset',\n label: 'preset',\n name: 'preset'\n },\n {\n type: 'string',\n label: 'url',\n name: 'src',\n property: {\n displayField: 'id',\n displayFullUrl: true,\n baseUrlAlias: BASE_URL_ALIAS,\n defaultStorage: '3d-model',\n storageFilters: {\n type: Array,\n value: [\n {\n name: 'category',\n value: 'urdf'\n }\n ]\n },\n useUpload: true,\n category: 'application'\n }\n },\n {\n type: 'select',\n label: 'up-axis',\n name: 'upAxis',\n property: {\n options: [\n { display: 'Z (URDF default)', value: 'z' },\n { display: 'Y (Three.js default)', value: 'y' }\n ]\n }\n },\n {\n type: 'number',\n label: 'unit-scale',\n name: 'unitScale',\n placeholder: '1000'\n },\n {\n type: 'select',\n label: 'auto-animate',\n name: 'autoAnimate',\n property: {\n options: [\n { display: 'Off', value: 'none' },\n { display: 'Sine swing', value: 'sine' }\n ]\n }\n },\n {\n type: 'select',\n label: 'physics',\n name: 'physics',\n property: {\n options: [\n { display: 'Direct (immediate)', value: 'none' },\n { display: 'Smooth (damped)', value: 'smooth' }\n ]\n }\n },\n {\n type: 'urdf-joints',\n label: '',\n name: 'joints',\n editor: {\n fullwidth: true\n }\n }\n ],\n 'value-property': 'source',\n help: 'scene/component/urdf'\n}\n\n@sceneComponent('urdf')\nexport class URDFObject extends GltfComponent(RectPath(Shape)) {\n /**\n * URDF 캐시 hit 만 처리. miss 시는 RealObjectURDF.\\_onLoaded 가\n * 캐시를 채우고 component.\\_topViewSnapshot 을 직접 세팅한다 (URDF\n * 로더는 GLB 로더와 다르므로 mixin 의 디폴트 — RealObjectGLTF.loadGLTF\n * 직접 호출 — 을 쓸 수 없다).\n */\n _ensureTopViewSnapshot() {\n const src = this.getState('src') as string | undefined\n if (!src) return\n\n const cached = RealObjectURDF.getTopViewCache(src)\n if (cached) {\n ;(this as any)._topViewSnapshot = cached\n this.invalidate()\n }\n }\n\n override buildRealObject(): IRealObject | undefined {\n return new RealObjectURDF(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n // --- URDF 바인딩 API ---\n\n /** 조인트 상태 맵. 값은 숫자(라디안/거리) 또는 { value } 형식 허용. */\n get joints(): Record<string, URDFJointState | number> | undefined {\n return this.getState('joints')\n }\n\n set joints(value: Record<string, URDFJointState | number> | undefined) {\n this.setState('joints', value)\n }\n\n /** 로드된 URDF의 조인트 메타 정보. property editor가 슬라이더 UI 생성에 사용. */\n get jointMeta(): URDFJointMeta[] {\n const ro = this.realObject as RealObjectURDF | undefined\n return ro?.jointMeta ?? []\n }\n\n get jointNames(): string[] {\n const ro = this.realObject as RealObjectURDF | undefined\n return ro?.jointNames ?? []\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@operato/scene-urdf",
|
|
3
3
|
"description": "Scene module for manipulating robot simulation through URDF format",
|
|
4
4
|
"author": "heartyoh",
|
|
5
|
-
"version": "10.0.0-beta.
|
|
5
|
+
"version": "10.0.0-beta.30",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"module": "dist/index.js",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"prettier --write"
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "06b35b1726ec4f27ee76657ce341c6c6f3ba1b3a"
|
|
70
70
|
}
|