@fmsim/machine 2.0.0-beta.3 → 2.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/carrier-manager.js +92 -0
- package/dist/carrier-manager.js.map +1 -0
- package/dist/carrier.js +51 -6
- package/dist/carrier.js.map +1 -1
- package/dist/conveyor-join.js +8 -2
- package/dist/conveyor-join.js.map +1 -1
- package/dist/conveyor.js +8 -0
- package/dist/conveyor.js.map +1 -1
- package/dist/factories/agv-3d.js +36 -8
- package/dist/factories/agv-3d.js.map +1 -1
- package/dist/factories/conveyor-3d.js +159 -69
- package/dist/factories/conveyor-3d.js.map +1 -1
- package/dist/factories/machine-3d.js +604 -82
- package/dist/factories/machine-3d.js.map +1 -1
- package/dist/factories/oht-3d.js +50 -24
- package/dist/factories/oht-3d.js.map +1 -1
- package/dist/factories/shuttle-3d.js +32 -6
- package/dist/factories/shuttle-3d.js.map +1 -1
- package/dist/index.js +50 -34
- package/dist/index.js.map +1 -1
- package/dist/mcs-carrier-holder.js +39 -22
- package/dist/mcs-carrier-holder.js.map +1 -1
- package/dist/node.js +1 -1
- package/dist/node.js.map +1 -1
- package/dist/scanner.js +30 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scene/root-container-override.js +9 -0
- package/dist/scene/root-container-override.js.map +1 -1
- package/dist/templates/index.js +2 -0
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/scanner.js +20 -0
- package/dist/templates/scanner.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/jest.config.js +10 -0
- package/package.json +4 -3
- package/src/carrier-manager.ts +116 -0
- package/src/carrier.ts +50 -4
- package/src/conveyor-join.ts +5 -2
- package/src/conveyor.ts +8 -0
- package/src/factories/agv-3d.ts +36 -8
- package/src/factories/conveyor-3d.ts +161 -71
- package/src/factories/machine-3d.ts +708 -72
- package/src/factories/oht-3d.ts +48 -24
- package/src/factories/shuttle-3d.ts +30 -6
- package/src/index.ts +56 -34
- package/src/mcs-carrier-holder.ts +38 -34
- package/src/node.ts +1 -1
- package/src/scanner.ts +29 -0
- package/src/scene/root-container-override.ts +12 -0
- package/src/templates/index.ts +2 -0
- package/src/templates/scanner.ts +20 -0
- package/translations/en.json +2 -1
- package/translations/ja.json +2 -1
- package/translations/ko.json +2 -1
- package/translations/ms.json +2 -1
- package/translations/zh.json +2 -1
|
@@ -40,14 +40,14 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
40
40
|
// '#F0F0F0'은 상태 미설정 시 기본 fallback — 무시하고 defaultColor 사용
|
|
41
41
|
try {
|
|
42
42
|
const sc = comp.statusColor
|
|
43
|
-
if (typeof sc === 'string' && sc && sc.toUpperCase() !== '#F0F0F0') return new THREE.Color(sc).getHex()
|
|
43
|
+
if (typeof sc === 'string' && sc && sc.toUpperCase() !== '#F0F0F0' && sc !== 'transparent') return new THREE.Color(sc).getHex()
|
|
44
44
|
} catch {
|
|
45
45
|
/* statusColor 미구현 시 무시 */
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// 2) state.fillStyle fallback
|
|
49
49
|
const { fillStyle } = this.component.state
|
|
50
|
-
if (fillStyle && typeof fillStyle === 'string') {
|
|
50
|
+
if (fillStyle && typeof fillStyle === 'string' && fillStyle !== 'transparent') {
|
|
51
51
|
try {
|
|
52
52
|
return new THREE.Color(fillStyle).getHex()
|
|
53
53
|
} catch {
|
|
@@ -61,16 +61,31 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
61
61
|
build() {
|
|
62
62
|
super.build()
|
|
63
63
|
|
|
64
|
-
const { width, height, conveyorType } = this.component.state
|
|
64
|
+
const { width: rawWidth, height: rawHeight, conveyorType, orientation } = this.component.state
|
|
65
65
|
const depth = this.effectiveDepth
|
|
66
|
-
if (!
|
|
66
|
+
if (!rawWidth || !rawHeight) return
|
|
67
|
+
|
|
68
|
+
// orientation: 'horizontal' = 롤러가 Z축(세로), 'vertical' = 롤러가 X축(가로)
|
|
69
|
+
// default = 긴 방향에 수직 (긴 축을 따라 이송)
|
|
70
|
+
const isVertical = orientation === 'vertical' ? true
|
|
71
|
+
: orientation === 'horizontal' ? false
|
|
72
|
+
: rawWidth < rawHeight // default: 세로가 길면 롤러는 가로(X축)
|
|
73
|
+
// isVertical=true → 롤러 축이 X(가로), 이송 방향이 Z(세로)
|
|
74
|
+
// isVertical=false → 롤러 축이 Z(세로), 이송 방향이 X(가로)
|
|
75
|
+
const width = rawWidth
|
|
76
|
+
const height = rawHeight
|
|
67
77
|
|
|
68
78
|
// 2D와 동일 로직으로 rollWidth 산출
|
|
69
79
|
const rollWidth = Math.max(10, Math.min(width, height) / 2)
|
|
70
80
|
const rollerDiameter = Math.max(rollWidth, 2)
|
|
71
81
|
const frameH = Math.min(rollerDiameter, depth)
|
|
72
82
|
const legH = Math.max(depth - frameH, 0)
|
|
73
|
-
|
|
83
|
+
|
|
84
|
+
// isVertical일 때 이송 방향이 Z축: 레일은 Z축을 따라, 벨트폭은 width
|
|
85
|
+
// !isVertical일 때 이송 방향이 X축: 레일은 X축을 따라, 벨트폭은 height
|
|
86
|
+
const beltWidth = isVertical ? width : height
|
|
87
|
+
const railLen = isVertical ? height : width
|
|
88
|
+
const railW = Math.max(beltWidth * 0.06, 2)
|
|
74
89
|
const legThickness = Math.max(railW * 0.8, 2)
|
|
75
90
|
|
|
76
91
|
const frameMaterial = new THREE.MeshStandardMaterial({
|
|
@@ -84,11 +99,21 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
84
99
|
const frameGeometries: THREE.BufferGeometry[] = []
|
|
85
100
|
const railY = depth - frameH / 2
|
|
86
101
|
|
|
87
|
-
// Side rails
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
// Side rails — 이송 방향을 따라, 벨트 양측에 배치
|
|
103
|
+
if (isVertical) {
|
|
104
|
+
// 레일이 Z축(세로)을 따라, ±X에 배치
|
|
105
|
+
for (const xSign of [-1, 1]) {
|
|
106
|
+
const rail = new THREE.BoxGeometry(railW, frameH, height)
|
|
107
|
+
rail.translate(xSign * (width / 2 - railW / 2), railY, 0)
|
|
108
|
+
frameGeometries.push(rail)
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
// 레일이 X축(가로)을 따라, ±Z에 배치
|
|
112
|
+
for (const zSign of [-1, 1]) {
|
|
113
|
+
const rail = new THREE.BoxGeometry(width, frameH, railW)
|
|
114
|
+
rail.translate(0, railY, zSign * (height / 2 - railW / 2))
|
|
115
|
+
frameGeometries.push(rail)
|
|
116
|
+
}
|
|
92
117
|
}
|
|
93
118
|
|
|
94
119
|
// 4 legs at corners
|
|
@@ -96,34 +121,51 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
96
121
|
const legTopY = depth - frameH
|
|
97
122
|
const legCenterY = legTopY - legH / 2
|
|
98
123
|
|
|
124
|
+
// 다리 위치: 레일 안쪽에 정렬
|
|
125
|
+
const legXPos = isVertical ? (width / 2 - railW / 2) : (width / 2 - legThickness / 2)
|
|
126
|
+
const legZPos = isVertical ? (height / 2 - legThickness / 2) : (height / 2 - railW / 2)
|
|
127
|
+
|
|
99
128
|
for (const xSign of [-1, 1]) {
|
|
100
129
|
for (const zSign of [-1, 1]) {
|
|
101
|
-
const lx = xSign * (width / 2 - legThickness / 2)
|
|
102
|
-
const lz = zSign * (height / 2 - railW / 2)
|
|
103
130
|
const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)
|
|
104
|
-
leg.translate(
|
|
131
|
+
leg.translate(xSign * legXPos, legCenterY, zSign * legZPos)
|
|
105
132
|
frameGeometries.push(leg)
|
|
106
133
|
}
|
|
107
134
|
}
|
|
108
135
|
|
|
109
|
-
// Cross-bracing
|
|
136
|
+
// Cross-bracing
|
|
110
137
|
const braceH = legThickness * 0.6
|
|
111
138
|
const braceW = legThickness * 0.6
|
|
112
|
-
const braceLen = height - railW
|
|
113
139
|
const braceY = legTopY - legH * 0.35
|
|
114
140
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
141
|
+
// 이송 방향 브레이스 (레일과 평행)
|
|
142
|
+
if (isVertical) {
|
|
143
|
+
for (const xSign of [-1, 1]) {
|
|
144
|
+
const brace = new THREE.BoxGeometry(braceW, braceH, height - legThickness)
|
|
145
|
+
brace.translate(xSign * legXPos, braceY, 0)
|
|
146
|
+
frameGeometries.push(brace)
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
for (const zSign of [-1, 1]) {
|
|
150
|
+
const brace = new THREE.BoxGeometry(width - legThickness, braceH, braceW)
|
|
151
|
+
brace.translate(0, braceY, zSign * legZPos)
|
|
152
|
+
frameGeometries.push(brace)
|
|
153
|
+
}
|
|
119
154
|
}
|
|
120
155
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
156
|
+
// 벨트폭 방향 브레이스 (레일과 수직)
|
|
157
|
+
if (isVertical) {
|
|
158
|
+
for (const zSign of [-1, 1]) {
|
|
159
|
+
const brace = new THREE.BoxGeometry(width - railW, braceH, braceW)
|
|
160
|
+
brace.translate(0, braceY, zSign * legZPos)
|
|
161
|
+
frameGeometries.push(brace)
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
for (const xSign of [-1, 1]) {
|
|
165
|
+
const brace = new THREE.BoxGeometry(braceW, braceH, height - railW)
|
|
166
|
+
brace.translate(xSign * legXPos, braceY, 0)
|
|
167
|
+
frameGeometries.push(brace)
|
|
168
|
+
}
|
|
127
169
|
}
|
|
128
170
|
}
|
|
129
171
|
|
|
@@ -134,11 +176,11 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
134
176
|
|
|
135
177
|
// --- Rollers, Belt, or Rails ---
|
|
136
178
|
if (conveyorType === 'rail') {
|
|
137
|
-
this.buildRails(width, height, depth, frameH, railW)
|
|
179
|
+
this.buildRails(width, height, depth, frameH, railW, isVertical)
|
|
138
180
|
} else if (conveyorType === 'belt') {
|
|
139
|
-
this.buildBelt(width, height, depth, frameH, railW)
|
|
181
|
+
this.buildBelt(width, height, depth, frameH, railW, isVertical)
|
|
140
182
|
} else {
|
|
141
|
-
this.buildRollers(width, height, depth, frameH, railW, rollWidth)
|
|
183
|
+
this.buildRollers(width, height, depth, frameH, railW, rollWidth, isVertical)
|
|
142
184
|
}
|
|
143
185
|
}
|
|
144
186
|
|
|
@@ -148,28 +190,45 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
148
190
|
depth: number,
|
|
149
191
|
frameH: number,
|
|
150
192
|
railW: number,
|
|
151
|
-
rollWidth: number
|
|
193
|
+
rollWidth: number,
|
|
194
|
+
isVertical: boolean = false
|
|
152
195
|
) {
|
|
153
196
|
const rollerRadius = Math.max(rollWidth / 8, 1)
|
|
154
|
-
const rollerLength = height - railW * 2 - 0.5
|
|
155
197
|
const diameter = rollerRadius * 2
|
|
156
|
-
// 롤러 간 최소 간격 (z-fighting 방지용 미세 갭만)
|
|
157
198
|
const step = diameter * 1.05
|
|
158
|
-
// 롤러 상단 = 이송 표면 (y=depth)
|
|
159
199
|
const rollerY = depth - rollerRadius
|
|
160
200
|
const color = this.resolveColor()
|
|
161
201
|
|
|
162
202
|
const rollerGeometries: THREE.BufferGeometry[] = []
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
203
|
+
|
|
204
|
+
if (isVertical) {
|
|
205
|
+
// 롤러 축 = X축(가로), 이송 방향 = Z축(세로)
|
|
206
|
+
const rollerLength = width - railW * 2 - 0.5
|
|
207
|
+
const count = Math.max(1, Math.floor(height / step))
|
|
208
|
+
const totalSpan = (count - 1) * step
|
|
209
|
+
const startZ = -totalSpan / 2
|
|
210
|
+
|
|
211
|
+
for (let i = 0; i < count; i++) {
|
|
212
|
+
const z = startZ + i * step
|
|
213
|
+
const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)
|
|
214
|
+
roller.rotateZ(Math.PI / 2)
|
|
215
|
+
roller.translate(0, rollerY, z)
|
|
216
|
+
rollerGeometries.push(roller)
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
// 롤러 축 = Z축(세로), 이송 방향 = X축(가로) — 기존 동작
|
|
220
|
+
const rollerLength = height - railW * 2 - 0.5
|
|
221
|
+
const count = Math.max(1, Math.floor(width / step))
|
|
222
|
+
const totalSpan = (count - 1) * step
|
|
223
|
+
const startX = -totalSpan / 2
|
|
224
|
+
|
|
225
|
+
for (let i = 0; i < count; i++) {
|
|
226
|
+
const x = startX + i * step
|
|
227
|
+
const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)
|
|
228
|
+
roller.rotateX(Math.PI / 2)
|
|
229
|
+
roller.translate(x, rollerY, 0)
|
|
230
|
+
rollerGeometries.push(roller)
|
|
231
|
+
}
|
|
173
232
|
}
|
|
174
233
|
|
|
175
234
|
if (rollerGeometries.length > 0) {
|
|
@@ -182,22 +241,31 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
182
241
|
}
|
|
183
242
|
}
|
|
184
243
|
|
|
185
|
-
private buildBelt(width: number, height: number, depth: number, frameH: number, railW: number) {
|
|
244
|
+
private buildBelt(width: number, height: number, depth: number, frameH: number, railW: number, isVertical: boolean = false) {
|
|
186
245
|
const drumRadius = frameH * 0.38
|
|
187
|
-
const drumLength = height - railW * 2
|
|
188
246
|
const beltY = depth - drumRadius
|
|
189
247
|
const color = this.resolveColor()
|
|
190
248
|
|
|
249
|
+
// 이송 방향 길이와 벨트폭
|
|
250
|
+
const transportLen = isVertical ? height : width
|
|
251
|
+
const beltWidth = isVertical ? width : height
|
|
252
|
+
const drumLength = beltWidth - railW * 2
|
|
253
|
+
|
|
191
254
|
// Two end drums
|
|
192
255
|
const drumGeometries: THREE.BufferGeometry[] = []
|
|
193
256
|
const drumInset = drumRadius * 1.5
|
|
194
|
-
const
|
|
195
|
-
const
|
|
257
|
+
const drum1 = -transportLen / 2 + drumInset
|
|
258
|
+
const drum2 = transportLen / 2 - drumInset
|
|
196
259
|
|
|
197
|
-
for (const
|
|
260
|
+
for (const dp of [drum1, drum2]) {
|
|
198
261
|
const drum = new THREE.CylinderGeometry(drumRadius, drumRadius, drumLength, 16)
|
|
199
|
-
|
|
200
|
-
|
|
262
|
+
if (isVertical) {
|
|
263
|
+
drum.rotateZ(Math.PI / 2)
|
|
264
|
+
drum.translate(0, beltY, dp)
|
|
265
|
+
} else {
|
|
266
|
+
drum.rotateX(Math.PI / 2)
|
|
267
|
+
drum.translate(dp, beltY, 0)
|
|
268
|
+
}
|
|
201
269
|
drumGeometries.push(drum)
|
|
202
270
|
}
|
|
203
271
|
|
|
@@ -217,8 +285,10 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
217
285
|
})
|
|
218
286
|
|
|
219
287
|
// Flat belt top surface spanning between drums
|
|
220
|
-
const flatLen =
|
|
221
|
-
const flatGeo =
|
|
288
|
+
const flatLen = drum2 - drum1
|
|
289
|
+
const flatGeo = isVertical
|
|
290
|
+
? new THREE.BoxGeometry(drumLength, beltThickness, flatLen)
|
|
291
|
+
: new THREE.BoxGeometry(flatLen, beltThickness, drumLength)
|
|
222
292
|
const flatMesh = new THREE.Mesh(flatGeo, beltMaterial)
|
|
223
293
|
flatMesh.position.set(0, beltY + drumRadius, 0)
|
|
224
294
|
flatMesh.castShadow = true
|
|
@@ -226,9 +296,9 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
226
296
|
|
|
227
297
|
// Belt wrap around drums (segmented half-cylinder)
|
|
228
298
|
const wrapSegments = 12
|
|
229
|
-
for (const [
|
|
230
|
-
[
|
|
231
|
-
[
|
|
299
|
+
for (const [dp, angleStart] of [
|
|
300
|
+
[drum1, Math.PI / 2],
|
|
301
|
+
[drum2, -Math.PI / 2],
|
|
232
302
|
] as [number, number][]) {
|
|
233
303
|
const wrapGeometries: THREE.BufferGeometry[] = []
|
|
234
304
|
for (let i = 0; i < wrapSegments; i++) {
|
|
@@ -236,18 +306,25 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
236
306
|
const a1 = angleStart + (Math.PI * (i + 1)) / wrapSegments
|
|
237
307
|
const r = drumRadius + beltThickness / 2
|
|
238
308
|
|
|
239
|
-
const
|
|
309
|
+
const p0 = dp + Math.cos(a0) * r
|
|
240
310
|
const y0 = beltY + Math.sin(a0) * r
|
|
241
|
-
const
|
|
311
|
+
const p1 = dp + Math.cos(a1) * r
|
|
242
312
|
const y1 = beltY + Math.sin(a1) * r
|
|
243
313
|
|
|
244
|
-
const segLen = Math.sqrt((
|
|
245
|
-
const segAngle = Math.atan2(y1 - y0,
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
314
|
+
const segLen = Math.sqrt((p1 - p0) ** 2 + (y1 - y0) ** 2) * 1.05
|
|
315
|
+
const segAngle = Math.atan2(y1 - y0, p1 - p0)
|
|
316
|
+
|
|
317
|
+
if (isVertical) {
|
|
318
|
+
const seg = new THREE.BoxGeometry(drumLength, beltThickness, segLen)
|
|
319
|
+
seg.rotateX(-segAngle)
|
|
320
|
+
seg.translate(0, (y0 + y1) / 2, (p0 + p1) / 2)
|
|
321
|
+
wrapGeometries.push(seg)
|
|
322
|
+
} else {
|
|
323
|
+
const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength)
|
|
324
|
+
seg.rotateZ(segAngle)
|
|
325
|
+
seg.translate((p0 + p1) / 2, (y0 + y1) / 2, 0)
|
|
326
|
+
wrapGeometries.push(seg)
|
|
327
|
+
}
|
|
251
328
|
}
|
|
252
329
|
const wrapMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(wrapGeometries), beltMaterial)
|
|
253
330
|
wrapMesh.castShadow = true
|
|
@@ -255,17 +332,21 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
255
332
|
}
|
|
256
333
|
|
|
257
334
|
// Flat belt bottom (return path)
|
|
258
|
-
const bottomGeo =
|
|
335
|
+
const bottomGeo = isVertical
|
|
336
|
+
? new THREE.BoxGeometry(drumLength * 0.85, beltThickness, flatLen)
|
|
337
|
+
: new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85)
|
|
259
338
|
const bottomMesh = new THREE.Mesh(bottomGeo, beltMaterial)
|
|
260
339
|
bottomMesh.position.set(0, beltY - drumRadius, 0)
|
|
261
340
|
this.object3d.add(bottomMesh)
|
|
262
341
|
}
|
|
263
342
|
|
|
264
|
-
private buildRails(width: number, height: number, depth: number, frameH: number, railW: number) {
|
|
343
|
+
private buildRails(width: number, height: number, depth: number, frameH: number, railW: number, isVertical: boolean = false) {
|
|
265
344
|
const color = this.resolveColor()
|
|
266
345
|
const railHeight = frameH * 0.3
|
|
267
346
|
const railY = depth - railHeight / 2
|
|
268
|
-
const
|
|
347
|
+
const beltWidth = isVertical ? width : height
|
|
348
|
+
const transportLen = isVertical ? height : width
|
|
349
|
+
const innerWidth = beltWidth - railW * 2
|
|
269
350
|
// 두 레일 간격: 내부 폭의 60%
|
|
270
351
|
const railSpacing = innerWidth * 0.6
|
|
271
352
|
|
|
@@ -277,11 +358,19 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
277
358
|
|
|
278
359
|
const railGeometries: THREE.BufferGeometry[] = []
|
|
279
360
|
|
|
280
|
-
// Two parallel rails running along
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
361
|
+
// Two parallel rails running along transport direction
|
|
362
|
+
if (isVertical) {
|
|
363
|
+
for (const xSign of [-1, 1]) {
|
|
364
|
+
const rail = new THREE.BoxGeometry(railW * 0.8, railHeight, transportLen - railW * 2)
|
|
365
|
+
rail.translate(xSign * (railSpacing / 2), railY, 0)
|
|
366
|
+
railGeometries.push(rail)
|
|
367
|
+
}
|
|
368
|
+
} else {
|
|
369
|
+
for (const zSign of [-1, 1]) {
|
|
370
|
+
const rail = new THREE.BoxGeometry(transportLen - railW * 2, railHeight, railW * 0.8)
|
|
371
|
+
rail.translate(0, railY, zSign * (railSpacing / 2))
|
|
372
|
+
railGeometries.push(rail)
|
|
373
|
+
}
|
|
285
374
|
}
|
|
286
375
|
|
|
287
376
|
const railMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(railGeometries), railMaterial)
|
|
@@ -295,6 +384,7 @@ export class Conveyor3D extends RealObjectGroup {
|
|
|
295
384
|
onchange(after: Record<string, unknown>, before: Record<string, unknown>) {
|
|
296
385
|
if (
|
|
297
386
|
'conveyorType' in after ||
|
|
387
|
+
'orientation' in after ||
|
|
298
388
|
'width' in after ||
|
|
299
389
|
'height' in after ||
|
|
300
390
|
'depth' in after ||
|